Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f4f4ec5024 | |||
| ba56173966 | |||
| 3e6e953461 | |||
| 343d02c40d | |||
| a69c41fef7 | |||
| ce78188072 | |||
| 8c46bbd2e9 | |||
| 4de0dd933d |
31
changelog.md
31
changelog.md
@@ -1,5 +1,36 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-03-12 - 2.2.3 - fix(repo)
|
||||
no changes to commit
|
||||
|
||||
|
||||
## 2026-03-11 - 2.2.2 - fix(decorators)
|
||||
patch container-responsive styles to fix stale container queries and add customElement wrapper that sets .is and warns on class/tag mismatch
|
||||
|
||||
- containerResponsive now derives the kebab name and replaces stale '@container <derived>' occurrences inside CSSResult cssText using unsafeCSS to correct container queries produced before decorators ran
|
||||
- containerResponsive appends containerContextStyles to the component styles while preserving/processing existing static styles
|
||||
- Added a customElement decorator wrapper that assigns .is on the class, logs a warning if the class name kebab-cases to a different tag name, and delegates to Lit's customElement
|
||||
- ts/index.ts now re-exports customElement from the local decorator so the new behavior is used project-wide
|
||||
|
||||
## 2026-03-11 - 2.2.1 - fix(dees-element)
|
||||
rename cssForCustom to cssForConstraint, remove DeesElement static cssFor* helpers, and add optional elementClass parameter to cssManager breakpoint helpers
|
||||
|
||||
- Rename: cssManager.cssForCustom -> cssManager.cssForConstraint and DeesElement.cssForCustom -> DeesElement.cssForConstraint; underlying domtools calls updated to cssForConstraint/cssForConstraintContainer.
|
||||
- Breaking: Removed static helpers DeesElement.cssForDesktop, cssForNotebook, cssForTablet, cssForPhablet, cssForPhone — consumers must now use cssManager.cssFor*(css, this) or pass an element class to get component-scoped container rules.
|
||||
- API change: cssManager.cssForDesktop|cssForNotebook|cssForTablet|cssForPhablet|cssForPhone now accept an optional elementClass (or pass this) and a helper getContainerNameFromClass was added to generate container names.
|
||||
- Docs: readme.md updated to show new signatures, guidance to pass this for component-scoped constraints, and renaming of "custom" to "constraint".
|
||||
- Dependency: bumped @design.estate/dees-domtools from ^2.4.0 to ^2.5.1.
|
||||
|
||||
## 2026-03-11 - 2.2.0 - feat(dees-element)
|
||||
add container-responsive APIs (containerResponsive decorator, DeesElement static cssFor* container helpers, and cssManager cssForCustom) and update docs
|
||||
|
||||
- Exported new containerResponsive decorator (ts/decorators.containerresponsive.ts and exported from ts/index.ts)
|
||||
- Added component-level static helpers on DeesElement: cssForDesktop, cssForNotebook, cssForTablet, cssForPhablet, cssForPhone, cssForCustom
|
||||
- Added cssManager.cssForCustom to provide curried custom breakpoint helper
|
||||
- Updated readme with Container-Responsive Components section and usage examples
|
||||
- Bumped dependency @design.estate/dees-domtools from ^2.3.8 to ^2.4.0
|
||||
- Non-breaking new functionality — recommend minor version bump
|
||||
|
||||
## 2026-01-27 - 2.1.6 - fix(docs, deps, tests)
|
||||
update README with expanded usage docs and examples; bump devDependencies and dees-domtools; fix test import path
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@design.estate/dees-element",
|
||||
"version": "2.1.6",
|
||||
"version": "2.2.3",
|
||||
"private": false,
|
||||
"description": "A library for creating custom elements extending the lit element class with additional functionalities.",
|
||||
"main": "dist_ts/index.js",
|
||||
@@ -20,7 +20,7 @@
|
||||
"@types/node": "^25.0.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@design.estate/dees-domtools": "^2.3.8",
|
||||
"@design.estate/dees-domtools": "^2.5.1",
|
||||
"@push.rocks/isounique": "^1.0.5",
|
||||
"@push.rocks/smartrx": "^3.0.10",
|
||||
"lit": "^3.3.2"
|
||||
|
||||
111
pnpm-lock.yaml
generated
111
pnpm-lock.yaml
generated
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools':
|
||||
specifier: ^2.3.8
|
||||
version: 2.3.8
|
||||
specifier: ^2.5.1
|
||||
version: 2.5.1
|
||||
'@push.rocks/isounique':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5
|
||||
@@ -45,6 +45,9 @@ packages:
|
||||
'@api.global/typedrequest@3.2.5':
|
||||
resolution: {integrity: sha512-LM/sUTuYnU5xY4gNZrN6ERMiKr+SpDZuSxJkAZz1YazC7ymGfo6uQ8sCnN8eNNQNFqIOkC+BtfYRayfbGwYLLg==}
|
||||
|
||||
'@api.global/typedrequest@3.3.0':
|
||||
resolution: {integrity: sha512-Jwobqla+9k2IBG0duwrCFtc6GU6wsvHS3f0gJJsxTrpapylBW1YSF7NnGHPGs7F9hbATsO6IoUBpR2ScoKyGJA==}
|
||||
|
||||
'@api.global/typedserver@3.0.80':
|
||||
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
||||
|
||||
@@ -243,8 +246,8 @@ packages:
|
||||
'@design.estate/dees-comms@1.0.30':
|
||||
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
|
||||
|
||||
'@design.estate/dees-domtools@2.3.8':
|
||||
resolution: {integrity: sha512-jUG9GMvPxKMwmRIZ9oLTL3c8hHvHuiwIk8cTrYnuZzGO/uJJ5/czk9o6LRXUuCOOG7TRLtqgOpK8EEQgaadfZA==}
|
||||
'@design.estate/dees-domtools@2.5.1':
|
||||
resolution: {integrity: sha512-ojzRSkOpQvxpd4drCNF1wadvPwthI6xIJpYjBbOwlgxkFCrlgxlOxHzRKEVnj5wWeUPqykKhddKp33LKW9mydw==}
|
||||
|
||||
'@design.estate/dees-element@2.1.3':
|
||||
resolution: {integrity: sha512-TjXWxVcdSPaT1IOk31ckfxvAZnJLuTxhFGsNCKoh63/UE2FVf6slp8//UFvN+ADigiA9ZsY0azkY99XbJCwDDA==}
|
||||
@@ -623,6 +626,9 @@ packages:
|
||||
'@push.rocks/lik@6.2.2':
|
||||
resolution: {integrity: sha512-j64FFPPyMXeeUorjKJVF6PWaJUfiIrF3pc41iJH4lOh0UUpBAHpcNzHVxTR58orwbVA/h3Hz+DQd4b1Rq0dFDQ==}
|
||||
|
||||
'@push.rocks/lik@6.3.1':
|
||||
resolution: {integrity: sha512-UWDwGBaVx5yPtAFXqDDBtQZCzETUOA/7myQIXb+YBsuiIw4yQuhNZ23uY2ChQH2Zn6DLqdNSgQcYC0WywMZBNQ==}
|
||||
|
||||
'@push.rocks/mongodump@1.1.0':
|
||||
resolution: {integrity: sha512-kW0ZUGyf1e4nwloVwBQjNId+MzgTcNS834C+RxH21i1NqyOubbpWZtJtPP+K+s35nSJRyCTy3ICfBMdDBTAm2w==}
|
||||
|
||||
@@ -717,6 +723,9 @@ packages:
|
||||
'@push.rocks/smartjson@5.2.0':
|
||||
resolution: {integrity: sha512-710e8UwovRfPgUtaBHcd6unaODUjV5fjxtGcGCqtaTcmvOV6VpasdVfT66xMDzQmWH2E9ZfHDJeso9HdDQzNQA==}
|
||||
|
||||
'@push.rocks/smartjson@6.0.0':
|
||||
resolution: {integrity: sha512-FYfJnmukt66WePn6xrVZ3BLmRQl9W82LcsICK3VU9sGW7kasig090jKXPm+yX8ibQcZAO/KyR/Q8tMIYZNxGew==}
|
||||
|
||||
'@push.rocks/smartlog-destination-devtools@1.0.12':
|
||||
resolution: {integrity: sha512-zvsIkrqByc0JRaBgIyhh+PSz2SY/e/bmhZdUcr/OW6pudgAcqe2sso68EzrKux0w9OMl1P9ZnzF3FpCZPFWD/A==}
|
||||
|
||||
@@ -807,8 +816,8 @@ packages:
|
||||
'@push.rocks/smartspawn@3.0.3':
|
||||
resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==}
|
||||
|
||||
'@push.rocks/smartstate@2.0.27':
|
||||
resolution: {integrity: sha512-q4UKir7GV3hakJWXQR4DoA4tUVwT5GRkJ/MtanHYF0wZLHfS19+nGmyO9y974zk3eT9hmy3+Lq5cKtU2W6+Y3w==}
|
||||
'@push.rocks/smartstate@2.2.1':
|
||||
resolution: {integrity: sha512-fLrilAJNI6QOs0hcBRD9eTwU2Rlo6NlDCKQo9N/zyp0VJ6AV1UVdEZcVIQILu1CO0RUHX9aBAbFunJrb2+Zrkg==}
|
||||
|
||||
'@push.rocks/smartstream@3.2.5':
|
||||
resolution: {integrity: sha512-PLGGIFDy8JLNVUnnntMSIYN4W081YSbNC7Y/sWpvUT8PAXtbEXXUiDFgK5o3gcI0ptpKQxHAwxhzNlPj0sbFVg==}
|
||||
@@ -819,6 +828,9 @@ packages:
|
||||
'@push.rocks/smarttime@4.1.1':
|
||||
resolution: {integrity: sha512-Ha/3J/G+zfTl4ahpZgF6oUOZnUjpLhrBja0OQ2cloFxF9sKT8I1COaSqIfBGDtoK2Nly4UD4aTJ3JcJNOg/kgA==}
|
||||
|
||||
'@push.rocks/smarttime@4.2.3':
|
||||
resolution: {integrity: sha512-8gMg8RUkrCG4p9NcEUZV7V6KpL24+jAMK02g7qyhfA6giz/JJWD0+8w8xjSR+G7qe16KVQ2y3RbvAL9TxmO36g==}
|
||||
|
||||
'@push.rocks/smartunique@3.0.9':
|
||||
resolution: {integrity: sha512-q6DYQgT7/dqdWi9HusvtWCjdsFzLFXY9LTtaZV6IYNJt6teZOonoygxTdNt9XLn6niBSbLYrHSKvJNTRH/uK+g==}
|
||||
|
||||
@@ -846,6 +858,9 @@ packages:
|
||||
'@push.rocks/webrequest@4.0.1':
|
||||
resolution: {integrity: sha512-I60XZZLVf8W5I7YdmUVVu4G92teE3rg3/aKaV00BRg8vJ3VXx3wc59Qj4em7zxQ5o0HvL8m1Aezw3RFMDPyVgA==}
|
||||
|
||||
'@push.rocks/webrequest@4.0.5':
|
||||
resolution: {integrity: sha512-wVSCaXqJ9Vh+rbwVz0wDl46dYz4rnwwSrm5vbVXKbuH6oKTPF0YRoujeJPqRltIn64RVGdLeY9/6ix+ZCrzhsg==}
|
||||
|
||||
'@push.rocks/websetup@3.0.19':
|
||||
resolution: {integrity: sha512-iKJDwXdMmQdu5siOIgziPRxM51lN1AU9HOr+yMteu1YMDkZT7HKCyisDAr4gC9WZ9a7FzsG8zgthm4dMeA8NTw==}
|
||||
|
||||
@@ -1270,8 +1285,8 @@ packages:
|
||||
'@tempfix/idb@8.0.3':
|
||||
resolution: {integrity: sha512-hPJQKO7+oAIY+pDNImrZ9QAINbz9KmwT+yO4iRVwdPanok2YKpaUxdJzIvCUwY0YgAawlvYdffbLvRLV5hbs2g==}
|
||||
|
||||
'@tempfix/lenis@1.3.17':
|
||||
resolution: {integrity: sha512-IqbEB2jLGd0CZrr6TQgjPlhIJJwjDD/53e60KmEr2MEMxwRFUn6pg/H2EvxtoeS7ItmQdhWkJwPgtvVRUCctNw==}
|
||||
'@tempfix/lenis@1.3.20':
|
||||
resolution: {integrity: sha512-ypeB0FuHLHOCQXW4d0RQ69txPJJH+1CHcpsZIUdcv2t1vR0IVyQr2vHihtde9UOXhjzqEnUphWon/UcJNsa0YA==}
|
||||
peerDependencies:
|
||||
'@nuxt/kit': '>=3.0.0'
|
||||
react: '>=17.0.0'
|
||||
@@ -1748,6 +1763,10 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
croner@10.0.1:
|
||||
resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==}
|
||||
engines: {node: '>=18.0'}
|
||||
|
||||
croner@9.1.0:
|
||||
resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==}
|
||||
engines: {node: '>=18.0'}
|
||||
@@ -3456,6 +3475,18 @@ snapshots:
|
||||
'@push.rocks/webrequest': 3.0.37
|
||||
'@push.rocks/webstream': 1.0.10
|
||||
|
||||
'@api.global/typedrequest@3.3.0':
|
||||
dependencies:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
'@push.rocks/isounique': 1.0.5
|
||||
'@push.rocks/lik': 6.3.1
|
||||
'@push.rocks/smartbuffer': 3.0.5
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartguard': 3.1.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/webrequest': 4.0.5
|
||||
'@push.rocks/webstream': 1.0.10
|
||||
|
||||
'@api.global/typedserver@3.0.80':
|
||||
dependencies:
|
||||
'@api.global/typedrequest': 3.2.5
|
||||
@@ -4032,24 +4063,24 @@ snapshots:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
broadcast-channel: 7.2.0
|
||||
|
||||
'@design.estate/dees-domtools@2.3.8':
|
||||
'@design.estate/dees-domtools@2.5.1':
|
||||
dependencies:
|
||||
'@api.global/typedrequest': 3.2.5
|
||||
'@api.global/typedrequest': 3.3.0
|
||||
'@design.estate/dees-comms': 1.0.30
|
||||
'@push.rocks/lik': 6.2.2
|
||||
'@push.rocks/lik': 6.3.1
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartjson': 5.2.0
|
||||
'@push.rocks/smartjson': 6.0.0
|
||||
'@push.rocks/smartmarkdown': 3.0.3
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartrouter': 1.3.3
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
'@push.rocks/smartstate': 2.0.27
|
||||
'@push.rocks/smartstate': 2.2.1
|
||||
'@push.rocks/smartstring': 4.1.0
|
||||
'@push.rocks/smarturl': 3.1.0
|
||||
'@push.rocks/webrequest': 3.0.37
|
||||
'@push.rocks/webrequest': 4.0.5
|
||||
'@push.rocks/websetup': 3.0.19
|
||||
'@push.rocks/webstore': 2.0.20
|
||||
'@tempfix/lenis': 1.3.17
|
||||
'@tempfix/lenis': 1.3.20
|
||||
lit: 3.3.2
|
||||
sweet-scroll: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
@@ -4060,7 +4091,7 @@ snapshots:
|
||||
|
||||
'@design.estate/dees-element@2.1.3':
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools': 2.3.8
|
||||
'@design.estate/dees-domtools': 2.5.1
|
||||
'@push.rocks/isounique': 1.0.5
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
lit: 3.3.2
|
||||
@@ -4632,6 +4663,17 @@ snapshots:
|
||||
'@types/symbol-tree': 3.2.5
|
||||
symbol-tree: 3.2.4
|
||||
|
||||
'@push.rocks/lik@6.3.1':
|
||||
dependencies:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartmatch': 2.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
'@push.rocks/smarttime': 4.2.3
|
||||
'@types/minimatch': 5.1.2
|
||||
'@types/symbol-tree': 3.2.5
|
||||
symbol-tree: 3.2.4
|
||||
|
||||
'@push.rocks/mongodump@1.1.0(socks@2.8.7)':
|
||||
dependencies:
|
||||
'@push.rocks/lik': 6.2.2
|
||||
@@ -4940,6 +4982,13 @@ snapshots:
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
|
||||
'@push.rocks/smartjson@6.0.0':
|
||||
dependencies:
|
||||
'@push.rocks/smartenv': 6.0.0
|
||||
'@push.rocks/smartstring': 4.1.0
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
|
||||
'@push.rocks/smartlog-destination-devtools@1.0.12':
|
||||
dependencies:
|
||||
'@push.rocks/smartlog-interfaces': 3.0.2
|
||||
@@ -5147,7 +5196,7 @@ snapshots:
|
||||
|
||||
'@push.rocks/smartrouter@1.3.3':
|
||||
dependencies:
|
||||
'@push.rocks/lik': 6.2.2
|
||||
'@push.rocks/lik': 6.3.1
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
path-to-regexp: 8.3.0
|
||||
|
||||
@@ -5218,11 +5267,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@push.rocks/smartstate@2.0.27':
|
||||
'@push.rocks/smartstate@2.2.1':
|
||||
dependencies:
|
||||
'@push.rocks/lik': 6.2.2
|
||||
'@push.rocks/smarthash': 3.2.6
|
||||
'@push.rocks/smartjson': 5.2.0
|
||||
'@push.rocks/smartjson': 6.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
'@push.rocks/webstore': 2.0.20
|
||||
@@ -5249,6 +5297,17 @@ snapshots:
|
||||
is-nan: 1.3.2
|
||||
pretty-ms: 9.3.0
|
||||
|
||||
'@push.rocks/smarttime@4.2.3':
|
||||
dependencies:
|
||||
'@push.rocks/lik': 6.3.1
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
croner: 10.0.1
|
||||
date-fns: 4.1.0
|
||||
dayjs: 1.11.19
|
||||
is-nan: 1.3.2
|
||||
pretty-ms: 9.3.0
|
||||
|
||||
'@push.rocks/smartunique@3.0.9':
|
||||
dependencies:
|
||||
'@types/uuid': 9.0.8
|
||||
@@ -5307,6 +5366,14 @@ snapshots:
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/webstore': 2.0.20
|
||||
|
||||
'@push.rocks/webrequest@4.0.5':
|
||||
dependencies:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartenv': 6.0.0
|
||||
'@push.rocks/smartjson': 6.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/webstore': 2.0.20
|
||||
|
||||
'@push.rocks/websetup@3.0.19':
|
||||
dependencies:
|
||||
'@pushrocks/smartdelay': 3.0.1
|
||||
@@ -5819,7 +5886,7 @@ snapshots:
|
||||
|
||||
'@tempfix/idb@8.0.3': {}
|
||||
|
||||
'@tempfix/lenis@1.3.17': {}
|
||||
'@tempfix/lenis@1.3.20': {}
|
||||
|
||||
'@tokenizer/inflate@0.4.1':
|
||||
dependencies:
|
||||
@@ -6298,6 +6365,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
croner@10.0.1: {}
|
||||
|
||||
croner@9.1.0: {}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
|
||||
63
readme.md
63
readme.md
@@ -72,11 +72,12 @@ The singleton `cssManager` is the central hub for theming and responsive layout:
|
||||
|---|---|
|
||||
| `cssManager.defaultStyles` | Base styles for consistent element rendering |
|
||||
| `cssManager.bdTheme(bright, dark)` | Returns a `CSSResult` that auto-switches between bright/dark values |
|
||||
| `cssManager.cssForDesktop(css)` | Media-query wrapper for desktop breakpoints |
|
||||
| `cssManager.cssForNotebook(css)` | Media-query wrapper for notebook breakpoints |
|
||||
| `cssManager.cssForTablet(css)` | Media-query wrapper for tablet breakpoints |
|
||||
| `cssManager.cssForPhablet(css)` | Media-query wrapper for phablet breakpoints |
|
||||
| `cssManager.cssForPhone(css)` | Media-query wrapper for phone breakpoints |
|
||||
| `cssManager.cssForDesktop(css, this?)` | Breakpoint for desktop; pass `this` for component-scoped |
|
||||
| `cssManager.cssForNotebook(css, this?)` | Breakpoint for notebook; pass `this` for component-scoped |
|
||||
| `cssManager.cssForTablet(css, this?)` | Breakpoint for tablet; pass `this` for component-scoped |
|
||||
| `cssManager.cssForPhablet(css, this?)` | Breakpoint for phablet; pass `this` for component-scoped |
|
||||
| `cssManager.cssForPhone(css, this?)` | Breakpoint for phone; pass `this` for component-scoped |
|
||||
| `cssManager.cssForConstraint({ maxWidth, minWidth })` | Custom viewport-level constraint (curried) |
|
||||
| `cssManager.cssGridColumns(cols, gap)` | Generates CSS grid column widths |
|
||||
|
||||
Example — responsive + themed styles:
|
||||
@@ -106,6 +107,57 @@ class MyCard extends DeesElement {
|
||||
}
|
||||
```
|
||||
|
||||
### 📦 Container-Responsive Components
|
||||
|
||||
For components that need to respond to their **own width** (not the viewport), use the `@containerResponsive()` decorator and pass `this` as the second argument to `cssManager.cssFor*`:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
DeesElement, customElement, html, css, cssManager,
|
||||
containerResponsive,
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
@containerResponsive()
|
||||
@customElement('my-stats-grid')
|
||||
class MyStatsGrid extends DeesElement {
|
||||
static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }`,
|
||||
|
||||
// Component-level: when THIS element is narrower than tablet width
|
||||
cssManager.cssForTablet(css`
|
||||
.grid { grid-template-columns: repeat(2, 1fr); }
|
||||
`, this),
|
||||
|
||||
// Viewport-level: when the browser window is phone-sized
|
||||
cssManager.cssForPhone(css`
|
||||
.grid { grid-template-columns: 1fr; }
|
||||
`),
|
||||
|
||||
// Component-level with custom width constraint
|
||||
this.cssForConstraint({ maxWidth: 500 })(css`
|
||||
.grid { gap: 8px; }
|
||||
`),
|
||||
];
|
||||
|
||||
render() {
|
||||
return html`<div class="grid"><slot></slot></div>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
|
||||
| API | Scope | Generated CSS |
|
||||
|-----|-------|---------------|
|
||||
| `cssManager.cssForPhablet(css)` | Viewport | `@media` + `@container wccToolsViewport` |
|
||||
| `cssManager.cssForPhablet(css, this)` | Component | `@container <tag-name>` only |
|
||||
| `cssManager.cssForConstraint({maxWidth:800})(css)` | Viewport | `@media` + `@container wccToolsViewport` |
|
||||
| `this.cssForConstraint({maxWidth:500})(css)` | Component | `@container <tag-name>` only |
|
||||
| `@containerResponsive()` | Decorator | Sets `container-type: inline-size` + `container-name` on `:host` |
|
||||
|
||||
The `@containerResponsive()` decorator is required for component-scoped queries — it establishes the CSS containment context on `:host`.
|
||||
|
||||
### ⚡ Reactive Properties & State
|
||||
|
||||
Use the standard Lit decorators, re-exported for convenience:
|
||||
@@ -255,6 +307,7 @@ The directives namespace also re-exports these commonly used Lit directives:
|
||||
| `unsafeHTML` | Render raw HTML in templates |
|
||||
| `render` | Lit render function |
|
||||
| `static` / `unsafeStatic` | Static html template helpers |
|
||||
| `containerResponsive` | Decorator that adds CSS containment to `:host` |
|
||||
| `domtools` | DOM tooling utilities |
|
||||
| `directives` | All directives (resolve, subscribe, etc.) |
|
||||
| `rxjs` (type) | RxJS type re-export |
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@design.estate/dees-element',
|
||||
version: '2.1.6',
|
||||
version: '2.2.3',
|
||||
description: 'A library for creating custom elements extending the lit element class with additional functionalities.'
|
||||
}
|
||||
|
||||
@@ -47,26 +47,60 @@ export class CssManager {
|
||||
return domtools.elementBasic.staticStyles;
|
||||
}
|
||||
|
||||
public cssForDesktop(contentArg: CSSResult) {
|
||||
private getContainerNameFromClass(elementClass: { is?: string; name: string }): string {
|
||||
return elementClass.is || elementClass.name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
|
||||
public cssForDesktop(contentArg: CSSResult, elementClass?: { is?: string; name: string }) {
|
||||
if (elementClass) {
|
||||
return unsafeCSS(domtools.breakpoints.cssForContainer(
|
||||
contentArg, `(min-width: ${domtools.breakpoints.desktop}px)`, this.getContainerNameFromClass(elementClass),
|
||||
));
|
||||
}
|
||||
return unsafeCSS(domtools.breakpoints.cssForDesktop(contentArg));
|
||||
}
|
||||
|
||||
public cssForNotebook(contentArg: CSSResult) {
|
||||
public cssForNotebook(contentArg: CSSResult, elementClass?: { is?: string; name: string }) {
|
||||
if (elementClass) {
|
||||
return unsafeCSS(domtools.breakpoints.cssForContainer(
|
||||
contentArg, `(max-width: ${domtools.breakpoints.notebook}px)`, this.getContainerNameFromClass(elementClass),
|
||||
));
|
||||
}
|
||||
return unsafeCSS(domtools.breakpoints.cssForNotebook(contentArg));
|
||||
}
|
||||
|
||||
public cssForTablet(contentArg: CSSResult) {
|
||||
public cssForTablet(contentArg: CSSResult, elementClass?: { is?: string; name: string }) {
|
||||
if (elementClass) {
|
||||
return unsafeCSS(domtools.breakpoints.cssForContainer(
|
||||
contentArg, `(max-width: ${domtools.breakpoints.tablet}px)`, this.getContainerNameFromClass(elementClass),
|
||||
));
|
||||
}
|
||||
return unsafeCSS(domtools.breakpoints.cssForTablet(contentArg));
|
||||
}
|
||||
|
||||
public cssForPhablet(contentArg: CSSResult) {
|
||||
public cssForPhablet(contentArg: CSSResult, elementClass?: { is?: string; name: string }) {
|
||||
if (elementClass) {
|
||||
return unsafeCSS(domtools.breakpoints.cssForContainer(
|
||||
contentArg, `(max-width: ${domtools.breakpoints.phablet}px)`, this.getContainerNameFromClass(elementClass),
|
||||
));
|
||||
}
|
||||
return unsafeCSS(domtools.breakpoints.cssForPhablet(contentArg));
|
||||
}
|
||||
|
||||
public cssForPhone(contentArg: CSSResult) {
|
||||
public cssForPhone(contentArg: CSSResult, elementClass?: { is?: string; name: string }) {
|
||||
if (elementClass) {
|
||||
return unsafeCSS(domtools.breakpoints.cssForContainer(
|
||||
contentArg, `(max-width: ${domtools.breakpoints.phone}px)`, this.getContainerNameFromClass(elementClass),
|
||||
));
|
||||
}
|
||||
return unsafeCSS(domtools.breakpoints.cssForPhone(contentArg));
|
||||
}
|
||||
|
||||
public cssForConstraint(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
return (contentArg: CSSResult) =>
|
||||
unsafeCSS(domtools.breakpoints.cssForConstraint(constraints)(contentArg));
|
||||
}
|
||||
|
||||
public bdTheme(brightValueArg: string, darkValueArg: string): CSSResult {
|
||||
let returnCssVar: string;
|
||||
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import { type CSSResult } from 'lit';
|
||||
|
||||
export class DeesElement extends plugins.lit.LitElement {
|
||||
// STATIC — component-level constraint helper (use in `static styles = [...]`)
|
||||
|
||||
private static getContainerName(): string {
|
||||
return (this as any).is || this.name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
|
||||
static cssForConstraint(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
return (cssArg: CSSResult) =>
|
||||
plugins.domtools.breakpoints.cssForConstraintContainer(constraints, this.getContainerName())(cssArg);
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
@plugins.lit.property({ type: Boolean })
|
||||
public accessor goBright: boolean = false;
|
||||
|
||||
47
ts/decorators.containerresponsive.ts
Normal file
47
ts/decorators.containerresponsive.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { unsafeCSS, type CSSResult } from 'lit';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
|
||||
const camelToKebab = (name: string) =>
|
||||
name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
export function containerResponsive() {
|
||||
return function (target: any) {
|
||||
const tagName: string =
|
||||
target.is || target.name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
// If .is differs from the regex-derived name, cssManager.cssFor*(css, this)
|
||||
// in static styles (evaluated before decorators) used the wrong container name.
|
||||
// Fix those stale references now.
|
||||
const derivedName = target.name ? camelToKebab(target.name) : null;
|
||||
if (derivedName && derivedName !== tagName) {
|
||||
const fixStyle = (style: CSSResult) => {
|
||||
if (style && style.cssText && style.cssText.includes(`@container ${derivedName}`)) {
|
||||
return unsafeCSS(
|
||||
style.cssText.replaceAll(`@container ${derivedName}`, `@container ${tagName}`)
|
||||
);
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
const original = target.styles;
|
||||
if (Array.isArray(original)) {
|
||||
target.styles = original.map(fixStyle);
|
||||
} else if (original) {
|
||||
target.styles = fixStyle(original);
|
||||
}
|
||||
}
|
||||
|
||||
// Append containment context styles
|
||||
const containerStyles = domtools.breakpoints.containerContextStyles(tagName);
|
||||
const current = target.styles;
|
||||
if (Array.isArray(current)) {
|
||||
target.styles = [...current, containerStyles];
|
||||
} else if (current) {
|
||||
target.styles = [current, containerStyles];
|
||||
} else {
|
||||
target.styles = [containerStyles];
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
}
|
||||
25
ts/decorators.customelement.ts
Normal file
25
ts/decorators.customelement.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { customElement as litCustomElement } from 'lit/decorators/custom-element.js';
|
||||
|
||||
const camelToKebab = (name: string) =>
|
||||
name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
export function customElement(tagName: string) {
|
||||
return (classOrTarget: any, context?: any) => {
|
||||
// Set .is so that other decorators and utilities can read the tag name
|
||||
classOrTarget.is = tagName;
|
||||
|
||||
// Warn if class name convention doesn't match the tag
|
||||
if (classOrTarget.name) {
|
||||
const derived = camelToKebab(classOrTarget.name);
|
||||
if (derived !== tagName) {
|
||||
console.warn(
|
||||
`[dees-element] Class "${classOrTarget.name}" kebab-cases to "${derived}" but tag is "${tagName}". ` +
|
||||
`Container queries use .is ("${tagName}").`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Delegate to Lit's original decorator
|
||||
return litCustomElement(tagName)(classOrTarget, context);
|
||||
};
|
||||
}
|
||||
@@ -7,7 +7,7 @@ export { html as static, unsafeStatic } from 'lit/static-html.js';
|
||||
|
||||
export { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
|
||||
export { customElement } from 'lit/decorators/custom-element.js';
|
||||
export { customElement } from './decorators.customelement.js';
|
||||
|
||||
export { property, state, query, queryAll, queryAsync } from 'lit/decorators.js';
|
||||
|
||||
@@ -18,6 +18,9 @@ export { domtools };
|
||||
// DeesElements exports
|
||||
export * from './classes.dees-element.js';
|
||||
|
||||
// decorator exports
|
||||
export { containerResponsive } from './decorators.containerresponsive.js';
|
||||
|
||||
// directives exports
|
||||
import * as directives from './directives/index.js';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user