luxen-ui 0.10.0 → 0.11.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 (37) hide show
  1. package/cdn/custom-elements.json +97 -97
  2. package/cdn/elements/tooltip/tooltip.d.ts +1 -1
  3. package/cdn/elements/tooltip/tooltip.js +1 -1
  4. package/cdn/elements/tooltip/tooltip.js.map +1 -1
  5. package/cdn/standalone.css +12 -0
  6. package/cdn/standalone.js +2 -2
  7. package/cdn/standalone.js.map +1 -1
  8. package/cdn/styles/preset.css +12 -0
  9. package/cdn/styles/tokens.css +12 -0
  10. package/dist/css/preset.css +12 -0
  11. package/dist/css/tokens.css +12 -0
  12. package/dist/custom-elements.json +97 -97
  13. package/dist/elements/tooltip/tooltip.css +1 -1
  14. package/dist/elements/tooltip/tooltip.d.ts +1 -1
  15. package/dist/elements/tooltip/tooltip.js +1 -1
  16. package/dist/metadata/index.json +2 -2
  17. package/dist/metadata/tooltip.json +1 -1
  18. package/dist/templates/elements/carousel.md +653 -0
  19. package/dist/templates/elements/disclosure.md +171 -0
  20. package/dist/templates/elements/divider.md +95 -0
  21. package/dist/templates/elements/dropdown.md +375 -0
  22. package/dist/templates/elements/icon.md +104 -0
  23. package/dist/templates/elements/input-otp.md +191 -0
  24. package/dist/templates/elements/input-stepper.md +214 -0
  25. package/dist/templates/elements/kbd.md +55 -0
  26. package/dist/templates/elements/popover.md +391 -0
  27. package/dist/templates/elements/rating.md +262 -0
  28. package/dist/templates/elements/skeleton.md +112 -0
  29. package/dist/templates/elements/spinner.md +63 -0
  30. package/dist/templates/elements/stories-viewer.md +102 -0
  31. package/dist/templates/elements/stories.md +281 -0
  32. package/dist/templates/elements/story.md +59 -0
  33. package/dist/templates/elements/tabs.md +139 -0
  34. package/dist/templates/elements/tooltip.md +397 -0
  35. package/dist/templates/elements/tree-item.md +71 -0
  36. package/elements.json +18 -18
  37. package/package.json +1 -1
@@ -1200,93 +1200,85 @@
1200
1200
  },
