@getvitops/generator 0.7.0 → 0.9.0
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 +233 -0
- package/assets/css/animation.css +12 -2
- package/assets/css/global.css +10 -0
- package/assets/css/index.css +1 -0
- package/assets/css/patterns/details.css +27 -8
- package/assets/css/patterns/drawer.css +15 -0
- package/assets/css/patterns/forms.css +31 -0
- package/assets/css/patterns/grouped.css +1 -1
- package/assets/css/patterns/popover.css +18 -1
- package/assets/css/patterns/subgrid.css +62 -16
- package/assets/css/patterns/theme-editor.css +122 -0
- package/assets/css/utilities.css +5 -3
- package/assets/js/editor.js +2 -0
- package/assets/js/elements.js +2 -2
- package/dist/index.d.mts +105 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +464 -164
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/schema.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme editor — chrome for `<wc-theme-editor>` (@getvitops/core/editor).
|
|
3
|
+
*
|
|
4
|
+
* Deliberately thin: the panel is a `.drawer.drawer--right` popover, its sections
|
|
5
|
+
* are `.details`, its controls come from `forms.css` and its buttons from the
|
|
6
|
+
* generated `btn`/`cta` patterns. What's left here is only what those don't cover
|
|
7
|
+
* — the launcher's fixed position, the label/control row, and the density the
|
|
8
|
+
* panel needs to fit a whole design system in a sidebar.
|
|
9
|
+
*
|
|
10
|
+
* This partial is imported by the bundle like any other, so a consumer who never
|
|
11
|
+
* loads the editor bundle still pays for it (~1KB) but sees nothing: every rule is
|
|
12
|
+
* scoped under `wc-theme-editor`, which only exists once the element is defined.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
wc-theme-editor {
|
|
16
|
+
/* Density: the panel packs ~200 controls, so it runs a step down from body. */
|
|
17
|
+
--_fs: var(--text-xs, 0.78rem);
|
|
18
|
+
|
|
19
|
+
.ed-launch {
|
|
20
|
+
position: fixed;
|
|
21
|
+
inset-block-end: 1rem;
|
|
22
|
+
inset-inline-end: 1rem;
|
|
23
|
+
z-index: var(--z-tier-top, 100);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.ed-panel {
|
|
27
|
+
--drawer-max-inline-size: min(28rem, 100vw);
|
|
28
|
+
|
|
29
|
+
overflow-y: auto;
|
|
30
|
+
padding: 1rem;
|
|
31
|
+
font-size: var(--_fs);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Sections: the drawer supplies the surface, so these only need separation. */
|
|
35
|
+
.ed-section {
|
|
36
|
+
border-block-start: var(--b-default);
|
|
37
|
+
padding-block-start: 0.5rem;
|
|
38
|
+
}
|
|
39
|
+
.ed-section > summary {
|
|
40
|
+
padding-block: 0.35rem;
|
|
41
|
+
gap: 0.4rem;
|
|
42
|
+
}
|
|
43
|
+
/* The pattern's icon slot is sized for body text; at panel density it needs to
|
|
44
|
+
be small enough not to outweigh the label it sits next to. */
|
|
45
|
+
.details-icon {
|
|
46
|
+
font-size: 0.75em;
|
|
47
|
+
line-height: 1;
|
|
48
|
+
opacity: 0.7;
|
|
49
|
+
}
|
|
50
|
+
.ed-sub {
|
|
51
|
+
border: var(--b-default);
|
|
52
|
+
border-radius: var(--br-default);
|
|
53
|
+
padding: 0.4rem 0.6rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* A control row: fixed-width var name, control takes the rest. */
|
|
57
|
+
.ed-row {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 0.5rem;
|
|
61
|
+
}
|
|
62
|
+
.ed-label {
|
|
63
|
+
flex: 0 0 8.5rem;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
font-family: var(--font-mono, monospace);
|
|
66
|
+
font-size: 0.9em;
|
|
67
|
+
color: var(--surface-text-x-muted);
|
|
68
|
+
text-overflow: ellipsis;
|
|
69
|
+
white-space: nowrap;
|
|
70
|
+
}
|
|
71
|
+
.ed-input {
|
|
72
|
+
flex: 1;
|
|
73
|
+
min-inline-size: 0;
|
|
74
|
+
padding: 0.3em 0.5em;
|
|
75
|
+
border: var(--b-default);
|
|
76
|
+
border-radius: var(--br-default);
|
|
77
|
+
background: var(--surface-bg);
|
|
78
|
+
color: inherit;
|
|
79
|
+
font: inherit;
|
|
80
|
+
}
|
|
81
|
+
.ed-mono {
|
|
82
|
+
font-family: var(--font-mono, monospace);
|
|
83
|
+
}
|
|
84
|
+
.ed-pair {
|
|
85
|
+
flex: 1;
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: 0.4rem;
|
|
89
|
+
min-inline-size: 0;
|
|
90
|
+
}
|
|
91
|
+
.ed-color {
|
|
92
|
+
flex: 0 0 auto;
|
|
93
|
+
--color-swatch-size: 1.8rem;
|
|
94
|
+
}
|
|
95
|
+
.ed-out {
|
|
96
|
+
flex: 0 0 4.5rem;
|
|
97
|
+
font-family: var(--font-mono, monospace);
|
|
98
|
+
font-size: 0.9em;
|
|
99
|
+
text-align: end;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Toolbar: a segmented light/dark pair plus actions. */
|
|
103
|
+
.ed-toolbar {
|
|
104
|
+
flex-wrap: wrap;
|
|
105
|
+
gap: 0.4rem;
|
|
106
|
+
position: sticky;
|
|
107
|
+
inset-block-start: 0;
|
|
108
|
+
z-index: 1;
|
|
109
|
+
padding-block: 0.5rem;
|
|
110
|
+
background: var(--surface-bg);
|
|
111
|
+
}
|
|
112
|
+
.ed-segwrap {
|
|
113
|
+
display: inline-flex;
|
|
114
|
+
}
|
|
115
|
+
.ed-seg.is-active {
|
|
116
|
+
background: var(--ui-primary-solid);
|
|
117
|
+
color: var(--ui-primary-on-solid);
|
|
118
|
+
}
|
|
119
|
+
.ed-danger {
|
|
120
|
+
color: var(--danger-text);
|
|
121
|
+
}
|
|
122
|
+
}
|
package/assets/css/utilities.css
CHANGED
|
@@ -311,13 +311,15 @@
|
|
|
311
311
|
Animate the UA-generated content box directly; interpolate-size (Layer 2)
|
|
312
312
|
lets block-size reach `auto`. Guarded — engines without ::details-content just
|
|
313
313
|
snap open (fully accessible). */
|
|
314
|
+
/* NOTE: the transition that used to live here is gone, for the same reason as in
|
|
315
|
+
patterns/details.css — in Chrome 149 *any* transition on ::details-content
|
|
316
|
+
deadlocks (content-visibility stays hidden → `auto` resolves to 0 → nothing
|
|
317
|
+
runs) and the disclosure never opens. Collapsing still works; only the motion
|
|
318
|
+
is dropped. Don't reinstate it without checking that a first click expands. */
|
|
314
319
|
@supports selector(::details-content) {
|
|
315
320
|
details::details-content {
|
|
316
321
|
overflow: clip;
|
|
317
322
|
block-size: 0;
|
|
318
|
-
transition:
|
|
319
|
-
block-size var(--reveal-duration) var(--interact-easing, ease),
|
|
320
|
-
content-visibility var(--reveal-duration) allow-discrete;
|
|
321
323
|
}
|
|
322
324
|
details[open]::details-content {
|
|
323
325
|
block-size: auto;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=`vitops:ds-overrides`,t=`/__vitops/design-system`,n=(e,t)=>t.startsWith(`stop-`)?`--color-${e}-${t.slice(5)}`:`--${e}-${t}`,r=(e,t)=>`--color-${e}-${t}`;var i=class extends HTMLElement{constructor(...e){super(...e),this.store={light:new Map,dark:new Map},this.roles=new Map,this.roleVars=new Set,this.syncers=new Set,this.scheme=`light`,this.canSave=!1}static{this.observedAttributes=[`manifest`]}connectedCallback(){this.boot()}async boot(){let e=this.getAttribute(`manifest`)??`/vitops/design-manifest.json`;try{let t=await fetch(e);if(!t.ok)throw Error(`manifest ${t.status}`);this.manifest=await t.json()}catch(t){console.warn(`[wc-theme-editor] manifest unavailable at ${e} — editor disabled`,t);return}this.styleEl=document.createElement(`style`),this.styleEl.id=`ds-overrides`,document.head.append(this.styleEl),this.hydrate(),this.render(),this.scheme=this.currentScheme(),new MutationObserver(()=>{let e=this.currentScheme();e!==this.scheme&&(this.scheme=e,this.syncers.forEach(e=>e()))}).observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`]}),this.canSave=await this.probeSave(),this.build(this.manifest)}async probeSave(){try{let e=await fetch(t);return e.ok?(await e.json()).writable===!0:!1}catch{return!1}}block(e,t){return t.size?`${e} {\n${[...t].map(([e,t])=>` ${e}: ${t};`).join(`
|
|
2
|
+
`)}\n}\n`:``}serializeCSS(){return this.block(`:root`,this.store.light)+this.block(`:root[data-brx-theme="dark"], :root[data-theme="dark"]`,this.store.dark)}render(){this.styleEl&&(this.styleEl.textContent=this.serializeCSS())}persist(){try{localStorage.setItem(e,JSON.stringify({light:[...this.store.light],dark:[...this.store.dark],roles:[...this.roles]}))}catch{}}hydrate(){try{let t=localStorage.getItem(e);if(!t)return;let n=JSON.parse(t);this.store.light=new Map(n.light??[]),this.store.dark=new Map(n.dark??[]),this.roles=new Map(n.roles??[]);for(let[e,t]of this.roles)this.markRoleVars(e,t)}catch{}}setOverride(e,t,n){let r=this.store[n];t==null||t===``?r.delete(e):r.set(e,t),this.render(),this.persist()}effective(e,t,n){return this.store[t].has(e)?this.store[t].get(e):t===`dark`&&this.store.light.has(e)?this.store.light.get(e):n}reset(){this.store.light.clear(),this.store.dark.clear(),this.roles.clear(),this.roleVars.clear(),this.render(),this.persist(),this.syncers.forEach(e=>e())}currentScheme(){let e=document.documentElement;return e.dataset.theme===`dark`||e.getAttribute(`data-brx-theme`)===`dark`?`dark`:`light`}setScheme(e){this.scheme=e,document.documentElement.dataset.theme=e,document.documentElement.style.colorScheme=`${e} only`;try{localStorage.setItem(`vitops-color-scheme`,e)}catch{}this.syncers.forEach(e=>e())}roleTokenNames(e,t,r){let i=t===`surface`?`surface`:`default`,a=e.colors.roleTokens?.[r]?.[i];if(!a)return[];let o=[];for(let e of[`light`,`dark`])for(let[r,i]of Object.entries(a[e]))o.push([n(t,r),i,e]);return o}markRoleVars(e,t){if(this.manifest)for(let[n]of this.roleTokenNames(this.manifest,e,t))this.roleVars.add(n)}remapRole(e,t,n){let r=this.roleTokenNames(e,t,n);if(r.length){this.roles.set(t,n);for(let[e,t,n]of r)this.roleVars.add(e),this.store[n].set(e,t);this.render(),this.persist()}}deepSet(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];(typeof i[t]!=`object`||i[t]==null)&&(i[t]={}),i=i[t]}i[r[r.length-1]]=n}buildPatch(e){let t={},n=[];for(let[e,n]of this.roles)this.deepSet(t,`colors.roles.${e}`,n);for(let[r,i]of this.store.light){if(this.roleVars.has(r))continue;let a=e.reverseIndex[r];a?this.deepSet(t,a,i):n.push(r)}for(let e of this.store.dark.keys())this.roleVars.has(e)||n.push(`${e} (dark)`);return{patch:t,skipped:n}}el(e,t={},n=[]){let r=document.createElement(e),i=r;for(let[e,n]of Object.entries(t))n===!0?i.setAttribute(e,``):n!==!1&&i.setAttribute(e,String(n));for(let e of n)i.append(e);return r}row(e,t,n){return this.syncers.add(n),n(),this.el(`label`,{class:`ed-row`},[this.el(`span`,{class:`ed-label`,title:e},[e.replace(/^--/,``)]),t])}textInput(e,t,n=``){let r=this.el(`input`,{type:`text`,class:`ed-input`});return r.addEventListener(`input`,()=>this.setOverride(e,r.value.trim()||null,this.scheme)),this.row(e,r,()=>{r.value=this.store[this.scheme].get(e)??``,r.placeholder=n||t})}colorInput(e,t){let n=this.el(`input`,{type:`color`,class:`ed-color`}),r=this.el(`input`,{type:`text`,class:`ed-input ed-mono`}),i=t=>this.setOverride(e,t||null,`light`);n.addEventListener(`input`,()=>{r.value=n.value,i(n.value)}),r.addEventListener(`input`,()=>{/^#[0-9a-f]{6}$/i.test(r.value)&&(n.value=r.value),i(r.value.trim())});let a=this.el(`span`,{class:`ed-pair`},[n,r]);return this.row(e,a,()=>{let i=this.store.light.get(e)??t;r.value=i,/^#[0-9a-f]{6}$/i.test(i)&&(n.value=i)})}selectInput(e,t){let n=this.el(`select`,{class:`ed-input`});n.append(this.el(`option`,{value:``},[`— default —`]));for(let e of t)n.append(this.el(`option`,{value:e.value},[e.label]));return n.addEventListener(`change`,()=>this.setOverride(e,n.value||null,this.scheme)),this.row(e,n,()=>{n.value=this.store[this.scheme].get(e)??``})}remSlider(e,t){let n=parseFloat(t)||1,r=this.el(`input`,{type:`range`,class:`ed-range`,min:`0`,max:String(Math.max(4,Math.ceil(n*2))),step:`0.05`}),i=this.el(`output`,{class:`ed-out`});r.addEventListener(`input`,()=>{i.textContent=`${r.value}rem`,this.setOverride(e,`${r.value}rem`,this.scheme)});let a=this.el(`span`,{class:`ed-pair`},[r,i]);return this.row(e,a,()=>{r.value=String(parseFloat(this.effective(e,this.scheme,t))||n),i.textContent=this.store[this.scheme].get(e)??`auto`})}slider(e,t){let n=t.toValue??(e=>`${e}${t.unit??``}`),r=t.fromValue??(e=>Number.isNaN(parseFloat(e))?t.def:parseFloat(e)),i=this.el(`input`,{type:`range`,class:`ed-range`,min:String(t.min),max:String(t.max),step:String(t.step)}),a=this.el(`output`,{class:`ed-out`});i.addEventListener(`input`,()=>{let t=n(parseFloat(i.value));a.textContent=t,this.setOverride(e,t,this.scheme)});let o=this.el(`span`,{class:`ed-pair`},[i,a]);return this.row(e,o,()=>{let n=this.store[this.scheme].get(e);i.value=String(n==null?t.def:r(n)),a.textContent=n??`${t.def}${t.unit??``}`})}section(e,t=!1){let n=this.el(`div`,{class:`ed-body rhythm`});return{details:this.el(`details`,{class:`details details--marker-start ed-section`,...t?{open:!0}:{}},[this.el(`summary`,{class:`font-eyebrow`},[this.el(`span`,{class:`details-icon`,"aria-hidden":`true`},[`▸`]),e]),n]),body:n}}hint(e){return this.el(`p`,{class:`font-footnote text-surface-x-muted`},[e])}sub(e){let t=this.section(e);return t.details.classList.add(`ed-sub`),t}buildPalette(e){let{details:t,body:n}=this.section(`Palette`,!0);n.append(this.hint(`Hues feed the semantic roles below — edit a hue and every role mapped to it follows. Hue edits are scheme-global: dark mode re-points which step a token reads, it never redefines the hue itself.`));for(let t of e.colors.ramps){let i=this.sub(t);for(let n of e.colors.steps){let a=e.colors.palette[t]?.[n];a!=null&&i.body.append(this.colorInput(r(t,n),a))}n.append(i.details)}return n.append(this.buildRoles(e)),t}buildRoles(e){let{details:t,body:n}=this.sub(`Semantic roles`);n.append(this.hint(`Point a role at another hue — its whole functional token set (bg / border / solid / on-solid / text) is rewritten for both appearances.`));let r=e.colors.ramps;for(let{name:t,ramp:i}of e.colors.roles){let a=this.el(`select`,{class:`ed-input`});for(let e of r)a.append(this.el(`option`,{value:e},[e]));a.addEventListener(`change`,()=>this.remapRole(e,t,a.value)),n.append(this.row(`--${t}`,a,()=>{a.value=this.roles.get(t)??i}))}return t}buildTypography(e){let{details:t,body:n}=this.section(`Typography`),r=Object.keys(e.fonts).map(e=>({label:e,value:`var(--font-${e})`})),i=e.scales.text.map(e=>({label:e.name,value:`var(--text-${e.name})`})),a={tt:[`none`,`uppercase`,`lowercase`,`capitalize`],fst:[`normal`,`italic`,`oblique`],td:[`none`,`underline`,`line-through`],tw:[`wrap`,`balance`,`pretty`,`nowrap`]};for(let t of e.typography.roles){let o=e.typography.specs[t]??{},s=this.sub(t);for(let[n,{key:c}]of Object.entries(e.typography.hooks)){let e=`--${t}-${n}`,l=o[c]==null?``:String(o[c]);n===`ff`?s.body.append(this.selectInput(e,r)):n===`fs`?s.body.append(this.selectInput(e,i)):a[n]?s.body.append(this.selectInput(e,a[n].map(e=>({label:e,value:e})))):s.body.append(this.textInput(e,l,l||c))}n.append(s.details)}return t}buildSpacing(e){let{details:t,body:n}=this.section(`Spacing`);n.append(this.hint(`Each step overrides to a fixed rem (dropping the fluid clamp). Reset restores it.`));for(let t of e.scales.space)n.append(this.remSlider(`--space-${t.name}`,t.max));return t}buildLayout(){let{details:e,body:t}=this.section(`Layout`);return t.append(this.hint(`Vertical rhythm and the .centered track widths — global structure.`)),t.append(this.slider(`--rhythm-scale`,{min:.5,max:2.5,step:.05,def:1}),this.slider(`--width-measure`,{min:30,max:110,step:1,def:65,unit:`ch`}),this.slider(`--width-breakout`,{min:40,max:150,step:1,def:90,unit:`ch`}),this.slider(`--width-spotlight`,{min:60,max:200,step:1,def:120,unit:`ch`}),this.slider(`--gutter`,{min:0,max:6,step:.1,def:3,toValue:e=>`clamp(1rem, 4cqi, ${e}rem)`,fromValue:e=>{let t=/clamp\([^,]+,[^,]+,\s*([\d.]+)/.exec(e);return t?parseFloat(t[1]):3}})),e}buildPatterns(e){let t=this.section(`Pattern defaults`);for(let[n,r]of Object.entries(e.patterns.defaults))t.body.append(this.textInput(`--${n}-default`,r,r));let n=this.section(`Radii`);for(let[t,r]of Object.entries(e.patterns.radii))n.body.append(this.textInput(`--br-${t}`,r,r));let r=this.section(`Pattern groups`);for(let[t,n]of Object.entries(e.patterns.groups)){let e=this.sub(t);for(let[r,i]of Object.entries(n))e.body.append(this.textInput(`--${r}-${t}`,i,i));r.body.append(e.details)}let i=this.section(`Components`);i.body.append(this.hint(`Per-component geometry — overrides the group defaults for just this component.`));for(let t of e.patterns.items){if(!t.wrappable.length)continue;let e=this.sub(t.name);for(let{sfx:n,prop:r}of t.wrappable){let i=t.base[r]??``;e.body.append(this.textInput(`--${n}-${t.name}`,i,i))}i.body.append(e.details)}let a=this.section(`Shadows`);for(let[t,n]of Object.entries(e.shadows))a.body.append(this.textInput(`--shadow-${t}`,n,n));return[t.details,n.details,r.details,i.details,a.details]}async flash(e,t){let n=e.textContent;e.textContent=t,setTimeout(()=>e.textContent=n,1400)}async copy(e,t){try{await navigator.clipboard.writeText(e),this.flash(t,`Copied ✓`)}catch{this.flash(t,`Copy failed`)}}async save(e,n){let{patch:r}=this.buildPatch(e);if(!Object.keys(r).length)return void this.flash(n,`Nothing to save`);try{let e=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({patch:r})});if(!e.ok){let t=await e.json().catch(()=>({}));console.error(`[wc-theme-editor] save rejected`,t.errors??e.statusText),this.flash(n,`Rejected ✗`);return}this.reset(),this.flash(n,`Saved ✓`)}catch(e){console.error(`[wc-theme-editor] save failed`,e),this.flash(n,`Failed ✗`)}}buildToolbar(e){let t=this.el(`div`,{class:`cluster-start ed-toolbar`}),n=this.el(`button`,{type:`button`,class:`btn ed-seg`},[`Light`]),r=this.el(`button`,{type:`button`,class:`btn ed-seg`},[`Dark`]),i=()=>{n.classList.toggle(`is-active`,this.scheme===`light`),r.classList.toggle(`is-active`,this.scheme===`dark`)};this.syncers.add(i),n.addEventListener(`click`,()=>this.setScheme(`light`)),r.addEventListener(`click`,()=>this.setScheme(`dark`)),i(),t.append(this.el(`span`,{class:`ed-segwrap`,role:`group`},[n,r]));let a=this.el(`button`,{type:`button`,class:`btn`},[`Copy CSS`]);a.addEventListener(`click`,()=>this.copy(this.serializeCSS()||`/* no overrides yet */`,a));let o=this.el(`button`,{type:`button`,class:`btn`},[`Copy JSON patch`]);if(o.addEventListener(`click`,()=>{let{patch:t,skipped:n}=this.buildPatch(e),r=n.length?`\n// runtime-only (no source mapping): ${n.join(`, `)}`:``;this.copy(JSON.stringify(t,null,2)+r,o)}),t.append(a,o),this.canSave){let n=this.el(`button`,{type:`button`,class:`cta`},[`Save to source`]);n.addEventListener(`click`,()=>void this.save(e,n)),t.append(n)}let s=this.el(`button`,{type:`button`,class:`btn ed-danger`},[`Reset all`]);return s.addEventListener(`click`,()=>this.reset()),t.append(s),t}build(e){let t=`ds-editor-panel`,n=this.el(`div`,{id:t,popover:`manual`,class:`drawer drawer--right drawer--modeless ed-panel bg-surface text-surface rhythm`,"aria-label":`Design-system editor`});n.append(this.el(`header`,{class:`cluster-between`},[this.el(`strong`,{class:`font-heading`},[`Theme editor`]),(()=>{let e=this.el(`button`,{type:`button`,class:`btn`,popovertarget:t,popovertargetaction:`hide`},[`×`]);return e.setAttribute(`aria-label`,`Close editor`),e})()]),this.buildToolbar(e),this.buildPalette(e),this.buildTypography(e),this.buildSpacing(e),this.buildLayout(),...this.buildPatterns(e));let r=this.el(`button`,{type:`button`,class:`cta ed-launch`,popovertarget:t},[`🎨 Theme`]);document.addEventListener(`keydown`,e=>{e.key===`Escape`&&n.matches(`:popover-open`)&&n.hidePopover()}),this.append(r,n)}};customElements.get(`wc-theme-editor`)||customElements.define(`wc-theme-editor`,i);
|
package/assets/js/elements.js
CHANGED
|
@@ -543,7 +543,7 @@ let Tt=!1;const Et=new Y.subtle.Watcher(async()=>{Tt||(Tt=!0,queueMicrotask(()=>
|
|
|
543
543
|
>
|
|
544
544
|
<span class=${e} part="icon" aria-hidden="true"></span>
|
|
545
545
|
</button>
|
|
546
|
-
`}};customElements.get(`copy-button`)||customElements.define(`copy-button`,Nt);var Pt=class extends ${static{this.properties={autoplay:{type:Number,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=!1;#r=!1;#i=null;#a=!1;#o=null;#s=!1;init(){this.autoplay=0}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.hasAttribute(`role`)||this.setAttribute(`role`,`region`),this.hasAttribute(`aria-roledescription`)||this.setAttribute(`aria-roledescription`,`carousel`),this.#e=[...this.children].filter(e=>!e.hasAttribute(`slot`)),!(this.#e.length<2)&&(this.#n=this.classList.contains(`carousel--auto-pages`),this.#n||(this.#c(),this.#d(),this.addEventListener(`scrollsnapchange`,this.#p)),!this.autoplay&&this.hasAttribute(`autoplay`)&&(this.autoplay=Number(this.getAttribute(`autoplay`))||0),this.#s=matchMedia(`(prefers-reduced-motion: reduce)`).matches,this.autoplay>0&&(this.#y(),this.#s?(this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()):this.#m(),this.addEventListener(`pointerenter`,this.#g),this.addEventListener(`pointerleave`,this.#_),this.addEventListener(`focusin`,this.#g),this.addEventListener(`focusout`,this.#_)))}disconnectedCallback(){super.disconnectedCallback(),this.#n||(this.removeEventListener(`scrollsnapchange`,this.#p),this.#u()),this.removeEventListener(`pointerenter`,this.#g),this.removeEventListener(`pointerleave`,this.#_),this.removeEventListener(`focusin`,this.#g),this.removeEventListener(`focusout`,this.#_),this.#h(),this.#o&&=(this.#o.removeEventListener(`click`,this.#v),this.#o.hasAttribute(`slot`)||this.#o.remove(),null),this.removeAttribute(`aria-live`)}#c(){let e=[],t=[];for(let n=0;n<this.#e.length;n++){let r=this.#e[n];e.push(this.#l(r,n)),t.push(this.#l(r,n))}for(let t=e.length-1;t>=0;t--)this.prepend(e[t]);for(let e of t)this.append(e);this.#t=[...e,...t]}#l(e,t){let n=e.cloneNode(!0);n.setAttribute(`data-carousel-clone`,String(t)),n.setAttribute(`aria-hidden`,`true`);for(let e of[n,...n.querySelectorAll(`[tabindex], a, button, input, select, textarea`)])e.tabIndex=-1;return n}#u(){for(let e of this.#t)e.remove();this.#t=[]}#d(){requestAnimationFrame(()=>{let e=this.#e[0];e&&(this.style.scrollBehavior=`auto`,this.scrollLeft=e.offsetLeft-this.offsetLeft-(parseFloat(getComputedStyle(this).scrollPaddingLeft)||0)+(parseFloat(getComputedStyle(this).paddingLeft)||0),requestAnimationFrame(()=>{this.style.scrollBehavior=``}))})}#f(){this.scrollBy({left:this.clientWidth,behavior:`smooth`})}#p=e=>{if(this.#r){this.#r=!1;return}let t=e.snapTargetInline;if(!t||!t.hasAttribute(`data-carousel-clone`))return;let n=Number(t.getAttribute(`data-carousel-clone`)),r=this.#e[n];if(!r)return;let i=r.offsetLeft-t.offsetLeft;this.#r=!0,this.style.scrollBehavior=`auto`,this.scrollLeft+=i,requestAnimationFrame(()=>{this.style.scrollBehavior=``})};#m(){this.#i||this.autoplay<=0||(this.#a=!1,this.#i=setInterval(()=>this.#f(),this.autoplay),this.setAttribute(`aria-live`,`off`),this.#b())}#h(){this.#i&&=(clearInterval(this.#i),null)}#g=()=>{this.#h(),this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()};#_=()=>{this.#s||this.#m()};#v=()=>{this.#a?(this.#s=!1,this.#m()):this.#g()};#y(){let e=this.querySelector(`[slot="autoplay"]`);if(e)this.#o=e;else{let e=document.createElement(`button`);e.type=`button`,this.append(e),this.#o=e}this.#o.setAttribute(`part`,`autoplay`),this.#o.addEventListener(`click`,this.#v),this.#b()}#b(){this.#o&&(this.#o.setAttribute(`aria-label`,this.#a?`Play`:`Pause`),this.#o.setAttribute(`aria-pressed`,String(!this.#a)),this.#o.hasAttribute(`slot`)||(this.#o.textContent=this.#a?`▶`:`⏸`))}};customElements.get(`wc-carousel`)||customElements.define(`wc-carousel`,Pt);var Ft=class extends ${static{this.properties={breakpoint:{type:String,reflect:!0},projection:{type:Boolean,reflect:!0},singular:{type:Boolean,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=[];#r=null;#i=null;#a=null;#o=[];#s=[];#c=0;#l=!1;#u=null;#d=0;init(){this.breakpoint=`40rem`,this.projection=!1,this.singular=!1}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.#f(),this.#e.length!==0&&(this.#m(),this.projection&&(this.#p(),this.#h(),this.#g(),this.singular&&(this.classList.add(`entries--singular`),this.#v(0))),this.#d=this.#b(),this.#x())}disconnectedCallback(){super.disconnectedCallback(),this.#u?.disconnect(),this.#u=null,this.#a?.remove(),this.#a=null,this.#o=[],this.#i?this.#i.remove():this.#r?.remove(),this.#r=null,this.#i=null,this.#s=[],this.classList.remove(`entries--wide`,`entries--projection`,`entries--singular`)}#f(){this.#e=[];let e=new Set,t=new Map,n=null;for(let r of this.children){let i=r.tagName.toLowerCase();if(/^h[1-6]$/.test(i))n=r;else if(i===`dl`&&n){let i=new Map,a=r.querySelectorAll(`dt`),o=r.querySelectorAll(`dd`);for(let n=0;n<a.length;n++){let r=a[n],s=r.textContent?.trim()??``,c=o[n]?.innerHTML??``;if(s){i.set(s,c),e.add(s);let n=r.getAttribute(`data-label`);n&&!t.has(s)&&t.set(s,n)}}this.#e.push({title:n.innerHTML,heading:n,dl:r,properties:i}),n=null}}this.#t=[...e],this.#n=this.#t.map(e=>t.get(e)??e)}#p(){this.classList.add(`entries--projection`)}#m(){let e=document.createElement(`table`);e.classList.add(`entries__table`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElement(`thead`),n=document.createElement(`tr`),r=document.createElement(`th`);r.textContent=``,n.appendChild(r),this.#s=[];for(let e of this.#t){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t),this.#s.push(t)}t.appendChild(n),e.appendChild(t);let i=document.createElement(`tbody`);for(let e of this.#e){let t=document.createElement(`tr`),n=document.createElement(`td`);n.innerHTML=e.title,n.style.fontWeight=`600`,t.appendChild(n);for(let n of this.#t){let r=document.createElement(`td`);r.innerHTML=e.properties.get(n)??``,t.appendChild(r)}i.appendChild(t)}e.appendChild(i),this.appendChild(e),this.#r=e}#h(){if(!this.#r)return;let e=document.createElement(`div`);e.classList.add(`entries__scroll`),this.#r.replaceWith(e),e.appendChild(this.#r),this.#i=e}#g(){let e=document.createElement(`nav`);e.classList.add(`entries__nav`),e.setAttribute(`aria-label`,`Column selector`),e.setAttribute(`aria-hidden`,`true`),this.#o=this.#t.map((t,n)=>{let r=document.createElement(`button`);return r.type=`button`,r.classList.add(`entries__nav-btn`),r.textContent=this.#n[n]??t,r.setAttribute(`aria-pressed`,String(n===0)),r.addEventListener(`click`,()=>this.#_(n)),e.appendChild(r),r}),this.#i.before(e),this.#a=e}#_(e){this.#c=e;for(let t=0;t<this.#o.length;t++)this.#o[t]?.setAttribute(`aria-pressed`,String(t===e));if(this.singular)this.#v(e);else{let t=this.#s[e];t&&this.#i&&t.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`start`})}this.dispatchEvent(new CustomEvent(`entries-column-change`,{detail:{column:e,header:this.#t[e]},bubbles:!0,composed:!0}))}#v(e){if(!this.#r)return;let t=e+1;for(let e of this.#r.rows)for(let n=1;n<e.cells.length;n++){let r=e.cells[n];r&&(r.hidden=n!==t)}}#y(){if(this.#r)for(let e of this.#r.rows)for(let t=1;t<e.cells.length;t++){let n=e.cells[t];n&&(n.hidden=!1)}}#b(){let e=this.breakpoint||`40rem`,t=document.createElement(`div`);t.style.width=e,t.style.position=`absolute`,t.style.visibility=`hidden`,this.appendChild(t);let n=t.offsetWidth;return t.remove(),n}#x(){this.#u=new ResizeObserver(this.#S),this.#u.observe(this)}#S=e=>{let t=e[0];if(!t)return;let n=t.contentBoxSize?.[0]?.inlineSize??t.contentRect.width;this.#l=n>=this.#d,this.#l?(this.classList.add(`entries--wide`),this.singular&&this.projection&&this.#y()):(this.classList.remove(`entries--wide`),this.singular&&this.projection&&this.#v(this.#c))}};customElements.get(`wc-entries`)||customElements.define(`wc-entries`,Ft);var It=class extends ${static{this.styles=[$.styles,o`
|
|
546
|
+
`}};customElements.get(`copy-button`)||customElements.define(`copy-button`,Nt);var Pt=class extends ${static{this.properties={autoplay:{type:Number,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=!1;#r=!1;#i=null;#a=!1;#o=null;#s=!1;init(){this.autoplay=0}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.hasAttribute(`role`)||this.setAttribute(`role`,`region`),this.hasAttribute(`aria-roledescription`)||this.setAttribute(`aria-roledescription`,`carousel`),this.#e=[...this.children].filter(e=>!e.hasAttribute(`slot`)),!(this.#e.length<2)&&(this.#n=this.classList.contains(`carousel--auto-pages`),this.#n||(this.#c(),this.#d(),this.addEventListener(`scrollsnapchange`,this.#p)),!this.autoplay&&this.hasAttribute(`autoplay`)&&(this.autoplay=Number(this.getAttribute(`autoplay`))||0),this.#s=matchMedia(`(prefers-reduced-motion: reduce)`).matches,this.autoplay>0&&(this.#y(),this.#s?(this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()):this.#m(),this.addEventListener(`pointerenter`,this.#g),this.addEventListener(`pointerleave`,this.#_),this.addEventListener(`focusin`,this.#g),this.addEventListener(`focusout`,this.#_)))}disconnectedCallback(){super.disconnectedCallback(),this.#n||(this.removeEventListener(`scrollsnapchange`,this.#p),this.#u()),this.removeEventListener(`pointerenter`,this.#g),this.removeEventListener(`pointerleave`,this.#_),this.removeEventListener(`focusin`,this.#g),this.removeEventListener(`focusout`,this.#_),this.#h(),this.#o&&=(this.#o.removeEventListener(`click`,this.#v),this.#o.hasAttribute(`slot`)||this.#o.remove(),null),this.removeAttribute(`aria-live`)}#c(){let e=[],t=[];for(let n=0;n<this.#e.length;n++){let r=this.#e[n];e.push(this.#l(r,n)),t.push(this.#l(r,n))}for(let t=e.length-1;t>=0;t--)this.prepend(e[t]);for(let e of t)this.append(e);this.#t=[...e,...t]}#l(e,t){let n=e.cloneNode(!0);n.setAttribute(`data-carousel-clone`,String(t)),n.setAttribute(`aria-hidden`,`true`);for(let e of[n,...n.querySelectorAll(`[tabindex], a, button, input, select, textarea`)])e.tabIndex=-1;return n}#u(){for(let e of this.#t)e.remove();this.#t=[]}#d(){requestAnimationFrame(()=>{let e=this.#e[0];e&&(this.style.scrollBehavior=`auto`,this.scrollLeft=e.offsetLeft-this.offsetLeft-(parseFloat(getComputedStyle(this).scrollPaddingLeft)||0)+(parseFloat(getComputedStyle(this).paddingLeft)||0),requestAnimationFrame(()=>{this.style.scrollBehavior=``}))})}#f(){this.scrollBy({left:this.clientWidth,behavior:`smooth`})}#p=e=>{if(this.#r){this.#r=!1;return}let t=e.snapTargetInline;if(!t||!t.hasAttribute(`data-carousel-clone`))return;let n=Number(t.getAttribute(`data-carousel-clone`)),r=this.#e[n];if(!r)return;let i=r.offsetLeft-t.offsetLeft;this.#r=!0,this.style.scrollBehavior=`auto`,this.scrollLeft+=i,requestAnimationFrame(()=>{this.style.scrollBehavior=``})};#m(){this.#i||this.autoplay<=0||(this.#a=!1,this.#i=setInterval(()=>this.#f(),this.autoplay),this.setAttribute(`aria-live`,`off`),this.#b())}#h(){this.#i&&=(clearInterval(this.#i),null)}#g=()=>{this.#h(),this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()};#_=()=>{this.#s||this.#m()};#v=()=>{this.#a?(this.#s=!1,this.#m()):this.#g()};#y(){let e=this.querySelector(`[slot="autoplay"]`);if(e)this.#o=e;else{let e=document.createElement(`button`);e.type=`button`,this.append(e),this.#o=e}this.#o.setAttribute(`part`,`autoplay`),this.#o.addEventListener(`click`,this.#v),this.#b()}#b(){this.#o&&(this.#o.setAttribute(`aria-label`,this.#a?`Play`:`Pause`),this.#o.setAttribute(`aria-pressed`,String(!this.#a)),this.#o.hasAttribute(`slot`)||(this.#o.textContent=this.#a?`▶`:`⏸`))}};customElements.get(`wc-carousel`)||customElements.define(`wc-carousel`,Pt);var Ft=class extends ${static{this.properties={breakpoint:{type:String,reflect:!0},projection:{type:Boolean,reflect:!0},singular:{type:Boolean,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=[];#r=null;#i=null;#a=null;#o=[];#s=[];#c=0;#l=!1;#u=null;#d=0;init(){this.breakpoint=`40rem`,this.projection=!1,this.singular=!1}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.#f(),this.#e.length!==0&&(this.#m(),this.projection&&(this.#p(),this.#h(),this.#g(),this.singular&&(this.classList.add(`entries--singular`),this.#v(0))),this.#d=this.#b(),this.#x())}disconnectedCallback(){super.disconnectedCallback(),this.#u?.disconnect(),this.#u=null,this.#a?.remove(),this.#a=null,this.#o=[],this.#i?this.#i.remove():this.#r?.remove(),this.#r=null,this.#i=null,this.#s=[],this.classList.remove(`entries--wide`,`entries--projection`,`entries--singular`)}#f(){this.#e=[];let e=new Set,t=new Map,n=null;for(let r of this.children){let i=r.tagName.toLowerCase();if(/^h[1-6]$/.test(i))n=r;else if(i===`dl`&&n){let i=new Map,a=r.querySelectorAll(`dt`),o=r.querySelectorAll(`dd`);for(let n=0;n<a.length;n++){let r=a[n],s=r.textContent?.trim()??``,c=o[n]?.innerHTML??``;if(s){i.set(s,c),e.add(s);let n=r.getAttribute(`data-label`);n&&!t.has(s)&&t.set(s,n)}}this.#e.push({title:n.innerHTML,heading:n,dl:r,properties:i}),n=null}}this.#t=[...e],this.#n=this.#t.map(e=>t.get(e)??e)}#p(){this.classList.add(`entries--projection`)}#m(){let e=document.createElement(`table`);e.classList.add(`entries__table`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElement(`thead`),n=document.createElement(`tr`),r=document.createElement(`th`);r.textContent=``,n.appendChild(r),this.#s=[];for(let e of this.#t){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t),this.#s.push(t)}t.appendChild(n),e.appendChild(t);let i=document.createElement(`tbody`);for(let e of this.#e){let t=document.createElement(`tr`),n=document.createElement(`td`);n.innerHTML=e.title,n.style.fontWeight=`600`,t.appendChild(n);for(let n of this.#t){let r=document.createElement(`td`);r.innerHTML=e.properties.get(n)??``,t.appendChild(r)}i.appendChild(t)}e.appendChild(i),this.appendChild(e),this.#r=e}#h(){if(!this.#r)return;let e=document.createElement(`div`);e.classList.add(`entries__scroll`),this.#r.replaceWith(e),e.appendChild(this.#r),this.#i=e}#g(){let e=document.createElement(`nav`);e.classList.add(`entries__nav`),e.setAttribute(`aria-label`,`Column selector`),e.setAttribute(`aria-hidden`,`true`),this.#o=this.#t.map((t,n)=>{let r=document.createElement(`button`);return r.type=`button`,r.classList.add(`entries__nav-btn`),r.textContent=this.#n[n]??t,r.setAttribute(`aria-pressed`,String(n===0)),r.addEventListener(`click`,()=>this.#_(n)),e.appendChild(r),r}),this.#i.before(e),this.#a=e}#_(e){this.#c=e;for(let t=0;t<this.#o.length;t++)this.#o[t]?.setAttribute(`aria-pressed`,String(t===e));if(this.singular)this.#v(e);else{let t=this.#s[e];t&&this.#i&&t.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`start`})}this.dispatchEvent(new CustomEvent(`entries-column-change`,{detail:{column:e,header:this.#t[e]},bubbles:!0,composed:!0}))}#v(e){if(!this.#r)return;let t=e+1;for(let e of this.#r.rows)for(let n=1;n<e.cells.length;n++){let r=e.cells[n];r&&(r.hidden=n!==t)}}#y(){if(this.#r)for(let e of this.#r.rows)for(let t=1;t<e.cells.length;t++){let n=e.cells[t];n&&(n.hidden=!1)}}#b(){let e=this.breakpoint||`40rem`,t=document.createElement(`div`);t.style.width=e,t.style.position=`absolute`,t.style.visibility=`hidden`,this.appendChild(t);let n=t.offsetWidth;return t.remove(),n}#x(){this.#u=new ResizeObserver(this.#S),this.#u.observe(this)}#S=e=>{let t=e[0];if(!t)return;let n=t.contentBoxSize?.[0]?.inlineSize??t.contentRect.width;this.#l=n>=this.#d,this.#l?(this.classList.add(`entries--wide`),this.singular&&this.projection&&this.#y()):(this.classList.remove(`entries--wide`),this.singular&&this.projection&&this.#v(this.#c))}};customElements.get(`wc-entries`)||customElements.define(`wc-entries`,Ft);var It=class e extends ${static{this.styles=[$.styles,o`
|
|
547
547
|
:host {
|
|
548
548
|
display: none;
|
|
549
549
|
}
|
|
@@ -641,7 +641,7 @@ let Tt=!1;const Et=new Y.subtle.Watcher(async()=>{Tt||(Tt=!0,queueMicrotask(()=>
|
|
|
641
641
|
transition: none;
|
|
642
642
|
}
|
|
643
643
|
}
|
|
644
|
-
`]}static{this.properties={scheme:{type:String,reflect:!0}}}constructor(){super(),this._mediaQuery=null,this._boundMediaHandler=null,this.init()}init(){this.scheme
|
|
644
|
+
`]}static{this.properties={scheme:{type:String,reflect:!0}}}constructor(){super(),this._mediaQuery=null,this._boundMediaHandler=null,this.init()}init(){this.scheme=e.readStored()??`system`}static{this.STORAGE_KEY=`vitops-color-scheme`}static readStored(){try{let t=localStorage.getItem(e.STORAGE_KEY);return t===`light`||t===`dark`||t===`system`?t:null}catch{return null}}_persist(){try{this.scheme===`system`?localStorage.removeItem(e.STORAGE_KEY):localStorage.setItem(e.STORAGE_KEY,this.scheme)}catch{}}connectedCallback(){super.connectedCallback(),this._mediaQuery=window.matchMedia(`(prefers-color-scheme: dark)`),this._boundMediaHandler=this._handleMediaChange.bind(this),this._mediaQuery.addEventListener(`change`,this._boundMediaHandler),this._applyColorScheme()}disconnectedCallback(){super.disconnectedCallback(),this._mediaQuery&&this._boundMediaHandler&&this._mediaQuery.removeEventListener(`change`,this._boundMediaHandler)}_handleMediaChange(e){this.scheme===`system`&&this.requestUpdate()}_applyColorScheme(){let e=document.documentElement;this.scheme===`system`?(e.style.removeProperty(`color-scheme`),delete e.dataset.theme):(e.style.colorScheme=`${this.scheme} only`,e.dataset.theme=this.scheme)}_handleSegmentClick(e){this.scheme!==e&&(this.scheme=e,this._applyColorScheme(),this._persist(),this.dispatchEvent(new CustomEvent(`scheme-change`,{detail:{scheme:this.scheme},bubbles:!0,composed:!0})))}updated(e){e.has(`scheme`)&&this._applyColorScheme()}render(){return Q`
|
|
645
645
|
<div class="toggle__group" role="group" aria-label="Color scheme" part="group">
|
|
646
646
|
<button
|
|
647
647
|
class="toggle__segment"
|
package/dist/index.d.mts
CHANGED
|
@@ -12,11 +12,11 @@ declare const DesignSystemSchema: z.ZodMiniObject<{
|
|
|
12
12
|
}, z.z.core.$strip>]>>;
|
|
13
13
|
roles: z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>;
|
|
14
14
|
utilities: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniEnum<{
|
|
15
|
-
fill: "fill";
|
|
16
15
|
bg: "bg";
|
|
17
16
|
text: "text";
|
|
18
17
|
border: "border";
|
|
19
18
|
outline: "outline";
|
|
19
|
+
fill: "fill";
|
|
20
20
|
stroke: "stroke";
|
|
21
21
|
}>>>;
|
|
22
22
|
}, z.z.core.$strip>;
|
|
@@ -102,11 +102,11 @@ declare const jsonSchema: {
|
|
|
102
102
|
}, z.z.core.$strip>]>>;
|
|
103
103
|
roles: z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>;
|
|
104
104
|
utilities: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniEnum<{
|
|
105
|
-
fill: "fill";
|
|
106
105
|
bg: "bg";
|
|
107
106
|
text: "text";
|
|
108
107
|
border: "border";
|
|
109
108
|
outline: "outline";
|
|
109
|
+
fill: "fill";
|
|
110
110
|
stroke: "stroke";
|
|
111
111
|
}>>>;
|
|
112
112
|
}, z.z.core.$strip>;
|
|
@@ -238,14 +238,43 @@ type ValidationResult = {
|
|
|
238
238
|
ok: true;
|
|
239
239
|
data: DesignSystem;
|
|
240
240
|
errors: [];
|
|
241
|
+
warnings: string[];
|
|
241
242
|
} | {
|
|
242
243
|
ok: false;
|
|
243
244
|
data: undefined;
|
|
244
245
|
errors: z.core.$ZodIssue[];
|
|
246
|
+
warnings: string[];
|
|
245
247
|
};
|
|
246
|
-
/**
|
|
248
|
+
/**
|
|
249
|
+
* Validate an unknown value against the design-system schema.
|
|
250
|
+
*
|
|
251
|
+
* `warnings` are configurations that parse and generate, but produce output that
|
|
252
|
+
* won't behave as authored — currently only the token-namespace collisions the
|
|
253
|
+
* flat `--<prop>-<name>` grammar makes possible.
|
|
254
|
+
*/
|
|
247
255
|
declare function validate(input: unknown): ValidationResult;
|
|
248
256
|
//#endregion
|
|
257
|
+
//#region src/tokens.d.ts
|
|
258
|
+
declare const NUMERIC_STEPS: readonly ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"];
|
|
259
|
+
type NumStep = (typeof NUMERIC_STEPS)[number];
|
|
260
|
+
interface ExpandedHue {
|
|
261
|
+
/** Numeric steps (sparse for fixed-tone kits). */
|
|
262
|
+
numeric: Partial<Record<NumStep, string>>;
|
|
263
|
+
/** True when only authored tones + endpoints exist (no interpolation). */
|
|
264
|
+
sparse?: boolean;
|
|
265
|
+
}
|
|
266
|
+
/** Expand every palette hue into its numeric scale. */
|
|
267
|
+
declare function expandPalette(raw: Record<string, unknown>): Record<string, ExpandedHue>;
|
|
268
|
+
interface FunctionalRole {
|
|
269
|
+
role: string;
|
|
270
|
+
hue: string;
|
|
271
|
+
/** token → CSS value, per appearance. */
|
|
272
|
+
light: Record<string, string>;
|
|
273
|
+
dark: Record<string, string>;
|
|
274
|
+
}
|
|
275
|
+
/** Resolve the functional token set for one role over its hue. */
|
|
276
|
+
declare function functionalRole(role: string, hueName: string, hue: ExpandedHue): FunctionalRole;
|
|
277
|
+
//#endregion
|
|
249
278
|
//#region src/generate.d.ts
|
|
250
279
|
type Format = 'bricks' | 'css' | 'tailwind';
|
|
251
280
|
interface GenerateOptions {
|
|
@@ -263,6 +292,34 @@ interface GenerateResult {
|
|
|
263
292
|
outDir: string;
|
|
264
293
|
written: string[];
|
|
265
294
|
}
|
|
295
|
+
interface ColorUtility {
|
|
296
|
+
/** Class name, without the leading dot. */
|
|
297
|
+
cls: string;
|
|
298
|
+
/** CSS property the class sets. */
|
|
299
|
+
prop: string;
|
|
300
|
+
/** `var(--…)` reference the class resolves to. */
|
|
301
|
+
value: string;
|
|
302
|
+
/** Which of the two axes below produced it. */
|
|
303
|
+
axis: 'plane' | 'stop';
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Every role colour utility, each class name emitted EXACTLY once.
|
|
307
|
+
*
|
|
308
|
+
* Two axes share the `<family>-<role>-<modifier>` namespace: the functional
|
|
309
|
+
* background/text/border **planes** (`--<role>-bg-muted`) and the
|
|
310
|
+
* appearance-relative emphasis **stops** (`--color-<role>-muted`). Where both
|
|
311
|
+
* would produce the same class the plane wins.
|
|
312
|
+
*
|
|
313
|
+
* That precedence used to be implicit — the css path emitted the stop matrix,
|
|
314
|
+
* then the planes, and relied on the CSS minifier dropping the shadowed
|
|
315
|
+
* earlier rule. The tailwind path never ran the stop half at all, so the two
|
|
316
|
+
* formats shipped different vocabularies (87 role classes existed in css and
|
|
317
|
+
* not in tailwind) with nothing to catch it. Deciding it here, once, is what
|
|
318
|
+
* keeps all three formats in step; `format-parity.test.ts` holds them there.
|
|
319
|
+
*
|
|
320
|
+
* Order is stops-then-planes to match the css bundle's historical rule order.
|
|
321
|
+
*/
|
|
322
|
+
declare function roleColorUtilities(roles: readonly FunctionalRole[], utilities: readonly string[]): ColorUtility[];
|
|
266
323
|
declare function generate(options: GenerateOptions): Promise<GenerateResult>;
|
|
267
324
|
//#endregion
|
|
268
325
|
//#region src/docs.d.ts
|
|
@@ -278,6 +335,46 @@ declare function generateDocs(ds: DesignSystem, assetsDir: string): Record<strin
|
|
|
278
335
|
* (`docs.ts`). Lives in its own module because `generate.ts` imports `docs.ts` —
|
|
279
336
|
* importing back the other way would be a cycle.
|
|
280
337
|
*/
|
|
338
|
+
/**
|
|
339
|
+
* Selector the dark functional-token flip hangs off.
|
|
340
|
+
*
|
|
341
|
+
* `data-brx-theme` is Bricks' own attribute — Bricks sets it, so it's what the
|
|
342
|
+
* WordPress target needs. Nothing sets it anywhere else, which meant the dark
|
|
343
|
+
* flip was unreachable outside Bricks: the shipped `<color-scheme-toggle>` web
|
|
344
|
+
* component writes `documentElement.dataset.theme` (i.e. `data-theme`), so
|
|
345
|
+
* clicking "Dark" changed an attribute no rule matched. Matching both makes the
|
|
346
|
+
* component work on every target without changing what Bricks already does.
|
|
347
|
+
*
|
|
348
|
+
* Note this covers the explicit choice only — there is deliberately no
|
|
349
|
+
* `prefers-color-scheme` block, so the toggle's "System" position currently
|
|
350
|
+
* resolves to light. Adding one would flip every existing consumer site dark for
|
|
351
|
+
* dark-OS users, which is a product decision, not a bug fix.
|
|
352
|
+
*
|
|
353
|
+
* Shared so the docs quote the selector the generator actually emits.
|
|
354
|
+
*/
|
|
355
|
+
declare const DARK_SEL = ":root[data-brx-theme=\"dark\"], :root[data-theme=\"dark\"]";
|
|
356
|
+
/**
|
|
357
|
+
* Roles the shipped CSS partials reference with NO fallback, so a config that
|
|
358
|
+
* omits one leaves those rules resolving to nothing — an invalid declaration,
|
|
359
|
+
* not a graceful degrade.
|
|
360
|
+
*
|
|
361
|
+
* `colors.roles` is an open record: any name works and generates a full token
|
|
362
|
+
* set, utilities and dark flip. But the framework's own component CSS is
|
|
363
|
+
* written against these six, so "roles are arbitrary" is only half true — they
|
|
364
|
+
* are *extensible*, over a required core. `validate()` warns when one is
|
|
365
|
+
* missing; `required-roles.test.ts` re-derives this list from the partials so
|
|
366
|
+
* it cannot drift as components are added.
|
|
367
|
+
*
|
|
368
|
+
* Kept as a constant rather than scanned at call time because `validate()` is
|
|
369
|
+
* a pure function — the CLI, the Vite plugin and `toJSONSchema` all import it,
|
|
370
|
+
* and none of them should touch the filesystem to answer "is this config ok?".
|
|
371
|
+
*/
|
|
372
|
+
declare const REQUIRED_ROLES: readonly string[];
|
|
373
|
+
/**
|
|
374
|
+
* The functional-token and emphasis-stop suffixes a role resolves to. Shared so
|
|
375
|
+
* the required-roles drift test greps for exactly what the generator emits.
|
|
376
|
+
*/
|
|
377
|
+
declare const ROLE_TOKEN_SUFFIXES: readonly string[];
|
|
281
378
|
/**
|
|
282
379
|
* Pattern base geometry props → per-pattern override-hook shorthand. Each hook
|
|
283
380
|
* wraps the authored value (`padding: var(--p-btn, 0.4em 0.8em)`) so a
|
|
@@ -532,11 +629,11 @@ declare const SiteConfigSchema: z.ZodMiniObject<{
|
|
|
532
629
|
}, z.z.core.$strip>]>>>;
|
|
533
630
|
roles: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
534
631
|
utilities: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniEnum<{
|
|
535
|
-
fill: "fill";
|
|
536
632
|
bg: "bg";
|
|
537
633
|
text: "text";
|
|
538
634
|
border: "border";
|
|
539
635
|
outline: "outline";
|
|
636
|
+
fill: "fill";
|
|
540
637
|
stroke: "stroke";
|
|
541
638
|
}>>>;
|
|
542
639
|
}, z.z.core.$strip>>;
|
|
@@ -644,9 +741,9 @@ declare const SiteConfigSchema: z.ZodMiniObject<{
|
|
|
644
741
|
number: "number";
|
|
645
742
|
date: "date";
|
|
646
743
|
file: "file";
|
|
744
|
+
text: "text";
|
|
647
745
|
email: "email";
|
|
648
746
|
url: "url";
|
|
649
|
-
text: "text";
|
|
650
747
|
tel: "tel";
|
|
651
748
|
password: "password";
|
|
652
749
|
textarea: "textarea";
|
|
@@ -1028,11 +1125,11 @@ declare const siteJsonSchema: {
|
|
|
1028
1125
|
}, z.z.core.$strip>]>>>;
|
|
1029
1126
|
roles: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
|
|
1030
1127
|
utilities: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniEnum<{
|
|
1031
|
-
fill: "fill";
|
|
1032
1128
|
bg: "bg";
|
|
1033
1129
|
text: "text";
|
|
1034
1130
|
border: "border";
|
|
1035
1131
|
outline: "outline";
|
|
1132
|
+
fill: "fill";
|
|
1036
1133
|
stroke: "stroke";
|
|
1037
1134
|
}>>>;
|
|
1038
1135
|
}, z.z.core.$strip>>;
|
|
@@ -1140,9 +1237,9 @@ declare const siteJsonSchema: {
|
|
|
1140
1237
|
number: "number";
|
|
1141
1238
|
date: "date";
|
|
1142
1239
|
file: "file";
|
|
1240
|
+
text: "text";
|
|
1143
1241
|
email: "email";
|
|
1144
1242
|
url: "url";
|
|
1145
|
-
text: "text";
|
|
1146
1243
|
tel: "tel";
|
|
1147
1244
|
password: "password";
|
|
1148
1245
|
textarea: "textarea";
|
|
@@ -1391,5 +1488,5 @@ declare function deepMerge(target: Record<string, unknown>, source: Record<strin
|
|
|
1391
1488
|
*/
|
|
1392
1489
|
declare function defaultConfig(): DesignSystem;
|
|
1393
1490
|
//#endregion
|
|
1394
|
-
export { BASE_HOOK, type DesignSystem, DesignSystemSchema, type Format, type GenerateOptions, type GenerateResult, SCHEMA_URL, SITE_SCHEMA_URL, type SiteConfig, SiteConfigSchema, type SiteValidationResult, TW_CLASH, type ValidationResult, deepMerge, defaultConfig, generate, generateDocs, jsonSchema, resolveSiteConfig, resolveTheme, siteJsonSchema, stripNulls, validate, validateSite };
|
|
1491
|
+
export { BASE_HOOK, type ColorUtility, DARK_SEL, type DesignSystem, DesignSystemSchema, type ExpandedHue, type Format, type FunctionalRole, type GenerateOptions, type GenerateResult, REQUIRED_ROLES, ROLE_TOKEN_SUFFIXES, SCHEMA_URL, SITE_SCHEMA_URL, type SiteConfig, SiteConfigSchema, type SiteValidationResult, TW_CLASH, type ValidationResult, deepMerge, defaultConfig, expandPalette, functionalRole, generate, generateDocs, jsonSchema, resolveSiteConfig, resolveTheme, roleColorUtilities, siteJsonSchema, stripNulls, validate, validateSite };
|
|
1395
1492
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/tokens.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":"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"}
|