@f-ewald/components 1.11.0 → 1.13.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 (57) hide show
  1. package/README.md +7 -0
  2. package/custom-elements.json +1651 -115
  3. package/dist/auto-scroll.d.ts +37 -0
  4. package/dist/auto-scroll.d.ts.map +1 -0
  5. package/dist/auto-scroll.js +100 -0
  6. package/dist/auto-scroll.js.map +1 -0
  7. package/dist/form-field.d.ts +39 -0
  8. package/dist/form-field.d.ts.map +1 -0
  9. package/dist/form-field.js +145 -0
  10. package/dist/form-field.js.map +1 -0
  11. package/dist/icons.d.ts +1 -0
  12. package/dist/icons.d.ts.map +1 -1
  13. package/dist/icons.js +1 -0
  14. package/dist/icons.js.map +1 -1
  15. package/dist/index.d.ts +7 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/load-more.d.ts +33 -0
  20. package/dist/load-more.d.ts.map +1 -0
  21. package/dist/load-more.js +82 -0
  22. package/dist/load-more.js.map +1 -0
  23. package/dist/percent-bar-chart.d.ts +32 -3
  24. package/dist/percent-bar-chart.d.ts.map +1 -1
  25. package/dist/percent-bar-chart.js +101 -36
  26. package/dist/percent-bar-chart.js.map +1 -1
  27. package/dist/scroll-to-bottom.d.ts +41 -0
  28. package/dist/scroll-to-bottom.d.ts.map +1 -0
  29. package/dist/scroll-to-bottom.js +189 -0
  30. package/dist/scroll-to-bottom.js.map +1 -0
  31. package/dist/scroll-to-top.d.ts +41 -0
  32. package/dist/scroll-to-top.d.ts.map +1 -0
  33. package/dist/scroll-to-top.js +189 -0
  34. package/dist/scroll-to-top.js.map +1 -0
  35. package/dist/tree-view.d.ts +44 -0
  36. package/dist/tree-view.d.ts.map +1 -0
  37. package/dist/tree-view.js +200 -0
  38. package/dist/tree-view.js.map +1 -0
  39. package/dist/ui-checkbox.d.ts +49 -0
  40. package/dist/ui-checkbox.d.ts.map +1 -0
  41. package/dist/ui-checkbox.js +228 -0
  42. package/dist/ui-checkbox.js.map +1 -0
  43. package/dist/utils/scroll.d.ts +9 -0
  44. package/dist/utils/scroll.d.ts.map +1 -0
  45. package/dist/utils/scroll.js +30 -0
  46. package/dist/utils/scroll.js.map +1 -0
  47. package/docs/auto-scroll.md +52 -0
  48. package/docs/form-field.md +63 -0
  49. package/docs/layouts/form-page.md +8 -4
  50. package/docs/load-more.md +43 -0
  51. package/docs/percent-bar-chart.md +19 -5
  52. package/docs/scroll-to-bottom.md +68 -0
  53. package/docs/scroll-to-top.md +59 -0
  54. package/docs/tree-view.md +69 -0
  55. package/docs/ui-checkbox.md +58 -0
  56. package/llms.txt +223 -6
  57. package/package.json +1 -1
@@ -1315,6 +1315,148 @@
1315
1315
  }
1316
1316
  ]
1317
1317
  },
1318
+ {
1319
+ "kind": "javascript-module",
1320
+ "path": "src/auto-scroll.ts",
1321
+ "declarations": [
1322
+ {
1323
+ "kind": "class",
1324
+ "description": "Wraps arbitrary slotted content (e.g. `timeline-container`) and keeps it\nscrolled to the bottom as new children are appended — but only while the\nuser is already scrolled near the bottom (\"stick to bottom\", a chat/log-\nviewer convention). If the user has scrolled up to read earlier content,\nnew content does not yank the scroll position back down.\n\nNew content is detected via a `MutationObserver`, so no cooperation from\nwhatever is slotted in is required. The host itself is the scrollable\nregion (`overflow-y: auto`) and needs a consumer-supplied bounded height to\nhave anything to scroll, e.g. `auto-scroll { height: 24rem; }`.",
1325
+ "name": "AutoScroll",
1326
+ "slots": [
1327
+ {
1328
+ "description": "Content to auto-scroll.",
1329
+ "name": ""
1330
+ }
1331
+ ],
1332
+ "members": [
1333
+ {
1334
+ "kind": "field",
1335
+ "name": "threshold",
1336
+ "type": {
1337
+ "text": "number"
1338
+ },
1339
+ "default": "24",
1340
+ "description": "Pixels of tolerance from the bottom edge counted as \"still at the bottom\".",
1341
+ "attribute": "threshold"
1342
+ },
1343
+ {
1344
+ "kind": "field",
1345
+ "name": "_pinned",
1346
+ "type": {
1347
+ "text": "boolean"
1348
+ },
1349
+ "privacy": "private",
1350
+ "default": "true"
1351
+ },
1352
+ {
1353
+ "kind": "field",
1354
+ "name": "#observer",
1355
+ "privacy": "private",
1356
+ "type": {
1357
+ "text": "MutationObserver | undefined"
1358
+ }
1359
+ },
1360
+ {
1361
+ "kind": "field",
1362
+ "name": "pinned",
1363
+ "type": {
1364
+ "text": "boolean"
1365
+ },
1366
+ "description": "Whether the view is currently stuck to the bottom. Read-only; see `scrollToBottom()`.",
1367
+ "readonly": true
1368
+ },
1369
+ {
1370
+ "kind": "method",
1371
+ "name": "scrollToBottom",
1372
+ "return": {
1373
+ "type": {
1374
+ "text": "void"
1375
+ }
1376
+ },
1377
+ "description": "Scrolls to the bottom immediately, regardless of the current `pinned` state."
1378
+ },
1379
+ {
1380
+ "kind": "field",
1381
+ "name": "#onScroll",
1382
+ "privacy": "private"
1383
+ },
1384
+ {
1385
+ "kind": "method",
1386
+ "name": "#onMutation",
1387
+ "privacy": "private",
1388
+ "return": {
1389
+ "type": {
1390
+ "text": "void"
1391
+ }
1392
+ }
1393
+ },
1394
+ {
1395
+ "kind": "method",
1396
+ "name": "#setPinned",
1397
+ "privacy": "private",
1398
+ "return": {
1399
+ "type": {
1400
+ "text": "void"
1401
+ }
1402
+ },
1403
+ "parameters": [
1404
+ {
1405
+ "name": "pinned",
1406
+ "type": {
1407
+ "text": "boolean"
1408
+ }
1409
+ }
1410
+ ]
1411
+ }
1412
+ ],
1413
+ "events": [
1414
+ {
1415
+ "name": "pinned-change",
1416
+ "type": {
1417
+ "text": "CustomEvent"
1418
+ },
1419
+ "description": "The stick-to-bottom state toggled; detail: `{ pinned }`."
1420
+ }
1421
+ ],
1422
+ "attributes": [
1423
+ {
1424
+ "name": "threshold",
1425
+ "type": {
1426
+ "text": "number"
1427
+ },
1428
+ "default": "24",
1429
+ "description": "Pixels of tolerance from the bottom edge counted as \"still at the bottom\".",
1430
+ "fieldName": "threshold"
1431
+ }
1432
+ ],
1433
+ "superclass": {
1434
+ "name": "LitElement",
1435
+ "package": "lit"
1436
+ },
1437
+ "tagName": "auto-scroll",
1438
+ "customElement": true
1439
+ }
1440
+ ],
1441
+ "exports": [
1442
+ {
1443
+ "kind": "js",
1444
+ "name": "AutoScroll",
1445
+ "declaration": {
1446
+ "name": "AutoScroll",
1447
+ "module": "src/auto-scroll.ts"
1448
+ }
1449
+ },
1450
+ {
1451
+ "kind": "custom-element-definition",
1452
+ "name": "auto-scroll",
1453
+ "declaration": {
1454
+ "name": "AutoScroll",
1455
+ "module": "src/auto-scroll.ts"
1456
+ }
1457
+ }
1458
+ ]
1459
+ },
1318
1460
  {
1319
1461
  "kind": "javascript-module",
1320
1462
  "path": "src/autocomplete-input.ts",
@@ -4219,6 +4361,134 @@
4219
4361
  }
4220
4362
  ]
4221
4363
  },
