fix(dees-element): rename cssForCustom to cssForConstraint, remove DeesElement static cssFor* helpers, and add optional elementClass parameter to cssManager breakpoint helpers
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@types/node": "^25.0.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@design.estate/dees-domtools": "^2.4.0",
|
||||
"@design.estate/dees-domtools": "^2.5.1",
|
||||
"@push.rocks/isounique": "^1.0.5",
|
||||
"@push.rocks/smartrx": "^3.0.10",
|
||||
"lit": "^3.3.2"
|
||||
|
||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools':
|
||||
specifier: ^2.4.0
|
||||
version: 2.4.0
|
||||
specifier: ^2.5.1
|
||||
version: 2.5.1
|
||||
'@push.rocks/isounique':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5
|
||||
@@ -246,8 +246,8 @@ packages:
|
||||
'@design.estate/dees-comms@1.0.30':
|
||||
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
|
||||
|
||||
'@design.estate/dees-domtools@2.4.0':
|
||||
resolution: {integrity: sha512-CbleS20q5R8EXMtN0SMGenckrRtcLmCR+e7aslbcd0XMWwN+SWyuRqCg1p6Fr9spW+cVOCo/bhpvrwSVubTuAA==}
|
||||
'@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==}
|
||||
@@ -4063,7 +4063,7 @@ snapshots:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
broadcast-channel: 7.2.0
|
||||
|
||||
'@design.estate/dees-domtools@2.4.0':
|
||||
'@design.estate/dees-domtools@2.5.1':
|
||||
dependencies:
|
||||
'@api.global/typedrequest': 3.3.0
|
||||
'@design.estate/dees-comms': 1.0.30
|
||||
@@ -4091,7 +4091,7 @@ snapshots:
|
||||
|
||||
'@design.estate/dees-element@2.1.3':
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools': 2.4.0
|
||||
'@design.estate/dees-domtools': 2.5.1
|
||||
'@push.rocks/isounique': 1.0.5
|
||||
'@push.rocks/smartrx': 3.0.10
|
||||
lit: 3.3.2
|
||||
|
||||
34
readme.md
34
readme.md
@@ -72,12 +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.cssForCustom({ maxWidth, minWidth })` | Custom viewport-level breakpoint (curried) |
|
||||
| `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:
|
||||
@@ -109,7 +109,7 @@ class MyCard extends DeesElement {
|
||||
|
||||
### 📦 Container-Responsive Components
|
||||
|
||||
For components that need to respond to their **own width** (not the viewport), use the `@containerResponsive()` decorator together with `DeesElement`'s static `cssFor*` methods:
|
||||
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 {
|
||||
@@ -124,18 +124,18 @@ class MyStatsGrid extends DeesElement {
|
||||
cssManager.defaultStyles,
|
||||
css`.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }`,
|
||||
|
||||
// Component-level: when THIS element is narrow
|
||||
this.cssForTablet(css`
|
||||
// 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 narrow
|
||||
// Viewport-level: when the browser window is phone-sized
|
||||
cssManager.cssForPhone(css`
|
||||
.grid { grid-template-columns: 1fr; }
|
||||
`),
|
||||
|
||||
// Component-level with custom constraint
|
||||
this.cssForCustom({ maxWidth: 500 })(css`
|
||||
// Component-level with custom width constraint
|
||||
this.cssForConstraint({ maxWidth: 500 })(css`
|
||||
.grid { gap: 8px; }
|
||||
`),
|
||||
];
|
||||
@@ -151,12 +151,12 @@ class MyStatsGrid extends DeesElement {
|
||||
| API | Scope | Generated CSS |
|
||||
|-----|-------|---------------|
|
||||
| `cssManager.cssForPhablet(css)` | Viewport | `@media` + `@container wccToolsViewport` |
|
||||
| `cssManager.cssForCustom({maxWidth:800})(css)` | Viewport | `@media` + `@container wccToolsViewport` |
|
||||
| `this.cssForPhablet(css)` | Component | `@container <tag-name>` only |
|
||||
| `this.cssForCustom({maxWidth:800})(css)` | Component | `@container <tag-name>` only |
|
||||
| `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 the component-level `this.cssFor*` methods to take effect — it establishes the CSS containment context on `:host`.
|
||||
The `@containerResponsive()` decorator is required for component-scoped queries — it establishes the CSS containment context on `:host`.
|
||||
|
||||
### ⚡ Reactive Properties & State
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@design.estate/dees-element',
|
||||
version: '2.2.0',
|
||||
version: '2.2.1',
|
||||
description: 'A library for creating custom elements extending the lit element class with additional functionalities.'
|
||||
}
|
||||
|
||||
@@ -47,29 +47,58 @@ 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 cssForCustom(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
public cssForConstraint(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
return (contentArg: CSSResult) =>
|
||||
unsafeCSS(domtools.breakpoints.cssForCustom(constraints)(contentArg));
|
||||
unsafeCSS(domtools.breakpoints.cssForConstraint(constraints)(contentArg));
|
||||
}
|
||||
|
||||
public bdTheme(brightValueArg: string, darkValueArg: string): CSSResult {
|
||||
|
||||
@@ -2,45 +2,15 @@ import * as plugins from './plugins.js';
|
||||
import { type CSSResult } from 'lit';
|
||||
|
||||
export class DeesElement extends plugins.lit.LitElement {
|
||||
// STATIC — component-level responsive helpers (use in `static styles = [...]`)
|
||||
// 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 cssForDesktop(cssArg: CSSResult) {
|
||||
return plugins.domtools.breakpoints.cssForContainer(
|
||||
cssArg, `(min-width: ${plugins.domtools.breakpoints.desktop}px)`, this.getContainerName(),
|
||||
);
|
||||
}
|
||||
|
||||
static cssForNotebook(cssArg: CSSResult) {
|
||||
return plugins.domtools.breakpoints.cssForContainer(
|
||||
cssArg, `(max-width: ${plugins.domtools.breakpoints.notebook}px)`, this.getContainerName(),
|
||||
);
|
||||
}
|
||||
|
||||
static cssForTablet(cssArg: CSSResult) {
|
||||
return plugins.domtools.breakpoints.cssForContainer(
|
||||
cssArg, `(max-width: ${plugins.domtools.breakpoints.tablet}px)`, this.getContainerName(),
|
||||
);
|
||||
}
|
||||
|
||||
static cssForPhablet(cssArg: CSSResult) {
|
||||
return plugins.domtools.breakpoints.cssForContainer(
|
||||
cssArg, `(max-width: ${plugins.domtools.breakpoints.phablet}px)`, this.getContainerName(),
|
||||
);
|
||||
}
|
||||
|
||||
static cssForPhone(cssArg: CSSResult) {
|
||||
return plugins.domtools.breakpoints.cssForContainer(
|
||||
cssArg, `(max-width: ${plugins.domtools.breakpoints.phone}px)`, this.getContainerName(),
|
||||
);
|
||||
}
|
||||
|
||||
static cssForCustom(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
static cssForConstraint(constraints: { maxWidth?: number; minWidth?: number }) {
|
||||
return (cssArg: CSSResult) =>
|
||||
plugins.domtools.breakpoints.cssForCustomContainer(constraints, this.getContainerName())(cssArg);
|
||||
plugins.domtools.breakpoints.cssForConstraintContainer(constraints, this.getContainerName())(cssArg);
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
|
||||
Reference in New Issue
Block a user