@sky.ui/core 0.0.46 → 0.0.48
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/dist/custom-elements.json +3087 -2885
- package/dist/helper/controllers/popover-controller.js +1 -1
- package/dist/helper/controllers/popover-controller.js.map +1 -1
- package/dist/helper/controllers/preset-controller.d.ts +9 -0
- package/dist/helper/controllers/preset-controller.js +1 -1
- package/dist/helper/controllers/preset-controller.js.map +1 -1
- package/dist/helper/index.js +1 -1
- package/dist/helper/utils/component-presets.d.ts +9 -0
- package/dist/helper/utils/component-presets.js +1 -1
- package/dist/helper/utils/component-presets.js.map +1 -1
- package/dist/helper/utils/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/sky-combobox/sky-combobox.d.ts +64 -0
- package/dist/sky-combobox/sky-combobox.js +65 -61
- package/dist/sky-combobox/sky-combobox.js.map +1 -1
- package/dist/sky-input/sky-input.js +7 -7
- package/dist/sky-input/sky-input.js.map +1 -1
- package/package.json +1 -1
|
@@ -114,6 +114,15 @@ export type ResolveComponentPropsOptions<T extends Record<string, unknown>> = {
|
|
|
114
114
|
*/
|
|
115
115
|
keys?: Array<keyof T & string>;
|
|
116
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* True when `host` is rendered inside another `sky-*` component's shadow tree
|
|
119
|
+
* (library chrome), not as slotted / light-DOM content.
|
|
120
|
+
*
|
|
121
|
+
* Slotted children keep `getRootNode() === document` (or an outer root), so
|
|
122
|
+
* provider defaults still apply. Internals like `sky-button` inside `sky-table`
|
|
123
|
+
* must not pick up app-level `defaults['sky-button']`.
|
|
124
|
+
*/
|
|
125
|
+
export declare function isSkyCompositeInternal(host: HTMLElement): boolean;
|
|
117
126
|
/**
|
|
118
127
|
* Walk ancestors for `<sky-config-provider>` and deep-merge outer → inner.
|
|
119
128
|
* Used when Lit context has not delivered a value yet (or as a reliable fallback).
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createContext as t}from"@lit/context";const e=new Set(["$inheritDefaults"]);function n(t){const e=String(t||"").trim();if(!e)return[];const n=new Set([e]);return e.startsWith("sky-")?n.add(e.slice(4)):n.add(`sky-${e}`),[...n]}function o(t,e){if(t)for(const o of n(e))if(Object.prototype.hasOwnProperty.call(t,o))return t[o]}function s(t){const e=String(t||"").trim();return e?e.startsWith("sky-")?e:`sky-${e}`:e}const r=t("sky/component-presets");function c(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase()}const f=new WeakMap,i=new WeakMap,a=new WeakMap,u=new WeakMap,p=new Set(["preset",...e]);function l(t){f.has(t)||f.set(t,new Set(t.getAttributeNames()))}function g(t){if(u.has(t))return;const e=new Map,n=t,o=t.constructor.elementProperties;if(o)for(const t of o.keys())"string"!=typeof t||p.has(t)||e.set(t,n[t]);u.set(t,e)}function h(t){if(!u.has(t))return void g(t);const e=u.get(t),n=t;for(const[t,o]of e)void 0===o&&void 0!==n[t]&&e.set(t,n[t])}function d(t){const e=f.get(t)??new Set;for(const n of t.getAttributeNames())e.add(n);f.set(t,e)}function y(t,e){const n=i.get(t)??new Set;n.add(e),i.set(t,n)}function w(t,e){if(i.get(t)?.has(e))return!0;const n=c(e),o=f.get(t);if(o?.has(n)||n!==e&&o?.has(e))return!0;if(!o&&(t.hasAttribute(n)||n!==e&&t.hasAttribute(e)))return!0;if(!a.get(t)?.has(e)){const n=u.get(t);if(n?.has(e)){if(t[e]!==n.get(e))return!0}}return!1}function k(t,e){const n=t??{},o=e??{},r={};for(const t of[n.defaults,o.defaults])for(const[e,n]of Object.entries(t??{})){const t=s(e);r[t]={...r[t]??{},...n??{}}}const c={};for(const t of[n.presets,o.presets])for(const[e,n]of Object.entries(t??{})){const t=s(e),o={...c[t]??{}};for(const[t,e]of Object.entries(n??{}))o[t]={...o[t]??{},...e??{}};c[t]=o}return{defaults:r,presets:c}}function m(t){const e=[];let n=t.parentElement;for(;n;){if("sky-config-provider"===n.localName){const t=n;if(t.mergedConfig)return t.mergedConfig;t.presets&&e.push(t.presets)}n=n.parentElement}return e.length?e.reduceRight((t,e)=>k(t,e),{}):null}function
|
|
1
|
+
import{createContext as t}from"@lit/context";const e=new Set(["$inheritDefaults"]);function n(t){const e=String(t||"").trim();if(!e)return[];const n=new Set([e]);return e.startsWith("sky-")?n.add(e.slice(4)):n.add(`sky-${e}`),[...n]}function o(t,e){if(t)for(const o of n(e))if(Object.prototype.hasOwnProperty.call(t,o))return t[o]}function s(t){const e=String(t||"").trim();return e?e.startsWith("sky-")?e:`sky-${e}`:e}const r=t("sky/component-presets");function c(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase()}const f=new WeakMap,i=new WeakMap,a=new WeakMap,u=new WeakMap,p=new Set(["preset",...e]);function l(t){f.has(t)||f.set(t,new Set(t.getAttributeNames()))}function g(t){if(u.has(t))return;const e=new Map,n=t,o=t.constructor.elementProperties;if(o)for(const t of o.keys())"string"!=typeof t||p.has(t)||e.set(t,n[t]);u.set(t,e)}function h(t){if(!u.has(t))return void g(t);const e=u.get(t),n=t;for(const[t,o]of e)void 0===o&&void 0!==n[t]&&e.set(t,n[t])}function d(t){const e=f.get(t)??new Set;for(const n of t.getAttributeNames())e.add(n);f.set(t,e)}function y(t,e){const n=i.get(t)??new Set;n.add(e),i.set(t,n)}function w(t,e){if(i.get(t)?.has(e))return!0;const n=c(e),o=f.get(t);if(o?.has(n)||n!==e&&o?.has(e))return!0;if(!o&&(t.hasAttribute(n)||n!==e&&t.hasAttribute(e)))return!0;if(!a.get(t)?.has(e)){const n=u.get(t);if(n?.has(e)){if(t[e]!==n.get(e))return!0}}return!1}function k(t,e){const n=t??{},o=e??{},r={};for(const t of[n.defaults,o.defaults])for(const[e,n]of Object.entries(t??{})){const t=s(e);r[t]={...r[t]??{},...n??{}}}const c={};for(const t of[n.presets,o.presets])for(const[e,n]of Object.entries(t??{})){const t=s(e),o={...c[t]??{}};for(const[t,e]of Object.entries(n??{}))o[t]={...o[t]??{},...e??{}};c[t]=o}return{defaults:r,presets:c}}function m(t){if("undefined"==typeof ShadowRoot)return!1;const e=t.getRootNode();if(!(e instanceof ShadowRoot))return!1;const n=e.host?.localName??"";return"sky-config-provider"!==n&&"sky-theme-provider"!==n&&n.startsWith("sky-")}function b(t){const e=[];let n=t.parentElement;for(;n;){if("sky-config-provider"===n.localName){const t=n;if(t.mergedConfig)return t.mergedConfig;t.presets&&e.push(t.presets)}n=n.parentElement}return e.length?e.reduceRight((t,e)=>k(t,e),{}):null}function O(t,o,s){const r=function(t,e){if(!t)return{};let o={};for(const s of n(e)){const e=t[s];e&&(o={...o,...e})}return o}(t?.defaults,o),c=function(t,e){if(!t)return{};const o={};for(const s of n(e)){const e=t[s];if(e)for(const[t,n]of Object.entries(e))o[t]={...o[t]??{},...n??{}}}return o}(t?.presets,o),f=s&&c[s]?c[s]:null,i=f&&!1===f.$inheritDefaults?{...f}:{...r,...f??{}};for(const t of e)delete i[t];return i}const S=new WeakMap;function j(t,e,n){d(t),function(t,e){const n=u.get(t);if(!n?.size)return;const o=a.get(t),s=t;for(const r of Object.keys(e))p.has(r)||o?.has(r)||i.get(t)?.has(r)||n.has(r)&&s[r]!==n.get(r)&&y(t,r)}(t,e),function(t){const e=a.get(t);if(!e?.size)return;const n=t;for(const[o,s]of e)w(t,o)||n[o]!==s&&y(t,o)}(t);const o=new Set([...p,...n?.skipKeys??[]]),s=S.get(t)??new Map,r=a.get(t)??new Map;let c=!1;const f=t;for(const n of[...s.keys()])if(!Object.prototype.hasOwnProperty.call(e,n)||void 0===e[n]){if(!w(t,n)&&s.has(n)){const t=s.get(n);f[n]!==t&&(f[n]=t,c=!0)}s.delete(n),r.delete(n)}for(const[n,i]of Object.entries(e))o.has(n)||void 0===i||(w(t,n)?r.delete(n):(s.has(n)||s.set(n,f[n]),f[n]!==i&&(f[n]=i,c=!0),r.set(n,i)));return S.set(t,s),a.set(t,r),c}function v(t){const e=S.get(t);if(!e?.size)return!1;const n=t;let o=!1;for(const[s,r]of e)w(t,s)||n[s]!==r&&(n[s]=r,o=!0);return e.clear(),a.get(t)?.clear(),o}function M(t){const{host:e,componentKey:n,presetName:o,config:s,values:r,keys:c}=t,f=O(s,n,o),i=c??Object.keys(f),a={...r};for(const t of i){const n=t;w(e,n)||Object.prototype.hasOwnProperty.call(f,n)&&void 0!==f[n]&&(a[n]=f[n])}return a}export{j as applyPresetLayer,c as camelToKebab,g as captureBuiltInPropSnapshot,l as captureInitialUserAttributes,v as clearAppliedPresetLayer,r as configContext,h as finalizeBuiltInPropSnapshot,b as findNearestPresetsConfig,O as getPresetLayer,m as isSkyCompositeInternal,w as isUserSetProp,o as lookupPresetSection,y as markUserSetProp,k as mergePresetsConfig,n as presetKeyAliases,d as refreshUserAttributes,M as resolveComponentProps,s as toPresetTagKey};
|
|
2
2
|
//# sourceMappingURL=component-presets.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-presets.js","sources":["../../../src/helper/utils/component-presets.ts"],"sourcesContent":["/**\n * Component prop presets — global defaults + named bundles for sky-* CEs.\n *\n * Precedence (highest wins):\n * explicit user prop (attribute, framework property, or marked/diverged) →\n * named `preset` → provider `defaults` → built-in class default\n *\n * A named preset overlays `defaults` unless it sets `$inheritDefaults: false`,\n * in which case it is used standalone (keys it omits fall to the built-in).\n *\n * User-owned detection:\n * - attributes present before Lit's first reflect (and any attrs added later)\n * - props marked via `markUserSetProp`\n * - props the consumer changed after presets applied (divergence)\n * - props a framework set before first apply (current value ≠ constructor\n * snapshot from `captureBuiltInPropSnapshot` — covers Vue/React CE property\n * bindings that never create attributes). Overriding *back* to the exact\n * built-in default still needs an attribute or `markUserSetProp`.\n *\n * @see sky-config-provider\n */\n\nimport { createContext } from \"@lit/context\";\n\n/** Prop bag applied to a single component instance. */\nexport type ComponentPropBag = Record<string, unknown> & {\n /**\n * Named presets only: set `false` to ignore `defaults[component]` and use\n * this bag standalone. Omitted / `true` keeps the default layering.\n */\n $inheritDefaults?: boolean;\n};\n\n/** Reserved bag keys that configure resolution instead of naming a prop. */\nconst RESERVED_BAG_KEYS = new Set([\"$inheritDefaults\"]);\n\n/**\n * Config keys are custom element tag names (`sky-button`).\n * Short aliases without the `sky-` prefix (`button`) are also accepted.\n */\nexport type ComponentPresetKey = string;\n\nexport type ComponentPresetsConfig = {\n /** Applied when the instance does not set the prop (no matching attribute). */\n defaults?: Partial<Record<ComponentPresetKey, ComponentPropBag>>;\n /** Named bundles selected via `preset=\"name\"` on the instance. */\n presets?: Partial<\n Record<ComponentPresetKey, Record<string, ComponentPropBag>>\n >;\n};\n\n/**\n * Lookup aliases for a component key: tag name and short name.\n * `sky-button` ↔ `button`, `sky-button-group` ↔ `button-group`.\n */\nexport function presetKeyAliases(key: string): string[] {\n const k = String(key || \"\").trim();\n if (!k) return [];\n const aliases = new Set<string>([k]);\n if (k.startsWith(\"sky-\")) aliases.add(k.slice(4));\n else aliases.add(`sky-${k}`);\n return [...aliases];\n}\n\n/** First matching bag under `defaults` / `presets` for any alias of `key`. */\nexport function lookupPresetSection<T>(\n section: Partial<Record<string, T>> | null | undefined,\n key: string,\n): T | undefined {\n if (!section) return undefined;\n for (const alias of presetKeyAliases(key)) {\n if (Object.prototype.hasOwnProperty.call(section, alias)) {\n return section[alias];\n }\n }\n return undefined;\n}\n\n/** Merge all alias bags (short + tag) under a section key. Later aliases win. */\nfunction mergeAliasBags(\n section: Partial<Record<string, ComponentPropBag>> | null | undefined,\n key: string,\n): ComponentPropBag {\n if (!section) return {};\n let out: ComponentPropBag = {};\n for (const alias of presetKeyAliases(key)) {\n const bag = section[alias];\n if (bag) out = { ...out, ...bag };\n }\n return out;\n}\n\nfunction mergeAliasNamedMaps(\n section:\n | Partial<Record<string, Record<string, ComponentPropBag>>>\n | null\n | undefined,\n key: string,\n): Record<string, ComponentPropBag> {\n if (!section) return {};\n const out: Record<string, ComponentPropBag> = {};\n for (const alias of presetKeyAliases(key)) {\n const named = section[alias];\n if (!named) continue;\n for (const [name, bag] of Object.entries(named)) {\n out[name] = { ...(out[name] ?? {}), ...(bag ?? {}) };\n }\n }\n return out;\n}\n\n/**\n * Canonical tag form for storage/docs: `button` → `sky-button`.\n * Already-tagged names are unchanged.\n */\nexport function toPresetTagKey(key: string): string {\n const k = String(key || \"\").trim();\n if (!k) return k;\n return k.startsWith(\"sky-\") ? k : `sky-${k}`;\n}\n\n/** Lit context provided by `<sky-config-provider>`. */\nexport const configContext = createContext<ComponentPresetsConfig | null>(\n \"sky/component-presets\",\n);\n\n/** camelCase / PascalCase → kebab-case attribute name. */\nexport function camelToKebab(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/_/g, \"-\")\n .toLowerCase();\n}\n\n/**\n * Attributes present before Lit's first reflect (captured in `PresetController`).\n * Needed so reflected class defaults (e.g. `variant=\"solid\"`) do not look user-owned.\n */\nconst initialUserAttrs = new WeakMap<HTMLElement, Set<string>>();\n\n/** Props explicitly marked user-owned (property-only writes / divergence). */\nconst userOwnedProps = new WeakMap<HTMLElement, Set<string>>();\n\n/** Last values written by `applyPresetLayer` (for divergence detection). */\nconst lastPresetApplied = new WeakMap<HTMLElement, Map<string, unknown>>();\n\n/**\n * Prop values at CE construction (before Vue/React assign host props).\n * Call from `PresetController` construction so field initializers are visible.\n */\nconst builtInPropSnapshots = new WeakMap<HTMLElement, Map<string, unknown>>();\n\nconst PRESET_SKIP_KEYS = new Set([\"preset\", ...RESERVED_BAG_KEYS]);\n\n/**\n * Snapshot host attributes once (call from controller `hostConnected`, before first update).\n * Declarative HTML / early `setAttribute` calls are treated as user-owned thereafter.\n */\nexport function captureInitialUserAttributes(host: HTMLElement): void {\n if (initialUserAttrs.has(host)) return;\n initialUserAttrs.set(host, new Set(host.getAttributeNames()));\n}\n\n/**\n * Snapshot Lit `@property` values once during host construction (before frameworks\n * assign props). Later diffs against this map mark framework property bindings as\n * user-owned so presets do not overwrite them.\n *\n * Declare `PresetController` after the host's presettable `@property` fields so\n * those initials are already assigned when this runs. Keys still `undefined` are\n * filled by `finalizeBuiltInPropSnapshot` on connect (constructor-body defaults).\n */\nexport function captureBuiltInPropSnapshot(host: HTMLElement): void {\n if (builtInPropSnapshots.has(host)) return;\n const snap = new Map<string, unknown>();\n const record = host as HTMLElement & Record<string, unknown>;\n const meta = (\n host.constructor as { elementProperties?: Map<PropertyKey, unknown> }\n ).elementProperties;\n if (meta) {\n for (const prop of meta.keys()) {\n if (typeof prop !== \"string\" || PRESET_SKIP_KEYS.has(prop)) continue;\n snap.set(prop, record[prop]);\n }\n }\n builtInPropSnapshots.set(host, snap);\n}\n\n/**\n * Fill snapshot entries that were still `undefined` when the controller\n * constructed (e.g. defaults assigned in the host `constructor` body after the\n * controller field). Does not overwrite defined snapshot values — those are the\n * true built-ins Vue/React may have already overridden by connect time.\n */\nexport function finalizeBuiltInPropSnapshot(host: HTMLElement): void {\n if (!builtInPropSnapshots.has(host)) {\n captureBuiltInPropSnapshot(host);\n return;\n }\n const snap = builtInPropSnapshots.get(host)!;\n const record = host as HTMLElement & Record<string, unknown>;\n for (const [key, value] of snap) {\n if (value === undefined && record[key] !== undefined) {\n snap.set(key, record[key]);\n }\n }\n}\n\n/**\n * Merge any attributes that appeared after connect (late framework bindings)\n * into the user-owned attribute snapshot.\n */\nexport function refreshUserAttributes(host: HTMLElement): void {\n const set = initialUserAttrs.get(host) ?? new Set<string>();\n for (const name of host.getAttributeNames()) set.add(name);\n initialUserAttrs.set(host, set);\n}\n\n/**\n * Mark a prop as consumer-owned so presets will not overwrite it.\n * Use for property-only bindings (no attribute) when needed.\n */\nexport function markUserSetProp(host: HTMLElement, prop: string): void {\n const set = userOwnedProps.get(host) ?? new Set<string>();\n set.add(prop);\n userOwnedProps.set(host, set);\n}\n\n/**\n * True when the host had an attribute for this prop before/at apply time,\n * the prop was marked user-owned (explicit mark or post-apply divergence),\n * or a framework assigned a property that differs from the constructor snapshot\n * before presets first wrote that key.\n */\nexport function isUserSetProp(host: HTMLElement, prop: string): boolean {\n if (userOwnedProps.get(host)?.has(prop)) return true;\n const kebab = camelToKebab(prop);\n const initial = initialUserAttrs.get(host);\n if (initial?.has(kebab) || (kebab !== prop && initial?.has(prop))) {\n return true;\n }\n if (\n !initial &&\n (host.hasAttribute(kebab) || (kebab !== prop && host.hasAttribute(prop)))\n ) {\n return true;\n }\n // Framework CE bindings (Vue/React) set properties, not attributes.\n if (!lastPresetApplied.get(host)?.has(prop)) {\n const snap = builtInPropSnapshots.get(host);\n if (snap?.has(prop)) {\n const record = host as HTMLElement & Record<string, unknown>;\n if (record[prop] !== snap.get(prop)) return true;\n }\n }\n return false;\n}\n\n/**\n * Permanently mark props a framework changed before our first write for that key.\n */\nfunction detectPreApplyFrameworkProps(\n host: HTMLElement,\n layer: ComponentPropBag,\n): void {\n const snap = builtInPropSnapshots.get(host);\n if (!snap?.size) return;\n const applied = lastPresetApplied.get(host);\n const record = host as HTMLElement & Record<string, unknown>;\n for (const key of Object.keys(layer)) {\n if (PRESET_SKIP_KEYS.has(key) || applied?.has(key)) continue;\n if (userOwnedProps.get(host)?.has(key)) continue;\n if (!snap.has(key)) continue;\n if (record[key] !== snap.get(key)) {\n markUserSetProp(host, key);\n }\n }\n}\n\n/**\n * If the consumer changed a prop after we applied a preset value, mark it\n * user-owned so later re-applies leave it alone.\n */\nfunction detectDivergedUserProps(host: HTMLElement): void {\n const applied = lastPresetApplied.get(host);\n if (!applied?.size) return;\n const record = host as HTMLElement & Record<string, unknown>;\n for (const [key, appliedValue] of applied) {\n if (isUserSetProp(host, key)) continue;\n if (record[key] !== appliedValue) {\n markUserSetProp(host, key);\n }\n }\n}\n\n/**\n * Deep-merge parent + child preset configs.\n * Inner provider wins per component key, then per prop / named preset.\n */\nexport function mergePresetsConfig(\n parent: ComponentPresetsConfig | null | undefined,\n child: ComponentPresetsConfig | null | undefined,\n): ComponentPresetsConfig {\n const p = parent ?? {};\n const c = child ?? {};\n\n const defaults: NonNullable<ComponentPresetsConfig[\"defaults\"]> = {};\n for (const source of [p.defaults, c.defaults]) {\n for (const [key, bag] of Object.entries(source ?? {})) {\n const tag = toPresetTagKey(key);\n defaults[tag] = { ...(defaults[tag] ?? {}), ...(bag ?? {}) };\n }\n }\n\n const presets: NonNullable<ComponentPresetsConfig[\"presets\"]> = {};\n for (const source of [p.presets, c.presets]) {\n for (const [comp, named] of Object.entries(source ?? {})) {\n const tag = toPresetTagKey(comp);\n const mergedNamed: Record<string, ComponentPropBag> = {\n ...(presets[tag] ?? {}),\n };\n for (const [name, bag] of Object.entries(named ?? {})) {\n mergedNamed[name] = { ...(mergedNamed[name] ?? {}), ...(bag ?? {}) };\n }\n presets[tag] = mergedNamed;\n }\n }\n\n return { defaults, presets };\n}\n\nexport type ResolveComponentPropsOptions<T extends Record<string, unknown>> = {\n host: HTMLElement;\n componentKey: ComponentPresetKey;\n /** Value of the instance `preset` attribute/prop. */\n presetName?: string | null;\n config?: ComponentPresetsConfig | null;\n /** Current instance values (class built-ins already applied). */\n values: T;\n /**\n * Keys eligible for preset / default substitution.\n * Omit to apply every key present in the preset layer.\n */\n keys?: Array<keyof T & string>;\n};\n\n/**\n * Walk ancestors for `<sky-config-provider>` and deep-merge outer → inner.\n * Used when Lit context has not delivered a value yet (or as a reliable fallback).\n */\nexport function findNearestPresetsConfig(\n host: HTMLElement,\n): ComponentPresetsConfig | null {\n const layers: ComponentPresetsConfig[] = [];\n let el: HTMLElement | null = host.parentElement;\n while (el) {\n if (el.localName === \"sky-config-provider\") {\n const provider = el as HTMLElement & {\n presets?: ComponentPresetsConfig;\n mergedConfig?: ComponentPresetsConfig;\n };\n // Prefer live `presets` so we do not depend on context publish timing.\n if (provider.mergedConfig) {\n // Nearest provider already merged its ancestors — use it and stop.\n return provider.mergedConfig;\n }\n if (provider.presets) layers.push(provider.presets);\n }\n el = el.parentElement;\n }\n if (!layers.length) return null;\n // layers collected inner→outer while walking up; merge outer first, inner last.\n return layers.reduceRight(\n (acc, layer) => mergePresetsConfig(acc, layer),\n {} as ComponentPresetsConfig,\n );\n}\n\n/**\n * Resolve the active prop bag for a component: `defaults[key]` ← `presets[key][name]`.\n * Any prop key present in that bag can be applied to the instance.\n *\n * A named preset with `$inheritDefaults: false` is used standalone, so keys it\n * omits fall through to the component built-in instead of `defaults`.\n */\nexport function getPresetLayer(\n config: ComponentPresetsConfig | null | undefined,\n componentKey: ComponentPresetKey,\n presetName?: string | null,\n): ComponentPropBag {\n const defaults = mergeAliasBags(config?.defaults, componentKey);\n const namedMap = mergeAliasNamedMaps(config?.presets, componentKey);\n const named =\n presetName && namedMap[presetName] ? namedMap[presetName]! : null;\n\n const merged =\n named && named.$inheritDefaults === false\n ? { ...named }\n : { ...defaults, ...(named ?? {}) };\n\n for (const key of RESERVED_BAG_KEYS) delete merged[key];\n return merged;\n}\n\n/** Per-host map of prop → value before presets overwrote it (for revert). */\nconst presetRestoreValues = new WeakMap<HTMLElement, Map<string, unknown>>();\n\nexport type ApplyPresetLayerOptions = {\n /** Extra keys never written from presets. */\n skipKeys?: string[];\n};\n\n/**\n * Write every key from the preset layer onto the host (any component prop).\n * Skips user-owned attributes / props. Remembers prior values so removing a\n * key from the provider config restores the built-in / prior value.\n *\n * Before writing, detects divergence: if the host value no longer matches the\n * last preset-applied value, that prop is marked user-owned (property-only\n * overrides after first apply). Also locks in framework property bindings that\n * differ from the constructor snapshot before the first write for that key.\n *\n * @returns true if any host property changed\n */\nexport function applyPresetLayer(\n host: HTMLElement,\n layer: ComponentPropBag,\n options?: ApplyPresetLayerOptions,\n): boolean {\n refreshUserAttributes(host);\n detectPreApplyFrameworkProps(host, layer);\n detectDivergedUserProps(host);\n\n const skip = new Set([\n ...PRESET_SKIP_KEYS,\n ...(options?.skipKeys ?? []),\n ]);\n const restore = presetRestoreValues.get(host) ?? new Map<string, unknown>();\n const applied = lastPresetApplied.get(host) ?? new Map<string, unknown>();\n let changed = false;\n const record = host as HTMLElement & Record<string, unknown>;\n\n // Drop / revert keys no longer provided by the layer.\n for (const key of [...restore.keys()]) {\n if (\n Object.prototype.hasOwnProperty.call(layer, key) &&\n layer[key] !== undefined\n ) {\n continue;\n }\n if (!isUserSetProp(host, key) && restore.has(key)) {\n const prev = restore.get(key);\n if (record[key] !== prev) {\n record[key] = prev;\n changed = true;\n }\n }\n restore.delete(key);\n applied.delete(key);\n }\n\n // Apply all keys in the layer (full prop surface — not a whitelist).\n for (const [key, value] of Object.entries(layer)) {\n if (skip.has(key) || value === undefined) continue;\n if (isUserSetProp(host, key)) {\n applied.delete(key);\n continue;\n }\n if (!restore.has(key)) {\n restore.set(key, record[key]);\n }\n if (record[key] !== value) {\n record[key] = value;\n changed = true;\n }\n applied.set(key, value);\n }\n\n presetRestoreValues.set(host, restore);\n lastPresetApplied.set(host, applied);\n return changed;\n}\n\n/**\n * Clear preset-applied props and restore saved built-ins (e.g. when paused in a group).\n */\nexport function clearAppliedPresetLayer(host: HTMLElement): boolean {\n const restore = presetRestoreValues.get(host);\n if (!restore?.size) return false;\n const record = host as HTMLElement & Record<string, unknown>;\n let changed = false;\n for (const [key, prev] of restore) {\n if (isUserSetProp(host, key)) continue;\n if (record[key] !== prev) {\n record[key] = prev;\n changed = true;\n }\n }\n restore.clear();\n lastPresetApplied.get(host)?.clear();\n return changed;\n}\n\n/**\n * Resolve effective props for styling / behavior without mutating the host.\n * When `keys` is omitted, every key in the preset layer is considered.\n * Skips keys the user set via attributes.\n */\nexport function resolveComponentProps<T extends Record<string, unknown>>(\n options: ResolveComponentPropsOptions<T>,\n): T {\n const { host, componentKey, presetName, config, values, keys } = options;\n const layer = getPresetLayer(config, componentKey, presetName);\n const keysToApply =\n keys ?? (Object.keys(layer) as Array<keyof T & string>);\n\n const out = { ...values };\n for (const key of keysToApply) {\n const k = key as string;\n if (isUserSetProp(host, k)) continue;\n if (Object.prototype.hasOwnProperty.call(layer, k) && layer[k] !== undefined) {\n (out as Record<string, unknown>)[k] = layer[k];\n }\n }\n return out;\n}\n"],"names":["RESERVED_BAG_KEYS","Set","presetKeyAliases","key","k","String","trim","aliases","startsWith","add","slice","lookupPresetSection","section","alias","Object","prototype","hasOwnProperty","call","toPresetTagKey","configContext","createContext","camelToKebab","name","replace","toLowerCase","initialUserAttrs","WeakMap","userOwnedProps","lastPresetApplied","builtInPropSnapshots","PRESET_SKIP_KEYS","captureInitialUserAttributes","host","has","set","getAttributeNames","captureBuiltInPropSnapshot","snap","Map","record","meta","constructor","elementProperties","prop","keys","finalizeBuiltInPropSnapshot","get","value","refreshUserAttributes","markUserSetProp","isUserSetProp","kebab","initial","hasAttribute","mergePresetsConfig","parent","child","p","c","defaults","source","bag","entries","tag","presets","comp","named","mergedNamed","findNearestPresetsConfig","layers","el","parentElement","localName","provider","mergedConfig","push","length","reduceRight","acc","layer","getPresetLayer","config","componentKey","presetName","out","mergeAliasBags","namedMap","mergeAliasNamedMaps","merged","$inheritDefaults","presetRestoreValues","applyPresetLayer","options","size","applied","detectPreApplyFrameworkProps","appliedValue","detectDivergedUserProps","skip","skipKeys","restore","changed","prev","delete","clearAppliedPresetLayer","clear","resolveComponentProps","values","keysToApply"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"component-presets.js","sources":["../../../src/helper/utils/component-presets.ts"],"sourcesContent":["/**\n * Component prop presets — global defaults + named bundles for sky-* CEs.\n *\n * Precedence (highest wins):\n * explicit user prop (attribute, framework property, or marked/diverged) →\n * named `preset` → provider `defaults` → built-in class default\n *\n * A named preset overlays `defaults` unless it sets `$inheritDefaults: false`,\n * in which case it is used standalone (keys it omits fall to the built-in).\n *\n * User-owned detection:\n * - attributes present before Lit's first reflect (and any attrs added later)\n * - props marked via `markUserSetProp`\n * - props the consumer changed after presets applied (divergence)\n * - props a framework set before first apply (current value ≠ constructor\n * snapshot from `captureBuiltInPropSnapshot` — covers Vue/React CE property\n * bindings that never create attributes). Overriding *back* to the exact\n * built-in default still needs an attribute or `markUserSetProp`.\n *\n * @see sky-config-provider\n */\n\nimport { createContext } from \"@lit/context\";\n\n/** Prop bag applied to a single component instance. */\nexport type ComponentPropBag = Record<string, unknown> & {\n /**\n * Named presets only: set `false` to ignore `defaults[component]` and use\n * this bag standalone. Omitted / `true` keeps the default layering.\n */\n $inheritDefaults?: boolean;\n};\n\n/** Reserved bag keys that configure resolution instead of naming a prop. */\nconst RESERVED_BAG_KEYS = new Set([\"$inheritDefaults\"]);\n\n/**\n * Config keys are custom element tag names (`sky-button`).\n * Short aliases without the `sky-` prefix (`button`) are also accepted.\n */\nexport type ComponentPresetKey = string;\n\nexport type ComponentPresetsConfig = {\n /** Applied when the instance does not set the prop (no matching attribute). */\n defaults?: Partial<Record<ComponentPresetKey, ComponentPropBag>>;\n /** Named bundles selected via `preset=\"name\"` on the instance. */\n presets?: Partial<\n Record<ComponentPresetKey, Record<string, ComponentPropBag>>\n >;\n};\n\n/**\n * Lookup aliases for a component key: tag name and short name.\n * `sky-button` ↔ `button`, `sky-button-group` ↔ `button-group`.\n */\nexport function presetKeyAliases(key: string): string[] {\n const k = String(key || \"\").trim();\n if (!k) return [];\n const aliases = new Set<string>([k]);\n if (k.startsWith(\"sky-\")) aliases.add(k.slice(4));\n else aliases.add(`sky-${k}`);\n return [...aliases];\n}\n\n/** First matching bag under `defaults` / `presets` for any alias of `key`. */\nexport function lookupPresetSection<T>(\n section: Partial<Record<string, T>> | null | undefined,\n key: string,\n): T | undefined {\n if (!section) return undefined;\n for (const alias of presetKeyAliases(key)) {\n if (Object.prototype.hasOwnProperty.call(section, alias)) {\n return section[alias];\n }\n }\n return undefined;\n}\n\n/** Merge all alias bags (short + tag) under a section key. Later aliases win. */\nfunction mergeAliasBags(\n section: Partial<Record<string, ComponentPropBag>> | null | undefined,\n key: string,\n): ComponentPropBag {\n if (!section) return {};\n let out: ComponentPropBag = {};\n for (const alias of presetKeyAliases(key)) {\n const bag = section[alias];\n if (bag) out = { ...out, ...bag };\n }\n return out;\n}\n\nfunction mergeAliasNamedMaps(\n section:\n | Partial<Record<string, Record<string, ComponentPropBag>>>\n | null\n | undefined,\n key: string,\n): Record<string, ComponentPropBag> {\n if (!section) return {};\n const out: Record<string, ComponentPropBag> = {};\n for (const alias of presetKeyAliases(key)) {\n const named = section[alias];\n if (!named) continue;\n for (const [name, bag] of Object.entries(named)) {\n out[name] = { ...(out[name] ?? {}), ...(bag ?? {}) };\n }\n }\n return out;\n}\n\n/**\n * Canonical tag form for storage/docs: `button` → `sky-button`.\n * Already-tagged names are unchanged.\n */\nexport function toPresetTagKey(key: string): string {\n const k = String(key || \"\").trim();\n if (!k) return k;\n return k.startsWith(\"sky-\") ? k : `sky-${k}`;\n}\n\n/** Lit context provided by `<sky-config-provider>`. */\nexport const configContext = createContext<ComponentPresetsConfig | null>(\n \"sky/component-presets\",\n);\n\n/** camelCase / PascalCase → kebab-case attribute name. */\nexport function camelToKebab(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/_/g, \"-\")\n .toLowerCase();\n}\n\n/**\n * Attributes present before Lit's first reflect (captured in `PresetController`).\n * Needed so reflected class defaults (e.g. `variant=\"solid\"`) do not look user-owned.\n */\nconst initialUserAttrs = new WeakMap<HTMLElement, Set<string>>();\n\n/** Props explicitly marked user-owned (property-only writes / divergence). */\nconst userOwnedProps = new WeakMap<HTMLElement, Set<string>>();\n\n/** Last values written by `applyPresetLayer` (for divergence detection). */\nconst lastPresetApplied = new WeakMap<HTMLElement, Map<string, unknown>>();\n\n/**\n * Prop values at CE construction (before Vue/React assign host props).\n * Call from `PresetController` construction so field initializers are visible.\n */\nconst builtInPropSnapshots = new WeakMap<HTMLElement, Map<string, unknown>>();\n\nconst PRESET_SKIP_KEYS = new Set([\"preset\", ...RESERVED_BAG_KEYS]);\n\n/**\n * Snapshot host attributes once (call from controller `hostConnected`, before first update).\n * Declarative HTML / early `setAttribute` calls are treated as user-owned thereafter.\n */\nexport function captureInitialUserAttributes(host: HTMLElement): void {\n if (initialUserAttrs.has(host)) return;\n initialUserAttrs.set(host, new Set(host.getAttributeNames()));\n}\n\n/**\n * Snapshot Lit `@property` values once during host construction (before frameworks\n * assign props). Later diffs against this map mark framework property bindings as\n * user-owned so presets do not overwrite them.\n *\n * Declare `PresetController` after the host's presettable `@property` fields so\n * those initials are already assigned when this runs. Keys still `undefined` are\n * filled by `finalizeBuiltInPropSnapshot` on connect (constructor-body defaults).\n */\nexport function captureBuiltInPropSnapshot(host: HTMLElement): void {\n if (builtInPropSnapshots.has(host)) return;\n const snap = new Map<string, unknown>();\n const record = host as HTMLElement & Record<string, unknown>;\n const meta = (\n host.constructor as { elementProperties?: Map<PropertyKey, unknown> }\n ).elementProperties;\n if (meta) {\n for (const prop of meta.keys()) {\n if (typeof prop !== \"string\" || PRESET_SKIP_KEYS.has(prop)) continue;\n snap.set(prop, record[prop]);\n }\n }\n builtInPropSnapshots.set(host, snap);\n}\n\n/**\n * Fill snapshot entries that were still `undefined` when the controller\n * constructed (e.g. defaults assigned in the host `constructor` body after the\n * controller field). Does not overwrite defined snapshot values — those are the\n * true built-ins Vue/React may have already overridden by connect time.\n */\nexport function finalizeBuiltInPropSnapshot(host: HTMLElement): void {\n if (!builtInPropSnapshots.has(host)) {\n captureBuiltInPropSnapshot(host);\n return;\n }\n const snap = builtInPropSnapshots.get(host)!;\n const record = host as HTMLElement & Record<string, unknown>;\n for (const [key, value] of snap) {\n if (value === undefined && record[key] !== undefined) {\n snap.set(key, record[key]);\n }\n }\n}\n\n/**\n * Merge any attributes that appeared after connect (late framework bindings)\n * into the user-owned attribute snapshot.\n */\nexport function refreshUserAttributes(host: HTMLElement): void {\n const set = initialUserAttrs.get(host) ?? new Set<string>();\n for (const name of host.getAttributeNames()) set.add(name);\n initialUserAttrs.set(host, set);\n}\n\n/**\n * Mark a prop as consumer-owned so presets will not overwrite it.\n * Use for property-only bindings (no attribute) when needed.\n */\nexport function markUserSetProp(host: HTMLElement, prop: string): void {\n const set = userOwnedProps.get(host) ?? new Set<string>();\n set.add(prop);\n userOwnedProps.set(host, set);\n}\n\n/**\n * True when the host had an attribute for this prop before/at apply time,\n * the prop was marked user-owned (explicit mark or post-apply divergence),\n * or a framework assigned a property that differs from the constructor snapshot\n * before presets first wrote that key.\n */\nexport function isUserSetProp(host: HTMLElement, prop: string): boolean {\n if (userOwnedProps.get(host)?.has(prop)) return true;\n const kebab = camelToKebab(prop);\n const initial = initialUserAttrs.get(host);\n if (initial?.has(kebab) || (kebab !== prop && initial?.has(prop))) {\n return true;\n }\n if (\n !initial &&\n (host.hasAttribute(kebab) || (kebab !== prop && host.hasAttribute(prop)))\n ) {\n return true;\n }\n // Framework CE bindings (Vue/React) set properties, not attributes.\n if (!lastPresetApplied.get(host)?.has(prop)) {\n const snap = builtInPropSnapshots.get(host);\n if (snap?.has(prop)) {\n const record = host as HTMLElement & Record<string, unknown>;\n if (record[prop] !== snap.get(prop)) return true;\n }\n }\n return false;\n}\n\n/**\n * Permanently mark props a framework changed before our first write for that key.\n */\nfunction detectPreApplyFrameworkProps(\n host: HTMLElement,\n layer: ComponentPropBag,\n): void {\n const snap = builtInPropSnapshots.get(host);\n if (!snap?.size) return;\n const applied = lastPresetApplied.get(host);\n const record = host as HTMLElement & Record<string, unknown>;\n for (const key of Object.keys(layer)) {\n if (PRESET_SKIP_KEYS.has(key) || applied?.has(key)) continue;\n if (userOwnedProps.get(host)?.has(key)) continue;\n if (!snap.has(key)) continue;\n if (record[key] !== snap.get(key)) {\n markUserSetProp(host, key);\n }\n }\n}\n\n/**\n * If the consumer changed a prop after we applied a preset value, mark it\n * user-owned so later re-applies leave it alone.\n */\nfunction detectDivergedUserProps(host: HTMLElement): void {\n const applied = lastPresetApplied.get(host);\n if (!applied?.size) return;\n const record = host as HTMLElement & Record<string, unknown>;\n for (const [key, appliedValue] of applied) {\n if (isUserSetProp(host, key)) continue;\n if (record[key] !== appliedValue) {\n markUserSetProp(host, key);\n }\n }\n}\n\n/**\n * Deep-merge parent + child preset configs.\n * Inner provider wins per component key, then per prop / named preset.\n */\nexport function mergePresetsConfig(\n parent: ComponentPresetsConfig | null | undefined,\n child: ComponentPresetsConfig | null | undefined,\n): ComponentPresetsConfig {\n const p = parent ?? {};\n const c = child ?? {};\n\n const defaults: NonNullable<ComponentPresetsConfig[\"defaults\"]> = {};\n for (const source of [p.defaults, c.defaults]) {\n for (const [key, bag] of Object.entries(source ?? {})) {\n const tag = toPresetTagKey(key);\n defaults[tag] = { ...(defaults[tag] ?? {}), ...(bag ?? {}) };\n }\n }\n\n const presets: NonNullable<ComponentPresetsConfig[\"presets\"]> = {};\n for (const source of [p.presets, c.presets]) {\n for (const [comp, named] of Object.entries(source ?? {})) {\n const tag = toPresetTagKey(comp);\n const mergedNamed: Record<string, ComponentPropBag> = {\n ...(presets[tag] ?? {}),\n };\n for (const [name, bag] of Object.entries(named ?? {})) {\n mergedNamed[name] = { ...(mergedNamed[name] ?? {}), ...(bag ?? {}) };\n }\n presets[tag] = mergedNamed;\n }\n }\n\n return { defaults, presets };\n}\n\nexport type ResolveComponentPropsOptions<T extends Record<string, unknown>> = {\n host: HTMLElement;\n componentKey: ComponentPresetKey;\n /** Value of the instance `preset` attribute/prop. */\n presetName?: string | null;\n config?: ComponentPresetsConfig | null;\n /** Current instance values (class built-ins already applied). */\n values: T;\n /**\n * Keys eligible for preset / default substitution.\n * Omit to apply every key present in the preset layer.\n */\n keys?: Array<keyof T & string>;\n};\n\n/**\n * True when `host` is rendered inside another `sky-*` component's shadow tree\n * (library chrome), not as slotted / light-DOM content.\n *\n * Slotted children keep `getRootNode() === document` (or an outer root), so\n * provider defaults still apply. Internals like `sky-button` inside `sky-table`\n * must not pick up app-level `defaults['sky-button']`.\n */\nexport function isSkyCompositeInternal(host: HTMLElement): boolean {\n if (typeof ShadowRoot === \"undefined\") return false;\n const root = host.getRootNode();\n if (!(root instanceof ShadowRoot)) return false;\n const tag = root.host?.localName ?? \"\";\n // Config/theme providers are not composites that own chrome children.\n if (tag === \"sky-config-provider\" || tag === \"sky-theme-provider\") {\n return false;\n }\n return tag.startsWith(\"sky-\");\n}\n\n/**\n * Walk ancestors for `<sky-config-provider>` and deep-merge outer → inner.\n * Used when Lit context has not delivered a value yet (or as a reliable fallback).\n */\nexport function findNearestPresetsConfig(\n host: HTMLElement,\n): ComponentPresetsConfig | null {\n const layers: ComponentPresetsConfig[] = [];\n let el: HTMLElement | null = host.parentElement;\n while (el) {\n if (el.localName === \"sky-config-provider\") {\n const provider = el as HTMLElement & {\n presets?: ComponentPresetsConfig;\n mergedConfig?: ComponentPresetsConfig;\n };\n // Prefer live `presets` so we do not depend on context publish timing.\n if (provider.mergedConfig) {\n // Nearest provider already merged its ancestors — use it and stop.\n return provider.mergedConfig;\n }\n if (provider.presets) layers.push(provider.presets);\n }\n el = el.parentElement;\n }\n if (!layers.length) return null;\n // layers collected inner→outer while walking up; merge outer first, inner last.\n return layers.reduceRight(\n (acc, layer) => mergePresetsConfig(acc, layer),\n {} as ComponentPresetsConfig,\n );\n}\n\n/**\n * Resolve the active prop bag for a component: `defaults[key]` ← `presets[key][name]`.\n * Any prop key present in that bag can be applied to the instance.\n *\n * A named preset with `$inheritDefaults: false` is used standalone, so keys it\n * omits fall through to the component built-in instead of `defaults`.\n */\nexport function getPresetLayer(\n config: ComponentPresetsConfig | null | undefined,\n componentKey: ComponentPresetKey,\n presetName?: string | null,\n): ComponentPropBag {\n const defaults = mergeAliasBags(config?.defaults, componentKey);\n const namedMap = mergeAliasNamedMaps(config?.presets, componentKey);\n const named =\n presetName && namedMap[presetName] ? namedMap[presetName]! : null;\n\n const merged =\n named && named.$inheritDefaults === false\n ? { ...named }\n : { ...defaults, ...(named ?? {}) };\n\n for (const key of RESERVED_BAG_KEYS) delete merged[key];\n return merged;\n}\n\n/** Per-host map of prop → value before presets overwrote it (for revert). */\nconst presetRestoreValues = new WeakMap<HTMLElement, Map<string, unknown>>();\n\nexport type ApplyPresetLayerOptions = {\n /** Extra keys never written from presets. */\n skipKeys?: string[];\n};\n\n/**\n * Write every key from the preset layer onto the host (any component prop).\n * Skips user-owned attributes / props. Remembers prior values so removing a\n * key from the provider config restores the built-in / prior value.\n *\n * Before writing, detects divergence: if the host value no longer matches the\n * last preset-applied value, that prop is marked user-owned (property-only\n * overrides after first apply). Also locks in framework property bindings that\n * differ from the constructor snapshot before the first write for that key.\n *\n * @returns true if any host property changed\n */\nexport function applyPresetLayer(\n host: HTMLElement,\n layer: ComponentPropBag,\n options?: ApplyPresetLayerOptions,\n): boolean {\n refreshUserAttributes(host);\n detectPreApplyFrameworkProps(host, layer);\n detectDivergedUserProps(host);\n\n const skip = new Set([\n ...PRESET_SKIP_KEYS,\n ...(options?.skipKeys ?? []),\n ]);\n const restore = presetRestoreValues.get(host) ?? new Map<string, unknown>();\n const applied = lastPresetApplied.get(host) ?? new Map<string, unknown>();\n let changed = false;\n const record = host as HTMLElement & Record<string, unknown>;\n\n // Drop / revert keys no longer provided by the layer.\n for (const key of [...restore.keys()]) {\n if (\n Object.prototype.hasOwnProperty.call(layer, key) &&\n layer[key] !== undefined\n ) {\n continue;\n }\n if (!isUserSetProp(host, key) && restore.has(key)) {\n const prev = restore.get(key);\n if (record[key] !== prev) {\n record[key] = prev;\n changed = true;\n }\n }\n restore.delete(key);\n applied.delete(key);\n }\n\n // Apply all keys in the layer (full prop surface — not a whitelist).\n for (const [key, value] of Object.entries(layer)) {\n if (skip.has(key) || value === undefined) continue;\n if (isUserSetProp(host, key)) {\n applied.delete(key);\n continue;\n }\n if (!restore.has(key)) {\n restore.set(key, record[key]);\n }\n if (record[key] !== value) {\n record[key] = value;\n changed = true;\n }\n applied.set(key, value);\n }\n\n presetRestoreValues.set(host, restore);\n lastPresetApplied.set(host, applied);\n return changed;\n}\n\n/**\n * Clear preset-applied props and restore saved built-ins (e.g. when paused in a group).\n */\nexport function clearAppliedPresetLayer(host: HTMLElement): boolean {\n const restore = presetRestoreValues.get(host);\n if (!restore?.size) return false;\n const record = host as HTMLElement & Record<string, unknown>;\n let changed = false;\n for (const [key, prev] of restore) {\n if (isUserSetProp(host, key)) continue;\n if (record[key] !== prev) {\n record[key] = prev;\n changed = true;\n }\n }\n restore.clear();\n lastPresetApplied.get(host)?.clear();\n return changed;\n}\n\n/**\n * Resolve effective props for styling / behavior without mutating the host.\n * When `keys` is omitted, every key in the preset layer is considered.\n * Skips keys the user set via attributes.\n */\nexport function resolveComponentProps<T extends Record<string, unknown>>(\n options: ResolveComponentPropsOptions<T>,\n): T {\n const { host, componentKey, presetName, config, values, keys } = options;\n const layer = getPresetLayer(config, componentKey, presetName);\n const keysToApply =\n keys ?? (Object.keys(layer) as Array<keyof T & string>);\n\n const out = { ...values };\n for (const key of keysToApply) {\n const k = key as string;\n if (isUserSetProp(host, k)) continue;\n if (Object.prototype.hasOwnProperty.call(layer, k) && layer[k] !== undefined) {\n (out as Record<string, unknown>)[k] = layer[k];\n }\n }\n return out;\n}\n"],"names":["RESERVED_BAG_KEYS","Set","presetKeyAliases","key","k","String","trim","aliases","startsWith","add","slice","lookupPresetSection","section","alias","Object","prototype","hasOwnProperty","call","toPresetTagKey","configContext","createContext","camelToKebab","name","replace","toLowerCase","initialUserAttrs","WeakMap","userOwnedProps","lastPresetApplied","builtInPropSnapshots","PRESET_SKIP_KEYS","captureInitialUserAttributes","host","has","set","getAttributeNames","captureBuiltInPropSnapshot","snap","Map","record","meta","constructor","elementProperties","prop","keys","finalizeBuiltInPropSnapshot","get","value","refreshUserAttributes","markUserSetProp","isUserSetProp","kebab","initial","hasAttribute","mergePresetsConfig","parent","child","p","c","defaults","source","bag","entries","tag","presets","comp","named","mergedNamed","isSkyCompositeInternal","ShadowRoot","root","getRootNode","localName","findNearestPresetsConfig","layers","el","parentElement","provider","mergedConfig","push","length","reduceRight","acc","layer","getPresetLayer","config","componentKey","presetName","out","mergeAliasBags","namedMap","mergeAliasNamedMaps","merged","$inheritDefaults","presetRestoreValues","applyPresetLayer","options","size","applied","detectPreApplyFrameworkProps","appliedValue","detectDivergedUserProps","skip","skipKeys","restore","changed","prev","delete","clearAppliedPresetLayer","clear","resolveComponentProps","values","keysToApply"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./color-resolver.js";export{applyPresetLayer,camelToKebab,captureBuiltInPropSnapshot,captureInitialUserAttributes,clearAppliedPresetLayer,configContext,finalizeBuiltInPropSnapshot,findNearestPresetsConfig,getPresetLayer,isUserSetProp,lookupPresetSection,markUserSetProp,mergePresetsConfig,presetKeyAliases,refreshUserAttributes,resolveComponentProps,toPresetTagKey}from"./component-presets.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./contrast-color.js";export{resolveRadius}from"./size-resolver.js";
|
|
1
|
+
export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./color-resolver.js";export{applyPresetLayer,camelToKebab,captureBuiltInPropSnapshot,captureInitialUserAttributes,clearAppliedPresetLayer,configContext,finalizeBuiltInPropSnapshot,findNearestPresetsConfig,getPresetLayer,isSkyCompositeInternal,isUserSetProp,lookupPresetSection,markUserSetProp,mergePresetsConfig,presetKeyAliases,refreshUserAttributes,resolveComponentProps,toPresetTagKey}from"./component-presets.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./contrast-color.js";export{resolveRadius}from"./size-resolver.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{html}from"lit";export{AnimationController}from"./helper/controllers/animation-controller.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./helper/utils/contrast-color.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./helper/utils/color-resolver.js";export{FormControlBase}from"./helper/internals/form-control-base.js";export{PopoverController}from"./helper/controllers/popover-controller.js";export{PresetController}from"./helper/controllers/preset-controller.js";export{SkyAlert}from"./sky-alert/sky-alert.js";export{SkyAppbar}from"./sky-appbar/sky-appbar.js";export{SkyAvatar}from"./sky-avatar/sky-avatar.js";export{SkyBadge}from"./sky-badge/sky-badge.js";export{SkyButton}from"./sky-button/sky-button.js";export{SkyCard}from"./sky-card/sky-card.js";export{SkyCheckbox}from"./sky-checkbox/sky-checkbox.js";export{SkyChip}from"./sky-chip/sky-chip.js";export{SkyCol}from"./sky-col/sky-col.js";export{
|
|
1
|
+
export{html}from"lit";export{AnimationController}from"./helper/controllers/animation-controller.js";export{COMBOBOX_RENDERERS_STATE_KEY,SkyCombobox}from"./sky-combobox/sky-combobox.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./helper/utils/contrast-color.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./helper/utils/color-resolver.js";export{FormControlBase}from"./helper/internals/form-control-base.js";export{PopoverController}from"./helper/controllers/popover-controller.js";export{PresetController}from"./helper/controllers/preset-controller.js";export{SkyAlert}from"./sky-alert/sky-alert.js";export{SkyAppbar}from"./sky-appbar/sky-appbar.js";export{SkyAvatar}from"./sky-avatar/sky-avatar.js";export{SkyBadge}from"./sky-badge/sky-badge.js";export{SkyButton}from"./sky-button/sky-button.js";export{SkyCard}from"./sky-card/sky-card.js";export{SkyCheckbox}from"./sky-checkbox/sky-checkbox.js";export{SkyChip}from"./sky-chip/sky-chip.js";export{SkyCol}from"./sky-col/sky-col.js";export{SkyDialog}from"./sky-dialog/sky-dialog.js";export{SkyDivider}from"./sky-divider/sky-divider.js";export{SkyFlexbox}from"./sky-flexbox/sky-flexbox.js";export{SkyFlexcol}from"./sky-flexcol/sky-flexcol.js";export{SkyForm}from"./sky-form/sky-form.js";export{SkyGrid}from"./sky-grid/sky-grid.js";export{SkyIcon}from"./sky-icon/sky-icon.js";export{SkyImage}from"./sky-image/sky-image.js";export{SkyInput}from"./sky-input/sky-input.js";export{SkyList}from"./sky-list/sky-list.js";export{SkyListitem}from"./sky-listitem/sky-listitem.js";export{SkyRadio}from"./sky-radio/sky-radio.js";export{SkyRow}from"./sky-row/sky-row.js";export{SkySheet,resolveSheetRadius}from"./sky-sheet/sky-sheet.js";export{SkySimpleTable}from"./sky-simple-table/sky-simple-table.js";export{SkyThemeProvider,defaultTheme,getCurrentTheme,getThemePreference,mergeTheme,onThemeChange,resolveActualTheme,themeContext}from"./sky-theme-provider/sky-theme-provider.js";export{applyPresetLayer,camelToKebab,captureBuiltInPropSnapshot,captureInitialUserAttributes,clearAppliedPresetLayer,configContext,finalizeBuiltInPropSnapshot,findNearestPresetsConfig,getPresetLayer,isSkyCompositeInternal,isUserSetProp,lookupPresetSection,markUserSetProp,mergePresetsConfig,presetKeyAliases,refreshUserAttributes,resolveComponentProps,toPresetTagKey}from"./helper/utils/component-presets.js";export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./helper/iconify-offline.js";export{resolveRadius}from"./helper/utils/size-resolver.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -26,6 +26,44 @@ export type SkyComboboxIconClickDetail = {
|
|
|
26
26
|
export type SkyComboboxAddNewOptionDetail = {
|
|
27
27
|
value: string;
|
|
28
28
|
};
|
|
29
|
+
/** Reserved key on `customRenderers` for renderer UI state (not an option renderer). */
|
|
30
|
+
export declare const COMBOBOX_RENDERERS_STATE_KEY = "$rendererState";
|
|
31
|
+
export type SkyComboboxRendererStateApi = {
|
|
32
|
+
rendererState: Readonly<Record<string, unknown>>;
|
|
33
|
+
patchRendererState: (patch: Record<string, unknown>) => void;
|
|
34
|
+
};
|
|
35
|
+
export type SkyComboboxOptionRenderContext = SkyComboboxRendererStateApi & {
|
|
36
|
+
/** Index within the currently filtered dropdown list. */
|
|
37
|
+
index: number;
|
|
38
|
+
/** Index in the original `options` array. */
|
|
39
|
+
sourceIndex: number;
|
|
40
|
+
/** Plain display label (no highlight markup). */
|
|
41
|
+
label: string;
|
|
42
|
+
/** Search-highlighted label HTML string (same as default option text). */
|
|
43
|
+
highlightedLabel: string;
|
|
44
|
+
selected: boolean;
|
|
45
|
+
/** Keyboard / pointer active row. */
|
|
46
|
+
active: boolean;
|
|
47
|
+
multiSelect: boolean;
|
|
48
|
+
};
|
|
49
|
+
export type SkyComboboxSelectedRenderContext = SkyComboboxRendererStateApi & {
|
|
50
|
+
selectedItems: any[];
|
|
51
|
+
/** Index within `selectedItems`. */
|
|
52
|
+
index: number;
|
|
53
|
+
multiSelect: boolean;
|
|
54
|
+
multiDisplay: SkyComboboxMultiDisplay;
|
|
55
|
+
/** Default plain label for this option. */
|
|
56
|
+
label: string;
|
|
57
|
+
};
|
|
58
|
+
export type SkyComboboxOptionRenderer = (option: unknown, ctx: SkyComboboxOptionRenderContext) => unknown;
|
|
59
|
+
export type SkyComboboxSelectedRenderer = (option: unknown, ctx: SkyComboboxSelectedRenderContext) => unknown;
|
|
60
|
+
export type SkyComboboxCustomRenderers = {
|
|
61
|
+
/** Custom dropdown option row content (host keeps checkbox / selected chrome). */
|
|
62
|
+
option?: SkyComboboxOptionRenderer;
|
|
63
|
+
/** Custom selected-value / chip label content. */
|
|
64
|
+
selected?: SkyComboboxSelectedRenderer;
|
|
65
|
+
[COMBOBOX_RENDERERS_STATE_KEY]?: Record<string, unknown>;
|
|
66
|
+
};
|
|
29
67
|
/**
|
|
30
68
|
* @element sky-combobox
|
|
31
69
|
*
|
|
@@ -101,6 +139,7 @@ export type SkyComboboxAddNewOptionDetail = {
|
|
|
101
139
|
* @property {boolean} emitFullObject - Emits full option objects in events.
|
|
102
140
|
* @property {string} emittedKey - Key emitted from object options when `emitFullObject` is false.
|
|
103
141
|
* @property {string} displayKey - Key used for visual labels in object options.
|
|
142
|
+
* @property {SkyComboboxCustomRenderers} customRenderers - Named renderers: `option` (dropdown row), `selected` (value/chip label), optional `$rendererState`.
|
|
104
143
|
* @property {number} visibleChips - Number of visible chips before `+N` overflow chip.
|
|
105
144
|
* @property {number} chipSize - Maximum label length for each chip.
|
|
106
145
|
* @property {string} color - Accent color token/CSS color.
|
|
@@ -129,6 +168,7 @@ export type SkyComboboxAddNewOptionDetail = {
|
|
|
129
168
|
* @method closeDropdown Closes the combobox dropdown.
|
|
130
169
|
* @method clearSelection Clears current selection if allowed.
|
|
131
170
|
* @method reset Resets combobox state and clears validation UI.
|
|
171
|
+
* @method patchRendererState Merges keys into `customRenderers.$rendererState` and re-renders.
|
|
132
172
|
*
|
|
133
173
|
* @example
|
|
134
174
|
* ```html
|
|
@@ -174,6 +214,13 @@ export declare class SkyCombobox extends FormControlBase {
|
|
|
174
214
|
emitFullObject: boolean;
|
|
175
215
|
emittedKey: string;
|
|
176
216
|
displayKey: string;
|
|
217
|
+
private _customRenderers;
|
|
218
|
+
/**
|
|
219
|
+
* Named custom renderers for option rows and selected-value labels.
|
|
220
|
+
* Coerces null/undefined to `{}` for safe framework binding.
|
|
221
|
+
*/
|
|
222
|
+
get customRenderers(): SkyComboboxCustomRenderers;
|
|
223
|
+
set customRenderers(value: SkyComboboxCustomRenderers | null | undefined);
|
|
177
224
|
addOption: boolean;
|
|
178
225
|
validationArrayFormat: boolean;
|
|
179
226
|
prefix: string;
|
|
@@ -205,6 +252,7 @@ export declare class SkyCombobox extends FormControlBase {
|
|
|
205
252
|
private hasLeftIcon;
|
|
206
253
|
private hasRightIcon;
|
|
207
254
|
private optionSlotSet;
|
|
255
|
+
private _rendererRuntimeState;
|
|
208
256
|
private inputWrapperEl;
|
|
209
257
|
private dropdownEl;
|
|
210
258
|
private hiddenDropdownEl;
|
|
@@ -292,6 +340,15 @@ export declare class SkyCombobox extends FormControlBase {
|
|
|
292
340
|
private handleBlur;
|
|
293
341
|
updated(changedProperties: Map<string, unknown>): void;
|
|
294
342
|
willUpdate(changedProperties: Map<string, unknown>): void;
|
|
343
|
+
/** Merges runtime renderer state (from `customRenderers.$rendererState`) and re-renders. */
|
|
344
|
+
patchRendererState(patch: Record<string, unknown>): void;
|
|
345
|
+
private syncRendererStateFromProp;
|
|
346
|
+
private rendererStateApi;
|
|
347
|
+
private buildOptionRenderContext;
|
|
348
|
+
private buildSelectedRenderContext;
|
|
349
|
+
private renderOptionContent;
|
|
350
|
+
private renderSelectedLabel;
|
|
351
|
+
private renderSelectedSummaryLabel;
|
|
295
352
|
private syncSelectedItemsWithValue;
|
|
296
353
|
private filterOptions;
|
|
297
354
|
/** Emit search query for hosts / `v-model:search-query` when `searchQuery` changes outside the search input handler. */
|
|
@@ -328,6 +385,13 @@ export declare class SkyCombobox extends FormControlBase {
|
|
|
328
385
|
toggleDropdown(event: MouseEvent): void;
|
|
329
386
|
renderDropdown(): import("lit-html").TemplateResult<1>;
|
|
330
387
|
getOptionValue(option: any): any;
|
|
388
|
+
/**
|
|
389
|
+
* Stable string key for comparing options / selection identity.
|
|
390
|
+
* Prefer `emittedKey` when present on object options; for other objects use
|
|
391
|
+
* JSON.stringify — never String(object) ("[object Object]"), which makes every
|
|
392
|
+
* option look selected when `emitFullObject` is true.
|
|
393
|
+
*/
|
|
394
|
+
private optionKey;
|
|
331
395
|
getOptionLabel(option: any): string;
|
|
332
396
|
renderValidationErrors(): import("lit-html").TemplateResult<1> | null;
|
|
333
397
|
getErrorMessages(): string[];
|