luxen-ui 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +50 -49
  2. package/cdn/custom-elements.json +210 -0
  3. package/cdn/elements/avatar/avatar.d.ts.map +1 -1
  4. package/cdn/elements/avatar/avatar.js +1 -1
  5. package/cdn/elements/avatar/avatar.js.map +1 -1
  6. package/cdn/elements/segmented-control/index.d.ts +2 -0
  7. package/cdn/elements/segmented-control/index.d.ts.map +1 -0
  8. package/cdn/elements/segmented-control/index.js +2 -0
  9. package/cdn/elements/segmented-control/index.js.map +1 -0
  10. package/cdn/elements/segmented-control/segmented-control.d.ts +80 -0
  11. package/cdn/elements/segmented-control/segmented-control.d.ts.map +1 -0
  12. package/cdn/elements/segmented-control/segmented-control.js +2 -0
  13. package/cdn/elements/segmented-control/segmented-control.js.map +1 -0
  14. package/cdn/elements/tooltip/tooltip.d.ts.map +1 -1
  15. package/cdn/elements/tooltip/tooltip.js +1 -1
  16. package/cdn/elements/tooltip/tooltip.js.map +1 -1
  17. package/cdn/registry.d.ts +1 -1
  18. package/cdn/registry.d.ts.map +1 -1
  19. package/cdn/registry.js.map +1 -1
  20. package/cdn/standalone.css +167 -0
  21. package/cdn/standalone.js +25 -22
  22. package/cdn/standalone.js.map +1 -1
  23. package/cdn/styles/elements/segmented-control.css +165 -0
  24. package/dist/css/elements/segmented-control.css +165 -0
  25. package/dist/custom-elements.json +210 -0
  26. package/dist/elements/avatar/avatar.d.ts.map +1 -1
  27. package/dist/elements/avatar/avatar.js +27 -7
  28. package/dist/elements/segmented-control/index.d.ts +2 -0
  29. package/dist/elements/segmented-control/index.d.ts.map +1 -0
  30. package/dist/elements/segmented-control/index.js +4 -0
  31. package/dist/elements/segmented-control/segmented-control.d.ts +80 -0
  32. package/dist/elements/segmented-control/segmented-control.d.ts.map +1 -0
  33. package/dist/elements/segmented-control/segmented-control.js +307 -0
  34. package/dist/elements/tooltip/tooltip.d.ts.map +1 -1
  35. package/dist/elements/tooltip/tooltip.js +12 -5
  36. package/dist/metadata/index.json +106 -1
  37. package/dist/metadata/segmented-control.json +105 -0
  38. package/dist/registry.d.ts +1 -1
  39. package/dist/registry.d.ts.map +1 -1
  40. package/dist/templates/elements/segmented-control.md +252 -0
  41. package/elements.json +8 -0
  42. package/package.json +1 -1
package/README.md CHANGED
@@ -22,55 +22,56 @@ Visit https://luxen-ui.com to explore the documentation.
22
22
 
23
23
  <!-- elements-table:start -->
24
24
 