4364
+ {
4365
+ "kind": "javascript-module",
4366
+ "path": "src/form-field.ts",
4367
+ "declarations": [
4368
+ {
4369
+ "kind": "class",
4370
+ "description": "Per-field wrapper for a form control: label, slotted control, and an\noptional hint or error message, in one consistent unit repeated across a\nform. Purely presentational — composes whatever control is slotted\n(`form-select`, `multi-select`, `autocomplete-input`, `ui-checkbox`, etc.)\nwithout intercepting its events or value.\n\nThe label wraps the default slot for a best-effort visual/click\nassociation only: every existing value-entry control encapsulates its\nreal `<input>` inside its own shadow DOM, so there is no light-DOM `id` a\n`for` attribute could target from outside, and this component cannot set\n`aria-describedby`/`aria-invalid` on an arbitrary slotted control's\nshadow-encapsulated input for the same reason. The error message uses\n`role=\"alert\"` as the practical accessibility mitigation instead of true\n`aria-describedby` association.",
4371
+ "name": "FormField",
4372
+ "slots": [
4373
+ {
4374
+ "description": "The wrapped form control.",
4375
+ "name": ""
4376
+ }
4377
+ ],
4378
+ "members": [
4379
+ {
4380
+ "kind": "field",
4381
+ "name": "label",
4382
+ "type": {
4383
+ "text": "string"
4384
+ },
4385
+ "default": "\"\"",
4386
+ "description": "Field label text.",
4387
+ "attribute": "label"
4388
+ },
4389
+ {
4390
+ "kind": "field",
4391
+ "name": "hint",
4392
+ "type": {
4393
+ "text": "string"
4394
+ },
4395
+ "default": "\"\"",
4396
+ "description": "Optional helper text shown below the control when there's no `error`.",
4397
+ "attribute": "hint"
4398
+ },
4399
+ {
4400
+ "kind": "field",
4401
+ "name": "error",
4402
+ "type": {
4403
+ "text": "string"
4404
+ },
4405
+ "default": "\"\"",
4406
+ "description": "Optional error text; replaces the `hint` display when non-empty.",
4407
+ "attribute": "error"
4408
+ },
4409
+ {
4410
+ "kind": "field",
4411
+ "name": "required",
4412
+ "type": {
4413
+ "text": "boolean"
4414
+ },
4415
+ "default": "false",
4416
+ "description": "Shows a required indicator next to the label.",
4417
+ "attribute": "required"
4418
+ },
4419
+ {
4420
+ "kind": "field",
4421
+ "name": "#messageId",
4422
+ "privacy": "private",
4423
+ "readonly": true,
4424
+ "default": "`form-field-message-${++instanceCount}`"
4425
+ }
4426
+ ],
4427
+ "attributes": [
4428
+ {
4429
+ "name": "label",
4430
+ "type": {
4431
+ "text": "string"
4432
+ },
4433
+ "default": "\"\"",
4434
+ "description": "Field label text.",
4435
+ "fieldName": "label"
4436
+ },
4437
+ {
4438
+ "name": "hint",
4439
+ "type": {
4440
+ "text": "string"
4441
+ },
4442
+ "default": "\"\"",
4443
+ "description": "Optional helper text shown below the control when there's no `error`.",
4444
+ "fieldName": "hint"
4445
+ },
4446
+ {
4447
+ "name": "error",
4448
+ "type": {
4449
+ "text": "string"
4450
+ },
4451
+ "default": "\"\"",
4452
+ "description": "Optional error text; replaces the `hint` display when non-empty.",
4453
+ "fieldName": "error"
4454
+ },
4455
+ {
4456
+ "name": "required",
4457
+ "type": {
4458
+ "text": "boolean"
4459
+ },
4460
+ "default": "false",
4461
+ "description": "Shows a required indicator next to the label.",
4462
+ "fieldName": "required"
4463
+ }
4464
+ ],
4465
+ "superclass": {
4466
+ "name": "LitElement",
4467
+ "package": "lit"
4468
+ },
4469
+ "tagName": "form-field",
4470
+ "customElement": true
4471
+ }
4472
+ ],
4473
+ "exports": [
4474
+ {
4475
+ "kind": "js",
4476
+ "name": "FormField",
4477
+ "declaration": {
4478
+ "name": "FormField",
4479
+ "module": "src/form-field.ts"
4480
+ }
4481
+ },
4482
+ {
4483
+ "kind": "custom-element-definition",
4484
+ "name": "form-field",
4485
+ "declaration": {
4486
+ "name": "FormField",
4487
+ "module": "src/form-field.ts"
4488
+ }
4489
+ }
4490
+ ]
4491
+ },
4222
4492
  {
4223
4493
  "kind": "javascript-module",
4224
4494
  "path": "src/form-select.ts",
@@ -5226,6 +5496,16 @@
5226
5496
  }
5227
5497
  ]
5228
5498
  },
5499
+ {
5500
+ "kind": "function",
5501
+ "name": "iconChevronUp",
5502
+ "parameters": [
5503
+ {
5504
+ "name": "size",
5505
+ "default": "16"
5506
+ }
5507
+ ]
5508
+ },
5229
5509
  {
5230
5510
  "kind": "function",
5231
5511
  "name": "iconCog",
@@ -5700,6 +5980,14 @@
5700
5980
  "module": "src/icons.ts"
5701
5981
  }
5702
5982
  },
5983
+ {
5984
+ "kind": "js",
5985
+ "name": "iconChevronUp",
5986
+ "declaration": {
5987
+ "name": "iconChevronUp",
5988
+ "module": "src/icons.ts"
5989
+ }
5990
+ },
5703
5991
  {
5704
5992
  "kind": "js",
5705
5993
  "name": "iconCog",
@@ -6187,6 +6475,22 @@
6187
6475
  "module": "./toast-notification.js"
6188
6476
  }
6189
6477
  },
6478
+ {
6479
+ "kind": "js",
6480
+ "name": "ScrollToBottom",
6481
+ "declaration": {
6482
+ "name": "ScrollToBottom",
6483
+ "module": "./scroll-to-bottom.js"
6484
+ }
6485
+ },
6486
+ {
6487
+ "kind": "js",
6488
+ "name": "ScrollToTop",
6489
+ "declaration": {
6490
+ "name": "ScrollToTop",
6491
+ "module": "./scroll-to-top.js"
6492
+ }
6493
+ },
6190
6494
  {
6191
6495
  "kind": "js",
6192
6496
  "name": "SlidePanel",
@@ -6443,6 +6747,14 @@
6443
6747
  "module": "./live-timer.js"
6444
6748
  }
6445
6749
  },
6750
+ {
6751
+ "kind": "js",
6752
+ "name": "LoadMore",
6753
+ "declaration": {
6754
+ "name": "LoadMore",
6755
+ "module": "./load-more.js"
6756
+ }
6757
+ },
6446
6758
  {
6447
6759
  "kind": "js",
6448
6760
  "name": "ChatMessage",
@@ -6467,6 +6779,22 @@
6467
6779
  "module": "./chat-message.js"
6468
6780
  }
6469
6781
  },
6782
+ {
6783
+ "kind": "js",
6784
+ "name": "UiCheckbox",
6785
+ "declaration": {
6786
+ "name": "UiCheckbox",
6787
+ "module": "./ui-checkbox.js"
6788
+ }
6789
+ },
6790
+ {
6791
+ "kind": "js",
6792
+ "name": "FormField",
6793
+ "declaration": {
6794
+ "name": "FormField",
6795
+ "module": "./form-field.js"
6796
+ }
6797
+ },
6470
6798
  {
6471
6799
  "kind": "js",
6472
6800
  "name": "FormSelect",
@@ -6533,9 +6861,25 @@
6533
6861
  },
6534
6862
  {
6535
6863
  "kind": "js",
6536
- "name": "PopoverPanel",
6864
+ "name": "TreeView",
6537
6865
  "declaration": {
6538
- "name": "PopoverPanel",
6866
+ "name": "TreeView",
6867
+ "module": "./tree-view.js"
6868
+ }
6869
+ },
6870
+ {
6871
+ "kind": "js",
6872
+ "name": "TreeNode",
6873
+ "declaration": {
6874
+ "name": "TreeNode",
6875
+ "module": "./tree-view.js"
6876
+ }
6877
+ },
6878
+ {
6879
+ "kind": "js",
6880
+ "name": "PopoverPanel",
6881
+ "declaration": {
6882
+ "name": "PopoverPanel",
6539
6883
  "module": "./popover-panel.js"
6540
6884
  }
6541
6885
  },
@@ -6787,6 +7131,14 @@
6787
7131
  "module": "./markdown-view.js"
6788
7132
  }
6789
7133
  },
7134
+ {
7135
+ "kind": "js",
7136
+ "name": "AutoScroll",
7137
+ "declaration": {
7138
+ "name": "AutoScroll",
7139
+ "module": "./auto-scroll.js"
7140
+ }
7141
+ },
6790
7142
  {
6791
7143
  "kind": "js",
6792
7144
  "name": "formatDuration",
@@ -8070,6 +8422,159 @@
8070
8422
  }
8071
8423
  ]
8072
8424
  },