1201
1201
  {
1202
1202
  "kind": "javascript-module",
1203
- "path": "src/html/elements/checkbox/checkbox.meta.ts",
1203
+ "path": "src/html/elements/close-button/close-button.meta.ts",
1204
1204
  "declarations": [
1205
1205
  {
1206
1206
  "kind": "class",
1207
1207
  "description": "",
1208
- "name": "CheckboxMeta",
1208
+ "name": "CloseButtonMeta",
1209
1209
  "cssProperties": [
1210
1210
  {
1211
- "description": "Box size. Defaults to `--l-form-control-toggle-size`.",
1211
+ "description": "Button size.",
1212
1212
  "name": "--size",
1213
- "default": "1.25em"
1213
+ "default": "36px"
1214
1214
  },
1215
1215
  {
1216
- "description": "Checked/indeterminate fill color.",
1217
- "name": "--accent",
1218
- "default": "var(--l-form-control-activated-color)"
1216
+ "description": "Icon color.",
1217
+ "name": "--icon-color"
1219
1218
  },
1220
1219
  {
1221
- "description": "Checkmark icon as a `url()`. Override to swap the SVG (color is baked into the image).",
1222
- "name": "--checkmark"
1223
- }
1224
- ],
1225
- "attributes": [
1226
- {
1227
- "description": "Whether the checkbox is checked.",
1228
- "name": "checked"
1220
+ "description": "Icon size.",
1221
+ "name": "--icon-size",
1222
+ "default": "24px"
1229
1223
  },
1230
1224
  {
1231
- "description": "Disables the checkbox.",
1232
- "name": "disabled"
1225
+ "description": "Hover ring color (`ring` appearance only).",
1226
+ "name": "--ring-color"
1233
1227
  },
1234
1228
  {
1235
- "description": "Marks the checkbox as required for form submission.",
1236
- "name": "required"
1229
+ "description": "Hover ring thickness (`ring` appearance only).",
1230
+ "name": "--ring-tickness"
1231
+ }
1232
+ ],
1233
+ "attributes": [
1234
+ {
1235
+ "description": "ring | square | circle — Visual appearance (matches the imported appearance CSS).",
1236
+ "name": "data-appearance"
1237
1237
  },
1238
1238
  {
1239
- "description": "Indeterminate state (DOM property `el.indeterminate = true`; renders a dash). Typically the parent of a group.",
1240
- "name": "indeterminate"
1239
+ "description": "Invoker command (typically `close`).",
1240
+ "name": "command"
1241
1241
  },
1242
1242
  {
1243
- "description": "Set to `true` to force the invalid style (otherwise applied via `:user-invalid`). `l-form-field` manages this automatically.",
1244
- "name": "aria-invalid"
1243
+ "description": "ID of the target element to close.",
1244
+ "name": "commandfor"
1245
1245
  }
1246
1246
  ],
1247
- "summary": "Checkboxes let users select one or more options, or toggle a single setting on or off.",
1247
+ "summary": "A circular/square icon button that renders an X via CSS mask, for dismissing dialogs and panels.",
1248
1248
  "examples": [
1249
1249
  {
1250
- "title": "Default",
1251
- "language": "html",
1252
- "code": "<input type=\"checkbox\" class=\"l-checkbox\" checked />"
1253
- },
1254
- {
1255
- "title": "In a field (no class needed)",
1250
+ "title": "Ring appearance",
1256
1251
  "language": "html",
1257
- "code": "<l-form-field>\n<label>Subscribe to the newsletter</label>\n<input type=\"checkbox\" />\n<l-hint>One email a month.</l-hint>\n</l-form-field>"
1252
+ "code": "<button class=\"l-close\" data-appearance=\"ring\" aria-label=\"Close\"></button>"
1258
1253
  }
1259
1254
  ],
1260
1255
  "_cssClasses": [
1261
1256
  {
1262
- "name": ".l-checkbox",
1263
- "description": "Base checkbox style, applied to `<input type=\"checkbox\">`. Inside `l-form-field` a bare checkbox is auto-styled, so the class is optional there."
1257
+ "name": ".l-close",
1258
+ "description": "Base close button with X icon via CSS mask."
1264
1259
  }
1265
1260
  ],
1266
1261
  "customElement": false,
1267
1262
  "_native": true,
1268
- "_nativeTag": "input",
1269
- "selector": ".l-checkbox",
1263
+ "_nativeTag": "button",
1264
+ "selector": ".l-close",
1270
1265
  "_attributes": [
1271
1266
  {
1272
- "name": "checked",
1273
- "description": "Whether the checkbox is checked."
1274
- },
1275
- {
1276
- "name": "disabled",
1277
- "description": "Disables the checkbox."
1278
- },
1279
- {
1280
- "name": "required",
1281
- "description": "Marks the checkbox as required for form submission."
1267
+ "name": "data-appearance",
1268
+ "values": [
1269
+ "ring",
1270
+ "square",
1271
+ "circle"
1272
+ ],
1273
+ "description": "Visual appearance (matches the imported appearance CSS)."
1282
1274
  },
1283
1275
  {
1284
- "name": "indeterminate",
1285
- "description": "Indeterminate state (DOM property `el.indeterminate = true`; renders a dash). Typically the parent of a group."
1276
+ "name": "command",
1277
+ "description": "Invoker command (typically `close`)."
1286
1278
  },
1287
1279
  {
1288
- "name": "aria-invalid",
1289
- "description": "Set to `true` to force the invalid style (otherwise applied via `:user-invalid`). `l-form-field` manages this automatically."
1280
+ "name": "commandfor",
1281
+ "description": "ID of the target element to close."
1290
1282
  }
1291
1283
  ]
1292
1284
  }
@@ -1294,95 +1286,103 @@
1294
1286
  "exports": [
1295
1287
  {
1296
1288
  "kind": "js",
1297
- "name": "CheckboxMeta",
1289
+ "name": "CloseButtonMeta",
1298
1290
  "declaration": {
1299
- "name": "CheckboxMeta",
1300
- "module": "src/html/elements/checkbox/checkbox.meta.ts"
1291
+ "name": "CloseButtonMeta",
1292
+ "module": "src/html/elements/close-button/close-button.meta.ts"
1301
1293
  }
1302
1294
  }
1303
1295
  ]
1304
1296
  },
1305
1297
  {
1306
1298
  "kind": "javascript-module",
1307
- "path": "src/html/elements/close-button/close-button.meta.ts",
1299
+ "path": "src/html/elements/checkbox/checkbox.meta.ts",
1308
1300
  "declarations": [
1309
1301
  {
1310
1302
  "kind": "class",
1311
1303
  "description": "",
1312
- "name": "CloseButtonMeta",
1304
+ "name": "CheckboxMeta",
1313
1305
  "cssProperties": [
1314
1306
  {
1315
- "description": "Button size.",
1307
+ "description": "Box size. Defaults to `--l-form-control-toggle-size`.",
1316
1308
  "name": "--size",
1317
- "default": "36px"
1318
- },
1319
- {
1320
- "description": "Icon color.",
1321
- "name": "--icon-color"
1322
- },
1323
- {
1324
- "description": "Icon size.",
1325
- "name": "--icon-size",
1326
- "default": "24px"
1309
+ "default": "1.25em"
1327
1310
  },
1328
1311
  {
1329
- "description": "Hover ring color (`ring` appearance only).",
1330
- "name": "--ring-color"
1312
+ "description": "Checked/indeterminate fill color.",
1313
+ "name": "--accent",
1314
+ "default": "var(--l-form-control-activated-color)"
1331
1315
  },
1332
1316
  {
1333
- "description": "Hover ring thickness (`ring` appearance only).",
1334
- "name": "--ring-tickness"
1317
+ "description": "Checkmark icon as a `url()`. Override to swap the SVG (color is baked into the image).",
1318
+ "name": "--checkmark"
1335
1319
  }
1336
1320
  ],
1337
1321
  "attributes": [
1338
1322
  {
1339
- "description": "ring | square | circle — Visual appearance (matches the imported appearance CSS).",
1340
- "name": "data-appearance"
1323
+ "description": "Whether the checkbox is checked.",
1324
+ "name": "checked"
1341
1325
  },
1342
1326
  {
1343
- "description": "Invoker command (typically `close`).",
1344
- "name": "command"
1327
+ "description": "Disables the checkbox.",
1328
+ "name": "disabled"
1345
1329
  },
1346
1330
  {
1347
- "description": "ID of the target element to close.",
1348
- "name": "commandfor"
1331
+ "description": "Marks the checkbox as required for form submission.",
1332
+ "name": "required"
1333
+ },
1334
+ {
1335
+ "description": "Indeterminate state (DOM property `el.indeterminate = true`; renders a dash). Typically the parent of a group.",
1336
+ "name": "indeterminate"
1337
+ },
1338
+ {
1339
+ "description": "Set to `true` to force the invalid style (otherwise applied via `:user-invalid`). `l-form-field` manages this automatically.",
1340
+ "name": "aria-invalid"
1349
1341
  }
1350
1342
  ],
1351
- "summary": "A circular/square icon button that renders an X via CSS mask, for dismissing dialogs and panels.",
1343
+ "summary": "Checkboxes let users select one or more options, or toggle a single setting on or off.",
1352
1344
  "examples": [
1353
1345
  {
1354
- "title": "Ring appearance",
1346
+ "title": "Default",
1355
1347
  "language": "html",
1356
- "code": "<button class=\"l-close\" data-appearance=\"ring\" aria-label=\"Close\"></button>"
1348
+ "code": "<input type=\"checkbox\" class=\"l-checkbox\" checked />"
1349
+ },
1350
+ {
1351
+ "title": "In a field (no class needed)",
1352
+ "language": "html",
1353
+ "code": "<l-form-field>\n<label>Subscribe to the newsletter</label>\n<input type=\"checkbox\" />\n<l-hint>One email a month.</l-hint>\n</l-form-field>"
1357
1354
  }
1358
1355
  ],
1359
1356
  "_cssClasses": [
1360
1357
  {
1361
- "name": ".l-close",
1362
- "description": "Base close button with X icon via CSS mask."
1358
+ "name": ".l-checkbox",
1359
+ "description": "Base checkbox style, applied to `<input type=\"checkbox\">`. Inside `l-form-field` a bare checkbox is auto-styled, so the class is optional there."
1363
1360
  }
1364
1361
  ],
1365
1362
  "customElement": false,
1366
1363
  "_native": true,
1367
- "_nativeTag": "button",
1368
- "selector": ".l-close",
1364
+ "_nativeTag": "input",
1365
+ "selector": ".l-checkbox",
1369
1366
  "_attributes": [
1370
1367
  {
1371
- "name": "data-appearance",
1372
- "values": [
1373
- "ring",
1374
- "square",
1375
- "circle"
1376
- ],
1377
- "description": "Visual appearance (matches the imported appearance CSS)."
1368
+ "name": "checked",
1369
+ "description": "Whether the checkbox is checked."
1378
1370
  },
1379
1371
  {
1380
- "name": "command",
1381
- "description": "Invoker command (typically `close`)."
1372
+ "name": "disabled",
1373
+ "description": "Disables the checkbox."
1382
1374
  },
1383
1375
  {
1384
- "name": "commandfor",
1385
- "description": "ID of the target element to close."
1376
+ "name": "required",
1377
+ "description": "Marks the checkbox as required for form submission."
1378
+ },
1379
+ {
1380
+ "name": "indeterminate",
1381
+ "description": "Indeterminate state (DOM property `el.indeterminate = true`; renders a dash). Typically the parent of a group."
1382
+ },
1383
+ {
1384
+ "name": "aria-invalid",
1385
+ "description": "Set to `true` to force the invalid style (otherwise applied via `:user-invalid`). `l-form-field` manages this automatically."
1386
1386
  }
1387
1387
  ]
1388
1388
  }
@@ -1390,10 +1390,10 @@
1390
1390
  "exports": [
1391
1391
  {
1392
1392
  "kind": "js",
1393
- "name": "CloseButtonMeta",
1393
+ "name": "CheckboxMeta",
1394
1394
  "declaration": {
1395
- "name": "CloseButtonMeta",
1396
- "module": "src/html/elements/close-button/close-button.meta.ts"
1395
+ "name": "CheckboxMeta",
1396
+ "module": "src/html/elements/checkbox/checkbox.meta.ts"
1397
1397
  }
1398
1398
  }
1399
1399
  ]
@@ -5847,7 +5847,7 @@
5847
5847
  "name": "Tooltip",
5848
5848
  "cssProperties": [
5849
5849
  {
5850
- "description": "Background color. Default: dark in light mode, light in dark mode.",
5850
+ "description": "Background color for this tooltip instance. Defaults to the global `--l-tooltip-background-color` token (a neutral inverse surface, dark in light mode / light in dark mode) — override that token to re-skin every tooltip at once.",
5851
5851
  "name": "--background-color"
5852
5852
  },
5853
5853
  {
@@ -10,7 +10,7 @@ import { Placement } from '@floating-ui/dom';
10
10
  * @csspart body - The tooltip popover container.
11
11
  * @csspart arrow - The directional arrow element.
12
12
  *
13
- * @cssproperty --background-color - Background color. Default: dark in light mode, light in dark mode.
13
+ * @cssproperty --background-color - Background color for this tooltip instance. Defaults to the global `--l-tooltip-background-color` token (a neutral inverse surface, dark in light mode / light in dark mode) — override that token to re-skin every tooltip at once.
14
14
  * @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.
15
15
  * @cssproperty --border-radius - Border radius. Default `4px`.
16
16
  * @cssproperty --max-width - Maximum width. Default `180px`.
@@ -1,4 +1,4 @@
1
- import{uniqueId as e}from"../../registry.js";import{i as t}from"../../chunks/lit.js";import{a as n,t as r}from"../../chunks/lit-html.js";import{LuxenElement as i}from"../../shared/luxen-element.js";import{i as a,t as o}from"../../chunks/decorate.js";import s from"../../shared/styles/host.styles.js";import{PopoverController as c}from"../../shared/controllers/popover.js";var l=t(`:host{--background-color:var(--l-color-bg-fill-brand,var(--lightningcss-light,#1f2937)var(--lightningcss-dark,#f9fafb));--border-radius:4px;--max-width:180px;--arrow-size:6px;--show-duration:.15s;--hide-duration:.15s;display:contents}[popover]{inset:unset;box-sizing:border-box;width:max-content;max-width:var(--max-width);border-radius:var(--border-radius);background:var(--background-color);color:var(--text-color,oklch(from var(--background-color) calc(.59 - .41 * sign(l - .5)) 0 0));filter:drop-shadow(0 1px 2px #00000029);pointer-events:none;border:0;padding:4px 8px;font-size:.8125rem;line-height:1.4;overflow:visible}@supports (color:contrast-color(red vs black, white)){[popover]{color:var(--text-color,contrast-color(var(--background-color) vs #111827, #fff to AA))}}i{width:var(--arrow-size);height:var(--arrow-size);background:var(--background-color);display:block;position:absolute;transform:rotate(45deg)}`),u=class extends i{constructor(...t){super(...t),this._tooltipId=e(`tooltip`),this._floating=new c(this,{getTriggerElement:()=>this._trigger,getFloatingElement:()=>this._popover,getArrowElement:()=>this._arrowEl}),this.#e=``,this.#t=`top`,this.#n=8,this.#r=!1,this.#i=!1,this.#a=`hover focus`,this._onPointerEnter=()=>{this._hasTrigger(`hover`)&&(this._floating.cleanupSafePolygon(),this.show())},this._onPointerLeave=e=>{!this._hasTrigger(`hover`)||!this.open||this._floating.handlePointerLeave(e,()=>this.hide())},this._onFocusIn=()=>{this._hasTrigger(`focus`)&&this.show()},this._onFocusOut=()=>{this._hasTrigger(`focus`)&&this.hide()},this._onClick=()=>{this._hasTrigger(`click`)&&this.toggle()},this._onKeyDown=e=>{this.open&&e.key===`Escape`&&(e.stopPropagation(),this.hide())}}static{this.styles=[s,l]}#e;get for(){return this.#e}set for(e){this.#e=e}#t;get placement(){return this.#t}set placement(e){this.#t=e}#n;get distance(){return this.#n}set distance(e){this.#n=e}#r;get open(){return this.#r}set open(e){this.#r=e}#i;get withoutArrow(){return this.#i}set withoutArrow(e){this.#i=e}#a;get trigger(){return this.#a}set trigger(e){this.#a=e}_hasTrigger(e){return this.trigger.split(` `).includes(e)}get _trigger(){return this.for?this.getRootNode().getElementById(this.for):null}get _popover(){return this.shadowRoot.querySelector(`[popover]`)}get _arrowEl(){return this.withoutArrow?null:this.shadowRoot.querySelector(`i`)}_getDuration(e){let t=parseFloat(getComputedStyle(this).getPropertyValue(e));return Number.isNaN(t)?150:t}connectedCallback(){super.connectedCallback(),requestAnimationFrame(()=>this._addTriggerListeners())}disconnectedCallback(){super.disconnectedCallback(),this._removeTriggerListeners()}updated(e){e.has(`open`)&&this._handleOpenChange(),e.has(`for`)&&(this._removeTriggerListeners(e.get(`for`)),this._addTriggerListeners())}show(){this.open||=!0}hide(){this.open&&=!1}toggle(){this.open=!this.open}async _handleOpenChange(){let e=this._popover;if(!e)return;let t={placement:this.placement,distance:this.distance};if(this.open){if(e.showPopover(),await this._floating.updatePosition(t),!this.open)return;await this._floating.animateShow(e,this._getDuration(`--show-duration`)),this._floating.startPositioning(t),this._trigger?.setAttribute(`aria-describedby`,this._tooltipId)}else this._floating.stopPositioning(),this._floating.cleanupSafePolygon(),this._trigger?.removeAttribute(`aria-describedby`),await this._floating.animateHide(e,this._getDuration(`--hide-duration`)),e.matches(`:popover-open`)&&e.hidePopover()}_addTriggerListeners(){this._floating.addTriggerListeners({onPointerEnter:this._onPointerEnter,onPointerLeave:this._onPointerLeave,onFocusIn:this._onFocusIn,onFocusOut:this._onFocusOut,onClick:this._onClick,onKeyDown:this._onKeyDown})}_removeTriggerListeners(e){let t=e?this.getRootNode().getElementById(e):void 0;this._floating.removeTriggerListeners(t)}render(){return n`
1
+ import{uniqueId as e}from"../../registry.js";import{i as t}from"../../chunks/lit.js";import{a as n,t as r}from"../../chunks/lit-html.js";import{LuxenElement as i}from"../../shared/luxen-element.js";import{i as a,t as o}from"../../chunks/decorate.js";import s from"../../shared/styles/host.styles.js";import{PopoverController as c}from"../../shared/controllers/popover.js";var l=t(`:host{--background-color:var(--l-tooltip-background-color,var(--lightningcss-light,#1f2937)var(--lightningcss-dark,#f9fafb));--border-radius:4px;--max-width:180px;--arrow-size:6px;--show-duration:.15s;--hide-duration:.15s;display:contents}[popover]{inset:unset;box-sizing:border-box;width:max-content;max-width:var(--max-width);border-radius:var(--border-radius);background:var(--background-color);color:var(--text-color,oklch(from var(--background-color) calc(.59 - .41 * sign(l - .5)) 0 0));filter:drop-shadow(0 1px 2px #00000029);pointer-events:none;border:0;padding:4px 8px;font-size:.8125rem;line-height:1.4;overflow:visible}@supports (color:contrast-color(red vs black, white)){[popover]{color:var(--text-color,contrast-color(var(--background-color) vs #111827, #fff to AA))}}i{width:var(--arrow-size);height:var(--arrow-size);background:var(--background-color);display:block;position:absolute;transform:rotate(45deg)}`),u=class extends i{constructor(...t){super(...t),this._tooltipId=e(`tooltip`),this._floating=new c(this,{getTriggerElement:()=>this._trigger,getFloatingElement:()=>this._popover,getArrowElement:()=>this._arrowEl}),this.#e=``,this.#t=`top`,this.#n=8,this.#r=!1,this.#i=!1,this.#a=`hover focus`,this._onPointerEnter=()=>{this._hasTrigger(`hover`)&&(this._floating.cleanupSafePolygon(),this.show())},this._onPointerLeave=e=>{!this._hasTrigger(`hover`)||!this.open||this._floating.handlePointerLeave(e,()=>this.hide())},this._onFocusIn=()=>{this._hasTrigger(`focus`)&&this.show()},this._onFocusOut=()=>{this._hasTrigger(`focus`)&&this.hide()},this._onClick=()=>{this._hasTrigger(`click`)&&this.toggle()},this._onKeyDown=e=>{this.open&&e.key===`Escape`&&(e.stopPropagation(),this.hide())}}static{this.styles=[s,l]}#e;get for(){return this.#e}set for(e){this.#e=e}#t;get placement(){return this.#t}set placement(e){this.#t=e}#n;get distance(){return this.#n}set distance(e){this.#n=e}#r;get open(){return this.#r}set open(e){this.#r=e}#i;get withoutArrow(){return this.#i}set withoutArrow(e){this.#i=e}#a;get trigger(){return this.#a}set trigger(e){this.#a=e}_hasTrigger(e){return this.trigger.split(` `).includes(e)}get _trigger(){return this.for?this.getRootNode().getElementById(this.for):null}get _popover(){return this.shadowRoot.querySelector(`[popover]`)}get _arrowEl(){return this.withoutArrow?null:this.shadowRoot.querySelector(`i`)}_getDuration(e){let t=parseFloat(getComputedStyle(this).getPropertyValue(e));return Number.isNaN(t)?150:t}connectedCallback(){super.connectedCallback(),requestAnimationFrame(()=>this._addTriggerListeners())}disconnectedCallback(){super.disconnectedCallback(),this._removeTriggerListeners()}updated(e){e.has(`open`)&&this._handleOpenChange(),e.has(`for`)&&(this._removeTriggerListeners(e.get(`for`)),this._addTriggerListeners())}show(){this.open||=!0}hide(){this.open&&=!1}toggle(){this.open=!this.open}async _handleOpenChange(){let e=this._popover;if(!e)return;let t={placement:this.placement,distance:this.distance};if(this.open){if(e.showPopover(),await this._floating.updatePosition(t),!this.open)return;await this._floating.animateShow(e,this._getDuration(`--show-duration`)),this._floating.startPositioning(t),this._trigger?.setAttribute(`aria-describedby`,this._tooltipId)}else this._floating.stopPositioning(),this._floating.cleanupSafePolygon(),this._trigger?.removeAttribute(`aria-describedby`),await this._floating.animateHide(e,this._getDuration(`--hide-duration`)),e.matches(`:popover-open`)&&e.hidePopover()}_addTriggerListeners(){this._floating.addTriggerListeners({onPointerEnter:this._onPointerEnter,onPointerLeave:this._onPointerLeave,onFocusIn:this._onFocusIn,onFocusOut:this._onFocusOut,onClick:this._onClick,onKeyDown:this._onKeyDown})}_removeTriggerListeners(e){let t=e?this.getRootNode().getElementById(e):void 0;this._floating.removeTriggerListeners(t)}render(){return n`
2
2
  <div
3
3
  id=${this._tooltipId}
4
4
  popover="manual"
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","names":[],"sources":["../../../src/html/elements/tooltip/tooltip.css?inline","../../../src/html/elements/tooltip/tooltip.ts"],"sourcesContent":[":host {\n --background-color: var(--l-color-bg-fill-brand, light-dark(#1f2937, #f9fafb));\n --border-radius: 4px;\n --max-width: 180px;\n --arrow-size: 6px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n padding: 4px 8px;\n border: 0;\n border-radius: var(--border-radius);\n background: var(--background-color);\n color: var(\n --text-color,\n oklch(from var(--background-color) calc(0.59 - 0.41 * sign(l - 0.5)) 0 0)\n );\n font-size: 0.8125rem;\n line-height: 1.4;\n filter: drop-shadow(0 1px 2px rgb(0 0 0 / 16%));\n pointer-events: none;\n}\n\n@supports (color: contrast-color(red vs black, white)) {\n [popover] {\n color: var(--text-color, contrast-color(var(--background-color) vs #111827, #fff to AA));\n }\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background-color);\n transform: rotate(45deg);\n}\n","import { html, nothing, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover.js';\nimport { uniqueId } from '../../registry.js';\nimport hostStyles from '../../shared/styles/host.styles.js';\nimport rawStyles from './tooltip.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * @summary A tooltip that displays contextual text on hover or focus.\n * @customElement l-tooltip\n *\n * @slot - Tooltip content (text or rich HTML).\n *\n * @csspart body - The tooltip popover container.\n * @csspart arrow - The directional arrow element.\n *\n * @cssproperty --background-color - Background color. Default: dark in light mode, light in dark mode.\n * @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.\n * @cssproperty --border-radius - Border radius. Default `4px`.\n * @cssproperty --max-width - Maximum width. Default `180px`.\n * @cssproperty --arrow-size - Arrow size. Default `6px`.\n * @cssproperty --show-duration - Show animation duration. Default `150ms`.\n * @cssproperty --hide-duration - Hide animation duration. Default `150ms`.\n */\nexport class Tooltip extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _tooltipId = uniqueId('tooltip');\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._trigger,\n getFloatingElement: () => this._popover,\n getArrowElement: () => this._arrowEl,\n });\n\n /** The HTML id of the element triggering the tooltip. */\n @property()\n accessor for = '';\n\n /** The preferred placement of the tooltip. */\n @property()\n accessor placement: Placement = 'top';\n\n /** The distance in pixels from the target element. */\n @property({ type: Number })\n accessor distance = 8;\n\n /** Whether or not the tooltip is visible. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Hide the directional arrow. */\n @property({ type: Boolean, reflect: true, attribute: 'without-arrow' })\n accessor withoutArrow = false;\n\n /** Space-separated list of trigger modes: `hover`, `focus`, `click`, `manual`. */\n @property()\n accessor trigger = 'hover focus';\n\n private _hasTrigger(type: string) {\n return this.trigger.split(' ').includes(type);\n }\n\n private get _trigger(): HTMLElement | null {\n return this.for ? (this.getRootNode() as Document | ShadowRoot).getElementById(this.for) : null;\n }\n\n private get _popover(): HTMLElement {\n return this.shadowRoot!.querySelector('[popover]')!;\n }\n\n private get _arrowEl(): HTMLElement | null {\n return this.withoutArrow ? null : this.shadowRoot!.querySelector('i');\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._addTriggerListeners());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._removeTriggerListeners();\n }\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n void this._handleOpenChange();\n }\n if (changed.has('for')) {\n this._removeTriggerListeners(changed.get('for') as string);\n this._addTriggerListeners();\n }\n }\n\n show() {\n if (!this.open) this.open = true;\n }\n\n hide() {\n if (this.open) this.open = false;\n }\n\n toggle() {\n this.open = !this.open;\n }\n\n private async _handleOpenChange() {\n const popover = this._popover;\n if (!popover) return;\n\n const posOpts = { placement: this.placement, distance: this.distance };\n\n if (this.open) {\n popover.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(popover, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._trigger?.setAttribute('aria-describedby', this._tooltipId);\n } else {\n this._floating.stopPositioning();\n this._floating.cleanupSafePolygon();\n this._trigger?.removeAttribute('aria-describedby');\n await this._floating.animateHide(popover, this._getDuration('--hide-duration'));\n if (popover.matches(':popover-open')) popover.hidePopover();\n }\n }\n\n // --- Trigger event handlers ---\n\n private _onPointerEnter = () => {\n if (!this._hasTrigger('hover')) return;\n this._floating.cleanupSafePolygon();\n this.show();\n };\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (!this._hasTrigger('hover') || !this.open) return;\n this._floating.handlePointerLeave(e, () => this.hide());\n };\n\n private _onFocusIn = () => {\n if (this._hasTrigger('focus')) this.show();\n };\n private _onFocusOut = () => {\n if (this._hasTrigger('focus')) this.hide();\n };\n private _onClick = () => {\n if (this._hasTrigger('click')) this.toggle();\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n if (this.open && e.key === 'Escape') {\n e.stopPropagation();\n this.hide();\n }\n };\n\n private _addTriggerListeners() {\n this._floating.addTriggerListeners({\n onPointerEnter: this._onPointerEnter,\n onPointerLeave: this._onPointerLeave,\n onFocusIn: this._onFocusIn,\n onFocusOut: this._onFocusOut,\n onClick: this._onClick,\n onKeyDown: this._onKeyDown,\n });\n }\n\n private _removeTriggerListeners(forId?: string) {\n const trigger = forId\n ? (this.getRootNode() as Document | ShadowRoot).getElementById(forId)\n : undefined;\n this._floating.removeTriggerListeners(trigger);\n }\n\n override render() {\n return html`\n <div\n id=${this._tooltipId}\n popover=\"manual\"\n role=\"tooltip\"\n part=\"body\"\n >\n ${this.withoutArrow\n ? nothing\n : html`\n <i\n part=\"arrow\"\n role=\"presentation\"\n ></i>\n `}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tooltip.js","names":[],"sources":["../../../src/html/elements/tooltip/tooltip.css?inline","../../../src/html/elements/tooltip/tooltip.ts"],"sourcesContent":[":host {\n --background-color: var(--l-tooltip-background-color, light-dark(#1f2937, #f9fafb));\n --border-radius: 4px;\n --max-width: 180px;\n --arrow-size: 6px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n padding: 4px 8px;\n border: 0;\n border-radius: var(--border-radius);\n background: var(--background-color);\n color: var(\n --text-color,\n oklch(from var(--background-color) calc(0.59 - 0.41 * sign(l - 0.5)) 0 0)\n );\n font-size: 0.8125rem;\n line-height: 1.4;\n filter: drop-shadow(0 1px 2px rgb(0 0 0 / 16%));\n pointer-events: none;\n}\n\n@supports (color: contrast-color(red vs black, white)) {\n [popover] {\n color: var(--text-color, contrast-color(var(--background-color) vs #111827, #fff to AA));\n }\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background-color);\n transform: rotate(45deg);\n}\n","import { html, nothing, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover.js';\nimport { uniqueId } from '../../registry.js';\nimport hostStyles from '../../shared/styles/host.styles.js';\nimport rawStyles from './tooltip.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * @summary A tooltip that displays contextual text on hover or focus.\n * @customElement l-tooltip\n *\n * @slot - Tooltip content (text or rich HTML).\n *\n * @csspart body - The tooltip popover container.\n * @csspart arrow - The directional arrow element.\n *\n * @cssproperty --background-color - Background color for this tooltip instance. Defaults to the global `--l-tooltip-background-color` token (a neutral inverse surface, dark in light mode / light in dark mode) — override that token to re-skin every tooltip at once.\n * @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.\n * @cssproperty --border-radius - Border radius. Default `4px`.\n * @cssproperty --max-width - Maximum width. Default `180px`.\n * @cssproperty --arrow-size - Arrow size. Default `6px`.\n * @cssproperty --show-duration - Show animation duration. Default `150ms`.\n * @cssproperty --hide-duration - Hide animation duration. Default `150ms`.\n */\nexport class Tooltip extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _tooltipId = uniqueId('tooltip');\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._trigger,\n getFloatingElement: () => this._popover,\n getArrowElement: () => this._arrowEl,\n });\n\n /** The HTML id of the element triggering the tooltip. */\n @property()\n accessor for = '';\n\n /** The preferred placement of the tooltip. */\n @property()\n accessor placement: Placement = 'top';\n\n /** The distance in pixels from the target element. */\n @property({ type: Number })\n accessor distance = 8;\n\n /** Whether or not the tooltip is visible. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Hide the directional arrow. */\n @property({ type: Boolean, reflect: true, attribute: 'without-arrow' })\n accessor withoutArrow = false;\n\n /** Space-separated list of trigger modes: `hover`, `focus`, `click`, `manual`. */\n @property()\n accessor trigger = 'hover focus';\n\n private _hasTrigger(type: string) {\n return this.trigger.split(' ').includes(type);\n }\n\n private get _trigger(): HTMLElement | null {\n return this.for ? (this.getRootNode() as Document | ShadowRoot).getElementById(this.for) : null;\n }\n\n private get _popover(): HTMLElement {\n return this.shadowRoot!.querySelector('[popover]')!;\n }\n\n private get _arrowEl(): HTMLElement | null {\n return this.withoutArrow ? null : this.shadowRoot!.querySelector('i');\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._addTriggerListeners());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._removeTriggerListeners();\n }\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n void this._handleOpenChange();\n }\n if (changed.has('for')) {\n this._removeTriggerListeners(changed.get('for') as string);\n this._addTriggerListeners();\n }\n }\n\n show() {\n if (!this.open) this.open = true;\n }\n\n hide() {\n if (this.open) this.open = false;\n }\n\n toggle() {\n this.open = !this.open;\n }\n\n private async _handleOpenChange() {\n const popover = this._popover;\n if (!popover) return;\n\n const posOpts = { placement: this.placement, distance: this.distance };\n\n if (this.open) {\n popover.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(popover, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._trigger?.setAttribute('aria-describedby', this._tooltipId);\n } else {\n this._floating.stopPositioning();\n this._floating.cleanupSafePolygon();\n this._trigger?.removeAttribute('aria-describedby');\n await this._floating.animateHide(popover, this._getDuration('--hide-duration'));\n if (popover.matches(':popover-open')) popover.hidePopover();\n }\n }\n\n // --- Trigger event handlers ---\n\n private _onPointerEnter = () => {\n if (!this._hasTrigger('hover')) return;\n this._floating.cleanupSafePolygon();\n this.show();\n };\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (!this._hasTrigger('hover') || !this.open) return;\n this._floating.handlePointerLeave(e, () => this.hide());\n };\n\n private _onFocusIn = () => {\n if (this._hasTrigger('focus')) this.show();\n };\n private _onFocusOut = () => {\n if (this._hasTrigger('focus')) this.hide();\n };\n private _onClick = () => {\n if (this._hasTrigger('click')) this.toggle();\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n if (this.open && e.key === 'Escape') {\n e.stopPropagation();\n this.hide();\n }\n };\n\n private _addTriggerListeners() {\n this._floating.addTriggerListeners({\n onPointerEnter: this._onPointerEnter,\n onPointerLeave: this._onPointerLeave,\n onFocusIn: this._onFocusIn,\n onFocusOut: this._onFocusOut,\n onClick: this._onClick,\n onKeyDown: this._onKeyDown,\n });\n }\n\n private _removeTriggerListeners(forId?: string) {\n const trigger = forId\n ? (this.getRootNode() as Document | ShadowRoot).getElementById(forId)\n : undefined;\n this._floating.removeTriggerListeners(trigger);\n }\n\n override render() {\n return html`\n <div\n id=${this._tooltipId}\n popover=\"manual\"\n role=\"tooltip\"\n part=\"body\"\n >\n ${this.withoutArrow\n ? nothing\n : html`\n <i\n part=\"arrow\"\n role=\"presentation\"\n ></i>\n `}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
@@ -1030,6 +1030,18 @@ In dark mode, mixes the base color with black (default 15% black).
1030
1030
  --l-form-field-choice-gap: var(--l-spacing-2);
1031
1031
  }
1032
1032
 
1033
+ /* Tooltip component token (--l-tooltip-background-color). */
1034
+
1035
+ /* Luxen design-tokens — tooltip component token.
1036
+ Bundled in the Luxen preset via `luxen-ui/css/tokens`. A neutral inverse
1037
+ surface, decoupled from the brand fill so re-theming primary does not
1038
+ recolor tooltips. */
1039
+
1040
+ :root {
1041
+ /* Tooltip surface color — dark in light mode, light in dark mode. Neutral by design; not tied to --l-color-bg-fill-brand, so changing the brand color does not recolor tooltips. Override globally to re-skin every tooltip, or use the per-instance --background-color custom property on a single `<l-tooltip>`. */
1042
+ --l-tooltip-background-color: light-dark(var(--l-color-gray-900), var(--l-color-gray-50));
1043
+ }
1044
+
1033
1045
  /* avatar.css */
1034
1046
  @layer components {
1035
1047
  /*
package/cdn/standalone.js CHANGED
@@ -31920,7 +31920,7 @@ define("toast", Toast);
31920
31920
  define("toast-item", ToastItem);
31921
31921
  //#endregion
31922
31922
  //#region src/html/elements/tooltip/tooltip.ts
31923
- var styles$2 = r$6(":host {\n --background-color: var(--l-color-bg-fill-brand, light-dark(#1f2937, #f9fafb));\n --border-radius: 4px;\n --max-width: 180px;\n --arrow-size: 6px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n padding: 4px 8px;\n border: 0;\n border-radius: var(--border-radius);\n background: var(--background-color);\n color: var(\n --text-color,\n oklch(from var(--background-color) calc(0.59 - 0.41 * sign(l - 0.5)) 0 0)\n );\n font-size: 0.8125rem;\n line-height: 1.4;\n filter: drop-shadow(0 1px 2px rgb(0 0 0 / 16%));\n pointer-events: none;\n}\n\n@supports (color: contrast-color(red vs black, white)) {\n [popover] {\n color: var(--text-color, contrast-color(var(--background-color) vs #111827, #fff to AA));\n }\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background-color);\n transform: rotate(45deg);\n}\n");
31923
+ var styles$2 = r$6(":host {\n --background-color: var(--l-tooltip-background-color, light-dark(#1f2937, #f9fafb));\n --border-radius: 4px;\n --max-width: 180px;\n --arrow-size: 6px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n padding: 4px 8px;\n border: 0;\n border-radius: var(--border-radius);\n background: var(--background-color);\n color: var(\n --text-color,\n oklch(from var(--background-color) calc(0.59 - 0.41 * sign(l - 0.5)) 0 0)\n );\n font-size: 0.8125rem;\n line-height: 1.4;\n filter: drop-shadow(0 1px 2px rgb(0 0 0 / 16%));\n pointer-events: none;\n}\n\n@supports (color: contrast-color(red vs black, white)) {\n [popover] {\n color: var(--text-color, contrast-color(var(--background-color) vs #111827, #fff to AA));\n }\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background-color);\n transform: rotate(45deg);\n}\n");
31924
31924
  /**
31925
31925
  * @summary A tooltip that displays contextual text on hover or focus.
31926
31926
  * @customElement l-tooltip
@@ -31930,7 +31930,7 @@ var styles$2 = r$6(":host {\n --background-color: var(--l-color-bg-fill-brand,
31930
31930
  * @csspart body - The tooltip popover container.
31931
31931
  * @csspart arrow - The directional arrow element.
31932
31932
  *
31933
- * @cssproperty --background-color - Background color. Default: dark in light mode, light in dark mode.
31933
+ * @cssproperty --background-color - Background color for this tooltip instance. Defaults to the global `--l-tooltip-background-color` token (a neutral inverse surface, dark in light mode / light in dark mode) — override that token to re-skin every tooltip at once.
31934
31934
  * @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.
31935
31935
  * @cssproperty --border-radius - Border radius. Default `4px`.
31936
31936
  * @cssproperty --max-width - Maximum width. Default `180px`.