25
- | Name | HTML tag | Type |
26
- | -------------- | -------------------- | --------------------------------------- |
27
- | Alert | `<l-alert>` | ◇ Custom HTML Element (no Shadow DOM) |
28
- | Alert dialog | `<l-alert-dialog>` | ⬢ Custom HTML Element (with Shadow DOM) |
29
- | Avatar | `<l-avatar>` | ⬢ Custom HTML Element (with Shadow DOM) |
30
- | Badge | `<l-badge>` | ◇ Custom HTML Element (no Shadow DOM) |
31
- | Breadcrumb | `<nav>` | ⏣ Native HTML Element |
32
- | Button | `<button>` | ⏣ Native HTML Element |
33
- | Button group | `<l-button-group>` | ◇ Custom HTML Element (no Shadow DOM) |
34
- | Carousel | `<l-carousel>` | ⬢ Custom HTML Element (with Shadow DOM) |
35
- | Carousel item | `<l-carousel-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
36
- | Checkbox | `<input>` | ⏣ Native HTML Element |
37
- | Close button | `<button>` | ⏣ Native HTML Element |
38
- | Combobox | `<l-combobox>` | ⬢ Custom HTML Element (with Shadow DOM) |
39
- | Dialog | `<l-dialog>` | ⬢ Custom HTML Element (with Shadow DOM) |
40
- | Disclosure | `<details>` | ⏣ Native HTML Element |
41
- | Divider | `<l-divider>` | ◇ Custom HTML Element (no Shadow DOM) |
42
- | Drawer | `<l-drawer>` | ⬢ Custom HTML Element (with Shadow DOM) |
43
- | Dropdown | `<l-dropdown>` | ⬢ Custom HTML Element (with Shadow DOM) |
44
- | Dropdown item | `<l-dropdown-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
45
- | Dropdown label | `<l-dropdown-label>` | ⬢ Custom HTML Element (with Shadow DOM) |
46
- | Form field | `<l-form-field>` | ⬡ Progressive Custom HTML Element |
47
- | Icon | `<l-icon>` | ⬢ Custom HTML Element (with Shadow DOM) |
48
- | Input | `<input>` | ⏣ Native HTML Element |
49
- | Input group | `<l-input-group>` | ⬡ Progressive Custom HTML Element |
50
- | Input OTP | `<l-input-otp>` | ⬡ Progressive Custom HTML Element |
51
- | Input stepper | `<l-input-stepper>` | ⬡ Progressive Custom HTML Element |
52
- | Kbd | `<kbd>` | ⏣ Native HTML Element |
53
- | Popover | `<l-popover>` | ⬢ Custom HTML Element (with Shadow DOM) |
54
- | Progress | `<progress>` | ⏣ Native HTML Element |
55
- | Prose editor | `<l-prose-editor>` | ⬢ Custom HTML Element (with Shadow DOM) |
56
- | Radio | `<input>` | ⏣ Native HTML Element |
57
- | Rating | `<l-rating>` | ⬢ Custom HTML Element (with Shadow DOM) |
58
- | Select | `<l-select>` | Custom HTML Element (with Shadow DOM) |
59
- | Skeleton | `<l-skeleton>` | Custom HTML Element (no Shadow DOM) |
60
- | Slider | `<l-slider>` | Custom HTML Element (with Shadow DOM) |
61
- | Spinner | `<l-spinner>` | ⬢ Custom HTML Element (with Shadow DOM) |
62
- | Sticky bar | `<l-sticky-bar>` | ⬢ Custom HTML Element (with Shadow DOM) |
63
- | Stories | `<l-stories>` | Custom HTML Element (no Shadow DOM) |
64
- | Stories viewer | `<l-stories-viewer>` | Custom HTML Element (with Shadow DOM) |
65
- | Story | `<l-story>` | Custom HTML Element (no Shadow DOM) |
66
- | Switch | `<input>` | Native HTML Element |
67
- | Tabs | `<l-tabs>` | Progressive Custom HTML Element |
68
- | Tag | `<l-tag>` | Custom HTML Element (with Shadow DOM) |
69
- | Textarea | `<textarea>` | Native HTML Element |
70
- | Toast | `<l-toast>` | Custom HTML Element (no Shadow DOM) |
71
- | Tooltip | `<l-tooltip>` | Custom HTML Element (with Shadow DOM) |
72
- | Tree | `<l-tree>` | ⬢ Custom HTML Element (with Shadow DOM) |
73
- | Tree item | `<l-tree-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
25
+ | Name | HTML tag | Type |
26
+ | ----------------- | ----------------------- | --------------------------------------- |
27
+ | Alert | `<l-alert>` | ◇ Custom HTML Element (no Shadow DOM) |
28
+ | Alert dialog | `<l-alert-dialog>` | ⬢ Custom HTML Element (with Shadow DOM) |
29
+ | Avatar | `<l-avatar>` | ⬢ Custom HTML Element (with Shadow DOM) |
30
+ | Badge | `<l-badge>` | ◇ Custom HTML Element (no Shadow DOM) |
31
+ | Breadcrumb | `<nav>` | ⏣ Native HTML Element |
32
+ | Button | `<button>` | ⏣ Native HTML Element |
33
+ | Button group | `<l-button-group>` | ◇ Custom HTML Element (no Shadow DOM) |
34
+ | Carousel | `<l-carousel>` | ⬢ Custom HTML Element (with Shadow DOM) |
35
+ | Carousel item | `<l-carousel-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
36
+ | Checkbox | `<input>` | ⏣ Native HTML Element |
37
+ | Close button | `<button>` | ⏣ Native HTML Element |
38
+ | Combobox | `<l-combobox>` | ⬢ Custom HTML Element (with Shadow DOM) |
39
+ | Dialog | `<l-dialog>` | ⬢ Custom HTML Element (with Shadow DOM) |
40
+ | Disclosure | `<details>` | ⏣ Native HTML Element |
41
+ | Divider | `<l-divider>` | ◇ Custom HTML Element (no Shadow DOM) |
42
+ | Drawer | `<l-drawer>` | ⬢ Custom HTML Element (with Shadow DOM) |
43
+ | Dropdown | `<l-dropdown>` | ⬢ Custom HTML Element (with Shadow DOM) |
44
+ | Dropdown item | `<l-dropdown-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
45
+ | Dropdown label | `<l-dropdown-label>` | ⬢ Custom HTML Element (with Shadow DOM) |
46
+ | Form field | `<l-form-field>` | ⬡ Progressive Custom HTML Element |
47
+ | Icon | `<l-icon>` | ⬢ Custom HTML Element (with Shadow DOM) |
48
+ | Input | `<input>` | ⏣ Native HTML Element |
49
+ | Input group | `<l-input-group>` | ⬡ Progressive Custom HTML Element |
50
+ | Input OTP | `<l-input-otp>` | ⬡ Progressive Custom HTML Element |
51
+ | Input stepper | `<l-input-stepper>` | ⬡ Progressive Custom HTML Element |
52
+ | Kbd | `<kbd>` | ⏣ Native HTML Element |
53
+ | Popover | `<l-popover>` | ⬢ Custom HTML Element (with Shadow DOM) |
54
+ | Progress | `<progress>` | ⏣ Native HTML Element |
55
+ | Prose editor | `<l-prose-editor>` | ⬢ Custom HTML Element (with Shadow DOM) |
56
+ | Radio | `<input>` | ⏣ Native HTML Element |
57
+ | Rating | `<l-rating>` | ⬢ Custom HTML Element (with Shadow DOM) |
58
+ | Segmented control | `<l-segmented-control>` | Progressive Custom HTML Element |
59
+ | Select | `<l-select>` | Custom HTML Element (with Shadow DOM) |
60
+ | Skeleton | `<l-skeleton>` | Custom HTML Element (no Shadow DOM) |
61
+ | Slider | `<l-slider>` | ⬢ Custom HTML Element (with Shadow DOM) |
62
+ | Spinner | `<l-spinner>` | ⬢ Custom HTML Element (with Shadow DOM) |
63
+ | Sticky bar | `<l-sticky-bar>` | Custom HTML Element (with Shadow DOM) |
64
+ | Stories | `<l-stories>` | Custom HTML Element (no Shadow DOM) |
65
+ | Stories viewer | `<l-stories-viewer>` | Custom HTML Element (with Shadow DOM) |
66
+ | Story | `<l-story>` | Custom HTML Element (no Shadow DOM) |
67
+ | Switch | `<input>` | Native HTML Element |
68
+ | Tabs | `<l-tabs>` | Progressive Custom HTML Element |
69
+ | Tag | `<l-tag>` | Custom HTML Element (with Shadow DOM) |
70
+ | Textarea | `<textarea>` | Native HTML Element |
71
+ | Toast | `<l-toast>` | Custom HTML Element (no Shadow DOM) |
72
+ | Tooltip | `<l-tooltip>` | ⬢ Custom HTML Element (with Shadow DOM) |
73
+ | Tree | `<l-tree>` | ⬢ Custom HTML Element (with Shadow DOM) |
74
+ | Tree item | `<l-tree-item>` | ⬢ Custom HTML Element (with Shadow DOM) |
74
75
 
75
76
  _⏣ Native HTML Element · ⬡ Progressive Custom HTML Element · ◇ Custom HTML Element (no Shadow DOM) · ⬢ Custom HTML Element (with Shadow DOM)_
76
77
 
@@ -6041,6 +6041,216 @@
6041
6041
  }
6042
6042
  ]
6043
6043
  },
6044
+ {
6045
+ "kind": "javascript-module",
6046
+ "path": "src/html/elements/segmented-control/index.ts",
6047
+ "declarations": [],
6048
+ "exports": [
6049
+ {
6050
+ "kind": "js",
6051
+ "name": "*",
6052
+ "declaration": {
6053
+ "name": "*",
6054
+ "module": "src/html/elements/segmented-control/segmented-control.js"
6055
+ }
6056
+ }
6057
+ ]
6058
+ },
6059
+ {
6060
+ "kind": "javascript-module",
6061
+ "path": "src/html/elements/segmented-control/segmented-control.ts",
6062
+ "declarations": [
6063
+ {
6064
+ "kind": "class",
6065
+ "description": "Fired when the selected segment changes. Bubbles; not composed.",
6066
+ "name": "SegmentChangeEvent",
6067
+ "members": [
6068
+ {
6069
+ "kind": "field",
6070
+ "name": "value",
6071
+ "type": {
6072
+ "text": "string"
6073
+ },
6074
+ "readonly": true,
6075
+ "default": "value"
6076
+ },
6077
+ {
6078
+ "kind": "field",
6079
+ "name": "index",
6080
+ "type": {
6081
+ "text": "number"
6082
+ },
6083
+ "readonly": true,
6084
+ "default": "index"
6085
+ }
6086
+ ],
6087
+ "superclass": {
6088
+ "name": "Event",
6089
+ "module": "src/html/elements/segmented-control/segmented-control.ts"
6090
+ }
6091
+ },
6092
+ {
6093
+ "kind": "class",
6094
+ "description": "",
6095
+ "name": "SegmentedControl",
6096
+ "cssProperties": [
6097
+ {
6098
+ "description": "Background of the sliding pill behind the selected segment.",
6099
+ "name": "--indicator-color",
6100
+ "default": "var(--l-color-surface)"
6101
+ },
6102
+ {
6103
+ "description": "Corner radius of the track.",
6104
+ "name": "--border-radius",
6105
+ "default": "var(--l-radius-lg)"
6106
+ }
6107
+ ],
6108
+ "members": [
6109
+ {
6110
+ "kind": "field",
6111
+ "name": "value",
6112
+ "type": {
6113
+ "text": "string"
6114
+ },
6115
+ "default": "''",
6116
+ "description": "Value of the selected segment (its `value` attribute, else its index).",
6117
+ "attribute": "value",
6118
+ "reflects": true
6119
+ },
6120
+ {
6121
+ "kind": "field",
6122
+ "name": "size",
6123
+ "type": {
6124
+ "text": "SegmentedControlSize"
6125
+ },
6126
+ "default": "'md'",
6127
+ "description": "Control height, aligned with buttons and form controls at the same size.",
6128
+ "attribute": "size",
6129
+ "reflects": true
6130
+ },
6131
+ {
6132
+ "kind": "field",
6133
+ "name": "label",
6134
+ "type": {
6135
+ "text": "string | undefined"
6136
+ },
6137
+ "description": "Accessible label announced for the group. Not displayed on screen.",
6138
+ "attribute": "label",
6139
+ "reflects": true
6140
+ },
6141
+ {
6142
+ "kind": "field",
6143
+ "name": "fullWidth",
6144
+ "type": {
6145
+ "text": "boolean"
6146
+ },
6147
+ "default": "false",
6148
+ "description": "Stretch segments to fill the container width.",
6149
+ "attribute": "full-width",
6150
+ "reflects": true
6151
+ },
6152
+ {
6153
+ "kind": "method",
6154
+ "name": "formResetCallback"
6155
+ },
6156
+ {
6157
+ "kind": "method",
6158
+ "name": "formStateRestoreCallback",
6159
+ "parameters": [
6160
+ {
6161
+ "name": "state",
6162
+ "type": {
6163
+ "text": "string"
6164
+ }
6165
+ },
6166
+ {
6167
+ "name": "mode",
6168
+ "type": {
6169
+ "text": "'restore' | 'autocomplete'"
6170
+ }
6171
+ }
6172
+ ]
6173
+ }
6174
+ ],
6175
+ "events": [
6176
+ {
6177
+ "name": "change",
6178
+ "description": "Fired when the selected segment changes. Not cancelable. Bubbles. Properties: `value: string`, `index: number`.",
6179
+ "cancelable": false
6180
+ }
6181
+ ],
6182
+ "attributes": [
6183
+ {
6184
+ "name": "value",
6185
+ "type": {
6186
+ "text": "string"
6187
+ },
6188
+ "default": "''",
6189
+ "description": "Value of the selected segment (its `value` attribute, else its index).",
6190
+ "fieldName": "value"
6191
+ },
6192
+ {
6193
+ "name": "size",
6194
+ "type": {
6195
+ "text": "SegmentedControlSize"
6196
+ },
6197
+ "default": "'md'",
6198
+ "description": "Control height, aligned with buttons and form controls at the same size.",
6199
+ "fieldName": "size"
6200
+ },
6201
+ {
6202
+ "name": "label",
6203
+ "type": {
6204
+ "text": "string | undefined"
6205
+ },
6206
+ "description": "Accessible label announced for the group. Not displayed on screen.",
6207
+ "fieldName": "label"
6208
+ },
6209
+ {
6210
+ "name": "full-width",
6211
+ "type": {
6212
+ "text": "boolean"
6213
+ },
6214
+ "default": "false",
6215
+ "description": "Stretch segments to fill the container width.",
6216
+ "fieldName": "fullWidth"
6217
+ }
6218
+ ],
6219
+ "superclass": {
6220
+ "name": "LuxenFormAssociatedElement",
6221
+ "module": "/src/html/shared/luxen-form-associated-element.js"
6222
+ },
6223
+ "tagName": "l-segmented-control",
6224
+ "customElement": true,
6225
+ "summary": "A single-select segmented control: a compact, mutually-exclusive\nswitch between a few options (radio-group semantics with a sliding pill).\nProgressively enhances light-DOM `<button>`s so it works before JS runs.\nForm-associated: give it a `name` and its selected `value` is submitted with\nthe form (and restored on reset), like a native radio group.",
6226
+ "examples": [
6227
+ {
6228
+ "title": "Mark the initially-selected segment with `aria-checked=\"true\"` (or set",
6229
+ "language": "html",
6230
+ "code": "`value` to its `value` attribute) so it is styled before the script upgrades\nthe element.\n```html\n<l-segmented-control label=\"Metric\" value=\"cost\">\n <button value=\"volume\">Volume</button>\n <button value=\"cost\" aria-checked=\"true\">Cost</button>\n</l-segmented-control>\n```"
6231
+ }
6232
+ ]
6233
+ }
6234
+ ],
6235
+ "exports": [
6236
+ {
6237
+ "kind": "js",
6238
+ "name": "SegmentChangeEvent",
6239
+ "declaration": {
6240
+ "name": "SegmentChangeEvent",
6241
+ "module": "src/html/elements/segmented-control/segmented-control.ts"
6242
+ }
6243
+ },
6244
+ {
6245
+ "kind": "js",
6246
+ "name": "SegmentedControl",
6247
+ "declaration": {
6248
+ "name": "SegmentedControl",
6249
+ "module": "src/html/elements/segmented-control/segmented-control.ts"
6250
+ }
6251
+ }
6252
+ ]
6253
+ },
6044
6254
  {
6045
6255
  "kind": "javascript-module",
6046
6256
  "path": "src/html/elements/select/index.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/html/elements/avatar/avatar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAqB7D;;;;;;;;;;;;GAYG;AACH,qBAAa,MAAO,SAAQ,YAAY;IACtC,MAAM,CAAC,MAAM,4BAAwB;IAErC,qFAAqF;IAErF,GAAG,SAAM;IAET,6EAA6E;IAE7E,IAAI,SAAM;IAEV,8DAA8D;IAE9D,IAAI,SAAQ;IAEZ,4DAA4D;IAE5D,KAAK,SAAK;IAEV,+DAA+D;IAE/D,WAAW,UAAS;IAEX,OAAO,CAAC,SAAS,CAAS;IAEnC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAMxC,iBAAiB;IAOjB,OAAO;IAgBP,OAAO,KAAK,IAAI,GAEf;IAED,MAAM;IAkCN,OAAO,CAAC,QAAQ,CAEd;CACH"}
