@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.
- package/README.md +6 -0
- package/custom-elements.json +1376 -49
- package/dist/auto-scroll.d.ts +37 -0
- package/dist/auto-scroll.d.ts.map +1 -0
- package/dist/auto-scroll.js +100 -0
- package/dist/auto-scroll.js.map +1 -0
- package/dist/form-field.d.ts +39 -0
- package/dist/form-field.d.ts.map +1 -0
- package/dist/form-field.js +145 -0
- package/dist/form-field.js.map +1 -0
- package/dist/icons.d.ts +1 -0
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +1 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/load-more.d.ts +33 -0
- package/dist/load-more.d.ts.map +1 -0
- package/dist/load-more.js +82 -0
- package/dist/load-more.js.map +1 -0
- package/dist/map-circle.d.ts +12 -9
- package/dist/map-circle.d.ts.map +1 -1
- package/dist/map-circle.js +26 -12
- package/dist/map-circle.js.map +1 -1
- package/dist/map-pin.d.ts +7 -5
- package/dist/map-pin.d.ts.map +1 -1
- package/dist/map-pin.js +14 -8
- package/dist/map-pin.js.map +1 -1
- package/dist/percent-bar-chart.d.ts +32 -3
- package/dist/percent-bar-chart.d.ts.map +1 -1
- package/dist/percent-bar-chart.js +101 -36
- package/dist/percent-bar-chart.js.map +1 -1
- package/dist/scroll-to-bottom.d.ts +41 -0
- package/dist/scroll-to-bottom.d.ts.map +1 -0
- package/dist/scroll-to-bottom.js +189 -0
- package/dist/scroll-to-bottom.js.map +1 -0
- package/dist/scroll-to-top.d.ts +41 -0
- package/dist/scroll-to-top.d.ts.map +1 -0
- package/dist/scroll-to-top.js +189 -0
- package/dist/scroll-to-top.js.map +1 -0
- package/dist/ui-checkbox.d.ts +49 -0
- package/dist/ui-checkbox.d.ts.map +1 -0
- package/dist/ui-checkbox.js +228 -0
- package/dist/ui-checkbox.js.map +1 -0
- package/dist/utils/scroll.d.ts +9 -0
- package/dist/utils/scroll.d.ts.map +1 -0
- package/dist/utils/scroll.js +30 -0
- package/dist/utils/scroll.js.map +1 -0
- package/docs/auto-scroll.md +52 -0
- package/docs/form-field.md +63 -0
- package/docs/layouts/form-page.md +8 -4
- package/docs/load-more.md +43 -0
- package/docs/map-circle.md +11 -9
- package/docs/map-pin.md +6 -5
- package/docs/percent-bar-chart.md +19 -5
- package/docs/scroll-to-bottom.md +68 -0
- package/docs/scroll-to-top.md +59 -0
- package/docs/ui-checkbox.md +58 -0
- package/llms.txt +199 -20
- package/package.json +1 -1
package/llms.txt
CHANGED
|
@@ -169,6 +169,37 @@ Example:
|
|
|
169
169
|
</app-sidebar>
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
+
## <auto-scroll>
|
|
173
|
+
|
|
174
|
+
Wraps arbitrary slotted content (e.g. `timeline-container`) and keeps it
|
|
175
|
+
scrolled to the bottom as new children are appended — but only while the
|
|
176
|
+
user is already scrolled near the bottom ("stick to bottom", a chat/log-
|
|
177
|
+
viewer convention). If the user has scrolled up to read earlier content,
|
|
178
|
+
new content does not yank the scroll position back down.
|
|
179
|
+
|
|
180
|
+
New content is detected via a `MutationObserver`, so no cooperation from
|
|
181
|
+
whatever is slotted in is required. The host itself is the scrollable
|
|
182
|
+
region (`overflow-y: auto`) and needs a consumer-supplied bounded height to
|
|
183
|
+
have anything to scroll, e.g. `auto-scroll { height: 24rem; }`.
|
|
184
|
+
|
|
185
|
+
Import: `import "@f-ewald/components/auto-scroll.js";`
|
|
186
|
+
|
|
187
|
+
Properties: `threshold` (attribute `threshold`) : number, default 24; `pinned` (JS property only) : boolean, default —
|
|
188
|
+
Events: `pinned-change`
|
|
189
|
+
CSS custom properties: none
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
```html
|
|
193
|
+
<auto-scroll style="height: 24rem">
|
|
194
|
+
<timeline-container>
|
|
195
|
+
<timeline-entry datetime="2026-07-23T09:00:00Z">
|
|
196
|
+
<span slot="headline">Deployment started</span>
|
|
197
|
+
Release v1.4.0 is rolling out.
|
|
198
|
+
</timeline-entry>
|
|
199
|
+
</timeline-container>
|
|
200
|
+
</auto-scroll>
|
|
201
|
+
```
|
|
202
|
+
|
|
172
203
|
## <autocomplete-input>
|
|
173
204
|
|
|
174
205
|
Generic form-associated text input with a suggestion dropdown, for any
|
|
@@ -608,6 +639,39 @@ Example:
|
|
|
608
639
|
</form-actions>
|
|
609
640
|
```
|
|
610
641
|
|
|
642
|
+
## <form-field>
|
|
643
|
+
|
|
644
|
+
Per-field wrapper for a form control: label, slotted control, and an
|
|
645
|
+
optional hint or error message, in one consistent unit repeated across a
|
|
646
|
+
form. Purely presentational — composes whatever control is slotted
|
|
647
|
+
(`form-select`, `multi-select`, `autocomplete-input`, `ui-checkbox`, etc.)
|
|
648
|
+
without intercepting its events or value.
|
|
649
|
+
|
|
650
|
+
The label wraps the default slot for a best-effort visual/click
|
|
651
|
+
association only: every existing value-entry control encapsulates its
|
|
652
|
+
real `<input>` inside its own shadow DOM, so there is no light-DOM `id` a
|
|
653
|
+
`for` attribute could target from outside, and this component cannot set
|
|
654
|
+
`aria-describedby`/`aria-invalid` on an arbitrary slotted control's
|
|
655
|
+
shadow-encapsulated input for the same reason. The error message uses
|
|
656
|
+
`role="alert"` as the practical accessibility mitigation instead of true
|
|
657
|
+
`aria-describedby` association.
|
|
658
|
+
|
|
659
|
+
Import: `import "@f-ewald/components/form-field.js";`
|
|
660
|
+
|
|
661
|
+
Properties: `label` (attribute `label`) : string, default ""; `hint` (attribute `hint`) : string, default ""; `error` (attribute `error`) : string, default ""; `required` (attribute `required`) : boolean, default false
|
|
662
|
+
Events: none
|
|
663
|
+
CSS custom properties: `--ui-danger`, `--ui-font`, `--ui-font-size-sm`, `--ui-font-size-xs`, `--ui-font-weight-medium`, `--ui-line-height-tight`, `--ui-text`, `--ui-text-muted`
|
|
664
|
+
|
|
665
|
+
Example:
|
|
666
|
+
```html
|
|
667
|
+
<form-field label="Task state" hint="Only affects your own view">
|
|
668
|
+
<form-select></form-select>
|
|
669
|
+
</form-field>
|
|
670
|
+
<form-field label="Terms" required error="You must accept to continue">
|
|
671
|
+
<ui-checkbox label="I agree to the terms"></ui-checkbox>
|
|
672
|
+
</form-field>
|
|
673
|
+
```
|
|
674
|
+
|
|
611
675
|
## <form-select>
|
|
612
676
|
|
|
613
677
|
A styled dropdown select: a trigger button showing the current option's
|
|
@@ -909,20 +973,40 @@ Example:
|
|
|
909
973
|
<live-timer since="2026-07-19T12:00:00Z" format="compact" prefix="running for "></live-timer>
|
|
910
974
|
```
|
|
911
975
|
|
|
976
|
+
## <load-more>
|
|
977
|
+
|
|
978
|
+
Click-to-load button for either end of a list. Fully property-driven: the
|
|
979
|
+
consumer sets `loading` while a fetch is in flight and `exhausted` once
|
|
980
|
+
there's nothing left to load; this component never fetches or manages
|
|
981
|
+
state itself.
|
|
982
|
+
|
|
983
|
+
Import: `import "@f-ewald/components/load-more.js";`
|
|
984
|
+
|
|
985
|
+
Properties: `direction` (attribute `direction`) : "top" | "bottom", default "bottom"; `loading` (attribute `loading`) : boolean, default false; `exhausted` (attribute `exhausted`) : boolean, default false; `label` (attribute `label`) : string, default "Load more"; `exhaustedLabel` (attribute `exhausted-label`) : string, default "No more results"
|
|
986
|
+
Events: `load-more`
|
|
987
|
+
CSS custom properties: none
|
|
988
|
+
|
|
989
|
+
Example:
|
|
990
|
+
```html
|
|
991
|
+
<load-more direction="top" label="Load older"></load-more>
|
|
992
|
+
<load-more></load-more>
|
|
993
|
+
```
|
|
994
|
+
|
|
912
995
|
## <map-circle>
|
|
913
996
|
|
|
914
|
-
A plain circular map marker: a
|
|
915
|
-
outer ring, no point/tail (unlike `<map-pin>`) —
|
|
916
|
-
need to visually "point" at their exact
|
|
917
|
-
primitive — it has no `mapbox-gl` (or any
|
|
918
|
-
the consumer positions it, e.g. via
|
|
919
|
-
It can also replace the former
|
|
920
|
-
`size="14" ring-width="3"`, leave
|
|
921
|
-
per color for use as a map
|
|
997
|
+
A plain circular map marker: a radial-gradient fill with a soft highlight
|
|
998
|
+
and a translucent white outer ring, no point/tail (unlike `<map-pin>`) —
|
|
999
|
+
for markers that don't need to visually "point" at their exact
|
|
1000
|
+
coordinate. Purely a visual primitive — it has no `mapbox-gl` (or any
|
|
1001
|
+
mapping library) dependency; the consumer positions it, e.g. via
|
|
1002
|
+
`new mapboxgl.Marker({ element: el })`. It can also replace the former
|
|
1003
|
+
`<map-point>` dense-layer primitive: use `size="14" ring-width="3"`, leave
|
|
1004
|
+
the slot empty, and rasterize one marker per color for use as a map
|
|
1005
|
+
`icon-image`.
|
|
922
1006
|
|
|
923
1007
|
Import: `import "@f-ewald/components/map-circle.js";`
|
|
924
1008
|
|
|
925
|
-
Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 18; `ringWidth` (attribute `ring-width`) : number, default 4; `highlighted` (attribute `highlighted`) : boolean, default false
|
|
1009
|
+
Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 18; `ringWidth` (attribute `ring-width`) : number, default 4; `ringOpacity` (attribute `ring-opacity`) : number, default 0.6; `highlighted` (attribute `highlighted`) : boolean, default false
|
|
926
1010
|
Events: none
|
|
927
1011
|
CSS custom properties: `--ui-font`, `--ui-font-weight-bold`, `--ui-line-height-glyph`
|
|
928
1012
|
|
|
@@ -935,14 +1019,14 @@ Example:
|
|
|
935
1019
|
|
|
936
1020
|
## <map-pin>
|
|
937
1021
|
|
|
938
|
-
A circular "Apple Maps"-style map pin: a
|
|
939
|
-
a slight point at the bottom. Purely a visual primitive —
|
|
940
|
-
`mapbox-gl` (or any mapping library) dependency; the consumer
|
|
941
|
-
it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.
|
|
1022
|
+
A circular "Apple Maps"-style map pin: a radial-gradient fill with a soft
|
|
1023
|
+
highlight and a slight point at the bottom. Purely a visual primitive —
|
|
1024
|
+
it has no `mapbox-gl` (or any mapping library) dependency; the consumer
|
|
1025
|
+
positions it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.
|
|
942
1026
|
|
|
943
1027
|
Import: `import "@f-ewald/components/map-pin.js";`
|
|
944
1028
|
|
|
945
|
-
Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 32; `highlighted` (attribute `highlighted`) : boolean, default false
|
|
1029
|
+
Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 32; `ringOpacity` (attribute `ring-opacity`) : number, default 0.6; `highlighted` (attribute `highlighted`) : boolean, default false
|
|
946
1030
|
Events: none
|
|
947
1031
|
CSS custom properties: `--ui-font`, `--ui-font-weight-bold`, `--ui-line-height-glyph`
|
|
948
1032
|
|
|
@@ -1108,12 +1192,16 @@ Example:
|
|
|
1108
1192
|
|
|
1109
1193
|
## <percent-bar-chart>
|
|
1110
1194
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1195
|
+
Bar chart for labeled rows, using D3's linear scale. Horizontal (default)
|
|
1196
|
+
renders stacked rows with bars growing rightward; `orientation="vertical"`
|
|
1197
|
+
renders side-by-side columns growing upward instead. `mode="percent"`
|
|
1198
|
+
(default) scales `value` against a fixed 0-100 domain and labels it with a
|
|
1199
|
+
`%` suffix; `mode="value"` scales it against `max` (or the largest `value`
|
|
1200
|
+
present) and formats it with `valueFormat`.
|
|
1113
1201
|
|
|
1114
1202
|
Import: `import "@f-ewald/components/percent-bar-chart.js";`
|
|
1115
1203
|
|
|
1116
|
-
Properties: `groups` (JS property only) : PercentBarGroup[], default []
|
|
1204
|
+
Properties: `groups` (JS property only) : PercentBarGroup[], default []; `mode` (attribute `mode`) : PercentBarMode, default "percent"; `orientation` (attribute `orientation`) : PercentBarOrientation, default "horizontal"; `max` (attribute `max`) : number | undefined, default —; `valueFormat` (JS property only) : (value: number) => string, default —
|
|
1117
1205
|
Events: none
|
|
1118
1206
|
CSS custom properties: `--ui-font`, `--ui-text-muted`
|
|
1119
1207
|
|
|
@@ -1121,10 +1209,16 @@ Example:
|
|
|
1121
1209
|
```html
|
|
1122
1210
|
<percent-bar-chart></percent-bar-chart>
|
|
1123
1211
|
<script type="module">
|
|
1124
|
-
document.querySelector("percent-bar-chart")
|
|
1125
|
-
|
|
1126
|
-
{ key: "
|
|
1212
|
+
const chart = document.querySelector("percent-bar-chart");
|
|
1213
|
+
chart.groups = [
|
|
1214
|
+
{ key: "a", label: "White", value: 45.2, color: "#4f46e5" },
|
|
1215
|
+
{ key: "b", label: "Asian", value: 28.1, color: "#0d9488" },
|
|
1127
1216
|
];
|
|
1217
|
+
|
|
1218
|
+
// Absolute values instead of percentages, as vertical columns:
|
|
1219
|
+
chart.mode = "value";
|
|
1220
|
+
chart.orientation = "vertical";
|
|
1221
|
+
chart.valueFormat = (value) => `$${value.toLocaleString()}`;
|
|
1128
1222
|
</script>
|
|
1129
1223
|
```
|
|
1130
1224
|
|
|
@@ -1325,6 +1419,67 @@ Example:
|
|
|
1325
1419
|
<roman-numeral value="2004"></roman-numeral>
|
|
1326
1420
|
```
|
|
1327
1421
|
|
|
1422
|
+
## <scroll-to-bottom>
|
|
1423
|
+
|
|
1424
|
+
Overlay button that appears once the page (or a given `target` container)
|
|
1425
|
+
has scrolled more than `threshold` pixels away from the bottom edge, and
|
|
1426
|
+
scrolls back to the bottom on click.
|
|
1427
|
+
|
|
1428
|
+
With no `target` (default), the button is `position: fixed` to the
|
|
1429
|
+
viewport. When `target` is set, the button switches to `position:
|
|
1430
|
+
absolute` and expects to be placed as a descendant of a `position:
|
|
1431
|
+
relative` (or otherwise positioned) ancestor that establishes the visual
|
|
1432
|
+
bounds to float within — typically `target` itself, given `overflow-y:
|
|
1433
|
+
auto; position: relative`, so the button stays pinned to that container's
|
|
1434
|
+
own visible corner as its content scrolls, rather than floating over the
|
|
1435
|
+
whole page.
|
|
1436
|
+
|
|
1437
|
+
Import: `import "@f-ewald/components/scroll-to-bottom.js";`
|
|
1438
|
+
|
|
1439
|
+
Properties: `target` (JS property only) : HTMLElement | null, default null; `threshold` (attribute `threshold`) : number, default 200; `label` (attribute `label`) : string, default "Scroll to bottom"
|
|
1440
|
+
Events: `scroll-to-bottom-triggered`
|
|
1441
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-font-weight-medium`, `--ui-line-height-tight`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`
|
|
1442
|
+
|
|
1443
|
+
Example:
|
|
1444
|
+
```html
|
|
1445
|
+
<scroll-to-bottom></scroll-to-bottom>
|
|
1446
|
+
|
|
1447
|
+
<!-- Floats inside its own scrollport instead of the whole page: -->
|
|
1448
|
+
<div id="log" style="position: relative; overflow-y: auto; height: 10rem">
|
|
1449
|
+
...
|
|
1450
|
+
<scroll-to-bottom threshold="20"></scroll-to-bottom>
|
|
1451
|
+
</div>
|
|
1452
|
+
<script type="module">
|
|
1453
|
+
document.querySelector('scroll-to-bottom').target = document.querySelector('#log');
|
|
1454
|
+
</script>
|
|
1455
|
+
```
|
|
1456
|
+
|
|
1457
|
+
## <scroll-to-top>
|
|
1458
|
+
|
|
1459
|
+
Overlay button that appears once the page (or a given `target` container)
|
|
1460
|
+
has scrolled more than `threshold` pixels away from the top edge, and
|
|
1461
|
+
scrolls back to the top on click.
|
|
1462
|
+
|
|
1463
|
+
With no `target` (default), the button is `position: fixed` to the
|
|
1464
|
+
viewport. When `target` is set, the button switches to `position:
|
|
1465
|
+
absolute` and expects to be placed as a descendant of a `position:
|
|
1466
|
+
relative` (or otherwise positioned) ancestor that establishes the visual
|
|
1467
|
+
bounds to float within — typically `target` itself, given `overflow-y:
|
|
1468
|
+
auto; position: relative`, so the button stays pinned to that container's
|
|
1469
|
+
own visible corner as its content scrolls, rather than floating over the
|
|
1470
|
+
whole page.
|
|
1471
|
+
|
|
1472
|
+
Import: `import "@f-ewald/components/scroll-to-top.js";`
|
|
1473
|
+
|
|
1474
|
+
Properties: `target` (JS property only) : HTMLElement | null, default null; `threshold` (attribute `threshold`) : number, default 200; `label` (attribute `label`) : string, default "Scroll to top"
|
|
1475
|
+
Events: `scroll-to-top-triggered`
|
|
1476
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-font-weight-medium`, `--ui-line-height-tight`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`
|
|
1477
|
+
|
|
1478
|
+
Example:
|
|
1479
|
+
```html
|
|
1480
|
+
<scroll-to-top></scroll-to-top>
|
|
1481
|
+
```
|
|
1482
|
+
|
|
1328
1483
|
## <slide-panel>
|
|
1329
1484
|
|
|
1330
1485
|
Generic sliding panel shell. Handles positioning, open/close animation,
|
|
@@ -1604,6 +1759,30 @@ Example:
|
|
|
1604
1759
|
<ui-button variant="secondary" href="/properties?edit=42">Edit</ui-button>
|
|
1605
1760
|
```
|
|
1606
1761
|
|
|
1762
|
+
## <ui-checkbox>
|
|
1763
|
+
|
|
1764
|
+
A form-associated boolean checkbox, usable standalone or inside a native
|
|
1765
|
+
`<form>`. Submits `name=on` when checked (matching native
|
|
1766
|
+
`<input type="checkbox">` semantics) and participates fully in form
|
|
1767
|
+
`reset()`, ancestor `<fieldset disabled>`, and `required` validity.
|
|
1768
|
+
|
|
1769
|
+
Renders a native `<input type="checkbox">` wrapped in a `<label>`, styled
|
|
1770
|
+
via `:has()` on the wrapping label (matching `radio-pills`/`radio-cards`)
|
|
1771
|
+
rather than styling the native input directly; the checkbox itself renders
|
|
1772
|
+
at `1rem`, matching the existing radio-input convention.
|
|
1773
|
+
|
|
1774
|
+
Import: `import "@f-ewald/components/ui-checkbox.js";`
|
|
1775
|
+
|
|
1776
|
+
Properties: `checked` (attribute `checked`) : boolean, default false; `indeterminate` (attribute `indeterminate`) : boolean, default false; `disabled` (attribute `disabled`) : boolean, default false; `required` (attribute `required`) : boolean, default false; `name` (attribute `name`) : string, default ""; `label` (attribute `label`) : string, default ""
|
|
1777
|
+
Events: `change`
|
|
1778
|
+
CSS custom properties: `--ui-danger`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-line-height-tight`, `--ui-primary`, `--ui-radius-sm`, `--ui-text`
|
|
1779
|
+
|
|
1780
|
+
Example:
|
|
1781
|
+
```html
|
|
1782
|
+
<ui-checkbox label="Subscribe to updates"></ui-checkbox>
|
|
1783
|
+
<ui-checkbox name="terms" label="I agree to the terms" required></ui-checkbox>
|
|
1784
|
+
```
|
|
1785
|
+
|
|
1607
1786
|
## <user-avatar>
|
|
1608
1787
|
|
|
1609
1788
|
Circular avatar. Shows `src` when it loads successfully; falls back to the
|