8425
+ {
8426
+ "kind": "javascript-module",
8427
+ "path": "src/load-more.ts",
8428
+ "declarations": [
8429
+ {
8430
+ "kind": "class",
8431
+ "description": "Click-to-load button for either end of a list. Fully property-driven: the\nconsumer sets `loading` while a fetch is in flight and `exhausted` once\nthere's nothing left to load; this component never fetches or manages\nstate itself.",
8432
+ "name": "LoadMore",
8433
+ "members": [
8434
+ {
8435
+ "kind": "field",
8436
+ "name": "direction",
8437
+ "type": {
8438
+ "text": "\"top\" | \"bottom\""
8439
+ },
8440
+ "default": "\"bottom\"",
8441
+ "description": "Which end of a list this instance loads more content for.",
8442
+ "attribute": "direction"
8443
+ },
8444
+ {
8445
+ "kind": "field",
8446
+ "name": "loading",
8447
+ "type": {
8448
+ "text": "boolean"
8449
+ },
8450
+ "default": "false",
8451
+ "description": "Consumer-managed busy flag, forwarded to the internal `ui-button`'s `busy`.",
8452
+ "attribute": "loading"
8453
+ },
8454
+ {
8455
+ "kind": "field",
8456
+ "name": "exhausted",
8457
+ "type": {
8458
+ "text": "boolean"
8459
+ },
8460
+ "default": "false",
8461
+ "description": "Terminal \"no more content\" state: disables the button and swaps its label.",
8462
+ "attribute": "exhausted"
8463
+ },
8464
+ {
8465
+ "kind": "field",
8466
+ "name": "label",
8467
+ "type": {
8468
+ "text": "string"
8469
+ },
8470
+ "default": "\"Load more\"",
8471
+ "description": "Button text in the normal (loadable) state.",
8472
+ "attribute": "label"
8473
+ },
8474
+ {
8475
+ "kind": "field",
8476
+ "name": "exhaustedLabel",
8477
+ "type": {
8478
+ "text": "string"
8479
+ },
8480
+ "default": "\"No more results\"",
8481
+ "description": "Button text shown once `exhausted` is true.",
8482
+ "attribute": "exhausted-label"
8483
+ },
8484
+ {
8485
+ "kind": "method",
8486
+ "name": "#onClick",
8487
+ "privacy": "private",
8488
+ "return": {
8489
+ "type": {
8490
+ "text": "void"
8491
+ }
8492
+ }
8493
+ }
8494
+ ],
8495
+ "events": [
8496
+ {
8497
+ "name": "load-more",
8498
+ "type": {
8499
+ "text": "CustomEvent"
8500
+ },
8501
+ "description": "The button was clicked while not `loading`/`exhausted`; detail: `{ direction }`."
8502
+ }
8503
+ ],
8504
+ "attributes": [
8505
+ {
8506
+ "name": "direction",
8507
+ "type": {
8508
+ "text": "\"top\" | \"bottom\""
8509
+ },
8510
+ "default": "\"bottom\"",
8511
+ "description": "Which end of a list this instance loads more content for.",
8512
+ "fieldName": "direction"
8513
+ },
8514
+ {
8515
+ "name": "loading",
8516
+ "type": {
8517
+ "text": "boolean"
8518
+ },
8519
+ "default": "false",
8520
+ "description": "Consumer-managed busy flag, forwarded to the internal `ui-button`'s `busy`.",
8521
+ "fieldName": "loading"
8522
+ },
8523
+ {
8524
+ "name": "exhausted",
8525
+ "type": {
8526
+ "text": "boolean"
8527
+ },
8528
+ "default": "false",
8529
+ "description": "Terminal \"no more content\" state: disables the button and swaps its label.",
8530
+ "fieldName": "exhausted"
8531
+ },
8532
+ {
8533
+ "name": "label",
8534
+ "type": {
8535
+ "text": "string"
8536
+ },
8537
+ "default": "\"Load more\"",
8538
+ "description": "Button text in the normal (loadable) state.",
8539
+ "fieldName": "label"
8540
+ },
8541
+ {
8542
+ "name": "exhausted-label",
8543
+ "type": {
8544
+ "text": "string"
8545
+ },
8546
+ "default": "\"No more results\"",
8547
+ "description": "Button text shown once `exhausted` is true.",
8548
+ "fieldName": "exhaustedLabel"
8549
+ }
8550
+ ],
8551
+ "superclass": {
8552
+ "name": "LitElement",
8553
+ "package": "lit"
8554
+ },
8555
+ "tagName": "load-more",
8556
+ "customElement": true
8557
+ }
8558
+ ],
8559
+ "exports": [
8560
+ {
8561
+ "kind": "js",
8562
+ "name": "LoadMore",
8563
+ "declaration": {
8564
+ "name": "LoadMore",
8565
+ "module": "src/load-more.ts"
8566
+ }
8567
+ },
8568
+ {
8569
+ "kind": "custom-element-definition",
8570
+ "name": "load-more",
8571
+ "declaration": {
8572
+ "name": "LoadMore",
8573
+ "module": "src/load-more.ts"
8574
+ }
8575
+ }
8576
+ ]
8577
+ },
8073
8578
  {
8074
8579
  "kind": "javascript-module",
8075
8580
  "path": "src/map-circle.ts",
@@ -9675,7 +10180,7 @@
9675
10180
  "declarations": [
9676
10181
  {
9677
10182
  "kind": "class",
9678
- "description": "Horizontal bar chart for labeled percentage rows, using D3's linear scale.\nEach group gets its own labeled row; bars are proportional to percentage of 100.",
10183
+ "description": "Bar chart for labeled rows, using D3's linear scale. Horizontal (default)\nrenders stacked rows with bars growing rightward; `orientation=\"vertical\"`\nrenders side-by-side columns growing upward instead. `mode=\"percent\"`\n(default) scales `value` against a fixed 0-100 domain and labels it with a\n`%` suffix; `mode=\"value\"` scales it against `max` (or the largest `value`\npresent) and formats it with `valueFormat`.",
9679
10184
  "name": "PercentBarChart",
9680
10185
  "members": [
9681
10186
  {
@@ -9687,6 +10192,43 @@
9687
10192
  "default": "[]",
9688
10193
  "description": "Rows to render, one per group."
9689
10194
  },
10195
+ {
10196
+ "kind": "field",
10197
+ "name": "mode",
10198
+ "type": {
10199
+ "text": "PercentBarMode"
10200
+ },
10201
+ "default": "\"percent\"",
10202
+ "description": "Whether `value` is a 0-100 percentage (fixed domain) or an arbitrary number (domain from data/`max`).",
10203
+ "attribute": "mode"
10204
+ },
10205
+ {
10206
+ "kind": "field",
10207
+ "name": "orientation",
10208
+ "type": {
10209
+ "text": "PercentBarOrientation"
10210
+ },
10211
+ "default": "\"horizontal\"",
10212
+ "description": "Bar direction: stacked rows growing rightward, or columns growing upward.",
10213
+ "attribute": "orientation"
10214
+ },
10215
+ {
10216
+ "kind": "field",
10217
+ "name": "max",
10218
+ "type": {
10219
+ "text": "number | undefined"
10220
+ },
10221
+ "description": "Explicit domain max for `mode=\"value\"`; auto-computed from `groups` when unset. Ignored in `mode=\"percent\"`.",
10222
+ "attribute": "max"
10223
+ },
10224
+ {
10225
+ "kind": "field",
10226
+ "name": "valueFormat",
10227
+ "type": {
10228
+ "text": "(value: number) => string"
10229
+ },
10230
+ "description": "Formats a row's value for its label in `mode=\"value\"`. Defaults to locale-formatted number."
10231
+ },
9690
10232
  {
9691
10233
  "kind": "field",
9692
10234
  "name": "_width",
@@ -9730,6 +10272,79 @@
9730
10272
  }
9731
10273
  ],
9732
10274
  "description": "Per-row gradient id, unique across instances and rows."
10275
+ },
10276
+ {
10277
+ "kind": "method",
10278
+ "name": "_labelFor",
10279
+ "privacy": "private",
10280
+ "return": {
10281
+ "type": {
10282
+ "text": "string"
10283
+ }
10284
+ },
10285
+ "parameters": [
10286
+ {
10287
+ "name": "value",
10288
+ "type": {
10289
+ "text": "number"
10290
+ }
10291
+ }
10292
+ ],
10293
+ "description": "The row's value formatted for display, per the current `mode`."
10294
+ },
10295
+ {
10296
+ "kind": "method",
10297
+ "name": "_domainMax",
10298
+ "privacy": "private",
10299
+ "return": {
10300
+ "type": {
10301
+ "text": "number"
10302
+ }
10303
+ },
10304
+ "description": "The scale domain's upper bound for the current `mode`."
10305
+ },
10306
+ {
10307
+ "kind": "method",
10308
+ "name": "_renderGradients",
10309
+ "privacy": "private"
10310
+ },
10311
+ {
10312
+ "kind": "method",
10313
+ "name": "_renderHorizontal",
10314
+ "privacy": "private"
10315
+ },
10316
+ {
10317
+ "kind": "method",
10318
+ "name": "_renderVertical",
10319
+ "privacy": "private"
10320
+ }
10321
+ ],
10322
+ "attributes": [
10323
+ {
10324
+ "name": "mode",
10325
+ "type": {
10326
+ "text": "PercentBarMode"
10327
+ },
10328
+ "default": "\"percent\"",
10329
+ "description": "Whether `value` is a 0-100 percentage (fixed domain) or an arbitrary number (domain from data/`max`).",
10330
+ "fieldName": "mode"
10331
+ },
10332
+ {
10333
+ "name": "orientation",
10334
+ "type": {
10335
+ "text": "PercentBarOrientation"
10336
+ },
10337
+ "default": "\"horizontal\"",
10338
+ "description": "Bar direction: stacked rows growing rightward, or columns growing upward.",
10339
+ "fieldName": "orientation"
10340
+ },
10341
+ {
10342
+ "name": "max",
10343
+ "type": {
10344
+ "text": "number | undefined"
10345
+ },
10346
+ "description": "Explicit domain max for `mode=\"value\"`; auto-computed from `groups` when unset. Ignored in `mode=\"percent\"`.",
10347
+ "fieldName": "max"
9733
10348
  }
9734
10349
  ],
9735
10350
  "superclass": {
@@ -11241,54 +11856,350 @@
11241
11856
  },
11242
11857
  {
11243
11858
  "kind": "javascript-module",
11244
- "path": "src/slide-panel.ts",
11859
+ "path": "src/scroll-to-bottom.ts",
11245
11860
  "declarations": [
11246
11861
  {
11247
11862
  "kind": "class",
11248
- "description": "Generic sliding panel shell. Handles positioning, open/close animation,\nheader chrome, and a close button. Body content is provided via the\ndefault slot; the consumer controls its own padding and overflow.\n\nDesktop: fixed right-side panel that slides from the right.\nMobile (≤48rem): bottom-sheet drawer (60vh) — reserved for future use.",
11249
- "name": "SlidePanel",
11863
+ "description": "Overlay button that appears once the page (or a given `target` container)\nhas scrolled more than `threshold` pixels away from the bottom edge, and\nscrolls back to the bottom on click.\n\nWith no `target` (default), the button is `position: fixed` to the\nviewport. When `target` is set, the button switches to `position:\nabsolute` and expects to be placed as a descendant of a `position:\nrelative` (or otherwise positioned) ancestor that establishes the visual\nbounds to float within typically `target` itself, given `overflow-y:\nauto; position: relative`, so the button stays pinned to that container's\nown visible corner as its content scrolls, rather than floating over the\nwhole page.",
11864
+ "name": "ScrollToBottom",
11250
11865
  "members": [
11251
11866
  {
11252
11867
  "kind": "field",
11253
- "name": "open",
11868
+ "name": "target",
11254
11869
  "type": {
11255
- "text": "boolean"
11870
+ "text": "HTMLElement | null"
11256
11871
  },
11257
- "default": "false",
11258
- "description": "Whether the panel is currently visible.",
11259
- "attribute": "open"
11872
+ "default": "null",
11873
+ "description": "Scrollable container to control; `null` (default) scrolls `window`."
11260
11874
  },
11261
11875
  {
11262
11876
  "kind": "field",
11263
- "name": "heading",
11877
+ "name": "threshold",
11878
+ "type": {
11879
+ "text": "number"
11880
+ },
11881
+ "default": "200",
11882
+ "description": "Pixels scrolled away from the bottom before the button appears.",
11883
+ "attribute": "threshold"
11884
+ },
11885
+ {
11886
+ "kind": "field",
11887
+ "name": "label",
11264
11888
  "type": {
11265
11889
  "text": "string"
11266
11890
  },
11267
- "default": "\"\"",
11268
- "description": "Title text shown in the panel header (overridable via slot=\"title\").",
11269
- "attribute": "heading"
11891
+ "default": "\"Scroll to bottom\"",
11892
+ "description": "Visible button text, and its accessible name.",
11893
+ "attribute": "label"
11270
11894
  },
11271
11895
  {
11272
11896
  "kind": "field",
11273
- "name": "_previousFocus",
11897
+ "name": "_visible",
11274
11898
  "type": {
11275
- "text": "HTMLElement | null"
11899
+ "text": "boolean"
11276
11900
  },
11277
11901
  "privacy": "private",
11902
+ "default": "false"
11903
+ },
11904
+ {
11905
+ "kind": "field",
11906
+ "name": "#listenedTo",
11907
+ "privacy": "private",
11908
+ "type": {
11909
+ "text": "HTMLElement | Window | null"
11910
+ },
11278
11911
  "default": "null"
11279
11912
  },
11280
11913
  {
11281
11914
  "kind": "method",
11282
- "name": "_close",
11283
- "privacy": "private"
11915
+ "name": "#subscribe",
11916
+ "privacy": "private",
11917
+ "return": {
11918
+ "type": {
11919
+ "text": "void"
11920
+ }
11921
+ }
11922
+ },
11923
+ {
11924
+ "kind": "method",
11925
+ "name": "#unsubscribe",
11926
+ "privacy": "private",
11927
+ "return": {
11928
+ "type": {
11929
+ "text": "void"
11930
+ }
11931
+ }
11284
11932
  },
11285
11933
  {
11286
11934
  "kind": "field",
11287
- "name": "_onWindowKeydown",
11935
+ "name": "#onScroll",
11288
11936
  "privacy": "private"
11289
- }
11290
- ],
11291
- "events": [
11937
+ },
11938
+ {
11939
+ "kind": "method",
11940
+ "name": "#onClick",
11941
+ "privacy": "private",
11942
+ "return": {
11943
+ "type": {
11944
+ "text": "void"
11945
+ }
11946
+ }
11947
+ }
11948
+ ],
11949
+ "events": [
11950
+ {
11951
+ "name": "scroll-to-bottom-triggered",
11952
+ "type": {
11953
+ "text": "CustomEvent"
11954
+ },
11955
+ "description": "The button was clicked, just before scrolling; detail: `{ target }`."
11956
+ }
11957
+ ],
11958
+ "attributes": [
11959
+ {
11960
+ "name": "threshold",
11961
+ "type": {
11962
+ "text": "number"
11963
+ },
11964
+ "default": "200",
11965
+ "description": "Pixels scrolled away from the bottom before the button appears.",
11966
+ "fieldName": "threshold"
11967
+ },
11968
+ {
11969
+ "name": "label",
11970
+ "type": {
11971
+ "text": "string"
11972
+ },
11973
+ "default": "\"Scroll to bottom\"",
11974
+ "description": "Visible button text, and its accessible name.",
11975
+ "fieldName": "label"
11976
+ }
11977
+ ],
11978
+ "superclass": {
11979
+ "name": "LitElement",
11980
+ "package": "lit"
11981
+ },
11982
+ "tagName": "scroll-to-bottom",
11983
+ "customElement": true
11984
+ }
11985
+ ],
11986
+ "exports": [
11987
+ {
11988
+ "kind": "js",
11989
+ "name": "ScrollToBottom",
11990
+ "declaration": {
11991
+ "name": "ScrollToBottom",
11992
+ "module": "src/scroll-to-bottom.ts"
11993
+ }
11994
+ },
11995
+ {
11996
+ "kind": "custom-element-definition",
11997
+ "name": "scroll-to-bottom",
11998
+ "declaration": {
11999
+ "name": "ScrollToBottom",
12000
+ "module": "src/scroll-to-bottom.ts"
12001
+ }
12002
+ }
12003
+ ]
12004
+ },
12005
+ {
12006
+ "kind": "javascript-module",
12007
+ "path": "src/scroll-to-top.ts",
12008
+ "declarations": [
12009
+ {
12010
+ "kind": "class",
12011
+ "description": "Overlay button that appears once the page (or a given `target` container)\nhas scrolled more than `threshold` pixels away from the top edge, and\nscrolls back to the top on click.\n\nWith no `target` (default), the button is `position: fixed` to the\nviewport. When `target` is set, the button switches to `position:\nabsolute` and expects to be placed as a descendant of a `position:\nrelative` (or otherwise positioned) ancestor that establishes the visual\nbounds to float within — typically `target` itself, given `overflow-y:\nauto; position: relative`, so the button stays pinned to that container's\nown visible corner as its content scrolls, rather than floating over the\nwhole page.",
12012
+ "name": "ScrollToTop",
12013
+ "members": [
12014
+ {
12015
+ "kind": "field",
12016
+ "name": "target",
12017
+ "type": {
12018
+ "text": "HTMLElement | null"
12019
+ },
12020
+ "default": "null",
12021
+ "description": "Scrollable container to control; `null` (default) scrolls `window`."
12022
+ },
12023
+ {
12024
+ "kind": "field",
12025
+ "name": "threshold",
12026
+ "type": {
12027
+ "text": "number"
12028
+ },
12029
+ "default": "200",
12030
+ "description": "Pixels scrolled away from the top before the button appears.",
12031
+ "attribute": "threshold"
12032
+ },
12033
+ {
12034
+ "kind": "field",
12035
+ "name": "label",
12036
+ "type": {
12037
+ "text": "string"
12038
+ },
12039
+ "default": "\"Scroll to top\"",
12040
+ "description": "Visible button text, and its accessible name.",
12041
+ "attribute": "label"
12042
+ },
12043
+ {
12044
+ "kind": "field",
12045
+ "name": "_visible",
12046
+ "type": {
12047
+ "text": "boolean"
12048
+ },
12049
+ "privacy": "private",
12050
+ "default": "false"
12051
+ },
12052
+ {
12053
+ "kind": "field",
12054
+ "name": "#listenedTo",
12055
+ "privacy": "private",
12056
+ "type": {
12057
+ "text": "HTMLElement | Window | null"
12058
+ },
12059
+ "default": "null"
12060
+ },
12061
+ {
12062
+ "kind": "method",
12063
+ "name": "#subscribe",
12064
+ "privacy": "private",
12065
+ "return": {
12066
+ "type": {
12067
+ "text": "void"
12068
+ }
12069
+ }
12070
+ },
12071
+ {
12072
+ "kind": "method",
12073
+ "name": "#unsubscribe",
12074
+ "privacy": "private",
12075
+ "return": {
12076
+ "type": {
12077
+ "text": "void"
12078
+ }
12079
+ }
12080
+ },
12081
+ {
12082
+ "kind": "field",
12083
+ "name": "#onScroll",
12084
+ "privacy": "private"
12085
+ },
12086
+ {
12087
+ "kind": "method",
12088
+ "name": "#onClick",
12089
+ "privacy": "private",
12090
+ "return": {
12091
+ "type": {
12092
+ "text": "void"
12093
+ }
12094
+ }
12095
+ }
12096
+ ],
12097
+ "events": [
12098
+ {
12099
+ "name": "scroll-to-top-triggered",
12100
+ "type": {
12101
+ "text": "CustomEvent"
12102
+ },
12103
+ "description": "The button was clicked, just before scrolling; detail: `{ target }`."
12104
+ }
12105
+ ],
12106
+ "attributes": [
12107
+ {
12108
+ "name": "threshold",
12109
+ "type": {
12110
+ "text": "number"
12111
+ },
12112
+ "default": "200",
12113
+ "description": "Pixels scrolled away from the top before the button appears.",
12114
+ "fieldName": "threshold"
12115
+ },
12116
+ {
12117
+ "name": "label",
12118
+ "type": {
12119
+ "text": "string"
12120
+ },
12121
+ "default": "\"Scroll to top\"",
12122
+ "description": "Visible button text, and its accessible name.",
12123
+ "fieldName": "label"
12124
+ }
12125
+ ],
12126
+ "superclass": {
12127
+ "name": "LitElement",
12128
+ "package": "lit"
12129
+ },
12130
+ "tagName": "scroll-to-top",
12131
+ "customElement": true
12132
+ }
12133
+ ],
12134
+ "exports": [
12135
+ {
12136
+ "kind": "js",
12137
+ "name": "ScrollToTop",
12138
+ "declaration": {
12139
+ "name": "ScrollToTop",
12140
+ "module": "src/scroll-to-top.ts"
12141
+ }
12142
+ },
12143
+ {
12144
+ "kind": "custom-element-definition",
12145
+ "name": "scroll-to-top",
12146
+ "declaration": {
12147
+ "name": "ScrollToTop",
12148
+ "module": "src/scroll-to-top.ts"
12149
+ }
12150
+ }
12151
+ ]
12152
+ },
12153
+ {
12154
+ "kind": "javascript-module",
12155
+ "path": "src/slide-panel.ts",
12156
+ "declarations": [
12157
+ {
12158
+ "kind": "class",
12159
+ "description": "Generic sliding panel shell. Handles positioning, open/close animation,\nheader chrome, and a close button. Body content is provided via the\ndefault slot; the consumer controls its own padding and overflow.\n\nDesktop: fixed right-side panel that slides from the right.\nMobile (≤48rem): bottom-sheet drawer (60vh) — reserved for future use.",
12160
+ "name": "SlidePanel",
12161
+ "members": [
12162
+ {
12163
+ "kind": "field",
12164
+ "name": "open",
12165
+ "type": {
12166
+ "text": "boolean"
12167
+ },
12168
+ "default": "false",
12169
+ "description": "Whether the panel is currently visible.",
12170
+ "attribute": "open"
12171
+ },
12172
+ {
12173
+ "kind": "field",
12174
+ "name": "heading",
12175
+ "type": {
12176
+ "text": "string"
12177
+ },
12178
+ "default": "\"\"",
12179
+ "description": "Title text shown in the panel header (overridable via slot=\"title\").",
12180
+ "attribute": "heading"
12181
+ },
12182
+ {
12183
+ "kind": "field",
12184
+ "name": "_previousFocus",
12185
+ "type": {
12186
+ "text": "HTMLElement | null"
12187
+ },
12188
+ "privacy": "private",
12189
+ "default": "null"
12190
+ },
12191
+ {
12192
+ "kind": "method",
12193
+ "name": "_close",
12194
+ "privacy": "private"
12195
+ },
12196
+ {
12197
+ "kind": "field",
12198
+ "name": "_onWindowKeydown",
12199
+ "privacy": "private"
12200
+ }
12201
+ ],
12202
+ "events": [
11292
12203
  {
11293
12204
  "name": "panel-close",
11294
12205
  "type": {
@@ -12306,154 +13217,669 @@
12306
13217
  },
12307
13218
  {
12308
13219
  "kind": "javascript-module",
12309
- "path": "src/ui-button.ts",
13220
+ "path": "src/tree-view.ts",
12310
13221
  "declarations": [
12311
13222
  {
12312
13223
  "kind": "class",
12313
- "description": "Button (or link styled as one) with an optional leading icon, in three\nvisual weights. Set `href` to render an `<a>` instead of a `<button>` —\nsame styling either way for cross-page navigation that should look like\nan action button; a disabled/busy link stays a real `<a>` with\n`aria-disabled` + `pointer-events: none` rather than losing its href.\nPut the icon in the `icon` slot and the label in the default slot.\n\nForm-associated (`type=\"submit\"`/`\"reset\"`): the actual `<button>` lives in\nthis element's shadow root, which native HTML form association does not\ncross into from an ancestor light-DOM `<form>`. `type=\"submit\"`/`\"reset\"`\nis instead wired through `ElementInternals.form` — the same mechanism\n`address-autocomplete` uses to associate with an ancestor form.",
12314
- "name": "UiButton",
12315
- "slots": [
12316
- {
12317
- "description": "Optional leading icon (e.g. an inline SVG).",
12318
- "name": "icon"
12319
- },
12320
- {
12321
- "description": "Button label.",
12322
- "name": ""
12323
- }
12324
- ],
13224
+ "description": "A generic, presentational tree shell: renders `nodes` recursively, one row\nper node, with each row's content produced by `renderNode` (default: plain\nlabel). Modeled on `data-table`'s headless pattern knows nothing about\nwhat a node's `data` means beyond what `renderNode` does with it.\n\nA node with a `children` array (even empty) is a folder: clicking or\nactivating its row toggles expand/collapse instead of firing `node-click`.\nA node with no `children` is a leaf: clicking or activating its row fires\n`node-click`. Folders start collapsed; set `default-expanded` to start\nevery folder expanded instead. Expansion state is otherwise managed\ninternally and untouched by later `nodes` updates, so a user's manual\ntoggles survive a data refresh.",
13225
+ "name": "TreeView",
12325
13226
  "members": [
12326
13227
  {
12327
13228
  "kind": "field",
12328
- "name": "formAssociated",
13229
+ "name": "nodes",
12329
13230
  "type": {
12330
- "text": "boolean"
13231
+ "text": "TreeNode[]"
12331
13232
  },
12332
- "static": true,
12333
- "default": "true"
13233
+ "default": "[]",
13234
+ "description": "Tree data; opaque to this component beyond what `renderNode` does with it."
12334
13235
  },
12335
13236
  {
12336
13237
  "kind": "field",
12337
- "name": "#internals",
12338
- "privacy": "private"
13238
+ "name": "renderNode",
13239
+ "type": {
13240
+ "text": "(node: TreeNode) => unknown"
13241
+ },
13242
+ "description": "Produces a row's rendered content for `node`. Default: plain label text."
12339
13243
  },
12340
13244
  {
12341
13245
  "kind": "field",
12342
- "name": "variant",
13246
+ "name": "defaultExpanded",
12343
13247
  "type": {
12344
- "text": "ButtonVariant"
13248
+ "text": "boolean"
12345
13249
  },
12346
- "default": "\"primary\"",
12347
- "description": "Visual weight.",
12348
- "attribute": "variant"
13250
+ "default": "false",
13251
+ "description": "Start every folder expanded instead of the default all-collapsed.",
13252
+ "attribute": "default-expanded"
12349
13253
  },
12350
13254
  {
12351
13255
  "kind": "field",
12352
- "name": "size",
12353
- "type": {
12354
- "text": "\"sm\" | \"md\""
12355
- },
12356
- "default": "\"md\"",
12357
- "description": "Size — `sm` reduces height/padding/font-size one step below the default.",
12358
- "attribute": "size"
13256
+ "name": "expanded",
13257
+ "privacy": "private",
13258
+ "default": "new Set<string>()"
12359
13259
  },
12360
13260
  {
12361
13261
  "kind": "field",
12362
- "name": "href",
13262
+ "name": "#initializedExpansion",
13263
+ "privacy": "private",
13264
+ "type": {
13265
+ "text": "boolean"
13266
+ },
13267
+ "default": "false"
13268
+ },
13269
+ {
13270
+ "kind": "method",
13271
+ "name": "#toggle",
13272
+ "privacy": "private",
13273
+ "return": {
13274
+ "type": {
13275
+ "text": "void"
13276
+ }
13277
+ },
13278
+ "parameters": [
13279
+ {
13280
+ "name": "id",
13281
+ "type": {
13282
+ "text": "string"
13283
+ }
13284
+ }
13285
+ ]
13286
+ },
13287
+ {
13288
+ "kind": "method",
13289
+ "name": "#activate",
13290
+ "privacy": "private",
13291
+ "return": {
13292
+ "type": {
13293
+ "text": "void"
13294
+ }
13295
+ },
13296
+ "parameters": [
13297
+ {
13298
+ "name": "node",
13299
+ "type": {
13300
+ "text": "TreeNode"
13301
+ }
13302
+ }
13303
+ ]
13304
+ },
13305
+ {
13306
+ "kind": "method",
13307
+ "name": "#onKeydown",
13308
+ "privacy": "private",
13309
+ "return": {
13310
+ "type": {
13311
+ "text": "void"
13312
+ }
13313
+ },
13314
+ "parameters": [
13315
+ {
13316
+ "name": "node",
13317
+ "type": {
13318
+ "text": "TreeNode"
13319
+ }
13320
+ },
13321
+ {
13322
+ "name": "e",
13323
+ "type": {
13324
+ "text": "KeyboardEvent"
13325
+ }
13326
+ }
13327
+ ]
13328
+ },
13329
+ {
13330
+ "kind": "method",
13331
+ "name": "#onRowClick",
13332
+ "privacy": "private",
13333
+ "return": {
13334
+ "type": {
13335
+ "text": "void"
13336
+ }
13337
+ },
13338
+ "parameters": [
13339
+ {
13340
+ "name": "node",
13341
+ "type": {
13342
+ "text": "TreeNode"
13343
+ }
13344
+ },
13345
+ {
13346
+ "name": "e",
13347
+ "type": {
13348
+ "text": "MouseEvent"
13349
+ }
13350
+ }
13351
+ ]
13352
+ },
13353
+ {
13354
+ "kind": "method",
13355
+ "name": "#isNestedInteractive",
13356
+ "privacy": "private",
13357
+ "return": {
13358
+ "type": {
13359
+ "text": "boolean"
13360
+ }
13361
+ },
13362
+ "parameters": [
13363
+ {
13364
+ "name": "path",
13365
+ "type": {
13366
+ "text": "EventTarget[]"
13367
+ }
13368
+ },
13369
+ {
13370
+ "name": "row",
13371
+ "type": {
13372
+ "text": "EventTarget | null"
13373
+ }
13374
+ }
13375
+ ]
13376
+ },
13377
+ {
13378
+ "kind": "method",
13379
+ "name": "#renderNode",
13380
+ "privacy": "private",
13381
+ "return": {
13382
+ "type": {
13383
+ "text": "TemplateResult"
13384
+ }
13385
+ },
13386
+ "parameters": [
13387
+ {
13388
+ "name": "node",
13389
+ "type": {
13390
+ "text": "TreeNode"
13391
+ }
13392
+ },
13393
+ {
13394
+ "name": "depth",
13395
+ "type": {
13396
+ "text": "number"
13397
+ }
13398
+ }
13399
+ ]
13400
+ }
13401
+ ],
13402
+ "events": [
13403
+ {
13404
+ "name": "node-click",
13405
+ "type": {
13406
+ "text": "CustomEvent"
13407
+ },
13408
+ "description": "A leaf row was activated; detail is `{ id, data }`."
13409
+ }
13410
+ ],
13411
+ "attributes": [
13412
+ {
13413
+ "name": "default-expanded",
13414
+ "type": {
13415
+ "text": "boolean"
13416
+ },
13417
+ "default": "false",
13418
+ "description": "Start every folder expanded instead of the default all-collapsed.",
13419
+ "fieldName": "defaultExpanded"
13420
+ }
13421
+ ],
13422
+ "superclass": {
13423
+ "name": "LitElement",
13424
+ "package": "lit"
13425
+ },
13426
+ "tagName": "tree-view",
13427
+ "customElement": true
13428
+ }
13429
+ ],
13430
+ "exports": [
13431
+ {
13432
+ "kind": "js",
13433
+ "name": "TreeView",
13434
+ "declaration": {
13435
+ "name": "TreeView",
13436
+ "module": "src/tree-view.ts"
13437
+ }
13438
+ },
13439
+ {
13440
+ "kind": "custom-element-definition",
13441
+ "name": "tree-view",
13442
+ "declaration": {
13443
+ "name": "TreeView",
13444
+ "module": "src/tree-view.ts"
13445
+ }
13446
+ }
13447
+ ]
13448
+ },
13449
+ {
13450
+ "kind": "javascript-module",
13451
+ "path": "src/ui-button.ts",
13452
+ "declarations": [
13453
+ {
13454
+ "kind": "class",
13455
+ "description": "Button (or link styled as one) with an optional leading icon, in three\nvisual weights. Set `href` to render an `<a>` instead of a `<button>` —\nsame styling either way — for cross-page navigation that should look like\nan action button; a disabled/busy link stays a real `<a>` with\n`aria-disabled` + `pointer-events: none` rather than losing its href.\nPut the icon in the `icon` slot and the label in the default slot.\n\nForm-associated (`type=\"submit\"`/`\"reset\"`): the actual `<button>` lives in\nthis element's shadow root, which native HTML form association does not\ncross into from an ancestor light-DOM `<form>`. `type=\"submit\"`/`\"reset\"`\nis instead wired through `ElementInternals.form` — the same mechanism\n`address-autocomplete` uses to associate with an ancestor form.",
13456
+ "name": "UiButton",
13457
+ "slots": [
13458
+ {
13459
+ "description": "Optional leading icon (e.g. an inline SVG).",
13460
+ "name": "icon"
13461
+ },
13462
+ {
13463
+ "description": "Button label.",
13464
+ "name": ""
13465
+ }
13466
+ ],
13467
+ "members": [
13468
+ {
13469
+ "kind": "field",
13470
+ "name": "formAssociated",
13471
+ "type": {
13472
+ "text": "boolean"
13473
+ },
13474
+ "static": true,
13475
+ "default": "true"
13476
+ },
13477
+ {
13478
+ "kind": "field",
13479
+ "name": "#internals",
13480
+ "privacy": "private"
13481
+ },
13482
+ {
13483
+ "kind": "field",
13484
+ "name": "variant",
13485
+ "type": {
13486
+ "text": "ButtonVariant"
13487
+ },
13488
+ "default": "\"primary\"",
13489
+ "description": "Visual weight.",
13490
+ "attribute": "variant"
13491
+ },
13492
+ {
13493
+ "kind": "field",
13494
+ "name": "size",
13495
+ "type": {
13496
+ "text": "\"sm\" | \"md\""
13497
+ },
13498
+ "default": "\"md\"",
13499
+ "description": "Size — `sm` reduces height/padding/font-size one step below the default.",
13500
+ "attribute": "size"
13501
+ },
13502
+ {
13503
+ "kind": "field",
13504
+ "name": "href",
13505
+ "type": {
13506
+ "text": "string | null"
13507
+ },
13508
+ "default": "null",
13509
+ "description": "Renders an `<a href=\"...\">` instead of a `<button>` when set.",
13510
+ "attribute": "href"
13511
+ },
13512
+ {
13513
+ "kind": "field",
13514
+ "name": "type",
13515
+ "type": {
13516
+ "text": "\"button\" | \"submit\" | \"reset\""
13517
+ },
13518
+ "default": "\"button\"",
13519
+ "description": "Native button `type`. Ignored when `href` is set.",
13520
+ "attribute": "type"
13521
+ },
13522
+ {
13523
+ "kind": "field",
13524
+ "name": "disabled",
13525
+ "type": {
13526
+ "text": "boolean"
13527
+ },
13528
+ "default": "false",
13529
+ "description": "Disables the control and dims it.",
13530
+ "attribute": "disabled"
13531
+ },
13532
+ {
13533
+ "kind": "field",
13534
+ "name": "busy",
13535
+ "type": {
13536
+ "text": "boolean"
13537
+ },
13538
+ "default": "false",
13539
+ "description": "Shows a spinner in place of the icon slot and disables the control.",
13540
+ "attribute": "busy"
13541
+ },
13542
+ {
13543
+ "kind": "method",
13544
+ "name": "_onClick",
13545
+ "privacy": "private",
13546
+ "description": "Drives submit/reset on the ancestor form via ElementInternals, since a shadow-DOM button can't do it natively."
13547
+ },
13548
+ {
13549
+ "kind": "method",
13550
+ "name": "_onLinkClick",
13551
+ "privacy": "private",
13552
+ "parameters": [
13553
+ {
13554
+ "name": "e",
13555
+ "type": {
13556
+ "text": "MouseEvent"
13557
+ }
13558
+ }
13559
+ ],
13560
+ "description": "Suppresses navigation while a link-styled button is disabled or busy."
13561
+ }
13562
+ ],
13563
+ "attributes": [
13564
+ {
13565
+ "name": "variant",
13566
+ "type": {
13567
+ "text": "ButtonVariant"
13568
+ },
13569
+ "default": "\"primary\"",
13570
+ "description": "Visual weight.",
13571
+ "fieldName": "variant"
13572
+ },
13573
+ {
13574
+ "name": "size",
13575
+ "type": {
13576
+ "text": "\"sm\" | \"md\""
13577
+ },
13578
+ "default": "\"md\"",
13579
+ "description": "Size — `sm` reduces height/padding/font-size one step below the default.",
13580
+ "fieldName": "size"
13581
+ },
13582
+ {
13583
+ "name": "href",
13584
+ "type": {
13585
+ "text": "string | null"
13586
+ },
13587
+ "default": "null",
13588
+ "description": "Renders an `<a href=\"...\">` instead of a `<button>` when set.",
13589
+ "fieldName": "href"
13590
+ },
13591
+ {
13592
+ "name": "type",
13593
+ "type": {
13594
+ "text": "\"button\" | \"submit\" | \"reset\""
13595
+ },
13596
+ "default": "\"button\"",
13597
+ "description": "Native button `type`. Ignored when `href` is set.",
13598
+ "fieldName": "type"
13599
+ },
13600
+ {
13601
+ "name": "disabled",
13602
+ "type": {
13603
+ "text": "boolean"
13604
+ },
13605
+ "default": "false",
13606
+ "description": "Disables the control and dims it.",
13607
+ "fieldName": "disabled"
13608
+ },
13609
+ {
13610
+ "name": "busy",
13611
+ "type": {
13612
+ "text": "boolean"
13613
+ },
13614
+ "default": "false",
13615
+ "description": "Shows a spinner in place of the icon slot and disables the control.",
13616
+ "fieldName": "busy"
13617
+ }
13618
+ ],
13619
+ "superclass": {
13620
+ "name": "LitElement",
13621
+ "package": "lit"
13622
+ },
13623
+ "tagName": "ui-button",
13624
+ "customElement": true
13625
+ }
13626
+ ],
13627
+ "exports": [
13628
+ {
13629
+ "kind": "js",
13630
+ "name": "UiButton",
13631
+ "declaration": {
13632
+ "name": "UiButton",
13633
+ "module": "src/ui-button.ts"
13634
+ }
13635
+ },
13636
+ {
13637
+ "kind": "custom-element-definition",
13638
+ "name": "ui-button",
13639
+ "declaration": {
13640
+ "name": "UiButton",
13641
+ "module": "src/ui-button.ts"
13642
+ }
13643
+ }
13644
+ ]
13645
+ },
13646
+ {
13647
+ "kind": "javascript-module",
13648
+ "path": "src/ui-checkbox.ts",
13649
+ "declarations": [
13650
+ {
13651
+ "kind": "class",
13652
+ "description": "A form-associated boolean checkbox, usable standalone or inside a native\n`<form>`. Submits `name=on` when checked (matching native\n`<input type=\"checkbox\">` semantics) and participates fully in form\n`reset()`, ancestor `<fieldset disabled>`, and `required` validity.\n\nRenders a native `<input type=\"checkbox\">` wrapped in a `<label>`, styled\nvia `:has()` on the wrapping label (matching `radio-pills`/`radio-cards`)\nrather than styling the native input directly; the checkbox itself renders\nat `1rem`, matching the existing radio-input convention.",
13653
+ "name": "UiCheckbox",
13654
+ "members": [
13655
+ {
13656
+ "kind": "field",
13657
+ "name": "formAssociated",
13658
+ "type": {
13659
+ "text": "boolean"
13660
+ },
13661
+ "static": true,
13662
+ "default": "true"
13663
+ },
13664
+ {
13665
+ "kind": "field",
13666
+ "name": "checked",
13667
+ "type": {
13668
+ "text": "boolean"
13669
+ },
13670
+ "default": "false",
13671
+ "description": "Whether the box is checked.",
13672
+ "attribute": "checked"
13673
+ },
13674
+ {
13675
+ "kind": "field",
13676
+ "name": "indeterminate",
13677
+ "type": {
13678
+ "text": "boolean"
13679
+ },
13680
+ "default": "false",
13681
+ "description": "Visual \"partial selection\" state; cleared on the next user interaction.",
13682
+ "attribute": "indeterminate"
13683
+ },
13684
+ {
13685
+ "kind": "field",
13686
+ "name": "disabled",
13687
+ "type": {
13688
+ "text": "boolean"
13689
+ },
13690
+ "default": "false",
13691
+ "description": "Disables interaction; merged with an ancestor `<fieldset disabled>`.",
13692
+ "attribute": "disabled"
13693
+ },
13694
+ {
13695
+ "kind": "field",
13696
+ "name": "required",
13697
+ "type": {
13698
+ "text": "boolean"
13699
+ },
13700
+ "default": "false",
13701
+ "description": "Marks the control invalid via `ElementInternals` while unchecked.",
13702
+ "attribute": "required"
13703
+ },
13704
+ {
13705
+ "kind": "field",
13706
+ "name": "name",
13707
+ "type": {
13708
+ "text": "string"
13709
+ },
13710
+ "default": "\"\"",
13711
+ "description": "Form field name; submitted as `name=on` only while checked.",
13712
+ "attribute": "name"
13713
+ },
13714
+ {
13715
+ "kind": "field",
13716
+ "name": "label",
12363
13717
  "type": {
12364
- "text": "string | null"
13718
+ "text": "string"
12365
13719
  },
12366
- "default": "null",
12367
- "description": "Renders an `<a href=\"...\">` instead of a `<button>` when set.",
12368
- "attribute": "href"
13720
+ "default": "\"\"",
13721
+ "description": "Visible label text rendered next to the box.",
13722
+ "attribute": "label"
12369
13723
  },
12370
13724
  {
12371
13725
  "kind": "field",
12372
- "name": "type",
13726
+ "name": "_formDisabled",
12373
13727
  "type": {
12374
- "text": "\"button\" | \"submit\" | \"reset\""
13728
+ "text": "boolean"
12375
13729
  },
12376
- "default": "\"button\"",
12377
- "description": "Native button `type`. Ignored when `href` is set.",
12378
- "attribute": "type"
13730
+ "privacy": "private",
13731
+ "default": "false"
12379
13732
  },
12380
13733
  {
12381
13734
  "kind": "field",
12382
- "name": "disabled",
13735
+ "name": "#internals",
13736
+ "privacy": "private"
13737
+ },
13738
+ {
13739
+ "kind": "field",
13740
+ "name": "#defaultChecked",
13741
+ "privacy": "private",
12383
13742
  "type": {
12384
13743
  "text": "boolean"
12385
13744
  },
12386
- "default": "false",
12387
- "description": "Disables the control and dims it.",
12388
- "attribute": "disabled"
13745
+ "default": "false"
12389
13746
  },
12390
13747
  {
12391
13748
  "kind": "field",
12392
- "name": "busy",
13749
+ "name": "#inputEl",
13750
+ "privacy": "private",
13751
+ "type": {
13752
+ "text": "HTMLInputElement | null"
13753
+ },
13754
+ "default": "null"
13755
+ },
13756
+ {
13757
+ "kind": "field",
13758
+ "name": "#isDisabled",
13759
+ "privacy": "private",
12393
13760
  "type": {
12394
13761
  "text": "boolean"
12395
13762
  },
12396
- "default": "false",
12397
- "description": "Shows a spinner in place of the icon slot and disables the control.",
12398
- "attribute": "busy"
13763
+ "description": "Whether the host or an ancestor fieldset currently disables the control.",
13764
+ "readonly": true
12399
13765
  },
12400
13766
  {
12401
13767
  "kind": "method",
12402
- "name": "_onClick",
13768
+ "name": "formResetCallback",
13769
+ "return": {
13770
+ "type": {
13771
+ "text": "void"
13772
+ }
13773
+ },
13774
+ "description": "Restores the checked state captured at first render, per the form contract."
13775
+ },
13776
+ {
13777
+ "kind": "method",
13778
+ "name": "formDisabledCallback",
13779
+ "return": {
13780
+ "type": {
13781
+ "text": "void"
13782
+ }
13783
+ },
13784
+ "parameters": [
13785
+ {
13786
+ "name": "disabled",
13787
+ "type": {
13788
+ "text": "boolean"
13789
+ }
13790
+ }
13791
+ ],
13792
+ "description": "Mirrors an ancestor fieldset's disabled state."
13793
+ },
13794
+ {
13795
+ "kind": "method",
13796
+ "name": "formStateRestoreCallback",
13797
+ "return": {
13798
+ "type": {
13799
+ "text": "void"
13800
+ }
13801
+ },
13802
+ "parameters": [
13803
+ {
13804
+ "name": "state",
13805
+ "type": {
13806
+ "text": "string | File | FormData | null"
13807
+ }
13808
+ }
13809
+ ],
13810
+ "description": "Restores the checked state from saved form state (bfcache/autofill)."
13811
+ },
13812
+ {
13813
+ "kind": "method",
13814
+ "name": "#syncFormValue",
12403
13815
  "privacy": "private",
12404
- "description": "Drives submit/reset on the ancestor form via ElementInternals, since a shadow-DOM button can't do it natively."
13816
+ "return": {
13817
+ "type": {
13818
+ "text": "void"
13819
+ }
13820
+ }
12405
13821
  },
12406
13822
  {
12407
13823
  "kind": "method",
12408
- "name": "_onLinkClick",
13824
+ "name": "#syncValidity",
13825
+ "privacy": "private",
13826
+ "return": {
13827
+ "type": {
13828
+ "text": "void"
13829
+ }
13830
+ }
13831
+ },
13832
+ {
13833
+ "kind": "method",
13834
+ "name": "#onChange",
12409
13835
  "privacy": "private",
13836
+ "return": {
13837
+ "type": {
13838
+ "text": "void"
13839
+ }
13840
+ },
12410
13841
  "parameters": [
12411
13842
  {
12412
13843
  "name": "e",
12413
13844
  "type": {
12414
- "text": "MouseEvent"
13845
+ "text": "Event"
12415
13846
  }
12416
13847
  }
12417
- ],
12418
- "description": "Suppresses navigation while a link-styled button is disabled or busy."
13848
+ ]
13849
+ },
13850
+ {
13851
+ "kind": "field",
13852
+ "name": "#onInputRef",
13853
+ "privacy": "private"
12419
13854
  }
12420
13855
  ],
12421
- "attributes": [
12422
- {
12423
- "name": "variant",
12424
- "type": {
12425
- "text": "ButtonVariant"
12426
- },
12427
- "default": "\"primary\"",
12428
- "description": "Visual weight.",
12429
- "fieldName": "variant"
12430
- },
13856
+ "events": [
12431
13857
  {
12432
- "name": "size",
13858
+ "name": "change",
12433
13859
  "type": {
12434
- "text": "\"sm\" | \"md\""
13860
+ "text": "CustomEvent"
12435
13861
  },
12436
- "default": "\"md\"",
12437
- "description": "Size — `sm` reduces height/padding/font-size one step below the default.",
12438
- "fieldName": "size"
12439
- },
13862
+ "description": "The checkbox was toggled by the user, in either direction; detail: `{ checked }`. Programmatic `checked` assignments do not fire it."
13863
+ }
13864
+ ],
13865
+ "attributes": [
12440
13866
  {
12441
- "name": "href",
13867
+ "name": "checked",
12442
13868
  "type": {
12443
- "text": "string | null"
13869
+ "text": "boolean"
12444
13870
  },
12445
- "default": "null",
12446
- "description": "Renders an `<a href=\"...\">` instead of a `<button>` when set.",
12447
- "fieldName": "href"
13871
+ "default": "false",
13872
+ "description": "Whether the box is checked.",
13873
+ "fieldName": "checked"
12448
13874
  },
12449
13875
  {
12450
- "name": "type",
13876
+ "name": "indeterminate",
12451
13877
  "type": {
12452
- "text": "\"button\" | \"submit\" | \"reset\""
13878
+ "text": "boolean"
12453
13879
  },
12454
- "default": "\"button\"",
12455
- "description": "Native button `type`. Ignored when `href` is set.",
12456
- "fieldName": "type"
13880
+ "default": "false",
13881
+ "description": "Visual \"partial selection\" state; cleared on the next user interaction.",
13882
+ "fieldName": "indeterminate"
12457
13883
  },
12458
13884
  {
12459
13885
  "name": "disabled",
@@ -12461,42 +13887,60 @@
12461
13887
  "text": "boolean"
12462
13888
  },
12463
13889
  "default": "false",
12464
- "description": "Disables the control and dims it.",
13890
+ "description": "Disables interaction; merged with an ancestor `<fieldset disabled>`.",
12465
13891
  "fieldName": "disabled"
12466
13892
  },
12467
13893
  {
12468
- "name": "busy",
13894
+ "name": "required",
12469
13895
  "type": {
12470
13896
  "text": "boolean"
12471
13897
  },
12472
13898
  "default": "false",
12473
- "description": "Shows a spinner in place of the icon slot and disables the control.",
12474
- "fieldName": "busy"
13899
+ "description": "Marks the control invalid via `ElementInternals` while unchecked.",
13900
+ "fieldName": "required"
13901
+ },
13902
+ {
13903
+ "name": "name",
13904
+ "type": {
13905
+ "text": "string"
13906
+ },
13907
+ "default": "\"\"",
13908
+ "description": "Form field name; submitted as `name=on` only while checked.",
13909
+ "fieldName": "name"
13910
+ },
13911
+ {
13912
+ "name": "label",
13913
+ "type": {
13914
+ "text": "string"
13915
+ },
13916
+ "default": "\"\"",
13917
+ "description": "Visible label text rendered next to the box.",
13918
+ "fieldName": "label"
12475
13919
  }
12476
13920
  ],
12477
13921
  "superclass": {
12478
13922
  "name": "LitElement",
12479
13923
  "package": "lit"
12480
13924
  },
12481
- "tagName": "ui-button",
13925
+ "tagName": "ui-checkbox",
12482
13926
  "customElement": true
12483
13927
  }
12484
13928
  ],
12485
13929
  "exports": [
12486
13930
  {
12487
13931
  "kind": "js",
12488
- "name": "UiButton",
13932
+ "name": "UiCheckbox",
12489
13933
  "declaration": {
12490
- "name": "UiButton",
12491
- "module": "src/ui-button.ts"
13934
+ "name": "UiCheckbox",
13935
+ "module": "src/ui-checkbox.ts"
12492
13936
  }
12493
13937
  },
12494
13938
  {
12495
13939
  "kind": "custom-element-definition",
12496
- "name": "ui-button",
13940
+ "name": "ui-checkbox",
12497
13941
  "declaration": {
12498
- "name": "UiButton",
12499
- "module": "src/ui-button.ts"
13942
+ "name": "UiCheckbox",
13943
+ "module": "src/ui-checkbox.ts"
12500
13944
  }
12501
13945
  }
12502
13946
  ]
@@ -13266,6 +14710,98 @@
13266
14710
  }
13267
14711
  ]
13268
14712
  },
14713
+ {
14714
+ "kind": "javascript-module",
14715
+ "path": "src/utils/scroll.ts",
14716
+ "declarations": [
14717
+ {
14718
+ "kind": "function",
14719
+ "name": "distanceFromTop",
14720
+ "return": {
14721
+ "type": {
14722
+ "text": "number"
14723
+ }
14724
+ },
14725
+ "parameters": [
14726
+ {
14727
+ "name": "target",
14728
+ "type": {
14729
+ "text": "ScrollableTarget"
14730
+ }
14731
+ }
14732
+ ],
14733
+ "description": "Pixels between the current scroll position and the top edge."
14734
+ },
14735
+ {
14736
+ "kind": "function",
14737
+ "name": "distanceFromBottom",
14738
+ "return": {
14739
+ "type": {
14740
+ "text": "number"
14741
+ }
14742
+ },
14743
+ "parameters": [
14744
+ {
14745
+ "name": "target",
14746
+ "type": {
14747
+ "text": "ScrollableTarget"
14748
+ }
14749
+ }
14750
+ ],
14751
+ "description": "Pixels between the current scroll position and the bottom edge."
14752
+ },
14753
+ {
14754
+ "kind": "function",
14755
+ "name": "scrollToEdge",
14756
+ "return": {
14757
+ "type": {
14758
+ "text": "void"
14759
+ }
14760
+ },
14761
+ "parameters": [
14762
+ {
14763
+ "name": "target",
14764
+ "type": {
14765
+ "text": "ScrollableTarget"
14766
+ }
14767
+ },
14768
+ {
14769
+ "name": "edge",
14770
+ "type": {
14771
+ "text": "\"top\" | \"bottom\""
14772
+ }
14773
+ }
14774
+ ],
14775
+ "description": "Scrolls `target` to its top or bottom edge, honoring `prefers-reduced-motion`."
14776
+ }
14777
+ ],
14778
+ "exports": [
14779
+ {
14780
+ "kind": "js",
14781
+ "name": "distanceFromTop",
14782
+ "declaration": {
14783
+ "name": "distanceFromTop",
14784
+ "module": "src/utils/scroll.ts"
14785
+ }
14786
+ },
14787
+ {
14788
+ "kind": "js",
14789
+ "name": "distanceFromBottom",
14790
+ "declaration": {
14791
+ "name": "distanceFromBottom",
14792
+ "module": "src/utils/scroll.ts"
14793
+ }
14794
+ },
14795
+ {
14796
+ "kind": "js",
14797
+ "name": "scrollToEdge",
14798
+ "declaration": {
14799
+ "name": "scrollToEdge",
14800
+ "module": "src/utils/scroll.ts"
14801
+ }
14802
+ }
14803
+ ]
14804
+ },
13269
14805
  {
13270
14806
  "kind": "javascript-module",
13271
14807
  "path": "src/utils/time.ts",