@sky.ui/core 0.0.41 → 0.0.43

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 (109) hide show
  1. package/dist/custom-elements.json +1277 -541
  2. package/dist/helper/controllers/animation-controller.d.ts +4 -4
  3. package/dist/helper/controllers/animation-controller.js.map +1 -1
  4. package/dist/helper/controllers/index.d.ts +1 -0
  5. package/dist/helper/controllers/index.js +1 -1
  6. package/dist/helper/controllers/popover-controller.d.ts +1 -1
  7. package/dist/helper/controllers/popover-controller.js.map +1 -1
  8. package/dist/helper/controllers/preset-controller.d.ts +55 -0
  9. package/dist/helper/controllers/preset-controller.js +2 -0
  10. package/dist/helper/controllers/preset-controller.js.map +1 -0
  11. package/dist/helper/iconify-offline.js.map +1 -1
  12. package/dist/helper/index.js +1 -1
  13. package/dist/helper/internals/form-control-base.d.ts +2 -2
  14. package/dist/helper/internals/form-control-base.js.map +1 -1
  15. package/dist/helper/styles/focus-ring.d.ts +10 -0
  16. package/dist/helper/styles/focus-ring.js +10 -0
  17. package/dist/helper/styles/focus-ring.js.map +1 -0
  18. package/dist/helper/utils/color-resolver.d.ts +0 -14
  19. package/dist/helper/utils/color-resolver.js +1 -1
  20. package/dist/helper/utils/color-resolver.js.map +1 -1
  21. package/dist/helper/utils/component-presets.d.ts +132 -0
  22. package/dist/helper/utils/component-presets.js +2 -0
  23. package/dist/helper/utils/component-presets.js.map +1 -0
  24. package/dist/helper/utils/contrast-color.d.ts +2 -2
  25. package/dist/helper/utils/contrast-color.js.map +1 -1
  26. package/dist/helper/utils/index.d.ts +1 -0
  27. package/dist/helper/utils/index.js +1 -1
  28. package/dist/helper/utils/size-resolver.js.map +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/sky-alert/sky-alert.d.ts +12 -4
  31. package/dist/sky-alert/sky-alert.js +4 -4
  32. package/dist/sky-alert/sky-alert.js.map +1 -1
  33. package/dist/sky-appbar/sky-appbar.d.ts +9 -3
  34. package/dist/sky-appbar/sky-appbar.js +4 -4
  35. package/dist/sky-appbar/sky-appbar.js.map +1 -1
  36. package/dist/sky-avatar/sky-avatar.d.ts +5 -1
  37. package/dist/sky-avatar/sky-avatar.js +7 -7
  38. package/dist/sky-avatar/sky-avatar.js.map +1 -1
  39. package/dist/sky-badge/sky-badge.d.ts +6 -2
  40. package/dist/sky-badge/sky-badge.js +6 -6
  41. package/dist/sky-badge/sky-badge.js.map +1 -1
  42. package/dist/sky-button/sky-button.d.ts +24 -4
  43. package/dist/sky-button/sky-button.js +9 -8
  44. package/dist/sky-button/sky-button.js.map +1 -1
  45. package/dist/sky-card/sky-card.d.ts +10 -2
  46. package/dist/sky-card/sky-card.js +4 -4
  47. package/dist/sky-card/sky-card.js.map +1 -1
  48. package/dist/sky-checkbox/sky-checkbox.d.ts +6 -3
  49. package/dist/sky-checkbox/sky-checkbox.js +47 -40
  50. package/dist/sky-checkbox/sky-checkbox.js.map +1 -1
  51. package/dist/sky-chip/sky-chip.d.ts +6 -2
  52. package/dist/sky-chip/sky-chip.js +10 -9
  53. package/dist/sky-chip/sky-chip.js.map +1 -1
  54. package/dist/sky-col/sky-col.d.ts +5 -1
  55. package/dist/sky-col/sky-col.js +4 -4
  56. package/dist/sky-col/sky-col.js.map +1 -1
  57. package/dist/sky-combobox/sky-combobox.d.ts +9 -2
  58. package/dist/sky-combobox/sky-combobox.js +27 -58
  59. package/dist/sky-combobox/sky-combobox.js.map +1 -1
  60. package/dist/sky-dialog/sky-dialog.d.ts +5 -1
  61. package/dist/sky-dialog/sky-dialog.js +3 -3
  62. package/dist/sky-dialog/sky-dialog.js.map +1 -1
  63. package/dist/sky-divider/sky-divider.d.ts +5 -1
  64. package/dist/sky-divider/sky-divider.js +5 -5
  65. package/dist/sky-divider/sky-divider.js.map +1 -1
  66. package/dist/sky-flexbox/sky-flexbox.d.ts +5 -1
  67. package/dist/sky-flexbox/sky-flexbox.js +4 -4
  68. package/dist/sky-flexbox/sky-flexbox.js.map +1 -1
  69. package/dist/sky-flexcol/sky-flexcol.d.ts +5 -1
  70. package/dist/sky-flexcol/sky-flexcol.js +2 -2
  71. package/dist/sky-flexcol/sky-flexcol.js.map +1 -1
  72. package/dist/sky-form/sky-form.d.ts +5 -1
  73. package/dist/sky-form/sky-form.js +2 -2
  74. package/dist/sky-form/sky-form.js.map +1 -1
  75. package/dist/sky-grid/sky-grid.d.ts +5 -1
  76. package/dist/sky-grid/sky-grid.js +3 -3
  77. package/dist/sky-grid/sky-grid.js.map +1 -1
  78. package/dist/sky-icon/sky-icon.d.ts +4 -1
  79. package/dist/sky-icon/sky-icon.js +4 -4
  80. package/dist/sky-icon/sky-icon.js.map +1 -1
  81. package/dist/sky-image/sky-image.d.ts +5 -1
  82. package/dist/sky-image/sky-image.js +5 -5
  83. package/dist/sky-image/sky-image.js.map +1 -1
  84. package/dist/sky-image/srcset-utils.js.map +1 -1
  85. package/dist/sky-input/sky-input.d.ts +5 -1
  86. package/dist/sky-input/sky-input.js +111 -111
  87. package/dist/sky-input/sky-input.js.map +1 -1
  88. package/dist/sky-list/sky-list.d.ts +5 -1
  89. package/dist/sky-list/sky-list.js +3 -3
  90. package/dist/sky-list/sky-list.js.map +1 -1
  91. package/dist/sky-listitem/sky-listitem.d.ts +5 -1
  92. package/dist/sky-listitem/sky-listitem.js +3 -3
  93. package/dist/sky-listitem/sky-listitem.js.map +1 -1
  94. package/dist/sky-radio/sky-radio.d.ts +8 -3
  95. package/dist/sky-radio/sky-radio.js +4 -3
  96. package/dist/sky-radio/sky-radio.js.map +1 -1
  97. package/dist/sky-row/sky-row.d.ts +4 -1
  98. package/dist/sky-row/sky-row.js +2 -2
  99. package/dist/sky-row/sky-row.js.map +1 -1
  100. package/dist/sky-sheet/sky-sheet.d.ts +7 -2
  101. package/dist/sky-sheet/sky-sheet.js +2 -2
  102. package/dist/sky-sheet/sky-sheet.js.map +1 -1
  103. package/dist/sky-simple-table/sky-simple-table.d.ts +5 -1
  104. package/dist/sky-simple-table/sky-simple-table.js +3 -3
  105. package/dist/sky-simple-table/sky-simple-table.js.map +1 -1
  106. package/dist/sky-theme-provider/sky-theme-provider.d.ts +1 -1
  107. package/dist/sky-theme-provider/sky-theme-provider.js +2 -2
  108. package/dist/sky-theme-provider/sky-theme-provider.js.map +1 -1
  109. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sky-list.js","sources":["../../src/sky-list/sky-list.ts"],"sourcesContent":["import { LitElement, html, css, PropertyValues } from \"lit\";\r\nimport { customElement, property, queryAssignedElements } from \"lit/decorators.js\";\r\nimport type { SkyListitem } from \"../sky-listitem/sky-listitem.js\";\r\n\r\nexport type SkyListSelectionMode = \"none\" | \"single\" | \"multiple\";\r\nexport type SkyListChangeDetail = {\r\n selectedItems: SkyListitem[];\r\n /** Values from each selected item's `value` (empty string if unset). */\r\n selectedValues: string[];\r\n};\r\n\r\n/**\r\n * @element sky-list\r\n *\r\n * @summary Styled list container for `sky-listitem` with selection modes and keyboard navigation.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://library.sky-ui.com/components/list\r\n *\r\n * @uiVModel selectedValues list-change detail=selectedValues\r\n *\r\n * @slot - Default slot for `<sky-listitem>` children.\r\n * @property {SkyListSelectionMode} selection - Selection mode (`none`, `single`, `multiple`).\r\n * @property {string[]} selectedValues - Selected item `value`s (mirror for `v-model`; set each `<sky-listitem value=\"…\">`). Default: `[]`.\r\n * @fires {CustomEvent<SkyListChangeDetail>} list-change - Fired when selected items change.\r\n * @method focusListItem Focuses a list item by index.\r\n * @method getItems Returns current slotted list items.\r\n *\r\n * @csspart list-container - The main container wrapping slotted list items.\r\n *\r\n * @Behavior\r\n * - Manages activation and selection state for slotted `sky-listitem` children.\r\n * - Supports keyboard navigation (`ArrowUp/Down`, `Home/End`, `Enter`, `Space`).\r\n * - Emits a normalized selected-items payload on each selection update.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-list selection=\"single\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-list selection=\"single\" @list-change=\"onListChange\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-list selection=\"single\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-list\")\r\nexport class SkyList extends LitElement {\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .list-container {\r\n width: 100%;\r\n border-radius: var(--sky-radius-secondary);\r\n overflow: hidden;\r\n background: var(--sky-glass-solid);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n border: var(--sky-border-primary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-secondary);\r\n isolation: isolate;\r\n }\r\n\r\n ::slotted(sky-listitem[subheader]) {\r\n position: sticky;\r\n top: 0;\r\n z-index: 1;\r\n }\r\n `;\r\n\r\n @property({ type: String }) selection: SkyListSelectionMode = \"none\";\r\n\r\n private _selectedValues: string[] = [];\r\n\r\n /** Bound selection as item `value` strings (requires `value` on items). Coerces null to `[]`. */\r\n @property({ type: Array })\r\n get selectedValues(): string[] {\r\n return this._selectedValues;\r\n }\r\n set selectedValues(value: string[] | null | undefined) {\r\n const old = this._selectedValues;\r\n this._selectedValues = Array.isArray(value) ? value : [];\r\n this.requestUpdate(\"selectedValues\", old);\r\n }\r\n\r\n @queryAssignedElements({ flatten: true })\r\n private items!: SkyListitem[];\r\n\r\n private currentIndex = 0;\r\n\r\n /** Avoid feedback when syncing selection from the `selectedValues` prop. */\r\n private _syncingSelectedValues = false;\r\n\r\n private _onItemActivate = (e: Event) => this.onItemActivate(e as CustomEvent);\r\n\r\n private _onSlotChange = () => {\r\n this._applySelectedValuesFromProp();\r\n this._focusFirstNavigable();\r\n };\r\n\r\n override firstUpdated(): void {\r\n this.syncAriaRole();\r\n this.addEventListener(\"keydown\", this.onKeydown);\r\n this.addEventListener(\"item-activate\", this._onItemActivate);\r\n this._applySelectedValuesFromProp();\r\n this._focusFirstNavigable();\r\n }\r\n\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.removeEventListener(\"keydown\", this.onKeydown);\r\n this.removeEventListener(\"item-activate\", this._onItemActivate);\r\n }\r\n\r\n private syncAriaRole(): void {\r\n if (this.selection === \"none\") {\r\n this.setAttribute(\"role\", \"list\");\r\n this.removeAttribute(\"aria-multiselectable\");\r\n return;\r\n }\r\n\r\n this.setAttribute(\"role\", \"listbox\");\r\n if (this.selection === \"multiple\") {\r\n this.setAttribute(\"aria-multiselectable\", \"true\");\r\n } else {\r\n this.removeAttribute(\"aria-multiselectable\");\r\n }\r\n }\r\n\r\n private navigableItems(): SkyListitem[] {\r\n return (this.items ?? []).filter((item) => this.isNavigableItem(item));\r\n }\r\n\r\n private isNavigableItem(item: SkyListitem | undefined): boolean {\r\n return !!item && !item.disabled && !item.subheader;\r\n }\r\n\r\n private itemIndex(item: SkyListitem): number {\r\n return (this.items ?? []).indexOf(item);\r\n }\r\n\r\n private onItemActivate(e: CustomEvent): void {\r\n const item = e.detail.item as SkyListitem;\r\n if (!this.isNavigableItem(item)) return;\r\n\r\n if (this.selection === \"single\") {\r\n this.items.forEach((i) => i.setSelected(false));\r\n item.setSelected(true);\r\n } else if (this.selection === \"multiple\") {\r\n item.setSelected(!item.selected);\r\n }\r\n\r\n const selectedItems = this.items.filter((i) => i.selected);\r\n const selectedValues = selectedItems.map((i) => i.value || \"\");\r\n this._syncingSelectedValues = true;\r\n this.selectedValues = [...selectedValues];\r\n this._syncingSelectedValues = false;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyListChangeDetail>(\"list-change\", {\r\n detail: {\r\n selectedItems,\r\n selectedValues,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n /** Applies `selectedValues` from the host to child items. */\r\n private _applySelectedValuesFromProp(): void {\r\n if (!this.items?.length || this.selection === \"none\") return;\r\n\r\n const want = new Set(this.selectedValues ?? []);\r\n if (this.selection === \"single\") {\r\n const first = [...want][0];\r\n for (const item of this.items) {\r\n if (item.subheader) continue;\r\n item.setSelected(first !== undefined && item.value === first);\r\n }\r\n return;\r\n }\r\n\r\n for (const item of this.items) {\r\n if (item.subheader) continue;\r\n item.setSelected(want.has(item.value));\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(\"selection\")) {\r\n this.syncAriaRole();\r\n }\r\n\r\n if ((changed.has(\"selectedValues\") || changed.has(\"selection\")) && !this._syncingSelectedValues) {\r\n this._applySelectedValuesFromProp();\r\n }\r\n }\r\n\r\n private onKeydown(e: KeyboardEvent): void {\r\n const navigable = this.navigableItems();\r\n if (!navigable.length) return;\r\n\r\n switch (e.key) {\r\n case \"ArrowDown\":\r\n e.preventDefault();\r\n this.focusStep(1);\r\n break;\r\n case \"ArrowUp\":\r\n e.preventDefault();\r\n this.focusStep(-1);\r\n break;\r\n case \"Home\":\r\n e.preventDefault();\r\n this.focusItem(this.itemIndex(navigable[0]!));\r\n break;\r\n case \"End\":\r\n e.preventDefault();\r\n this.focusItem(this.itemIndex(navigable[navigable.length - 1]!));\r\n break;\r\n case \" \":\r\n case \"Enter\":\r\n e.preventDefault();\r\n this.items[this.currentIndex]?.dispatchEvent(\r\n new CustomEvent(\"item-activate\", {\r\n detail: { item: this.items[this.currentIndex] },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n break;\r\n }\r\n }\r\n\r\n private focusStep(delta: number): void {\r\n const navigable = this.navigableItems();\r\n if (!navigable.length) return;\r\n\r\n const current = this.items[this.currentIndex];\r\n let navIdx = current ? navigable.indexOf(current) : -1;\r\n if (navIdx < 0) navIdx = delta > 0 ? -1 : navigable.length;\r\n\r\n const nextNavIdx = Math.max(0, Math.min(navIdx + delta, navigable.length - 1));\r\n const next = navigable[nextNavIdx];\r\n if (next) this.focusItem(this.itemIndex(next));\r\n }\r\n\r\n private _focusFirstNavigable(): void {\r\n const first = this.navigableItems()[0];\r\n if (first) this.focusItem(this.itemIndex(first));\r\n }\r\n\r\n private focusItem(index: number): void {\r\n if (!this.items?.length) return;\r\n\r\n const len = this.items.length;\r\n let next = Math.max(0, Math.min(index, len - 1));\r\n if (!this.isNavigableItem(this.items[next])) {\r\n const navigable = this.navigableItems();\r\n const candidate = navigable.find((item) => this.itemIndex(item) >= next) ?? navigable[0];\r\n if (!candidate) return;\r\n next = this.itemIndex(candidate);\r\n }\r\n\r\n const prev = this.items[this.currentIndex];\r\n if (prev) prev.shadowRoot?.querySelector(\".list-item\")?.setAttribute(\"tabindex\", \"-1\");\r\n\r\n this.currentIndex = next;\r\n const current = this.items[this.currentIndex];\r\n if (current && this.isNavigableItem(current)) {\r\n const el = current.shadowRoot?.querySelector(\".list-item\") as HTMLElement | null;\r\n if (el) {\r\n el.setAttribute(\"tabindex\", \"0\");\r\n el.focus();\r\n }\r\n }\r\n }\r\n\r\n public focusListItem(index: number): void {\r\n this.focusItem(index);\r\n }\r\n\r\n public getItems(): SkyListitem[] {\r\n return [...(this.items ?? [])];\r\n }\r\n\r\n override render() {\r\n return html`\r\n <div class=\"list-container\" part=\"list-container\">\r\n <slot @slotchange=${this._onSlotChange}></slot>\r\n </div>\r\n `;\r\n }\r\n}"],"names":["SkyList","LitElement","constructor","super","arguments","this","selection","_selectedValues","currentIndex","_syncingSelectedValues","_onItemActivate","e","onItemActivate","_onSlotChange","_applySelectedValuesFromProp","_focusFirstNavigable","selectedValues","value","old","Array","isArray","requestUpdate","firstUpdated","syncAriaRole","addEventListener","onKeydown","disconnectedCallback","removeEventListener","setAttribute","removeAttribute","navigableItems","items","filter","item","isNavigableItem","disabled","subheader","itemIndex","indexOf","detail","forEach","i","setSelected","selected","selectedItems","map","dispatchEvent","CustomEvent","bubbles","composed","length","want","Set","first","has","updated","changed","navigable","key","preventDefault","focusStep","focusItem","delta","current","navIdx","next","Math","max","min","index","len","candidate","find","prev","shadowRoot","querySelector","el","focus","focusListItem","getItems","render","html","styles","css","__decorateClass","property","type","String","prototype","queryAssignedElements","flatten","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"sky-list.js","sources":["../../src/sky-list/sky-list.ts"],"sourcesContent":["import { LitElement, html, css, PropertyValues } from \"lit\";\r\nimport { customElement, property, queryAssignedElements } from \"lit/decorators.js\";\r\nimport type { SkyListitem } from \"../sky-listitem/sky-listitem.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkyListSelectionMode = \"none\" | \"single\" | \"multiple\";\r\nexport type SkyListChangeDetail = {\r\n selectedItems: SkyListitem[];\r\n /** Values from each selected item's `value` (empty string if unset). */\r\n selectedValues: string[];\r\n};\r\n\r\n/**\r\n * @element sky-list\r\n *\r\n * @summary Styled list container for `sky-listitem` with selection modes and keyboard navigation.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/list\r\n *\r\n * @uiVModel selectedValues list-change detail=selectedValues\r\n *\r\n * @slot - Default slot for `<sky-listitem>` children.\r\n * @property {SkyListSelectionMode} selection - Selection mode (`none`, `single`, `multiple`).\r\n * @property {string[]} selectedValues - Selected item `value`s (mirror for `v-model`; set each `<sky-listitem value=\"…\">`). Default: `[]`.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n * @fires {CustomEvent<SkyListChangeDetail>} list-change - Fired when selected items change.\r\n * @method focusListItem Focuses a list item by index.\r\n * @method getItems Returns current slotted list items.\r\n *\r\n * @csspart list-container - The main container wrapping slotted list items.\r\n *\r\n * @Behavior\r\n * - Manages activation and selection state for slotted `sky-listitem` children.\r\n * - Supports keyboard navigation (`ArrowUp/Down`, `Home/End`, `Enter`, `Space`).\r\n * - Emits a normalized selected-items payload on each selection update.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-list selection=\"single\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-list selection=\"single\" @list-change=\"onListChange\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-list selection=\"single\">\r\n * <sky-listitem>Option A</sky-listitem>\r\n * <sky-listitem>Option B</sky-listitem>\r\n * <sky-listitem>Option C</sky-listitem>\r\n * </sky-list>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-list\")\r\nexport class SkyList extends LitElement {\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: block;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .list-container {\r\n width: 100%;\r\n border-radius: var(--sky-radius-secondary);\r\n overflow: hidden;\r\n background: var(--sky-glass-solid);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n border: var(--sky-border-primary);\r\n box-shadow:\r\n var(--sky-box-shadow-inset),\r\n var(--sky-box-shadow-secondary);\r\n isolation: isolate;\r\n }\r\n\r\n ::slotted(sky-listitem[subheader]) {\r\n position: sticky;\r\n top: 0;\r\n z-index: 1;\r\n }\r\n `;\r\n\r\n @property({ type: String }) selection: SkyListSelectionMode = \"none\";\r\n\r\n private _selectedValues: string[] = [];\r\n\r\n /** Bound selection as item `value` strings (requires `value` on items). Coerces null to `[]`. */\r\n @property({ type: Array })\r\n get selectedValues(): string[] {\r\n return this._selectedValues;\r\n }\r\n set selectedValues(value: string[] | null | undefined) {\r\n const old = this._selectedValues;\r\n this._selectedValues = Array.isArray(value) ? value : [];\r\n this.requestUpdate(\"selectedValues\", old);\r\n }\r\n\r\n @queryAssignedElements({ flatten: true })\r\n private items!: SkyListitem[];\r\n\r\n private currentIndex = 0;\r\n\r\n /** Avoid feedback when syncing selection from the `selectedValues` prop. */\r\n private _syncingSelectedValues = false;\r\n\r\n private _onItemActivate = (e: Event) => this.onItemActivate(e as CustomEvent);\r\n\r\n private _onSlotChange = () => {\r\n this._applySelectedValuesFromProp();\r\n this._focusFirstNavigable();\r\n };\r\n\r\n override firstUpdated(): void {\r\n this.syncAriaRole();\r\n this.addEventListener(\"keydown\", this.onKeydown);\r\n this.addEventListener(\"item-activate\", this._onItemActivate);\r\n this._applySelectedValuesFromProp();\r\n this._focusFirstNavigable();\r\n }\r\n\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.removeEventListener(\"keydown\", this.onKeydown);\r\n this.removeEventListener(\"item-activate\", this._onItemActivate);\r\n }\r\n\r\n private syncAriaRole(): void {\r\n if (this.selection === \"none\") {\r\n this.setAttribute(\"role\", \"list\");\r\n this.removeAttribute(\"aria-multiselectable\");\r\n return;\r\n }\r\n\r\n this.setAttribute(\"role\", \"listbox\");\r\n if (this.selection === \"multiple\") {\r\n this.setAttribute(\"aria-multiselectable\", \"true\");\r\n } else {\r\n this.removeAttribute(\"aria-multiselectable\");\r\n }\r\n }\r\n\r\n private navigableItems(): SkyListitem[] {\r\n return (this.items ?? []).filter((item) => this.isNavigableItem(item));\r\n }\r\n\r\n private isNavigableItem(item: SkyListitem | undefined): boolean {\r\n return !!item && !item.disabled && !item.subheader;\r\n }\r\n\r\n private itemIndex(item: SkyListitem): number {\r\n return (this.items ?? []).indexOf(item);\r\n }\r\n\r\n private onItemActivate(e: CustomEvent): void {\r\n const item = e.detail.item as SkyListitem;\r\n if (!this.isNavigableItem(item)) return;\r\n\r\n if (this.selection === \"single\") {\r\n this.items.forEach((i) => i.setSelected(false));\r\n item.setSelected(true);\r\n } else if (this.selection === \"multiple\") {\r\n item.setSelected(!item.selected);\r\n }\r\n\r\n const selectedItems = this.items.filter((i) => i.selected);\r\n const selectedValues = selectedItems.map((i) => i.value || \"\");\r\n this._syncingSelectedValues = true;\r\n this.selectedValues = [...selectedValues];\r\n this._syncingSelectedValues = false;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent<SkyListChangeDetail>(\"list-change\", {\r\n detail: {\r\n selectedItems,\r\n selectedValues,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n /** Applies `selectedValues` from the host to child items. */\r\n private _applySelectedValuesFromProp(): void {\r\n if (!this.items?.length || this.selection === \"none\") return;\r\n\r\n const want = new Set(this.selectedValues ?? []);\r\n if (this.selection === \"single\") {\r\n const first = [...want][0];\r\n for (const item of this.items) {\r\n if (item.subheader) continue;\r\n item.setSelected(first !== undefined && item.value === first);\r\n }\r\n return;\r\n }\r\n\r\n for (const item of this.items) {\r\n if (item.subheader) continue;\r\n item.setSelected(want.has(item.value));\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(\"selection\")) {\r\n this.syncAriaRole();\r\n }\r\n\r\n if ((changed.has(\"selectedValues\") || changed.has(\"selection\")) && !this._syncingSelectedValues) {\r\n this._applySelectedValuesFromProp();\r\n }\r\n }\r\n\r\n private onKeydown(e: KeyboardEvent): void {\r\n const navigable = this.navigableItems();\r\n if (!navigable.length) return;\r\n\r\n switch (e.key) {\r\n case \"ArrowDown\":\r\n e.preventDefault();\r\n this.focusStep(1);\r\n break;\r\n case \"ArrowUp\":\r\n e.preventDefault();\r\n this.focusStep(-1);\r\n break;\r\n case \"Home\":\r\n e.preventDefault();\r\n this.focusItem(this.itemIndex(navigable[0]!));\r\n break;\r\n case \"End\":\r\n e.preventDefault();\r\n this.focusItem(this.itemIndex(navigable[navigable.length - 1]!));\r\n break;\r\n case \" \":\r\n case \"Enter\":\r\n e.preventDefault();\r\n this.items[this.currentIndex]?.dispatchEvent(\r\n new CustomEvent(\"item-activate\", {\r\n detail: { item: this.items[this.currentIndex] },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n break;\r\n }\r\n }\r\n\r\n private focusStep(delta: number): void {\r\n const navigable = this.navigableItems();\r\n if (!navigable.length) return;\r\n\r\n const current = this.items[this.currentIndex];\r\n let navIdx = current ? navigable.indexOf(current) : -1;\r\n if (navIdx < 0) navIdx = delta > 0 ? -1 : navigable.length;\r\n\r\n const nextNavIdx = Math.max(0, Math.min(navIdx + delta, navigable.length - 1));\r\n const next = navigable[nextNavIdx];\r\n if (next) this.focusItem(this.itemIndex(next));\r\n }\r\n\r\n private _focusFirstNavigable(): void {\r\n const first = this.navigableItems()[0];\r\n if (first) this.focusItem(this.itemIndex(first));\r\n }\r\n\r\n private focusItem(index: number): void {\r\n if (!this.items?.length) return;\r\n\r\n const len = this.items.length;\r\n let next = Math.max(0, Math.min(index, len - 1));\r\n if (!this.isNavigableItem(this.items[next])) {\r\n const navigable = this.navigableItems();\r\n const candidate = navigable.find((item) => this.itemIndex(item) >= next) ?? navigable[0];\r\n if (!candidate) return;\r\n next = this.itemIndex(candidate);\r\n }\r\n\r\n const prev = this.items[this.currentIndex];\r\n if (prev) prev.shadowRoot?.querySelector(\".list-item\")?.setAttribute(\"tabindex\", \"-1\");\r\n\r\n this.currentIndex = next;\r\n const current = this.items[this.currentIndex];\r\n if (current && this.isNavigableItem(current)) {\r\n const el = current.shadowRoot?.querySelector(\".list-item\") as HTMLElement | null;\r\n if (el) {\r\n el.setAttribute(\"tabindex\", \"0\");\r\n el.focus();\r\n }\r\n }\r\n }\r\n\r\n public focusListItem(index: number): void {\r\n this.focusItem(index);\r\n }\r\n\r\n public getItems(): SkyListitem[] {\r\n return [...(this.items ?? [])];\r\n }\r\n\r\n override render() {\r\n return html`\r\n <div class=\"list-container\" part=\"list-container\">\r\n <slot @slotchange=${this._onSlotChange}></slot>\r\n </div>\r\n `;\r\n }\r\n}"],"names":["SkyList","LitElement","constructor","super","arguments","this","preset","_presets","PresetController","selection","_selectedValues","currentIndex","_syncingSelectedValues","_onItemActivate","e","onItemActivate","_onSlotChange","_applySelectedValuesFromProp","_focusFirstNavigable","selectedValues","value","old","Array","isArray","requestUpdate","firstUpdated","syncAriaRole","addEventListener","onKeydown","disconnectedCallback","removeEventListener","setAttribute","removeAttribute","navigableItems","items","filter","item","isNavigableItem","disabled","subheader","itemIndex","indexOf","detail","forEach","i","setSelected","selected","selectedItems","map","dispatchEvent","CustomEvent","bubbles","composed","length","want","Set","first","has","updated","changed","navigable","key","preventDefault","focusStep","focusItem","delta","current","navIdx","next","Math","max","min","index","len","candidate","find","prev","shadowRoot","querySelector","el","focus","focusListItem","getItems","render","html","styles","css","__decorateClass","property","type","String","reflect","prototype","queryAssignedElements","flatten","customElement"],"mappings":"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"}
