origam 2.26.0 → 2.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -18,6 +18,19 @@ This project follows [Semantic Versioning](https://semver.org).
18
18
 
19
19
  ## [Unreleased]
20
20
 
21
+ ## [2.26.2] - 2026-10-15
22
+
23
+ ### Fixed — un theme sans `name` avec `mode` l'emporte sur la palette integree du meme mode (#1102)
24
+
25
+ `themeSelector({ mode: 'dark' })` emettait `[data-mode="dark"]` (0,1,0) face a `[data-mode="dark"]:not([data-theme="light"])` (0,2,0) de `dark.css` : le theme sombre sans nom perdait sur `theme=dark/mode=dark`, `mode=dark` seul et `theme=site/mode=dark` (mesure Chromium : `--origam-color__action--primary---bg` restait a `#7c3aed`). Il peignait aussi sombre sous `data-theme="light" data-mode="dark"` par egalite d'ordre source (regle #807 violee). Le selecteur est desormais `html[data-mode="…"]` (dark : `(0,2,1)`, `:not([data-theme="light"])` conserve ; light : `(0,1,1)`), independant de l'ordre d'injection, et reste sous les blocs `:root:root[data-theme]` des marques nommees. Le doc `theme.interface.ts` (« scoped to `:root` ») est corrige. Spec : `unnamed-theme-specificity.spec.ts`.
26
+
27
+ ## [2.26.1] - 2026-10-14
28
+
29
+ ### Fixed — `warnLegacyColor` : dev uniquement, et plus d'avertissement pour `var()` / `color-mix()` (#1099)
30
+
31
+ - L'avertissement « received a raw color » est desormais garde par `import.meta.env?.DEV` (meme garde que `warnUnsupportedProp`) : il ne sort plus en production et la chaine disparait d'un bundle de production (`.output` marketing : 0 occurrence).
32
+ - `bgColor="var(--brand)"` / `color="color-mix(...)"` ne sont plus traites comme une couleur brute : ce sont le chemin de migration recommande. Le rendu est inchange (canal custom / style inline). `#fff`, `rgb()` etc. avertissent toujours en dev, une fois par valeur.
33
+
21
34
  ## [2.26.0] - 2026-10-14
22
35
 
23
36
  ### Changed — `OrigamCard`, `OrigamExpansionPanel(Content)`, `OrigamDataTableRows` : le skeleton suit l'anatomie du conteneur (#1073 lot 2b, #1081, #1076)
@@ -21,8 +21,11 @@ export interface IOrigamThemeSingletonState {
21
21
  /**
22
22
  * Runtime theme object ingested by `createOrigam({ themes })`. At install time
23
23
  * the DS resolves it to a block of `--origam-*` CSS variables injected into
24
- * `<head>`, scoped to `:root` (or `[data-theme="<name>"]` when `name` is set,
25
- * optionally narrowed by `[data-mode]` when `mode` is set).
24
+ * `<head>`, scoped by `name` / `mode` (see `themeSelector`):
25
+ * no `name` and no `mode` → `:root`; no `name` but a `mode` → `html[data-mode]`
26
+ * (plus a bare `[data-mode]` twin for sub-trees), specific enough to beat the
27
+ * built-in palette of that mode and still lose to every named brand (#1102);
28
+ * a `name` → `[data-theme="<name>"]`, optionally narrowed by `[data-mode]`.
26
29
  *
27
30
  * ## A theme has exactly THREE authoring surfaces
28
31
  *
@@ -74,7 +74,11 @@ function themeSelector(theme) {
74
74
  const hasName = typeof theme.name === "string" && theme.name.length > 0;
75
75
  const hasMode = theme.mode === "light" || theme.mode === "dark";
76
76
  if (!hasName && !hasMode) return ":root";
77
- if (!hasName) return `[data-mode="${theme.mode}"]`;
77
+ if (!hasName) {
78
+ const root = theme.mode === "dark" ? 'html[data-mode="dark"]:not([data-theme="light"])' : 'html[data-mode="light"]';
79
+ const subtree = theme.mode === "dark" ? '[data-mode="dark"]:not([data-theme]):not([data-theme="light"])' : '[data-mode="light"]:not([data-theme])';
80
+ return `${root}, ${subtree}`;
81
+ }
78
82
  const modeAttr = hasMode ? `[data-mode="${theme.mode}"]` : "";
79
83
  const attrs = `[data-theme="${theme.name}"]${modeAttr}`;
80
84
  return `:root:root${attrs}, ${attrs}`;
@@ -27,7 +27,8 @@ export declare function resolveThemeVars(theme: IOrigamTheme): TThemeVars;
27
27
  * Compute the CSS selector a theme block targets, from its `name` / `mode`:
28
28
  * - neither → `:root`
29
29
  * - name only → `[data-theme="<name>"]`
30
- * - mode only → `[data-mode="<mode>"]`
30
+ * - mode only → `html[data-mode="<mode>"], [data-mode="<mode>"]:not([data-theme])`
31
+ * (dark adds `:not([data-theme="light"])`, see #1102)
31
32
  * - name + mode → `[data-theme="<name>"][data-mode="<mode>"]`
32
33
  *
33
34
  * A `mode` of `'auto'` is treated as "no mode scoping".
@@ -55,7 +55,11 @@ export function themeSelector(theme) {
55
55
  const hasName = typeof theme.name === "string" && theme.name.length > 0;
56
56
  const hasMode = theme.mode === "light" || theme.mode === "dark";
57
57
  if (!hasName && !hasMode) return ":root";
58
- if (!hasName) return `[data-mode="${theme.mode}"]`;
58
+ if (!hasName) {
59
+ const root = theme.mode === "dark" ? 'html[data-mode="dark"]:not([data-theme="light"])' : 'html[data-mode="light"]';
60
+ const subtree = theme.mode === "dark" ? '[data-mode="dark"]:not([data-theme]):not([data-theme="light"])' : '[data-mode="light"]:not([data-theme])';
61
+ return `${root}, ${subtree}`;
62
+ }
59
63
  const modeAttr = hasMode ? `[data-mode="${theme.mode}"]` : "";
60
64
  const attrs = `[data-theme="${theme.name}"]${modeAttr}`;
61
65
  return `:root:root${attrs}, ${attrs}`;
@@ -408,7 +408,9 @@ function tokenForegroundForIntent(intent) {
408
408
  }
409
409
  const _warnedColorKeys = /* @__PURE__ */new Set();
410
410
  function warnLegacyColor(kind, value) {
411
+ if (!process.env?.DEV) return;
411
412
  if (typeof console === "undefined") return;
413
+ if (/^\s*(?:var|color-mix)\(/i.test(value)) return;
412
414
  const key = `${kind}::${value}`;
413
415
  if (_warnedColorKeys.has(key)) return;
414
416
  _warnedColorKeys.add(key);
@@ -470,6 +470,13 @@ export declare function tokenForegroundForIntent(intent: TIntent): string;
470
470
  * Warn (once per prop / value) that the consumer passed a raw CSS color
471
471
  * to a prop where the design system expects a `TIntent`. Raw color
472
472
  * support is deprecated and will be removed in v3.0.0.
473
+ *
474
+ * @description
475
+ * Dev-only (`import.meta.env.DEV`, same gate as `warnUnsupportedProp`), so
476
+ * the message is tree-shaken from production bundles. `var(--x)` and
477
+ * `color-mix(...)` are NOT raw colors: they are the migration path the DS
478
+ * recommends (token reference / derived from tokens) and are rendered
479
+ * through the custom-value channel without any warning.
473
480
  ********************************************************/
474
481
  export declare function warnLegacyColor(kind: 'color' | 'bgColor', value: string): void;
475
482
  /*********************************************************
@@ -314,7 +314,9 @@ export function tokenForegroundForIntent(intent) {
314
314
  }
315
315
  const _warnedColorKeys = /* @__PURE__ */ new Set();
316
316
  export function warnLegacyColor(kind, value) {
317
+ if (!import.meta.env?.DEV) return;
317
318
  if (typeof console === "undefined") return;
319
+ if (/^\s*(?:var|color-mix)\(/i.test(value)) return;
318
320
  const key = `${kind}::${value}`;
319
321
  if (_warnedColorKeys.has(key)) return;
320
322
  _warnedColorKeys.add(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "origam",
3
- "version": "2.26.0",
3
+ "version": "2.26.2",
4
4
  "type": "module",
5
5
  "description": "origam — a Vue 3 design system with multi-theme design tokens, CSS-first components and TypeScript types.",
6
6
  "keywords": [