@f-ewald/components 0.3.0 → 0.5.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 CHANGED
@@ -50,6 +50,7 @@ import "@f-ewald/components/roman-numeral.js";
50
50
  | `<distribution-chart>` | [docs/distribution-chart.md](./docs/distribution-chart.md) |
51
51
  | `<map-circle>` | [docs/map-circle.md](./docs/map-circle.md) |
52
52
  | `<map-pin>` | [docs/map-pin.md](./docs/map-pin.md) |
53
+ | `<map-point>` | [docs/map-point.md](./docs/map-point.md) |
53
54
  | `<percent-bar-chart>` | [docs/percent-bar-chart.md](./docs/percent-bar-chart.md) |
54
55
  | `<price-history-chart>` | [docs/price-history-chart.md](./docs/price-history-chart.md) |
55
56
  | `<radio-cards>` | [docs/radio-cards.md](./docs/radio-cards.md) |
@@ -58,6 +59,7 @@ import "@f-ewald/components/roman-numeral.js";
58
59
  | `<reveal-button>` | [docs/reveal-button.md](./docs/reveal-button.md) |
59
60
  | `<roman-numeral>` | [docs/roman-numeral.md](./docs/roman-numeral.md) |
60
61
  | `<slide-panel>` | [docs/slide-panel.md](./docs/slide-panel.md) |
62
+ | `<stat-meter>` | [docs/stat-meter.md](./docs/stat-meter.md) |
61
63
  | `<toast-notification>` | [docs/toast-notification.md](./docs/toast-notification.md) |
62
64
  | `<ui-button>` | [docs/ui-button.md](./docs/ui-button.md) |
63
65
  | `<user-avatar>` | [docs/user-avatar.md](./docs/user-avatar.md) |
@@ -2504,6 +2504,14 @@
2504
2504
  "module": "./map-circle.js"
2505
2505
  }
2506
2506
  },
2507
+ {
2508
+ "kind": "js",
2509
+ "name": "MapPoint",
2510
+ "declaration": {
2511
+ "name": "MapPoint",
2512
+ "module": "./map-point.js"
2513
+ }
2514
+ },
2507
2515
  {
2508
2516
  "kind": "js",
2509
2517
  "name": "RadioCards",
@@ -2552,6 +2560,14 @@
2552
2560
  "module": "./ui-button.js"
2553
2561
  }
2554
2562
  },
2563
+ {
2564
+ "kind": "js",
2565
+ "name": "StatMeter",
2566
+ "declaration": {
2567
+ "name": "StatMeter",
2568
+ "module": "./stat-meter.js"
2569
+ }
2570
+ },
2555
2571
  {
2556
2572
  "kind": "js",
2557
2573
  "name": "tokens",
@@ -2817,6 +2833,109 @@
2817
2833
  }
2818
2834
  ]
2819
2835
  },