1
+ {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/html/elements/avatar/avatar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA0C7D;;;;;;;;;;;;GAYG;AACH,qBAAa,MAAO,SAAQ,YAAY;IACtC,MAAM,CAAC,MAAM,4BAAwB;IAErC,qFAAqF;IAErF,GAAG,SAAM;IAET,6EAA6E;IAE7E,IAAI,SAAM;IAEV,8DAA8D;IAE9D,IAAI,SAAQ;IAEZ,4DAA4D;IAE5D,KAAK,SAAK;IAEV,+DAA+D;IAE/D,WAAW,UAAS;IAEX,OAAO,CAAC,SAAS,CAAS;IAEnC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAMxC,iBAAiB;IAOjB,OAAO;IAgBP,OAAO,KAAK,IAAI,GAEf;IAED,MAAM;IAkCN,OAAO,CAAC,QAAQ,CAEd;CACH"}
@@ -1,4 +1,4 @@
1
- import{i as e}from"../../chunks/lit.js";import{i as t,r as n,t as r}from"../../chunks/decorate.js";import{a as i,o as a,t as o}from"../../chunks/lit-html.js";import{LuxenElement as s}from"../../shared/luxen-element.js";import c from"../../shared/styles/host.styles.js";import{r as l,t as u}from"../../chunks/static-html.js";var d=e(`:host{--size:40px;--_font-size:calc(var(--size) * .4);width:var(--size);height:var(--size);border-radius:calc(var(--size) * .15);isolation:isolate;vertical-align:middle;color:var(--l-color-text-secondary);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}:host([size=xs]){--size:24px;--_font-size:.75rem}:host([size=sm]){--size:32px;--_font-size:.875rem}:host([size=lg]){--size:48px;--_font-size:1.25rem}:host([size=xl]){--size:56px;--_font-size:1.25rem}img{object-fit:cover;border-radius:inherit;width:100%;height:100%}.initials{margin:auto}.icon{color:currentColor;width:60%;height:60%}.badge{z-index:1;min-width:12px;height:12px;box-shadow:0 0 0 2px var(--l-color-surface);background-color:var(--l-color-surface);font-variant-numeric:tabular-nums;color:var(--l-color-text-primary);border-radius:3px;justify-content:center;align-items:center;padding-inline:2px;font-size:.625rem;font-weight:500;line-height:1;display:flex;position:absolute;bottom:0;right:0;overflow:hidden}.base:after{content:"";border-radius:inherit;pointer-events:none;position:absolute;inset:0;box-shadow:inset 0 0 0 1px var(--lightningcss-light,oklch(0% 0 0/.07))var(--lightningcss-dark,oklch(100% 0 0/.1))}.base{border-radius:calc(var(--size) * .15);background-color:var(--color,var(--l-color-bg-fill-neutral-soft));--_on:calc(255 * ( 1 - sign(.2126 * (r / 255) * (r / 255) + .7152 * (g / 255) * (g / 255) + .0722 * (b / 255) * (b / 255) - .2) ) / 2);width:100%;height:100%;color:var(--text-color,rgb(from var(--color) var(--_on) var(--_on) var(--_on)));font-size:var(--_font-size);text-transform:uppercase;cursor:inherit;border:none;justify-content:center;align-items:center;padding:0;font-weight:500;line-height:1;display:inline-flex}@supports (color:contrast-color(red)){.base{color:var(--text-color,contrast-color(var(--color)))}}button.base{cursor:pointer}button.base:focus-visible{outline:2px solid var(--l-focus-ring);outline-offset:2px}button.base:hover{box-shadow:inset 0 0 0 1.5px var(--l-color-border-interactive)}@container style(--appearance:circle){.base{border-radius:50%}}`);function f(e){return e.match(/(\b\S)?/g).join(``).match(/(^\S|\S$)?/g).join(``).toUpperCase()}var p=a`<svg class="icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
1
+ import{i as e}from"../../chunks/lit.js";import{i as t,r as n,t as r}from"../../chunks/decorate.js";import{a as i,o as a,t as o}from"../../chunks/lit-html.js";import{LuxenElement as s}from"../../shared/luxen-element.js";import c from"../../shared/styles/host.styles.js";import{r as l,t as u}from"../../chunks/static-html.js";var d=e(`:host{--size:40px;--_font-size:calc(var(--size) * .4);width:var(--size);height:var(--size);border-radius:calc(var(--size) * .15);isolation:isolate;vertical-align:middle;color:var(--l-color-text-secondary);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}:host([size=xs]){--size:24px;--_font-size:.75rem}:host([size=sm]){--size:32px;--_font-size:.875rem}:host([size=lg]){--size:48px;--_font-size:1.25rem}:host([size=xl]){--size:56px;--_font-size:1.25rem}img{object-fit:cover;border-radius:inherit;width:100%;height:100%}.initials{margin:auto}.icon{color:currentColor;width:60%;height:60%}.badge{z-index:1;min-width:12px;height:12px;box-shadow:0 0 0 2px var(--l-color-surface);background-color:var(--l-color-surface);font-variant-numeric:tabular-nums;color:var(--l-color-text-primary);border-radius:3px;justify-content:center;align-items:center;padding-inline:2px;font-size:.625rem;font-weight:500;line-height:1;display:flex;position:absolute;bottom:0;right:0;overflow:hidden}.base:after{content:"";border-radius:inherit;pointer-events:none;position:absolute;inset:0;box-shadow:inset 0 0 0 1px var(--lightningcss-light,oklch(0% 0 0/.07))var(--lightningcss-dark,oklch(100% 0 0/.1))}.base{border-radius:calc(var(--size) * .15);background-color:var(--color,var(--l-color-bg-fill-neutral-soft));--_on:calc(255 * ( 1 - sign(.2126 * (r / 255) * (r / 255) + .7152 * (g / 255) * (g / 255) + .0722 * (b / 255) * (b / 255) - .2) ) / 2);width:100%;height:100%;color:var(--text-color,rgb(from var(--color) var(--_on) var(--_on) var(--_on)));font-size:var(--_font-size);text-transform:uppercase;cursor:inherit;border:none;justify-content:center;align-items:center;padding:0;font-weight:500;line-height:1;display:inline-flex}@supports (color:contrast-color(red)){.base{color:var(--text-color,contrast-color(var(--color)))}}button.base{cursor:pointer}button.base:focus-visible{outline:2px solid var(--l-focus-ring);outline-offset:2px}button.base:hover{box-shadow:inset 0 0 0 1.5px var(--l-color-border-interactive)}@container style(--appearance:circle){.base{border-radius:50%}}`);function f(e=``){let t=e.normalize(`NFC`).trim().split(/\s+/).filter(Boolean);if(t.length===0)return``;let n=e=>[...e][0];return(n(t[0])+(t.length>1?n(t[t.length-1]):``)).toUpperCase()}var p=a`<svg class="icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
2
2
  <path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" />
3
3
  </svg>`,m=class extends s{constructor(...e){super(...e),this.src=``,this.name=``,this.size=`md`,this.badge=0,this.interactive=!1,this._hasError=!1,this._onError=()=>{this._hasError=!0}}static{this.styles=[c,d]}willUpdate(e){e.has(`src`)&&(this._hasError=!1)}connectedCallback(){super.connectedCallback(),!this.interactive&&!this.hasAttribute(`role`)&&this.setAttribute(`role`,`img`)}updated(){this.interactive?(this.getAttribute(`role`)===`img`&&this.removeAttribute(`role`),this.removeAttribute(`aria-label`)):(this.hasAttribute(`role`)||this.setAttribute(`role`,`img`),this.name&&this.setAttribute(`aria-label`,this.name));let e=getComputedStyle(this).getPropertyValue(`--appearance`).trim()===`circle`;this.style.borderRadius=e?`50%`:``}get _tag(){return this.interactive?u`button`:u`div`}render(){let e=this.src&&!this._hasError?i`<img
4
4
  src=${this.src}
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","names":[],"sources":["../../../src/html/elements/avatar/avatar.css?inline","../../../src/html/elements/avatar/avatar.ts"],"sourcesContent":[":host {\n --size: 40px;\n --_font-size: calc(var(--size) * 0.4);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: var(--size);\n height: var(--size);\n border-radius: calc(var(--size) * 0.15);\n isolation: isolate;\n vertical-align: middle;\n flex-shrink: 0;\n color: var(--l-color-text-secondary);\n}\n\n:host([size='xs']) {\n --size: 24px;\n --_font-size: 0.75rem;\n}\n:host([size='sm']) {\n --size: 32px;\n --_font-size: 0.875rem;\n}\n:host([size='lg']) {\n --size: 48px;\n --_font-size: 1.25rem;\n}\n:host([size='xl']) {\n --size: 56px;\n --_font-size: 1.25rem;\n}\n\nimg {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: inherit;\n}\n\n.initials {\n margin: auto;\n}\n\n.icon {\n width: 60%;\n height: 60%;\n color: currentColor;\n}\n\n.badge {\n position: absolute;\n bottom: 0;\n right: 0;\n z-index: 1;\n height: 12px;\n min-width: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: 2px;\n border-radius: 3px;\n box-shadow: 0 0 0 2px var(--l-color-surface);\n background-color: var(--l-color-surface);\n font-size: 0.625rem;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n line-height: 1;\n color: var(--l-color-text-primary);\n overflow: hidden;\n}\n\n/*\n * Inset ring via ::after so it renders on top of the <img>.\n * A box-shadow on :host would be covered by the image since\n * it fills the entire element with object-fit: cover.\n */\n.base::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 1px light-dark(oklch(0 0 0 / 7%), oklch(100% 0 0 / 10%));\n pointer-events: none;\n}\n\n.base {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border: none;\n border-radius: calc(var(--size) * 0.15);\n background-color: var(--color, var(--l-color-bg-fill-neutral-soft));\n /*\n * Text over --color, decided by the background's own luminance — never the\n * document mode, since --color is consumer-set and ignores light/dark.\n * The contrast-color() block below is the primary path (Baseline 2026); this\n * --_on calc() is the fallback for browsers predating it (Chrome ≤146,\n * Safari <26, Firefox <146). It approximates WCAG relative luminance with\n * squared sRGB channels (a cheap linearization, Rec. 709 weights) and flips at\n * 0.2, just above the black/white crossover (~0.179) to offset squaring\n * underestimating mid-tones — holding AA across saturated brand colors where an\n * OKLCH-lightness threshold collapses to ≈1:1 (OKLCH L tracks hue, not\n * luminance: a mid red reads \"light\" yet needs white text). --text-color lets\n * consumers force a specific brand text color, overriding both paths.\n */\n --_on: calc(\n 255 *\n (\n 1 -\n sign(\n 0.2126 * (r / 255) * (r / 255) + 0.7152 * (g / 255) * (g / 255) + 0.0722 * (b / 255) *\n (b / 255) - 0.2\n )\n ) /\n 2\n );\n color: var(--text-color, rgb(from var(--color) var(--_on) var(--_on) var(--_on)));\n font-size: var(--_font-size);\n font-weight: 500;\n line-height: 1;\n text-transform: uppercase;\n padding: 0;\n cursor: inherit;\n}\n\n/* Primary path: native, guaranteed-contrast black/white. contrast-color() is\n * Baseline Newly Available (2026) — Safari 26+, Firefox 146+, Chrome/Edge 147+ —\n * and supersedes the luminance approximation above where supported. @supports (not\n * declaration order) is required: the value contains var(), so a non-supporting\n * browser would treat contrast-color() as invalid-at-computed-value-time and reset\n * to `inherit` rather than falling back to the calc() line. No bg fallback inside,\n * so a bare avatar (no --color) keeps inheriting --l-color-text-secondary.\n * --text-color still wins here, overriding contrast-color()'s choice.\n * (The earlier `… vs black, white to AA` extended syntax was dropped from the spec.) */\n@supports (color: contrast-color(red)) {\n .base {\n color: var(--text-color, contrast-color(var(--color)));\n }\n}\n\nbutton.base {\n cursor: pointer;\n}\n\nbutton.base:focus-visible {\n outline: 2px solid var(--l-focus-ring);\n outline-offset: 2px;\n}\n\nbutton.base:hover {\n box-shadow: inset 0 0 0 1.5px var(--l-color-border-interactive);\n}\n\n@container style(--appearance: circle) {\n .base {\n border-radius: 50%;\n }\n}\n","import { html, nothing, svg, unsafeCSS } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { html as staticHtml, literal } from 'lit/static-html.js';\nimport { property, state } from 'lit/decorators.js';\nimport hostStyles from '../../shared/styles/host.styles.js';\nimport rawStyles from './avatar.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\nfunction getInitials(name: string): string {\n return name\n .match(/(\\b\\S)?/g)!\n .join('')\n .match(/(^\\S|\\S$)?/g)!\n .join('')\n .toUpperCase();\n}\n\nconst defaultIcon = svg`<svg class=\"icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z\" />\n</svg>`;\n\n/**\n * @summary An avatar component for displaying user images, initials, or a default icon.\n * @customElement l-avatar\n *\n * @cssproperty [--size=40px] - Box size (any length). Set it inline (e.g. `style=\"--size: 20px\"`) for an arbitrary size beyond the `size` token scale; the font then follows proportionally. The `size` attribute sets it to the matching token.\n * @cssproperty --color - Background fill color for initials and the default icon.\n * @cssproperty --text-color - Initials/icon color over `--color`. Defaults to an auto-derived readable color; set it to enforce a specific brand color (overrides the automatic choice).\n * @cssproperty --appearance - Set to `circle` for a fully circular avatar (default is a rounded square).\n *\n * @csspart base - The avatar container that paints `--color`; style it (e.g. `color`) to override the auto-derived text color.\n *\n * @cssClass .l-avatar-group - Flex wrapper that overlaps a row of stacked avatars.\n */\nexport class Avatar extends LuxenElement {\n static styles = [hostStyles, styles];\n\n /** Image URL. Falls back to initials (then the default icon) if it fails to load. */\n @property()\n src = '';\n\n /** Name used as the accessible label and to derive the initials fallback. */\n @property()\n name = '';\n\n /** Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`. */\n @property({ reflect: true })\n size = 'md';\n\n /** Count shown in the corner badge. `0` hides the badge. */\n @property({ type: Number })\n badge = 0;\n\n /** Render as a `<button>` with focus ring and hover states. */\n @property({ type: Boolean, reflect: true })\n interactive = false;\n\n @state() private _hasError = false;\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('src')) {\n this._hasError = false;\n }\n }\n\n connectedCallback() {\n super.connectedCallback();\n if (!this.interactive && !this.hasAttribute('role')) {\n this.setAttribute('role', 'img');\n }\n }\n\n updated() {\n // An interactive avatar renders a focusable <button>, and a role=\"img\" node\n // must stay a leaf in the accessibility tree — so the host carries no role\n // or label and the inner button holds the accessible name (see render()).\n if (this.interactive) {\n if (this.getAttribute('role') === 'img') this.removeAttribute('role');\n this.removeAttribute('aria-label');\n } else {\n if (!this.hasAttribute('role')) this.setAttribute('role', 'img');\n if (this.name) this.setAttribute('aria-label', this.name);\n }\n\n const isCircle = getComputedStyle(this).getPropertyValue('--appearance').trim() === 'circle';\n this.style.borderRadius = isCircle ? '50%' : '';\n }\n\n private get _tag() {\n return this.interactive ? literal`button` : literal`div`;\n }\n\n render() {\n const content =\n this.src && !this._hasError\n ? html`<img\n src=${this.src}\n alt=${this.name || ''}\n @error=${this._onError}\n />`\n : this.name\n ? html`<span class=\"initials\">${getInitials(this.name)}</span>`\n : html`<slot>${defaultIcon}</slot>`;\n\n return staticHtml`\n <${this._tag}\n class=\"base\"\n part=\"base\"\n type=${this.interactive ? 'button' : nothing}\n aria-label=${this.interactive && this.name ? this.name : nothing}\n >\n ${content}\n </${this._tag}>\n ${\n this.badge\n ? html`<div\n class=\"badge\"\n aria-hidden=\"true\"\n >\n ${this.badge}\n </div>`\n : nothing\n }\n `;\n }\n\n private _onError = () => {\n this._hasError = true;\n };\n}\n"],"mappings":"oUCOA,IAAM,EAAS,EAAU,4jEAAS,EAElC,SAAS,EAAY,EAAsB,CACzC,OAAO,EACJ,MAAM,UAAU,CAAC,CACjB,KAAK,EAAE,CAAC,CACR,MAAM,aAAa,CAAC,CACpB,KAAK,EAAE,CAAC,CACR,YAAY,CACjB,CAEA,IAAM,EAAc,CAAG;;QAiBV,EAAb,cAA4B,CAAa,wCAKjC,aAIC,aAIA,gBAIC,mBAIM,kBAEe,qBAqEJ,CACvB,KAAK,UAAY,EACnB,qBA7FgB,CAAC,EAAY,CAAM,EAwBnC,WAAW,EAA+B,CACpC,EAAQ,IAAI,KAAK,IACnB,KAAK,UAAY,GAErB,CAEA,mBAAoB,CAClB,MAAM,kBAAkB,EACpB,CAAC,KAAK,aAAe,CAAC,KAAK,aAAa,MAAM,GAChD,KAAK,aAAa,OAAQ,KAAK,CAEnC,CAEA,SAAU,CAIJ,KAAK,aACH,KAAK,aAAa,MAAM,IAAM,OAAO,KAAK,gBAAgB,MAAM,EACpE,KAAK,gBAAgB,YAAY,IAE5B,KAAK,aAAa,MAAM,GAAG,KAAK,aAAa,OAAQ,KAAK,EAC3D,KAAK,MAAM,KAAK,aAAa,aAAc,KAAK,IAAI,GAG1D,IAAM,EAAW,iBAAiB,IAAI,CAAC,CAAC,iBAAiB,cAAc,CAAC,CAAC,KAAK,IAAM,SACpF,KAAK,MAAM,aAAe,EAAW,MAAQ,EAC/C,CAEA,IAAY,MAAO,CACjB,OAAO,KAAK,YAAc,CAAO,SAAW,CAAO,KACrD,CAEA,QAAS,CACP,IAAM,EACJ,KAAK,KAAO,CAAC,KAAK,UACd,CAAI;kBACI,KAAK,IAAI;kBACT,KAAK,MAAQ,GAAG;qBACb,KAAK,SAAS;cAEzB,KAAK,KACH,CAAI,0BAA0B,EAAY,KAAK,IAAI,EAAE,SACrD,CAAI,SAAS,EAAY,SAEjC,MAAO,EAAU;SACZ,KAAK,KAAK;;;eAGJ,KAAK,YAAc,SAAW,EAAQ;qBAChC,KAAK,aAAe,KAAK,KAAO,KAAK,KAAO,EAAQ;;UAE/D,EAAQ;UACR,KAAK,KAAK;QAEZ,KAAK,MACD,CAAI;;;;gBAIA,KAAK,MAAM;oBAEf,EACL;KAEL,CAKF,KA3FG,EAAS,CAAA,EAAA,EAAA,UAAA,MAAA,IAAA,EAAA,KAIT,EAAS,CAAA,EAAA,EAAA,UAAA,OAAA,IAAA,EAAA,KAIT,EAAS,CAAE,QAAS,EAAK,CAAC,CAAA,EAAA,EAAA,UAAA,OAAA,IAAA,EAAA,KAI1B,EAAS,CAAE,KAAM,MAAO,CAAC,CAAA,EAAA,EAAA,UAAA,QAAA,IAAA,EAAA,KAIzB,EAAS,CAAE,KAAM,QAAS,QAAS,EAAK,CAAC,CAAA,EAAA,EAAA,UAAA,cAAA,IAAA,EAAA,KAGzC,EAAM,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"avatar.js","names":[],"sources":["../../../src/html/elements/avatar/avatar.css?inline","../../../src/html/elements/avatar/avatar.ts"],"sourcesContent":[":host {\n --size: 40px;\n --_font-size: calc(var(--size) * 0.4);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: var(--size);\n height: var(--size);\n border-radius: calc(var(--size) * 0.15);\n isolation: isolate;\n vertical-align: middle;\n flex-shrink: 0;\n color: var(--l-color-text-secondary);\n}\n\n:host([size='xs']) {\n --size: 24px;\n --_font-size: 0.75rem;\n}\n:host([size='sm']) {\n --size: 32px;\n --_font-size: 0.875rem;\n}\n:host([size='lg']) {\n --size: 48px;\n --_font-size: 1.25rem;\n}\n:host([size='xl']) {\n --size: 56px;\n --_font-size: 1.25rem;\n}\n\nimg {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: inherit;\n}\n\n.initials {\n margin: auto;\n}\n\n.icon {\n width: 60%;\n height: 60%;\n color: currentColor;\n}\n\n.badge {\n position: absolute;\n bottom: 0;\n right: 0;\n z-index: 1;\n height: 12px;\n min-width: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: 2px;\n border-radius: 3px;\n box-shadow: 0 0 0 2px var(--l-color-surface);\n background-color: var(--l-color-surface);\n font-size: 0.625rem;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n line-height: 1;\n color: var(--l-color-text-primary);\n overflow: hidden;\n}\n\n/*\n * Inset ring via ::after so it renders on top of the <img>.\n * A box-shadow on :host would be covered by the image since\n * it fills the entire element with object-fit: cover.\n */\n.base::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 1px light-dark(oklch(0 0 0 / 7%), oklch(100% 0 0 / 10%));\n pointer-events: none;\n}\n\n.base {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n border: none;\n border-radius: calc(var(--size) * 0.15);\n background-color: var(--color, var(--l-color-bg-fill-neutral-soft));\n /*\n * Text over --color, decided by the background's own luminance — never the\n * document mode, since --color is consumer-set and ignores light/dark.\n * The contrast-color() block below is the primary path (Baseline 2026); this\n * --_on calc() is the fallback for browsers predating it (Chrome ≤146,\n * Safari <26, Firefox <146). It approximates WCAG relative luminance with\n * squared sRGB channels (a cheap linearization, Rec. 709 weights) and flips at\n * 0.2, just above the black/white crossover (~0.179) to offset squaring\n * underestimating mid-tones — holding AA across saturated brand colors where an\n * OKLCH-lightness threshold collapses to ≈1:1 (OKLCH L tracks hue, not\n * luminance: a mid red reads \"light\" yet needs white text). --text-color lets\n * consumers force a specific brand text color, overriding both paths.\n */\n --_on: calc(\n 255 *\n (\n 1 -\n sign(\n 0.2126 * (r / 255) * (r / 255) + 0.7152 * (g / 255) * (g / 255) + 0.0722 * (b / 255) *\n (b / 255) - 0.2\n )\n ) /\n 2\n );\n color: var(--text-color, rgb(from var(--color) var(--_on) var(--_on) var(--_on)));\n font-size: var(--_font-size);\n font-weight: 500;\n line-height: 1;\n text-transform: uppercase;\n padding: 0;\n cursor: inherit;\n}\n\n/* Primary path: native, guaranteed-contrast black/white. contrast-color() is\n * Baseline Newly Available (2026) — Safari 26+, Firefox 146+, Chrome/Edge 147+ —\n * and supersedes the luminance approximation above where supported. @supports (not\n * declaration order) is required: the value contains var(), so a non-supporting\n * browser would treat contrast-color() as invalid-at-computed-value-time and reset\n * to `inherit` rather than falling back to the calc() line. No bg fallback inside,\n * so a bare avatar (no --color) keeps inheriting --l-color-text-secondary.\n * --text-color still wins here, overriding contrast-color()'s choice.\n * (The earlier `… vs black, white to AA` extended syntax was dropped from the spec.) */\n@supports (color: contrast-color(red)) {\n .base {\n color: var(--text-color, contrast-color(var(--color)));\n }\n}\n\nbutton.base {\n cursor: pointer;\n}\n\nbutton.base:focus-visible {\n outline: 2px solid var(--l-focus-ring);\n outline-offset: 2px;\n}\n\nbutton.base:hover {\n box-shadow: inset 0 0 0 1.5px var(--l-color-border-interactive);\n}\n\n@container style(--appearance: circle) {\n .base {\n border-radius: 50%;\n }\n}\n","import { html, nothing, svg, unsafeCSS } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { html as staticHtml, literal } from 'lit/static-html.js';\nimport { property, state } from 'lit/decorators.js';\nimport hostStyles from '../../shared/styles/host.styles.js';\nimport rawStyles from './avatar.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * Extracts up to two uppercase initials from a name: the first letter of the\n * first word, plus the first letter of the last word when there is more than one.\n *\n * Splits on whitespace rather than relying on a `\\b`/`\\w` regex, which only\n * recognises ASCII and mangles accented or non-ASCII names.\n *\n * @param name - The name to extract initials from. Defaults to an empty string.\n * @return The uppercased initials, or an empty string when `name` is blank.\n *\n * @example getInitials('John Doe') // 'JD'\n * @example getInitials('Markus Nösterer') // 'MN' (accents preserved)\n * @example getInitials('Cher') // 'C' (single word → one initial)\n * @example getInitials(' John Doe ') // 'JD' (extra whitespace ignored)\n * @example getInitials('') // ''\n */\nfunction getInitials(name: string = ''): string {\n const words = name.normalize('NFC').trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) return '';\n\n // Spreading iterates by code point, so an accented letter (or an astral\n // character like an emoji) is taken whole instead of a broken half.\n // oxlint-disable-next-line typescript/no-misused-spread -- code-point-safe first char is the intent\n const firstLetter = (word: string) => [...word][0];\n\n const first = firstLetter(words[0]);\n const last = words.length > 1 ? firstLetter(words[words.length - 1]) : '';\n return (first + last).toUpperCase();\n}\n\nconst defaultIcon = svg`<svg class=\"icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z\" />\n</svg>`;\n\n/**\n * @summary An avatar component for displaying user images, initials, or a default icon.\n * @customElement l-avatar\n *\n * @cssproperty [--size=40px] - Box size (any length). Set it inline (e.g. `style=\"--size: 20px\"`) for an arbitrary size beyond the `size` token scale; the font then follows proportionally. The `size` attribute sets it to the matching token.\n * @cssproperty --color - Background fill color for initials and the default icon.\n * @cssproperty --text-color - Initials/icon color over `--color`. Defaults to an auto-derived readable color; set it to enforce a specific brand color (overrides the automatic choice).\n * @cssproperty --appearance - Set to `circle` for a fully circular avatar (default is a rounded square).\n *\n * @csspart base - The avatar container that paints `--color`; style it (e.g. `color`) to override the auto-derived text color.\n *\n * @cssClass .l-avatar-group - Flex wrapper that overlaps a row of stacked avatars.\n */\nexport class Avatar extends LuxenElement {\n static styles = [hostStyles, styles];\n\n /** Image URL. Falls back to initials (then the default icon) if it fails to load. */\n @property()\n src = '';\n\n /** Name used as the accessible label and to derive the initials fallback. */\n @property()\n name = '';\n\n /** Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`. */\n @property({ reflect: true })\n size = 'md';\n\n /** Count shown in the corner badge. `0` hides the badge. */\n @property({ type: Number })\n badge = 0;\n\n /** Render as a `<button>` with focus ring and hover states. */\n @property({ type: Boolean, reflect: true })\n interactive = false;\n\n @state() private _hasError = false;\n\n willUpdate(changed: Map<string, unknown>) {\n if (changed.has('src')) {\n this._hasError = false;\n }\n }\n\n connectedCallback() {\n super.connectedCallback();\n if (!this.interactive && !this.hasAttribute('role')) {\n this.setAttribute('role', 'img');\n }\n }\n\n updated() {\n // An interactive avatar renders a focusable <button>, and a role=\"img\" node\n // must stay a leaf in the accessibility tree — so the host carries no role\n // or label and the inner button holds the accessible name (see render()).\n if (this.interactive) {\n if (this.getAttribute('role') === 'img') this.removeAttribute('role');\n this.removeAttribute('aria-label');\n } else {\n if (!this.hasAttribute('role')) this.setAttribute('role', 'img');\n if (this.name) this.setAttribute('aria-label', this.name);\n }\n\n const isCircle = getComputedStyle(this).getPropertyValue('--appearance').trim() === 'circle';\n this.style.borderRadius = isCircle ? '50%' : '';\n }\n\n private get _tag() {\n return this.interactive ? literal`button` : literal`div`;\n }\n\n render() {\n const content =\n this.src && !this._hasError\n ? html`<img\n src=${this.src}\n alt=${this.name || ''}\n @error=${this._onError}\n />`\n : this.name\n ? html`<span class=\"initials\">${getInitials(this.name)}</span>`\n : html`<slot>${defaultIcon}</slot>`;\n\n return staticHtml`\n <${this._tag}\n class=\"base\"\n part=\"base\"\n type=${this.interactive ? 'button' : nothing}\n aria-label=${this.interactive && this.name ? this.name : nothing}\n >\n ${content}\n </${this._tag}>\n ${\n this.badge\n ? html`<div\n class=\"badge\"\n aria-hidden=\"true\"\n >\n ${this.badge}\n </div>`\n : nothing\n }\n `;\n }\n\n private _onError = () => {\n this._hasError = true;\n };\n}\n"],"mappings":"oUCOA,IAAM,EAAS,EAAU,4jEAAS,EAkBlC,SAAS,EAAY,EAAe,GAAY,CAC9C,IAAM,EAAQ,EAAK,UAAU,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO,EACtE,GAAI,EAAM,SAAW,EAAG,MAAO,GAK/B,IAAM,EAAe,GAAiB,CAAC,GAAG,CAAI,CAAC,CAAC,GAIhD,OAFc,EAAY,EAAM,EAExB,GADK,EAAM,OAAS,EAAI,EAAY,EAAM,EAAM,OAAS,EAAE,EAAI,IAAA,CACjD,YAAY,CACpC,CAEA,IAAM,EAAc,CAAG;;QAiBV,EAAb,cAA4B,CAAa,wCAKjC,aAIC,aAIA,gBAIC,mBAIM,kBAEe,qBAqEJ,CACvB,KAAK,UAAY,EACnB,qBA7FgB,CAAC,EAAY,CAAM,EAwBnC,WAAW,EAA+B,CACpC,EAAQ,IAAI,KAAK,IACnB,KAAK,UAAY,GAErB,CAEA,mBAAoB,CAClB,MAAM,kBAAkB,EACpB,CAAC,KAAK,aAAe,CAAC,KAAK,aAAa,MAAM,GAChD,KAAK,aAAa,OAAQ,KAAK,CAEnC,CAEA,SAAU,CAIJ,KAAK,aACH,KAAK,aAAa,MAAM,IAAM,OAAO,KAAK,gBAAgB,MAAM,EACpE,KAAK,gBAAgB,YAAY,IAE5B,KAAK,aAAa,MAAM,GAAG,KAAK,aAAa,OAAQ,KAAK,EAC3D,KAAK,MAAM,KAAK,aAAa,aAAc,KAAK,IAAI,GAG1D,IAAM,EAAW,iBAAiB,IAAI,CAAC,CAAC,iBAAiB,cAAc,CAAC,CAAC,KAAK,IAAM,SACpF,KAAK,MAAM,aAAe,EAAW,MAAQ,EAC/C,CAEA,IAAY,MAAO,CACjB,OAAO,KAAK,YAAc,CAAO,SAAW,CAAO,KACrD,CAEA,QAAS,CACP,IAAM,EACJ,KAAK,KAAO,CAAC,KAAK,UACd,CAAI;kBACI,KAAK,IAAI;kBACT,KAAK,MAAQ,GAAG;qBACb,KAAK,SAAS;cAEzB,KAAK,KACH,CAAI,0BAA0B,EAAY,KAAK,IAAI,EAAE,SACrD,CAAI,SAAS,EAAY,SAEjC,MAAO,EAAU;SACZ,KAAK,KAAK;;;eAGJ,KAAK,YAAc,SAAW,EAAQ;qBAChC,KAAK,aAAe,KAAK,KAAO,KAAK,KAAO,EAAQ;;UAE/D,EAAQ;UACR,KAAK,KAAK;QAEZ,KAAK,MACD,CAAI;;;;gBAIA,KAAK,MAAM;oBAEf,EACL;KAEL,CAKF,KA3FG,EAAS,CAAA,EAAA,EAAA,UAAA,MAAA,IAAA,EAAA,KAIT,EAAS,CAAA,EAAA,EAAA,UAAA,OAAA,IAAA,EAAA,KAIT,EAAS,CAAE,QAAS,EAAK,CAAC,CAAA,EAAA,EAAA,UAAA,OAAA,IAAA,EAAA,KAI1B,EAAS,CAAE,KAAM,MAAO,CAAC,CAAA,EAAA,EAAA,UAAA,QAAA,IAAA,EAAA,KAIzB,EAAS,CAAE,KAAM,QAAS,QAAS,EAAK,CAAC,CAAA,EAAA,EAAA,UAAA,cAAA,IAAA,EAAA,KAGzC,EAAM,CAAA,EAAA,EAAA,UAAA,YAAA,IAAA,EAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './segmented-control.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/html/elements/segmented-control/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{define as e}from"../../define.js";import{SegmentedControl as t}from"./segmented-control.js";e(`segmented-control`,t);
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/html/elements/segmented-control/index.ts"],"sourcesContent":["import { define } from '../../define.js';\nimport { SegmentedControl } from './segmented-control.js';\nexport * from './segmented-control.js';\ndefine('segmented-control', SegmentedControl);\n"],"mappings":"mGAGA,EAAO,oBAAqB,CAAgB"}
@@ -0,0 +1,80 @@
1
+ import { LuxenFormAssociatedElement } from '../../shared/luxen-form-associated-element.js';
2
+ export type SegmentedControlSize = 'sm' | 'md' | 'lg' | 'xl';
3
+ /** Fired when the selected segment changes. Bubbles; not composed. */
4
+ export declare class SegmentChangeEvent extends Event {
5
+ readonly value: string;
6
+ readonly index: number;
7
+ constructor(value: string, index: number);
8
+ }
9
+ interface SegmentedControlEventMap {
10
+ change: SegmentChangeEvent;
11
+ }
12
+ /**
13
+ * @summary A single-select segmented control: a compact, mutually-exclusive
14
+ * switch between a few options (radio-group semantics with a sliding pill).
15
+ * Progressively enhances light-DOM `<button>`s so it works before JS runs.
16
+ * Form-associated: give it a `name` and its selected `value` is submitted with
17
+ * the form (and restored on reset), like a native radio group.
18
+ *
19
+ * @example
20
+ * Mark the initially-selected segment with `aria-checked="true"` (or set
21
+ * `value` to its `value` attribute) so it is styled before the script upgrades
22
+ * the element.
23
+ * ```html
24
+ * <l-segmented-control label="Metric" value="cost">
25
+ * <button value="volume">Volume</button>
26
+ * <button value="cost" aria-checked="true">Cost</button>
27
+ * </l-segmented-control>
28
+ * ```
29
+ *
30
+ * @event change - Fired when the selected segment changes. Not cancelable. Bubbles. Properties: `value: string`, `index: number`.
31
+ *
32
+ * @cssproperty [--indicator-color=var(--l-color-surface)] - Background of the sliding pill behind the selected segment.
33
+ * @cssproperty [--border-radius=var(--l-radius-lg)] - Corner radius of the track.
34
+ *
35
+ * @customElement l-segmented-control
36
+ */
37
+ export declare class SegmentedControl extends LuxenFormAssociatedElement {
38
+ createRenderRoot(): this;
39
+ private _initialized;
40
+ private _setupTimer;
41
+ private _buttons;
42
+ private _resizeObserver;
43
+ /** Value of the selected segment (its `value` attribute, else its index). */
44
+ value: string;
45
+ /** Control height, aligned with buttons and form controls at the same size. */
46
+ size: SegmentedControlSize;
47
+ /** Accessible label announced for the group. Not displayed on screen. */
48
+ label?: string;
49
+ /** Stretch segments to fill the container width. */
50
+ fullWidth: boolean;
51
+ connectedCallback(): void;
52
+ disconnectedCallback(): void;
53
+ /** @returns true when setup ran or was already done; false to schedule a retry. */
54
+ private _trySetup;
55
+ updated(changed: Map<string, unknown>): void;
56
+ formResetCallback(): void;
57
+ formStateRestoreCallback(state: string, mode: 'restore' | 'autocomplete'): void;
58
+ private _setup;
59
+ private _teardown;
60
+ /** Resolve the selected index from `value`, else an authored `aria-checked`, else 0. */
61
+ private _resolveActiveIndex;
62
+ private _syncValueFromIndex;
63
+ private _select;
64
+ /** Index of the next non-disabled segment from `from`, moving by `dir`, wrapping. */
65
+ private _nextEnabled;
66
+ private _isDisabled;
67
+ /** Reflect the host `disabled` state onto the segments (aria + tab order). */
68
+ private _applyDisabledState;
69
+ private _updateIndicator;
70
+ private _onClick;
71
+ private _onKeyDown;
72
+ }
73
+ export interface SegmentedControl {
74
+ addEventListener<K extends keyof SegmentedControlEventMap>(type: K, listener: (this: SegmentedControl, ev: SegmentedControlEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
75
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
76
+ removeEventListener<K extends keyof SegmentedControlEventMap>(type: K, listener: (this: SegmentedControl, ev: SegmentedControlEventMap[K]) => void, options?: boolean | EventListenerOptions): void;
77
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
78
+ }
79
+ export {};
80
+ //# sourceMappingURL=segmented-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.d.ts","sourceRoot":"","sources":["../../../src/html/elements/segmented-control/segmented-control.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7D,sEAAsE;AACtE,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAKzC;AAED,UAAU,wBAAwB;IAChC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,qBAAa,gBAAiB,SAAQ,0BAA0B;IACrD,gBAAgB;IAIzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,eAAe,CAA+B;IAEtD,6EAA6E;IAE7E,KAAK,SAAM;IAEX,+EAA+E;IAE/E,IAAI,EAAE,oBAAoB,CAAQ;IAElC,yEAAyE;IAEzE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,oDAAoD;IAEpD,SAAS,UAAS;IAIT,iBAAiB;IAUjB,oBAAoB;IAM7B,mFAAmF;IACnF,OAAO,CAAC,SAAS;IAOR,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAsBrC,iBAAiB;IAMjB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,cAAc;IAOjF,OAAO,CAAC,MAAM;IAoDd,OAAO,CAAC,SAAS;IAUjB,wFAAwF;IACxF,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,OAAO;IAuBf,qFAAqF;IACrF,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,WAAW;IAInB,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,QAAQ,CAQd;IAKF,OAAO,CAAC,UAAU,CAkChB;CACH;AAQD,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,CAAC,SAAS,MAAM,wBAAwB,EACvD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,EAC3E,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;IACR,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;IACR,mBAAmB,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAC1D,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,EAC3E,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,GACvC,IAAI,CAAC;IACR,mBAAmB,CACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,GACvC,IAAI,CAAC;CACT"}
@@ -0,0 +1,2 @@
1
+ import{i as e,t}from"../../chunks/decorate.js";import{LuxenFormAssociatedElement as n}from"../../shared/luxen-form-associated-element.js";var r=class extends Event{constructor(e,t){super(`change`,{bubbles:!0,composed:!1,cancelable:!1}),this.value=e,this.index=t}},i=class extends n{constructor(...e){super(...e),this._initialized=!1,this._setupTimer=0,this._buttons=[],this._resizeObserver=null,this.value=``,this.size=`md`,this.fullWidth=!1,this._onClick=e=>{if(this.disabled)return;let t=e.target.closest(`button`);if(!t)return;let n=this._buttons.indexOf(t);n<0||this._isDisabled(t)||(this._select(n),t.focus())},this._onKeyDown=e=>{if(this.disabled)return;let t=e,n=e.target;if(n.getAttribute(`role`)!==`radio`)return;let r=this._buttons.indexOf(n);if(r<0)return;let i=r;switch(t.key){case`ArrowRight`:case`ArrowDown`:i=this._nextEnabled(r,1);break;case`ArrowLeft`:case`ArrowUp`:i=this._nextEnabled(r,-1);break;case`Home`:i=this._nextEnabled(-1,1);break;case`End`:i=this._nextEnabled(this._buttons.length,-1);break;case` `:break;default:return}e.preventDefault(),this._select(i),this._buttons[i].focus()}}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._trySetup()||(this._setupTimer=window.setTimeout(()=>this._trySetup(),0))}disconnectedCallback(){super.disconnectedCallback(),clearTimeout(this._setupTimer),this._teardown()}_trySetup(){return this._initialized||!this.isConnected?!0:this.querySelectorAll(`button`).length<2?!1:(this._setup(),!0)}updated(e){this._initialized&&(e.has(`value`)&&this._select(this._resolveActiveIndex(),!1),e.has(`size`)&&this._updateIndicator(),e.has(`label`)&&(this.label?this.setAttribute(`aria-label`,this.label):this.removeAttribute(`aria-label`)),e.has(`disabled`)&&this._applyDisabledState())}formResetCallback(){this.value=this._defaultFormValue,super.formResetCallback()}formStateRestoreCallback(e,t){this.value=e,super.formStateRestoreCallback(e,t)}_setup(){if(this._buttons=Array.from(this.querySelectorAll(`button`)),this._buttons.length<2)return;this._initialized=!0,this.setAttribute(`role`,`radiogroup`),this.label&&this.setAttribute(`aria-label`,this.label);let e=this._resolveActiveIndex();for(let t=0;t<this._buttons.length;t++){let n=this._buttons[t];n.type=`button`,n.setAttribute(`role`,`radio`),n.setAttribute(`aria-checked`,String(t===e)),n.setAttribute(`tabindex`,t===e?`0`:`-1`),(n.textContent??``).trim()===``&&(n.setAttribute(`data-icon-only`,``),!n.hasAttribute(`aria-label`)&&!n.hasAttribute(`aria-labelledby`)&&console.warn(`<${this.localName}>: icon-only segment #${t} has no accessible name; add aria-label.`))}this.addEventListener(`click`,this._onClick),this.addEventListener(`keydown`,this._onKeyDown),this._applyDisabledState(),this._syncValueFromIndex(e),this._defaultFormValue=this.value,this._syncFormValue(this.value),this._updateIndicator(),this._resizeObserver=new ResizeObserver(()=>this._updateIndicator()),this._resizeObserver.observe(this)}_teardown(){this.removeEventListener(`click`,this._onClick),this.removeEventListener(`keydown`,this._onKeyDown),this._resizeObserver?.disconnect(),this._resizeObserver=null,this._initialized=!1}_resolveActiveIndex(){let{_buttons:e}=this;if(this.value!==``){let t=e.findIndex(e=>(e.getAttribute(`value`)??``)===this.value);if(t>=0)return t;let n=Number(this.value);if(Number.isInteger(n)&&n>=0&&n<e.length)return n}let t=e.findIndex(e=>e.getAttribute(`aria-checked`)===`true`);if(t>=0)return t;let n=e.findIndex(e=>!this._isDisabled(e));return n>=0?n:0}_syncValueFromIndex(e){this.value=this._buttons[e]?.getAttribute(`value`)??String(e)}_select(e,t=!0){if(e<0||e>=this._buttons.length)return;let n=this._buttons[e].getAttribute(`aria-checked`)!==`true`;for(let t=0;t<this._buttons.length;t++){let n=t===e;this._buttons[t].setAttribute(`aria-checked`,String(n)),this._buttons[t].setAttribute(`tabindex`,n&&!this.disabled?`0`:`-1`)}this._syncValueFromIndex(e),this._syncFormValue(this.value),this._updateIndicator(),t&&n&&(this.hasInteracted=!0,this.dispatchEvent(new r(this.value,e)))}_nextEnabled(e,t){let n=this._buttons.length;for(let r=1;r<=n;r++){let i=(e+t*r+n*r)%n;if(!this._isDisabled(this._buttons[i]))return i}return e}_isDisabled(e){return e.disabled||e.getAttribute(`aria-disabled`)===`true`}_applyDisabledState(){for(let e of this._buttons)this.disabled?(e.setAttribute(`aria-disabled`,`true`),e.setAttribute(`tabindex`,`-1`)):(e.removeAttribute(`aria-disabled`),e.setAttribute(`tabindex`,e.getAttribute(`aria-checked`)===`true`?`0`:`-1`))}_updateIndicator(){let e=this._buttons.find(e=>e.getAttribute(`aria-checked`)===`true`);e&&(this.style.setProperty(`--_indicator-left`,`${e.offsetLeft}px`),this.style.setProperty(`--_indicator-width`,`${e.offsetWidth}px`))}};t([e({reflect:!0})],i.prototype,`value`,void 0),t([e({reflect:!0})],i.prototype,`size`,void 0),t([e({reflect:!0})],i.prototype,`label`,void 0),t([e({type:Boolean,reflect:!0,attribute:`full-width`})],i.prototype,`fullWidth`,void 0);export{r as SegmentChangeEvent,i as SegmentedControl};
2
+ //# sourceMappingURL=segmented-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.js","names":[],"sources":["../../../src/html/elements/segmented-control/segmented-control.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\nimport { LuxenFormAssociatedElement } from '../../shared/luxen-form-associated-element.js';\n\nexport type SegmentedControlSize = 'sm' | 'md' | 'lg' | 'xl';\n\n/** Fired when the selected segment changes. Bubbles; not composed. */\nexport class SegmentChangeEvent extends Event {\n readonly value: string;\n readonly index: number;\n constructor(value: string, index: number) {\n super('change', { bubbles: true, composed: false, cancelable: false });\n this.value = value;\n this.index = index;\n }\n}\n\ninterface SegmentedControlEventMap {\n change: SegmentChangeEvent;\n}\n\n/**\n * @summary A single-select segmented control: a compact, mutually-exclusive\n * switch between a few options (radio-group semantics with a sliding pill).\n * Progressively enhances light-DOM `<button>`s so it works before JS runs.\n * Form-associated: give it a `name` and its selected `value` is submitted with\n * the form (and restored on reset), like a native radio group.\n *\n * @example\n * Mark the initially-selected segment with `aria-checked=\"true\"` (or set\n * `value` to its `value` attribute) so it is styled before the script upgrades\n * the element.\n * ```html\n * <l-segmented-control label=\"Metric\" value=\"cost\">\n * <button value=\"volume\">Volume</button>\n * <button value=\"cost\" aria-checked=\"true\">Cost</button>\n * </l-segmented-control>\n * ```\n *\n * @event change - Fired when the selected segment changes. Not cancelable. Bubbles. Properties: `value: string`, `index: number`.\n *\n * @cssproperty [--indicator-color=var(--l-color-surface)] - Background of the sliding pill behind the selected segment.\n * @cssproperty [--border-radius=var(--l-radius-lg)] - Corner radius of the track.\n *\n * @customElement l-segmented-control\n */\n// oxlint-disable-next-line typescript/no-unsafe-declaration-merging -- typed addEventListener overloads merged below; no uninitialized properties.\nexport class SegmentedControl extends LuxenFormAssociatedElement {\n override createRenderRoot() {\n return this;\n }\n\n private _initialized = false;\n private _setupTimer = 0;\n private _buttons: HTMLButtonElement[] = [];\n private _resizeObserver: ResizeObserver | null = null;\n\n /** Value of the selected segment (its `value` attribute, else its index). */\n @property({ reflect: true })\n value = '';\n\n /** Control height, aligned with buttons and form controls at the same size. */\n @property({ reflect: true })\n size: SegmentedControlSize = 'md';\n\n /** Accessible label announced for the group. Not displayed on screen. */\n @property({ reflect: true })\n label?: string;\n\n /** Stretch segments to fill the container width. */\n @property({ type: Boolean, reflect: true, attribute: 'full-width' })\n fullWidth = false;\n\n // --- Lifecycle ---\n\n override connectedCallback() {\n super.connectedCallback();\n // Children may not be parsed yet when the element upgrades mid-parse: try\n // synchronously, then retry once on a macrotask. setTimeout, not rAF — rAF\n // is suspended in hidden documents, so the element would stay inert there.\n if (!this._trySetup()) {\n this._setupTimer = window.setTimeout(() => this._trySetup(), 0);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n clearTimeout(this._setupTimer);\n this._teardown();\n }\n\n /** @returns true when setup ran or was already done; false to schedule a retry. */\n private _trySetup(): boolean {\n if (this._initialized || !this.isConnected) return true;\n if (this.querySelectorAll('button').length < 2) return false;\n this._setup();\n return true;\n }\n\n override updated(changed: Map<string, unknown>) {\n if (!this._initialized) return;\n if (changed.has('value')) {\n this._select(this._resolveActiveIndex(), false);\n }\n if (changed.has('size')) {\n this._updateIndicator();\n }\n if (changed.has('label')) {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n } else {\n this.removeAttribute('aria-label');\n }\n }\n if (changed.has('disabled')) {\n this._applyDisabledState();\n }\n }\n\n // --- Form lifecycle ---\n\n override formResetCallback() {\n // Restoring `value` re-selects the default segment via `updated()`.\n this.value = this._defaultFormValue;\n super.formResetCallback();\n }\n\n override formStateRestoreCallback(state: string, mode: 'restore' | 'autocomplete') {\n this.value = state;\n super.formStateRestoreCallback(state, mode);\n }\n\n // --- Setup / Teardown ---\n\n private _setup() {\n this._buttons = Array.from(this.querySelectorAll('button'));\n if (this._buttons.length < 2) return;\n this._initialized = true;\n\n this.setAttribute('role', 'radiogroup');\n if (this.label) this.setAttribute('aria-label', this.label);\n\n const activeIndex = this._resolveActiveIndex();\n\n for (let i = 0; i < this._buttons.length; i++) {\n const btn = this._buttons[i];\n // Force type=button so a segment never submits the enclosing form.\n btn.type = 'button';\n btn.setAttribute('role', 'radio');\n btn.setAttribute('aria-checked', String(i === activeIndex));\n btn.setAttribute('tabindex', i === activeIndex ? '0' : '-1');\n\n // A segment with no visible text is icon-only: square it and require an\n // accessible name (the icon itself is decorative to assistive tech).\n if ((btn.textContent ?? '').trim() === '') {\n btn.setAttribute('data-icon-only', '');\n if (!btn.hasAttribute('aria-label') && !btn.hasAttribute('aria-labelledby')) {\n // eslint-disable-next-line no-console\n console.warn(\n `<${this.localName}>: icon-only segment #${i} has no accessible name; add aria-label.`,\n );\n }\n }\n }\n\n this.addEventListener('click', this._onClick);\n this.addEventListener('keydown', this._onKeyDown);\n\n // Reflect a whole-control `disabled` onto the segments (aria + tab order).\n this._applyDisabledState();\n\n // Canonicalize `value` to the active segment now that roles are set, and\n // seed the form value (the value a form reset restores to).\n this._syncValueFromIndex(activeIndex);\n this._defaultFormValue = this.value;\n this._syncFormValue(this.value);\n\n // Initial pill position. Synchronous first (offset reads force layout),\n // then a ResizeObserver keeps it correct across hidden→visible transitions\n // and size changes — rAF is suspended in hidden documents, so it must not\n // be the only scheduling mechanism.\n this._updateIndicator();\n this._resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this._resizeObserver.observe(this);\n }\n\n private _teardown() {\n this.removeEventListener('click', this._onClick);\n this.removeEventListener('keydown', this._onKeyDown);\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._initialized = false;\n }\n\n // --- Selection ---\n\n /** Resolve the selected index from `value`, else an authored `aria-checked`, else 0. */\n private _resolveActiveIndex(): number {\n const { _buttons } = this;\n if (this.value !== '') {\n const byValue = _buttons.findIndex((b) => (b.getAttribute('value') ?? '') === this.value);\n if (byValue >= 0) return byValue;\n const asIndex = Number(this.value);\n if (Number.isInteger(asIndex) && asIndex >= 0 && asIndex < _buttons.length) return asIndex;\n }\n const checked = _buttons.findIndex((b) => b.getAttribute('aria-checked') === 'true');\n if (checked >= 0) return checked;\n // No explicit selection: default to the first enabled segment (else 0).\n const firstEnabled = _buttons.findIndex((b) => !this._isDisabled(b));\n return firstEnabled >= 0 ? firstEnabled : 0;\n }\n\n private _syncValueFromIndex(index: number) {\n this.value = this._buttons[index]?.getAttribute('value') ?? String(index);\n }\n\n private _select(index: number, emitEvent = true) {\n if (index < 0 || index >= this._buttons.length) return;\n // Whether this is an actual change — re-selecting the current segment must\n // not re-fire `change` (matches native radio / `<select>`).\n const changed = this._buttons[index].getAttribute('aria-checked') !== 'true';\n\n for (let i = 0; i < this._buttons.length; i++) {\n const isActive = i === index;\n this._buttons[i].setAttribute('aria-checked', String(isActive));\n // Disabled control keeps every segment out of the tab order.\n this._buttons[i].setAttribute('tabindex', isActive && !this.disabled ? '0' : '-1');\n }\n\n this._syncValueFromIndex(index);\n this._syncFormValue(this.value);\n this._updateIndicator();\n\n if (emitEvent && changed) {\n this.hasInteracted = true;\n this.dispatchEvent(new SegmentChangeEvent(this.value, index));\n }\n }\n\n /** Index of the next non-disabled segment from `from`, moving by `dir`, wrapping. */\n private _nextEnabled(from: number, dir: 1 | -1): number {\n const len = this._buttons.length;\n for (let step = 1; step <= len; step++) {\n const i = (from + dir * step + len * step) % len;\n if (!this._isDisabled(this._buttons[i])) return i;\n }\n return from;\n }\n\n private _isDisabled(btn: HTMLButtonElement): boolean {\n return btn.disabled || btn.getAttribute('aria-disabled') === 'true';\n }\n\n /** Reflect the host `disabled` state onto the segments (aria + tab order). */\n private _applyDisabledState() {\n for (const btn of this._buttons) {\n if (this.disabled) {\n btn.setAttribute('aria-disabled', 'true');\n btn.setAttribute('tabindex', '-1');\n } else {\n btn.removeAttribute('aria-disabled');\n // Restore the roving tabindex (only the selected segment is tabbable).\n btn.setAttribute('tabindex', btn.getAttribute('aria-checked') === 'true' ? '0' : '-1');\n }\n }\n }\n\n // --- Indicator ---\n\n private _updateIndicator() {\n const active = this._buttons.find((b) => b.getAttribute('aria-checked') === 'true');\n if (!active) return;\n this.style.setProperty('--_indicator-left', `${active.offsetLeft}px`);\n this.style.setProperty('--_indicator-width', `${active.offsetWidth}px`);\n }\n\n // --- Event handlers ---\n\n private _onClick = (e: Event) => {\n if (this.disabled) return;\n const btn = (e.target as HTMLElement).closest<HTMLButtonElement>('button');\n if (!btn) return;\n const index = this._buttons.indexOf(btn);\n if (index < 0 || this._isDisabled(btn)) return;\n this._select(index);\n btn.focus();\n };\n\n // Typed `Event` (not `KeyboardEvent`): the listener is attached to `this`,\n // whose merged addEventListener overloads (see the interface below) fall back\n // to the platform `EventListener` signature for non-map events like `keydown`.\n private _onKeyDown = (e: Event) => {\n if (this.disabled) return;\n const ke = e as KeyboardEvent;\n const target = e.target as HTMLElement;\n if (target.getAttribute('role') !== 'radio') return;\n\n const current = this._buttons.indexOf(target as HTMLButtonElement);\n if (current < 0) return;\n\n let next = current;\n switch (ke.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n next = this._nextEnabled(current, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n next = this._nextEnabled(current, -1);\n break;\n case 'Home':\n next = this._nextEnabled(-1, 1);\n break;\n case 'End':\n next = this._nextEnabled(this._buttons.length, -1);\n break;\n case ' ':\n // Space (re)selects the focused segment (APG radio group).\n break;\n default:\n return;\n }\n e.preventDefault();\n this._select(next);\n this._buttons[next].focus();\n };\n}\n\n// Type `addEventListener('change', …)` so listeners receive a `SegmentChangeEvent`\n// (with `.value`/`.index`) instead of a bare `Event`. `change` collides with\n// lib.dom's `GlobalEventHandlersEventMap`, so it can't be augmented globally —\n// the overloads are declaration-merged onto this element's interface instead.\n// The interface MUST come after the class (the CEM analyzer dedups on the first\n// declaration of the name). See `tabs.ts` for the fully-annotated reference.\nexport interface SegmentedControl {\n addEventListener<K extends keyof SegmentedControlEventMap>(\n type: K,\n listener: (this: SegmentedControl, ev: SegmentedControlEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener<K extends keyof SegmentedControlEventMap>(\n type: K,\n listener: (this: SegmentedControl, ev: SegmentedControlEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/html/elements/tooltip/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAoBlD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,OAAQ,SAAQ,YAAY;IACvC,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,SAAS,CAId;IAEH,yDAAyD;IAEzD,QAAQ,CAAC,GAAG,SAAM;IAElB,8CAA8C;IAE9C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAS;IAEtC,sDAAsD;IAEtD,QAAQ,CAAC,QAAQ,SAAK;IAEtB;;;OAGG;IAEH,QAAQ,CAAC,SAAS,SAAK;IAEvB;;;;OAIG;IAEH,QAAQ,CAAC,SAAS,SAAK;IAEvB,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,UAAU,CAAC,CAAgC;IAEnD,6CAA6C;IAE7C,QAAQ,CAAC,IAAI,UAAS;IAEtB,kCAAkC;IAElC,QAAQ,CAAC,YAAY,UAAS;IAE9B,kFAAkF;IAElF,QAAQ,CAAC,OAAO,SAAiB;IAEjC,OAAO,CAAC,WAAW;IAInB,OAAO,KAAK,QAAQ,GAQnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,YAAY;IAKX,iBAAiB;IAMjB,oBAAoB;IAQpB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IAY9C,sFAAsF;IACtF,OAAO,CAAC,YAAY;IAOpB,IAAI;IAIJ,IAAI;IAIJ,MAAM;YAIQ,iBAAiB;IAgC/B,OAAO,CAAC,eAAe,CAwBrB;IAEF,OAAO,CAAC,eAAe,CAarB;IAEF,gFAAgF;IAChF,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU,CAOhB;IACF,OAAO,CAAC,WAAW,CAOjB;IACF,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,uBAAuB;IAOtB,MAAM;CAoBhB"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../src/html/elements/tooltip/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAoBlD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,OAAQ,SAAQ,YAAY;IACvC,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,SAAS,CAId;IAEH,yDAAyD;IAEzD,QAAQ,CAAC,GAAG,SAAM;IAElB,8CAA8C;IAE9C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAS;IAEtC,sDAAsD;IAEtD,QAAQ,CAAC,QAAQ,SAAK;IAEtB;;;OAGG;IAEH,QAAQ,CAAC,SAAS,SAAK;IAEvB;;;;OAIG;IAEH,QAAQ,CAAC,SAAS,SAAK;IAEvB,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,UAAU,CAAC,CAAgC;IAEnD,6CAA6C;IAE7C,QAAQ,CAAC,IAAI,UAAS;IAEtB,kCAAkC;IAElC,QAAQ,CAAC,YAAY,UAAS;IAE9B,kFAAkF;IAElF,QAAQ,CAAC,OAAO,SAAiB;IAEjC,OAAO,CAAC,WAAW;IAInB,OAAO,KAAK,QAAQ,GAQnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,YAAY;IAKX,iBAAiB;IAMjB,oBAAoB;IAQpB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IAY9C,sFAAsF;IACtF,OAAO,CAAC,YAAY;IAOpB,IAAI;IAIJ,IAAI;IAIJ,MAAM;YAIQ,iBAAiB;IAgC/B,OAAO,CAAC,eAAe,CAwBrB;IAEF,OAAO,CAAC,eAAe,CAarB;IAEF,gFAAgF;IAChF,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU,CAYhB;IACF,OAAO,CAAC,WAAW,CAOjB;IACF,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,uBAAuB;IAOtB,MAAM;CAoBhB"}