@webority/theme 0.68.3 → 0.70.1

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/README.md CHANGED
@@ -122,6 +122,25 @@ after the components. Dark mode is emitted under `[data-theme=dark]`, `[data-bs-
122
122
  `data-theme=auto` media query. Contrast of every brand text and surface pair is held at 4.5:1 by check-contrast.
123
123
  `_brand-signal.scss` owns brand values only; no component CSS.
124
124
 
125
+ ## Runtime brand from a product's token file (opt-in)
126
+
127
+ A product's look can be applied to the precompiled theme at runtime, which is how the hosted showcase shows
128
+ every component in a product's design language.
129
+
130
+ - `webority-theme-export <compiled.css>... --product <name> --out tokens.json` (a bin of this package) writes
131
+ the token file, format `webority-theme-tokens/1`: `{ format, product, light, dark, bootstrapDark }`, each a
132
+ map of custom property to value. It reads the product's compiled CSS, not its SCSS, because Bootstrap's rgb
133
+ triplets and subtle and emphasis mixes only exist after compilation. `light` is the top-level `:root`,
134
+ `dark` the theme's `:root[data-theme=dark]` rule, `bootstrapDark` Bootstrap's `[data-bs-theme=dark]` rule.
135
+ - `dist/webority-runtime-brand.css` (export `@webority/theme/css/runtime-brand`, source
136
+ `scss/_runtime-brand.scss`) re-points the few component rules Bootstrap compiles from `$primary` as literals
137
+ (primary buttons, nav pills, pagination, list group, progress, range thumb, mouse focus border, `.link-primary`
138
+ hover, `.table-primary`) at `--bs-primary`. It holds no colour of its own (check-theme-exports asserts it).
139
+ - Load order: the theme, then the runtime brand layer, then the token file's values on `:root`, under the dark
140
+ selectors for `dark`, and under `[data-bs-theme=dark]` for `bootstrapDark`.
141
+ - Each product serves its file at `/theme/tokens.json` with `Access-Control-Allow-Origin` for the showcase host.
142
+ - A font the token file names renders only when the page has its face: the theme's own families do.
143
+
125
144
  ## Dark mode
126
145
 
127
146
  The theme ships with two built-in dark-mode support patterns:
@@ -135,6 +135,7 @@
135
135
  "card-accent",
136
136
  "card-body",
137
137
  "card-clickable",
138
+ "card-close",
138
139
  "card-constrained",
139
140
  "card-elevated",
140
141
  "card-footer",
@@ -404,6 +405,7 @@
404
405
  "modal-dialog",
405
406
  "modal-dialog-centered",
406
407
  "modal-footer",
408
+ "ms-1",
407
409
  "ms-2",
408
410
  "ms-check",
409
411
  "ms-chips",
@@ -443,6 +445,7 @@
443
445
  "page-header-bar-bulk-count",
444
446
  "page-header-bar-crumbs",
445
447
  "page-header-bar-meta",
448
+ "page-header-bar-spacer",
446
449
  "page-header-bar-tools",
447
450
  "page-header-bar-views",
448
451
  "page-header-center",
@@ -654,6 +657,7 @@
654
657
  "tbl-empty-plain",
655
658
  "tbl-empty-text",
656
659
  "tbl-empty-title",
660
+ "text-bg-primary",
657
661
  "text-body-secondary",
658
662
  "text-break",
659
663
  "text-center",
@@ -1032,11 +1036,14 @@
1032
1036
  "wui-filter-more-panel",
1033
1037
  "wui-filter-more-trigger",
1034
1038
  "wui-filter-popover",
1035
- "wui-filter-popover-count",
1039
+ "wui-filter-popover-field",
1036
1040
  "wui-filter-popover-foot",
1037
1041
  "wui-filter-popover-grid",
1042
+ "wui-filter-popover-head",
1038
1043
  "wui-filter-popover-more",
1044
+ "wui-filter-popover-note",
1039
1045
  "wui-filter-popover-panel",
1046
+ "wui-filter-popover-title",
1040
1047
  "wui-filter-popover-trigger",
1041
1048
  "wui-flag",
1042
1049
  "wui-floating-btn",
@@ -0,0 +1 @@
1
+ .btn-primary{--bs-btn-bg: var(--bs-primary);--bs-btn-border-color: var(--bs-primary);--bs-btn-disabled-bg: var(--bs-primary);--bs-btn-disabled-border-color: var(--bs-primary);--bs-btn-focus-shadow-rgb: var(--bs-primary-rgb)}.btn-outline-primary{--bs-btn-focus-shadow-rgb: var(--bs-primary-rgb)}.nav-pills{--bs-nav-pills-link-active-bg: var(--bs-primary)}.pagination{--bs-pagination-active-bg: var(--bs-primary);--bs-pagination-active-border-color: var(--bs-primary)}.list-group{--bs-list-group-active-bg: var(--bs-primary);--bs-list-group-active-border-color: var(--bs-primary)}.progress,.progress-stacked{--bs-progress-bar-bg: var(--bs-primary)}.form-check-input:focus:not(:focus-visible):not(:checked):not([type=checkbox]:indeterminate){border-color:color-mix(in srgb, var(--bs-primary) 50%, #fff)}.form-range::-webkit-slider-thumb{background-color:var(--bs-primary)}.form-range::-webkit-slider-thumb:active{background-color:color-mix(in srgb, var(--bs-primary) 30%, #fff)}.form-range::-moz-range-thumb{background-color:var(--bs-primary)}.form-range::-moz-range-thumb:active{background-color:color-mix(in srgb, var(--bs-primary) 30%, #fff)}.link-primary:hover,.link-primary:focus{color:color-mix(in srgb, color-mix(in srgb, var(--bs-primary) 80%, #000) calc(var(--bs-link-opacity, 1) * 100%), transparent) !important;text-decoration-color:color-mix(in srgb, color-mix(in srgb, var(--bs-primary) 80%, #000) calc(var(--bs-link-underline-opacity, 1) * 100%), transparent) !important}.table-primary{--wui-table-primary-bg: color-mix(in srgb, var(--bs-primary) 20%, #fff);--bs-table-bg: var(--wui-table-primary-bg);--bs-table-border-color: color-mix(in srgb, #000 20%, var(--wui-table-primary-bg));--bs-table-striped-bg: color-mix(in srgb, #000 5%, var(--wui-table-primary-bg));--bs-table-active-bg: color-mix(in srgb, #000 10%, var(--wui-table-primary-bg));--bs-table-hover-bg: color-mix(in srgb, #000 7.5%, var(--wui-table-primary-bg))}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{readFileSync as e,writeFileSync as t}from"node:fs";var n=`webority-theme-tokens/1`,r=[`--wui-primary`,`--bs-primary`,`--bs-primary-rgb`,`--bs-link-color-rgb`,`--bs-body-font-family`];function i(e){console.error(`webority-theme-export: ${e}`),console.error(`usage: webority-theme-export <compiled.css>... --product <name> [--out <tokens.json>]`),process.exit(2)}function a(e){let t=[],n,r;for(let a=0;a<e.length;a++)e[a]===`--product`?n=e[++a]:e[a]===`--out`?r=e[++a]:e[a].startsWith(`--`)?i(`unknown option ${e[a]}`):t.push(e[a]);return t.length===0&&i(`no compiled CSS file given`),(!n||!/^[a-z0-9-]+$/.test(n))&&i(`--product must be the product's lowercase name`),{files:t,product:n,out:r}}function o(e,t){let n=[],r=0,i=null,a=0;for(let o=0;o<e.length;o++){let s=e[o];i?s===`\\`?o++:s===i&&(i=null):s===`"`||s===`'`?i=s:s===`(`||s===`[`?r++:s===`)`||s===`]`?r--:s===t&&r===0&&(n.push(e.slice(a,o)),a=o+1)}return n.push(e.slice(a)),n}function s(e){let t=[],n=0,r=null,i=0,a=-1;for(let s=0;s<e.length;s++){let l=e[s];if(r)l===`\\`?s++:l===r&&(r=null);else if(l===`"`||l===`'`)r=l;else if(l===`{`)n===0&&(a=s),n++;else if(l===`}`){if(n--,n===0){let n=e.slice(i,a).trim();n.startsWith(`@`)||t.push({selectors:o(n,`,`).map(c),body:e.slice(a+1,s)}),i=s+1}}else l===`;`&&n===0&&(i=s+1)}return t}function c(e){return e.trim().replace(/\s+/g,` `).replace(/["']/g,``)}var l=new Set([`:root`,`[data-bs-theme=light]`,`:root[data-bs-theme=light]`,`:root[data-theme=light]`]),u=new Set([`:root[data-theme=dark]`,`:root[data-bs-theme=dark]`]),d=new Set([`[data-bs-theme=dark]`]);function f(e){let t=[];for(let n of o(e,`;`)){let e=n.indexOf(`:`);if(e<0)continue;let r=n.slice(0,e).trim();r.startsWith(`--`)&&t.push([r,n.slice(e+1).trim().replace(/\s*!important$/,``)])}return t}var{files:p,product:m,out:h}=a(process.argv.slice(2)),g={},_={},v={};for(let t of p){let n=e(t,`utf8`).replace(/\/\*[\s\S]*?\*\//g,``);for(let e of s(n)){let t=t=>e.selectors.some(e=>t.has(e)),n=t(u)?_:t(d)?v:t(l)?g:null;if(n)for(let[t,r]of f(e.body))n[t]=r}}var y=r.filter(e=>!(e in g));y.length>0&&(console.error(`webority-theme-export: ${p.join(`, `)} declares no ${y.join(`, `)} on :root.`),console.error(`Pass the compiled stylesheet that carries the full theme, not a page or component bundle.`),process.exit(1));var b=e=>Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t))),x=`${JSON.stringify({format:n,product:m,light:b(g),dark:b(_),bootstrapDark:b(v)},null,2)}\n`;h?(t(h,x),process.stderr.write(`webority-theme-export: ${Object.keys(g).length} light and ${Object.keys(_).length} dark and ${Object.keys(v).length} Bootstrap dark values -> ${h}\n`)):process.stdout.write(x);export{};