2836
+ {
2837
+ "kind": "javascript-module",
2838
+ "path": "src/map-point.ts",
2839
+ "declarations": [
2840
+ {
2841
+ "kind": "class",
2842
+ "description": "A small plain-colored map marker for dense point layers (transit stops,\namenities, hazard points, etc.): a light-to-dark gradient fill with a thin\nwhite ring, no badge/content slot — every instance on a given layer shares\nthe same look, so there's nothing to render per-feature (unlike\n`<map-pin>`/`<map-circle>`, which carry per-marker slotted content).\nPurely a visual primitive — it has no `mapbox-gl` (or any mapping library)\ndependency; typically rasterized once per color and used as a Mapbox\n`icon-image` on a `symbol` layer rather than mounted as individual DOM\nmarkers, so a whole layer's worth of points shares one icon image.",
2843
+ "name": "MapPoint",
2844
+ "members": [
2845
+ {
2846
+ "kind": "field",
2847
+ "name": "color",
2848
+ "type": {
2849
+ "text": "string"
2850
+ },
2851
+ "default": "\"#4f46e5\"",
2852
+ "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
2853
+ "attribute": "color"
2854
+ },
2855
+ {
2856
+ "kind": "field",
2857
+ "name": "size",
2858
+ "type": {
2859
+ "text": "number"
2860
+ },
2861
+ "default": "14",
2862
+ "description": "Diameter, in CSS pixels.",
2863
+ "attribute": "size"
2864
+ },
2865
+ {
2866
+ "kind": "field",
2867
+ "name": "ringWidth",
2868
+ "type": {
2869
+ "text": "number"
2870
+ },
2871
+ "default": "3",
2872
+ "description": "White outer ring thickness, in the same viewBox units as `size` (scales with it).",
2873
+ "attribute": "ring-width"
2874
+ },
2875
+ {
2876
+ "kind": "field",
2877
+ "name": "_gradId",
2878
+ "privacy": "private",
2879
+ "readonly": true,
2880
+ "default": "`map-point-grad-${gradientIdCounter++}`"
2881
+ }
2882
+ ],
2883
+ "attributes": [
2884
+ {
2885
+ "name": "color",
2886
+ "type": {
2887
+ "text": "string"
2888
+ },
2889
+ "default": "\"#4f46e5\"",
2890
+ "description": "Fill color; the gradient's light (top) and dark (bottom) stops are derived from this.",
2891
+ "fieldName": "color"
2892
+ },
2893
+ {
2894
+ "name": "size",
2895
+ "type": {
2896
+ "text": "number"
2897
+ },
2898
+ "default": "14",
2899
+ "description": "Diameter, in CSS pixels.",
2900
+ "fieldName": "size"
2901
+ },
2902
+ {
2903
+ "name": "ring-width",
2904
+ "type": {
2905
+ "text": "number"
2906
+ },
2907
+ "default": "3",
2908
+ "description": "White outer ring thickness, in the same viewBox units as `size` (scales with it).",
2909
+ "fieldName": "ringWidth"
2910
+ }
2911
+ ],
2912
+ "superclass": {
2913
+ "name": "LitElement",
2914
+ "package": "lit"
2915
+ },
2916
+ "tagName": "map-point",
2917
+ "customElement": true
2918
+ }
2919
+ ],
2920
+ "exports": [
2921
+ {
2922
+ "kind": "js",
2923
+ "name": "MapPoint",
2924
+ "declaration": {
2925
+ "name": "MapPoint",
2926
+ "module": "src/map-point.ts"
2927
+ }
2928
+ },
2929
+ {
2930
+ "kind": "custom-element-definition",
2931
+ "name": "map-point",
2932
+ "declaration": {
2933
+ "name": "MapPoint",
2934
+ "module": "src/map-point.ts"
2935
+ }
2936
+ }
2937
+ ]
2938
+ },
2820
2939
  {
2821
2940
  "kind": "javascript-module",
2822
2941
  "path": "src/percent-bar-chart.ts",
@@ -3520,6 +3639,102 @@
3520
3639
  }
3521
3640
  ]
3522
3641
  },
