@f-ewald/components 1.12.0 → 1.14.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 (62) hide show
  1. package/README.md +6 -0
  2. package/custom-elements.json +1376 -49
  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 +6 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +6 -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/map-circle.d.ts +12 -9
  24. package/dist/map-circle.d.ts.map +1 -1
  25. package/dist/map-circle.js +26 -12
  26. package/dist/map-circle.js.map +1 -1
  27. package/dist/map-pin.d.ts +7 -5
  28. package/dist/map-pin.d.ts.map +1 -1
  29. package/dist/map-pin.js +14 -8
  30. package/dist/map-pin.js.map +1 -1
  31. package/dist/percent-bar-chart.d.ts +32 -3
  32. package/dist/percent-bar-chart.d.ts.map +1 -1
  33. package/dist/percent-bar-chart.js +101 -36
  34. package/dist/percent-bar-chart.js.map +1 -1
  35. package/dist/scroll-to-bottom.d.ts +41 -0
  36. package/dist/scroll-to-bottom.d.ts.map +1 -0
  37. package/dist/scroll-to-bottom.js +189 -0
  38. package/dist/scroll-to-bottom.js.map +1 -0
  39. package/dist/scroll-to-top.d.ts +41 -0
  40. package/dist/scroll-to-top.d.ts.map +1 -0
  41. package/dist/scroll-to-top.js +189 -0
  42. package/dist/scroll-to-top.js.map +1 -0
  43. package/dist/ui-checkbox.d.ts +49 -0
  44. package/dist/ui-checkbox.d.ts.map +1 -0
  45. package/dist/ui-checkbox.js +228 -0
  46. package/dist/ui-checkbox.js.map +1 -0
  47. package/dist/utils/scroll.d.ts +9 -0
  48. package/dist/utils/scroll.d.ts.map +1 -0
  49. package/dist/utils/scroll.js +30 -0
  50. package/dist/utils/scroll.js.map +1 -0
  51. package/docs/auto-scroll.md +52 -0
  52. package/docs/form-field.md +63 -0
  53. package/docs/layouts/form-page.md +8 -4
  54. package/docs/load-more.md +43 -0
  55. package/docs/map-circle.md +11 -9
  56. package/docs/map-pin.md +6 -5
  57. package/docs/percent-bar-chart.md +19 -5
  58. package/docs/scroll-to-bottom.md +68 -0
  59. package/docs/scroll-to-top.md +59 -0
  60. package/docs/ui-checkbox.md +58 -0
  61. package/llms.txt +199 -20
  62. 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",
@@ -6805,9 +7133,17 @@
6805
7133
  },
6806
7134
  {
6807
7135
  "kind": "js",
6808
- "name": "formatDuration",
7136
+ "name": "AutoScroll",
6809
7137
  "declaration": {
6810
- "name": "formatDuration",
7138
+ "name": "AutoScroll",
7139
+ "module": "./auto-scroll.js"
7140
+ }
7141
+ },
7142
+ {
7143
+ "kind": "js",
7144
+ "name": "formatDuration",
7145
+ "declaration": {
7146
+ "name": "formatDuration",
6811
7147
  "module": "./utils/duration.js"
6812
7148
  }
6813
7149
  },
@@ -8086,13 +8422,166 @@
8086
8422
  }
8087
8423
  ]