@@ -10,7 +10,7 @@ export type SkyListitemActivateDetail = {
10
10
  * @status stable
11
11
  * @since 1.0.0
12
12
  *
13
- * @documentation https://library.sky-ui.com/components/list
13
+ * @documentation https://sky-ui.com/components/list
14
14
  *
15
15
  * @slot content - Main content of the list item (usually label or text).
16
16
  * @slot actions - Trailing action elements (e.g., icons, buttons).
@@ -20,6 +20,7 @@ export type SkyListitemActivateDetail = {
20
20
  * @property {boolean} selected - Whether item is selected.
21
21
  * @property {boolean} dense - Whether compact spacing is used.
22
22
  * @property {boolean} disabled - Whether interaction is disabled.
23
+ * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `""`.
23
24
  * @fires {CustomEvent<SkyListitemActivateDetail>} item-activate - Fired when the item is activated.
24
25
  * @method setSelected Sets selection state programmatically.
25
26
  *
@@ -69,6 +70,9 @@ export declare class SkyListitem extends LitElement {
69
70
  selected: boolean;
70
71
  dense: boolean;
71
72
  disabled: boolean;
73
+ /** Named prop preset from nearest `sky-config-provider`. */
74
+ preset: string;
75
+ private _presets;
72
76
  static styles: import("lit").CSSResult;
73
77
  private onClick;
74
78
  setSelected(selected: boolean): void;
@@ -1,4 +1,4 @@
1
- import{css as e,LitElement as t,html as s,nothing as r}from"lit";import{property as a,customElement as i}from"lit/decorators.js";import{when as o}from"lit/directives/when.js";var n=Object.defineProperty,l=Object.getOwnPropertyDescriptor,d=(e,t,s,r)=>{for(var a,i=r>1?void 0:r?l(t,s):t,o=e.length-1;o>=0;o--)(a=e[o])&&(i=(r?a(t,s,i):a(i))||i);return r&&i&&n(t,s,i),i};let p=class extends t{constructor(){super(...arguments),this.avatar="",this.value="",this.subheader="",this.selected=!1,this.dense=!1,this.disabled=!1}onClick(){this.disabled||this.subheader||this.dispatchEvent(new CustomEvent("item-activate",{detail:{item:this},bubbles:!0,composed:!0}))}setSelected(e){this.selected=e,this.requestUpdate()}render(){return this.subheader?s`
1
+ import{css as e,LitElement as t,html as s,nothing as r}from"lit";import{property as a,customElement as i}from"lit/decorators.js";import{when as o}from"lit/directives/when.js";import{PresetController as n}from"../helper/controllers/preset-controller.js";var l=Object.defineProperty,d=Object.getOwnPropertyDescriptor,p=(e,t,s,r)=>{for(var a,i=r>1?void 0:r?d(t,s):t,o=e.length-1;o>=0;o--)(a=e[o])&&(i=(r?a(t,s,i):a(i))||i);return r&&i&&l(t,s,i),i};let c=class extends t{constructor(){super(...arguments),this.avatar="",this.value="",this.subheader="",this.selected=!1,this.dense=!1,this.disabled=!1,this.preset="",this._presets=new n(this)}onClick(){this.disabled||this.subheader||this.dispatchEvent(new CustomEvent("item-activate",{detail:{item:this},bubbles:!0,composed:!0}))}setSelected(e){this.selected=e,this.requestUpdate()}render(){return this.subheader?s`
2
2
  <div class="subheader" part="subheader" role="presentation">${this.subheader}</div>
3
3
  `:s`
4
4
  <div
@@ -27,7 +27,7 @@ import{css as e,LitElement as t,html as s,nothing as r}from"lit";import{property
27
27
  <slot name="actions">${r}</slot>
28
28
  </div>
29
29
  </div>
30
- `}};p.styles=e`
30
+ `}};c.styles=e`
31
31
  :host {
32
32
  display: block;
33
33
  cursor: pointer;
@@ -132,5 +132,5 @@ import{css as e,LitElement as t,html as s,nothing as r}from"lit";import{property
132
132
  transition: none;
133
133
  }
134
134
  }
135
- `,d([a({type:String})],p.prototype,"avatar",2),d([a({type:String})],p.prototype,"value",2),d([a({type:String,reflect:!0})],p.prototype,"subheader",2),d([a({type:Boolean,reflect:!0})],p.prototype,"selected",2),d([a({type:Boolean,reflect:!0})],p.prototype,"dense",2),d([a({type:Boolean,reflect:!0})],p.prototype,"disabled",2),p=d([i("sky-listitem")],p);export{p as SkyListitem};
135
+ `,p([a({type:String})],c.prototype,"avatar",2),p([a({type:String})],c.prototype,"value",2),p([a({type:String,reflect:!0})],c.prototype,"subheader",2),p([a({type:Boolean,reflect:!0})],c.prototype,"selected",2),p([a({type:Boolean,reflect:!0})],c.prototype,"dense",2),p([a({type:Boolean,reflect:!0})],c.prototype,"disabled",2),p([a({type:String,reflect:!0})],c.prototype,"preset",2),c=p([i("sky-listitem")],c);export{c as SkyListitem};
136
136
  //# sourceMappingURL=sky-listitem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sky-listitem.js","sources":["../../src/sky-listitem/sky-listitem.ts"],"sourcesContent":["import { LitElement, html, css, nothing } from \"lit\";\r\nimport { customElement, property } from \"lit/decorators.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\n\r\nexport type SkyListitemActivateDetail = { item: SkyListitem };\r\n\r\n/**\r\n * @element sky-listitem\r\n *\r\n * @summary List item with optional avatar, actions, subheader mode, and selectable state.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://library.sky-ui.com/components/list\r\n *\r\n * @slot content - Main content of the list item (usually label or text).\r\n * @slot actions - Trailing action elements (e.g., icons, buttons).\r\n * @property {string} avatar - Optional avatar image URL.\r\n * @property {string} value - Stable id for selection (`sky-list` `selectedValues` / `list-change`). Default: `\"\"`.\r\n * @property {string} subheader - Subheader text; when set, item renders as a section header.\r\n * @property {boolean} selected - Whether item is selected.\r\n * @property {boolean} dense - Whether compact spacing is used.\r\n * @property {boolean} disabled - Whether interaction is disabled.\r\n * @fires {CustomEvent<SkyListitemActivateDetail>} item-activate - Fired when the item is activated.\r\n * @method setSelected Sets selection state programmatically.\r\n *\r\n * @csspart list-item - The main list item container.\r\n * @csspart leading - The leading section (avatar container).\r\n * @csspart avatar - The avatar image element.\r\n * @csspart content - The content wrapper for the main slot.\r\n * @csspart actions - The trailing actions container.\r\n * @csspart subheader - The subheader divider element.\r\n *\r\n * @Behavior\r\n * - Renders either a selectable list row or a non-interactive subheader variant.\r\n * - Emits `item-activate` for parent list orchestration.\r\n * - Supports compact and disabled display variants.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected>\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected @item-activate=\"onActivate\">\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected>\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-listitem\")\r\nexport class SkyListitem extends LitElement {\r\n @property({ type: String }) avatar = \"\";\r\n /** Optional stable value for list selection (`sky-list` binding). */\r\n @property({ type: String }) value = \"\";\r\n @property({ type: String, reflect: true }) subheader = \"\";\r\n @property({ type: Boolean, reflect: true }) selected = false;\r\n @property({ type: Boolean, reflect: true }) dense = false;\r\n @property({ type: Boolean, reflect: true }) disabled = false;\r\n\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n cursor: pointer;\r\n outline: none;\r\n }\r\n\r\n :host([subheader]) {\r\n cursor: default;\r\n }\r\n\r\n :host([disabled]) {\r\n opacity: var(--sky-opacity-disabled, 0.6);\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n }\r\n\r\n .list-item {\r\n display: flex;\r\n align-items: center;\r\n padding: var(--sky-space-2\\\\.5, 10px) var(--sky-space-3\\\\.5, 14px);\r\n border-bottom: var(--sky-border-primary);\r\n border-inline-start: 3px solid transparent;\r\n transition:\r\n background var(--sky-transition-normal, 200ms ease),\r\n border-color var(--sky-transition-normal, 200ms ease),\r\n box-shadow var(--sky-transition-normal, 200ms ease);\r\n color: var(--sky-text-primary);\r\n position: relative;\r\n box-sizing: border-box;\r\n }\r\n\r\n :host(:hover:not([disabled])) .list-item,\r\n :host(:focus-visible) .list-item {\r\n background: var(--sky-hover-primary);\r\n }\r\n\r\n :host(:focus-visible) .list-item {\r\n box-shadow: var(--sky-focus-ring);\r\n }\r\n\r\n :host([selected]) .list-item {\r\n background: var(--sky-hover-secondary);\r\n border-inline-start-color: var(--sky-active-primary);\r\n }\r\n\r\n :host(:last-child) .list-item {\r\n border-bottom: none;\r\n }\r\n\r\n .leading {\r\n display: flex;\r\n align-items: center;\r\n margin-inline-end: var(--sky-space-3, 12px);\r\n flex-shrink: 0;\r\n }\r\n\r\n .avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: var(--sky-radius-full);\r\n object-fit: cover;\r\n background: var(--sky-hover-tertiary);\r\n }\r\n\r\n :host([dense]) .list-item {\r\n padding: var(--sky-space-1\\\\.5, 6px) var(--sky-space-2\\\\.5, 10px);\r\n }\r\n\r\n :host([dense]) .avatar {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n\r\n .content {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n text-align: start;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .actions {\r\n display: flex;\r\n align-items: center;\r\n margin-inline-start: var(--sky-space-3, 12px);\r\n gap: var(--sky-space-2, 8px);\r\n flex-shrink: 0;\r\n }\r\n\r\n .subheader {\r\n font-family: var(--sky-font);\r\n font-size: var(--sky-font-size-sm);\r\n text-align: start;\r\n color: var(--sky-text-secondary);\r\n padding: var(--sky-space-1\\\\.5, 6px) var(--sky-space-3\\\\.5, 14px);\r\n font-weight: var(--sky-font-weight-semibold);\r\n background: var(--sky-hover-tertiary);\r\n border-bottom: var(--sky-border-primary);\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .list-item {\r\n transition: none;\r\n }\r\n }\r\n `;\r\n\r\n private onClick(): void {\r\n if (this.disabled || this.subheader) return;\r\n this.dispatchEvent(\r\n new CustomEvent<SkyListitemActivateDetail>(\"item-activate\", {\r\n detail: { item: this },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n setSelected(selected: boolean): void {\r\n this.selected = selected;\r\n this.requestUpdate();\r\n }\r\n\r\n override render() {\r\n if (this.subheader) {\r\n return html`\r\n <div class=\"subheader\" part=\"subheader\" role=\"presentation\">${this.subheader}</div>\r\n `;\r\n }\r\n\r\n return html`\r\n <div\r\n class=\"list-item\"\r\n part=\"list-item\"\r\n role=\"option\"\r\n aria-selected=${this.selected ? \"true\" : \"false\"}\r\n aria-disabled=${this.disabled ? \"true\" : \"false\"}\r\n tabindex=\"-1\"\r\n @click=${this.onClick}\r\n >\r\n ${when(\r\n this.avatar,\r\n () => html`\r\n <div class=\"leading\" part=\"leading\">\r\n <img\r\n class=\"avatar\"\r\n src=${this.avatar}\r\n alt=\"\"\r\n part=\"avatar\"\r\n />\r\n </div>\r\n `,\r\n )}\r\n\r\n <div class=\"content\" part=\"content\"><slot name=\"content\"></slot></div>\r\n\r\n <div class=\"actions\" part=\"actions\">\r\n <slot name=\"actions\">${nothing}</slot>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}"],"names":["SkyListitem","LitElement","constructor","super","arguments","this","avatar","value","subheader","selected","dense","disabled","onClick","dispatchEvent","CustomEvent","detail","item","bubbles","composed","setSelected","requestUpdate","render","html","when","nothing","styles","css","__decorateClass","property","type","String","prototype","reflect","Boolean","customElement"],"mappings":"+WAkEO,IAAMA,EAAN,cAA0BC,EAA1B,WAAAC,GAAAC,SAAAC,WACuBC,KAAAC,OAAS,GAETD,KAAAE,MAAQ,GACOF,KAAAG,UAAY,GACXH,KAAAI,UAAW,EACXJ,KAAAK,OAAQ,EACRL,KAAAM,UAAW,CAAA,CA6G/C,OAAAC,GACFP,KAAKM,UAAYN,KAAKG,WAC1BH,KAAKQ,cACH,IAAIC,YAAuC,gBAAiB,CAC1DC,OAAQ,CAAEC,KAAMX,MAChBY,SAAS,EACTC,UAAU,IAGhB,CAEA,WAAAC,CAAYV,GACVJ,KAAKI,SAAWA,EAChBJ,KAAKe,eACP,CAES,MAAAC,GACP,OAAIhB,KAAKG,UACAc,CAAA;sEACyDjB,KAAKG;QAIhEc,CAAA;;;;;wBAKajB,KAAKI,SAAW,OAAS;wBACzBJ,KAAKM,SAAW,OAAS;;iBAEhCN,KAAKO;;UAEZW,EACAlB,KAAKC,OACL,IAAMgB,CAAA;;;;sBAIMjB,KAAKC;;;;;;;;;;iCAWMkB;;;KAI/B,GA1KWxB,EASKyB,OAASC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IARGC,EAAA,CAA3BC,EAAS,CAAEC,KAAMC,UADP9B,EACiB+B,UAAA,SAAA,GAEAJ,EAAA,CAA3BC,EAAS,CAAEC,KAAMC,UAHP9B,EAGiB+B,UAAA,QAAA,GACeJ,EAAA,CAA1CC,EAAS,CAAEC,KAAMC,OAAQE,SAAS,KAJxBhC,EAIgC+B,UAAA,YAAA,GACCJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KALzBhC,EAKiC+B,UAAA,WAAA,GACAJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KANzBhC,EAMiC+B,UAAA,QAAA,GACAJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KAPzBhC,EAOiC+B,UAAA,WAAA,GAPjC/B,EAAN2B,EAAA,CADNO,EAAc,iBACFlC"}
1
+ {"version":3,"file":"sky-listitem.js","sources":["../../src/sky-listitem/sky-listitem.ts"],"sourcesContent":["import { LitElement, html, css, nothing } from \"lit\";\r\nimport { customElement, property } from \"lit/decorators.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkyListitemActivateDetail = { item: SkyListitem };\r\n\r\n/**\r\n * @element sky-listitem\r\n *\r\n * @summary List item with optional avatar, actions, subheader mode, and selectable state.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/list\r\n *\r\n * @slot content - Main content of the list item (usually label or text).\r\n * @slot actions - Trailing action elements (e.g., icons, buttons).\r\n * @property {string} avatar - Optional avatar image URL.\r\n * @property {string} value - Stable id for selection (`sky-list` `selectedValues` / `list-change`). Default: `\"\"`.\r\n * @property {string} subheader - Subheader text; when set, item renders as a section header.\r\n * @property {boolean} selected - Whether item is selected.\r\n * @property {boolean} dense - Whether compact spacing is used.\r\n * @property {boolean} disabled - Whether interaction is disabled.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n * @fires {CustomEvent<SkyListitemActivateDetail>} item-activate - Fired when the item is activated.\r\n * @method setSelected Sets selection state programmatically.\r\n *\r\n * @csspart list-item - The main list item container.\r\n * @csspart leading - The leading section (avatar container).\r\n * @csspart avatar - The avatar image element.\r\n * @csspart content - The content wrapper for the main slot.\r\n * @csspart actions - The trailing actions container.\r\n * @csspart subheader - The subheader divider element.\r\n *\r\n * @Behavior\r\n * - Renders either a selectable list row or a non-interactive subheader variant.\r\n * - Emits `item-activate` for parent list orchestration.\r\n * - Supports compact and disabled display variants.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected>\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected @item-activate=\"onActivate\">\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-listitem avatar=\"https://example.com/avatar.jpg\" selected>\r\n * <span slot=\"content\">John Doe</span>\r\n * <button slot=\"actions\" type=\"button\">Action</button>\r\n * </sky-listitem>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-listitem\")\r\nexport class SkyListitem extends LitElement {\r\n @property({ type: String }) avatar = \"\";\r\n /** Optional stable value for list selection (`sky-list` binding). */\r\n @property({ type: String }) value = \"\";\r\n @property({ type: String, reflect: true }) subheader = \"\";\r\n @property({ type: Boolean, reflect: true }) selected = false;\r\n @property({ type: Boolean, reflect: true }) dense = false;\r\n @property({ type: Boolean, reflect: true }) disabled = false;\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: block;\r\n cursor: pointer;\r\n outline: none;\r\n }\r\n\r\n :host([subheader]) {\r\n cursor: default;\r\n }\r\n\r\n :host([disabled]) {\r\n opacity: var(--sky-opacity-disabled, 0.6);\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n }\r\n\r\n .list-item {\r\n display: flex;\r\n align-items: center;\r\n padding: var(--sky-space-2\\\\.5, 10px) var(--sky-space-3\\\\.5, 14px);\r\n border-bottom: var(--sky-border-primary);\r\n border-inline-start: 3px solid transparent;\r\n transition:\r\n background var(--sky-transition-normal, 200ms ease),\r\n border-color var(--sky-transition-normal, 200ms ease),\r\n box-shadow var(--sky-transition-normal, 200ms ease);\r\n color: var(--sky-text-primary);\r\n position: relative;\r\n box-sizing: border-box;\r\n }\r\n\r\n :host(:hover:not([disabled])) .list-item,\r\n :host(:focus-visible) .list-item {\r\n background: var(--sky-hover-primary);\r\n }\r\n\r\n :host(:focus-visible) .list-item {\r\n box-shadow: var(--sky-focus-ring);\r\n }\r\n\r\n :host([selected]) .list-item {\r\n background: var(--sky-hover-secondary);\r\n border-inline-start-color: var(--sky-active-primary);\r\n }\r\n\r\n :host(:last-child) .list-item {\r\n border-bottom: none;\r\n }\r\n\r\n .leading {\r\n display: flex;\r\n align-items: center;\r\n margin-inline-end: var(--sky-space-3, 12px);\r\n flex-shrink: 0;\r\n }\r\n\r\n .avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: var(--sky-radius-full);\r\n object-fit: cover;\r\n background: var(--sky-hover-tertiary);\r\n }\r\n\r\n :host([dense]) .list-item {\r\n padding: var(--sky-space-1\\\\.5, 6px) var(--sky-space-2\\\\.5, 10px);\r\n }\r\n\r\n :host([dense]) .avatar {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n\r\n .content {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n text-align: start;\r\n font-family: var(--sky-font);\r\n }\r\n\r\n .actions {\r\n display: flex;\r\n align-items: center;\r\n margin-inline-start: var(--sky-space-3, 12px);\r\n gap: var(--sky-space-2, 8px);\r\n flex-shrink: 0;\r\n }\r\n\r\n .subheader {\r\n font-family: var(--sky-font);\r\n font-size: var(--sky-font-size-sm);\r\n text-align: start;\r\n color: var(--sky-text-secondary);\r\n padding: var(--sky-space-1\\\\.5, 6px) var(--sky-space-3\\\\.5, 14px);\r\n font-weight: var(--sky-font-weight-semibold);\r\n background: var(--sky-hover-tertiary);\r\n border-bottom: var(--sky-border-primary);\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .list-item {\r\n transition: none;\r\n }\r\n }\r\n `;\r\n\r\n private onClick(): void {\r\n if (this.disabled || this.subheader) return;\r\n this.dispatchEvent(\r\n new CustomEvent<SkyListitemActivateDetail>(\"item-activate\", {\r\n detail: { item: this },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n\r\n setSelected(selected: boolean): void {\r\n this.selected = selected;\r\n this.requestUpdate();\r\n }\r\n\r\n override render() {\r\n if (this.subheader) {\r\n return html`\r\n <div class=\"subheader\" part=\"subheader\" role=\"presentation\">${this.subheader}</div>\r\n `;\r\n }\r\n\r\n return html`\r\n <div\r\n class=\"list-item\"\r\n part=\"list-item\"\r\n role=\"option\"\r\n aria-selected=${this.selected ? \"true\" : \"false\"}\r\n aria-disabled=${this.disabled ? \"true\" : \"false\"}\r\n tabindex=\"-1\"\r\n @click=${this.onClick}\r\n >\r\n ${when(\r\n this.avatar,\r\n () => html`\r\n <div class=\"leading\" part=\"leading\">\r\n <img\r\n class=\"avatar\"\r\n src=${this.avatar}\r\n alt=\"\"\r\n part=\"avatar\"\r\n />\r\n </div>\r\n `,\r\n )}\r\n\r\n <div class=\"content\" part=\"content\"><slot name=\"content\"></slot></div>\r\n\r\n <div class=\"actions\" part=\"actions\">\r\n <slot name=\"actions\">${nothing}</slot>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}"],"names":["SkyListitem","LitElement","constructor","super","arguments","this","avatar","value","subheader","selected","dense","disabled","preset","_presets","PresetController","onClick","dispatchEvent","CustomEvent","detail","item","bubbles","composed","setSelected","requestUpdate","render","html","when","nothing","styles","css","__decorateClass","property","type","String","prototype","reflect","Boolean","customElement"],"mappings":"6bAoEO,IAAMA,EAAN,cAA0BC,EAA1B,WAAAC,GAAAC,SAAAC,WACuBC,KAAAC,OAAS,GAETD,KAAAE,MAAQ,GACOF,KAAAG,UAAY,GACXH,KAAAI,UAAW,EACXJ,KAAAK,OAAQ,EACRL,KAAAM,UAAW,EAIZN,KAAAO,OAAS,GAEpDP,KAAQQ,SAAW,IAAIC,EAAiBT,KAAI,CA6GpC,OAAAU,GACFV,KAAKM,UAAYN,KAAKG,WAC1BH,KAAKW,cACH,IAAIC,YAAuC,gBAAiB,CAC1DC,OAAQ,CAAEC,KAAMd,MAChBe,SAAS,EACTC,UAAU,IAGhB,CAEA,WAAAC,CAAYb,GACVJ,KAAKI,SAAWA,EAChBJ,KAAKkB,eACP,CAES,MAAAC,GACP,OAAInB,KAAKG,UACAiB,CAAA;sEACyDpB,KAAKG;QAIhEiB,CAAA;;;;;wBAKapB,KAAKI,SAAW,OAAS;wBACzBJ,KAAKM,SAAW,OAAS;;iBAEhCN,KAAKU;;UAEZW,EACArB,KAAKC,OACL,IAAMmB,CAAA;;;;sBAIMpB,KAAKC;;;;;;;;;;iCAWMqB;;;KAI/B,GAhLW3B,EAeK4B,OAASC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAdGC,EAAA,CAA3BC,EAAS,CAAEC,KAAMC,UADPjC,EACiBkC,UAAA,SAAA,GAEAJ,EAAA,CAA3BC,EAAS,CAAEC,KAAMC,UAHPjC,EAGiBkC,UAAA,QAAA,GACeJ,EAAA,CAA1CC,EAAS,CAAEC,KAAMC,OAAQE,SAAS,KAJxBnC,EAIgCkC,UAAA,YAAA,GACCJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KALzBnC,EAKiCkC,UAAA,WAAA,GACAJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KANzBnC,EAMiCkC,UAAA,QAAA,GACAJ,EAAA,CAA3CC,EAAS,CAAEC,KAAMI,QAASD,SAAS,KAPzBnC,EAOiCkC,UAAA,WAAA,GAIDJ,EAAA,CAA1CC,EAAS,CAAEC,KAAMC,OAAQE,SAAS,KAXxBnC,EAWgCkC,UAAA,SAAA,GAXhClC,EAAN8B,EAAA,CADNO,EAAc,iBACFrC"}
@@ -16,7 +16,7 @@ export type SkyRadioValueClearedDetail = {
16
16
  * @status stable
17
17
  * @since 1.0.0
18
18
  *
19
- * @documentation https://library.sky-ui.com/components/radio
19
+ * @documentation https://sky-ui.com/components/radio
20
20
  *
21
21
  * @slot - Content to display instead of the label property.
22
22
  *
@@ -34,6 +34,7 @@ export type SkyRadioValueClearedDetail = {
34
34
  * @property {boolean} required - Enables required validation for standalone usage.
35
35
  * @property {string} requiredMessage - Error message for required validation failures.
36
36
  * @property {boolean} compact - Compact control size.
37
+ * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `""`.
37
38
  *
38
39
  * @fires {CustomEvent<SkyRadioSelectDetail>} radio-select - Fired when the option becomes selected.
39
40
  * @fires {Event} change - Native change event for form compatibility.
@@ -82,10 +83,14 @@ export declare class SkyRadio extends FormControlBase {
82
83
  compact: boolean;
83
84
  private _hasMeaningfulSlot;
84
85
  private syncStyleVars;
85
- protected willUpdate(changed: Map<string, unknown>): void;
86
+ /** After PresetController hostUpdate — paint with current color. */
87
+ protected update(changed: Map<string, unknown>): void;
86
88
  check(): void;
87
89
  focusRadio(): void;
88
- static styles: import("lit").CSSResult;
90
+ /** Named prop preset from nearest `sky-config-provider`. */
91
+ preset: string;
92
+ private _presets;
93
+ static styles: import("lit").CSSResult[];
89
94
  constructor();
90
95
  static shadowRootOptions: {
91
96
  clonable?: boolean;
@@ -1,4 +1,4 @@
1
- import{unsafeCSS as e,css as t,LitElement as o,html as r}from"lit";import{property as s,state as i,customElement as a}from"lit/decorators.js";import{when as l}from"lit/directives/when.js";import{classMap as n}from"lit/directives/class-map.js";import{resolveColor as d}from"../helper/utils/color-resolver.js";import{cssOnFillEnhance as c}from"../helper/utils/contrast-color.js";import{FormControlBase as h}from"../helper/internals/form-control-base.js";var p=Object.defineProperty,y=Object.getOwnPropertyDescriptor,u=(e,t,o,r)=>{for(var s,i=r>1?void 0:r?y(t,o):t,a=e.length-1;a>=0;a--)(s=e[a])&&(i=(r?s(t,o,i):s(i))||i);return r&&i&&p(t,o,i),i};let k=class extends h{constructor(){super(),this.label="",this.value="",this.checked=!1,this.color="primary",this.compact=!1,this._hasMeaningfulSlot=!1,this._onSlotChange=e=>{const t=e.target,o=this._slotHasMeaningfulContent(t);o!==this._hasMeaningfulSlot&&(this._hasMeaningfulSlot=o)},this.onNativeChange=e=>{const t=e.currentTarget;if(this.disabled||this.readonly)return void(t.checked!==this.checked&&(t.checked=this.checked));const o=t.checked&&!this.checked;if(this.checked=t.checked,this.checked&&this.name&&!this.closest("sky-radio-group")){const e=Array.from(document.querySelectorAll("sky-radio"));for(const t of e)t!==this&&t.name===this.name&&(t.checked=!1)}o&&(this.dispatchEvent(new CustomEvent("radio-select",{detail:{value:this.value},bubbles:!0,composed:!0})),this.reemitNativeEvent("change",e),this.reemitNativeEvent("input",e),this.syncFormValue(),this.syncValidity())},this.handleKeydown=e=>{if(!(this.disabled||this.readonly||" "!==e.key&&"Enter"!==e.key)){e.preventDefault();const t=this.shadowRoot?.querySelector("input[type='radio']");t?.click()}},this.captureDefaultValue("")}syncStyleVars(){this.style.setProperty("--radio-checked-color",d(this.color))}willUpdate(e){super.willUpdate(e),(0===e.size||e.has("color"))&&this.syncStyleVars()}check(){this.disabled||this.readonly||(this.checked=!0,this.syncFormValue())}focusRadio(){const e=this.shadowRoot?.querySelector('input[type="radio"]');e?.focus()}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this.handleKeydown),this.hasAttribute("tabindex")||(this.tabIndex=this.disabled?-1:0)}disconnectedCallback(){this.removeEventListener("keydown",this.handleKeydown),super.disconnectedCallback()}updated(e){const t=this.shadowRoot?.querySelector("input[type='radio']");e.has("checked")&&(t&&t.checked!==this.checked&&(t.checked=this.checked),void 0!==e.get("checked")&&(this.syncFormValue(),this.syncValidity())),(e.has("disabled")||e.has("readonly"))&&(t&&(t.disabled=this.disabled,t.readOnly=this.readonly),this.tabIndex=this.disabled?-1:0),e.has("value")&&(this.syncFormValue(),this.syncValidity())}_slotHasMeaningfulContent(e){return e.assignedNodes({flatten:!0}).some(e=>e.nodeType===Node.ELEMENT_NODE||(e.textContent??"").trim().length>0)}getFormValue(){return this.checked?this.value:null}setValueFromFormState(e){this.checked="string"==typeof e&&e===this.value}getValidityAnchor(){return this.getNativeControl()||void 0}isEmpty(){return!this.checked}getNativeControl(){return this.shadowRoot?.querySelector("input[type='radio']")||null}onNativeValueMutated(e){const t=this.getNativeControl();t&&(this.checked=t.checked)}getCustomErrorMessage(){return this.validationErrors?.[0]||""}get validationErrors(){return this.required&&!this.checked?[this.requiredMessage]:[]}render(){return r`
1
+ import{unsafeCSS as e,css as t,LitElement as r,html as o}from"lit";import{property as s,state as i,customElement as a}from"lit/decorators.js";import{when as l}from"lit/directives/when.js";import{classMap as n}from"lit/directives/class-map.js";import{resolveColor as d}from"../helper/utils/color-resolver.js";import{cssOnFillEnhance as c}from"../helper/utils/contrast-color.js";import{FormControlBase as h}from"../helper/internals/form-control-base.js";import{PresetController as p}from"../helper/controllers/preset-controller.js";import{skyFocusRingHostStyles as y}from"../helper/styles/focus-ring.js";var u=Object.defineProperty,k=Object.getOwnPropertyDescriptor,b=(e,t,r,o)=>{for(var s,i=o>1?void 0:o?k(t,r):t,a=e.length-1;a>=0;a--)(s=e[a])&&(i=(o?s(t,r,i):s(i))||i);return o&&i&&u(t,r,i),i};let m=class extends h{constructor(){super(),this.label="",this.value="",this.checked=!1,this.color="primary",this.compact=!1,this._hasMeaningfulSlot=!1,this.preset="",this._presets=new p(this),this._onSlotChange=e=>{const t=e.target,r=this._slotHasMeaningfulContent(t);r!==this._hasMeaningfulSlot&&(this._hasMeaningfulSlot=r)},this.onNativeChange=e=>{const t=e.currentTarget;if(this.disabled||this.readonly)return void(t.checked!==this.checked&&(t.checked=this.checked));const r=t.checked&&!this.checked;if(this.checked=t.checked,this.checked&&this.name&&!this.closest("sky-radio-group")){const e=Array.from(document.querySelectorAll("sky-radio"));for(const t of e)t!==this&&t.name===this.name&&(t.checked=!1)}r&&(this.dispatchEvent(new CustomEvent("radio-select",{detail:{value:this.value},bubbles:!0,composed:!0})),this.reemitNativeEvent("change",e),this.reemitNativeEvent("input",e),this.syncFormValue(),this.syncValidity())},this.handleKeydown=e=>{if(!(this.disabled||this.readonly||" "!==e.key&&"Enter"!==e.key)){e.preventDefault();const t=this.shadowRoot?.querySelector("input[type='radio']");t?.click()}},this.captureDefaultValue("")}syncStyleVars(){this.style.setProperty("--radio-checked-color",d(this.color))}update(e){(0===e.size||e.has("color")||e.has("preset"))&&this.syncStyleVars(),super.update(e)}check(){this.disabled||this.readonly||(this.checked=!0,this.syncFormValue())}focusRadio(){const e=this.shadowRoot?.querySelector('input[type="radio"]');e?.focus()}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this.handleKeydown),this.hasAttribute("tabindex")||(this.tabIndex=this.disabled?-1:0)}disconnectedCallback(){this.removeEventListener("keydown",this.handleKeydown),super.disconnectedCallback()}updated(e){const t=this.shadowRoot?.querySelector("input[type='radio']");e.has("checked")&&(t&&t.checked!==this.checked&&(t.checked=this.checked),void 0!==e.get("checked")&&(this.syncFormValue(),this.syncValidity())),(e.has("disabled")||e.has("readonly"))&&(t&&(t.disabled=this.disabled,t.readOnly=this.readonly),this.tabIndex=this.disabled?-1:0),e.has("value")&&(this.syncFormValue(),this.syncValidity())}_slotHasMeaningfulContent(e){return e.assignedNodes({flatten:!0}).some(e=>e.nodeType===Node.ELEMENT_NODE||(e.textContent??"").trim().length>0)}getFormValue(){return this.checked?this.value:null}setValueFromFormState(e){this.checked="string"==typeof e&&e===this.value}getValidityAnchor(){return this.getNativeControl()||void 0}isEmpty(){return!this.checked}getNativeControl(){return this.shadowRoot?.querySelector("input[type='radio']")||null}onNativeValueMutated(e){const t=this.getNativeControl();t&&(this.checked=t.checked)}getCustomErrorMessage(){return this.validationErrors?.[0]||""}get validationErrors(){return this.required&&!this.checked?[this.requiredMessage]:[]}render(){return o`
2
2
  <label
3
3
  part="label"
4
4
  ?disabled=${this.disabled}
@@ -23,12 +23,13 @@ import{unsafeCSS as e,css as t,LitElement as o,html as r}from"lit";import{proper
23
23
  <slot @slotchange=${this._onSlotChange}></slot>
24
24
  ${l(!this._hasMeaningfulSlot,()=>this.label)}
25
25
  </label>
26
- `}};k.styles=t`
26
+ `}};m.styles=[y,t`
27
27
  :host {
28
28
  display: inline-flex;
29
29
  align-items: center;
30
30
  --sky-radio-size: 18px;
31
31
  --sky-radio-dot: 10px;
32
+ --sky-focus-ring-color: var(--radio-checked-color, var(--sky-active-primary));
32
33
  }
33
34
 
34
35
  :host([compact]) {
@@ -140,5 +141,5 @@ import{unsafeCSS as e,css as t,LitElement as o,html as r}from"lit";import{proper
140
141
  }
141
142
 
142
143
  ${e(c([{selector:".radio-wrapper.checked::before",fillVar:"--radio-checked-color",property:"background-color"}]))}
143
- `,k.shadowRootOptions={...o.shadowRootOptions,delegatesFocus:!0},u([s({type:String})],k.prototype,"label",2),u([s({type:String})],k.prototype,"value",2),u([s({type:Boolean,reflect:!0})],k.prototype,"checked",2),u([s({type:String})],k.prototype,"color",2),u([s({type:Boolean,reflect:!0})],k.prototype,"compact",2),u([i()],k.prototype,"_hasMeaningfulSlot",2),k=u([a("sky-radio")],k);export{k as SkyRadio};
144
+ `],m.shadowRootOptions={...r.shadowRootOptions,delegatesFocus:!0},b([s({type:String})],m.prototype,"label",2),b([s({type:String})],m.prototype,"value",2),b([s({type:Boolean,reflect:!0})],m.prototype,"checked",2),b([s({type:String})],m.prototype,"color",2),b([s({type:Boolean,reflect:!0})],m.prototype,"compact",2),b([i()],m.prototype,"_hasMeaningfulSlot",2),b([s({type:String,reflect:!0})],m.prototype,"preset",2),m=b([a("sky-radio")],m);export{m as SkyRadio};
144
145
  //# sourceMappingURL=sky-radio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sky-radio.js","sources":["../../src/sky-radio/sky-radio.ts"],"sourcesContent":["import { LitElement, html, css, nothing, unsafeCSS } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { when } from \"lit/directives/when.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { resolveColor } from \"../helper/utils/color-resolver\";\nimport { cssOnFillEnhance } from \"../helper/utils/contrast-color\";\nimport { FormControlBase, FormState } from \"../helper/internals/form-control-base\";\n\nexport type SkyRadioSelectDetail = { value: string };\nexport type SkyRadioValidationErrorDetail = { errors: string[] };\nexport type SkyRadioValueClearedDetail = { value: \"\" };\n\n/**\n * @element sky-radio\n *\n * @summary Single radio option for grouped or standalone selection.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://library.sky-ui.com/components/radio\n *\n * @slot - Content to display instead of the label property.\n *\n * @csspart wrapper - The circular radio control element.\n * @csspart input - The native hidden radio input element.\n * @csspart label - The text label element.\n *\n * @property {string} label - Text label displayed beside the control.\n * @property {string} value - Option value used for selection and form value.\n * @property {boolean} checked - Whether this option is selected.\n * @property {string} name - Radio name used for same-name exclusivity.\n * @property {string} color - Accent color used in checked state.\n * @property {boolean} disabled - Disables user interaction.\n * @property {boolean} readonly - Prevents selection changes while still allowing focus.\n * @property {boolean} required - Enables required validation for standalone usage.\n * @property {string} requiredMessage - Error message for required validation failures.\n * @property {boolean} compact - Compact control size.\n *\n * @fires {CustomEvent<SkyRadioSelectDetail>} radio-select - Fired when the option becomes selected.\n * @fires {Event} change - Native change event for form compatibility.\n * @fires {Event} input - Native input event for form compatibility.\n * @fires {CustomEvent<SkyRadioValidationErrorDetail>} validation-error - Fired when validation errors occur.\n * @fires {CustomEvent<SkyRadioValueClearedDetail>} value-cleared - Fired when selection is reset.\n * @method check Selects this radio option.\n * @method focusRadio Focuses the underlying native radio control.\n *\n * @Behavior\n * - Uses a native hidden radio input for semantics and keyboard interaction.\n * - Supports grouped usage inside `sky-radio-group` and standalone usage.\n * - Synchronizes checked state and form value through `FormControlBase`.\n *\n * @example\n * ```html\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\n * <sky-radio value=\"green\">Green Environment</sky-radio>\n * </sky-radio-group>\n * ```\n * ```vue\n * <template>\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\n * <sky-radio value=\"green\">Green Environment</sky-radio>\n * </sky-radio-group>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return (\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\n * <sky-radio value=\"green\">Green Environment</sky-radio>\n * </sky-radio-group>\n * );\n * }\n * ```\n */\n@customElement(\"sky-radio\")\nexport class SkyRadio extends FormControlBase {\n @property({ type: String }) label: string = \"\";\n @property({ type: String }) value: string = \"\";\n @property({ type: Boolean, reflect: true }) checked: boolean = false;\n @property({ type: String }) color: string = \"primary\";\n @property({ type: Boolean, reflect: true }) compact = false;\n @state() private _hasMeaningfulSlot = false;\n\n private syncStyleVars(): void {\n this.style.setProperty(\"--radio-checked-color\", resolveColor(this.color));\n }\n\n protected override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n if (changed.size === 0 || changed.has(\"color\")) {\n this.syncStyleVars();\n }\n }\n\n public check(): void {\n if (this.disabled || this.readonly) return;\n this.checked = true;\n this.syncFormValue();\n }\n\n public focusRadio(): void {\n const input = this.shadowRoot?.querySelector('input[type=\"radio\"]') as HTMLInputElement | null;\n input?.focus();\n }\n\n static override styles = css`\n :host {\n display: inline-flex;\n align-items: center;\n --sky-radio-size: 18px;\n --sky-radio-dot: 10px;\n }\n\n :host([compact]) {\n --sky-radio-size: 14px;\n --sky-radio-dot: 8px;\n }\n\n :host([compact]) label {\n font-size: var(--sky-font-size-xs);\n gap: var(--sky-space-1, 4px);\n }\n\n /* readonly: allow focus + keyboard traversal, but show subtle visual state */\n :host([readonly]) label {\n cursor: default;\n }\n\n label {\n display: flex;\n align-items: center;\n gap: var(--sky-space-1\\\\.5, 6px);\n color: var(--sky-text-primary);\n cursor: pointer;\n font-size: var(--sky-font-size-sm);\n font-family: var(--sky-font);\n }\n\n label[disabled] {\n pointer-events: none;\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n :host([disabled]) label,\n :host([disabled]) .radio-wrapper {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n .radio-wrapper {\n position: relative;\n box-sizing: border-box;\n width: var(--sky-radio-size);\n height: var(--sky-radio-size);\n display: inline-block;\n background: var(--sky-glass-solid);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n border: 2px solid var(--sky-text-tertiary);\n border-radius: 50%;\n transition:\n border-color var(--sky-transition-normal, 200ms ease),\n background-color var(--sky-transition-normal, 200ms ease),\n box-shadow var(--sky-transition-normal, 200ms ease);\n cursor: pointer;\n flex-shrink: 0;\n }\n\n .radio-wrapper::before {\n content: \"\";\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0);\n width: var(--sky-radio-dot);\n height: var(--sky-radio-dot);\n background-color: var(--sky-glass-solid);\n border-radius: 50%;\n transition:\n transform var(--sky-transition-normal, 200ms ease),\n background-color var(--sky-transition-normal, 200ms ease);\n }\n\n .radio-wrapper.checked {\n border-color: var(--radio-checked-color);\n background-color: var(--radio-checked-color);\n }\n\n .radio-wrapper.checked::before {\n transform: translate(-50%, -50%) scale(1);\n background-color: var(--sky-on-color-fallback-light, var(--sky-text-white));\n }\n\n input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n width: 0;\n height: 0;\n }\n\n :host(:focus-within) .radio-wrapper {\n box-shadow: var(--sky-focus-ring);\n border-color: var(--radio-checked-color);\n }\n\n sky-icon {\n display: inline-block;\n width: 1em;\n height: 1em;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .radio-wrapper,\n .radio-wrapper::before {\n transition: none;\n }\n }\n\n ${unsafeCSS(\n cssOnFillEnhance([\n {\n selector: \".radio-wrapper.checked::before\",\n fillVar: \"--radio-checked-color\",\n property: \"background-color\",\n },\n ]),\n )}\n `;\n\n constructor() {\n super();\n this.captureDefaultValue(\"\");\n }\n static override shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(\"keydown\", this.handleKeydown);\n // Make the host focusable\n if (!this.hasAttribute(\"tabindex\")) {\n this.tabIndex = this.disabled ? -1 : 0;\n }\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener(\"keydown\", this.handleKeydown);\n super.disconnectedCallback();\n }\n\n override updated(changed: Map<string, unknown>): void {\n const input = this.shadowRoot?.querySelector<HTMLInputElement>(\n \"input[type='radio']\",\n );\n\n if (changed.has(\"checked\")) {\n if (input && input.checked !== this.checked) input.checked = this.checked;\n\n if (changed.get(\"checked\") !== undefined) {\n this.syncFormValue();\n this.syncValidity();\n }\n }\n if (changed.has(\"disabled\") || changed.has(\"readonly\")) {\n if (input) {\n input.disabled = this.disabled;\n input.readOnly = this.readonly;\n }\n this.tabIndex = this.disabled ? -1 : 0;\n }\n\n if (changed.has(\"value\")) {\n this.syncFormValue();\n this.syncValidity();\n }\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 private _onSlotChange = (e: Event) => {\n const slot = e.target as HTMLSlotElement;\n const next = this._slotHasMeaningfulContent(slot);\n if (next !== this._hasMeaningfulSlot) this._hasMeaningfulSlot = next;\n };\n\n private onNativeChange = (e: Event) => {\n const input = e.currentTarget as HTMLInputElement;\n\n // ✅ Prevent state change when disabled or readonly, and re-sync native state\n if (this.disabled || this.readonly) {\n if (input.checked !== this.checked) {\n input.checked = this.checked;\n }\n return;\n }\n\n const becameChecked = input.checked && !this.checked;\n this.checked = input.checked;\n\n // When used individually, uncheck siblings with the same name\n if (this.checked && this.name && !this.closest(\"sky-radio-group\")) {\n const all = Array.from(document.querySelectorAll<SkyRadio>(\"sky-radio\"));\n for (const r of all) {\n if (r !== this && r.name === this.name) r.checked = false;\n }\n }\n\n if (becameChecked) {\n // Dispatch custom event\n this.dispatchEvent(\n new CustomEvent<SkyRadioSelectDetail>(\"radio-select\", {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n })\n );\n\n // Dispatch native events for form compatibility\n this.reemitNativeEvent(\"change\", e);\n this.reemitNativeEvent(\"input\", e);\n\n // Sync form value\n this.syncFormValue();\n this.syncValidity();\n }\n };\n\n private handleKeydown = (event: KeyboardEvent) => {\n // ✅ no keyboard activation in disabled/readonly mode\n if (this.disabled || this.readonly) return;\n\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n const input = this.shadowRoot?.querySelector<HTMLInputElement>(\n \"input[type='radio']\"\n );\n input?.click();\n }\n };\n\n // ============================================================\n // FormControlBase implementation\n // ============================================================\n\n /** Get the current value for form submission */\n protected override getFormValue(): FormState {\n return this.checked ? this.value : null;\n }\n\n /** Set value from form state (e.g., form reset) */\n protected override setValueFromFormState(state: FormState): void {\n if (typeof state === \"string\") {\n this.checked = state === this.value;\n } else {\n this.checked = false;\n }\n }\n\n /** Get the validity anchor (the hidden input) */\n protected override getValidityAnchor(): HTMLElement | undefined {\n return this.getNativeControl() || undefined;\n }\n\n /** Check if empty (for required validation) */\n protected override isEmpty(): boolean {\n return !this.checked;\n }\n\n /** Get the native control (hidden radio input) */\n protected override getNativeControl(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>(\"input[type='radio']\") || null;\n }\n\n /** Handle native value mutation */\n protected override onNativeValueMutated(_native: any): void {\n // Sync the checked state from native input\n const input = this.getNativeControl() as HTMLInputElement;\n if (input) {\n this.checked = input.checked;\n }\n }\n\n /** Override to provide custom error messages */\n protected override getCustomErrorMessage(): string {\n return this.validationErrors?.[0] || \"\";\n }\n\n /** Get current validation errors */\n get validationErrors(): string[] {\n return this.required && !this.checked ? [this.requiredMessage] : [];\n }\n\n override render() {\n return html`\n <label\n part=\"label\"\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n aria-disabled=${this.disabled ? \"true\" : \"false\"}\n aria-readonly=${this.readonly ? \"true\" : \"false\"}\n >\n <input\n type=\"radio\"\n part=\"input\"\n .name=${this.name}\n .value=${this.value}\n .checked=${this.checked}\n @change=${this.onNativeChange}\n ?disabled=${this.disabled}\n ?required=${this.required}\n />\n <div\n class=${classMap({ \"radio-wrapper\": true, checked: this.checked })}\n part=\"wrapper\"\n ></div>\n <slot @slotchange=${this._onSlotChange}></slot>\n ${when(!this._hasMeaningfulSlot, () => this.label)}\n </label>\n `;\n }\n}\n"],"names":["SkyRadio","FormControlBase","constructor","super","this","label","value","checked","color","compact","_hasMeaningfulSlot","_onSlotChange","e","slot","target","next","_slotHasMeaningfulContent","onNativeChange","input","currentTarget","disabled","readonly","becameChecked","name","closest","all","Array","from","document","querySelectorAll","r","dispatchEvent","CustomEvent","detail","bubbles","composed","reemitNativeEvent","syncFormValue","syncValidity","handleKeydown","event","key","preventDefault","shadowRoot","querySelector","click","captureDefaultValue","syncStyleVars","style","setProperty","resolveColor","willUpdate","changed","size","has","check","focusRadio","focus","connectedCallback","addEventListener","hasAttribute","tabIndex","disconnectedCallback","removeEventListener","updated","get","readOnly","slotEl","assignedNodes","flatten","some","n","nodeType","Node","ELEMENT_NODE","textContent","trim","length","getFormValue","setValueFromFormState","state","getValidityAnchor","getNativeControl","isEmpty","onNativeValueMutated","_native","getCustomErrorMessage","validationErrors","required","requiredMessage","render","html","classMap","when","styles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","property","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","type","String","prototype","Boolean","reflect","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"sky-radio.js","sources":["../../src/sky-radio/sky-radio.ts"],"sourcesContent":["import { LitElement, html, css, nothing, unsafeCSS } from \"lit\";\r\nimport { customElement, property, state } from \"lit/decorators.js\";\r\nimport { when } from \"lit/directives/when.js\";\r\nimport { classMap } from \"lit/directives/class-map.js\";\r\nimport { resolveColor } from \"../helper/utils/color-resolver\";\r\nimport { cssOnFillEnhance } from \"../helper/utils/contrast-color\";\r\nimport { FormControlBase, FormState } from \"../helper/internals/form-control-base\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\nimport { skyFocusRingHostStyles } from \"../helper/styles/focus-ring\";\r\n\r\nexport type SkyRadioSelectDetail = { value: string };\r\nexport type SkyRadioValidationErrorDetail = { errors: string[] };\r\nexport type SkyRadioValueClearedDetail = { value: \"\" };\r\n\r\n/**\r\n * @element sky-radio\r\n *\r\n * @summary Single radio option for grouped or standalone selection.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/radio\r\n *\r\n * @slot - Content to display instead of the label property.\r\n *\r\n * @csspart wrapper - The circular radio control element.\r\n * @csspart input - The native hidden radio input element.\r\n * @csspart label - The text label element.\r\n *\r\n * @property {string} label - Text label displayed beside the control.\r\n * @property {string} value - Option value used for selection and form value.\r\n * @property {boolean} checked - Whether this option is selected.\r\n * @property {string} name - Radio name used for same-name exclusivity.\r\n * @property {string} color - Accent color used in checked state.\r\n * @property {boolean} disabled - Disables user interaction.\r\n * @property {boolean} readonly - Prevents selection changes while still allowing focus.\r\n * @property {boolean} required - Enables required validation for standalone usage.\r\n * @property {string} requiredMessage - Error message for required validation failures.\r\n * @property {boolean} compact - Compact control size.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @fires {CustomEvent<SkyRadioSelectDetail>} radio-select - Fired when the option becomes selected.\r\n * @fires {Event} change - Native change event for form compatibility.\r\n * @fires {Event} input - Native input event for form compatibility.\r\n * @fires {CustomEvent<SkyRadioValidationErrorDetail>} validation-error - Fired when validation errors occur.\r\n * @fires {CustomEvent<SkyRadioValueClearedDetail>} value-cleared - Fired when selection is reset.\r\n * @method check Selects this radio option.\r\n * @method focusRadio Focuses the underlying native radio control.\r\n *\r\n * @Behavior\r\n * - Uses a native hidden radio input for semantics and keyboard interaction.\r\n * - Supports grouped usage inside `sky-radio-group` and standalone usage.\r\n * - Synchronizes checked state and form value through `FormControlBase`.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\r\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\r\n * <sky-radio value=\"green\">Green Environment</sky-radio>\r\n * </sky-radio-group>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\r\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\r\n * <sky-radio value=\"green\">Green Environment</sky-radio>\r\n * </sky-radio-group>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-radio-group label=\"Deployment\" name=\"deployment\">\r\n * <sky-radio value=\"blue\" checked color=\"primary\">Blue Environment</sky-radio>\r\n * <sky-radio value=\"green\">Green Environment</sky-radio>\r\n * </sky-radio-group>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-radio\")\r\nexport class SkyRadio extends FormControlBase {\r\n @property({ type: String }) label: string = \"\";\r\n @property({ type: String }) value: string = \"\";\r\n @property({ type: Boolean, reflect: true }) checked: boolean = false;\r\n @property({ type: String }) color: string = \"primary\";\r\n @property({ type: Boolean, reflect: true }) compact = false;\r\n @state() private _hasMeaningfulSlot = false;\r\n\r\n private syncStyleVars(): void {\r\n this.style.setProperty(\"--radio-checked-color\", resolveColor(this.color));\r\n }\r\n\r\n /** After PresetController hostUpdate — paint with current color. */\r\n protected override update(changed: Map<string, unknown>): void {\r\n if (changed.size === 0 || changed.has(\"color\") || changed.has(\"preset\")) {\r\n this.syncStyleVars();\r\n }\r\n super.update(changed);\r\n }\r\n\r\n public check(): void {\r\n if (this.disabled || this.readonly) return;\r\n this.checked = true;\r\n this.syncFormValue();\r\n }\r\n\r\n public focusRadio(): void {\r\n const input = this.shadowRoot?.querySelector('input[type=\"radio\"]') as HTMLInputElement | null;\r\n input?.focus();\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 = [\r\n skyFocusRingHostStyles,\r\n css`\r\n :host {\r\n display: inline-flex;\r\n align-items: center;\r\n --sky-radio-size: 18px;\r\n --sky-radio-dot: 10px;\r\n --sky-focus-ring-color: var(--radio-checked-color, var(--sky-active-primary));\r\n }\r\n\r\n :host([compact]) {\r\n --sky-radio-size: 14px;\r\n --sky-radio-dot: 8px;\r\n }\r\n\r\n :host([compact]) label {\r\n font-size: var(--sky-font-size-xs);\r\n gap: var(--sky-space-1, 4px);\r\n }\r\n\r\n /* readonly: allow focus + keyboard traversal, but show subtle visual state */\r\n :host([readonly]) label {\r\n cursor: default;\r\n }\r\n\r\n label {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--sky-space-1\\\\.5, 6px);\r\n color: var(--sky-text-primary);\r\n cursor: pointer;\r\n font-size: var(--sky-font-size-sm);\r\n font-family: var(--sky-font);\r\n }\r\n\r\n label[disabled] {\r\n pointer-events: none;\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n\r\n :host([disabled]) label,\r\n :host([disabled]) .radio-wrapper {\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n }\r\n\r\n .radio-wrapper {\r\n position: relative;\r\n box-sizing: border-box;\r\n width: var(--sky-radio-size);\r\n height: var(--sky-radio-size);\r\n display: inline-block;\r\n background: var(--sky-glass-solid);\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n border: 2px solid var(--sky-text-tertiary);\r\n border-radius: 50%;\r\n transition:\r\n border-color var(--sky-transition-normal, 200ms ease),\r\n background-color var(--sky-transition-normal, 200ms ease),\r\n box-shadow var(--sky-transition-normal, 200ms ease);\r\n cursor: pointer;\r\n flex-shrink: 0;\r\n }\r\n\r\n .radio-wrapper::before {\r\n content: \"\";\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%) scale(0);\r\n width: var(--sky-radio-dot);\r\n height: var(--sky-radio-dot);\r\n background-color: var(--sky-glass-solid);\r\n border-radius: 50%;\r\n transition:\r\n transform var(--sky-transition-normal, 200ms ease),\r\n background-color var(--sky-transition-normal, 200ms ease);\r\n }\r\n\r\n .radio-wrapper.checked {\r\n border-color: var(--radio-checked-color);\r\n background-color: var(--radio-checked-color);\r\n }\r\n\r\n .radio-wrapper.checked::before {\r\n transform: translate(-50%, -50%) scale(1);\r\n background-color: var(--sky-on-color-fallback-light, var(--sky-text-white));\r\n }\r\n\r\n input[type=\"radio\"] {\r\n position: absolute;\r\n opacity: 0;\r\n pointer-events: none;\r\n width: 0;\r\n height: 0;\r\n }\r\n\r\n :host(:focus-within) .radio-wrapper {\r\n box-shadow: var(--sky-focus-ring);\r\n border-color: var(--radio-checked-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 @media (prefers-reduced-motion: reduce) {\r\n .radio-wrapper,\r\n .radio-wrapper::before {\r\n transition: none;\r\n }\r\n }\r\n\r\n ${unsafeCSS(\r\n cssOnFillEnhance([\r\n {\r\n selector: \".radio-wrapper.checked::before\",\r\n fillVar: \"--radio-checked-color\",\r\n property: \"background-color\",\r\n },\r\n ]),\r\n )}\r\n `,\r\n ];\r\n\r\n constructor() {\r\n super();\r\n this.captureDefaultValue(\"\");\r\n }\r\n static override shadowRootOptions = {\r\n ...LitElement.shadowRootOptions,\r\n delegatesFocus: true,\r\n };\r\n\r\n\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this.addEventListener(\"keydown\", this.handleKeydown);\r\n if (!this.hasAttribute(\"tabindex\")) {\r\n this.tabIndex = this.disabled ? -1 : 0;\r\n }\r\n }\r\n\r\n override disconnectedCallback(): void {\r\n this.removeEventListener(\"keydown\", this.handleKeydown);\r\n super.disconnectedCallback();\r\n }\r\n\r\n override updated(changed: Map<string, unknown>): void {\r\n const input = this.shadowRoot?.querySelector<HTMLInputElement>(\r\n \"input[type='radio']\",\r\n );\r\n\r\n if (changed.has(\"checked\")) {\r\n if (input && input.checked !== this.checked) input.checked = this.checked;\r\n\r\n if (changed.get(\"checked\") !== undefined) {\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n }\r\n if (changed.has(\"disabled\") || changed.has(\"readonly\")) {\r\n if (input) {\r\n input.disabled = this.disabled;\r\n input.readOnly = this.readonly;\r\n }\r\n this.tabIndex = this.disabled ? -1 : 0;\r\n }\r\n\r\n if (changed.has(\"value\")) {\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\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 private _onSlotChange = (e: Event) => {\r\n const slot = e.target as HTMLSlotElement;\r\n const next = this._slotHasMeaningfulContent(slot);\r\n if (next !== this._hasMeaningfulSlot) this._hasMeaningfulSlot = next;\r\n };\r\n\r\n private onNativeChange = (e: Event) => {\r\n const input = e.currentTarget as HTMLInputElement;\r\n\r\n // Ignore native toggles when disabled or readonly; re-sync checked state.\r\n if (this.disabled || this.readonly) {\r\n if (input.checked !== this.checked) {\r\n input.checked = this.checked;\r\n }\r\n return;\r\n }\r\n\r\n const becameChecked = input.checked && !this.checked;\r\n this.checked = input.checked;\r\n\r\n // When used individually, uncheck siblings with the same name\r\n if (this.checked && this.name && !this.closest(\"sky-radio-group\")) {\r\n const all = Array.from(document.querySelectorAll<SkyRadio>(\"sky-radio\"));\r\n for (const r of all) {\r\n if (r !== this && r.name === this.name) r.checked = false;\r\n }\r\n }\r\n\r\n if (becameChecked) {\r\n this.dispatchEvent(\r\n new CustomEvent<SkyRadioSelectDetail>(\"radio-select\", {\r\n detail: { value: this.value },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n\r\n this.reemitNativeEvent(\"change\", e);\r\n this.reemitNativeEvent(\"input\", e);\r\n this.syncFormValue();\r\n this.syncValidity();\r\n }\r\n };\r\n\r\n private handleKeydown = (event: KeyboardEvent) => {\r\n if (this.disabled || this.readonly) return;\r\n\r\n if (event.key === \" \" || event.key === \"Enter\") {\r\n event.preventDefault();\r\n const input = this.shadowRoot?.querySelector<HTMLInputElement>(\r\n \"input[type='radio']\"\r\n );\r\n input?.click();\r\n }\r\n };\r\n\r\n /** Get the current value for form submission */\r\n protected override getFormValue(): FormState {\r\n return this.checked ? this.value : null;\r\n }\r\n\r\n /** Set value from form state (e.g., form reset) */\r\n protected override setValueFromFormState(state: FormState): void {\r\n if (typeof state === \"string\") {\r\n this.checked = state === this.value;\r\n } else {\r\n this.checked = false;\r\n }\r\n }\r\n\r\n /** Get the validity anchor (the hidden input) */\r\n protected override getValidityAnchor(): HTMLElement | undefined {\r\n return this.getNativeControl() || undefined;\r\n }\r\n\r\n /** Check if empty (for required validation) */\r\n protected override isEmpty(): boolean {\r\n return !this.checked;\r\n }\r\n\r\n /** Get the native control (hidden radio input) */\r\n protected override getNativeControl(): HTMLElement | null {\r\n return this.shadowRoot?.querySelector<HTMLElement>(\"input[type='radio']\") || null;\r\n }\r\n\r\n /** Handle native value mutation */\r\n protected override onNativeValueMutated(_native: any): void {\r\n const input = this.getNativeControl() as HTMLInputElement;\r\n if (input) {\r\n this.checked = input.checked;\r\n }\r\n }\r\n\r\n /** Override to provide custom error messages */\r\n protected override getCustomErrorMessage(): string {\r\n return this.validationErrors?.[0] || \"\";\r\n }\r\n\r\n /** Get current validation errors */\r\n get validationErrors(): string[] {\r\n return this.required && !this.checked ? [this.requiredMessage] : [];\r\n }\r\n\r\n override render() {\r\n return html`\r\n <label\r\n part=\"label\"\r\n ?disabled=${this.disabled}\r\n ?readonly=${this.readonly}\r\n aria-disabled=${this.disabled ? \"true\" : \"false\"}\r\n aria-readonly=${this.readonly ? \"true\" : \"false\"}\r\n >\r\n <input\r\n type=\"radio\"\r\n part=\"input\"\r\n .name=${this.name}\r\n .value=${this.value}\r\n .checked=${this.checked}\r\n @change=${this.onNativeChange}\r\n ?disabled=${this.disabled}\r\n ?required=${this.required}\r\n />\r\n <div\r\n class=${classMap({ \"radio-wrapper\": true, checked: this.checked })}\r\n part=\"wrapper\"\r\n ></div>\r\n <slot @slotchange=${this._onSlotChange}></slot>\r\n ${when(!this._hasMeaningfulSlot, () => this.label)}\r\n </label>\r\n `;\r\n }\r\n}\r\n"],"names":["SkyRadio","FormControlBase","constructor","super","this","label","value","checked","color","compact","_hasMeaningfulSlot","preset","_presets","PresetController","_onSlotChange","e","slot","target","next","_slotHasMeaningfulContent","onNativeChange","input","currentTarget","disabled","readonly","becameChecked","name","closest","all","Array","from","document","querySelectorAll","r","dispatchEvent","CustomEvent","detail","bubbles","composed","reemitNativeEvent","syncFormValue","syncValidity","handleKeydown","event","key","preventDefault","shadowRoot","querySelector","click","captureDefaultValue","syncStyleVars","style","setProperty","resolveColor","update","changed","size","has","check","focusRadio","focus","connectedCallback","addEventListener","hasAttribute","tabIndex","disconnectedCallback","removeEventListener","updated","get","readOnly","slotEl","assignedNodes","flatten","some","n","nodeType","Node","ELEMENT_NODE","textContent","trim","length","getFormValue","setValueFromFormState","state","getValidityAnchor","getNativeControl","isEmpty","onNativeValueMutated","_native","getCustomErrorMessage","validationErrors","required","requiredMessage","render","html","classMap","when","styles","skyFocusRingHostStyles","css","unsafeCSS","cssOnFillEnhance","selector","fillVar","property","shadowRootOptions","LitElement","delegatesFocus","__decorateClass","type","String","prototype","Boolean","reflect","customElement"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { LitElement } from "lit";
7
7
  * @status stable
8
8
  * @since 1.0.0
9
9
  *
10
- * @documentation https://library.sky-ui.com/components/grid
10
+ * @documentation https://sky-ui.com/components/grid
11
11
  * @dependency sky-grid
12
12
  *
13
13
  * @slot - Default slot for child content.
@@ -52,6 +52,9 @@ import { LitElement } from "lit";
52
52
  * ```
53
53
  */
54
54
  export declare class SkyRow extends LitElement {
55
+ /** Named prop preset from nearest `sky-config-provider`. */
56
+ preset: string;
57
+ private _presets;
55
58
  static styles: import("lit").CSSResult;
56
59
  render(): import("lit-html").TemplateResult<1>;
57
60
  }
@@ -1,6 +1,6 @@
1
- import{customElement as r}from"lit/decorators.js";import{css as t,LitElement as e,html as o}from"lit";var s=Object.getOwnPropertyDescriptor;let l=class extends e{render(){return o`<slot></slot>`}};l.styles=t`
1
+ import{property as r,customElement as t}from"lit/decorators.js";import{css as e,LitElement as o,html as s}from"lit";import{PresetController as p}from"../helper/controllers/preset-controller.js";var l=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=(r,t,e,o)=>{for(var s,p=o>1?void 0:o?n(t,e):t,i=r.length-1;i>=0;i--)(s=r[i])&&(p=(o?s(t,e,p):s(p))||p);return o&&p&&l(t,e,p),p};let c=class extends o{constructor(){super(...arguments),this.preset="",this._presets=new p(this)}render(){return s`<slot></slot>`}};c.styles=e`
2
2
  :host {
3
3
  display: contents;
4
4
  }
5
- `,l=((r,t,e,o)=>{for(var l,n=o>1?void 0:o?s(t,e):t,i=r.length-1;i>=0;i--)(l=r[i])&&(n=l(n)||n);return n})([r("sky-row")],l);export{l as SkyRow};
5
+ `,i([r({type:String,reflect:!0})],c.prototype,"preset",2),c=i([t("sky-row")],c);export{c as SkyRow};
6
6
  //# sourceMappingURL=sky-row.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sky-row.js","sources":["../../src/sky-row/sky-row.ts"],"sourcesContent":["import { customElement } from \"lit/decorators.js\";\r\nimport { LitElement, html, css } from \"lit\";\r\n\r\n\r\n/**\r\n * @element sky-row\r\n *\r\n * @summary Lightweight semantic row wrapper for use inside `sky-grid`.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://library.sky-ui.com/components/grid\r\n * @dependency sky-grid\r\n *\r\n * @slot - Default slot for child content.\r\n *\r\n * @Behavior\r\n * - Renders as `display: contents` so it does not add layout wrappers.\r\n * - Preserves semantic grouping for rows while children participate directly in parent layout.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-row\")\r\nexport class SkyRow extends LitElement {\r\n static override styles = css`\r\n :host {\r\n display: contents;\r\n }\r\n `;\r\n\r\n override render() {\r\n return html`<slot></slot>`;\r\n }\r\n}"],"names":["SkyRow","LitElement","render","html","styles","css","__decorateClass","customElement"],"mappings":"4IAyDO,IAAMA,EAAN,cAAqBC,EAOjB,MAAAC,GACP,OAAOC,CAAA,eACT,GATWH,EACKI,OAASC,CAAA;;;;IADdL,uGAANM,CAAA,CADNC,EAAc,YACFP"}
1
+ {"version":3,"file":"sky-row.js","sources":["../../src/sky-row/sky-row.ts"],"sourcesContent":["import { customElement, property } from \"lit/decorators.js\";\r\nimport { LitElement, html, css } from \"lit\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\n\r\n/**\r\n * @element sky-row\r\n *\r\n * @summary Lightweight semantic row wrapper for use inside `sky-grid`.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/grid\r\n * @dependency sky-grid\r\n *\r\n * @slot - Default slot for child content.\r\n *\r\n * @Behavior\r\n * - Renders as `display: contents` so it does not add layout wrappers.\r\n * - Preserves semantic grouping for rows while children participate directly in parent layout.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-grid columns=\"3\" gap=\"12px\">\r\n * <sky-row>\r\n * <div>Account</div>\r\n * <div>Status</div>\r\n * <div>Actions</div>\r\n * </sky-row>\r\n * </sky-grid>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-row\")\r\nexport class SkyRow extends LitElement {\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: contents;\r\n }\r\n `;\r\n\r\n override render() {\r\n return html`<slot></slot>`;\r\n }\r\n}"],"names":["SkyRow","LitElement","constructor","super","arguments","this","preset","_presets","PresetController","render","html","styles","css","__decorateClass","property","type","String","reflect","prototype","customElement"],"mappings":"kYA0DO,IAAMA,EAAN,cAAqBC,EAArB,WAAAC,GAAAC,SAAAC,WAGsCC,KAAAC,OAAS,GAEpDD,KAAQE,SAAW,IAAIC,EAAiBH,KAAI,CAQnC,MAAAI,GACP,OAAOC,CAAA,eACT,GAfWV,EAOKW,OAASC,CAAA;;;;IAJkBC,EAAA,CAA1CC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAHxBjB,EAGgCkB,UAAA,SAAA,GAHhClB,EAANa,EAAA,CADNM,EAAc,YACFnB"}
@@ -15,7 +15,7 @@ export declare function resolveSheetRadius(input: string): string;
15
15
  * @status stable
16
16
  * @since 1.0.0
17
17
  *
18
- * @documentation https://library.sky-ui.com/components/sheet
18
+ * @documentation https://sky-ui.com/components/sheet
19
19
  *
20
20
  * @slot - Content placed inside the sheet container.
21
21
  *
@@ -24,6 +24,7 @@ export declare function resolveSheetRadius(input: string): string;
24
24
  * @property {SkySheetShadow} shadow - Shadow style preset.
25
25
  * @property {SkySheetBorder} border - Border style preset.
26
26
  * @property {SkySheetRadius} radius - Preset (`none`, `sm`, `md`, `lg`, `xl`) or CSS length (`1rem`, `16px`).
27
+ * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `""`.
27
28
  *
28
29
  * @Behavior
29
30
  * - Applies visual styles directly on `:host` for compact composition.
@@ -64,7 +65,11 @@ export declare class SkySheet extends LitElement {
64
65
  radius: SkySheetRadius;
65
66
  connectedCallback(): void;
66
67
  private _applyRadiusVar;
67
- protected willUpdate(changed: PropertyValues): void;
68
+ /** After PresetController hostUpdate — paint with current radius. */
69
+ protected update(changed: PropertyValues): void;
70
+ /** Named prop preset from nearest `sky-config-provider`. */
71
+ preset: string;
72
+ private _presets;
68
73
  static styles: import("lit").CSSResult;
69
74
  render(): import("lit-html").TemplateResult<1>;
70
75
  }
@@ -1,4 +1,4 @@
1
- import{css as r,LitElement as s,html as a}from"lit";import{property as e,customElement as o}from"lit/decorators.js";import{resolveRadius as t}from"../helper/utils/size-resolver.js";var i=Object.defineProperty,d=Object.getOwnPropertyDescriptor,n=(r,s,a,e)=>{for(var o,t=e>1?void 0:e?d(s,a):s,n=r.length-1;n>=0;n--)(o=r[n])&&(t=(e?o(s,a,t):o(t))||t);return e&&t&&i(s,a,t),t};const y={none:"0",sm:"var(--sky-radius-primary)",md:"var(--sky-radius-secondary)",lg:"var(--sky-radius-tertiary)",xl:"var(--sky-radius-full)"};function b(r){return Object.prototype.hasOwnProperty.call(y,r)?y[r]:t(r)}let l=class extends s{constructor(){super(...arguments),this.bg="primary",this.blurLevel="sm",this.shadow="sm",this.border="sm",this.radius="md"}connectedCallback(){super.connectedCallback(),this._applyRadiusVar()}_applyRadiusVar(){this.style.setProperty("--sheet-radius",b(this.radius))}willUpdate(r){super.willUpdate(r),(0===r.size||r.has("radius"))&&this._applyRadiusVar()}render(){return a`<slot></slot>`}};l.styles=r`
1
+ import{css as r,LitElement as s,html as e}from"lit";import{property as t,customElement as a}from"lit/decorators.js";import{resolveRadius as o}from"../helper/utils/size-resolver.js";import{PresetController as i}from"../helper/controllers/preset-controller.js";var n=Object.defineProperty,d=Object.getOwnPropertyDescriptor,y=(r,s,e,t)=>{for(var a,o=t>1?void 0:t?d(s,e):s,i=r.length-1;i>=0;i--)(a=r[i])&&(o=(t?a(s,e,o):a(o))||o);return t&&o&&n(s,e,o),o};const b={none:"0",sm:"var(--sky-radius-primary)",md:"var(--sky-radius-secondary)",lg:"var(--sky-radius-tertiary)",xl:"var(--sky-radius-full)"};function l(r){return Object.prototype.hasOwnProperty.call(b,r)?b[r]:o(r)}let p=class extends s{constructor(){super(...arguments),this.bg="primary",this.blurLevel="sm",this.shadow="sm",this.border="sm",this.radius="md",this.preset="",this._presets=new i(this)}connectedCallback(){super.connectedCallback(),this._applyRadiusVar()}_applyRadiusVar(){this.style.setProperty("--sheet-radius",l(this.radius))}update(r){(0===r.size||r.has("radius")||r.has("preset"))&&this._applyRadiusVar(),super.update(r)}render(){return e`<slot></slot>`}};p.styles=r`
2
2
  :host {
3
3
  display: block;
4
4
  box-sizing: border-box;
@@ -89,5 +89,5 @@ import{css as r,LitElement as s,html as a}from"lit";import{property as e,customE
89
89
  :host([border="lg"]) {
90
90
  border: var(--sky-border-tertiary);
91
91
  }
92
- `,n([e({type:String,reflect:!0})],l.prototype,"bg",2),n([e({type:String,reflect:!0})],l.prototype,"blurLevel",2),n([e({type:String,reflect:!0})],l.prototype,"shadow",2),n([e({type:String,reflect:!0})],l.prototype,"border",2),n([e({type:String,reflect:!0})],l.prototype,"radius",2),l=n([o("sky-sheet")],l);export{l as SkySheet,b as resolveSheetRadius};
92
+ `,y([t({type:String,reflect:!0})],p.prototype,"bg",2),y([t({type:String,reflect:!0})],p.prototype,"blurLevel",2),y([t({type:String,reflect:!0})],p.prototype,"shadow",2),y([t({type:String,reflect:!0})],p.prototype,"border",2),y([t({type:String,reflect:!0})],p.prototype,"radius",2),y([t({type:String,reflect:!0})],p.prototype,"preset",2),p=y([a("sky-sheet")],p);export{p as SkySheet,l as resolveSheetRadius};
93
93
  //# sourceMappingURL=sky-sheet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sky-sheet.js","sources":["../../src/sky-sheet/sky-sheet.ts"],"sourcesContent":["import { LitElement, html, css, type PropertyValues } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { resolveRadius } from \"../helper/utils/size-resolver.js\";\n\nexport type SkySheetBackground = \"primary\" | \"secondary\" | \"tertiary\" | \"solid\" | \"transparent\";\nexport type SkySheetBlurLevel = \"none\" | \"sm\" | \"md\" | \"lg\";\nexport type SkySheetShadow = \"none\" | \"sm\" | \"md\" | \"lg\" | \"inset\";\nexport type SkySheetBorder = \"none\" | \"sm\" | \"md\" | \"lg\";\n\n/** Preset tokens or any CSS length (e.g. `1rem`, `16px`). */\nexport type SkySheetRadius = string;\n\nconst SHEET_RADIUS_PRESETS: Record<string, string> = {\n none: \"0\",\n sm: \"var(--sky-radius-primary)\",\n md: \"var(--sky-radius-secondary)\",\n lg: \"var(--sky-radius-tertiary)\",\n xl: \"var(--sky-radius-full)\",\n};\n\n/** Preset map includes `xl`; arbitrary values pass through like `resolveRadius`. */\nexport function resolveSheetRadius(input: string): string {\n if (Object.prototype.hasOwnProperty.call(SHEET_RADIUS_PRESETS, input)) {\n return SHEET_RADIUS_PRESETS[input];\n }\n return resolveRadius(input);\n}\n\n/**\n * @element sky-sheet\n *\n * @summary Themed surface container with configurable background, blur, border, and shadow.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://library.sky-ui.com/components/sheet\n *\n * @slot - Content placed inside the sheet container.\n *\n * @property {SkySheetBackground} bg - Background style.\n * @property {SkySheetBlurLevel} blurLevel - Backdrop blur intensity.\n * @property {SkySheetShadow} shadow - Shadow style preset.\n * @property {SkySheetBorder} border - Border style preset.\n * @property {SkySheetRadius} radius - Preset (`none`, `sm`, `md`, `lg`, `xl`) or CSS length (`1rem`, `16px`).\n *\n * @Behavior\n * - Applies visual styles directly on `:host` for compact composition.\n * - Uses theme CSS variables for consistent glass and elevation tokens.\n * - Renders slot content without additional wrappers.\n *\n * @example\n * ```html\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\n * <h3>Deployment Summary</h3>\n * <p>All regional checks passed. Ready to promote to production.</p>\n * </sky-sheet>\n * ```\n * ```vue\n * <template>\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\n * <h3>Deployment Summary</h3>\n * <p>All regional checks passed. Ready to promote to production.</p>\n * </sky-sheet>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return (\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\n * <h3>Deployment Summary</h3>\n * <p>All regional checks passed. Ready to promote to production.</p>\n * </sky-sheet>\n * );\n * }\n * ```\n */\n@customElement(\"sky-sheet\")\nexport class SkySheet extends LitElement {\n\n @property({ type: String, reflect: true })\n bg: SkySheetBackground = \"primary\";\n\n @property({ type: String, reflect: true })\n blurLevel: SkySheetBlurLevel = \"sm\";\n\n @property({ type: String, reflect: true })\n shadow: SkySheetShadow = \"sm\";\n\n @property({ type: String, reflect: true })\n border: SkySheetBorder = \"sm\";\n\n @property({ type: String, reflect: true })\n radius: SkySheetRadius = \"md\";\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._applyRadiusVar();\n }\n\n private _applyRadiusVar(): void {\n this.style.setProperty(\"--sheet-radius\", resolveSheetRadius(this.radius));\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n if (changed.size === 0 || changed.has(\"radius\")) {\n this._applyRadiusVar();\n }\n }\n\n static override styles = css`\n :host {\n display: block;\n box-sizing: border-box;\n font-family: var(--sky-font);\n width: 100%;\n height: 100%;\n padding: var(--sky-space-3, 12px);\n border-radius: var(--sheet-radius, var(--sky-radius-secondary));\n }\n\n /* background */\n :host([bg=\"primary\"]) {\n background: var(--sky-glass-primary);\n }\n :host([bg=\"secondary\"]) {\n background: var(--sky-glass-secondary);\n }\n :host([bg=\"tertiary\"]) {\n background: var(--sky-glass-tertiary);\n }\n :host([bg=\"solid\"]) {\n background: var(--sky-glass-solid);\n background-image: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n :host([bg=\"transparent\"]) {\n background: transparent;\n background-image: none;\n }\n\n :host([bg=\"primary\"]:not([blurLevel=\"none\"])),\n :host([bg=\"secondary\"]:not([blurLevel=\"none\"])),\n :host([bg=\"tertiary\"]:not([blurLevel=\"none\"])) {\n background-image: var(--sky-glass-surface);\n }\n\n :host([blurLevel=\"none\"]) {\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n :host([blurLevel=\"sm\"]) {\n backdrop-filter: var(--sky-blur-primary) var(--sky-brightness-primary)\n var(--sky-saturation-primary);\n -webkit-backdrop-filter: var(--sky-blur-primary)\n var(--sky-brightness-primary) var(--sky-saturation-primary);\n }\n :host([blurLevel=\"md\"]) {\n backdrop-filter: var(--sky-blur-secondary) var(--sky-brightness-secondary)\n var(--sky-saturation-secondary);\n -webkit-backdrop-filter: var(--sky-blur-secondary)\n var(--sky-brightness-secondary) var(--sky-saturation-secondary);\n }\n :host([blurLevel=\"lg\"]) {\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\n var(--sky-saturation-tertiary);\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\n }\n\n /* shadow */\n :host([shadow=\"none\"]) {\n box-shadow: none;\n }\n :host([shadow=\"sm\"]) {\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-primary);\n }\n :host([shadow=\"md\"]) {\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-secondary);\n }\n :host([shadow=\"lg\"]) {\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-tertiary);\n }\n :host([shadow=\"inset\"]) {\n box-shadow: var(--sky-box-shadow-inset);\n }\n\n /* border */\n :host([border=\"none\"]) {\n border: none;\n }\n :host([border=\"sm\"]) {\n border: var(--sky-border-primary);\n }\n :host([border=\"md\"]) {\n border: var(--sky-border-secondary);\n }\n :host([border=\"lg\"]) {\n border: var(--sky-border-tertiary);\n }\n `;\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n"],"names":["SHEET_RADIUS_PRESETS","none","sm","md","lg","xl","resolveSheetRadius","input","Object","prototype","hasOwnProperty","call","resolveRadius","SkySheet","LitElement","constructor","super","arguments","this","bg","blurLevel","shadow","border","radius","connectedCallback","_applyRadiusVar","style","setProperty","willUpdate","changed","size","has","render","html","styles","css","__decorateClass","property","type","String","reflect","customElement"],"mappings":"qXAYA,MAAMA,EAA+C,CACnDC,KAAM,IACNC,GAAI,4BACJC,GAAI,8BACJC,GAAI,6BACJC,GAAI,0BAIC,SAASC,EAAmBC,GACjC,OAAIC,OAAOC,UAAUC,eAAeC,KAAKX,EAAsBO,GACtDP,EAAqBO,GAEvBK,EAAcL,EACvB,CAoDO,IAAMM,EAAN,cAAuBC,EAAvB,WAAAC,GAAAC,SAAAC,WAGLC,KAAAC,GAAyB,UAGzBD,KAAAE,UAA+B,KAG/BF,KAAAG,OAAyB,KAGzBH,KAAAI,OAAyB,KAGzBJ,KAAAK,OAAyB,IAAA,CAEhB,iBAAAC,GACPR,MAAMQ,oBACNN,KAAKO,iBACP,CAEQ,eAAAA,GACNP,KAAKQ,MAAMC,YAAY,iBAAkBrB,EAAmBY,KAAKK,QACnE,CAEmB,UAAAK,CAAWC,GAC5Bb,MAAMY,WAAWC,IACI,IAAjBA,EAAQC,MAAcD,EAAQE,IAAI,YACpCb,KAAKO,iBAET,CA+FS,MAAAO,GACP,OAAOC,CAAA,eACT,GAhIWpB,EAiCKqB,OAASC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA9BzBC,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAFxB3B,EAGXJ,UAAA,KAAA,GAGA2B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KALxB3B,EAMXJ,UAAA,YAAA,GAGA2B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KARxB3B,EASXJ,UAAA,SAAA,GAGA2B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAXxB3B,EAYXJ,UAAA,SAAA,GAGA2B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAdxB3B,EAeXJ,UAAA,SAAA,GAfWI,EAANuB,EAAA,CADNK,EAAc,cACF5B"}
1
+ {"version":3,"file":"sky-sheet.js","sources":["../../src/sky-sheet/sky-sheet.ts"],"sourcesContent":["import { LitElement, html, css, type PropertyValues } from \"lit\";\r\nimport { customElement, property } from \"lit/decorators.js\";\r\nimport { resolveRadius } from \"../helper/utils/size-resolver.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkySheetBackground = \"primary\" | \"secondary\" | \"tertiary\" | \"solid\" | \"transparent\";\r\nexport type SkySheetBlurLevel = \"none\" | \"sm\" | \"md\" | \"lg\";\r\nexport type SkySheetShadow = \"none\" | \"sm\" | \"md\" | \"lg\" | \"inset\";\r\nexport type SkySheetBorder = \"none\" | \"sm\" | \"md\" | \"lg\";\r\n\r\n/** Preset tokens or any CSS length (e.g. `1rem`, `16px`). */\r\nexport type SkySheetRadius = string;\r\n\r\nconst SHEET_RADIUS_PRESETS: Record<string, string> = {\r\n none: \"0\",\r\n sm: \"var(--sky-radius-primary)\",\r\n md: \"var(--sky-radius-secondary)\",\r\n lg: \"var(--sky-radius-tertiary)\",\r\n xl: \"var(--sky-radius-full)\",\r\n};\r\n\r\n/** Preset map includes `xl`; arbitrary values pass through like `resolveRadius`. */\r\nexport function resolveSheetRadius(input: string): string {\r\n if (Object.prototype.hasOwnProperty.call(SHEET_RADIUS_PRESETS, input)) {\r\n return SHEET_RADIUS_PRESETS[input];\r\n }\r\n return resolveRadius(input);\r\n}\r\n\r\n/**\r\n * @element sky-sheet\r\n *\r\n * @summary Themed surface container with configurable background, blur, border, and shadow.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/sheet\r\n *\r\n * @slot - Content placed inside the sheet container.\r\n *\r\n * @property {SkySheetBackground} bg - Background style.\r\n * @property {SkySheetBlurLevel} blurLevel - Backdrop blur intensity.\r\n * @property {SkySheetShadow} shadow - Shadow style preset.\r\n * @property {SkySheetBorder} border - Border style preset.\r\n * @property {SkySheetRadius} radius - Preset (`none`, `sm`, `md`, `lg`, `xl`) or CSS length (`1rem`, `16px`).\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @Behavior\r\n * - Applies visual styles directly on `:host` for compact composition.\r\n * - Uses theme CSS variables for consistent glass and elevation tokens.\r\n * - Renders slot content without additional wrappers.\r\n *\r\n * @example\r\n * ```html\r\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\r\n * <h3>Deployment Summary</h3>\r\n * <p>All regional checks passed. Ready to promote to production.</p>\r\n * </sky-sheet>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\r\n * <h3>Deployment Summary</h3>\r\n * <p>All regional checks passed. Ready to promote to production.</p>\r\n * </sky-sheet>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-sheet bg=\"solid\" blur-level=\"md\" shadow=\"lg\" border=\"md\" radius=\"lg\">\r\n * <h3>Deployment Summary</h3>\r\n * <p>All regional checks passed. Ready to promote to production.</p>\r\n * </sky-sheet>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-sheet\")\r\nexport class SkySheet extends LitElement {\r\n\r\n @property({ type: String, reflect: true })\r\n bg: SkySheetBackground = \"primary\";\r\n\r\n @property({ type: String, reflect: true })\r\n blurLevel: SkySheetBlurLevel = \"sm\";\r\n\r\n @property({ type: String, reflect: true })\r\n shadow: SkySheetShadow = \"sm\";\r\n\r\n @property({ type: String, reflect: true })\r\n border: SkySheetBorder = \"sm\";\r\n\r\n @property({ type: String, reflect: true })\r\n radius: SkySheetRadius = \"md\";\r\n\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this._applyRadiusVar();\r\n }\r\n\r\n private _applyRadiusVar(): void {\r\n this.style.setProperty(\"--sheet-radius\", resolveSheetRadius(this.radius));\r\n }\r\n\r\n /** After PresetController hostUpdate — paint with current radius. */\r\n protected override update(changed: PropertyValues): void {\r\n if (changed.size === 0 || changed.has(\"radius\") || changed.has(\"preset\")) {\r\n this._applyRadiusVar();\r\n }\r\n super.update(changed);\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: block;\r\n box-sizing: border-box;\r\n font-family: var(--sky-font);\r\n width: 100%;\r\n height: 100%;\r\n padding: var(--sky-space-3, 12px);\r\n border-radius: var(--sheet-radius, var(--sky-radius-secondary));\r\n }\r\n\r\n /* background */\r\n :host([bg=\"primary\"]) {\r\n background: var(--sky-glass-primary);\r\n }\r\n :host([bg=\"secondary\"]) {\r\n background: var(--sky-glass-secondary);\r\n }\r\n :host([bg=\"tertiary\"]) {\r\n background: var(--sky-glass-tertiary);\r\n }\r\n :host([bg=\"solid\"]) {\r\n background: var(--sky-glass-solid);\r\n background-image: none;\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n }\r\n :host([bg=\"transparent\"]) {\r\n background: transparent;\r\n background-image: none;\r\n }\r\n\r\n :host([bg=\"primary\"]:not([blurLevel=\"none\"])),\r\n :host([bg=\"secondary\"]:not([blurLevel=\"none\"])),\r\n :host([bg=\"tertiary\"]:not([blurLevel=\"none\"])) {\r\n background-image: var(--sky-glass-surface);\r\n }\r\n\r\n :host([blurLevel=\"none\"]) {\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n }\r\n :host([blurLevel=\"sm\"]) {\r\n backdrop-filter: var(--sky-blur-primary) var(--sky-brightness-primary)\r\n var(--sky-saturation-primary);\r\n -webkit-backdrop-filter: var(--sky-blur-primary)\r\n var(--sky-brightness-primary) var(--sky-saturation-primary);\r\n }\r\n :host([blurLevel=\"md\"]) {\r\n backdrop-filter: var(--sky-blur-secondary) var(--sky-brightness-secondary)\r\n var(--sky-saturation-secondary);\r\n -webkit-backdrop-filter: var(--sky-blur-secondary)\r\n var(--sky-brightness-secondary) var(--sky-saturation-secondary);\r\n }\r\n :host([blurLevel=\"lg\"]) {\r\n backdrop-filter: var(--sky-blur-tertiary) var(--sky-brightness-tertiary)\r\n var(--sky-saturation-tertiary);\r\n -webkit-backdrop-filter: var(--sky-blur-tertiary)\r\n var(--sky-brightness-tertiary) var(--sky-saturation-tertiary);\r\n }\r\n\r\n /* shadow */\r\n :host([shadow=\"none\"]) {\r\n box-shadow: none;\r\n }\r\n :host([shadow=\"sm\"]) {\r\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-primary);\r\n }\r\n :host([shadow=\"md\"]) {\r\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-secondary);\r\n }\r\n :host([shadow=\"lg\"]) {\r\n box-shadow: var(--sky-box-shadow-inset), var(--sky-box-shadow-tertiary);\r\n }\r\n :host([shadow=\"inset\"]) {\r\n box-shadow: var(--sky-box-shadow-inset);\r\n }\r\n\r\n /* border */\r\n :host([border=\"none\"]) {\r\n border: none;\r\n }\r\n :host([border=\"sm\"]) {\r\n border: var(--sky-border-primary);\r\n }\r\n :host([border=\"md\"]) {\r\n border: var(--sky-border-secondary);\r\n }\r\n :host([border=\"lg\"]) {\r\n border: var(--sky-border-tertiary);\r\n }\r\n `;\r\n\r\n override render() {\r\n return html`<slot></slot>`;\r\n }\r\n}\r\n"],"names":["SHEET_RADIUS_PRESETS","none","sm","md","lg","xl","resolveSheetRadius","input","Object","prototype","hasOwnProperty","call","resolveRadius","SkySheet","LitElement","constructor","super","arguments","this","bg","blurLevel","shadow","border","radius","preset","_presets","PresetController","connectedCallback","_applyRadiusVar","style","setProperty","update","changed","size","has","render","html","styles","css","__decorateClass","property","type","String","reflect","customElement"],"mappings":"mcAaA,MAAMA,EAA+C,CACnDC,KAAM,IACNC,GAAI,4BACJC,GAAI,8BACJC,GAAI,6BACJC,GAAI,0BAIC,SAASC,EAAmBC,GACjC,OAAIC,OAAOC,UAAUC,eAAeC,KAAKX,EAAsBO,GACtDP,EAAqBO,GAEvBK,EAAcL,EACvB,CAqDO,IAAMM,EAAN,cAAuBC,EAAvB,WAAAC,GAAAC,SAAAC,WAGLC,KAAAC,GAAyB,UAGzBD,KAAAE,UAA+B,KAG/BF,KAAAG,OAAyB,KAGzBH,KAAAI,OAAyB,KAGzBJ,KAAAK,OAAyB,KAqBkBL,KAAAM,OAAS,GAEpDN,KAAQO,SAAW,IAAIC,EAAiBR,KAAI,CArBnC,iBAAAS,GACPX,MAAMW,oBACNT,KAAKU,iBACP,CAEQ,eAAAA,GACNV,KAAKW,MAAMC,YAAY,iBAAkBxB,EAAmBY,KAAKK,QACnE,CAGmB,MAAAQ,CAAOC,IACH,IAAjBA,EAAQC,MAAcD,EAAQE,IAAI,WAAaF,EAAQE,IAAI,YAC7DhB,KAAKU,kBAEPZ,MAAMe,OAAOC,EACf,CAqGS,MAAAG,GACP,OAAOC,CAAA,eACT,GAvIWvB,EAwCKwB,OAASC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IArCzBC,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAFxB9B,EAGXJ,UAAA,KAAA,GAGA8B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KALxB9B,EAMXJ,UAAA,YAAA,GAGA8B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KARxB9B,EASXJ,UAAA,SAAA,GAGA8B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAXxB9B,EAYXJ,UAAA,SAAA,GAGA8B,EAAA,CADCC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KAdxB9B,EAeXJ,UAAA,SAAA,GAqB2C8B,EAAA,CAA1CC,EAAS,CAAEC,KAAMC,OAAQC,SAAS,KApCxB9B,EAoCgCJ,UAAA,SAAA,GApChCI,EAAN0B,EAAA,CADNK,EAAc,cACF/B"}
@@ -16,7 +16,7 @@ export type SkySimpleTableColumn = {
16
16
  * @status stable
17
17
  * @since 1.0.0
18
18
  *
19
- * @documentation https://library.sky-ui.com/components/simple-table
19
+ * @documentation https://sky-ui.com/components/simple-table
20
20
  *
21
21
  * @csspart wrapper - Scrollable table wrapper.
22
22
  * @csspart table - The native table element.
@@ -29,6 +29,7 @@ export type SkySimpleTableColumn = {
29
29
  * @property {SkySimpleTableColumn[]} columns - Column definitions. Uses first row keys when omitted.
30
30
  * @property {SkySimpleTableColumn[]} column - Alias for `columns`.
31
31
  * @property {string} emptyText - Message shown when there are no rows.
32
+ * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `""`.
32
33
  *
33
34
  * @example
34
35
  * ```html
@@ -53,6 +54,9 @@ export declare class SkySimpleTable extends LitElement {
53
54
  emptyText: string;
54
55
  get column(): SkySimpleTableColumn[];
55
56
  set column(value: SkySimpleTableColumn[] | null | undefined);
57
+ /** Named prop preset from nearest `sky-config-provider`. */
58
+ preset: string;
59
+ private _presets;
56
60
  static styles: import("lit").CSSResult;
57
61
  private get _safeData();
58
62
  private get _resolvedColumns();
@@ -1,4 +1,4 @@
1
- import{css as t,LitElement as r,html as e,nothing as a}from"lit";import{property as s,customElement as o}from"lit/decorators.js";import{repeat as l}from"lit/directives/repeat.js";import{styleMap as i}from"lit/directives/style-map.js";var y=Object.defineProperty,p=Object.getOwnPropertyDescriptor,n=(t,r,e,a)=>{for(var s,o=a>1?void 0:a?p(r,e):r,l=t.length-1;l>=0;l--)(s=t[l])&&(o=(a?s(r,e,o):s(o))||o);return a&&o&&y(r,e,o),o};let d=class extends r{constructor(){super(...arguments),this.data=[],this.columns=[],this.emptyText="No data available"}get column(){return this.columns}set column(t){const r=this.columns;this.columns=Array.isArray(t)?t:[],this.requestUpdate("column",r)}get _safeData(){return Array.isArray(this.data)?this.data:[]}get _resolvedColumns(){if(Array.isArray(this.columns)&&this.columns.length>0)return this.columns.filter(t=>Boolean(t?.key));const t=this._safeData[0];return t?Object.keys(t).map(t=>({key:t,label:this._toTitle(t)})):[]}_toTitle(t){return t.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}_formatCell(t){return null==t?"":t instanceof Date?t.toLocaleDateString():String(t)}_cellStyle(t){return{textAlign:t.align,width:t.width}}render(){const t=this._safeData,r=this._resolvedColumns;return t.length&&r.length?e`
1
+ import{css as t,LitElement as r,html as e,nothing as a}from"lit";import{property as s,customElement as o}from"lit/decorators.js";import{repeat as l}from"lit/directives/repeat.js";import{styleMap as i}from"lit/directives/style-map.js";import{PresetController as p}from"../helper/controllers/preset-controller.js";var n=Object.defineProperty,y=Object.getOwnPropertyDescriptor,d=(t,r,e,a)=>{for(var s,o=a>1?void 0:a?y(r,e):r,l=t.length-1;l>=0;l--)(s=t[l])&&(o=(a?s(r,e,o):s(o))||o);return a&&o&&n(r,e,o),o};let c=class extends r{constructor(){super(...arguments),this.data=[],this.columns=[],this.emptyText="No data available",this.preset="",this._presets=new p(this)}get column(){return this.columns}set column(t){const r=this.columns;this.columns=Array.isArray(t)?t:[],this.requestUpdate("column",r)}get _safeData(){return Array.isArray(this.data)?this.data:[]}get _resolvedColumns(){if(Array.isArray(this.columns)&&this.columns.length>0)return this.columns.filter(t=>Boolean(t?.key));const t=this._safeData[0];return t?Object.keys(t).map(t=>({key:t,label:this._toTitle(t)})):[]}_toTitle(t){return t.replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/\b\w/g,t=>t.toUpperCase())}_formatCell(t){return null==t?"":t instanceof Date?t.toLocaleDateString():String(t)}_cellStyle(t){return{textAlign:t.align,width:t.width}}render(){const t=this._safeData,r=this._resolvedColumns;return t.length&&r.length?e`
2
2
  <div class="wrapper" part="wrapper">
3
3
  <table part="table">
4
4
  <thead>
@@ -30,7 +30,7 @@ import{css as t,LitElement as r,html as e,nothing as a}from"lit";import{property
30
30
  <div class="wrapper" part="wrapper">
31
31
  <div class="empty" part="empty">${this.emptyText}</div>
32
32
  </div>
33
- `}};d.styles=t`
33
+ `}};c.styles=t`
34
34
  :host {
35
35
  display: block;
36
36
  width: 100%;
@@ -96,5 +96,5 @@ import{css as t,LitElement as r,html as e,nothing as a}from"lit";import{property
96
96
  text-align: center;
97
97
  font-size: var(--sky-font-size-sm, 0.875rem);
98
98
  }
99
- `,n([s({type:Array})],d.prototype,"data",2),n([s({type:Array})],d.prototype,"columns",2),n([s({type:String})],d.prototype,"emptyText",2),n([s({type:Array})],d.prototype,"column",1),d=n([o("sky-simple-table")],d);export{d as SkySimpleTable};
99
+ `,d([s({type:Array})],c.prototype,"data",2),d([s({type:Array})],c.prototype,"columns",2),d([s({type:String})],c.prototype,"emptyText",2),d([s({type:Array})],c.prototype,"column",1),d([s({type:String,reflect:!0})],c.prototype,"preset",2),c=d([o("sky-simple-table")],c);export{c as SkySimpleTable};
100
100
  //# sourceMappingURL=sky-simple-table.js.map