3642
+ {
3643
+ "kind": "javascript-module",
3644
+ "path": "src/stat-meter.ts",
3645
+ "declarations": [
3646
+ {
3647
+ "kind": "class",
3648
+ "description": "A compact labeled meter for a single percentage reading — e.g. CPU or\nmemory usage in a dashboard header. `percent` may be `null` when no\nreading is available yet (e.g. the first tick of a polling metric); the\nbar then renders empty and the value shows an em dash instead of \"0%\".",
3649
+ "name": "StatMeter",
3650
+ "members": [
3651
+ {
3652
+ "kind": "field",
3653
+ "name": "label",
3654
+ "type": {
3655
+ "text": "string"
3656
+ },
3657
+ "default": "\"\"",
3658
+ "description": "Short label shown before the bar, e.g. \"CPU\" or \"MEM\".",
3659
+ "attribute": "label"
3660
+ },
3661
+ {
3662
+ "kind": "field",
3663
+ "name": "percent",
3664
+ "type": {
3665
+ "text": "number | null"
3666
+ },
3667
+ "default": "null",
3668
+ "description": "Percentage 0-100. `null` renders an empty bar and a \"—\" value instead of \"0%\".",
3669
+ "attribute": "percent"
3670
+ },
3671
+ {
3672
+ "kind": "field",
3673
+ "name": "color",
3674
+ "type": {
3675
+ "text": "string"
3676
+ },
3677
+ "default": "\"\"",
3678
+ "description": "Fill color override; falls back to the `--ui-success` token.",
3679
+ "attribute": "color"
3680
+ }
3681
+ ],
3682
+ "attributes": [
3683
+ {
3684
+ "name": "label",
3685
+ "type": {
3686
+ "text": "string"
3687
+ },
3688
+ "default": "\"\"",
3689
+ "description": "Short label shown before the bar, e.g. \"CPU\" or \"MEM\".",
3690
+ "fieldName": "label"
3691
+ },
3692
+ {
3693
+ "name": "percent",
3694
+ "type": {
3695
+ "text": "number | null"
3696
+ },
3697
+ "default": "null",
3698
+ "description": "Percentage 0-100. `null` renders an empty bar and a \"—\" value instead of \"0%\".",
3699
+ "fieldName": "percent"
3700
+ },
3701
+ {
3702
+ "name": "color",
3703
+ "type": {
3704
+ "text": "string"
3705
+ },
3706
+ "default": "\"\"",
3707
+ "description": "Fill color override; falls back to the `--ui-success` token.",
3708
+ "fieldName": "color"
3709
+ }
3710
+ ],
3711
+ "superclass": {
3712
+ "name": "LitElement",
3713
+ "package": "lit"
3714
+ },
3715
+ "tagName": "stat-meter",
3716
+ "customElement": true
3717
+ }
3718
+ ],
3719
+ "exports": [
3720
+ {
3721
+ "kind": "js",
3722
+ "name": "StatMeter",
3723
+ "declaration": {
3724
+ "name": "StatMeter",
3725
+ "module": "src/stat-meter.ts"
3726
+ }
3727
+ },
3728
+ {
3729
+ "kind": "custom-element-definition",
3730
+ "name": "stat-meter",
3731
+ "declaration": {
3732
+ "name": "StatMeter",
3733
+ "module": "src/stat-meter.ts"
3734
+ }
3735
+ }
3736
+ ]
3737
+ },
3523
3738
  {
3524
3739
  "kind": "javascript-module",
3525
3740
  "path": "src/toast-notification.ts",
package/dist/index.d.ts CHANGED
@@ -16,9 +16,11 @@ export { AutocompleteInput, type AutocompleteOption, } from "./autocomplete-inpu
16
16
  export { UserAvatar } from "./user-avatar.js";
17
17
  export { MapPin } from "./map-pin.js";
18
18
  export { MapCircle } from "./map-circle.js";
19
+ export { MapPoint } from "./map-point.js";
19
20
  export { RadioCards, type RadioCardOption } from "./radio-cards.js";
20
21
  export { RadioPills, type RadioPillOption } from "./radio-pills.js";
21
22
  export { UiButton, type ButtonVariant } from "./ui-button.js";
23
+ export { StatMeter } from "./stat-meter.js";
22
24
  export { tokens, tokenValues } from "./tokens.js";
23
25
  export * from "./icons.js";
24
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,KAAK,YAAY,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClD,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,KAAK,YAAY,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClD,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -16,9 +16,11 @@ export { AutocompleteInput, } from "./autocomplete-input.js";
16
16
  export { UserAvatar } from "./user-avatar.js";
17
17
  export { MapPin } from "./map-pin.js";
18
18
  export { MapCircle } from "./map-circle.js";
19
+ export { MapPoint } from "./map-point.js";
19
20
  export { RadioCards } from "./radio-cards.js";
20
21
  export { RadioPills } from "./radio-pills.js";
21
22
  export { UiButton } from "./ui-button.js";
23
+ export { StatMeter } from "./stat-meter.js";
22
24
  export { tokens, tokenValues } from "./tokens.js";
23
25
  export * from "./icons.js";
24
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,GAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAwB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,GAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAsB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClD,cAAc,YAAY,CAAC","sourcesContent":["export { AnimateConfetti } from \"./animate-confetti.js\";\nexport { RevealButton } from \"./reveal-button.js\";\nexport { RomanNumeral } from \"./roman-numeral.js\";\nexport { ConfirmDialog } from \"./confirm-dialog.js\";\nexport {\n ToastNotification,\n notifySuccess,\n notifyError,\n notifyInfo,\n type ToastVariant,\n} from \"./toast-notification.js\";\nexport { SlidePanel } from \"./slide-panel.js\";\nexport { CopyLinkButton } from \"./copy-link-button.js\";\nexport { RelativeTime } from \"./relative-time.js\";\nexport { DistanceValue } from \"./distance-value.js\";\nexport { PriceHistoryChart, type PricePoint } from \"./price-history-chart.js\";\nexport { DistributionChart, type DistributionValue } from \"./distribution-chart.js\";\nexport { PercentBarChart, type PercentBarGroup } from \"./percent-bar-chart.js\";\nexport { WeightBarChart, type WeightBarItem } from \"./weight-bar-chart.js\";\nexport {\n AddressAutocomplete,\n type AddressSuggestion,\n} from \"./address-autocomplete.js\";\nexport {\n AutocompleteInput,\n type AutocompleteOption,\n} from \"./autocomplete-input.js\";\nexport { UserAvatar } from \"./user-avatar.js\";\nexport { MapPin } from \"./map-pin.js\";\nexport { MapCircle } from \"./map-circle.js\";\nexport { RadioCards, type RadioCardOption } from \"./radio-cards.js\";\nexport { RadioPills, type RadioPillOption } from \"./radio-pills.js\";\nexport { UiButton, type ButtonVariant } from \"./ui-button.js\";\nexport { tokens, tokenValues } from \"./tokens.js\";\nexport * from \"./icons.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,GAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAwB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,GAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAsB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClD,cAAc,YAAY,CAAC","sourcesContent":["export { AnimateConfetti } from \"./animate-confetti.js\";\nexport { RevealButton } from \"./reveal-button.js\";\nexport { RomanNumeral } from \"./roman-numeral.js\";\nexport { ConfirmDialog } from \"./confirm-dialog.js\";\nexport {\n ToastNotification,\n notifySuccess,\n notifyError,\n notifyInfo,\n type ToastVariant,\n} from \"./toast-notification.js\";\nexport { SlidePanel } from \"./slide-panel.js\";\nexport { CopyLinkButton } from \"./copy-link-button.js\";\nexport { RelativeTime } from \"./relative-time.js\";\nexport { DistanceValue } from \"./distance-value.js\";\nexport { PriceHistoryChart, type PricePoint } from \"./price-history-chart.js\";\nexport { DistributionChart, type DistributionValue } from \"./distribution-chart.js\";\nexport { PercentBarChart, type PercentBarGroup } from \"./percent-bar-chart.js\";\nexport { WeightBarChart, type WeightBarItem } from \"./weight-bar-chart.js\";\nexport {\n AddressAutocomplete,\n type AddressSuggestion,\n} from \"./address-autocomplete.js\";\nexport {\n AutocompleteInput,\n type AutocompleteOption,\n} from \"./autocomplete-input.js\";\nexport { UserAvatar } from \"./user-avatar.js\";\nexport { MapPin } from \"./map-pin.js\";\nexport { MapCircle } from \"./map-circle.js\";\nexport { MapPoint } from \"./map-point.js\";\nexport { RadioCards, type RadioCardOption } from \"./radio-cards.js\";\nexport { RadioPills, type RadioPillOption } from \"./radio-pills.js\";\nexport { UiButton, type ButtonVariant } from \"./ui-button.js\";\nexport { StatMeter } from \"./stat-meter.js\";\nexport { tokens, tokenValues } from \"./tokens.js\";\nexport * from \"./icons.js\";\n"]}
@@ -0,0 +1,31 @@
1
+ import { LitElement } from "lit";
2
+ /**
3
+ * A small plain-colored map marker for dense point layers (transit stops,
4
+ * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
5
+ * white ring, no badge/content slot — every instance on a given layer shares
6
+ * the same look, so there's nothing to render per-feature (unlike
7
+ * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
8
+ * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
9
+ * dependency; typically rasterized once per color and used as a Mapbox
10
+ * `icon-image` on a `symbol` layer rather than mounted as individual DOM
11
+ * markers, so a whole layer's worth of points shares one icon image.
12
+ *
13
+ * @element map-point
14
+ */
15
+ export declare class MapPoint extends LitElement {
16
+ static styles: import("lit").CSSResult[];
17
+ /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */
18
+ color: string;
19
+ /** Diameter, in CSS pixels. */
20
+ size: number;
21
+ /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */
22
+ ringWidth: number;
23
+ private readonly _gradId;
24
+ render(): import("lit-html").TemplateResult<1>;
25
+ }
26
+ declare global {
27
+ interface HTMLElementTagNameMap {
28
+ "map-point": MapPoint;
29
+ }
30
+ }
31
+ //# sourceMappingURL=map-point.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-point.d.ts","sourceRoot":"","sources":["../src/map-point.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;;;GAYG;AACH,qBACa,QAAS,SAAQ,UAAU;IACtC,OAAgB,MAAM,4BAWpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IAEnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAE1D,MAAM,yCAoBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
@@ -0,0 +1,83 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, css, html } from "lit";
8
+ import { customElement, property } from "lit/decorators.js";
9
+ import { tokens } from "./tokens.js";
10
+ import { mixHex } from "./utils/color.js";
11
+ let gradientIdCounter = 0;
12
+ /**
13
+ * A small plain-colored map marker for dense point layers (transit stops,
14
+ * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
15
+ * white ring, no badge/content slot — every instance on a given layer shares
16
+ * the same look, so there's nothing to render per-feature (unlike
17
+ * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
18
+ * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
19
+ * dependency; typically rasterized once per color and used as a Mapbox
20
+ * `icon-image` on a `symbol` layer rather than mounted as individual DOM
21
+ * markers, so a whole layer's worth of points shares one icon image.
22
+ *
23
+ * @element map-point
24
+ */
25
+ let MapPoint = class MapPoint extends LitElement {
26
+ constructor() {
27
+ super(...arguments);
28
+ /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */
29
+ this.color = "#4f46e5";
30
+ /** Diameter, in CSS pixels. */
31
+ this.size = 14;
32
+ /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */
33
+ this.ringWidth = 3;
34
+ this._gradId = `map-point-grad-${gradientIdCounter++}`;
35
+ }
36
+ static { this.styles = [
37
+ tokens,
38
+ css `
39
+ :host {
40
+ display: inline-block;
41
+ line-height: 0;
42
+ }
43
+ svg {
44
+ display: block;
45
+ }
46
+ `,
47
+ ]; }
48
+ render() {
49
+ const light = mixHex(this.color, "#ffffff", 30);
50
+ const dark = mixHex(this.color, "#000000", 30);
51
+ return html `
52
+ <svg
53
+ width=${this.size}
54
+ height=${this.size}
55
+ viewBox="0 0 32 32"
56
+ fill="none"
57
+ xmlns="http://www.w3.org/2000/svg"
58
+ >
59
+ <defs>
60
+ <linearGradient id=${this._gradId} x1="0" y1="0" x2="0" y2="1">
61
+ <stop offset="0%" stop-color=${light} />
62
+ <stop offset="100%" stop-color=${dark} />
63
+ </linearGradient>
64
+ </defs>
65
+ <circle cx="16" cy="16" r="13" fill="url(#${this._gradId})" stroke="#ffffff" stroke-width=${this.ringWidth} />
66
+ </svg>
67
+ `;
68
+ }
69
+ };
70
+ __decorate([
71
+ property()
72
+ ], MapPoint.prototype, "color", void 0);
73
+ __decorate([
74
+ property({ type: Number })
75
+ ], MapPoint.prototype, "size", void 0);
76
+ __decorate([
77
+ property({ type: Number, attribute: "ring-width" })
78
+ ], MapPoint.prototype, "ringWidth", void 0);
79
+ MapPoint = __decorate([
80
+ customElement("map-point")
81
+ ], MapPoint);
82
+ export { MapPoint };
83
+ //# sourceMappingURL=map-point.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-point.js","sourceRoot":"","sources":["../src/map-point.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;GAYG;AAEI,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAAjC;;QAcL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QAElD,YAAO,GAAG,kBAAkB,iBAAiB,EAAE,EAAE,CAAC;IAuBrE,CAAC;aA3CiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;KAQF;KACF,AAXqB,CAWpB;IAWO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,IAAI;;;;;;+BAMK,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;oDAGG,IAAI,CAAC,OAAO,oCAAoC,IAAI,CAAC,SAAS;;KAE7G,CAAC;IACJ,CAAC;CACF,CAAA;AA7Ba;IAAX,QAAQ,EAAE;uCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;2CAAe;AAnBxD,QAAQ;IADpB,aAAa,CAAC,WAAW,CAAC;GACd,QAAQ,CA4CpB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A small plain-colored map marker for dense point layers (transit stops,\n * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin\n * white ring, no badge/content slot — every instance on a given layer shares\n * the same look, so there's nothing to render per-feature (unlike\n * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).\n * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)\n * dependency; typically rasterized once per color and used as a Mapbox\n * `icon-image` on a `symbol` layer rather than mounted as individual DOM\n * markers, so a whole layer's worth of points shares one icon image.\n *\n * @element map-point\n */\n@customElement(\"map-point\")\nexport class MapPoint extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n line-height: 0;\n }\n svg {\n display: block;\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter, in CSS pixels. */\n @property({ type: Number }) size = 14;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 3;\n\n private readonly _gradId = `map-point-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n return html`\n <svg\n width=${this.size}\n height=${this.size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <circle cx=\"16\" cy=\"16\" r=\"13\" fill=\"url(#${this._gradId})\" stroke=\"#ffffff\" stroke-width=${this.ringWidth} />\n </svg>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-point\": MapPoint;\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { LitElement } from "lit";
2
+ /**
3
+ * A compact labeled meter for a single percentage reading — e.g. CPU or
4
+ * memory usage in a dashboard header. `percent` may be `null` when no
5
+ * reading is available yet (e.g. the first tick of a polling metric); the
6
+ * bar then renders empty and the value shows an em dash instead of "0%".
7
+ *
8
+ * @element stat-meter
9
+ */
10
+ export declare class StatMeter extends LitElement {
11
+ static styles: import("lit").CSSResult[];
12
+ /** Short label shown before the bar, e.g. "CPU" or "MEM". */
13
+ label: string;
14
+ /** Percentage 0-100. `null` renders an empty bar and a "—" value instead of "0%". */
15
+ percent: number | null;
16
+ /** Fill color override; falls back to the `--ui-success` token. */
17
+ color: string;
18
+ render(): import("lit-html").TemplateResult<1>;
19
+ }
20
+ declare global {
21
+ interface HTMLElementTagNameMap {
22
+ "stat-meter": StatMeter;
23
+ }
24
+ }
25
+ //# sourceMappingURL=stat-meter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-meter.d.ts","sourceRoot":"","sources":["../src/stat-meter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;;;;GAOG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,4BAmDpB;IAEF,6DAA6D;IACjD,KAAK,SAAM;IAEvB,qFAAqF;IACzD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1D,mEAAmE;IACvD,KAAK,SAAM;IAEd,MAAM,yCAWd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
@@ -0,0 +1,106 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, css, html } from "lit";
8
+ import { customElement, property } from "lit/decorators.js";
9
+ import { tokens } from "./tokens.js";
10
+ /**
11
+ * A compact labeled meter for a single percentage reading — e.g. CPU or
12
+ * memory usage in a dashboard header. `percent` may be `null` when no
13
+ * reading is available yet (e.g. the first tick of a polling metric); the
14
+ * bar then renders empty and the value shows an em dash instead of "0%".
15
+ *
16
+ * @element stat-meter
17
+ */
18
+ let StatMeter = class StatMeter extends LitElement {
19
+ constructor() {
20
+ super(...arguments);
21
+ /** Short label shown before the bar, e.g. "CPU" or "MEM". */
22
+ this.label = "";
23
+ /** Percentage 0-100. `null` renders an empty bar and a "—" value instead of "0%". */
24
+ this.percent = null;
25
+ /** Fill color override; falls back to the `--ui-success` token. */
26
+ this.color = "";
27
+ }
28
+ static { this.styles = [
29
+ tokens,
30
+ css `
31
+ :host {
32
+ display: inline-flex;
33
+ align-items: center;
34
+ gap: 8px;
35
+ font-family: var(
36
+ --ui-font,
37
+ ui-sans-serif,
38
+ system-ui,
39
+ sans-serif,
40
+ "Apple Color Emoji",
41
+ "Segoe UI Emoji",
42
+ "Segoe UI Symbol",
43
+ "Noto Color Emoji"
44
+ );
45
+ }
46
+
47
+ .label {
48
+ font-size: var(--ui-font-size-sm, 0.75rem);
49
+ font-weight: 600;
50
+ letter-spacing: 0.04em;
51
+ color: var(--ui-text-muted, #64748b);
52
+ }
53
+
54
+ .track {
55
+ display: block;
56
+ width: 64px;
57
+ height: 6px;
58
+ border-radius: 3px;
59
+ background: var(--ui-surface-muted, #f8fafc);
60
+ overflow: hidden;
61
+ }
62
+
63
+ .fill {
64
+ display: block;
65
+ height: 100%;
66
+ background: var(--fill-color, var(--ui-success, #16a34a));
67
+ transition: width 0.3s ease;
68
+ }
69
+
70
+ .value {
71
+ min-width: 32px;
72
+ font-size: var(--ui-font-size-sm, 0.75rem);
73
+ font-weight: 500;
74
+ color: var(--ui-text, #0f172a);
75
+ font-variant-numeric: tabular-nums;
76
+ text-align: right;
77
+ }
78
+ `,
79
+ ]; }
80
+ render() {
81
+ const pct = this.percent;
82
+ const clamped = pct === null ? 0 : Math.min(100, Math.max(0, pct));
83
+ const fillStyle = this.color ? `width: ${clamped}%; --fill-color: ${this.color}` : `width: ${clamped}%`;
84
+ return html `
85
+ <span class="label">${this.label}</span>
86
+ <span class="track" role="img" aria-label="${this.label} ${pct === null ? "no reading" : `${pct}%`}">
87
+ <span class="fill" style=${fillStyle}></span>
88
+ </span>
89
+ <span class="value">${pct === null ? "—" : `${pct}%`}</span>
90
+ `;
91
+ }
92
+ };
93
+ __decorate([
94
+ property()
95
+ ], StatMeter.prototype, "label", void 0);
96
+ __decorate([
97
+ property({ type: Number })
98
+ ], StatMeter.prototype, "percent", void 0);
99
+ __decorate([
100
+ property()
101
+ ], StatMeter.prototype, "color", void 0);
102
+ StatMeter = __decorate([
103
+ customElement("stat-meter")
104
+ ], StatMeter);
105
+ export { StatMeter };
106
+ //# sourceMappingURL=stat-meter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-meter.js","sourceRoot":"","sources":["../src/stat-meter.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;GAOG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAsDL,6DAA6D;QACjD,UAAK,GAAG,EAAE,CAAC;QAEvB,qFAAqF;QACzD,YAAO,GAAkB,IAAI,CAAC;QAE1D,mEAAmE;QACvD,UAAK,GAAG,EAAE,CAAC;IAczB,CAAC;aA1EiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgDF;KACF,AAnDqB,CAmDpB;IAWO,MAAM;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,OAAO,oBAAoB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,OAAO,GAAG,CAAC;QACxG,OAAO,IAAI,CAAA;4BACa,IAAI,CAAC,KAAK;mDACa,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG;mCACrE,SAAS;;4BAEhB,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG;KACrD,CAAC;IACJ,CAAC;CACF,CAAA;AApBa;IAAX,QAAQ,EAAE;wCAAY;AAGK;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAA+B;AAG9C;IAAX,QAAQ,EAAE;wCAAY;AA7DZ,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CA2ErB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * A compact labeled meter for a single percentage reading — e.g. CPU or\n * memory usage in a dashboard header. `percent` may be `null` when no\n * reading is available yet (e.g. the first tick of a polling metric); the\n * bar then renders empty and the value shows an em dash instead of \"0%\".\n *\n * @element stat-meter\n */\n@customElement(\"stat-meter\")\nexport class StatMeter extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n }\n\n .label {\n font-size: var(--ui-font-size-sm, 0.75rem);\n font-weight: 600;\n letter-spacing: 0.04em;\n color: var(--ui-text-muted, #64748b);\n }\n\n .track {\n display: block;\n width: 64px;\n height: 6px;\n border-radius: 3px;\n background: var(--ui-surface-muted, #f8fafc);\n overflow: hidden;\n }\n\n .fill {\n display: block;\n height: 100%;\n background: var(--fill-color, var(--ui-success, #16a34a));\n transition: width 0.3s ease;\n }\n\n .value {\n min-width: 32px;\n font-size: var(--ui-font-size-sm, 0.75rem);\n font-weight: 500;\n color: var(--ui-text, #0f172a);\n font-variant-numeric: tabular-nums;\n text-align: right;\n }\n `,\n ];\n\n /** Short label shown before the bar, e.g. \"CPU\" or \"MEM\". */\n @property() label = \"\";\n\n /** Percentage 0-100. `null` renders an empty bar and a \"—\" value instead of \"0%\". */\n @property({ type: Number }) percent: number | null = null;\n\n /** Fill color override; falls back to the `--ui-success` token. */\n @property() color = \"\";\n\n override render() {\n const pct = this.percent;\n const clamped = pct === null ? 0 : Math.min(100, Math.max(0, pct));\n const fillStyle = this.color ? `width: ${clamped}%; --fill-color: ${this.color}` : `width: ${clamped}%`;\n return html`\n <span class=\"label\">${this.label}</span>\n <span class=\"track\" role=\"img\" aria-label=\"${this.label} ${pct === null ? \"no reading\" : `${pct}%`}\">\n <span class=\"fill\" style=${fillStyle}></span>\n </span>\n <span class=\"value\">${pct === null ? \"—\" : `${pct}%`}</span>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"stat-meter\": StatMeter;\n }\n}\n"]}
@@ -0,0 +1,44 @@
1
+ # `<map-point>`
2
+
3
+ A small plain-colored map marker for dense point layers (transit stops,
4
+ amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
5
+ white ring, no badge/content slot — every instance on a given layer shares
6
+ the same look, so there's nothing to render per-feature (unlike
7
+ `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
8
+ Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
9
+ dependency; typically rasterized once per color and used as a Mapbox
10
+ `icon-image` on a `symbol` layer rather than mounted as individual DOM
11
+ markers, so a whole layer's worth of points shares one icon image.
12
+
13
+ ## Install
14
+
15
+ ```js
16
+ import "@f-ewald/components/map-point.js";
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```html
22
+ <map-point color="#0099D8"></map-point>
23
+ <map-point color="#fb8072" size="10" ring-width="2"></map-point>
24
+ ```
25
+
26
+ ## Attributes / properties
27
+
28
+ | Property | Attribute | Type | Default | Description |
29
+ | --- | --- | --- | --- | --- |
30
+ | `color` | `color` | `string` | `"#4f46e5"` | Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. |
31
+ | `size` | `size` | `number` | `14` | Diameter, in CSS pixels. |
32
+ | `ringWidth` | `ring-width` | `number` | `3` | White outer ring thickness, in the same viewBox units as `size` (scales with it). |
33
+
34
+ ## Events
35
+
36
+ _None._
37
+
38
+ ## Slots
39
+
40
+ _None._
41
+
42
+ ## CSS custom properties
43
+
44
+ _None._
@@ -0,0 +1,48 @@
1
+ # `<stat-meter>`
2
+
3
+ A compact labeled meter for a single percentage reading — e.g. CPU or
4
+ memory usage in a dashboard header. `percent` may be `null` when no
5
+ reading is available yet (e.g. the first tick of a polling metric); the
6
+ bar then renders empty and the value shows an em dash instead of "0%".
7
+
8
+ ## Install
9
+
10
+ ```js
11
+ import "@f-ewald/components/stat-meter.js";
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```html
17
+ <stat-meter label="CPU" percent="42"></stat-meter>
18
+ <stat-meter label="MEM" percent="76"></stat-meter>
19
+ <stat-meter label="I/O"></stat-meter> <!-- percent unset -> null -> renders "—" -->
20
+ <stat-meter label="GPU" percent="88" color="#dc2626"></stat-meter>
21
+ ```
22
+
23
+ ## Attributes / properties
24
+
25
+ | Property | Attribute | Type | Default | Description |
26
+ | --- | --- | --- | --- | --- |
27
+ | `label` | `label` | `string` | `""` | Short label shown before the bar, e.g. "CPU" or "MEM". |
28
+ | `percent` | `percent` | `number | null` | `null` | Percentage 0-100. `null` renders an empty bar and a "—" value instead of "0%". |
29
+ | `color` | `color` | `string` | `""` | Fill color override; falls back to the `--ui-success` token. |
30
+
31
+ ## Events
32
+
33
+ _None._
34
+
35
+ ## Slots
36
+
37
+ _None._
38
+
39
+ ## CSS custom properties
40
+
41
+ | Custom property |
42
+ | --- |
43
+ | `--ui-font` |
44
+ | `--ui-font-size-sm` |
45
+ | `--ui-success` |
46
+ | `--ui-surface-muted` |
47
+ | `--ui-text` |
48
+ | `--ui-text-muted` |
package/llms.txt CHANGED
@@ -227,6 +227,30 @@ Example:
227
227
  <map-pin color="#22c55e" size="26" highlighted>🏠</map-pin>
228
228
  ```
229
229
 
230
+ ## <map-point>
231
+
232
+ A small plain-colored map marker for dense point layers (transit stops,
233
+ amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
234
+ white ring, no badge/content slot — every instance on a given layer shares
235
+ the same look, so there's nothing to render per-feature (unlike
236
+ `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
237
+ Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
238
+ dependency; typically rasterized once per color and used as a Mapbox
239
+ `icon-image` on a `symbol` layer rather than mounted as individual DOM
240
+ markers, so a whole layer's worth of points shares one icon image.
241
+
242
+ Import: `import "@f-ewald/components/map-point.js";`
243
+
244
+ Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 14; `ringWidth` (attribute `ring-width`) : number, default 3
245
+ Events: none
246
+ CSS custom properties: none
247
+
248
+ Example:
249
+ ```html
250
+ <map-point color="#0099D8"></map-point>
251
+ <map-point color="#fb8072" size="10" ring-width="2"></map-point>
252
+ ```
253
+
230
254
  ## <percent-bar-chart>
231
255
 
232
256
  Horizontal bar chart for labeled percentage rows, using D3's linear scale.
@@ -402,6 +426,27 @@ Example:
402
426
  </slide-panel>
403
427
  ```
404
428
 
429
+ ## <stat-meter>
430
+
431
+ A compact labeled meter for a single percentage reading — e.g. CPU or
432
+ memory usage in a dashboard header. `percent` may be `null` when no
433
+ reading is available yet (e.g. the first tick of a polling metric); the
434
+ bar then renders empty and the value shows an em dash instead of "0%".
435
+
436
+ Import: `import "@f-ewald/components/stat-meter.js";`
437
+
438
+ Properties: `label` (attribute `label`) : string, default ""; `percent` (attribute `percent`) : number | null, default null; `color` (attribute `color`) : string, default ""
439
+ Events: none
440
+ CSS custom properties: `--ui-font`, `--ui-font-size-sm`, `--ui-success`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
441
+
442
+ Example:
443
+ ```html
444
+ <stat-meter label="CPU" percent="42"></stat-meter>
445
+ <stat-meter label="MEM" percent="76"></stat-meter>
446
+ <stat-meter label="I/O"></stat-meter> <!-- percent unset -> null -> renders "—" -->
447
+ <stat-meter label="GPU" percent="88" color="#dc2626"></stat-meter>
448
+ ```
449
+
405
450
  ## <toast-notification>
406
451
 
407
452
  Fixed-position stack of dismissible notifications, anchored top-right
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@f-ewald/components",
3
3
  "private": false,
4
- "version": "0.3.0",
4
+ "version": "0.5.0",
5
5
  "description": "A collection of universally usable web components for various tasks.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",