8088
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
+ },
8089
8578
  {
8090
8579
  "kind": "javascript-module",
8091
8580
  "path": "src/map-circle.ts",
8092
8581
  "declarations": [
8093
8582
  {
8094
8583
  "kind": "class",
8095
- "description": "A plain circular map marker: a light-to-dark gradient fill with a white\nouter ring, no point/tail (unlike `<map-pin>`) for markers that don't\nneed to visually \"point\" at their exact coordinate. Purely a visual\nprimitive — it has no `mapbox-gl` (or any mapping library) dependency;\nthe consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.\nIt can also replace the former `<map-point>` dense-layer primitive: use\n`size=\"14\" ring-width=\"3\"`, leave the slot empty, and rasterize one marker\nper color for use as a map `icon-image`.",
8584
+ "description": "A plain circular map marker: a radial-gradient fill with a soft highlight\nand a translucent white outer ring, no point/tail (unlike `<map-pin>`) —\nfor markers that don't need to visually \"point\" at their exact\ncoordinate. Purely a visual primitive — it has no `mapbox-gl` (or any\nmapping library) dependency; the consumer positions it, e.g. via\n`new mapboxgl.Marker({ element: el })`. It can also replace the former\n`<map-point>` dense-layer primitive: use `size=\"14\" ring-width=\"3\"`, leave\nthe slot empty, and rasterize one marker per color for use as a map\n`icon-image`.",
8096
8585
  "name": "MapCircle",
8097
8586
  "slots": [
8098
8587
  {
@@ -8108,7 +8597,7 @@
8108
8597
  "text": "string"
8109
8598
  },
8110
8599
  "default": "\"#4f46e5\"",
8111
- "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
8600
+ "description": "Fill color; the gradient's light (highlight) and dark (edge) stops are derived from this.",
8112
8601
  "attribute": "color"
8113
8602
  },
8114
8603
  {
@@ -8131,6 +8620,16 @@
8131
8620
  "description": "White outer ring thickness, in the same viewBox units as `size` (scales with it).",
8132
8621
  "attribute": "ring-width"
8133
8622
  },
8623
+ {
8624
+ "kind": "field",
8625
+ "name": "ringOpacity",
8626
+ "type": {
8627
+ "text": "number"
8628
+ },
8629
+ "default": "0.6",
8630
+ "description": "Outer ring opacity, 0-1 (Apple Maps-style rings are translucent, not solid white).",
8631
+ "attribute": "ring-opacity"
8632
+ },
8134
8633
  {
8135
8634
  "kind": "field",
8136
8635
  "name": "highlighted",
@@ -8157,7 +8656,7 @@
8157
8656
  "text": "string"
8158
8657
  },
8159
8658
  "default": "\"#4f46e5\"",
8160
- "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
8659
+ "description": "Fill color; the gradient's light (highlight) and dark (edge) stops are derived from this.",
8161
8660
  "fieldName": "color"
8162
8661
  },
8163
8662
  {
@@ -8178,6 +8677,15 @@
8178
8677
  "description": "White outer ring thickness, in the same viewBox units as `size` (scales with it).",
8179
8678
  "fieldName": "ringWidth"
8180
8679
  },
8680
+ {
8681
+ "name": "ring-opacity",
8682
+ "type": {
8683
+ "text": "number"
8684
+ },
8685
+ "default": "0.6",
8686
+ "description": "Outer ring opacity, 0-1 (Apple Maps-style rings are translucent, not solid white).",
8687
+ "fieldName": "ringOpacity"
8688
+ },
8181
8689
  {
8182
8690
  "name": "highlighted",
8183
8691
  "type": {
@@ -8221,7 +8729,7 @@
8221
8729
  "declarations": [
8222
8730
  {
8223
8731
  "kind": "class",
8224
- "description": "A circular \"Apple Maps\"-style map pin: a light-to-dark gradient fill with\na slight point at the bottom. Purely a visual primitive it has no\n`mapbox-gl` (or any mapping library) dependency; the consumer positions\nit, e.g. via `new mapboxgl.Marker({ element: pinEl })`.",
8732
+ "description": "A circular \"Apple Maps\"-style map pin: a radial-gradient fill with a soft\nhighlight and a slight point at the bottom. Purely a visual primitive —\nit has no `mapbox-gl` (or any mapping library) dependency; the consumer\npositions it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.",
8225
8733
  "name": "MapPin",
8226
8734
  "slots": [
8227
8735
  {
@@ -8237,7 +8745,7 @@
8237
8745
  "text": "string"
8238
8746
  },
8239
8747
  "default": "\"#4f46e5\"",
8240
- "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
8748
+ "description": "Fill color; the gradient's light (highlight) and dark (edge) stops are derived from this.",
8241
8749
  "attribute": "color"
8242
8750
  },
8243
8751
  {
@@ -8250,6 +8758,16 @@
8250
8758
  "description": "Diameter of the circular head, in CSS pixels.",
8251
8759
  "attribute": "size"
8252
8760
  },
8761
+ {
8762
+ "kind": "field",
8763
+ "name": "ringOpacity",
8764
+ "type": {
8765
+ "text": "number"
8766
+ },
8767
+ "default": "0.6",
8768
+ "description": "Outer ring opacity, 0-1 (Apple Maps-style rings are translucent, not solid white).",
8769
+ "attribute": "ring-opacity"
8770
+ },
8253
8771
  {
8254
8772
  "kind": "field",
8255
8773
  "name": "highlighted",
@@ -8276,7 +8794,7 @@
8276
8794
  "text": "string"
8277
8795
  },
8278
8796
  "default": "\"#4f46e5\"",
8279
- "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
8797
+ "description": "Fill color; the gradient's light (highlight) and dark (edge) stops are derived from this.",
8280
8798
  "fieldName": "color"
8281
8799
  },
8282
8800
  {
@@ -8288,6 +8806,15 @@
8288
8806
  "description": "Diameter of the circular head, in CSS pixels.",
8289
8807
  "fieldName": "size"
8290
8808
  },
8809
+ {
8810
+ "name": "ring-opacity",
8811
+ "type": {
8812
+ "text": "number"
8813
+ },
8814
+ "default": "0.6",
8815
+ "description": "Outer ring opacity, 0-1 (Apple Maps-style rings are translucent, not solid white).",
8816
+ "fieldName": "ringOpacity"
8817
+ },
8291
8818
  {
8292
8819
  "name": "highlighted",
8293
8820
  "type": {
@@ -9691,7 +10218,7 @@
9691
10218
  "declarations": [
9692
10219
  {
9693
10220
  "kind": "class",
9694
- "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.",
10221
+ "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`.",
9695
10222
  "name": "PercentBarChart",
9696
10223
  "members": [
9697
10224
  {
@@ -9703,6 +10230,43 @@
9703
10230
  "default": "[]",
9704
10231
  "description": "Rows to render, one per group."
9705
10232
  },
10233
+ {
10234
+ "kind": "field",
10235
+ "name": "mode",
10236
+ "type": {
10237
+ "text": "PercentBarMode"
10238
+ },
10239
+ "default": "\"percent\"",
10240
+ "description": "Whether `value` is a 0-100 percentage (fixed domain) or an arbitrary number (domain from data/`max`).",
10241
+ "attribute": "mode"
10242
+ },
10243
+ {
10244
+ "kind": "field",
10245
+ "name": "orientation",
10246
+ "type": {
10247
+ "text": "PercentBarOrientation"
10248
+ },
10249
+ "default": "\"horizontal\"",
10250
+ "description": "Bar direction: stacked rows growing rightward, or columns growing upward.",
10251
+ "attribute": "orientation"
10252
+ },
10253
+ {
10254
+ "kind": "field",
10255
+ "name": "max",
10256
+ "type": {
10257
+ "text": "number | undefined"
10258
+ },
10259
+ "description": "Explicit domain max for `mode=\"value\"`; auto-computed from `groups` when unset. Ignored in `mode=\"percent\"`.",
10260
+ "attribute": "max"
10261
+ },
10262
+ {
10263
+ "kind": "field",
10264
+ "name": "valueFormat",
10265
+ "type": {
10266
+ "text": "(value: number) => string"
10267
+ },
10268
+ "description": "Formats a row's value for its label in `mode=\"value\"`. Defaults to locale-formatted number."
10269
+ },
9706
10270
  {
9707
10271
  "kind": "field",
9708
10272
  "name": "_width",
@@ -9746,6 +10310,79 @@
9746
10310
  }
9747
10311
  ],
9748
10312
  "description": "Per-row gradient id, unique across instances and rows."
10313
+ },
10314
+ {
10315
+ "kind": "method",
10316
+ "name": "_labelFor",
10317
+ "privacy": "private",
10318
+ "return": {
10319
+ "type": {
10320
+ "text": "string"
10321
+ }
10322
+ },
10323
+ "parameters": [
10324
+ {
10325
+ "name": "value",
10326
+ "type": {
10327
+ "text": "number"
10328
+ }
10329
+ }
10330
+ ],
10331
+ "description": "The row's value formatted for display, per the current `mode`."
10332
+ },
10333
+ {
10334
+ "kind": "method",
10335
+ "name": "_domainMax",
10336
+ "privacy": "private",
10337
+ "return": {
10338
+ "type": {
10339
+ "text": "number"
10340
+ }
10341
+ },
10342
+ "description": "The scale domain's upper bound for the current `mode`."
10343
+ },
10344
+ {
10345
+ "kind": "method",
10346
+ "name": "_renderGradients",
10347
+ "privacy": "private"
10348
+ },
10349
+ {
10350
+ "kind": "method",
10351
+ "name": "_renderHorizontal",
10352
+ "privacy": "private"
10353
+ },
10354
+ {
10355
+ "kind": "method",
10356
+ "name": "_renderVertical",
10357
+ "privacy": "private"
10358
+ }
10359
+ ],
10360
+ "attributes": [
10361
+ {
10362
+ "name": "mode",
10363
+ "type": {
10364
+ "text": "PercentBarMode"
10365
+ },
10366
+ "default": "\"percent\"",
10367
+ "description": "Whether `value` is a 0-100 percentage (fixed domain) or an arbitrary number (domain from data/`max`).",
10368
+ "fieldName": "mode"
10369
+ },
10370
+ {
10371
+ "name": "orientation",
10372
+ "type": {
10373
+ "text": "PercentBarOrientation"
10374
+ },
10375
+ "default": "\"horizontal\"",
10376
+ "description": "Bar direction: stacked rows growing rightward, or columns growing upward.",
10377
+ "fieldName": "orientation"
10378
+ },
10379
+ {
10380
+ "name": "max",
10381
+ "type": {
10382
+ "text": "number | undefined"
10383
+ },
10384
+ "description": "Explicit domain max for `mode=\"value\"`; auto-computed from `groups` when unset. Ignored in `mode=\"percent\"`.",
10385
+ "fieldName": "max"
9749
10386
  }
9750
10387
  ],
9751
10388
  "superclass": {
@@ -11257,50 +11894,346 @@
11257
11894
  },
11258
11895
  {
11259
11896
  "kind": "javascript-module",
11260
- "path": "src/slide-panel.ts",
11897
+ "path": "src/scroll-to-bottom.ts",
11261
11898
  "declarations": [
11262
11899
  {
11263
11900
  "kind": "class",
11264
- "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.",
11265
- "name": "SlidePanel",
11901
+ "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.",
11902
+ "name": "ScrollToBottom",
11266
11903
  "members": [
11267
11904
  {
11268
11905
  "kind": "field",
11269
- "name": "open",
11906
+ "name": "target",
11270
11907
  "type": {
11271
- "text": "boolean"
11908
+ "text": "HTMLElement | null"
11272
11909
  },
11273
- "default": "false",
11274
- "description": "Whether the panel is currently visible.",
11275
- "attribute": "open"
11910
+ "default": "null",
11911
+ "description": "Scrollable container to control; `null` (default) scrolls `window`."
11276
11912
  },
11277
11913
  {
11278
11914
  "kind": "field",
11279
- "name": "heading",
11915
+ "name": "threshold",
11916
+ "type": {
11917
+ "text": "number"
11918
+ },
11919
+ "default": "200",
11920
+ "description": "Pixels scrolled away from the bottom before the button appears.",
11921
+ "attribute": "threshold"
11922
+ },
11923
+ {
11924
+ "kind": "field",
11925
+ "name": "label",
11280
11926
  "type": {
11281
11927
  "text": "string"
11282
11928
  },
11283
- "default": "\"\"",
11284
- "description": "Title text shown in the panel header (overridable via slot=\"title\").",
11285
- "attribute": "heading"
11929
+ "default": "\"Scroll to bottom\"",
11930
+ "description": "Visible button text, and its accessible name.",
11931
+ "attribute": "label"
11286
11932
  },
11287
11933
  {
11288
11934
  "kind": "field",
11289
- "name": "_previousFocus",
11935
+ "name": "_visible",
11290
11936
  "type": {
11291
- "text": "HTMLElement | null"
11937
+ "text": "boolean"
11292
11938
  },
11293
11939
  "privacy": "private",
11940
+ "default": "false"
11941
+ },
11942
+ {
11943
+ "kind": "field",
11944
+ "name": "#listenedTo",
11945
+ "privacy": "private",
11946
+ "type": {
11947
+ "text": "HTMLElement | Window | null"
11948
+ },
11294
11949
  "default": "null"
11295
11950
  },
11296
11951
  {
11297
11952
  "kind": "method",
11298
- "name": "_close",
11299
- "privacy": "private"
11953
+ "name": "#subscribe",
11954
+ "privacy": "private",
11955
+ "return": {
11956
+ "type": {
11957
+ "text": "void"
11958
+ }
11959
+ }
11300
11960
  },
11301
11961
  {
11302
- "kind": "field",
11303
- "name": "_onWindowKeydown",
11962
+ "kind": "method",
11963
+ "name": "#unsubscribe",
11964
+ "privacy": "private",
11965
+ "return": {
11966
+ "type": {
11967
+ "text": "void"
11968
+ }
11969
+ }
11970
+ },
11971
+ {
11972
+ "kind": "field",
11973
+ "name": "#onScroll",
11974
+ "privacy": "private"
11975
+ },
11976
+ {
11977
+ "kind": "method",
11978
+ "name": "#onClick",
11979
+ "privacy": "private",
11980
+ "return": {
11981
+ "type": {
11982
+ "text": "void"
11983
+ }
11984
+ }
11985
+ }
11986
+ ],
11987
+ "events": [
11988
+ {
11989
+ "name": "scroll-to-bottom-triggered",
11990
+ "type": {
11991
+ "text": "CustomEvent"
11992
+ },
11993
+ "description": "The button was clicked, just before scrolling; detail: `{ target }`."
11994
+ }
11995
+ ],
11996
+ "attributes": [
11997
+ {
11998
+ "name": "threshold",
11999
+ "type": {
12000
+ "text": "number"
12001
+ },
12002
+ "default": "200",
12003
+ "description": "Pixels scrolled away from the bottom before the button appears.",
12004
+ "fieldName": "threshold"
12005
+ },
12006
+ {
12007
+ "name": "label",
12008
+ "type": {
12009
+ "text": "string"
12010
+ },
12011
+ "default": "\"Scroll to bottom\"",
12012
+ "description": "Visible button text, and its accessible name.",
12013
+ "fieldName": "label"
12014
+ }
12015
+ ],
12016
+ "superclass": {
12017
+ "name": "LitElement",
12018
+ "package": "lit"
12019
+ },
12020
+ "tagName": "scroll-to-bottom",
12021
+ "customElement": true
12022
+ }
12023
+ ],
12024
+ "exports": [
12025
+ {
12026
+ "kind": "js",
12027
+ "name": "ScrollToBottom",
12028
+ "declaration": {
12029
+ "name": "ScrollToBottom",
12030
+ "module": "src/scroll-to-bottom.ts"
12031
+ }
12032
+ },
12033
+ {
12034
+ "kind": "custom-element-definition",
12035
+ "name": "scroll-to-bottom",
12036
+ "declaration": {
12037
+ "name": "ScrollToBottom",
12038
+ "module": "src/scroll-to-bottom.ts"
12039
+ }
12040
+ }
12041
+ ]
12042
+ },
12043
+ {
12044
+ "kind": "javascript-module",
12045
+ "path": "src/scroll-to-top.ts",
12046
+ "declarations": [
12047
+ {
12048
+ "kind": "class",
12049
+ "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.",
12050
+ "name": "ScrollToTop",
12051
+ "members": [
12052
+ {
12053
+ "kind": "field",
12054
+ "name": "target",
12055
+ "type": {
12056
+ "text": "HTMLElement | null"
12057
+ },
12058
+ "default": "null",
12059
+ "description": "Scrollable container to control; `null` (default) scrolls `window`."
12060
+ },
12061
+ {
12062
+ "kind": "field",
12063
+ "name": "threshold",
12064
+ "type": {
12065
+ "text": "number"
12066
+ },
12067
+ "default": "200",
12068
+ "description": "Pixels scrolled away from the top before the button appears.",
12069
+ "attribute": "threshold"
12070
+ },
12071
+ {
12072
+ "kind": "field",
12073
+ "name": "label",
12074
+ "type": {
12075
+ "text": "string"
12076
+ },
12077
+ "default": "\"Scroll to top\"",
12078
+ "description": "Visible button text, and its accessible name.",
12079
+ "attribute": "label"
12080
+ },
12081
+ {
12082
+ "kind": "field",
12083
+ "name": "_visible",
12084
+ "type": {
12085
+ "text": "boolean"
12086
+ },
12087
+ "privacy": "private",
12088
+ "default": "false"
12089
+ },
12090
+ {
12091
+ "kind": "field",
12092
+ "name": "#listenedTo",
12093
+ "privacy": "private",
12094
+ "type": {
12095
+ "text": "HTMLElement | Window | null"
12096
+ },
12097
+ "default": "null"
12098
+ },
12099
+ {
12100
+ "kind": "method",
12101
+ "name": "#subscribe",
12102
+ "privacy": "private",
12103
+ "return": {
12104
+ "type": {
12105
+ "text": "void"
12106
+ }
12107
+ }
12108
+ },
12109
+ {
12110
+ "kind": "method",
12111
+ "name": "#unsubscribe",
12112
+ "privacy": "private",
12113
+ "return": {
12114
+ "type": {
12115
+ "text": "void"
12116
+ }
12117
+ }
12118
+ },
12119
+ {
12120
+ "kind": "field",
12121
+ "name": "#onScroll",
12122
+ "privacy": "private"
12123
+ },
12124
+ {
12125
+ "kind": "method",
12126
+ "name": "#onClick",
12127
+ "privacy": "private",
12128
+ "return": {
12129
+ "type": {
12130
+ "text": "void"
12131
+ }
12132
+ }
12133
+ }
12134
+ ],
12135
+ "events": [
12136
+ {
12137
+ "name": "scroll-to-top-triggered",
12138
+ "type": {
12139
+ "text": "CustomEvent"
12140
+ },
12141
+ "description": "The button was clicked, just before scrolling; detail: `{ target }`."
12142
+ }
12143
+ ],
12144
+ "attributes": [
12145
+ {
12146
+ "name": "threshold",
12147
+ "type": {
12148
+ "text": "number"
12149
+ },
12150
+ "default": "200",
12151
+ "description": "Pixels scrolled away from the top before the button appears.",
12152
+ "fieldName": "threshold"
12153
+ },
12154
+ {
12155
+ "name": "label",
12156
+ "type": {
12157
+ "text": "string"
12158
+ },
12159
+ "default": "\"Scroll to top\"",
12160
+ "description": "Visible button text, and its accessible name.",
12161
+ "fieldName": "label"
12162
+ }
12163
+ ],
12164
+ "superclass": {
12165
+ "name": "LitElement",
12166
+ "package": "lit"
12167
+ },
12168
+ "tagName": "scroll-to-top",
12169
+ "customElement": true
12170
+ }
12171
+ ],
12172
+ "exports": [
12173
+ {
12174
+ "kind": "js",
12175
+ "name": "ScrollToTop",
12176
+ "declaration": {
12177
+ "name": "ScrollToTop",
12178
+ "module": "src/scroll-to-top.ts"
12179
+ }
12180
+ },
12181
+ {
12182
+ "kind": "custom-element-definition",
12183
+ "name": "scroll-to-top",
12184
+ "declaration": {
12185
+ "name": "ScrollToTop",
12186
+ "module": "src/scroll-to-top.ts"
12187
+ }
12188
+ }
12189
+ ]
12190
+ },
12191
+ {
12192
+ "kind": "javascript-module",
12193
+ "path": "src/slide-panel.ts",
12194
+ "declarations": [
12195
+ {
12196
+ "kind": "class",
12197
+ "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.",
12198
+ "name": "SlidePanel",
12199
+ "members": [
12200
+ {
12201
+ "kind": "field",
12202
+ "name": "open",
12203
+ "type": {
12204
+ "text": "boolean"
12205
+ },
12206
+ "default": "false",
12207
+ "description": "Whether the panel is currently visible.",
12208
+ "attribute": "open"
12209
+ },
12210
+ {
12211
+ "kind": "field",
12212
+ "name": "heading",
12213
+ "type": {
12214
+ "text": "string"
12215
+ },
12216
+ "default": "\"\"",
12217
+ "description": "Title text shown in the panel header (overridable via slot=\"title\").",
12218
+ "attribute": "heading"
12219
+ },
12220
+ {
12221
+ "kind": "field",
12222
+ "name": "_previousFocus",
12223
+ "type": {
12224
+ "text": "HTMLElement | null"
12225
+ },
12226
+ "privacy": "private",
12227
+ "default": "null"
12228
+ },
12229
+ {
12230
+ "kind": "method",
12231
+ "name": "_close",
12232
+ "privacy": "private"
12233
+ },
12234
+ {
12235
+ "kind": "field",
12236
+ "name": "_onWindowKeydown",
11304
12237
  "privacy": "private"
11305
12238
  }
11306
12239
  ],
@@ -12750,52 +13683,354 @@
12750
13683
  },
12751
13684
  {
12752
13685
  "kind": "javascript-module",
12753
- "path": "src/user-avatar.ts",
13686
+ "path": "src/ui-checkbox.ts",
12754
13687
  "declarations": [
12755
13688
  {
12756
13689
  "kind": "class",
12757
- "description": "Circular avatar. Shows `src` when it loads successfully; falls back to the\nfirst letter of `name` (uppercased) if `src` is unset or fails to load\n(e.g. an expired OAuth profile-photo URL); falls back further to a generic\nperson icon if `name` is also unset. A broken image never leaves a blank\ncircle.",
12758
- "name": "UserAvatar",
13690
+ "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.",
13691
+ "name": "UiCheckbox",
12759
13692
  "members": [
12760
13693
  {
12761
13694
  "kind": "field",
12762
- "name": "src",
13695
+ "name": "formAssociated",
12763
13696
  "type": {
12764
- "text": "string | null"
13697
+ "text": "boolean"
12765
13698
  },
12766
- "default": "null",
12767
- "description": "Image URL to show. Falls back to initials/icon if unset or it fails to load.",
12768
- "attribute": "src"
13699
+ "static": true,
13700
+ "default": "true"
12769
13701
  },
12770
13702
  {
12771
13703
  "kind": "field",
12772
- "name": "name",
13704
+ "name": "checked",
12773
13705
  "type": {
12774
- "text": "string | null"
13706
+ "text": "boolean"
12775
13707
  },
12776
- "default": "null",
12777
- "description": "Source string for the fallback initial (e.g. a display name or email) — first character, uppercased.",
12778
- "attribute": "name"
13708
+ "default": "false",
13709
+ "description": "Whether the box is checked.",
13710
+ "attribute": "checked"
12779
13711
  },
12780
13712
  {
12781
13713
  "kind": "field",
12782
- "name": "size",
13714
+ "name": "indeterminate",
12783
13715
  "type": {
12784
- "text": "string | number"
13716
+ "text": "boolean"
12785
13717
  },
12786
- "default": "32",
12787
- "description": "Diameter in CSS pixels, or a preset name (`xs`=18, `sm`=24, `md`=32, `lg`=48).",
12788
- "attribute": "size"
13718
+ "default": "false",
13719
+ "description": "Visual \"partial selection\" state; cleared on the next user interaction.",
13720
+ "attribute": "indeterminate"
12789
13721
  },
12790
13722
  {
12791
13723
  "kind": "field",
12792
- "name": "_imgError",
13724
+ "name": "disabled",
12793
13725
  "type": {
12794
13726
  "text": "boolean"
12795
13727
  },
12796
- "privacy": "private",
12797
- "default": "false"
12798
- },
13728
+ "default": "false",
13729
+ "description": "Disables interaction; merged with an ancestor `<fieldset disabled>`.",
13730
+ "attribute": "disabled"
13731
+ },
13732
+ {
13733
+ "kind": "field",
13734
+ "name": "required",
13735
+ "type": {
13736
+ "text": "boolean"
13737
+ },
13738
+ "default": "false",
13739
+ "description": "Marks the control invalid via `ElementInternals` while unchecked.",
13740
+ "attribute": "required"
13741
+ },
13742
+ {
13743
+ "kind": "field",
13744
+ "name": "name",
13745
+ "type": {
13746
+ "text": "string"
13747
+ },
13748
+ "default": "\"\"",
13749
+ "description": "Form field name; submitted as `name=on` only while checked.",
13750
+ "attribute": "name"
13751
+ },
13752
+ {
13753
+ "kind": "field",
13754
+ "name": "label",
13755
+ "type": {
13756
+ "text": "string"
13757
+ },
13758
+ "default": "\"\"",
13759
+ "description": "Visible label text rendered next to the box.",
13760
+ "attribute": "label"
13761
+ },
13762
+ {
13763
+ "kind": "field",
13764
+ "name": "_formDisabled",
13765
+ "type": {
13766
+ "text": "boolean"
13767
+ },
13768
+ "privacy": "private",
13769
+ "default": "false"
13770
+ },
13771
+ {
13772
+ "kind": "field",
13773
+ "name": "#internals",
13774
+ "privacy": "private"
13775
+ },
13776
+ {
13777
+ "kind": "field",
13778
+ "name": "#defaultChecked",
13779
+ "privacy": "private",
13780
+ "type": {
13781
+ "text": "boolean"
13782
+ },
13783
+ "default": "false"
13784
+ },
13785
+ {
13786
+ "kind": "field",
13787
+ "name": "#inputEl",
13788
+ "privacy": "private",
13789
+ "type": {
13790
+ "text": "HTMLInputElement | null"
13791
+ },
13792
+ "default": "null"
13793
+ },
13794
+ {
13795
+ "kind": "field",
13796
+ "name": "#isDisabled",
13797
+ "privacy": "private",
13798
+ "type": {
13799
+ "text": "boolean"
13800
+ },
13801
+ "description": "Whether the host or an ancestor fieldset currently disables the control.",
13802
+ "readonly": true
13803
+ },
13804
+ {
13805
+ "kind": "method",
13806
+ "name": "formResetCallback",
13807
+ "return": {
13808
+ "type": {
13809
+ "text": "void"
13810
+ }
13811
+ },
13812
+ "description": "Restores the checked state captured at first render, per the form contract."
13813
+ },
13814
+ {
13815
+ "kind": "method",
13816
+ "name": "formDisabledCallback",
13817
+ "return": {
13818
+ "type": {
13819
+ "text": "void"
13820
+ }
13821
+ },
13822
+ "parameters": [
13823
+ {
13824
+ "name": "disabled",
13825
+ "type": {
13826
+ "text": "boolean"
13827
+ }
13828
+ }
13829
+ ],
13830
+ "description": "Mirrors an ancestor fieldset's disabled state."
13831
+ },
13832
+ {
13833
+ "kind": "method",
13834
+ "name": "formStateRestoreCallback",
13835
+ "return": {
13836
+ "type": {
13837
+ "text": "void"
13838
+ }
13839
+ },
13840
+ "parameters": [
13841
+ {
13842
+ "name": "state",
13843
+ "type": {
13844
+ "text": "string | File | FormData | null"
13845
+ }
13846
+ }
13847
+ ],
13848
+ "description": "Restores the checked state from saved form state (bfcache/autofill)."
13849
+ },
13850
+ {
13851
+ "kind": "method",
13852
+ "name": "#syncFormValue",
13853
+ "privacy": "private",
13854
+ "return": {
13855
+ "type": {
13856
+ "text": "void"
13857
+ }
13858
+ }
13859
+ },
13860
+ {
13861
+ "kind": "method",
13862
+ "name": "#syncValidity",
13863
+ "privacy": "private",
13864
+ "return": {
13865
+ "type": {
13866
+ "text": "void"
13867
+ }
13868
+ }
13869
+ },
13870
+ {
13871
+ "kind": "method",
13872
+ "name": "#onChange",
13873
+ "privacy": "private",
13874
+ "return": {
13875
+ "type": {
13876
+ "text": "void"
13877
+ }
13878
+ },
13879
+ "parameters": [
13880
+ {
13881
+ "name": "e",
13882
+ "type": {
13883
+ "text": "Event"
13884
+ }
13885
+ }
13886
+ ]
13887
+ },
13888
+ {
13889
+ "kind": "field",
13890
+ "name": "#onInputRef",
13891
+ "privacy": "private"
13892
+ }
13893
+ ],
13894
+ "events": [
13895
+ {
13896
+ "name": "change",
13897
+ "type": {
13898
+ "text": "CustomEvent"
13899
+ },
13900
+ "description": "The checkbox was toggled by the user, in either direction; detail: `{ checked }`. Programmatic `checked` assignments do not fire it."
13901
+ }
13902
+ ],
13903
+ "attributes": [
13904
+ {
13905
+ "name": "checked",
13906
+ "type": {
13907
+ "text": "boolean"
13908
+ },
13909
+ "default": "false",
13910
+ "description": "Whether the box is checked.",
13911
+ "fieldName": "checked"
13912
+ },
13913
+ {
13914
+ "name": "indeterminate",
13915
+ "type": {
13916
+ "text": "boolean"
13917
+ },
13918
+ "default": "false",
13919
+ "description": "Visual \"partial selection\" state; cleared on the next user interaction.",
13920
+ "fieldName": "indeterminate"
13921
+ },
13922
+ {
13923
+ "name": "disabled",
13924
+ "type": {
13925
+ "text": "boolean"
13926
+ },
13927
+ "default": "false",
13928
+ "description": "Disables interaction; merged with an ancestor `<fieldset disabled>`.",
13929
+ "fieldName": "disabled"
13930
+ },
13931
+ {
13932
+ "name": "required",
13933
+ "type": {
13934
+ "text": "boolean"
13935
+ },
13936
+ "default": "false",
13937
+ "description": "Marks the control invalid via `ElementInternals` while unchecked.",
13938
+ "fieldName": "required"
13939
+ },
13940
+ {
13941
+ "name": "name",
13942
+ "type": {
13943
+ "text": "string"
13944
+ },
13945
+ "default": "\"\"",
13946
+ "description": "Form field name; submitted as `name=on` only while checked.",
13947
+ "fieldName": "name"
13948
+ },
13949
+ {
13950
+ "name": "label",
13951
+ "type": {
13952
+ "text": "string"
13953
+ },
13954
+ "default": "\"\"",
13955
+ "description": "Visible label text rendered next to the box.",
13956
+ "fieldName": "label"
13957
+ }
13958
+ ],
13959
+ "superclass": {
13960
+ "name": "LitElement",
13961
+ "package": "lit"
13962
+ },
13963
+ "tagName": "ui-checkbox",
13964
+ "customElement": true
13965
+ }
13966
+ ],
13967
+ "exports": [
13968
+ {
13969
+ "kind": "js",
13970
+ "name": "UiCheckbox",
13971
+ "declaration": {
13972
+ "name": "UiCheckbox",
13973
+ "module": "src/ui-checkbox.ts"
13974
+ }
13975
+ },
13976
+ {
13977
+ "kind": "custom-element-definition",
13978
+ "name": "ui-checkbox",
13979
+ "declaration": {
13980
+ "name": "UiCheckbox",
13981
+ "module": "src/ui-checkbox.ts"
13982
+ }
13983
+ }
13984
+ ]
13985
+ },
13986
+ {
13987
+ "kind": "javascript-module",
13988
+ "path": "src/user-avatar.ts",
13989
+ "declarations": [
13990
+ {
13991
+ "kind": "class",
13992
+ "description": "Circular avatar. Shows `src` when it loads successfully; falls back to the\nfirst letter of `name` (uppercased) if `src` is unset or fails to load\n(e.g. an expired OAuth profile-photo URL); falls back further to a generic\nperson icon if `name` is also unset. A broken image never leaves a blank\ncircle.",
13993
+ "name": "UserAvatar",
13994
+ "members": [
13995
+ {
13996
+ "kind": "field",
13997
+ "name": "src",
13998
+ "type": {
13999
+ "text": "string | null"
14000
+ },
14001
+ "default": "null",
14002
+ "description": "Image URL to show. Falls back to initials/icon if unset or it fails to load.",
14003
+ "attribute": "src"
14004
+ },
14005
+ {
14006
+ "kind": "field",
14007
+ "name": "name",
14008
+ "type": {
14009
+ "text": "string | null"
14010
+ },
14011
+ "default": "null",
14012
+ "description": "Source string for the fallback initial (e.g. a display name or email) — first character, uppercased.",
14013
+ "attribute": "name"
14014
+ },
14015
+ {
14016
+ "kind": "field",
14017
+ "name": "size",
14018
+ "type": {
14019
+ "text": "string | number"
14020
+ },
14021
+ "default": "32",
14022
+ "description": "Diameter in CSS pixels, or a preset name (`xs`=18, `sm`=24, `md`=32, `lg`=48).",
14023
+ "attribute": "size"
14024
+ },
14025
+ {
14026
+ "kind": "field",
14027
+ "name": "_imgError",
14028
+ "type": {
14029
+ "text": "boolean"
14030
+ },
14031
+ "privacy": "private",
14032
+ "default": "false"
14033
+ },
12799
14034
  {
12800
14035
  "kind": "field",
12801
14036
  "name": "SIZE_PRESETS",
@@ -13513,6 +14748,98 @@
13513
14748
  }
13514
14749
  ]
13515
14750
  },
14751
+ {
14752
+ "kind": "javascript-module",
14753
+ "path": "src/utils/scroll.ts",
14754
+ "declarations": [
14755
+ {
14756
+ "kind": "function",
14757
+ "name": "distanceFromTop",
14758
+ "return": {
14759
+ "type": {
14760
+ "text": "number"
14761
+ }
14762
+ },
14763
+ "parameters": [
14764
+ {
14765
+ "name": "target",
14766
+ "type": {
14767
+ "text": "ScrollableTarget"
14768
+ }
14769
+ }
14770
+ ],
14771
+ "description": "Pixels between the current scroll position and the top edge."
14772
+ },
14773
+ {
14774
+ "kind": "function",
14775
+ "name": "distanceFromBottom",
14776
+ "return": {
14777
+ "type": {
14778
+ "text": "number"
14779
+ }
14780
+ },
14781
+ "parameters": [
14782
+ {
14783
+ "name": "target",
14784
+ "type": {
14785
+ "text": "ScrollableTarget"
14786
+ }
14787
+ }
14788
+ ],
14789
+ "description": "Pixels between the current scroll position and the bottom edge."
14790
+ },
14791
+ {
14792
+ "kind": "function",
14793
+ "name": "scrollToEdge",
14794
+ "return": {
14795
+ "type": {
14796
+ "text": "void"
14797
+ }
14798
+ },
14799
+ "parameters": [
14800
+ {
14801
+ "name": "target",
14802
+ "type": {
14803
+ "text": "ScrollableTarget"
14804
+ }
14805
+ },
14806
+ {
14807
+ "name": "edge",
14808
+ "type": {
14809
+ "text": "\"top\" | \"bottom\""
14810
+ }
14811
+ }
14812
+ ],
14813
+ "description": "Scrolls `target` to its top or bottom edge, honoring `prefers-reduced-motion`."
14814
+ }
14815
+ ],
14816
+ "exports": [
14817
+ {
14818
+ "kind": "js",
14819
+ "name": "distanceFromTop",
14820
+ "declaration": {
14821
+ "name": "distanceFromTop",
14822
+ "module": "src/utils/scroll.ts"
14823
+ }
14824
+ },
14825
+ {
14826
+ "kind": "js",
14827
+ "name": "distanceFromBottom",
14828
+ "declaration": {
14829
+ "name": "distanceFromBottom",
14830
+ "module": "src/utils/scroll.ts"
14831
+ }
14832
+ },
14833
+ {
14834
+ "kind": "js",
14835
+ "name": "scrollToEdge",
14836
+ "declaration": {
14837
+ "name": "scrollToEdge",
14838
+ "module": "src/utils/scroll.ts"
14839
+ }
14840
+ }
14841
+ ]
14842
+ },
13516
14843
  {
13517
14844
  "kind": "javascript-module",
13518
14845
  "path": "src/utils/time.ts",