@taprootio/espalier 2.16.0 → 2.17.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/custom-elements.json +10148 -10038
- package/dist/root/helpers/compute-theme-properties.js +1 -1
- package/dist/root/helpers/compute-variants.js +1 -1
- package/dist/shared/esp-element-base.js +2 -2
- package/dist/shared/theme.d.ts +96 -5
- package/dist/shared/theme.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseCssColor as y,serializeOklch as p,gamutMapToSRGB as
|
|
1
|
+
import{parseCssColor as y,serializeOklch as p,gamutMapToSRGB as B,deriveSemantic as C,deriveSemanticWithContrast as x}from"../../shared/color-engine.js";import{generateScaleProperties as I}from"../../shared/scale-engine.js";import{SEMANTIC_COLOR_NAMES as k,LIGHTNESS_KEYS as M,semanticToCSS as m}from"../../shared/theme.js";import{lightnessKeyToCSS as O}from"./lightness-key-to-css.js";import{computeVariants as L,resolveMappingSource as w}from"./compute-variants.js";function R(o){return{rootFontSize:o.rootFontSize,typeRatio:o.typeRatio,spaceRatio:o.spaceRatio,borderRadius:o.borderRadius,viewportMin:o.viewportMin,viewportMax:o.viewportMax}}function N(o,S){const d=y(o.seedColor);if(!d)return{};const n={};n["--esp-scheme"]=S,n["--esp-seed-color"]=o.seedColor;const e=L(d,o);for(const[a,t]of Object.entries(e))n[`--esp-color-${a}`]=p(B(t));for(const a of M)n[O(a)]=`${Math.round(o.lightness[a]*100)}%`;const u={text:{bg:"background",targetLc:75},dangerText:{bg:"background",targetLc:75},headings:{bg:"background",targetLc:60},headingsHover:{bg:"background",targetLc:60},link:{bg:"background",targetLc:75},linkHover:{bg:"background",targetLc:75},actionText:{bg:"actionBackground",targetLc:75},inputCaret:{bg:"layer2",targetLc:60},inputSelection:{bg:"inputSelectionBg",targetLc:60}},f=new Set,l=a=>{const t=w(a,e,o.anchors);return t||(f.has(a)||(f.add(a),console.warn(`Espalier theme: color source "${a}" cannot be resolved \u2014 falling back to the seed. Run validateTheme for the declared anchors.`)),e.primary)},g={};for(const a of k){if(u[a])continue;const t=o.semanticMappings[a],r=o.chroma[a],i=l(t.source),s=o.lightness[t.lightness],c=C(i,s,r.min,r.max);g[a]=c,n[m(a)]=p(c)}for(const a of k){const t=u[a];if(!t)continue;const r=o.semanticMappings[a],i=o.chroma[a],s=l(r.source),c=o.lightness[r.lightness],v=g[t.bg],b=x(s,c,i.min,i.max,v,t.targetLc);g[a]=b,n[m(a)]=p(b)}return Object.assign(n,I(R(o))),o.fontBody&&(n["--esp-font-body"]=o.fontBody),o.fontHeadings&&(n["--esp-font-headings"]=o.fontHeadings),o.fontBrand&&(n["--esp-font-brand"]=o.fontBrand),o.fontMonospace&&(n["--esp-font-monospace"]=o.fontMonospace),n["--esp-font-weight-body"]=o.fontWeightBody,n["--esp-font-weight-headings"]=o.fontWeightHeadings,n["--esp-font-weight-brand"]=o.fontWeightBrand,n["--esp-font-weight-monospace"]=o.fontWeightMonospace,o.pageBackgroundImage&&(n["--esp-page-background-image"]=o.pageBackgroundImage),o.pageBackgroundImageOpacity!==void 0&&(n["--esp-page-background-image-opacity"]=o.pageBackgroundImageOpacity.toString()),o.boxBackgroundImage&&(n["--esp-box-background-image"]=o.boxBackgroundImage),o.boxBackgroundImageOpacity!==void 0&&(n["--esp-box-background-image-opacity"]=o.boxBackgroundImageOpacity.toString()),o.vellumOpacity!==void 0&&(n["--esp-vellum-opacity"]=o.vellumOpacity.toString()),o.vellumBackgroundImage&&(n["--esp-vellum-background-image"]=o.vellumBackgroundImage),o.vellumBackgroundImageOpacity!==void 0&&(n["--esp-vellum-background-image-opacity"]=o.vellumBackgroundImageOpacity.toString()),n}export{N as computeThemeProperties};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{rotateHue as
|
|
1
|
+
import{parseCssColor as h,rotateHue as n}from"../../shared/color-engine.js";import{parseAnchorSource as e,resolveAnchorColor as p}from"../../shared/theme.js";const s=.6,u=.85;function y(t,c){const{angles:r,semanticHues:a,variantChroma:o}=c,l=m=>o[m]??t.c,i=Math.min(u,Math.max(s,t.l));return{primary:t,"analogous-left":{l:t.l,c:l("analogous-left"),h:n(t.h,-r.analogous)},"analogous-right":{l:t.l,c:l("analogous-right"),h:n(t.h,r.analogous)},complementary:{l:t.l,c:l("complementary"),h:n(t.h,r.complementary)},"split-complementary-left":{l:t.l,c:l("split-complementary-left"),h:n(t.h,r.complementary-r.splitComplementary)},"split-complementary-right":{l:t.l,c:l("split-complementary-right"),h:n(t.h,r.complementary+r.splitComplementary)},"triadic-left":{l:t.l,c:l("triadic-left"),h:n(t.h,r.triadic)},"triadic-right":{l:t.l,c:l("triadic-right"),h:n(t.h,-r.triadic)},danger:{l:i,c:l("danger"),h:n(a.danger,0)},success:{l:i,c:l("success"),h:n(a.success,0)},warning:{l:i,c:l("warning"),h:n(a.warning,0)}}}function S(t,c,r){const a=e(t);if(!a)return c[t]??null;const o=p(r,a);return o===null?null:h(o)}export{y as computeVariants,S as resolveMappingSource};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var p=function(f,e,t,o){var r=arguments.length,s=r<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(f,e,t,o);else for(var c=f.length-1;c>=0;c--)(a=f[c])&&(s=(r<3?a(s):r>3?a(e,t,s):a(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{css as
|
|
1
|
+
var p=function(f,e,t,o){var r=arguments.length,s=r<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(f,e,t,o);else for(var c=f.length-1;c>=0;c--)(a=f[c])&&(s=(r<3?a(s):r>3?a(e,t,s):a(e,t))||s);return r>3&&s&&Object.defineProperty(e,t,s),s};import{css as x,LitElement as U}from"lit";import{property as y,state as A}from"lit/decorators.js";import{subscribeToRootEvent as g}from"./root-event-subscription.js";import{traverseToClosest as T}from"./utilities.js";import{parseCssColor as L,serializeOklch as k,gamutMapToSRGB as O,deriveSemantic as F,deriveSemanticWithContrast as _}from"./color-engine.js";import{computeVariants as S,resolveMappingSource as z}from"../root/helpers/compute-variants.js";import{SEMANTIC_COLOR_NAMES as P,semanticToCSS as w}from"./theme.js";import{alignAttributeTextInheritance as D,focusRing as B}from"./style-fragments.js";class n extends U{constructor(){super(...arguments),this.seedColorBacker="oklch(0.7 0.125 216)",this.espRoot=null,this.variantTokenOriginalValues=new Map,this.rootEventSubscriptionsActive=!1,this.subscribedRoot=null,this.rootEventUnsubscribers=[],this.variantBacker="primary",this.correlationId=globalThis.crypto?.randomUUID?.()??Math.random().toString(36),this.scheme="light",this.handleSeedColorChanged=e=>{this.syncRootFromDom(!1)&&(this.seedColor=e.seedColor,this.applyVariantTokens())},this.handleSchemeChanged=e=>{!this.syncRootFromDom(!1)||this.scheme===e.scheme||(this.scheme=e.scheme,this.applyVariantTokens())},this.handleThemeChanged=()=>{this.syncRootFromDom(!1)&&this.applyVariantTokens()},this.handleIconSpriteUrlChanged=()=>{this.syncRootFromDom(!1)&&this.requestUpdate()}}get seedColor(){return this.seedColorBacker}set seedColor(e){this.seedColorBacker=e}focusResolvedElementAfterUpdate(e,t){const o=()=>{const r=e();return r?(r.focus(t),!0):!1};o()||this.updateComplete.then(()=>{o()})}focusShadowElementAfterUpdate(e,t){this.focusResolvedElementAfterUpdate(()=>this.shadowRoot?.querySelector(e),t)}emitValueChanged(e){this.dispatchEvent(new CustomEvent("value-changed",{detail:e,bubbles:!0,composed:!0}))}get variant(){return this.variantBacker}set variant(e){this.variantBacker=e,this.applyVariantTokens()}connectedCallback(){super.connectedCallback();const e=this.syncRootFromDom(!1);e&&this.subscribeToRootEvents(e)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromRootEvents()}firstUpdated(e){this.syncRootFromDom(!0)}syncRootFromDom(e){const t=T(this,"esp-root");if(!t){if(this.espRoot&&this.clearVariantTokens(),this.unsubscribeFromRootEvents(),this.espRoot=null,!e)return null;throw new Error("No esp-root ancestor found. Espalier components must be placed inside an <esp-root> element.")}const o=t!==this.espRoot,s=t.scheme==="dark"?"dark":"light",a=this.scheme!==s,c=this.seedColor!==t.seedColor;return this.espRoot=t,o&&this.isConnected&&this.subscribeToRootEvents(t),(o||a||c)&&(this.scheme=s,this.seedColor=t.seedColor,this.applyVariantTokens()),o&&this.requestUpdate(),t}subscribeToRootEvents(e){this.rootEventSubscriptionsActive&&this.subscribedRoot===e||(this.unsubscribeFromRootEvents(),this.subscribedRoot=e,this.rootEventUnsubscribers=[g(e,"seed-color-changed",this.handleSeedColorChanged),g(e,"scheme-changed",this.handleSchemeChanged),g(e,"theme-changed",this.handleThemeChanged),g(e,"icon-sprite-url-changed",this.handleIconSpriteUrlChanged)],this.rootEventSubscriptionsActive=!0)}unsubscribeFromRootEvents(){if(this.rootEventSubscriptionsActive){for(const e of this.rootEventUnsubscribers)e();this.rootEventUnsubscribers=[],this.subscribedRoot=null,this.rootEventSubscriptionsActive=!1}}traverseToClosest(e){return T(this,e)}applyVariantTokens(){if(!this.espRoot)return;const e=this.getVariantColorSource();if(!e){this.clearVariantTokens();return}const t=this.espRoot.activeTheme,o=L(t.seedColor);if(!o)return;const s=S(o,t)[e];if(!s){this.clearVariantTokens();return}this.setVariantTokenProperty("--esp-color-primary",k(O(s)));const a=S(s,t),c=n.statusVariantSources.has(e),{textContrast:C}=n,b={},R=i=>z(i,a,t.anchors)??a.primary;for(const i of P){if(C[i])continue;const l=t.semanticMappings[i],h=t.chroma[i],d=this.effectiveVariantTokenSource(i,l.source,c),v=R(d),m=t.lightness[l.lightness],u=F(v,m,h.min,h.max);b[i]=u,this.setVariantTokenProperty(w(i),k(u))}for(const i of P){const l=C[i];if(!l)continue;const h=t.semanticMappings[i],d=t.chroma[i],v=this.effectiveVariantTokenSource(i,h.source,c),m=R(v),u=t.lightness[h.lightness],E=b[l.bg],V=_(m,u,d.min,d.max,E,l.targetLc);b[i]=V,this.setVariantTokenProperty(w(i),k(V))}}effectiveVariantTokenSource(e,t,o){return o&&n.semanticActionTokens.has(e)?"primary":t}getVariantColorSource(){switch(this.variant){case"":case"primary":case"neutral":return"";case"info":return"complementary";default:return this.variant}}setVariantTokenProperty(e,t){const o=this.variantTokenOriginalValues.get(e);if(o){const r=this.style.getPropertyValue(e),s=this.style.getPropertyPriority(e);(r!==o.generatedValue||s!==o.generatedPriority)&&(o.originalValue=r.length?r:null,o.originalPriority=s),o.generatedValue=t,o.generatedPriority=""}else{const r=this.style.getPropertyValue(e);this.variantTokenOriginalValues.set(e,{generatedPriority:"",generatedValue:t,originalPriority:this.style.getPropertyPriority(e),originalValue:r.length?r:null})}this.style.setProperty(e,t)}clearVariantTokens(){for(const[e,t]of this.variantTokenOriginalValues){const o=this.style.getPropertyValue(e),r=this.style.getPropertyPriority(e);(o!==t.generatedValue||r!==t.generatedPriority)&&(t.originalValue=o.length?o:null,t.originalPriority=r),t.originalValue===null?this.style.removeProperty(e):this.style.setProperty(e,t.originalValue,t.originalPriority)}this.variantTokenOriginalValues.clear()}}n.textContrast={text:{bg:"background",targetLc:75},dangerText:{bg:"background",targetLc:75},headings:{bg:"background",targetLc:60},headingsHover:{bg:"background",targetLc:60},link:{bg:"background",targetLc:75},linkHover:{bg:"background",targetLc:75},actionText:{bg:"actionBackground",targetLc:75},inputCaret:{bg:"layer2",targetLc:60},inputSelection:{bg:"inputSelectionBg",targetLc:60}},n.statusVariantSources=new Set(["danger","success","warning"]),n.semanticActionTokens=new Set(["actionBackground","actionText"]),n.styles=[B(".esp-field:focus-within","--esp-field-focus-shadow"),D,x`
|
|
2
2
|
:host {
|
|
3
3
|
|
|
4
4
|
--_esp-field-resolved-hover-bg: var(
|
|
@@ -122,4 +122,4 @@ var p=function(f,e,t,o){var r=arguments.length,s=r<3?e:o===null?o=Object.getOwnP
|
|
|
122
122
|
.esp-field:has(textarea:disabled):hover {
|
|
123
123
|
background-color: var(--esp-field-background, var(--esp-color-layer-2));
|
|
124
124
|
}
|
|
125
|
-
`],p([
|
|
125
|
+
`],p([A()],n.prototype,"seedColor",null),p([y({attribute:!1})],n.prototype,"correlationId",void 0),p([y({type:String,reflect:!0})],n.prototype,"scheme",void 0),p([y({type:String,attribute:"variant",reflect:!0})],n.prototype,"variant",null);export{n as EspalierElementBase};
|
package/dist/shared/theme.d.ts
CHANGED
|
@@ -50,6 +50,79 @@ export type ColorSource = "primary" | "analogous-left" | "analogous-right" | "co
|
|
|
50
50
|
* color's chroma.
|
|
51
51
|
*/
|
|
52
52
|
export type VariantColorSource = Exclude<ColorSource, "primary">;
|
|
53
|
+
/**
|
|
54
|
+
* The object form of an anchor: a required base `color` plus named
|
|
55
|
+
* sub-slots — per-family variants the way designers already specify
|
|
56
|
+
* them (`rose.text` for the deepened rose that may carry copy).
|
|
57
|
+
*/
|
|
58
|
+
export type ThemeAnchorSlots = {
|
|
59
|
+
color: string;
|
|
60
|
+
} & Record<string, string>;
|
|
61
|
+
/**
|
|
62
|
+
* A named brand color in a **resolved** theme.
|
|
63
|
+
*
|
|
64
|
+
* Either a color string, or the slot object — which always carries its
|
|
65
|
+
* base `color`, because a partial that names only slots refines an
|
|
66
|
+
* anchor rather than replacing it. Like `seedColor`, this type states
|
|
67
|
+
* the contract `validateTheme` enforces: a theme assembled from an
|
|
68
|
+
* unvalidated partial that never declared a base color reports an error
|
|
69
|
+
* there, and degrades to the seed at runtime.
|
|
70
|
+
*
|
|
71
|
+
* Every value accepts any CSS color form (ESP0161) and is normalized to
|
|
72
|
+
* OKLCH at the merge boundary.
|
|
73
|
+
*/
|
|
74
|
+
export type ThemeAnchor = string | ThemeAnchorSlots;
|
|
75
|
+
/**
|
|
76
|
+
* A named brand color in a **partial** theme, where an object form may
|
|
77
|
+
* name slots alone — `{ rose: { hover: "#88404c" } }` refines the rose
|
|
78
|
+
* anchor a base theme already declared.
|
|
79
|
+
*/
|
|
80
|
+
export type PartialThemeAnchor = string | Record<string, string>;
|
|
81
|
+
/** Anchors as they appear in a partial theme. */
|
|
82
|
+
export type PartialThemeAnchors = Record<string, PartialThemeAnchor>;
|
|
83
|
+
/**
|
|
84
|
+
* Named brand colors, keyed by slug.
|
|
85
|
+
*
|
|
86
|
+
* Anchors are free-standing color sources for semantic mappings —
|
|
87
|
+
* `source: "anchor:<name>"` — so a multi-color brand is declared as the
|
|
88
|
+
* swatches the designer handed over instead of being bent through hue
|
|
89
|
+
* geometry and per-token chroma clamps. See ADR-015.
|
|
90
|
+
*/
|
|
91
|
+
export type ThemeAnchors = Record<string, ThemeAnchor>;
|
|
92
|
+
/**
|
|
93
|
+
* A semantic mapping's color source: a geometric or status family from
|
|
94
|
+
* {@link ColorSource}, or a declared anchor — `anchor:<name>` for its
|
|
95
|
+
* base color, `anchor:<name>.<slot>` for a sub-slot.
|
|
96
|
+
*
|
|
97
|
+
* An anchor source contributes its own hue **and chroma**; lightness
|
|
98
|
+
* always comes from the mapping's ramp stop, and APCA enforcement
|
|
99
|
+
* applies unchanged. Under an element variant, anchor sources stay
|
|
100
|
+
* absolute — a brand color is a color, not a relationship to the seed,
|
|
101
|
+
* so variant re-seeding does not rotate it.
|
|
102
|
+
*/
|
|
103
|
+
export type MappingSource = ColorSource | `anchor:${string}`;
|
|
104
|
+
/** Anchor names and slot names share one slug grammar. */
|
|
105
|
+
export declare const ANCHOR_SLUG_PATTERN: RegExp;
|
|
106
|
+
/** A parsed `anchor:` mapping source. */
|
|
107
|
+
export interface AnchorReference {
|
|
108
|
+
name: string;
|
|
109
|
+
slot?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Parse an `anchor:` mapping source into its reference, or return
|
|
113
|
+
* `null` for anything that is not anchor syntax at all. (A reference
|
|
114
|
+
* with an invalid or undeclared name parses fine here — declaration
|
|
115
|
+
* checks belong to validateTheme and resolution.)
|
|
116
|
+
*/
|
|
117
|
+
export declare function parseAnchorSource(source: string): AnchorReference | null;
|
|
118
|
+
/**
|
|
119
|
+
* Resolve an anchor reference to its declared color string.
|
|
120
|
+
*
|
|
121
|
+
* `anchor:<name>` on an object-form anchor resolves the `color` key; a
|
|
122
|
+
* slot reference into a string-form anchor has nowhere to point and
|
|
123
|
+
* resolves `null`, as do unknown names and slots.
|
|
124
|
+
*/
|
|
125
|
+
export declare function resolveAnchorColor(anchors: ThemeAnchors, reference: AnchorReference): string | null;
|
|
53
126
|
/** Every semantic color token the system computes. */
|
|
54
127
|
export type SemanticColorName = "background" | "layer1" | "layer2" | "layer3" | "layer4" | "actionBackground" | "actionText" | "border" | "shadow" | "text" | "dangerText" | "headings" | "headingsHover" | "link" | "linkHover" | "linkHoverBg" | "inputCaret" | "inputSelection" | "inputSelectionBg";
|
|
55
128
|
/** Chroma range enforced on a semantic token before gamut mapping. */
|
|
@@ -65,8 +138,11 @@ export interface ChromaRange {
|
|
|
65
138
|
* lightness ramp position sets the perceived brightness.
|
|
66
139
|
*/
|
|
67
140
|
export interface SemanticMapping {
|
|
68
|
-
/**
|
|
69
|
-
|
|
141
|
+
/**
|
|
142
|
+
* The color source to sample: a geometric/status family, or a
|
|
143
|
+
* declared anchor as `anchor:<name>` / `anchor:<name>.<slot>`.
|
|
144
|
+
*/
|
|
145
|
+
source: MappingSource;
|
|
70
146
|
/** The lightness ramp position to apply. */
|
|
71
147
|
lightness: LightnessKey;
|
|
72
148
|
}
|
|
@@ -201,6 +277,13 @@ export interface EspalierTheme {
|
|
|
201
277
|
chroma: Record<SemanticColorName, ChromaRange>;
|
|
202
278
|
/** Maps each semantic token to its color source + lightness. */
|
|
203
279
|
semanticMappings: SemanticMappings;
|
|
280
|
+
/**
|
|
281
|
+
* Named brand colors available to semantic mappings as
|
|
282
|
+
* `anchor:<name>` sources. Empty by default — a single-color brand
|
|
283
|
+
* needs none; a multi-color brand declares its swatches here instead
|
|
284
|
+
* of bending hue angles. See {@link ThemeAnchors} and ADR-015.
|
|
285
|
+
*/
|
|
286
|
+
anchors: ThemeAnchors;
|
|
204
287
|
/** Optional CSS `background-image` for the page surface. */
|
|
205
288
|
pageBackgroundImage?: string;
|
|
206
289
|
/** Opacity (0–1) for the page background image. */
|
|
@@ -216,8 +299,16 @@ export interface EspalierTheme {
|
|
|
216
299
|
/** Opacity (0–1) for the vellum background image layer. */
|
|
217
300
|
vellumBackgroundImageOpacity?: number;
|
|
218
301
|
}
|
|
219
|
-
/**
|
|
220
|
-
|
|
302
|
+
/**
|
|
303
|
+
* Recursively-partial version of {@link EspalierTheme}.
|
|
304
|
+
*
|
|
305
|
+
* `anchors` is stated explicitly rather than derived: a partial may
|
|
306
|
+
* carry slot-only anchor overrides, which the resolved
|
|
307
|
+
* {@link ThemeAnchor} deliberately does not permit.
|
|
308
|
+
*/
|
|
309
|
+
export type PartialTheme = Omit<DeepPartial<EspalierTheme>, "anchors"> & {
|
|
310
|
+
anchors?: PartialThemeAnchors;
|
|
311
|
+
};
|
|
221
312
|
/** Validation result returned by {@link validateTheme}. */
|
|
222
313
|
export interface ThemeValidationResult {
|
|
223
314
|
/** `true` when there are zero errors (warnings are allowed). */
|
|
@@ -347,7 +438,7 @@ export declare function validateTheme(base64: string): ThemeValidationResult;
|
|
|
347
438
|
* and therefore need key-by-key merging instead of wholesale
|
|
348
439
|
* replacement when combining two {@link PartialTheme} objects.
|
|
349
440
|
*/
|
|
350
|
-
export declare const NESTED_THEME_KEYS: readonly ["angles", "chroma", "lightness", "semanticHues", "semanticMappings", "variantChroma"];
|
|
441
|
+
export declare const NESTED_THEME_KEYS: readonly ["anchors", "angles", "chroma", "lightness", "semanticHues", "semanticMappings", "variantChroma"];
|
|
351
442
|
/**
|
|
352
443
|
* Deep-merge two {@link PartialTheme} objects.
|
|
353
444
|
*
|
package/dist/shared/theme.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ACCEPTED_COLOR_FORMS as v,parseCssColor as $,parseOklch as I,serializeOklch as T}from"./color-engine.js";const h=["background","layer1","layer2","layer3","layer4","actionBackground","actionText","border","shadow","text","dangerText","headings","headingsHover","link","linkHover","linkHoverBg","inputCaret","inputSelection","inputSelectionBg"],B=["primary","analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning"],R=["analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning"],d=["surface","raised1","raised2","raised3","raised4","accent","muted","text","border","ink","shadow"],w={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},A={surface:.15,raised1:.2,raised2:.3,raised3:.4,raised4:.36,accent:.6,muted:.75,text:.85,border:.7,ink:.95,shadow:.6},y={background:{source:"primary",lightness:"surface"},layer1:{source:"primary",lightness:"raised1"},layer2:{source:"primary",lightness:"raised2"},layer3:{source:"primary",lightness:"raised3"},layer4:{source:"primary",lightness:"raised4"},actionBackground:{source:"primary",lightness:"raised3"},actionText:{source:"primary",lightness:"ink"},border:{source:"primary",lightness:"border"},shadow:{source:"primary",lightness:"shadow"},text:{source:"primary",lightness:"text"},dangerText:{source:"danger",lightness:"text"},headings:{source:"primary",lightness:"muted"},headingsHover:{source:"primary",lightness:"text"},link:{source:"complementary",lightness:"accent"},linkHover:{source:"complementary",lightness:"text"},linkHoverBg:{source:"triadic-left",lightness:"raised2"},inputCaret:{source:"triadic-right",lightness:"ink"},inputSelection:{source:"complementary",lightness:"text"},inputSelectionBg:{source:"triadic-left",lightness:"raised2"}},f=.4;function b(){const i={};for(const e of h)i[e]={min:0,max:f};return i}const M={seedColor:"oklch(0.7 0.125 216)",fontBody:"",fontHeadings:"",fontBrand:"",fontMonospace:"",fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"bold",fontWeightMonospace:"normal",stylesheets:[],rootFontSize:16,typeRatio:1.25,spaceRatio:1.618,borderRadius:.2,viewportMin:320,viewportMax:1200,angles:{analogous:30,complementary:180,splitComplementary:30,triadic:120},semanticHues:{danger:27,success:150,warning:90},variantChroma:{},chroma:b(),semanticMappings:{...y}},L={...M,chroma:b(),semanticMappings:{...y},lightness:{...w}},D={...M,chroma:b(),semanticMappings:{...y},lightness:{...A}},S=new Set(["__proto__","constructor","prototype"]);function l(i){return!S.has(i)}function E(i,e){return S.has(i)?void 0:e}function U(i){return`--esp-color-${i.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function _(i){try{const e=atob(i),s=JSON.parse(e,E);return typeof s!="object"||s===null||Array.isArray(s)?null:s}catch{return null}}function k(i){return btoa(JSON.stringify(i))}function j(i){if(I(i))return i;const e=$(i);return e?T(e):i}function K(i,e){const s={...i,seedColor:typeof e.seedColor=="string"?j(e.seedColor):i.seedColor,fontBody:e.fontBody??i.fontBody,fontHeadings:e.fontHeadings??i.fontHeadings,fontBrand:e.fontBrand??i.fontBrand,fontMonospace:e.fontMonospace??i.fontMonospace,fontWeightBody:String(e.fontWeightBody??i.fontWeightBody),fontWeightHeadings:String(e.fontWeightHeadings??i.fontWeightHeadings),fontWeightBrand:String(e.fontWeightBrand??i.fontWeightBrand),fontWeightMonospace:String(e.fontWeightMonospace??i.fontWeightMonospace),stylesheets:e.stylesheets??[...i.stylesheets],rootFontSize:e.rootFontSize??i.rootFontSize,typeRatio:e.typeRatio??i.typeRatio,spaceRatio:e.spaceRatio??i.spaceRatio,borderRadius:e.borderRadius??i.borderRadius,viewportMin:e.viewportMin??i.viewportMin,viewportMax:e.viewportMax??i.viewportMax,angles:{...i.angles,...e.angles},semanticHues:{...i.semanticHues,...e.semanticHues},variantChroma:{...i.variantChroma,...e.variantChroma},lightness:{...i.lightness,...e.lightness},chroma:C(i.chroma,e.chroma),semanticMappings:C(i.semanticMappings,e.semanticMappings)};return e.pageBackgroundImage!==void 0&&(s.pageBackgroundImage=e.pageBackgroundImage),e.pageBackgroundImageOpacity!==void 0&&(s.pageBackgroundImageOpacity=e.pageBackgroundImageOpacity),e.boxBackgroundImage!==void 0&&(s.boxBackgroundImage=e.boxBackgroundImage),e.boxBackgroundImageOpacity!==void 0&&(s.boxBackgroundImageOpacity=e.boxBackgroundImageOpacity),e.vellumOpacity!==void 0&&(s.vellumOpacity=e.vellumOpacity),e.vellumBackgroundImage!==void 0&&(s.vellumBackgroundImage=e.vellumBackgroundImage),e.vellumBackgroundImageOpacity!==void 0&&(s.vellumBackgroundImageOpacity=e.vellumBackgroundImageOpacity),s}function C(i,e){if(!e)return{...i};const s={...i};for(const c of Object.keys(e)){const u=e[c];u!==void 0&&(s[c]=u)}return s}function z(i){const e=[],s=[];let c;try{c=atob(i)}catch{return e.push("Failed to decode Base64 string."),{valid:!1,errors:e,warnings:s}}let u;try{u=JSON.parse(c)}catch{return e.push("Decoded string is not valid JSON."),{valid:!1,errors:e,warnings:s}}if(typeof u!="object"||u===null||Array.isArray(u))return e.push("Theme must be a JSON object."),{valid:!1,errors:e,warnings:s};const o=u;"seedColor"in o&&(typeof o.seedColor!="string"?e.push("seedColor must be a string."):$(o.seedColor)||e.push(`seedColor is not a valid CSS color: "${o.seedColor}". Accepted forms: ${v}.`));for(const t of["fontBody","fontHeadings","fontBrand","fontMonospace"])t in o&&typeof o[t]!="string"&&e.push(`${t} must be a string.`);const g=["normal","bold","lighter","bolder"],p=["inherit","initial","unset","revert","revert-layer"];for(const t of["fontWeightBody","fontWeightHeadings","fontWeightBrand","fontWeightMonospace"])if(t in o){const n=o[t];if(typeof n=="number")(n<1||n>1e3)&&e.push(`${t} numeric value must be 1\u20131000 (got ${n}).`);else if(typeof n=="string"){const a=g.includes(n)||p.includes(n);if(/^\d+$/.test(n)){const x=Number(n);(x<1||x>1e3)&&e.push(`${t} numeric value must be 1\u20131000 (got "${n}").`)}else a||s.push(`${t} = "${n}" is not a standard font-weight value.`)}else e.push(`${t} must be a string or number.`)}"stylesheets"in o&&(Array.isArray(o.stylesheets)?o.stylesheets.some(t=>typeof t!="string")&&e.push("Every entry in stylesheets must be a string."):e.push("stylesheets must be an array of strings."));const m=[["rootFontSize",1,100],["borderRadius",0,10],["viewportMin",100,1e4],["viewportMax",200,1e4]];for(const[t,n,a]of m)if(t in o)if(typeof o[t]!="number"||!isFinite(o[t]))e.push(`${t} must be a finite number.`);else{const r=o[t];n!==void 0&&r<n&&e.push(`${t} must be \u2265 ${n} (got ${r}).`),a!==void 0&&r>a&&s.push(`${t} = ${r} is unusually high (max ${a}).`)}for(const t of["typeRatio","spaceRatio"])if(t in o)if(typeof o[t]!="number"||!isFinite(o[t]))e.push(`${t} must be a finite number.`);else{const n=o[t];n<=1&&e.push(`${t} must be > 1 (got ${n}).`);const a=t==="typeRatio"?1.3:2;n>a&&s.push(`${t} = ${n} is very high (max ${a}); scales may be extreme.`)}if("viewportMin"in o&&"viewportMax"in o){const t=o.viewportMin,n=o.viewportMax;typeof t=="number"&&typeof n=="number"&&t>=n&&e.push(`viewportMin (${t}) must be less than viewportMax (${n}).`)}if("angles"in o)if(typeof o.angles!="object"||o.angles===null)e.push("angles must be an object.");else{const t=o.angles;for(const n of["analogous","complementary","splitComplementary","triadic"])if(n in t)if(typeof t[n]!="number"||!isFinite(t[n]))e.push(`angles.${n} must be a finite number.`);else{const a=t[n];(a<0||a>360)&&s.push(`angles.${n} = ${a} is outside 0\u2013360.`)}}if("semanticHues"in o)if(typeof o.semanticHues!="object"||o.semanticHues===null)e.push("semanticHues must be an object.");else{const t=o.semanticHues;for(const n of["danger","success","warning"])if(n in t)if(typeof t[n]!="number"||!isFinite(t[n]))e.push(`semanticHues.${n} must be a finite number.`);else{const a=t[n];(a<0||a>360)&&s.push(`semanticHues.${n} = ${a} is outside 0\u2013360.`)}}if("variantChroma"in o)if(typeof o.variantChroma!="object"||o.variantChroma===null)e.push("variantChroma must be an object.");else{const t=o.variantChroma;for(const n of R)if(n in t)if(typeof t[n]!="number"||!isFinite(t[n]))e.push(`variantChroma["${n}"] must be a finite number.`);else{const a=t[n];a<0&&e.push(`variantChroma["${n}"] must be \u2265 0 (got ${a}).`),a>f&&s.push(`variantChroma["${n}"] = ${a} exceeds ${f}.`)}}if("lightness"in o)if(typeof o.lightness!="object"||o.lightness===null)e.push("lightness must be an object.");else{const t=o.lightness;for(const n of d)if(n in t)if(typeof t[n]!="number"||!isFinite(t[n]))e.push(`lightness.${n} must be a finite number.`);else{const a=t[n];(a<0||a>1)&&e.push(`lightness.${n} must be 0\u20131 (got ${a}).`)}}if("chroma"in o)if(typeof o.chroma!="object"||o.chroma===null)e.push("chroma must be an object.");else{const t=o.chroma;for(const n of h)if(n in t){const a=t[n];if(typeof a!="object"||a===null){e.push(`chroma.${n} must be { min, max }.`);continue}const r=a;(typeof r.min!="number"||r.min<0)&&e.push(`chroma.${n}.min must be \u2265 0.`),(typeof r.max!="number"||r.max<0||r.max>f)&&e.push(`chroma.${n}.max must be 0\u2013${f}.`),typeof r.min=="number"&&typeof r.max=="number"&&r.min>r.max&&e.push(`chroma.${n}.min (${r.min}) must be \u2264 max (${r.max}).`)}}if("semanticMappings"in o)if(typeof o.semanticMappings!="object"||o.semanticMappings===null)e.push("semanticMappings must be an object.");else{const t=o.semanticMappings;for(const n of h)if(n in t){const a=t[n];if(typeof a!="object"||a===null){e.push(`semanticMappings.${n} must be { source, lightness }.`);continue}const r=a;(typeof r.source!="string"||!B.includes(r.source))&&e.push(`semanticMappings.${n}.source must be one of: ${B.join(", ")}.`),(typeof r.lightness!="string"||!d.includes(r.lightness))&&e.push(`semanticMappings.${n}.lightness must be one of: ${d.join(", ")}.`)}}for(const t of["pageBackgroundImage","boxBackgroundImage","vellumBackgroundImage"])t in o&&typeof o[t]!="string"&&e.push(`${t} must be a string.`);for(const t of["pageBackgroundImageOpacity","boxBackgroundImageOpacity","vellumOpacity","vellumBackgroundImageOpacity"])if(t in o)if(typeof o[t]!="number"||!isFinite(o[t]))e.push(`${t} must be a finite number.`);else{const n=o[t];(n<0||n>1)&&e.push(`${t} must be 0\u20131 (got ${n}).`)}return{valid:e.length===0,errors:e,warnings:s}}const W=["angles","chroma","lightness","semanticHues","semanticMappings","variantChroma"];function F(i,e){const s={};for(const[c,u]of Object.entries(i))l(c)&&(s[c]=u);for(const[c,u]of Object.entries(e))u!==void 0&&l(c)&&(s[c]=u);for(const c of W){const u=i[c],o=e[c];if(u&&typeof u=="object"&&!Array.isArray(u)&&o&&typeof o=="object"&&!Array.isArray(o)){const g={};for(const[p,m]of Object.entries(u))l(p)&&(g[p]=m);for(const[p,m]of Object.entries(o))m!==void 0&&l(p)&&(g[p]=m);s[c]=g}}return s}function G(...i){let e={};for(const s of i){if(!s)continue;const c=_(s);c&&(e=F(e,c))}return k(e)}function O(i){return i.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const H={borderRadius:.1,fontBody:'"Noto Sans", sans-serif',fontWeightBody:"normal",fontHeadings:'"Inika", serif',fontWeightHeadings:"normal",fontBrand:'"Inika", serif',fontWeightBrand:"normal",fontMonospace:'"JetBrains Mono", monospace',fontWeightMonospace:"normal",seedColor:"oklch(.07 0.15 216)"};function J(i){return k({...H,pageBackgroundImage:`url("${O(i)}")`,pageBackgroundImageOpacity:.5})}function P(i){return k({...H,pageBackgroundImage:`url("${O(i)}")`,pageBackgroundImageOpacity:.55})}export{B as COLOR_SOURCES,A as DEFAULT_DARK_LIGHTNESS,D as DEFAULT_DARK_THEME,w as DEFAULT_LIGHT_LIGHTNESS,L as DEFAULT_LIGHT_THEME,y as DEFAULT_SEMANTIC_MAPPINGS,d as LIGHTNESS_KEYS,W as NESTED_THEME_KEYS,h as SEMANTIC_COLOR_NAMES,R as VARIANT_COLOR_SOURCES,P as buildTaprootDarkTheme,J as buildTaprootLightTheme,k as encodeTheme,G as layerThemes,F as mergePartials,K as mergeTheme,_ as parseTheme,U as semanticToCSS,z as validateTheme};
|
|
1
|
+
import{ACCEPTED_COLOR_FORMS as $,parseCssColor as b,parseOklch as _,serializeOklch as W}from"./color-engine.js";const A=/^[a-z][a-z0-9-]*$/,N=/^anchor:([^.]+)(?:\.(.+))?$/;function F(s){const e=N.exec(s);return e?e[2]===void 0?{name:e[1]}:{name:e[1],slot:e[2]}:null}function X(s,e){const i=s[e.name];if(i===void 0)return null;if(typeof i=="string")return e.slot===void 0?i:null;const r=i[e.slot??"color"];return typeof r=="string"?r:null}const k=["background","layer1","layer2","layer3","layer4","actionBackground","actionText","border","shadow","text","dangerText","headings","headingsHover","link","linkHover","linkHoverBg","inputCaret","inputSelection","inputSelectionBg"],x=["primary","analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning"],D=["analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning"],B=["surface","raised1","raised2","raised3","raised4","accent","muted","text","border","ink","shadow"],L={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},U={surface:.15,raised1:.2,raised2:.3,raised3:.4,raised4:.36,accent:.6,muted:.75,text:.85,border:.7,ink:.95,shadow:.6},S={background:{source:"primary",lightness:"surface"},layer1:{source:"primary",lightness:"raised1"},layer2:{source:"primary",lightness:"raised2"},layer3:{source:"primary",lightness:"raised3"},layer4:{source:"primary",lightness:"raised4"},actionBackground:{source:"primary",lightness:"raised3"},actionText:{source:"primary",lightness:"ink"},border:{source:"primary",lightness:"border"},shadow:{source:"primary",lightness:"shadow"},text:{source:"primary",lightness:"text"},dangerText:{source:"danger",lightness:"text"},headings:{source:"primary",lightness:"muted"},headingsHover:{source:"primary",lightness:"text"},link:{source:"complementary",lightness:"accent"},linkHover:{source:"complementary",lightness:"text"},linkHoverBg:{source:"triadic-left",lightness:"raised2"},inputCaret:{source:"triadic-right",lightness:"ink"},inputSelection:{source:"complementary",lightness:"text"},inputSelectionBg:{source:"triadic-left",lightness:"raised2"}},d=.4;function M(){const s={};for(const e of k)s[e]={min:0,max:d};return s}const j={seedColor:"oklch(0.7 0.125 216)",fontBody:"",fontHeadings:"",fontBrand:"",fontMonospace:"",fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"bold",fontWeightMonospace:"normal",stylesheets:[],rootFontSize:16,typeRatio:1.25,spaceRatio:1.618,borderRadius:.2,viewportMin:320,viewportMax:1200,angles:{analogous:30,complementary:180,splitComplementary:30,triadic:120},semanticHues:{danger:27,success:150,warning:90},variantChroma:{},chroma:M(),semanticMappings:{...S},anchors:{}},Z={...j,chroma:M(),semanticMappings:{...S},anchors:{},lightness:{...L}},q={...j,chroma:M(),semanticMappings:{...S},anchors:{},lightness:{...U}},H=new Set(["__proto__","constructor","prototype"]);function m(s){return!H.has(s)}function z(s,e){return H.has(s)?void 0:e}function Q(s){return`--esp-color-${s.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function K(s){try{const e=atob(s),i=JSON.parse(e,z);return typeof i!="object"||i===null||Array.isArray(i)?null:i}catch{return null}}function O(s){return btoa(JSON.stringify(s))}function C(s){if(_(s))return s;const e=b(s);return e?W(e):s}function R(s,e){const i={};for(const[r,u]of Object.entries(s))m(r)&&(i[r]=u);if(!e)return i;for(const[r,u]of Object.entries(e)){if(u===void 0||!m(r))continue;const o=i[r];if(o!==void 0&&typeof u=="object"&&u!==null){const f={};if(typeof o=="string")f.color=o;else for(const[p,g]of Object.entries(o))m(p)&&(f[p]=g);for(const[p,g]of Object.entries(u))g!==void 0&&m(p)&&(f[p]=g);i[r]=f;continue}i[r]=u}return i}function J(s){const e={};for(const[i,r]of Object.entries(s)){if(!m(i))continue;if(typeof r=="string"){e[i]=C(r);continue}const u={};for(const[o,f]of Object.entries(r))m(o)&&(u[o]=typeof f=="string"?C(f):f);e[i]=u}return e}function ee(s,e){const i={...s,seedColor:typeof e.seedColor=="string"?C(e.seedColor):s.seedColor,fontBody:e.fontBody??s.fontBody,fontHeadings:e.fontHeadings??s.fontHeadings,fontBrand:e.fontBrand??s.fontBrand,fontMonospace:e.fontMonospace??s.fontMonospace,fontWeightBody:String(e.fontWeightBody??s.fontWeightBody),fontWeightHeadings:String(e.fontWeightHeadings??s.fontWeightHeadings),fontWeightBrand:String(e.fontWeightBrand??s.fontWeightBrand),fontWeightMonospace:String(e.fontWeightMonospace??s.fontWeightMonospace),stylesheets:e.stylesheets??[...s.stylesheets],rootFontSize:e.rootFontSize??s.rootFontSize,typeRatio:e.typeRatio??s.typeRatio,spaceRatio:e.spaceRatio??s.spaceRatio,borderRadius:e.borderRadius??s.borderRadius,viewportMin:e.viewportMin??s.viewportMin,viewportMax:e.viewportMax??s.viewportMax,angles:{...s.angles,...e.angles},semanticHues:{...s.semanticHues,...e.semanticHues},variantChroma:{...s.variantChroma,...e.variantChroma},lightness:{...s.lightness,...e.lightness},chroma:T(s.chroma,e.chroma),semanticMappings:T(s.semanticMappings,e.semanticMappings),anchors:J(R(s.anchors,e.anchors))};return e.pageBackgroundImage!==void 0&&(i.pageBackgroundImage=e.pageBackgroundImage),e.pageBackgroundImageOpacity!==void 0&&(i.pageBackgroundImageOpacity=e.pageBackgroundImageOpacity),e.boxBackgroundImage!==void 0&&(i.boxBackgroundImage=e.boxBackgroundImage),e.boxBackgroundImageOpacity!==void 0&&(i.boxBackgroundImageOpacity=e.boxBackgroundImageOpacity),e.vellumOpacity!==void 0&&(i.vellumOpacity=e.vellumOpacity),e.vellumBackgroundImage!==void 0&&(i.vellumBackgroundImage=e.vellumBackgroundImage),e.vellumBackgroundImageOpacity!==void 0&&(i.vellumBackgroundImageOpacity=e.vellumBackgroundImageOpacity),i}function T(s,e){if(!e)return{...s};const i={...s};for(const r of Object.keys(e)){const u=e[r];u!==void 0&&(i[r]=u)}return i}function ne(s){const e=[],i=[];let r;try{r=atob(s)}catch{return e.push("Failed to decode Base64 string."),{valid:!1,errors:e,warnings:i}}let u;try{u=JSON.parse(r)}catch{return e.push("Decoded string is not valid JSON."),{valid:!1,errors:e,warnings:i}}if(typeof u!="object"||u===null||Array.isArray(u))return e.push("Theme must be a JSON object."),{valid:!1,errors:e,warnings:i};const o=u;"seedColor"in o&&(typeof o.seedColor!="string"?e.push("seedColor must be a string."):b(o.seedColor)||e.push(`seedColor is not a valid CSS color: "${o.seedColor}". Accepted forms: ${$}.`));for(const n of["fontBody","fontHeadings","fontBrand","fontMonospace"])n in o&&typeof o[n]!="string"&&e.push(`${n} must be a string.`);const f=["normal","bold","lighter","bolder"],p=["inherit","initial","unset","revert","revert-layer"];for(const n of["fontWeightBody","fontWeightHeadings","fontWeightBrand","fontWeightMonospace"])if(n in o){const t=o[n];if(typeof t=="number")(t<1||t>1e3)&&e.push(`${n} numeric value must be 1\u20131000 (got ${t}).`);else if(typeof t=="string"){const a=f.includes(t)||p.includes(t);if(/^\d+$/.test(t)){const l=Number(t);(l<1||l>1e3)&&e.push(`${n} numeric value must be 1\u20131000 (got "${t}").`)}else a||i.push(`${n} = "${t}" is not a standard font-weight value.`)}else e.push(`${n} must be a string or number.`)}"stylesheets"in o&&(Array.isArray(o.stylesheets)?o.stylesheets.some(n=>typeof n!="string")&&e.push("Every entry in stylesheets must be a string."):e.push("stylesheets must be an array of strings."));const g=[["rootFontSize",1,100],["borderRadius",0,10],["viewportMin",100,1e4],["viewportMax",200,1e4]];for(const[n,t,a]of g)if(n in o)if(typeof o[n]!="number"||!isFinite(o[n]))e.push(`${n} must be a finite number.`);else{const c=o[n];t!==void 0&&c<t&&e.push(`${n} must be \u2265 ${t} (got ${c}).`),a!==void 0&&c>a&&i.push(`${n} = ${c} is unusually high (max ${a}).`)}for(const n of["typeRatio","spaceRatio"])if(n in o)if(typeof o[n]!="number"||!isFinite(o[n]))e.push(`${n} must be a finite number.`);else{const t=o[n];t<=1&&e.push(`${n} must be > 1 (got ${t}).`);const a=n==="typeRatio"?1.3:2;t>a&&i.push(`${n} = ${t} is very high (max ${a}); scales may be extreme.`)}if("viewportMin"in o&&"viewportMax"in o){const n=o.viewportMin,t=o.viewportMax;typeof n=="number"&&typeof t=="number"&&n>=t&&e.push(`viewportMin (${n}) must be less than viewportMax (${t}).`)}if("angles"in o)if(typeof o.angles!="object"||o.angles===null)e.push("angles must be an object.");else{const n=o.angles;for(const t of["analogous","complementary","splitComplementary","triadic"])if(t in n)if(typeof n[t]!="number"||!isFinite(n[t]))e.push(`angles.${t} must be a finite number.`);else{const a=n[t];(a<0||a>360)&&i.push(`angles.${t} = ${a} is outside 0\u2013360.`)}}if("semanticHues"in o)if(typeof o.semanticHues!="object"||o.semanticHues===null)e.push("semanticHues must be an object.");else{const n=o.semanticHues;for(const t of["danger","success","warning"])if(t in n)if(typeof n[t]!="number"||!isFinite(n[t]))e.push(`semanticHues.${t} must be a finite number.`);else{const a=n[t];(a<0||a>360)&&i.push(`semanticHues.${t} = ${a} is outside 0\u2013360.`)}}if("variantChroma"in o)if(typeof o.variantChroma!="object"||o.variantChroma===null)e.push("variantChroma must be an object.");else{const n=o.variantChroma;for(const t of D)if(t in n)if(typeof n[t]!="number"||!isFinite(n[t]))e.push(`variantChroma["${t}"] must be a finite number.`);else{const a=n[t];a<0&&e.push(`variantChroma["${t}"] must be \u2265 0 (got ${a}).`),a>d&&i.push(`variantChroma["${t}"] = ${a} exceeds ${d}.`)}}if("lightness"in o)if(typeof o.lightness!="object"||o.lightness===null)e.push("lightness must be an object.");else{const n=o.lightness;for(const t of B)if(t in n)if(typeof n[t]!="number"||!isFinite(n[t]))e.push(`lightness.${t} must be a finite number.`);else{const a=n[t];(a<0||a>1)&&e.push(`lightness.${t} must be 0\u20131 (got ${a}).`)}}if("chroma"in o)if(typeof o.chroma!="object"||o.chroma===null)e.push("chroma must be an object.");else{const n=o.chroma;for(const t of k)if(t in n){const a=n[t];if(typeof a!="object"||a===null){e.push(`chroma.${t} must be { min, max }.`);continue}const c=a;(typeof c.min!="number"||c.min<0)&&e.push(`chroma.${t}.min must be \u2265 0.`),(typeof c.max!="number"||c.max<0||c.max>d)&&e.push(`chroma.${t}.max must be 0\u2013${d}.`),typeof c.min=="number"&&typeof c.max=="number"&&c.min>c.max&&e.push(`chroma.${t}.min (${c.min}) must be \u2264 max (${c.max}).`)}}if("anchors"in o)if(typeof o.anchors!="object"||o.anchors===null||Array.isArray(o.anchors))e.push("anchors must be an object of named colors.");else for(const[n,t]of Object.entries(o.anchors))if(m(n)?A.test(n)||e.push(`anchors: "${n}" is not a valid anchor name; use a lowercase slug (letters, digits, hyphens).`):e.push(`anchors: "${n}" is a reserved JavaScript property name and cannot be an anchor name; rename it.`),x.includes(n)&&e.push(`anchors: "${n}" collides with a reserved color source name.`),typeof t=="string")b(t)||e.push(`anchors.${n} is not a valid CSS color: "${t}". Accepted forms: ${$}.`);else if(typeof t=="object"&&t!==null&&!Array.isArray(t)){const a=t;typeof a.color!="string"&&e.push(`anchors.${n} must declare its base "color".`);for(const[c,l]of Object.entries(a))m(c)?c!=="color"&&!A.test(c)&&e.push(`anchors.${n}: "${c}" is not a valid slot name; use a lowercase slug.`):e.push(`anchors.${n}: "${c}" is a reserved JavaScript property name and cannot be a slot name; rename it.`),typeof l!="string"?e.push(`anchors.${n}.${c} must be a CSS color string.`):b(l)||e.push(`anchors.${n}.${c} is not a valid CSS color: "${l}". Accepted forms: ${$}.`)}else e.push(`anchors.${n} must be a color string or a { color, \u2026slots } object.`);const y=new Map;if("anchors"in o&&typeof o.anchors=="object"&&o.anchors!==null&&!Array.isArray(o.anchors))for(const[n,t]of Object.entries(o.anchors))y.set(n,t);if("semanticMappings"in o)if(typeof o.semanticMappings!="object"||o.semanticMappings===null)e.push("semanticMappings must be an object.");else{const n=o.semanticMappings;for(const t of k)if(t in n){const a=n[t];if(typeof a!="object"||a===null){e.push(`semanticMappings.${t} must be { source, lightness }.`);continue}const c=a;if(typeof c.source!="string")e.push(`semanticMappings.${t}.source must be a string.`);else if(c.source.startsWith("anchor:")){const l=F(c.source);if(!l)e.push(`semanticMappings.${t}.source "${c.source}" is not valid anchor syntax; use anchor:<name> or anchor:<name>.<slot>.`);else if(y.has(l.name)){if(l.slot!==void 0){const h=y.get(l.name);if(typeof(typeof h=="object"&&h!==null&&!Array.isArray(h)?h[l.slot]:void 0)!="string"){const v=typeof h=="object"&&h!==null?Object.keys(h).filter(E=>E!=="color"):[];e.push(`semanticMappings.${t}.source references unknown slot "${l.slot}" on anchor "${l.name}". Declared slots: ${v.length>0?v.join(", "):"(none)"}.`)}}}else{const h=[...y.keys()];e.push(`semanticMappings.${t}.source references undeclared anchor "${l.name}". Declared anchors: ${h.length>0?h.join(", "):"(none)"}.`)}}else x.includes(c.source)||e.push(`semanticMappings.${t}.source must be one of: ${x.join(", ")}, or a declared anchor as anchor:<name> / anchor:<name>.<slot>.`);(typeof c.lightness!="string"||!B.includes(c.lightness))&&e.push(`semanticMappings.${t}.lightness must be one of: ${B.join(", ")}.`)}}for(const n of["pageBackgroundImage","boxBackgroundImage","vellumBackgroundImage"])n in o&&typeof o[n]!="string"&&e.push(`${n} must be a string.`);for(const n of["pageBackgroundImageOpacity","boxBackgroundImageOpacity","vellumOpacity","vellumBackgroundImageOpacity"])if(n in o)if(typeof o[n]!="number"||!isFinite(o[n]))e.push(`${n} must be a finite number.`);else{const t=o[n];(t<0||t>1)&&e.push(`${n} must be 0\u20131 (got ${t}).`)}return{valid:e.length===0,errors:e,warnings:i}}const G=["anchors","angles","chroma","lightness","semanticHues","semanticMappings","variantChroma"];function P(s,e){const i={};for(const[r,u]of Object.entries(s))m(r)&&(i[r]=u);for(const[r,u]of Object.entries(e))u!==void 0&&m(r)&&(i[r]=u);for(const r of G){const u=s[r],o=e[r];if(u&&typeof u=="object"&&!Array.isArray(u)&&o&&typeof o=="object"&&!Array.isArray(o)){if(r==="anchors"){i[r]=R(u,o);continue}const f={};for(const[p,g]of Object.entries(u))m(p)&&(f[p]=g);for(const[p,g]of Object.entries(o))g!==void 0&&m(p)&&(f[p]=g);i[r]=f}}return i}function te(...s){let e={};for(const i of s){if(!i)continue;const r=K(i);r&&(e=P(e,r))}return O(e)}function I(s){return s.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const w={borderRadius:.1,fontBody:'"Noto Sans", sans-serif',fontWeightBody:"normal",fontHeadings:'"Inika", serif',fontWeightHeadings:"normal",fontBrand:'"Inika", serif',fontWeightBrand:"normal",fontMonospace:'"JetBrains Mono", monospace',fontWeightMonospace:"normal",seedColor:"oklch(.07 0.15 216)"};function oe(s){return O({...w,pageBackgroundImage:`url("${I(s)}")`,pageBackgroundImageOpacity:.5})}function se(s){return O({...w,pageBackgroundImage:`url("${I(s)}")`,pageBackgroundImageOpacity:.55})}export{A as ANCHOR_SLUG_PATTERN,x as COLOR_SOURCES,U as DEFAULT_DARK_LIGHTNESS,q as DEFAULT_DARK_THEME,L as DEFAULT_LIGHT_LIGHTNESS,Z as DEFAULT_LIGHT_THEME,S as DEFAULT_SEMANTIC_MAPPINGS,B as LIGHTNESS_KEYS,G as NESTED_THEME_KEYS,k as SEMANTIC_COLOR_NAMES,D as VARIANT_COLOR_SOURCES,se as buildTaprootDarkTheme,oe as buildTaprootLightTheme,O as encodeTheme,te as layerThemes,P as mergePartials,ee as mergeTheme,F as parseAnchorSource,K as parseTheme,X as resolveAnchorColor,Q as semanticToCSS,ne as validateTheme};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"packageManager": "bun@1.3.12",
|
|
5
5
|
"description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
|
|
6
6
|
"customElements": "custom-elements.json",
|