panelui-native 0.66.1 → 0.68.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 (129) hide show
  1. package/README.md +21 -1
  2. package/lib/module/components/area-chart/index.js +18 -1
  3. package/lib/module/components/area-chart/index.js.map +1 -1
  4. package/lib/module/components/bar-chart/index.js +18 -1
  5. package/lib/module/components/bar-chart/index.js.map +1 -1
  6. package/lib/module/components/candlestick-chart/index.js +18 -1
  7. package/lib/module/components/candlestick-chart/index.js.map +1 -1
  8. package/lib/module/components/form/index.js +7 -5
  9. package/lib/module/components/form/index.js.map +1 -1
  10. package/lib/module/components/form/typed-form.js +11 -0
  11. package/lib/module/components/form/typed-form.js.map +1 -0
  12. package/lib/module/components/form/use-form.js +4 -0
  13. package/lib/module/components/form/use-form.js.map +1 -1
  14. package/lib/module/components/heatmap-chart/index.js +27 -1
  15. package/lib/module/components/heatmap-chart/index.js.map +1 -1
  16. package/lib/module/components/line-chart/index.js +18 -1
  17. package/lib/module/components/line-chart/index.js.map +1 -1
  18. package/lib/module/components/message-scroller/index.js +172 -10
  19. package/lib/module/components/message-scroller/index.js.map +1 -1
  20. package/lib/module/components/message-scroller/message-scroller-math.js +23 -0
  21. package/lib/module/components/message-scroller/message-scroller-math.js.map +1 -1
  22. package/lib/module/components/meter/index.js +250 -0
  23. package/lib/module/components/meter/index.js.map +1 -0
  24. package/lib/module/components/meter/meter-scale.js +88 -0
  25. package/lib/module/components/meter/meter-scale.js.map +1 -0
  26. package/lib/module/components/planner/index.js +714 -0
  27. package/lib/module/components/planner/index.js.map +1 -0
  28. package/lib/module/components/planner/planner-entries.js +124 -0
  29. package/lib/module/components/planner/planner-entries.js.map +1 -0
  30. package/lib/module/components/radar-chart/index.js +18 -1
  31. package/lib/module/components/radar-chart/index.js.map +1 -1
  32. package/lib/module/components/scatter-chart/index.js +18 -1
  33. package/lib/module/components/scatter-chart/index.js.map +1 -1
  34. package/lib/module/components/skeleton/index.js +45 -7
  35. package/lib/module/components/skeleton/index.js.map +1 -1
  36. package/lib/module/components/spinner/index.js +63 -14
  37. package/lib/module/components/spinner/index.js.map +1 -1
  38. package/lib/module/components/time-picker/index.js +46 -21
  39. package/lib/module/components/time-picker/index.js.map +1 -1
  40. package/lib/module/components/time-picker/ruler-window.js +25 -0
  41. package/lib/module/components/time-picker/ruler-window.js.map +1 -0
  42. package/lib/module/hooks/breakpoint-contract.js +29 -0
  43. package/lib/module/hooks/breakpoint-contract.js.map +1 -0
  44. package/lib/module/hooks/index.js +1 -1
  45. package/lib/module/hooks/index.js.map +1 -1
  46. package/lib/module/hooks/use-breakpoint.js +46 -1
  47. package/lib/module/hooks/use-breakpoint.js.map +1 -1
  48. package/lib/module/index.js +3 -1
  49. package/lib/module/index.js.map +1 -1
  50. package/lib/module/primitives/chart-accessibility.js +68 -0
  51. package/lib/module/primitives/chart-accessibility.js.map +1 -0
  52. package/lib/typescript/src/components/area-chart/index.d.ts +2 -1
  53. package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
  54. package/lib/typescript/src/components/bar-chart/index.d.ts +2 -1
  55. package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -1
  56. package/lib/typescript/src/components/candlestick-chart/index.d.ts +2 -1
  57. package/lib/typescript/src/components/candlestick-chart/index.d.ts.map +1 -1
  58. package/lib/typescript/src/components/form/index.d.ts +18 -5
  59. package/lib/typescript/src/components/form/index.d.ts.map +1 -1
  60. package/lib/typescript/src/components/form/typed-form.d.ts +7 -0
  61. package/lib/typescript/src/components/form/typed-form.d.ts.map +1 -0
  62. package/lib/typescript/src/components/form/use-form.d.ts +4 -0
  63. package/lib/typescript/src/components/form/use-form.d.ts.map +1 -1
  64. package/lib/typescript/src/components/heatmap-chart/index.d.ts +2 -1
  65. package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
  66. package/lib/typescript/src/components/line-chart/index.d.ts +2 -1
  67. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  68. package/lib/typescript/src/components/message-scroller/index.d.ts +30 -2
  69. package/lib/typescript/src/components/message-scroller/index.d.ts.map +1 -1
  70. package/lib/typescript/src/components/message-scroller/message-scroller-math.d.ts +10 -0
  71. package/lib/typescript/src/components/message-scroller/message-scroller-math.d.ts.map +1 -1
  72. package/lib/typescript/src/components/meter/index.d.ts +270 -0
  73. package/lib/typescript/src/components/meter/index.d.ts.map +1 -0
  74. package/lib/typescript/src/components/meter/meter-scale.d.ts +57 -0
  75. package/lib/typescript/src/components/meter/meter-scale.d.ts.map +1 -0
  76. package/lib/typescript/src/components/planner/index.d.ts +274 -0
  77. package/lib/typescript/src/components/planner/index.d.ts.map +1 -0
  78. package/lib/typescript/src/components/planner/planner-entries.d.ts +75 -0
  79. package/lib/typescript/src/components/planner/planner-entries.d.ts.map +1 -0
  80. package/lib/typescript/src/components/radar-chart/index.d.ts +4 -0
  81. package/lib/typescript/src/components/radar-chart/index.d.ts.map +1 -1
  82. package/lib/typescript/src/components/scatter-chart/index.d.ts +2 -1
  83. package/lib/typescript/src/components/scatter-chart/index.d.ts.map +1 -1
  84. package/lib/typescript/src/components/skeleton/index.d.ts +25 -2
  85. package/lib/typescript/src/components/skeleton/index.d.ts.map +1 -1
  86. package/lib/typescript/src/components/spinner/index.d.ts +25 -2
  87. package/lib/typescript/src/components/spinner/index.d.ts.map +1 -1
  88. package/lib/typescript/src/components/time-picker/index.d.ts +5 -6
  89. package/lib/typescript/src/components/time-picker/index.d.ts.map +1 -1
  90. package/lib/typescript/src/components/time-picker/ruler-window.d.ts +12 -0
  91. package/lib/typescript/src/components/time-picker/ruler-window.d.ts.map +1 -0
  92. package/lib/typescript/src/hooks/breakpoint-contract.d.ts +6 -0
  93. package/lib/typescript/src/hooks/breakpoint-contract.d.ts.map +1 -0
  94. package/lib/typescript/src/hooks/index.d.ts +1 -1
  95. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  96. package/lib/typescript/src/hooks/use-breakpoint.d.ts +22 -0
  97. package/lib/typescript/src/hooks/use-breakpoint.d.ts.map +1 -1
  98. package/lib/typescript/src/index.d.ts +3 -1
  99. package/lib/typescript/src/index.d.ts.map +1 -1
  100. package/lib/typescript/src/primitives/chart-accessibility.d.ts +33 -0
  101. package/lib/typescript/src/primitives/chart-accessibility.d.ts.map +1 -0
  102. package/lib/typescript/types/form-api.type-test.d.ts +2 -0
  103. package/lib/typescript/types/form-api.type-test.d.ts.map +1 -0
  104. package/package.json +28 -2
  105. package/src/components/area-chart/index.tsx +27 -2
  106. package/src/components/bar-chart/index.tsx +27 -2
  107. package/src/components/candlestick-chart/index.tsx +30 -2
  108. package/src/components/form/index.tsx +32 -5
  109. package/src/components/form/typed-form.ts +13 -0
  110. package/src/components/form/use-form.ts +9 -0
  111. package/src/components/heatmap-chart/index.tsx +49 -3
  112. package/src/components/line-chart/index.tsx +27 -2
  113. package/src/components/message-scroller/index.tsx +234 -6
  114. package/src/components/message-scroller/message-scroller-math.ts +38 -0
  115. package/src/components/meter/index.tsx +318 -0
  116. package/src/components/meter/meter-scale.ts +109 -0
  117. package/src/components/planner/index.tsx +886 -0
  118. package/src/components/planner/planner-entries.ts +146 -0
  119. package/src/components/radar-chart/index.tsx +24 -0
  120. package/src/components/scatter-chart/index.tsx +27 -2
  121. package/src/components/skeleton/index.tsx +59 -5
  122. package/src/components/spinner/index.tsx +80 -13
  123. package/src/components/time-picker/index.tsx +57 -29
  124. package/src/components/time-picker/ruler-window.ts +24 -0
  125. package/src/hooks/breakpoint-contract.ts +31 -0
  126. package/src/hooks/index.ts +4 -0
  127. package/src/hooks/use-breakpoint.ts +61 -10
  128. package/src/index.ts +30 -0
  129. package/src/primitives/chart-accessibility.ts +102 -0
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+
3
+ import { forwardRef, useEffect } from 'react';
4
+ import { View } from 'react-native';
5
+ import Animated, { useAnimatedStyle, useReducedMotion, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
6
+ import { tv } from 'tailwind-variants';
7
+ import { Text } from "../../primitives/text.js";
8
+ import { clamp, colorFor, fractionOf, formatValue, litSegments } from "./meter-scale.js";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ const SPRING = {
11
+ damping: 20,
12
+ stiffness: 180,
13
+ mass: 0.6
14
+ };
15
+ /** Milliseconds for a segment to light or go out. */
16
+ const SEGMENT_DURATION = 180;
17
+ /** How faint an unlit segment sits. Present, but plainly not counted. */
18
+ const SEGMENT_UNLIT = 0.22;
19
+ const meterVariants = tv({
20
+ slots: {
21
+ root: 'w-full gap-2',
22
+ header: 'flex-row items-center justify-between gap-2',
23
+ track: 'w-full overflow-hidden rounded-full',
24
+ indicator: 'h-full rounded-full',
25
+ segments: 'w-full flex-row',
26
+ segment: 'flex-1 rounded-full'
27
+ },
28
+ variants: {
29
+ color: {
30
+ primary: {
31
+ track: 'bg-primary/16',
32
+ indicator: 'bg-primary',
33
+ segment: 'bg-primary'
34
+ },
35
+ success: {
36
+ track: 'bg-success/16',
37
+ indicator: 'bg-success',
38
+ segment: 'bg-success'
39
+ },
40
+ warning: {
41
+ track: 'bg-warning/16',
42
+ indicator: 'bg-warning',
43
+ segment: 'bg-warning'
44
+ },
45
+ destructive: {
46
+ track: 'bg-destructive/16',
47
+ indicator: 'bg-destructive',
48
+ segment: 'bg-destructive'
49
+ },
50
+ info: {
51
+ track: 'bg-info/16',
52
+ indicator: 'bg-info',
53
+ segment: 'bg-info'
54
+ },
55
+ muted: {
56
+ track: 'bg-muted',
57
+ indicator: 'bg-muted-foreground',
58
+ segment: 'bg-muted-foreground'
59
+ }
60
+ },
61
+ size: {
62
+ sm: {
63
+ track: 'h-1.5',
64
+ segments: 'h-1.5 gap-1',
65
+ segment: 'h-1.5'
66
+ },
67
+ md: {
68
+ track: 'h-2',
69
+ segments: 'h-2 gap-1.5',
70
+ segment: 'h-2'
71
+ },
72
+ lg: {
73
+ track: 'h-3',
74
+ segments: 'h-3 gap-1.5',
75
+ segment: 'h-3'
76
+ }
77
+ }
78
+ },
79
+ defaultVariants: {
80
+ color: 'primary',
81
+ size: 'md'
82
+ }
83
+ });
84
+ /**
85
+ * One block of a segmented meter. It reads the lit count rather than a boolean
86
+ * so the whole row animates from one shared value, without a render per block.
87
+ */
88
+ function Segment({
89
+ index,
90
+ lit,
91
+ className,
92
+ reducedMotion
93
+ }) {
94
+ const style = useAnimatedStyle(() => {
95
+ const on = lit.value > index ? 1 : SEGMENT_UNLIT;
96
+ return {
97
+ opacity: reducedMotion ? on : withTiming(on, {
98
+ duration: SEGMENT_DURATION
99
+ })
100
+ };
101
+ });
102
+ return /*#__PURE__*/_jsx(Animated.View, {
103
+ style: style,
104
+ className: className
105
+ });
106
+ }
107
+
108
+ /**
109
+ * A measurement on a fixed scale: disk used, battery left, a score, a password's
110
+ * strength. The fill is driven on the UI thread, so a value change costs one
111
+ * render and nothing per frame.
112
+ *
113
+ * A meter is not a progress bar. Progress is a task moving towards an end that
114
+ * finishing is the point of; a meter is a reading that happens to sit where it
115
+ * sits, and may go back down. Reach for
116
+ * [Progress](/docs/components/progress) when something is completing.
117
+ *
118
+ * `thresholds` paint the bar by where the reading falls, and `segments` draws
119
+ * the scale as discrete blocks for readings that are counted rather than
120
+ * measured.
121
+ *
122
+ * The value is read against `minValue` / `maxValue`, which default to 0 and
123
+ * 100 — so a percentage needs neither. Set them and the meter speaks in
124
+ * whatever is being measured: bytes, degrees, points. Nothing has to be
125
+ * converted to a percent on the way in, and the screen reader is told the real
126
+ * scale rather than a derived one.
127
+ *
128
+ * React Native has no meter role, so this announces as a progress bar with its
129
+ * value, range and unit attached. That is the closest the platform offers, and
130
+ * it is why `label` matters: the role will not distinguish a reading from a
131
+ * task, and the name is what does.
132
+ */
133
+ export const Meter = /*#__PURE__*/forwardRef(({
134
+ className,
135
+ indicatorClassName,
136
+ headerClassName,
137
+ value,
138
+ minValue = 0,
139
+ maxValue = 100,
140
+ label,
141
+ showValueLabel = false,
142
+ valueLabel,
143
+ formatOptions,
144
+ thresholds,
145
+ segments,
146
+ color,
147
+ size,
148
+ accessibilityLabel,
149
+ ...props
150
+ }, ref) => {
151
+ const held = clamp(value, minValue, maxValue);
152
+ const fraction = fractionOf(value, minValue, maxValue);
153
+ const resolvedColor = colorFor(held, color ?? 'primary', thresholds);
154
+ const slots = meterVariants({
155
+ color: resolvedColor,
156
+ size
157
+ });
158
+ const reducedMotion = useReducedMotion();
159
+ const trackWidth = useSharedValue(0);
160
+ const progress = useSharedValue(fraction);
161
+ // Any reading above the floor lights a block, so "a little" never looks
162
+ // like "none". Rounding down would leave the first quarter of a
163
+ // four-block meter dark, which is the reading it is least able to afford.
164
+ const litCount = segments ? litSegments(fraction, segments) : 0;
165
+ const lit = useSharedValue(litCount);
166
+
167
+ // Reduce motion lands on the value instead of springing to it — the
168
+ // number is the information, and the overshoot is decoration.
169
+ useEffect(() => {
170
+ progress.value = reducedMotion ? fraction : withSpring(fraction, SPRING);
171
+ }, [fraction, progress, reducedMotion]);
172
+ useEffect(() => {
173
+ lit.value = litCount;
174
+ }, [lit, litCount]);
175
+ const onLayout = event => {
176
+ trackWidth.value = event.nativeEvent.layout.width;
177
+ };
178
+ const fillStyle = useAnimatedStyle(() => ({
179
+ width: trackWidth.value * progress.value
180
+ }));
181
+ const spoken = formatValue(held, fraction, valueLabel, formatOptions);
182
+ const showValue = showValueLabel;
183
+ const hasHeader = label != null || showValue;
184
+ const accessibility = {
185
+ accessibilityRole: 'progressbar',
186
+ accessibilityLabel: accessibilityLabel ?? label,
187
+ accessibilityValue: {
188
+ min: minValue,
189
+ max: maxValue,
190
+ now: held,
191
+ // Without this the scale is read as a bare number. `text` is what
192
+ // carries the unit — the percent sign, the gigabytes, the word.
193
+ text: spoken
194
+ }
195
+ };
196
+ const bar = segments && segments > 0 ? /*#__PURE__*/_jsx(View, {
197
+ ref: ref,
198
+ ...accessibility,
199
+ className: slots.segments({
200
+ className
201
+ }),
202
+ ...props,
203
+ children: Array.from({
204
+ length: segments
205
+ }, (_, index) => /*#__PURE__*/_jsx(Segment, {
206
+ index: index,
207
+ lit: lit,
208
+ reducedMotion: reducedMotion,
209
+ className: slots.segment({
210
+ className: indicatorClassName
211
+ })
212
+ }, index))
213
+ }) : /*#__PURE__*/_jsx(View, {
214
+ ref: ref,
215
+ ...accessibility,
216
+ className: slots.track({
217
+ className
218
+ }),
219
+ onLayout: onLayout,
220
+ ...props,
221
+ children: /*#__PURE__*/_jsx(Animated.View, {
222
+ style: fillStyle,
223
+ className: slots.indicator({
224
+ className: indicatorClassName
225
+ })
226
+ })
227
+ });
228
+ if (!hasHeader) return bar;
229
+ return /*#__PURE__*/_jsxs(View, {
230
+ className: slots.root(),
231
+ children: [/*#__PURE__*/_jsxs(View, {
232
+ className: slots.header({
233
+ className: headerClassName
234
+ }),
235
+ children: [label != null ? /*#__PURE__*/_jsx(Text, {
236
+ size: "sm",
237
+ weight: "medium",
238
+ numberOfLines: 1,
239
+ children: label
240
+ }) : /*#__PURE__*/_jsx(View, {}), showValue ? /*#__PURE__*/_jsx(Text, {
241
+ size: "sm",
242
+ muted: true,
243
+ numberOfLines: 1,
244
+ children: spoken
245
+ }) : null]
246
+ }), bar]
247
+ });
248
+ });
249
+ Meter.displayName = 'Meter';
250
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useEffect","View","Animated","useAnimatedStyle","useReducedMotion","useSharedValue","withSpring","withTiming","tv","Text","clamp","colorFor","fractionOf","formatValue","litSegments","jsx","_jsx","jsxs","_jsxs","SPRING","damping","stiffness","mass","SEGMENT_DURATION","SEGMENT_UNLIT","meterVariants","slots","root","header","track","indicator","segments","segment","variants","color","primary","success","warning","destructive","info","muted","size","sm","md","lg","defaultVariants","Segment","index","lit","className","reducedMotion","style","on","value","opacity","duration","Meter","indicatorClassName","headerClassName","minValue","maxValue","label","showValueLabel","valueLabel","formatOptions","thresholds","accessibilityLabel","props","ref","held","fraction","resolvedColor","trackWidth","progress","litCount","onLayout","event","nativeEvent","layout","width","fillStyle","spoken","showValue","hasHeader","accessibility","accessibilityRole","accessibilityValue","min","max","now","text","bar","children","Array","from","length","_","weight","numberOfLines","displayName"],"sourceRoot":"../../../../src","sources":["components/meter/index.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,SAAS,QAAQ,OAAO;AAC7C,SAASC,IAAI,QAAgD,cAAc;AAC3E,OAAOC,QAAQ,IACbC,gBAAgB,EAChBC,gBAAgB,EAChBC,cAAc,EACdC,UAAU,EACVC,UAAU,QAEL,yBAAyB;AAChC,SAASC,EAAE,QAA2B,mBAAmB;AACzD,SAASC,IAAI,QAAQ,0BAAuB;AAC5C,SACEC,KAAK,EACLC,QAAQ,EACRC,UAAU,EACVC,WAAW,EACXC,WAAW,QAGN,kBAAe;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAEvB,MAAMC,MAAM,GAAG;EAAEC,OAAO,EAAE,EAAE;EAAEC,SAAS,EAAE,GAAG;EAAEC,IAAI,EAAE;AAAI,CAAU;AAClE;AACA,MAAMC,gBAAgB,GAAG,GAAG;AAC5B;AACA,MAAMC,aAAa,GAAG,IAAI;AAE1B,MAAMC,aAAa,GAAGjB,EAAE,CAAC;EACvBkB,KAAK,EAAE;IACLC,IAAI,EAAE,cAAc;IACpBC,MAAM,EAAE,6CAA6C;IACrDC,KAAK,EAAE,qCAAqC;IAC5CC,SAAS,EAAE,qBAAqB;IAChCC,QAAQ,EAAE,iBAAiB;IAC3BC,OAAO,EAAE;EACX,CAAC;EACDC,QAAQ,EAAE;IACRC,KAAK,EAAE;MACLC,OAAO,EAAE;QAAEN,KAAK,EAAE,eAAe;QAAEC,SAAS,EAAE,YAAY;QAAEE,OAAO,EAAE;MAAa,CAAC;MACnFI,OAAO,EAAE;QAAEP,KAAK,EAAE,eAAe;QAAEC,SAAS,EAAE,YAAY;QAAEE,OAAO,EAAE;MAAa,CAAC;MACnFK,OAAO,EAAE;QAAER,KAAK,EAAE,eAAe;QAAEC,SAAS,EAAE,YAAY;QAAEE,OAAO,EAAE;MAAa,CAAC;MACnFM,WAAW,EAAE;QACXT,KAAK,EAAE,mBAAmB;QAC1BC,SAAS,EAAE,gBAAgB;QAC3BE,OAAO,EAAE;MACX,CAAC;MACDO,IAAI,EAAE;QAAEV,KAAK,EAAE,YAAY;QAAEC,SAAS,EAAE,SAAS;QAAEE,OAAO,EAAE;MAAU,CAAC;MACvEQ,KAAK,EAAE;QACLX,KAAK,EAAE,UAAU;QACjBC,SAAS,EAAE,qBAAqB;QAChCE,OAAO,EAAE;MACX;IACF,CAAC;IACDS,IAAI,EAAE;MACJC,EAAE,EAAE;QAAEb,KAAK,EAAE,OAAO;QAAEE,QAAQ,EAAE,aAAa;QAAEC,OAAO,EAAE;MAAQ,CAAC;MACjEW,EAAE,EAAE;QAAEd,KAAK,EAAE,KAAK;QAAEE,QAAQ,EAAE,aAAa;QAAEC,OAAO,EAAE;MAAM,CAAC;MAC7DY,EAAE,EAAE;QAAEf,KAAK,EAAE,KAAK;QAAEE,QAAQ,EAAE,aAAa;QAAEC,OAAO,EAAE;MAAM;IAC9D;EACF,CAAC;EACDa,eAAe,EAAE;IACfX,KAAK,EAAE,SAAS;IAChBO,IAAI,EAAE;EACR;AACF,CAAC,CAAC;AAiFF;AACA;AACA;AACA;AACA,SAASK,OAAOA,CAAC;EAAEC,KAAK;EAAEC,GAAG;EAAEC,SAAS;EAAEC;AAA4B,CAAC,EAAE;EACvE,MAAMC,KAAK,GAAGhD,gBAAgB,CAAC,MAAM;IACnC,MAAMiD,EAAE,GAAGJ,GAAG,CAACK,KAAK,GAAGN,KAAK,GAAG,CAAC,GAAGvB,aAAa;IAChD,OAAO;MACL8B,OAAO,EAAEJ,aAAa,GAClBE,EAAE,GACF7C,UAAU,CAAC6C,EAAE,EAAE;QAAEG,QAAQ,EAAEhC;MAAiB,CAAC;IACnD,CAAC;EACH,CAAC,CAAC;EAEF,oBAAOP,IAAA,CAACd,QAAQ,CAACD,IAAI;IAACkD,KAAK,EAAEA,KAAM;IAACF,SAAS,EAAEA;EAAU,CAAE,CAAC;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMO,KAAK,gBAAGzD,UAAU,CAC7B,CACE;EACEkD,SAAS;EACTQ,kBAAkB;EAClBC,eAAe;EACfL,KAAK;EACLM,QAAQ,GAAG,CAAC;EACZC,QAAQ,GAAG,GAAG;EACdC,KAAK;EACLC,cAAc,GAAG,KAAK;EACtBC,UAAU;EACVC,aAAa;EACbC,UAAU;EACVlC,QAAQ;EACRG,KAAK;EACLO,IAAI;EACJyB,kBAAkB;EAClB,GAAGC;AACL,CAAC,EACDC,GAAG,KACA;EACH,MAAMC,IAAI,GAAG3D,KAAK,CAAC2C,KAAK,EAAEM,QAAQ,EAAEC,QAAQ,CAAC;EAC7C,MAAMU,QAAQ,GAAG1D,UAAU,CAACyC,KAAK,EAAEM,QAAQ,EAAEC,QAAQ,CAAC;EACtD,MAAMW,aAAa,GAAG5D,QAAQ,CAAC0D,IAAI,EAAEnC,KAAK,IAAI,SAAS,EAAE+B,UAAU,CAAC;EACpE,MAAMvC,KAAK,GAAGD,aAAa,CAAC;IAAES,KAAK,EAAEqC,aAAa;IAAE9B;EAAK,CAAC,CAAC;EAC3D,MAAMS,aAAa,GAAG9C,gBAAgB,CAAC,CAAC;EAExC,MAAMoE,UAAU,GAAGnE,cAAc,CAAC,CAAC,CAAC;EACpC,MAAMoE,QAAQ,GAAGpE,cAAc,CAACiE,QAAQ,CAAC;EACzC;EACA;EACA;EACA,MAAMI,QAAQ,GAAG3C,QAAQ,GAAGjB,WAAW,CAACwD,QAAQ,EAAEvC,QAAQ,CAAC,GAAG,CAAC;EAC/D,MAAMiB,GAAG,GAAG3C,cAAc,CAACqE,QAAQ,CAAC;;EAEpC;EACA;EACA1E,SAAS,CAAC,MAAM;IACdyE,QAAQ,CAACpB,KAAK,GAAGH,aAAa,GAAGoB,QAAQ,GAAGhE,UAAU,CAACgE,QAAQ,EAAEnD,MAAM,CAAC;EAC1E,CAAC,EAAE,CAACmD,QAAQ,EAAEG,QAAQ,EAAEvB,aAAa,CAAC,CAAC;EAEvClD,SAAS,CAAC,MAAM;IACdgD,GAAG,CAACK,KAAK,GAAGqB,QAAQ;EACtB,CAAC,EAAE,CAAC1B,GAAG,EAAE0B,QAAQ,CAAC,CAAC;EAEnB,MAAMC,QAAQ,GAAIC,KAAwB,IAAK;IAC7CJ,UAAU,CAACnB,KAAK,GAAGuB,KAAK,CAACC,WAAW,CAACC,MAAM,CAACC,KAAK;EACnD,CAAC;EAED,MAAMC,SAAS,GAAG7E,gBAAgB,CAAC,OAAO;IACxC4E,KAAK,EAAEP,UAAU,CAACnB,KAAK,GAAGoB,QAAQ,CAACpB;EACrC,CAAC,CAAC,CAAC;EAEH,MAAM4B,MAAM,GAAGpE,WAAW,CAACwD,IAAI,EAAEC,QAAQ,EAAEP,UAAU,EAAEC,aAAa,CAAC;EACrE,MAAMkB,SAAS,GAAGpB,cAAc;EAChC,MAAMqB,SAAS,GAAGtB,KAAK,IAAI,IAAI,IAAIqB,SAAS;EAE5C,MAAME,aAAa,GAAG;IACpBC,iBAAiB,EAAE,aAAsB;IACzCnB,kBAAkB,EAAEA,kBAAkB,IAAIL,KAAK;IAC/CyB,kBAAkB,EAAE;MAClBC,GAAG,EAAE5B,QAAQ;MACb6B,GAAG,EAAE5B,QAAQ;MACb6B,GAAG,EAAEpB,IAAI;MACT;MACA;MACAqB,IAAI,EAAET;IACR;EACF,CAAC;EAED,MAAMU,GAAG,GACP5D,QAAQ,IAAIA,QAAQ,GAAG,CAAC,gBACtBf,IAAA,CAACf,IAAI;IACHmE,GAAG,EAAEA,GAAI;IAAA,GACLgB,aAAa;IACjBnC,SAAS,EAAEvB,KAAK,CAACK,QAAQ,CAAC;MAAEkB;IAAU,CAAC,CAAE;IAAA,GACrCkB,KAAK;IAAAyB,QAAA,EAERC,KAAK,CAACC,IAAI,CAAC;MAAEC,MAAM,EAAEhE;IAAS,CAAC,EAAE,CAACiE,CAAC,EAAEjD,KAAK,kBACzC/B,IAAA,CAAC8B,OAAO;MAENC,KAAK,EAAEA,KAAM;MACbC,GAAG,EAAEA,GAAI;MACTE,aAAa,EAAEA,aAAc;MAC7BD,SAAS,EAAEvB,KAAK,CAACM,OAAO,CAAC;QAAEiB,SAAS,EAAEQ;MAAmB,CAAC;IAAE,GAJvDV,KAKN,CACF;EAAC,CACE,CAAC,gBAEP/B,IAAA,CAACf,IAAI;IACHmE,GAAG,EAAEA,GAAI;IAAA,GACLgB,aAAa;IACjBnC,SAAS,EAAEvB,KAAK,CAACG,KAAK,CAAC;MAAEoB;IAAU,CAAC,CAAE;IACtC0B,QAAQ,EAAEA,QAAS;IAAA,GACfR,KAAK;IAAAyB,QAAA,eAET5E,IAAA,CAACd,QAAQ,CAACD,IAAI;MACZkD,KAAK,EAAE6B,SAAU;MACjB/B,SAAS,EAAEvB,KAAK,CAACI,SAAS,CAAC;QAAEmB,SAAS,EAAEQ;MAAmB,CAAC;IAAE,CAC/D;EAAC,CACE,CACP;EAEH,IAAI,CAAC0B,SAAS,EAAE,OAAOQ,GAAG;EAE1B,oBACEzE,KAAA,CAACjB,IAAI;IAACgD,SAAS,EAAEvB,KAAK,CAACC,IAAI,CAAC,CAAE;IAAAiE,QAAA,gBAC5B1E,KAAA,CAACjB,IAAI;MAACgD,SAAS,EAAEvB,KAAK,CAACE,MAAM,CAAC;QAAEqB,SAAS,EAAES;MAAgB,CAAC,CAAE;MAAAkC,QAAA,GAC3D/B,KAAK,IAAI,IAAI,gBACZ7C,IAAA,CAACP,IAAI;QAACgC,IAAI,EAAC,IAAI;QAACwD,MAAM,EAAC,QAAQ;QAACC,aAAa,EAAE,CAAE;QAAAN,QAAA,EAC9C/B;MAAK,CACF,CAAC,gBAEP7C,IAAA,CAACf,IAAI,IAAE,CACR,EACAiF,SAAS,gBACRlE,IAAA,CAACP,IAAI;QAACgC,IAAI,EAAC,IAAI;QAACD,KAAK;QAAC0D,aAAa,EAAE,CAAE;QAAAN,QAAA,EACpCX;MAAM,CACH,CAAC,GACL,IAAI;IAAA,CACJ,CAAC,EACNU,GAAG;EAAA,CACA,CAAC;AAEX,CACF,CAAC;AAEDnC,KAAK,CAAC2C,WAAW,GAAG,OAAO","ignoreList":[]}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Where a reading sits on a meter's scale, and what colour it has earned.
5
+ *
6
+ * Kept apart from the component because it is the part that can be wrong
7
+ * without looking wrong: a threshold picked in the wrong order, or a segment
8
+ * count that rounds a real reading down to nothing, is a meter that lies
9
+ * quietly. None of it touches React, so it can be tested on its own.
10
+ */
11
+
12
+ /** The token a meter can be painted with. */
13
+
14
+ /**
15
+ * A point on the scale, and the colour the meter takes from there upwards.
16
+ *
17
+ * `from` is in the same units as `value` — not a percentage of the range — so
18
+ * a threshold on a 0–8 GB meter is written in gigabytes.
19
+ */
20
+
21
+ /** `value` held inside the scale, so a stray number cannot escape the track. */
22
+ export function clamp(value, min, max) {
23
+ if (!(value > min)) return min;
24
+ if (value > max) return max;
25
+ return value;
26
+ }
27
+
28
+ /**
29
+ * How far up the scale the value sits, 0–1. An empty or inverted range has no
30
+ * meaningful position in it, so it reads as empty rather than dividing by zero.
31
+ */
32
+ export function fractionOf(value, min, max) {
33
+ const span = max - min;
34
+ if (!(span > 0)) return 0;
35
+ return clamp((value - min) / span, 0, 1);
36
+ }
37
+
38
+ /**
39
+ * The colour the reading has earned: the highest threshold at or below the
40
+ * value, or the base colour when it has reached none of them.
41
+ *
42
+ * Highest-wins rather than first-wins, so the caller can list thresholds in
43
+ * any order and get the same answer. A rule that depended on the order would
44
+ * make a reordered array a silent behaviour change.
45
+ */
46
+ export function colorFor(value, base, thresholds) {
47
+ if (!thresholds?.length) return base;
48
+ let winner;
49
+ for (const threshold of thresholds) {
50
+ if (value < threshold.from) continue;
51
+ if (!winner || threshold.from > winner.from) winner = threshold;
52
+ }
53
+ return winner?.color ?? base;
54
+ }
55
+
56
+ /**
57
+ * How many blocks of a segmented meter are lit.
58
+ *
59
+ * Rounded up, so any reading above the floor lights at least one. Rounding
60
+ * down would leave the whole first block of a four-block meter dark, and "a
61
+ * little" looking like "none" is the reading a meter can least afford to get
62
+ * wrong.
63
+ */
64
+ export function litSegments(fraction, segments) {
65
+ if (!(segments > 0)) return 0;
66
+ return Math.min(Math.ceil(fraction * segments), segments);
67
+ }
68
+
69
+ /**
70
+ * The value caption: an explicit override, an `Intl` rendering, or a rounded
71
+ * percent.
72
+ *
73
+ * A `percent` style is given the fraction, because that is what a percentage
74
+ * of the scale means; every other style is given the value, because a byte
75
+ * count or a score is a quantity and not a proportion.
76
+ */
77
+ export function formatValue(value, fraction, valueLabel, formatOptions) {
78
+ if (valueLabel != null) return valueLabel;
79
+ if (formatOptions) {
80
+ try {
81
+ return new Intl.NumberFormat(undefined, formatOptions).format(formatOptions.style === 'percent' ? fraction : value);
82
+ } catch {
83
+ // Some engines ship a partial Intl; fall through to the plain percent.
84
+ }
85
+ }
86
+ return `${Math.round(fraction * 100)}%`;
87
+ }
88
+ //# sourceMappingURL=meter-scale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["clamp","value","min","max","fractionOf","span","colorFor","base","thresholds","length","winner","threshold","from","color","litSegments","fraction","segments","Math","ceil","formatValue","valueLabel","formatOptions","Intl","NumberFormat","undefined","format","style","round"],"sourceRoot":"../../../../src","sources":["components/meter/meter-scale.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AASA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA,OAAO,SAASA,KAAKA,CAACC,KAAa,EAAEC,GAAW,EAAEC,GAAW,EAAE;EAC7D,IAAI,EAAEF,KAAK,GAAGC,GAAG,CAAC,EAAE,OAAOA,GAAG;EAC9B,IAAID,KAAK,GAAGE,GAAG,EAAE,OAAOA,GAAG;EAC3B,OAAOF,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASG,UAAUA,CAACH,KAAa,EAAEC,GAAW,EAAEC,GAAW,EAAE;EAClE,MAAME,IAAI,GAAGF,GAAG,GAAGD,GAAG;EACtB,IAAI,EAAEG,IAAI,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;EACzB,OAAOL,KAAK,CAAC,CAACC,KAAK,GAAGC,GAAG,IAAIG,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,QAAQA,CACtBL,KAAa,EACbM,IAA4B,EAC5BC,UAAwC,EACxC;EACA,IAAI,CAACA,UAAU,EAAEC,MAAM,EAAE,OAAOF,IAAI;EACpC,IAAIG,MAAkC;EACtC,KAAK,MAAMC,SAAS,IAAIH,UAAU,EAAE;IAClC,IAAIP,KAAK,GAAGU,SAAS,CAACC,IAAI,EAAE;IAC5B,IAAI,CAACF,MAAM,IAAIC,SAAS,CAACC,IAAI,GAAGF,MAAM,CAACE,IAAI,EAAEF,MAAM,GAAGC,SAAS;EACjE;EACA,OAAOD,MAAM,EAAEG,KAAK,IAAIN,IAAI;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,WAAWA,CAACC,QAAgB,EAAEC,QAAgB,EAAE;EAC9D,IAAI,EAAEA,QAAQ,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;EAC7B,OAAOC,IAAI,CAACf,GAAG,CAACe,IAAI,CAACC,IAAI,CAACH,QAAQ,GAAGC,QAAQ,CAAC,EAAEA,QAAQ,CAAC;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,WAAWA,CACzBlB,KAAa,EACbc,QAAgB,EAChBK,UAAmB,EACnBC,aAAwC,EACxC;EACA,IAAID,UAAU,IAAI,IAAI,EAAE,OAAOA,UAAU;EACzC,IAAIC,aAAa,EAAE;IACjB,IAAI;MACF,OAAO,IAAIC,IAAI,CAACC,YAAY,CAACC,SAAS,EAAEH,aAAa,CAAC,CAACI,MAAM,CAC3DJ,aAAa,CAACK,KAAK,KAAK,SAAS,GAAGX,QAAQ,GAAGd,KACjD,CAAC;IACH,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;EACA,OAAO,GAAGgB,IAAI,CAACU,KAAK,CAACZ,QAAQ,GAAG,GAAG,CAAC,GAAG;AACzC","ignoreList":[]}