@sky.ui/core 0.0.52 → 0.0.54

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.
Files changed (38) hide show
  1. package/dist/custom-elements.json +4325 -4219
  2. package/dist/helper/index.js +1 -1
  3. package/dist/helper/utils/index.d.ts +1 -0
  4. package/dist/helper/utils/index.js +1 -1
  5. package/dist/helper/utils/stable-array.d.ts +6 -0
  6. package/dist/helper/utils/stable-array.js +2 -0
  7. package/dist/helper/utils/stable-array.js.map +1 -0
  8. package/dist/index.js +1 -1
  9. package/dist/sky-avatar/sky-avatar.js +5 -5
  10. package/dist/sky-avatar/sky-avatar.js.map +1 -1
  11. package/dist/sky-chip/sky-chip.d.ts +8 -2
  12. package/dist/sky-chip/sky-chip.js +10 -10
  13. package/dist/sky-chip/sky-chip.js.map +1 -1
  14. package/dist/sky-combobox/sky-combobox.d.ts +2 -0
  15. package/dist/sky-combobox/sky-combobox.js +16 -16
  16. package/dist/sky-combobox/sky-combobox.js.map +1 -1
  17. package/dist/sky-flexbox/sky-flexbox.d.ts +2 -0
  18. package/dist/sky-flexbox/sky-flexbox.js +3 -3
  19. package/dist/sky-flexbox/sky-flexbox.js.map +1 -1
  20. package/dist/sky-form/sky-form.js +7 -7
  21. package/dist/sky-form/sky-form.js.map +1 -1
  22. package/dist/sky-image/sky-image.js +5 -5
  23. package/dist/sky-image/sky-image.js.map +1 -1
  24. package/dist/sky-input/sky-input.js +6 -6
  25. package/dist/sky-input/sky-input.js.map +1 -1
  26. package/dist/sky-list/sky-list.js +3 -3
  27. package/dist/sky-list/sky-list.js.map +1 -1
  28. package/dist/sky-listitem/sky-listitem.d.ts +1 -0
  29. package/dist/sky-listitem/sky-listitem.js +4 -2
  30. package/dist/sky-listitem/sky-listitem.js.map +1 -1
  31. package/dist/sky-radio/sky-radio.js +1 -1
  32. package/dist/sky-radio/sky-radio.js.map +1 -1
  33. package/dist/sky-simple-table/sky-simple-table.d.ts +7 -2
  34. package/dist/sky-simple-table/sky-simple-table.js +9 -9
  35. package/dist/sky-simple-table/sky-simple-table.js.map +1 -1
  36. package/dist/sky-theme-provider/sky-theme-provider.js +2 -2
  37. package/dist/sky-theme-provider/sky-theme-provider.js.map +1 -1
  38. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./iconify-offline.js";export{AnimationController}from"./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"./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"./utils/color-resolver.js";export{FormControlBase}from"./internals/form-control-base.js";export{PopoverController}from"./controllers/popover-controller.js";export{PresetController}from"./controllers/preset-controller.js";export{applyPresetLayer,camelToKebab,captureBuiltInPropSnapshot,captureInitialUserAttributes,clearAppliedPresetLayer,configContext,finalizeBuiltInPropSnapshot,findNearestPresetsConfig,getPresetLayer,isSkyCompositeInternal,isUserSetProp,lookupPresetSection,markUserSetProp,mergePresetsConfig,presetKeyAliases,refreshUserAttributes,resolveComponentProps,toPresetTagKey}from"./utils/component-presets.js";export{resolveRadius}from"./utils/size-resolver.js";
1
+ export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./iconify-offline.js";export{AnimationController}from"./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"./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"./utils/color-resolver.js";export{EMPTY_ARRAY,arrayPropHasChanged,coerceArray}from"./utils/stable-array.js";export{FormControlBase}from"./internals/form-control-base.js";export{PopoverController}from"./controllers/popover-controller.js";export{PresetController}from"./controllers/preset-controller.js";export{applyPresetLayer,camelToKebab,captureBuiltInPropSnapshot,captureInitialUserAttributes,clearAppliedPresetLayer,configContext,finalizeBuiltInPropSnapshot,findNearestPresetsConfig,getPresetLayer,isSkyCompositeInternal,isUserSetProp,lookupPresetSection,markUserSetProp,mergePresetsConfig,presetKeyAliases,refreshUserAttributes,resolveComponentProps,toPresetTagKey}from"./utils/component-presets.js";export{resolveRadius}from"./utils/size-resolver.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -2,3 +2,4 @@ export * from "./color-resolver";
2
2
  export * from "./component-presets";
3
3
  export * from "./contrast-color";
4
4
  export * from "./size-resolver";
5
+ export * from "./stable-array";
@@ -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,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";
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";export{EMPTY_ARRAY,arrayPropHasChanged,coerceArray}from"./stable-array.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,6 @@
1
+ /** Shared empty sentinel so null/undefined/[] rebinds do not look like a new value. */
2
+ export declare const EMPTY_ARRAY: never[];
3
+ /** Lit `hasChanged` for array props: same ref or both empty → no update. */
4
+ export declare function arrayPropHasChanged(value: unknown, old: unknown): boolean;
5
+ /** Coerce null/undefined/empty to the shared empty sentinel. */
6
+ export declare function coerceArray<T>(value: T[] | null | undefined): T[];
@@ -0,0 +1,2 @@
1
+ const r=Object.freeze([]);function n(n,t){const e=Array.isArray(n)?n:r,a=Array.isArray(t)?t:r;return e!==a&&(0!==e.length||0!==a.length)}function t(n){return Array.isArray(n)&&n.length>0?n:r}export{r as EMPTY_ARRAY,n as arrayPropHasChanged,t as coerceArray};
2
+ //# sourceMappingURL=stable-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-array.js","sources":["../../../src/helper/utils/stable-array.ts"],"sourcesContent":["/** Shared empty sentinel so null/undefined/[] rebinds do not look like a new value. */\nexport const EMPTY_ARRAY: never[] = Object.freeze([]) as unknown as never[];\n\n/** Lit `hasChanged` for array props: same ref or both empty → no update. */\nexport function arrayPropHasChanged(value: unknown, old: unknown): boolean {\n const next = Array.isArray(value) ? value : EMPTY_ARRAY;\n const prev = Array.isArray(old) ? old : EMPTY_ARRAY;\n if (next === prev) return false;\n if (next.length === 0 && prev.length === 0) return false;\n return true;\n}\n\n/** Coerce null/undefined/empty to the shared empty sentinel. */\nexport function coerceArray<T>(value: T[] | null | undefined): T[] {\n return Array.isArray(value) && value.length > 0\n ? value\n : (EMPTY_ARRAY as unknown as T[]);\n}\n"],"names":["EMPTY_ARRAY","Object","freeze","arrayPropHasChanged","value","old","next","Array","isArray","prev","length","coerceArray"],"mappings":"AACO,MAAMA,EAAuBC,OAAOC,OAAO,IAG3C,SAASC,EAAoBC,EAAgBC,GAClD,MAAMC,EAAOC,MAAMC,QAAQJ,GAASA,EAAQJ,EACtCS,EAAOF,MAAMC,QAAQH,GAAOA,EAAML,EACxC,OAAIM,IAASG,IACO,IAAhBH,EAAKI,QAAgC,IAAhBD,EAAKC,OAEhC,CAGO,SAASC,EAAeP,GAC7B,OAAOG,MAAMC,QAAQJ,IAAUA,EAAMM,OAAS,EAC1CN,EACCJ,CACP"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
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";
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{EMPTY_ARRAY,arrayPropHasChanged,coerceArray}from"./helper/utils/stable-array.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
@@ -1,25 +1,25 @@
1
- import{css as t,LitElement as e,nothing as r,html as i}from"lit";import{property as o,state as a,customElement as s}from"lit/decorators.js";import{when as n}from"lit/directives/when.js";import{keyed as l}from"lit/directives/keyed.js";import{resolveRadius as d}from"../helper/utils/size-resolver.js";import{resolveColor as p}from"../helper/utils/color-resolver.js";import{styleMap as c}from"lit/directives/style-map.js";import{classMap as h}from"lit/directives/class-map.js";import{PresetController as y}from"../helper/controllers/preset-controller.js";var v=Object.defineProperty,g=Object.getOwnPropertyDescriptor,m=(t,e,r,i)=>{for(var o,a=i>1?void 0:i?g(e,r):e,s=t.length-1;s>=0;s--)(o=t[s])&&(a=(i?o(e,r,a):o(a))||a);return i&&a&&v(e,r,a),a};const b={sm:"var(--sky-space-8, 2rem)",md:"var(--sky-space-10, 2.5rem)",lg:"var(--sky-space-12, 3rem)"},f={sm:32,md:40,lg:48};let u=class extends e{constructor(){super(...arguments),this.size="50px",this.image="",this.fit="cover",this.radius="md",this.alt="",this.color="dark",this.outline="",this.outlineOffset="2px",this.loading=!1,this.disabled=!1,this.interactive=!1,this.shadow=!1,this._imageError=!1,this.preset="",this._presets=new y(this),this._onImageLoad=()=>{this._imageError=!1},this._onImageError=()=>{this._imageError=!0}}updated(t){super.updated(t),t.has("image")&&(this._imageError=!1);const e=b[this.size]??this.size;this.style.setProperty("--avatar-size",e),this.style.setProperty("--avatar-bg-size","contain"===this.fit?"contain":"cover"),this.style.setProperty("--avatar-border-radius",d(this.radius)),this.color&&this.style.setProperty("--slot-text-color",p(this.color)),this.adjustSpinnerSize()}_handleInteractiveClick(t){this.interactive&&!this.disabled&&(t.stopPropagation(),this.dispatchEvent(new Event("click",{bubbles:!0,composed:!0})))}_handleInteractiveKeydown(t){this.interactive&&!this.disabled&&("Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.dispatchEvent(new Event("click",{bubbles:!0,composed:!0}))))}adjustSpinnerSize(){const t=f[this.size]??parseFloat(this.size);if(Number.isFinite(t)){const e=.25*t,r=this.shadowRoot?.querySelector(".spinner");r&&(r.style.width=`${e}px`,r.style.height=`${e}px`,r.style.borderWidth=`${Math.max(1,e/10)}px`)}}render(){const t=this.image&&!this._imageError,e={};t&&(e.backgroundImage=`url(${encodeURI(this.image)})`),this.outline&&(e.outline=this.outline),this.outlineOffset&&(e.outlineOffset=this.outlineOffset);const o=this.interactive?"button":t&&this.alt?"img":r,a=this.interactive&&this.alt||t&&this.alt?this.alt:r;return i`
1
+ import{css as t,LitElement as e,nothing as i,html as r}from"lit";import{property as o,state as a,customElement as s}from"lit/decorators.js";import{when as n}from"lit/directives/when.js";import{keyed as l}from"lit/directives/keyed.js";import{resolveRadius as d}from"../helper/utils/size-resolver.js";import{resolveColor as p}from"../helper/utils/color-resolver.js";import{styleMap as c}from"lit/directives/style-map.js";import{classMap as h}from"lit/directives/class-map.js";import{PresetController as y}from"../helper/controllers/preset-controller.js";var v=Object.defineProperty,g=Object.getOwnPropertyDescriptor,m=(t,e,i,r)=>{for(var o,a=r>1?void 0:r?g(e,i):e,s=t.length-1;s>=0;s--)(o=t[s])&&(a=(r?o(e,i,a):o(a))||a);return r&&a&&v(e,i,a),a};const b={sm:"var(--sky-space-8, 2rem)",md:"var(--sky-space-10, 2.5rem)",lg:"var(--sky-space-12, 3rem)"},f={sm:32,md:40,lg:48};let u=class extends e{constructor(){super(...arguments),this.size="50px",this.image="",this.fit="cover",this.radius="md",this.alt="",this.color="dark",this.outline="",this.outlineOffset="2px",this.loading=!1,this.disabled=!1,this.interactive=!1,this.shadow=!1,this._imageError=!1,this.preset="",this._presets=new y(this),this._onImageLoad=()=>{this._imageError=!1},this._onImageError=()=>{this._imageError=!0}}updated(t){if(super.updated(t),t.has("image")&&(this._imageError=!1),t.has("size")||t.has("fit")||t.has("radius")||t.has("color")){const t=b[this.size]??this.size;this.style.setProperty("--avatar-size",t),this.style.setProperty("--avatar-bg-size","contain"===this.fit?"contain":"cover"),this.style.setProperty("--avatar-border-radius",d(this.radius)),this.color&&this.style.setProperty("--slot-text-color",p(this.color))}(t.has("size")||t.has("loading"))&&this.adjustSpinnerSize()}_handleInteractiveClick(t){this.interactive&&!this.disabled&&(t.stopPropagation(),this.dispatchEvent(new Event("click",{bubbles:!0,composed:!0})))}_handleInteractiveKeydown(t){this.interactive&&!this.disabled&&("Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.dispatchEvent(new Event("click",{bubbles:!0,composed:!0}))))}adjustSpinnerSize(){const t=f[this.size]??parseFloat(this.size);if(Number.isFinite(t)){const e=.25*t,i=this.shadowRoot?.querySelector(".spinner");i&&(i.style.width=`${e}px`,i.style.height=`${e}px`,i.style.borderWidth=`${Math.max(1,e/10)}px`)}}render(){const t=this.image&&!this._imageError,e={};t&&(e.backgroundImage=`url(${encodeURI(this.image)})`),this.outline&&(e.outline=this.outline),this.outlineOffset&&(e.outlineOffset=this.outlineOffset);const o=this.interactive?"button":t&&this.alt?"img":i,a=this.interactive&&this.alt||t&&this.alt?this.alt:i;return r`
2
2
  <div
3
3
  class=${h({avatar:!0,"avatar--interactive":!!this.interactive})}
4
4
  part="avatar"
5
5
  style=${c(e)}
6
6
  role=${o}
7
7
  aria-label=${a}
8
- tabindex=${this.interactive&&!this.disabled?"0":r}
8
+ tabindex=${this.interactive&&!this.disabled?"0":i}
9
9
  @click=${this._handleInteractiveClick}
10
10
  @keydown=${this._handleInteractiveKeydown}
11
11
  >
12
- ${this.image?i`<img
12
+ ${this.image?r`<img
13
13
  class="image-probe"
14
14
  src=${this.image}
15
15
  alt=""
16
16
  @load=${this._onImageLoad}
17
17
  @error=${this._onImageError}
18
- />`:r}
18
+ />`:i}
19
19
  <div class="loading-overlay" part="loading-overlay">
20
20
  <div class="spinner" part="spinner"></div>
21
21
  </div>
22
- ${l(t?"_img_":"_slot_",n(!t,()=>i`<slot></slot>`,()=>r))}
22
+ ${l(t?"_img_":"_slot_",n(!t,()=>r`<slot></slot>`,()=>i))}
23
23
  </div>
24
24
  `}};u.styles=t`
25
25
  :host {
@@ -1 +1 @@
1
- {"version":3,"file":"sky-avatar.js","sources":["../../src/sky-avatar/sky-avatar.ts"],"sourcesContent":["import { LitElement, html, css, PropertyValues, nothing } from \"lit\";\r\nimport { customElement, property, state } from \"lit/decorators.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { keyed } from \"lit/directives/keyed.js\";\r\nimport { resolveRadius } from \"../helper/utils/size-resolver\";\r\nimport { resolveColor } from \"../helper/utils/color-resolver\";\r\nimport { styleMap } from \"lit/directives/style-map.js\";\r\nimport { classMap } from \"lit/directives/class-map.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkyAvatarFit = \"cover\" | \"contain\";\r\n\r\nconst SIZE_PRESETS: Record<string, string> = {\r\n sm: \"var(--sky-space-8, 2rem)\",\r\n md: \"var(--sky-space-10, 2.5rem)\",\r\n lg: \"var(--sky-space-12, 3rem)\",\r\n};\r\n\r\nconst SIZE_PX: Record<string, number> = { sm: 32, md: 40, lg: 48 };\r\n\r\n\r\n/**\r\n * @element sky-avatar\r\n *\r\n * @summary Avatar that renders image content or fallback slot content with configurable size, radius, outline, and loading state.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/avatar\r\n *\r\n * @slot - Fallback content (e.g., initials or an icon) rendered when `image` is empty.\r\n *\r\n * @property {string} size - Avatar size: preset `sm` | `md` | `lg` or CSS length (for example `50px`).\r\n * @property {string} image - Image URL; fallback slot is shown on load error.\r\n * @property {SkyAvatarFit} fit - Image fill mode: `cover` (default) or `contain`.\r\n * @property {string} radius - Border radius token or CSS value.\r\n * @property {string} color - Token or CSS color applied to fallback slot content.\r\n * @property {string} alt - Accessible name when image content conveys meaning.\r\n * @property {string} outline - CSS `outline` value.\r\n * @property {string} outlineOffset - CSS `outline-offset` value.\r\n * @property {boolean} loading - Shows loading overlay when true.\r\n * @property {boolean} disabled - Dims and disables pointer interactions.\r\n * @property {boolean} interactive - Enables interactive behavior with keyboard/click activation.\r\n * @property {boolean} shadow - When true, applies solid surface, border ring, and elevation; no backdrop blur.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @csspart avatar - The avatar container element.\r\n * @csspart loading-overlay - The loading overlay container (shown when `loading` is true).\r\n * @csspart spinner - The spinner element shown when loading.\r\n *\r\n * @Behavior\r\n * - Applies image content when available; otherwise renders fallback slot content.\r\n * - Uses keyed rendering to reset avatar content when image availability changes.\r\n * - Scales spinner dimensions from resolved avatar size for numeric values.\r\n * - Respects reduced-motion preference by disabling spinner animation.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\r\n * JD\r\n * </sky-avatar>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\r\n * JD\r\n * </sky-avatar>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\r\n * JD\r\n * </sky-avatar>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-avatar\")\r\nexport class SkyAvatar extends LitElement {\r\n\r\n /** Avatar size: preset sm|md|lg or CSS length. @default \"50px\" */\r\n @property({ type: String }) size: string = \"50px\";\r\n\r\n /** Image URL. On error, slot is shown. @default \"\" */\r\n @property({ type: String }) image: string = \"\";\r\n\r\n /** How the image fills the avatar. @default \"cover\" */\r\n @property({ type: String, reflect: true }) fit: SkyAvatarFit = \"cover\";\r\n\r\n /** Border radius token or CSS value. @default \"md\" */\r\n @property({ type: String }) radius: string = \"md\";\r\n\r\n /** Accessible name when image is set. @default \"\" */\r\n @property({ type: String }) alt: string = \"\";\r\n\r\n /** Slot text/icon color token/CSS color. @default \"dark\" */\r\n @property({ type: String }) color: string = \"dark\";\r\n\r\n /** Outline string. @default \"\" */\r\n @property({ type: String }) outline: string = \"\";\r\n\r\n /** Outline offset value. @default \"2px\" */\r\n @property({ type: String }) outlineOffset: string = \"2px\";\r\n\r\n /** Loading state. @default false */\r\n @property({ type: Boolean, reflect: true }) loading: boolean = false;\r\n\r\n /** Disables the avatar. @default false */\r\n @property({ type: Boolean, reflect: true }) disabled: boolean = false;\r\n\r\n /** When true, focusable with focus ring and click. @default false */\r\n @property({ type: Boolean }) interactive: boolean = false;\r\n\r\n /**\r\n * Elevated ring styling (`border`, inset shadow). No backdrop blur on avatar media.\r\n * `false` (default) keeps the avatar minimal for inline use.\r\n */\r\n @property({ type: Boolean, reflect: true })\r\n shadow = false;\r\n\r\n /** True when image failed to load; show slot instead. */\r\n @state() private _imageError = false;\r\n\r\n\r\n\r\n /** Named prop preset from nearest `sky-config-provider`. */\r\n @property({ type: String, reflect: true }) preset = \"\";\r\n\r\n private _presets = new PresetController(this);\r\n\r\n static override styles = css`\r\n :host {\r\n display: inline-flex;\r\n line-height: 0;\r\n justify-content: center;\r\n align-items: center;\r\n }\r\n\r\n :host([disabled]) {\r\n opacity: var(--sky-opacity-disabled, 0.5);\r\n pointer-events: none;\r\n }\r\n\r\n .avatar {\r\n width: var(--avatar-size);\r\n height: var(--avatar-size);\r\n position: relative;\r\n background-size: var(--avatar-bg-size, cover);\r\n background-position: center;\r\n background-repeat: no-repeat;\r\n border-radius: var(--avatar-border-radius, var(--sky-radius-secondary));\r\n display: flex;\r\n color: var(--slot-text-color);\r\n justify-content: center;\r\n align-items: center;\r\n background-clip: padding-box;\r\n -webkit-background-clip: padding-box;\r\n box-sizing: border-box;\r\n overflow: hidden;\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n }\r\n\r\n :host([shadow]) .avatar {\r\n background-color: var(--sky-glass-solid);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-primary);\r\n border: var(--sky-border-primary);\r\n }\r\n\r\n :host([loading]) .avatar {\r\n will-change: transform;\r\n transform: translateZ(0);\r\n }\r\n\r\n .avatar:focus-visible {\r\n outline: none;\r\n box-shadow: var(--sky-focus-ring);\r\n }\r\n\r\n :host([shadow]) .avatar:focus-visible {\r\n box-shadow:\r\n var(--sky-focus-ring),\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-primary);\r\n }\r\n\r\n .avatar--interactive {\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n\r\n .image-probe {\r\n position: absolute;\r\n width: 0;\r\n height: 0;\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n\r\n ::slotted(*) {\r\n font-family: var(--sky-font);\r\n font-weight: var(--sky-font-weight-semibold, 600);\r\n font-size: calc(var(--avatar-size) * 0.38);\r\n line-height: 1;\r\n letter-spacing: var(--sky-letter-spacing-normal, 0);\r\n text-align: center;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n object-fit: contain;\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n }\r\n\r\n .loading-overlay {\r\n position: absolute;\r\n inset: 0;\r\n border-radius: inherit;\r\n background: var(--sky-overlay-secondary);\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n z-index: 1;\r\n visibility: hidden;\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n }\r\n :host([loading]) .loading-overlay {\r\n visibility: visible;\r\n }\r\n\r\n .spinner {\r\n border-width: 2px;\r\n border-style: solid;\r\n border-color: var(--sky-border-light);\r\n border-top-color: var(--slot-text-color, var(--sky-text-primary));\r\n border-radius: var(--sky-radius-full);\r\n width: 40px;\r\n height: 40px;\r\n animation: spin var(--sky-duration-slow, 1s) linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n 0% {\r\n transform: rotate(0deg);\r\n }\r\n 100% {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n :host([loading]) .avatar {\r\n will-change: auto;\r\n transform: none;\r\n }\r\n\r\n .spinner {\r\n animation: none;\r\n border-top-color: var(--slot-text-color, var(--sky-text-primary));\r\n opacity: var(--sky-opacity-muted, 0.7);\r\n }\r\n }\r\n `;\r\n\r\n override updated(changed: PropertyValues): void {\r\n super.updated(changed);\r\n\r\n if (changed.has(\"image\")) {\r\n this._imageError = false;\r\n }\r\n\r\n const resolvedSize = SIZE_PRESETS[this.size] ?? this.size;\r\n this.style.setProperty(\"--avatar-size\", resolvedSize);\r\n\r\n this.style.setProperty(\r\n \"--avatar-bg-size\",\r\n this.fit === \"contain\" ? \"contain\" : \"cover\",\r\n );\r\n\r\n this.style.setProperty(\r\n \"--avatar-border-radius\",\r\n resolveRadius(this.radius),\r\n );\r\n\r\n if (this.color) {\r\n this.style.setProperty(\"--slot-text-color\", resolveColor(this.color));\r\n }\r\n\r\n this.adjustSpinnerSize();\r\n }\r\n\r\n /** Marks image load success and keeps image rendering active. */\r\n private _onImageLoad = (): void => {\r\n this._imageError = false;\r\n };\r\n\r\n /** Marks image load failure and enables fallback slot rendering. */\r\n private _onImageError = (): void => {\r\n this._imageError = true;\r\n };\r\n\r\n /** Re-dispatches click in interactive mode for host-level consumers. */\r\n private _handleInteractiveClick(e: Event): void {\r\n if (!this.interactive || this.disabled) return;\r\n e.stopPropagation();\r\n this.dispatchEvent(new Event(\"click\", { bubbles: true, composed: true }));\r\n }\r\n\r\n /** Handles keyboard activation in interactive mode. */\r\n private _handleInteractiveKeydown(e: KeyboardEvent): void {\r\n if (!this.interactive || this.disabled) return;\r\n if (e.key === \"Enter\" || e.key === \" \") {\r\n e.preventDefault();\r\n this.dispatchEvent(new Event(\"click\", { bubbles: true, composed: true }));\r\n }\r\n }\r\n\r\n\r\n\r\n /** Derives spinner dimensions from current avatar size. */\r\n private adjustSpinnerSize(): void {\r\n const avatarSizePx =\r\n SIZE_PX[this.size] ?? parseFloat(this.size);\r\n if (Number.isFinite(avatarSizePx)) {\r\n const spinnerSize = avatarSizePx * 0.25;\r\n const spinner = this.shadowRoot?.querySelector<HTMLElement>(\".spinner\");\r\n if (spinner) {\r\n spinner.style.width = `${spinnerSize}px`;\r\n spinner.style.height = `${spinnerSize}px`;\r\n spinner.style.borderWidth = `${Math.max(1, spinnerSize / 10)}px`;\r\n }\r\n }\r\n }\r\n\r\n override render() {\r\n const showImage = this.image && !this._imageError;\r\n const avatarStyle: Record<string, string> = {};\r\n if (showImage) {\r\n avatarStyle[\"backgroundImage\"] = `url(${encodeURI(this.image)})`;\r\n }\r\n if (this.outline) {\r\n avatarStyle[\"outline\"] = this.outline;\r\n }\r\n if (this.outlineOffset) {\r\n avatarStyle[\"outlineOffset\"] = this.outlineOffset;\r\n }\r\n\r\n const role = this.interactive\r\n ? \"button\"\r\n : showImage && this.alt\r\n ? \"img\"\r\n : nothing;\r\n const ariaLabel =\r\n this.interactive && this.alt\r\n ? this.alt\r\n : showImage && this.alt\r\n ? this.alt\r\n : nothing;\r\n\r\n return html`\r\n <div\r\n class=${classMap({\r\n avatar: true,\r\n \"avatar--interactive\": !!this.interactive,\r\n })}\r\n part=\"avatar\"\r\n style=${styleMap(avatarStyle)}\r\n role=${role}\r\n aria-label=${ariaLabel}\r\n tabindex=${this.interactive && !this.disabled ? \"0\" : nothing}\r\n @click=${this._handleInteractiveClick}\r\n @keydown=${this._handleInteractiveKeydown}\r\n >\r\n ${this.image\r\n ? html`<img\r\n class=\"image-probe\"\r\n src=${this.image}\r\n alt=\"\"\r\n @load=${this._onImageLoad}\r\n @error=${this._onImageError}\r\n />`\r\n : nothing}\r\n <div class=\"loading-overlay\" part=\"loading-overlay\">\r\n <div class=\"spinner\" part=\"spinner\"></div>\r\n </div>\r\n ${keyed(\r\n showImage ? \"_img_\" : \"_slot_\",\r\n when(!showImage, () => html`<slot></slot>`, () => nothing),\r\n )}\r\n </div>\r\n `;\r\n }\r\n}\r\n"],"names":["SIZE_PRESETS","sm","md","lg","SIZE_PX","SkyAvatar","LitElement","constructor","super","arguments","this","size","image","fit","radius","alt","color","outline","outlineOffset","loading","disabled","interactive","shadow","_imageError","preset","_presets","PresetController","_onImageLoad","_onImageError","updated","changed","has","resolvedSize","style","setProperty","resolveRadius","resolveColor","adjustSpinnerSize","_handleInteractiveClick","e","stopPropagation","dispatchEvent","Event","bubbles","composed","_handleInteractiveKeydown","key","preventDefault","avatarSizePx","parseFloat","Number","isFinite","spinnerSize","spinner","shadowRoot","querySelector","width","height","borderWidth","Math","max","render","showImage","avatarStyle","encodeURI","role","nothing","ariaLabel","html","classMap","avatar","styleMap","keyed","when","styles","css","__decorateClass","property","type","String","prototype","reflect","Boolean","state","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"sky-avatar.js","sources":["../../src/sky-avatar/sky-avatar.ts"],"sourcesContent":["import { LitElement, html, css, PropertyValues, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { when } from \"lit/directives/when.js\";\nimport { keyed } from \"lit/directives/keyed.js\";\nimport { resolveRadius } from \"../helper/utils/size-resolver\";\nimport { resolveColor } from \"../helper/utils/color-resolver\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { PresetController } from \"../helper/controllers/preset-controller\";\n\nexport type SkyAvatarFit = \"cover\" | \"contain\";\n\nconst SIZE_PRESETS: Record<string, string> = {\n sm: \"var(--sky-space-8, 2rem)\",\n md: \"var(--sky-space-10, 2.5rem)\",\n lg: \"var(--sky-space-12, 3rem)\",\n};\n\nconst SIZE_PX: Record<string, number> = { sm: 32, md: 40, lg: 48 };\n\n\n/**\n * @element sky-avatar\n *\n * @summary Avatar that renders image content or fallback slot content with configurable size, radius, outline, and loading state.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://sky-ui.com/components/avatar\n *\n * @slot - Fallback content (e.g., initials or an icon) rendered when `image` is empty.\n *\n * @property {string} size - Avatar size: preset `sm` | `md` | `lg` or CSS length (for example `50px`).\n * @property {string} image - Image URL; fallback slot is shown on load error.\n * @property {SkyAvatarFit} fit - Image fill mode: `cover` (default) or `contain`.\n * @property {string} radius - Border radius token or CSS value.\n * @property {string} color - Token or CSS color applied to fallback slot content.\n * @property {string} alt - Accessible name when image content conveys meaning.\n * @property {string} outline - CSS `outline` value.\n * @property {string} outlineOffset - CSS `outline-offset` value.\n * @property {boolean} loading - Shows loading overlay when true.\n * @property {boolean} disabled - Dims and disables pointer interactions.\n * @property {boolean} interactive - Enables interactive behavior with keyboard/click activation.\n * @property {boolean} shadow - When true, applies solid surface, border ring, and elevation; no backdrop blur.\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\n *\n * @csspart avatar - The avatar container element.\n * @csspart loading-overlay - The loading overlay container (shown when `loading` is true).\n * @csspart spinner - The spinner element shown when loading.\n *\n * @Behavior\n * - Applies image content when available; otherwise renders fallback slot content.\n * - Uses keyed rendering to reset avatar content when image availability changes.\n * - Scales spinner dimensions from resolved avatar size for numeric values.\n * - Respects reduced-motion preference by disabling spinner animation.\n *\n * @example\n * ```html\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\n * JD\n * </sky-avatar>\n * ```\n * ```vue\n * <template>\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\n * JD\n * </sky-avatar>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return (\n * <sky-avatar size=\"56px\" radius=\"full\" color=\"primary\">\n * JD\n * </sky-avatar>\n * );\n * }\n * ```\n */\n@customElement(\"sky-avatar\")\nexport class SkyAvatar extends LitElement {\n\n /** Avatar size: preset sm|md|lg or CSS length. @default \"50px\" */\n @property({ type: String }) size: string = \"50px\";\n\n /** Image URL. On error, slot is shown. @default \"\" */\n @property({ type: String }) image: string = \"\";\n\n /** How the image fills the avatar. @default \"cover\" */\n @property({ type: String, reflect: true }) fit: SkyAvatarFit = \"cover\";\n\n /** Border radius token or CSS value. @default \"md\" */\n @property({ type: String }) radius: string = \"md\";\n\n /** Accessible name when image is set. @default \"\" */\n @property({ type: String }) alt: string = \"\";\n\n /** Slot text/icon color token/CSS color. @default \"dark\" */\n @property({ type: String }) color: string = \"dark\";\n\n /** Outline string. @default \"\" */\n @property({ type: String }) outline: string = \"\";\n\n /** Outline offset value. @default \"2px\" */\n @property({ type: String }) outlineOffset: string = \"2px\";\n\n /** Loading state. @default false */\n @property({ type: Boolean, reflect: true }) loading: boolean = false;\n\n /** Disables the avatar. @default false */\n @property({ type: Boolean, reflect: true }) disabled: boolean = false;\n\n /** When true, focusable with focus ring and click. @default false */\n @property({ type: Boolean }) interactive: boolean = false;\n\n /**\n * Elevated ring styling (`border`, inset shadow). No backdrop blur on avatar media.\n * `false` (default) keeps the avatar minimal for inline use.\n */\n @property({ type: Boolean, reflect: true })\n shadow = false;\n\n /** True when image failed to load; show slot instead. */\n @state() private _imageError = false;\n\n\n\n /** Named prop preset from nearest `sky-config-provider`. */\n @property({ type: String, reflect: true }) preset = \"\";\n\n private _presets = new PresetController(this);\n\n static override styles = css`\n :host {\n display: inline-flex;\n line-height: 0;\n justify-content: center;\n align-items: center;\n }\n\n :host([disabled]) {\n opacity: var(--sky-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n .avatar {\n width: var(--avatar-size);\n height: var(--avatar-size);\n position: relative;\n background-size: var(--avatar-bg-size, cover);\n background-position: center;\n background-repeat: no-repeat;\n border-radius: var(--avatar-border-radius, var(--sky-radius-secondary));\n display: flex;\n color: var(--slot-text-color);\n justify-content: center;\n align-items: center;\n background-clip: padding-box;\n -webkit-background-clip: padding-box;\n box-sizing: border-box;\n overflow: hidden;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n\n :host([shadow]) .avatar {\n background-color: var(--sky-glass-solid);\n box-shadow:\n var(--sky-box-shadow-inset),\n var(--sky-box-shadow-primary);\n border: var(--sky-border-primary);\n }\n\n :host([loading]) .avatar {\n will-change: transform;\n transform: translateZ(0);\n }\n\n .avatar:focus-visible {\n outline: none;\n box-shadow: var(--sky-focus-ring);\n }\n\n :host([shadow]) .avatar:focus-visible {\n box-shadow:\n var(--sky-focus-ring),\n var(--sky-box-shadow-inset),\n var(--sky-box-shadow-primary);\n }\n\n .avatar--interactive {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n .image-probe {\n position: absolute;\n width: 0;\n height: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n ::slotted(*) {\n font-family: var(--sky-font);\n font-weight: var(--sky-font-weight-semibold, 600);\n font-size: calc(var(--avatar-size) * 0.38);\n line-height: 1;\n letter-spacing: var(--sky-letter-spacing-normal, 0);\n text-align: center;\n display: flex;\n justify-content: center;\n align-items: center;\n object-fit: contain;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n\n .loading-overlay {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--sky-overlay-secondary);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1;\n visibility: hidden;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n :host([loading]) .loading-overlay {\n visibility: visible;\n }\n\n .spinner {\n border-width: 2px;\n border-style: solid;\n border-color: var(--sky-border-light);\n border-top-color: var(--slot-text-color, var(--sky-text-primary));\n border-radius: var(--sky-radius-full);\n width: 40px;\n height: 40px;\n animation: spin var(--sky-duration-slow, 1s) linear infinite;\n }\n\n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host([loading]) .avatar {\n will-change: auto;\n transform: none;\n }\n\n .spinner {\n animation: none;\n border-top-color: var(--slot-text-color, var(--sky-text-primary));\n opacity: var(--sky-opacity-muted, 0.7);\n }\n }\n `;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (changed.has(\"image\")) {\n this._imageError = false;\n }\n\n if (\n changed.has(\"size\") ||\n changed.has(\"fit\") ||\n changed.has(\"radius\") ||\n changed.has(\"color\")\n ) {\n const resolvedSize = SIZE_PRESETS[this.size] ?? this.size;\n this.style.setProperty(\"--avatar-size\", resolvedSize);\n\n this.style.setProperty(\n \"--avatar-bg-size\",\n this.fit === \"contain\" ? \"contain\" : \"cover\",\n );\n\n this.style.setProperty(\n \"--avatar-border-radius\",\n resolveRadius(this.radius),\n );\n\n if (this.color) {\n this.style.setProperty(\"--slot-text-color\", resolveColor(this.color));\n }\n }\n\n if (changed.has(\"size\") || changed.has(\"loading\")) {\n this.adjustSpinnerSize();\n }\n }\n\n /** Marks image load success and keeps image rendering active. */\n private _onImageLoad = (): void => {\n this._imageError = false;\n };\n\n /** Marks image load failure and enables fallback slot rendering. */\n private _onImageError = (): void => {\n this._imageError = true;\n };\n\n /** Re-dispatches click in interactive mode for host-level consumers. */\n private _handleInteractiveClick(e: Event): void {\n if (!this.interactive || this.disabled) return;\n e.stopPropagation();\n this.dispatchEvent(new Event(\"click\", { bubbles: true, composed: true }));\n }\n\n /** Handles keyboard activation in interactive mode. */\n private _handleInteractiveKeydown(e: KeyboardEvent): void {\n if (!this.interactive || this.disabled) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n this.dispatchEvent(new Event(\"click\", { bubbles: true, composed: true }));\n }\n }\n\n\n\n /** Derives spinner dimensions from current avatar size. */\n private adjustSpinnerSize(): void {\n const avatarSizePx =\n SIZE_PX[this.size] ?? parseFloat(this.size);\n if (Number.isFinite(avatarSizePx)) {\n const spinnerSize = avatarSizePx * 0.25;\n const spinner = this.shadowRoot?.querySelector<HTMLElement>(\".spinner\");\n if (spinner) {\n spinner.style.width = `${spinnerSize}px`;\n spinner.style.height = `${spinnerSize}px`;\n spinner.style.borderWidth = `${Math.max(1, spinnerSize / 10)}px`;\n }\n }\n }\n\n override render() {\n const showImage = this.image && !this._imageError;\n const avatarStyle: Record<string, string> = {};\n if (showImage) {\n avatarStyle[\"backgroundImage\"] = `url(${encodeURI(this.image)})`;\n }\n if (this.outline) {\n avatarStyle[\"outline\"] = this.outline;\n }\n if (this.outlineOffset) {\n avatarStyle[\"outlineOffset\"] = this.outlineOffset;\n }\n\n const role = this.interactive\n ? \"button\"\n : showImage && this.alt\n ? \"img\"\n : nothing;\n const ariaLabel =\n this.interactive && this.alt\n ? this.alt\n : showImage && this.alt\n ? this.alt\n : nothing;\n\n return html`\n <div\n class=${classMap({\n avatar: true,\n \"avatar--interactive\": !!this.interactive,\n })}\n part=\"avatar\"\n style=${styleMap(avatarStyle)}\n role=${role}\n aria-label=${ariaLabel}\n tabindex=${this.interactive && !this.disabled ? \"0\" : nothing}\n @click=${this._handleInteractiveClick}\n @keydown=${this._handleInteractiveKeydown}\n >\n ${this.image\n ? html`<img\n class=\"image-probe\"\n src=${this.image}\n alt=\"\"\n @load=${this._onImageLoad}\n @error=${this._onImageError}\n />`\n : nothing}\n <div class=\"loading-overlay\" part=\"loading-overlay\">\n <div class=\"spinner\" part=\"spinner\"></div>\n </div>\n ${keyed(\n showImage ? \"_img_\" : \"_slot_\",\n when(!showImage, () => html`<slot></slot>`, () => nothing),\n )}\n </div>\n `;\n }\n}\n"],"names":["SIZE_PRESETS","sm","md","lg","SIZE_PX","SkyAvatar","LitElement","constructor","super","arguments","this","size","image","fit","radius","alt","color","outline","outlineOffset","loading","disabled","interactive","shadow","_imageError","preset","_presets","PresetController","_onImageLoad","_onImageError","updated","changed","has","resolvedSize","style","setProperty","resolveRadius","resolveColor","adjustSpinnerSize","_handleInteractiveClick","e","stopPropagation","dispatchEvent","Event","bubbles","composed","_handleInteractiveKeydown","key","preventDefault","avatarSizePx","parseFloat","Number","isFinite","spinnerSize","spinner","shadowRoot","querySelector","width","height","borderWidth","Math","max","render","showImage","avatarStyle","encodeURI","role","nothing","ariaLabel","html","classMap","avatar","styleMap","keyed","when","styles","css","__decorateClass","property","type","String","prototype","reflect","Boolean","state","customElement"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { LitElement } from "lit";
1
+ import { LitElement, PropertyValues } from "lit";
2
2
  export type SkyChipVariant = "solid" | "flat" | "shadow" | "bordered" | "faded" | "light" | "dot";
3
3
  export type SkyChipRemovedEventDetail = {
4
4
  label: string;
@@ -79,8 +79,12 @@ export declare class SkyChip extends LitElement {
79
79
  preset: string;
80
80
  private _presets;
81
81
  static styles: import("lit").CSSResult[];
82
+ private _prefixFilled;
83
+ private _suffixFilled;
84
+ private _defaultFilled;
85
+ private _slotFlagsSeeded;
82
86
  /** Updates host CSS variables from current color token/value. */
83
- protected updated(): void;
87
+ protected updated(changed: PropertyValues): void;
84
88
  /** Size resolver similar to button: controls padding + font-size */
85
89
  private _resolveSize;
86
90
  /**
@@ -94,6 +98,8 @@ export declare class SkyChip extends LitElement {
94
98
  private _hasPrefixSlotContent;
95
99
  private _hasSuffixSlotContent;
96
100
  private _hasDefaultSlotContent;
101
+ private _seedSlotFlagsFromLightDom;
102
+ willUpdate(): void;
97
103
  private _onSlotChange;
98
104
  render(): import("lit-html").TemplateResult<1>;
99
105
  }
@@ -1,20 +1,20 @@
1
- import{unsafeCSS as o,css as t,LitElement as e,nothing as r,html as i}from"lit";import{property as s,customElement as n}from"lit/decorators.js";import{when as a}from"lit/directives/when.js";import{styleMap as l}from"lit/directives/style-map.js";import{classMap as c}from"lit/directives/class-map.js";import{resolveColor as p,isDefaultColorToken as h,resolveInkColorForToken as d,resolveAccentColorForToken as y}from"../helper/utils/color-resolver.js";import{cssOnFillEnhance as f,ON_COLOR_FALLBACK_LIGHT as u}from"../helper/utils/contrast-color.js";import{resolveRadius as g}from"../helper/utils/size-resolver.js";import{PresetController as v}from"../helper/controllers/preset-controller.js";import{SkyIcon as b}from"../sky-icon/sky-icon.js";import{skyFocusRingHostStyles as m}from"../helper/styles/focus-ring.js";var x=Object.defineProperty,k=Object.getOwnPropertyDescriptor,S=(o,t,e,r)=>{for(var i,s=r>1?void 0:r?k(t,e):t,n=o.length-1;n>=0;n--)(i=o[n])&&(s=(r?i(t,e,s):i(s))||s);return r&&s&&x(t,e,s),s};let w=class extends e{constructor(){super(...arguments),this.label="",this.removable=!1,this.color="primary",this.radius="full",this.size="md",this.iconL=null,this.iconR=null,this.loading=!1,this.disabled=!1,this.variant="flat",this.preset="",this._presets=new v(this),this._onSlotChange=()=>{this.requestUpdate()}}updated(){const o=p(this.color),t=h(this.color)?"var(--sky-text-primary)":u;this.style.setProperty("--chip-bg-color",o),this.style.setProperty("--chip-text-color",t),h(this.color)?(this.style.setProperty("--chip-ink-color",d(this.color)),this.style.setProperty("--chip-accent-color",y(this.color)),this.style.setProperty("--chip-fill-color","var(--sky-hover-tertiary)")):(this.style.removeProperty("--chip-ink-color"),this.style.removeProperty("--chip-accent-color"),this.style.removeProperty("--chip-fill-color"))}_resolveSize(o){const t={xs:{padding:"2px 4px",fontSize:"11px"},sm:{padding:"3px 6px",fontSize:"12px"},md:{padding:"4px 8px",fontSize:"13px"},lg:{padding:"5px 10px",fontSize:"14px"},xl:{padding:"6px 12px",fontSize:"15px"}};if(t[o])return t[o];const e=String(o).trim().match(/^([\d.]+)(px|rem|em)?$/i),r=e?.[2]||"px",i=e?parseFloat(e[1]):13,s=`${i}${r}`,n=(o,t,e)=>Math.max(t,Math.min(e,o)),a=n(.4*i,2,10),l=n(.8*i,6,16),c=o=>`${Math.round(100*o)/100}${r}`;return{padding:`${c(a)} ${c(l)}`,fontSize:s}}removeChip(){const o=new CustomEvent("chip-removed",{detail:{label:this.label},bubbles:!0,composed:!0});this.dispatchEvent(o),this.remove()}_slotHasMeaningfulContent(o){return o.assignedNodes({flatten:!0}).some(o=>o.nodeType===Node.ELEMENT_NODE||(o.textContent??"").trim().length>0)}_hasPrefixSlotContent(){if(this.querySelector('[slot="prefix"]'))return!0;const o=this.shadowRoot?.querySelector('slot[name="prefix"]');return!!o&&this._slotHasMeaningfulContent(o)}_hasSuffixSlotContent(){if(this.querySelector('[slot="suffix"]'))return!0;const o=this.shadowRoot?.querySelector('slot[name="suffix"]');return!!o&&this._slotHasMeaningfulContent(o)}_hasDefaultSlotContent(){for(const o of Array.from(this.childNodes)){if(o.nodeType===Node.ELEMENT_NODE){const t=o.getAttribute("slot");if("prefix"===t||"suffix"===t)continue;return!0}if((o.textContent??"").trim().length>0)return!0}const o=this.shadowRoot?.querySelector("slot:not([name])");return!!o&&this._slotHasMeaningfulContent(o)}render(){const o=this._resolveSize(this.size),t={padding:o.padding,borderRadius:g(this.radius),fontSize:o.fontSize};return i`
1
+ import{unsafeCSS as o,css as t,LitElement as e,nothing as i,html as r}from"lit";import{property as s,customElement as l}from"lit/decorators.js";import{when as n}from"lit/directives/when.js";import{styleMap as a}from"lit/directives/style-map.js";import{classMap as c}from"lit/directives/class-map.js";import{resolveColor as p,isDefaultColorToken as h,resolveInkColorForToken as d,resolveAccentColorForToken as f}from"../helper/utils/color-resolver.js";import{cssOnFillEnhance as y,ON_COLOR_FALLBACK_LIGHT as u}from"../helper/utils/contrast-color.js";import{resolveRadius as g}from"../helper/utils/size-resolver.js";import{PresetController as v}from"../helper/controllers/preset-controller.js";import{SkyIcon as m}from"../sky-icon/sky-icon.js";import{skyFocusRingHostStyles as b}from"../helper/styles/focus-ring.js";var x=Object.defineProperty,k=Object.getOwnPropertyDescriptor,S=(o,t,e,i)=>{for(var r,s=i>1?void 0:i?k(t,e):t,l=o.length-1;l>=0;l--)(r=o[l])&&(s=(i?r(t,e,s):r(s))||s);return i&&s&&x(t,e,s),s};let _=class extends e{constructor(){super(...arguments),this.label="",this.removable=!1,this.color="primary",this.radius="full",this.size="md",this.iconL=null,this.iconR=null,this.loading=!1,this.disabled=!1,this.variant="flat",this.preset="",this._presets=new v(this),this._prefixFilled=!1,this._suffixFilled=!1,this._defaultFilled=!1,this._slotFlagsSeeded=!1,this._onSlotChange=o=>{const t=o.target;if(!t||"SLOT"!==t.tagName)return;this._slotFlagsSeeded=!0;const e=this._slotHasMeaningfulContent(t),i=t.name;if("prefix"===i){if(this._prefixFilled===e)return;this._prefixFilled=e}else if("suffix"===i){if(this._suffixFilled===e)return;this._suffixFilled=e}else{if(this._defaultFilled===e)return;this._defaultFilled=e}this.requestUpdate()}}updated(o){if(!o.has("color"))return;const t=p(this.color),e=h(this.color)?"var(--sky-text-primary)":u;this.style.setProperty("--chip-bg-color",t),this.style.setProperty("--chip-text-color",e),h(this.color)?(this.style.setProperty("--chip-ink-color",d(this.color)),this.style.setProperty("--chip-accent-color",f(this.color)),this.style.setProperty("--chip-fill-color","var(--sky-hover-tertiary)")):(this.style.removeProperty("--chip-ink-color"),this.style.removeProperty("--chip-accent-color"),this.style.removeProperty("--chip-fill-color"))}_resolveSize(o){const t={xs:{padding:"2px 4px",fontSize:"11px"},sm:{padding:"3px 6px",fontSize:"12px"},md:{padding:"4px 8px",fontSize:"13px"},lg:{padding:"5px 10px",fontSize:"14px"},xl:{padding:"6px 12px",fontSize:"15px"}};if(t[o])return t[o];const e=String(o).trim().match(/^([\d.]+)(px|rem|em)?$/i),i=e?.[2]||"px",r=e?parseFloat(e[1]):13,s=`${r}${i}`,l=(o,t,e)=>Math.max(t,Math.min(e,o)),n=l(.4*r,2,10),a=l(.8*r,6,16),c=o=>`${Math.round(100*o)/100}${i}`;return{padding:`${c(n)} ${c(a)}`,fontSize:s}}removeChip(){const o=new CustomEvent("chip-removed",{detail:{label:this.label},bubbles:!0,composed:!0});this.dispatchEvent(o),this.remove()}_slotHasMeaningfulContent(o){return o.assignedNodes({flatten:!0}).some(o=>o.nodeType===Node.ELEMENT_NODE||(o.textContent??"").trim().length>0)}_hasPrefixSlotContent(){return this._prefixFilled}_hasSuffixSlotContent(){return this._suffixFilled}_hasDefaultSlotContent(){return this._defaultFilled}_seedSlotFlagsFromLightDom(){this._prefixFilled=!!this.querySelector('[slot="prefix"]'),this._suffixFilled=!!this.querySelector('[slot="suffix"]'),this._defaultFilled=!1;for(const o of Array.from(this.childNodes)){if(o.nodeType===Node.ELEMENT_NODE){const t=o.getAttribute("slot");if("prefix"===t||"suffix"===t)continue;this._defaultFilled=!0;break}if((o.textContent??"").trim().length>0){this._defaultFilled=!0;break}}this._slotFlagsSeeded=!0}willUpdate(){this._slotFlagsSeeded||this._seedSlotFlagsFromLightDom()}render(){const o=this._resolveSize(this.size),t={padding:o.padding,borderRadius:g(this.radius),fontSize:o.fontSize};return r`
2
2
  <div
3
3
  class=${c({chip:!0,[this.variant]:!0,loading:this.loading})}
4
- style=${l(t)}
4
+ style=${a(t)}
5
5
  part="chip"
6
6
  >
7
7
  <slot name="prefix" @slotchange=${this._onSlotChange}></slot>
8
- ${a(!this._hasPrefixSlotContent()&&this.iconL,()=>i`
8
+ ${n(!this._hasPrefixSlotContent()&&this.iconL,()=>r`
9
9
  <sky-icon class="icon" part="icon" icon="${this.iconL}"></sky-icon>
10
10
  `)}
11
11
  <slot @slotchange=${this._onSlotChange}></slot>
12
- ${this._hasDefaultSlotContent()?r:this.label}
12
+ ${this._hasDefaultSlotContent()?i:this.label}
13
13
  <slot name="suffix" @slotchange=${this._onSlotChange}></slot>
14
- ${a(!this._hasSuffixSlotContent()&&this.iconR,()=>i`
14
+ ${n(!this._hasSuffixSlotContent()&&this.iconR,()=>r`
15
15
  <sky-icon class="icon icon-right" part="icon" icon="${this.iconR}"></sky-icon>
16
16
  `)}
17
- ${a(this.removable,()=>i`
17
+ ${n(this.removable,()=>r`
18
18
  <button
19
19
  class="close-button"
20
20
  part="close-button"
@@ -25,13 +25,13 @@ import{unsafeCSS as o,css as t,LitElement as e,nothing as r,html as i}from"lit";
25
25
  <sky-icon icon="ion:close"></sky-icon>
26
26
  </button>
27
27
  `)}
28
- ${a(this.loading,()=>i`
28
+ ${n(this.loading,()=>r`
29
29
  <div class="loading-overlay" part="loading-overlay">
30
30
  <div class="loading-spinner" part="loading-spinner"></div>
31
31
  </div>
32
32
  `)}
33
33
  </div>
34
- `}};w.dependencies={"sky-icon":b},w.styles=[m,t`
34
+ `}};_.dependencies={"sky-icon":m},_.styles=[b,t`
35
35
  :host {
36
36
  display: inline-block;
37
37
  font-family: var(--sky-font);
@@ -227,6 +227,6 @@ import{unsafeCSS as o,css as t,LitElement as e,nothing as r,html as i}from"lit";
227
227
  }
228
228
 
229
229
  /* Solid / shadow chips: enhance label + icon FG against fill. */
230
- ${o(f([{selector:".chip.solid, .chip.shadow",fillVar:"--chip-bg-color"},{selector:".chip.solid .icon, .chip.shadow .icon",fillVar:"--chip-bg-color"}]))}
231
- `],S([s({type:String})],w.prototype,"label",2),S([s({type:Boolean})],w.prototype,"removable",2),S([s({type:String})],w.prototype,"color",2),S([s({type:String})],w.prototype,"radius",2),S([s({type:String})],w.prototype,"size",2),S([s({type:String})],w.prototype,"iconL",2),S([s({type:String})],w.prototype,"iconR",2),S([s({type:Boolean})],w.prototype,"loading",2),S([s({type:Boolean,reflect:!0})],w.prototype,"disabled",2),S([s({type:String,reflect:!0})],w.prototype,"variant",2),S([s({type:String,reflect:!0})],w.prototype,"preset",2),w=S([n("sky-chip")],w);export{w as SkyChip};
230
+ ${o(y([{selector:".chip.solid, .chip.shadow",fillVar:"--chip-bg-color"},{selector:".chip.solid .icon, .chip.shadow .icon",fillVar:"--chip-bg-color"}]))}
231
+ `],S([s({type:String})],_.prototype,"label",2),S([s({type:Boolean})],_.prototype,"removable",2),S([s({type:String})],_.prototype,"color",2),S([s({type:String})],_.prototype,"radius",2),S([s({type:String})],_.prototype,"size",2),S([s({type:String})],_.prototype,"iconL",2),S([s({type:String})],_.prototype,"iconR",2),S([s({type:Boolean})],_.prototype,"loading",2),S([s({type:Boolean,reflect:!0})],_.prototype,"disabled",2),S([s({type:String,reflect:!0})],_.prototype,"variant",2),S([s({type:String,reflect:!0})],_.prototype,"preset",2),_=S([l("sky-chip")],_);export{_ as SkyChip};
232
232
  //# sourceMappingURL=sky-chip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sky-chip.js","sources":["../../src/sky-chip/sky-chip.ts"],"sourcesContent":["import { LitElement, html, css, nothing, unsafeCSS } from \"lit\";\r\nimport { customElement, property } from \"lit/decorators.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { styleMap } from \"lit/directives/style-map.js\";\r\nimport { classMap } from \"lit/directives/class-map.js\";\r\nimport {\r\n isDefaultColorToken,\r\n resolveAccentColorForToken,\r\n resolveColor,\r\n resolveInkColorForToken,\r\n} from \"../helper/utils/color-resolver\";\r\nimport { cssOnFillEnhance, ON_COLOR_FALLBACK_LIGHT } from \"../helper/utils/contrast-color\";\r\nimport { resolveRadius } from \"../helper/utils/size-resolver\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\nimport { SkyIcon } from \"../sky-icon/sky-icon.js\";\r\nimport { skyFocusRingHostStyles } from \"../helper/styles/focus-ring\";\r\n\r\nexport type SkyChipVariant =\r\n | \"solid\"\r\n | \"flat\"\r\n | \"shadow\"\r\n | \"bordered\"\r\n | \"faded\"\r\n | \"light\"\r\n | \"dot\";\r\nexport type SkyChipRemovedEventDetail = { label: string };\r\n\r\n/**\r\n * @element sky-chip\r\n *\r\n * @summary Customizable chip for tags or selections with icon support, removable action, loading state, and visual variants.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/chip\r\n * @dependency sky-icon\r\n *\r\n * @slot - Default slot for the chip label or any other content.\r\n * @slot prefix - Optional prefix content that can be placed before the label.\r\n * @slot suffix - Optional suffix content that can be placed after the label.\r\n *\r\n * @csspart chip - The visual representation of the chip component.\r\n * @csspart icon - The icons displayed within the chip.\r\n * @csspart close-button - The button for removing the chip.\r\n * @csspart loading-spinner - The spinner that appears during loading.\r\n * @csspart error-message - The error message displayed for invalid chips.\r\n *\r\n * @property {string} label - The label displayed on the chip. Default: `\"\"`.\r\n * @property {boolean} removable - Whether the chip can be removed by the user. Default: `false`.\r\n * @property {string} color - The background color of the chip, can accept tokens or custom CSS color. Default: `\"primary\"`.\r\n * @property {string} radius - The border radius of the chip. Default: `\"full\"`.\r\n * @property {string} size - The size of the chip, which affects padding and font size. Default: `\"md\"`.\r\n * @property {string} iconL - Left icon; shown only when the `prefix` slot is empty. Default: `null`.\r\n * @property {string} iconR - Right icon; shown only when the `suffix` slot is empty. Default: `null`.\r\n * @property {boolean} loading - Whether the chip is in a loading state. Default: `false`.\r\n * @property {boolean} disabled - Whether the chip is disabled. Default: `false`.\r\n * @property {SkyChipVariant} variant - Visual style variant. Default: `\"flat\"`.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n * @method removeChip Dispatches `chip-removed` and removes the chip from the DOM.\r\n *\r\n * @fires {CustomEvent<SkyChipRemovedEventDetail>} chip-removed - Fired when the chip is removed by user action.\r\n *\r\n * @Behavior\r\n * - Uses default slot content when present, otherwise falls back to `label`.\r\n * - `iconL` / `iconR` render only when `prefix` / `suffix` slots have no meaningful content.\r\n * - Emits `chip-removed` and removes itself when removable close action is triggered.\r\n * - Resolves color tokens and radius/size presets to CSS values at render time.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>;\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-chip\")\r\nexport class SkyChip extends LitElement {\r\n\r\n static dependencies: Record<string, CustomElementConstructor> = {\r\n \"sky-icon\": SkyIcon,\r\n };\r\n\r\n @property({ type: String }) label: string = \"\";\r\n @property({ type: Boolean }) removable: boolean = false;\r\n\r\n /** Accepts preset tokens OR any valid CSS color (e.g., #0af, rgb(), var(--x)) */\r\n @property({ type: String }) color: string = \"primary\";\r\n\r\n /** Radius can be any CSS radius value */\r\n @property({ type: String }) radius: string = \"full\";\r\n\r\n /** Size controls padding + font-size (xs, sm, md, lg, xl or numeric like \"14px\") */\r\n @property({ type: String }) size: string = \"md\";\r\n\r\n @property({ type: String }) iconL: string | null = null;\r\n @property({ type: String }) iconR: string | null = null;\r\n @property({ type: Boolean }) loading: boolean = false;\r\n @property({ type: Boolean, reflect: true }) disabled: boolean = false;\r\n @property({ type: String, reflect: true }) variant: SkyChipVariant = \"flat\";\r\n\r\n /** Named prop preset from nearest `sky-config-provider`. */\r\n @property({ type: String, reflect: true }) preset = \"\";\r\n\r\n private _presets = new PresetController(this);\r\n\r\n static override styles = [\r\n skyFocusRingHostStyles,\r\n css`\r\n :host {\r\n display: inline-block;\r\n font-family: var(--sky-font);\r\n z-index: 1;\r\n --sky-focus-ring-color: var(--chip-bg-color, var(--sky-active-primary));\r\n }\r\n\r\n :host([disabled]) {\r\n pointer-events: none;\r\n opacity: var(--sky-opacity-disabled, 0.6);\r\n }\r\n\r\n .chip {\r\n position: relative;\r\n display: flex;\r\n gap: 2px;\r\n width: max-content;\r\n align-items: center;\r\n border-radius: var(--sky-radius-secondary);\r\n color: var(--chip-text-color);\r\n font-weight: var(--sky-font-weight-medium, 500);\r\n transition: background-color 0.3s ease, color 0.3s ease,\r\n box-shadow 0.2s ease, transform 0.2s ease;\r\n cursor: pointer;\r\n background-color: var(--chip-bg-color);\r\n }\r\n\r\n .close-button {\r\n position: relative;\r\n display: flex;\r\n height: 18px;\r\n width: 18px;\r\n justify-content: center;\r\n font-size: inherit;\r\n align-items: center;\r\n background-color: var(--sky-hover-primary);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n border: none;\r\n border-radius: var(--sky-radius-full);\r\n cursor: pointer;\r\n color: var(--sky-text-primary);\r\n transition: color 0.2s ease, background-color 0.2s ease;\r\n }\r\n\r\n .close-button sky-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n line-height: 1;\r\n transition: color 0.3s ease;\r\n }\r\n\r\n :dir(rtl) .close-button {\r\n margin-right: var(--sky-space-1, 5px);\r\n margin-left: unset;\r\n }\r\n\r\n .close-button:hover {\r\n color: var(--sky-danger-primary);\r\n }\r\n\r\n .close-button:focus-visible {\r\n outline: none;\r\n box-shadow: var(--sky-focus-ring);\r\n }\r\n\r\n .close-button:hover sky-icon,\r\n .close-button:focus-visible sky-icon{\r\n color: var(--sky-danger-primary);\r\n outline: none;\r\n }\r\n\r\n .icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--chip-text-color);\r\n }\r\n\r\n sky-icon {\r\n display: inline-block;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n\r\n ::slotted([slot=\"prefix\"]),\r\n ::slotted([slot=\"suffix\"]) {\r\n display: inline-flex;\r\n align-items: center;\r\n }\r\n\r\n .loading-overlay {\r\n position: absolute;\r\n inset: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: var(--sky-overlay-primary);\r\n border-radius: inherit;\r\n }\r\n\r\n .loading-spinner {\r\n width: 14px;\r\n height: 14px;\r\n border: 2px solid var(--sky-border-light, var(--sky-text-tertiary));\r\n border-top-color: var(--chip-bg-color);\r\n border-radius: var(--sky-radius-full);\r\n animation: spin 0.8s linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n from {\r\n transform: rotate(0deg);\r\n }\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .chip,\r\n .close-button,\r\n .close-button sky-icon {\r\n transition: none;\r\n }\r\n .loading-spinner {\r\n animation: none;\r\n }\r\n }\r\n\r\n .chip.bordered {\r\n border: 1px solid var(--chip-ink-color, var(--chip-bg-color));\r\n color: var(--chip-ink-color, var(--chip-bg-color));\r\n background: transparent;\r\n }\r\n\r\n .chip.light {\r\n background: transparent;\r\n color: var(--chip-ink-color, var(--chip-bg-color));\r\n }\r\n\r\n .chip.flat {\r\n box-shadow: none;\r\n background: color-mix(\r\n in srgb,\r\n var(--chip-fill-color, var(--chip-bg-color)) 20%,\r\n transparent\r\n );\r\n color: var(--chip-ink-color, var(--chip-bg-color));\r\n }\r\n\r\n .chip.faded {\r\n background-color: var(--sky-glass-primary);\r\n border: 1px solid var(--sky-text-tertiary);\r\n color: var(--chip-ink-color, var(--chip-bg-color));\r\n }\r\n\r\n .chip.shadow {\r\n box-shadow: var(--sky-box-shadow-primary);\r\n }\r\n\r\n .chip.shadow:hover {\r\n box-shadow: var(--sky-box-shadow-hover);\r\n }\r\n\r\n .chip.faded .icon,\r\n .chip.flat .icon,\r\n .chip.light .icon,\r\n .chip.dot .icon,\r\n .chip.bordered .icon {\r\n color: var(--chip-ink-color, var(--chip-bg-color));\r\n }\r\n\r\n .chip.dot {\r\n padding-left: var(--sky-space-5, 20px) !important;\r\n position: relative;\r\n background-color: transparent;\r\n border: 1px solid var(--sky-text-tertiary);\r\n color: var(--sky-text-primary);\r\n }\r\n\r\n .chip.dot::before {\r\n content: \"\";\r\n position: absolute;\r\n left: var(--sky-space-1\\\\.5, 6px);\r\n top: 50%;\r\n transform: translateY(-50%);\r\n width: var(--sky-space-2, 8px);\r\n height: var(--sky-space-2, 8px);\r\n border-radius: var(--sky-radius-full);\r\n background-color: var(--chip-accent-color, var(--chip-bg-color));\r\n }\r\n\r\n /* Solid / shadow chips: enhance label + icon FG against fill. */\r\n ${unsafeCSS(\r\n cssOnFillEnhance([\r\n {\r\n selector: \".chip.solid, .chip.shadow\",\r\n fillVar: \"--chip-bg-color\",\r\n },\r\n {\r\n selector: \".chip.solid .icon, .chip.shadow .icon\",\r\n fillVar: \"--chip-bg-color\",\r\n },\r\n ]),\r\n )}\r\n `,\r\n ];\r\n\r\n /** Updates host CSS variables from current color token/value. */\r\n protected override updated(): void {\r\n const bgColor = resolveColor(this.color);\r\n const textColor = isDefaultColorToken(this.color)\r\n ? \"var(--sky-text-primary)\"\r\n : ON_COLOR_FALLBACK_LIGHT;\r\n\r\n this.style.setProperty(\"--chip-bg-color\", bgColor);\r\n this.style.setProperty(\"--chip-text-color\", textColor);\r\n\r\n if (isDefaultColorToken(this.color)) {\r\n this.style.setProperty(\"--chip-ink-color\", resolveInkColorForToken(this.color));\r\n this.style.setProperty(\r\n \"--chip-accent-color\",\r\n resolveAccentColorForToken(this.color),\r\n );\r\n this.style.setProperty(\"--chip-fill-color\", \"var(--sky-hover-tertiary)\");\r\n } else {\r\n this.style.removeProperty(\"--chip-ink-color\");\r\n this.style.removeProperty(\"--chip-accent-color\");\r\n this.style.removeProperty(\"--chip-fill-color\");\r\n }\r\n }\r\n\r\n /** Size resolver similar to button: controls padding + font-size */\r\n private _resolveSize(\r\n input: string\r\n ): {\r\n padding: string;\r\n fontSize: string;\r\n } {\r\n const presets: Record<string, { padding: string; fontSize: string }> = {\r\n xs: { padding: \"2px 4px\", fontSize: \"11px\" },\r\n sm: { padding: \"3px 6px\", fontSize: \"12px\" },\r\n md: { padding: \"4px 8px\", fontSize: \"13px\" },\r\n lg: { padding: \"5px 10px\", fontSize: \"14px\" },\r\n xl: { padding: \"6px 12px\", fontSize: \"15px\" },\r\n };\r\n\r\n if (presets[input]) return presets[input];\r\n\r\n const m = String(input).trim().match(/^([\\d.]+)(px|rem|em)?$/i);\r\n const unit = m?.[2] || \"px\";\r\n const fsNum = m ? parseFloat(m[1]) : 13;\r\n const fs = `${fsNum}${unit}`;\r\n\r\n const clamp = (n: number, min: number, max: number) =>\r\n Math.max(min, Math.min(max, n));\r\n\r\n const py = clamp(fsNum * 0.4, 2, 10);\r\n const px = clamp(fsNum * 0.8, 6, 16);\r\n\r\n const to = (n: number) => `${Math.round(n * 100) / 100}${unit}`;\r\n\r\n return {\r\n padding: `${to(py)} ${to(px)}`,\r\n fontSize: fs,\r\n };\r\n }\r\n\r\n /**\r\n * Dispatches `chip-removed` and removes the chip from the DOM.\r\n *\r\n * @returns {void}\r\n */\r\n public removeChip(): void {\r\n const removeEvent = new CustomEvent<SkyChipRemovedEventDetail>(\"chip-removed\", {\r\n detail: { label: this.label },\r\n bubbles: true,\r\n composed: true,\r\n });\r\n this.dispatchEvent(removeEvent);\r\n this.remove();\r\n }\r\n\r\n private _slotHasMeaningfulContent(slotEl: HTMLSlotElement): boolean {\r\n const nodes = slotEl.assignedNodes({ flatten: true });\r\n return nodes.some((n) =>\r\n n.nodeType === Node.ELEMENT_NODE\r\n ? true\r\n : (n.textContent ?? \"\").trim().length > 0\r\n );\r\n }\r\n\r\n /** Light DOM check works before the shadow tree exists (first render). */\r\n private _hasPrefixSlotContent(): boolean {\r\n if (this.querySelector('[slot=\"prefix\"]')) return true;\r\n const slot = this.shadowRoot?.querySelector(\r\n 'slot[name=\"prefix\"]',\r\n ) as HTMLSlotElement | null;\r\n return slot ? this._slotHasMeaningfulContent(slot) : false;\r\n }\r\n\r\n private _hasSuffixSlotContent(): boolean {\r\n if (this.querySelector('[slot=\"suffix\"]')) return true;\r\n const slot = this.shadowRoot?.querySelector(\r\n 'slot[name=\"suffix\"]',\r\n ) as HTMLSlotElement | null;\r\n return slot ? this._slotHasMeaningfulContent(slot) : false;\r\n }\r\n\r\n private _hasDefaultSlotContent(): boolean {\r\n for (const n of Array.from(this.childNodes)) {\r\n if (n.nodeType === Node.ELEMENT_NODE) {\r\n const slot = (n as Element).getAttribute(\"slot\");\r\n if (slot === \"prefix\" || slot === \"suffix\") continue;\r\n return true;\r\n }\r\n if ((n.textContent ?? \"\").trim().length > 0) return true;\r\n }\r\n const slot = this.shadowRoot?.querySelector(\r\n \"slot:not([name])\",\r\n ) as HTMLSlotElement | null;\r\n return slot ? this._slotHasMeaningfulContent(slot) : false;\r\n }\r\n\r\n private _onSlotChange = (): void => {\r\n this.requestUpdate();\r\n };\r\n\r\n override render() {\r\n const sizeDef = this._resolveSize(this.size);\r\n const chipStyle = {\r\n padding: sizeDef.padding,\r\n borderRadius: resolveRadius(this.radius),\r\n fontSize: sizeDef.fontSize,\r\n };\r\n\r\n return html`\r\n <div\r\n class=${classMap({\r\n chip: true,\r\n [this.variant]: true,\r\n loading: this.loading,\r\n })}\r\n style=${styleMap(chipStyle)}\r\n part=\"chip\"\r\n >\r\n <slot name=\"prefix\" @slotchange=${this._onSlotChange}></slot>\r\n ${when(!this._hasPrefixSlotContent() && this.iconL, () => html`\r\n <sky-icon class=\"icon\" part=\"icon\" icon=\"${this.iconL!}\"></sky-icon>\r\n `)}\r\n <slot @slotchange=${this._onSlotChange}></slot>\r\n ${this._hasDefaultSlotContent() ? nothing : this.label}\r\n <slot name=\"suffix\" @slotchange=${this._onSlotChange}></slot>\r\n ${when(!this._hasSuffixSlotContent() && this.iconR, () => html`\r\n <sky-icon class=\"icon icon-right\" part=\"icon\" icon=\"${this.iconR!}\"></sky-icon>\r\n `)}\r\n ${when(this.removable, () => html`\r\n <button\r\n class=\"close-button\"\r\n part=\"close-button\"\r\n type=\"button\"\r\n aria-label=\"Remove chip\"\r\n @click=${this.removeChip}\r\n >\r\n <sky-icon icon=\"ion:close\"></sky-icon>\r\n </button>\r\n `)}\r\n ${when(this.loading, () => html`\r\n <div class=\"loading-overlay\" part=\"loading-overlay\">\r\n <div class=\"loading-spinner\" part=\"loading-spinner\"></div>\r\n </div>\r\n `)}\r\n </div>\r\n `;\r\n }\r\n}"],"names":["SkyChip","LitElement","constructor","super","arguments","this","label","removable","color","radius","size","iconL","iconR","loading","disabled","variant","preset","_presets","PresetController","_onSlotChange","requestUpdate","updated","bgColor","resolveColor","textColor","isDefaultColorToken","ON_COLOR_FALLBACK_LIGHT","style","setProperty","resolveInkColorForToken","resolveAccentColorForToken","removeProperty","_resolveSize","input","presets","xs","padding","fontSize","sm","md","lg","xl","m","String","trim","match","unit","fsNum","parseFloat","fs","clamp","n","min","max","Math","py","px","to","round","removeChip","removeEvent","CustomEvent","detail","bubbles","composed","dispatchEvent","remove","_slotHasMeaningfulContent","slotEl","assignedNodes","flatten","some","nodeType","Node","ELEMENT_NODE","textContent","length","_hasPrefixSlotContent","querySelector","slot","shadowRoot","_hasSuffixSlotContent","_hasDefaultSlotContent","Array","from","childNodes","getAttribute","render","sizeDef","chipStyle","borderRadius","resolveRadius","html","classMap","chip","styleMap","when","nothing","dependencies","SkyIcon","styles","skyFocusRingHostStyles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","__decorateClass","property","type","prototype","Boolean","reflect","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"sky-chip.js","sources":["../../src/sky-chip/sky-chip.ts"],"sourcesContent":["import { LitElement, html, css, nothing, unsafeCSS, PropertyValues } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { when } from \"lit/directives/when.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport {\n isDefaultColorToken,\n resolveAccentColorForToken,\n resolveColor,\n resolveInkColorForToken,\n} from \"../helper/utils/color-resolver\";\nimport { cssOnFillEnhance, ON_COLOR_FALLBACK_LIGHT } from \"../helper/utils/contrast-color\";\nimport { resolveRadius } from \"../helper/utils/size-resolver\";\nimport { PresetController } from \"../helper/controllers/preset-controller\";\nimport { SkyIcon } from \"../sky-icon/sky-icon.js\";\nimport { skyFocusRingHostStyles } from \"../helper/styles/focus-ring\";\n\nexport type SkyChipVariant =\n | \"solid\"\n | \"flat\"\n | \"shadow\"\n | \"bordered\"\n | \"faded\"\n | \"light\"\n | \"dot\";\nexport type SkyChipRemovedEventDetail = { label: string };\n\n/**\n * @element sky-chip\n *\n * @summary Customizable chip for tags or selections with icon support, removable action, loading state, and visual variants.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://sky-ui.com/components/chip\n * @dependency sky-icon\n *\n * @slot - Default slot for the chip label or any other content.\n * @slot prefix - Optional prefix content that can be placed before the label.\n * @slot suffix - Optional suffix content that can be placed after the label.\n *\n * @csspart chip - The visual representation of the chip component.\n * @csspart icon - The icons displayed within the chip.\n * @csspart close-button - The button for removing the chip.\n * @csspart loading-spinner - The spinner that appears during loading.\n * @csspart error-message - The error message displayed for invalid chips.\n *\n * @property {string} label - The label displayed on the chip. Default: `\"\"`.\n * @property {boolean} removable - Whether the chip can be removed by the user. Default: `false`.\n * @property {string} color - The background color of the chip, can accept tokens or custom CSS color. Default: `\"primary\"`.\n * @property {string} radius - The border radius of the chip. Default: `\"full\"`.\n * @property {string} size - The size of the chip, which affects padding and font size. Default: `\"md\"`.\n * @property {string} iconL - Left icon; shown only when the `prefix` slot is empty. Default: `null`.\n * @property {string} iconR - Right icon; shown only when the `suffix` slot is empty. Default: `null`.\n * @property {boolean} loading - Whether the chip is in a loading state. Default: `false`.\n * @property {boolean} disabled - Whether the chip is disabled. Default: `false`.\n * @property {SkyChipVariant} variant - Visual style variant. Default: `\"flat\"`.\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\n * @method removeChip Dispatches `chip-removed` and removes the chip from the DOM.\n *\n * @fires {CustomEvent<SkyChipRemovedEventDetail>} chip-removed - Fired when the chip is removed by user action.\n *\n * @Behavior\n * - Uses default slot content when present, otherwise falls back to `label`.\n * - `iconL` / `iconR` render only when `prefix` / `suffix` slots have no meaningful content.\n * - Emits `chip-removed` and removes itself when removable close action is triggered.\n * - Resolves color tokens and radius/size presets to CSS values at render time.\n *\n * @example\n * ```html\n * <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>\n * ```\n * ```vue\n * <template>\n * <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return <sky-chip label=\"Active Filter\" removable iconl=\"ion:funnel\" variant=\"light\"></sky-chip>;\n * }\n * ```\n */\n@customElement(\"sky-chip\")\nexport class SkyChip extends LitElement {\n\n static dependencies: Record<string, CustomElementConstructor> = {\n \"sky-icon\": SkyIcon,\n };\n\n @property({ type: String }) label: string = \"\";\n @property({ type: Boolean }) removable: boolean = false;\n\n /** Accepts preset tokens OR any valid CSS color (e.g., #0af, rgb(), var(--x)) */\n @property({ type: String }) color: string = \"primary\";\n\n /** Radius can be any CSS radius value */\n @property({ type: String }) radius: string = \"full\";\n\n /** Size controls padding + font-size (xs, sm, md, lg, xl or numeric like \"14px\") */\n @property({ type: String }) size: string = \"md\";\n\n @property({ type: String }) iconL: string | null = null;\n @property({ type: String }) iconR: string | null = null;\n @property({ type: Boolean }) loading: boolean = false;\n @property({ type: Boolean, reflect: true }) disabled: boolean = false;\n @property({ type: String, reflect: true }) variant: SkyChipVariant = \"flat\";\n\n /** Named prop preset from nearest `sky-config-provider`. */\n @property({ type: String, reflect: true }) preset = \"\";\n\n private _presets = new PresetController(this);\n\n static override styles = [\n skyFocusRingHostStyles,\n css`\n :host {\n display: inline-block;\n font-family: var(--sky-font);\n z-index: 1;\n --sky-focus-ring-color: var(--chip-bg-color, var(--sky-active-primary));\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--sky-opacity-disabled, 0.6);\n }\n\n .chip {\n position: relative;\n display: flex;\n gap: 2px;\n width: max-content;\n align-items: center;\n border-radius: var(--sky-radius-secondary);\n color: var(--chip-text-color);\n font-weight: var(--sky-font-weight-medium, 500);\n transition: background-color 0.3s ease, color 0.3s ease,\n box-shadow 0.2s ease, transform 0.2s ease;\n cursor: pointer;\n background-color: var(--chip-bg-color);\n }\n\n .close-button {\n position: relative;\n display: flex;\n height: 18px;\n width: 18px;\n justify-content: center;\n font-size: inherit;\n align-items: center;\n background-color: var(--sky-hover-primary);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n border: none;\n border-radius: var(--sky-radius-full);\n cursor: pointer;\n color: var(--sky-text-primary);\n transition: color 0.2s ease, background-color 0.2s ease;\n }\n\n .close-button sky-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n transition: color 0.3s ease;\n }\n\n :dir(rtl) .close-button {\n margin-right: var(--sky-space-1, 5px);\n margin-left: unset;\n }\n\n .close-button:hover {\n color: var(--sky-danger-primary);\n }\n\n .close-button:focus-visible {\n outline: none;\n box-shadow: var(--sky-focus-ring);\n }\n\n .close-button:hover sky-icon,\n .close-button:focus-visible sky-icon{\n color: var(--sky-danger-primary);\n outline: none;\n }\n\n .icon {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--chip-text-color);\n }\n\n sky-icon {\n display: inline-block;\n width: 1em;\n height: 1em;\n }\n\n ::slotted([slot=\"prefix\"]),\n ::slotted([slot=\"suffix\"]) {\n display: inline-flex;\n align-items: center;\n }\n\n .loading-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--sky-overlay-primary);\n border-radius: inherit;\n }\n\n .loading-spinner {\n width: 14px;\n height: 14px;\n border: 2px solid var(--sky-border-light, var(--sky-text-tertiary));\n border-top-color: var(--chip-bg-color);\n border-radius: var(--sky-radius-full);\n animation: spin 0.8s linear infinite;\n }\n\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .chip,\n .close-button,\n .close-button sky-icon {\n transition: none;\n }\n .loading-spinner {\n animation: none;\n }\n }\n\n .chip.bordered {\n border: 1px solid var(--chip-ink-color, var(--chip-bg-color));\n color: var(--chip-ink-color, var(--chip-bg-color));\n background: transparent;\n }\n\n .chip.light {\n background: transparent;\n color: var(--chip-ink-color, var(--chip-bg-color));\n }\n\n .chip.flat {\n box-shadow: none;\n background: color-mix(\n in srgb,\n var(--chip-fill-color, var(--chip-bg-color)) 20%,\n transparent\n );\n color: var(--chip-ink-color, var(--chip-bg-color));\n }\n\n .chip.faded {\n background-color: var(--sky-glass-primary);\n border: 1px solid var(--sky-text-tertiary);\n color: var(--chip-ink-color, var(--chip-bg-color));\n }\n\n .chip.shadow {\n box-shadow: var(--sky-box-shadow-primary);\n }\n\n .chip.shadow:hover {\n box-shadow: var(--sky-box-shadow-hover);\n }\n\n .chip.faded .icon,\n .chip.flat .icon,\n .chip.light .icon,\n .chip.dot .icon,\n .chip.bordered .icon {\n color: var(--chip-ink-color, var(--chip-bg-color));\n }\n\n .chip.dot {\n padding-left: var(--sky-space-5, 20px) !important;\n position: relative;\n background-color: transparent;\n border: 1px solid var(--sky-text-tertiary);\n color: var(--sky-text-primary);\n }\n\n .chip.dot::before {\n content: \"\";\n position: absolute;\n left: var(--sky-space-1\\\\.5, 6px);\n top: 50%;\n transform: translateY(-50%);\n width: var(--sky-space-2, 8px);\n height: var(--sky-space-2, 8px);\n border-radius: var(--sky-radius-full);\n background-color: var(--chip-accent-color, var(--chip-bg-color));\n }\n\n /* Solid / shadow chips: enhance label + icon FG against fill. */\n ${unsafeCSS(\n cssOnFillEnhance([\n {\n selector: \".chip.solid, .chip.shadow\",\n fillVar: \"--chip-bg-color\",\n },\n {\n selector: \".chip.solid .icon, .chip.shadow .icon\",\n fillVar: \"--chip-bg-color\",\n },\n ]),\n )}\n `,\n ];\n\n private _prefixFilled = false;\n private _suffixFilled = false;\n private _defaultFilled = false;\n private _slotFlagsSeeded = false;\n\n /** Updates host CSS variables from current color token/value. */\n protected override updated(changed: PropertyValues): void {\n if (!changed.has(\"color\")) return;\n\n const bgColor = resolveColor(this.color);\n const textColor = isDefaultColorToken(this.color)\n ? \"var(--sky-text-primary)\"\n : ON_COLOR_FALLBACK_LIGHT;\n\n this.style.setProperty(\"--chip-bg-color\", bgColor);\n this.style.setProperty(\"--chip-text-color\", textColor);\n\n if (isDefaultColorToken(this.color)) {\n this.style.setProperty(\"--chip-ink-color\", resolveInkColorForToken(this.color));\n this.style.setProperty(\n \"--chip-accent-color\",\n resolveAccentColorForToken(this.color),\n );\n this.style.setProperty(\"--chip-fill-color\", \"var(--sky-hover-tertiary)\");\n } else {\n this.style.removeProperty(\"--chip-ink-color\");\n this.style.removeProperty(\"--chip-accent-color\");\n this.style.removeProperty(\"--chip-fill-color\");\n }\n }\n\n /** Size resolver similar to button: controls padding + font-size */\n private _resolveSize(\n input: string\n ): {\n padding: string;\n fontSize: string;\n } {\n const presets: Record<string, { padding: string; fontSize: string }> = {\n xs: { padding: \"2px 4px\", fontSize: \"11px\" },\n sm: { padding: \"3px 6px\", fontSize: \"12px\" },\n md: { padding: \"4px 8px\", fontSize: \"13px\" },\n lg: { padding: \"5px 10px\", fontSize: \"14px\" },\n xl: { padding: \"6px 12px\", fontSize: \"15px\" },\n };\n\n if (presets[input]) return presets[input];\n\n const m = String(input).trim().match(/^([\\d.]+)(px|rem|em)?$/i);\n const unit = m?.[2] || \"px\";\n const fsNum = m ? parseFloat(m[1]) : 13;\n const fs = `${fsNum}${unit}`;\n\n const clamp = (n: number, min: number, max: number) =>\n Math.max(min, Math.min(max, n));\n\n const py = clamp(fsNum * 0.4, 2, 10);\n const px = clamp(fsNum * 0.8, 6, 16);\n\n const to = (n: number) => `${Math.round(n * 100) / 100}${unit}`;\n\n return {\n padding: `${to(py)} ${to(px)}`,\n fontSize: fs,\n };\n }\n\n /**\n * Dispatches `chip-removed` and removes the chip from the DOM.\n *\n * @returns {void}\n */\n public removeChip(): void {\n const removeEvent = new CustomEvent<SkyChipRemovedEventDetail>(\"chip-removed\", {\n detail: { label: this.label },\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(removeEvent);\n this.remove();\n }\n\n private _slotHasMeaningfulContent(slotEl: HTMLSlotElement): boolean {\n const nodes = slotEl.assignedNodes({ flatten: true });\n return nodes.some((n) =>\n n.nodeType === Node.ELEMENT_NODE\n ? true\n : (n.textContent ?? \"\").trim().length > 0\n );\n }\n\n /** Light DOM check works before the shadow tree exists (first render). */\n private _hasPrefixSlotContent(): boolean {\n return this._prefixFilled;\n }\n\n private _hasSuffixSlotContent(): boolean {\n return this._suffixFilled;\n }\n\n private _hasDefaultSlotContent(): boolean {\n return this._defaultFilled;\n }\n\n private _seedSlotFlagsFromLightDom(): void {\n this._prefixFilled = !!this.querySelector('[slot=\"prefix\"]');\n this._suffixFilled = !!this.querySelector('[slot=\"suffix\"]');\n this._defaultFilled = false;\n for (const n of Array.from(this.childNodes)) {\n if (n.nodeType === Node.ELEMENT_NODE) {\n const slot = (n as Element).getAttribute(\"slot\");\n if (slot === \"prefix\" || slot === \"suffix\") continue;\n this._defaultFilled = true;\n break;\n }\n if ((n.textContent ?? \"\").trim().length > 0) {\n this._defaultFilled = true;\n break;\n }\n }\n this._slotFlagsSeeded = true;\n }\n\n override willUpdate(): void {\n if (!this._slotFlagsSeeded) this._seedSlotFlagsFromLightDom();\n }\n\n private _onSlotChange = (e: Event): void => {\n const slot = e.target as HTMLSlotElement | null;\n if (!slot || slot.tagName !== \"SLOT\") return;\n this._slotFlagsSeeded = true;\n const filled = this._slotHasMeaningfulContent(slot);\n const name = slot.name;\n if (name === \"prefix\") {\n if (this._prefixFilled === filled) return;\n this._prefixFilled = filled;\n } else if (name === \"suffix\") {\n if (this._suffixFilled === filled) return;\n this._suffixFilled = filled;\n } else {\n if (this._defaultFilled === filled) return;\n this._defaultFilled = filled;\n }\n this.requestUpdate();\n };\n\n override render() {\n const sizeDef = this._resolveSize(this.size);\n const chipStyle = {\n padding: sizeDef.padding,\n borderRadius: resolveRadius(this.radius),\n fontSize: sizeDef.fontSize,\n };\n\n return html`\n <div\n class=${classMap({\n chip: true,\n [this.variant]: true,\n loading: this.loading,\n })}\n style=${styleMap(chipStyle)}\n part=\"chip\"\n >\n <slot name=\"prefix\" @slotchange=${this._onSlotChange}></slot>\n ${when(!this._hasPrefixSlotContent() && this.iconL, () => html`\n <sky-icon class=\"icon\" part=\"icon\" icon=\"${this.iconL!}\"></sky-icon>\n `)}\n <slot @slotchange=${this._onSlotChange}></slot>\n ${this._hasDefaultSlotContent() ? nothing : this.label}\n <slot name=\"suffix\" @slotchange=${this._onSlotChange}></slot>\n ${when(!this._hasSuffixSlotContent() && this.iconR, () => html`\n <sky-icon class=\"icon icon-right\" part=\"icon\" icon=\"${this.iconR!}\"></sky-icon>\n `)}\n ${when(this.removable, () => html`\n <button\n class=\"close-button\"\n part=\"close-button\"\n type=\"button\"\n aria-label=\"Remove chip\"\n @click=${this.removeChip}\n >\n <sky-icon icon=\"ion:close\"></sky-icon>\n </button>\n `)}\n ${when(this.loading, () => html`\n <div class=\"loading-overlay\" part=\"loading-overlay\">\n <div class=\"loading-spinner\" part=\"loading-spinner\"></div>\n </div>\n `)}\n </div>\n `;\n }\n}"],"names":["SkyChip","LitElement","constructor","super","arguments","this","label","removable","color","radius","size","iconL","iconR","loading","disabled","variant","preset","_presets","PresetController","_prefixFilled","_suffixFilled","_defaultFilled","_slotFlagsSeeded","_onSlotChange","e","slot","target","tagName","filled","_slotHasMeaningfulContent","name","requestUpdate","updated","changed","has","bgColor","resolveColor","textColor","isDefaultColorToken","ON_COLOR_FALLBACK_LIGHT","style","setProperty","resolveInkColorForToken","resolveAccentColorForToken","removeProperty","_resolveSize","input","presets","xs","padding","fontSize","sm","md","lg","xl","m","String","trim","match","unit","fsNum","parseFloat","fs","clamp","n","min","max","Math","py","px","to","round","removeChip","removeEvent","CustomEvent","detail","bubbles","composed","dispatchEvent","remove","slotEl","assignedNodes","flatten","some","nodeType","Node","ELEMENT_NODE","textContent","length","_hasPrefixSlotContent","_hasSuffixSlotContent","_hasDefaultSlotContent","_seedSlotFlagsFromLightDom","querySelector","Array","from","childNodes","getAttribute","willUpdate","render","sizeDef","chipStyle","borderRadius","resolveRadius","html","classMap","chip","styleMap","when","nothing","dependencies","SkyIcon","styles","skyFocusRingHostStyles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","__decorateClass","property","type","prototype","Boolean","reflect","customElement"],"mappings":"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"}
@@ -263,6 +263,8 @@ export declare class SkyCombobox extends FormControlBase {
263
263
  private iconLeftEls;
264
264
  private iconRightEls;
265
265
  private _searchDebounceId;
266
+ /** When true, skip willUpdate filtering so typing debounce can delay list work. */
267
+ private _deferSearchFilter;
266
268
  private _closeResetId;
267
269
  private static readonly _SEARCH_DEBOUNCE_MS;
268
270
  private static readonly _SEARCH_DEBOUNCE_OPTIONS_THRESHOLD;