@lotics/ui 21.2.0 → 21.3.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/docs/catalog.md CHANGED
@@ -159,7 +159,9 @@ plain sm tabular count beside it — the cell/heading/peek-trigger meter; a capt
159
159
  above a tiny bar reads misaligned. **The track clamps at 100%, the caption does not** — over
160
160
  its max it reads `2,100 / 2,000 · 105%`, because a meter that says "100%" when you are over
161
161
  tells the reader they are exactly at the limit. Numbers format in the reader's locale, so
162
- never hand-format the value you pass in) / `StackedProgressBar` / `StepProgress`, `Breakdown` (a
162
+ never hand-format the value you pass in when display precision differs from the true value
163
+ (whole credits off a fractional balance), `formatValue` reshapes the caption text and leaves
164
+ the fill and the percentage exact) / `StackedProgressBar` / `StepProgress`, `Breakdown` (a
163
165
  stacked bar + ranked share rows, pressable to drill; `maxRows` folds the long tail behind a
164
166
  "Show N more" toggle — `labels` to localize — so several facet cards align to one height in
165
167
  a row), `Funnel` (a CONVERSION funnel — ordered stages as bars that NARROW; the step
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/ui",
3
- "version": "21.2.0",
3
+ "version": "21.3.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./vite": {
package/src/locale.tsx CHANGED
@@ -289,8 +289,11 @@ export const en: LoticsLocale = {
289
289
  downloadAll: "Download all",
290
290
  downloadSelected: (n: number) => `Download (${n})`,
291
291
  delete: "Delete",
292
- removeTitle: "Remove attachment?",
293
- removeMessage: "This removes the file.",
292
+ // `FilesEditorRemove` removes the whole SELECTION, so the confirm is phrased for a set —
293
+ // singular copy under-reports what the button is about to do. And the kit does not know what
294
+ // the files hang off, so it says what it can see: the files, and that they are selected.
295
+ removeTitle: "Remove files?",
296
+ removeMessage: "The selected files will be removed.",
294
297
  removeCancel: "Cancel",
295
298
  removeConfirm: "Remove",
296
299
  },
@@ -438,7 +441,7 @@ export const vi: LoticsLocale = {
438
441
  downloadSelected: (n: number) => `Tải ${n} tệp`,
439
442
  delete: "Xóa",
440
443
  removeTitle: "Xóa tệp?",
441
- removeMessage: "Tệp sẽ bị gỡ khỏi bản ghi.",
444
+ removeMessage: "Các tệp đã chọn sẽ bị xóa.",
442
445
  removeCancel: "Hủy",
443
446
  removeConfirm: "Xóa",
444
447
  },
@@ -16,6 +16,16 @@ export interface ProgressBarProps {
16
16
  * "1,250 / 2,500 · 50%" (separators follow the reader's locale). Reports the
17
17
  * TRUE ratio — over `max` it reads "105%" while the track stays clamped. */
18
18
  format?: ProgressBarFormat;
19
+ /**
20
+ * How `value` and `max` render inside the caption. Defaults to the reader's locale grouping.
21
+ *
22
+ * The escape hatch for a quantity whose natural precision is not its DISPLAY precision — a
23
+ * fractional credit balance metered to whole credits, a byte count shown as GB. Still the bar's
24
+ * job rather than the caller's: pass the true `value`/`max` so the track and the percentage stay
25
+ * exact, and let this reshape only the text. Pre-rounding the numbers you pass in moves the fill
26
+ * and the percentage too, which is how a 99.6%-full meter starts claiming it is exactly full.
27
+ */
28
+ formatValue?: (n: number) => string;
19
29
  color?: string;
20
30
  completeColor?: string;
21
31
  /** COMPACT: one row — the track (flex) with a plain sm tabular count beside
@@ -37,6 +47,7 @@ export function ProgressBar(props: ProgressBarProps) {
37
47
  max,
38
48
  title,
39
49
  format = "percentage",
50
+ formatValue,
40
51
  color = colors.blue["500"],
41
52
  completeColor = colors.green["500"],
42
53
  compact = false,
@@ -55,10 +66,11 @@ export function ProgressBar(props: ProgressBarProps) {
55
66
  const ratio = max > 0 ? Math.max(0, (value / max) * 100) : 0;
56
67
  const percentage = Math.min(100, ratio);
57
68
  const isComplete = ratio >= 100;
69
+ const num = formatValue ?? ((n: number) => n.toLocaleString(localeTag));
58
70
 
59
71
  if (compact) {
60
72
  const label =
61
- format === "percentage" ? `${Math.round(ratio)}%` : `${value.toLocaleString(localeTag)}/${max.toLocaleString(localeTag)}`;
73
+ format === "percentage" ? `${Math.round(ratio)}%` : `${num(value)}/${num(max)}`;
62
74
  return (
63
75
  <View style={styles.compactRow}>
64
76
  <View style={[styles.track, styles.compactTrack]}>
@@ -75,7 +87,7 @@ export function ProgressBar(props: ProgressBarProps) {
75
87
 
76
88
  const caption =
77
89
  format === "fraction"
78
- ? `${value.toLocaleString(localeTag)} / ${max.toLocaleString(localeTag)} · ${Math.round(ratio)}%`
90
+ ? `${num(value)} / ${num(max)} · ${Math.round(ratio)}%`
79
91
  : format === "percentage"
80
92
  ? `${Math.round(ratio)}%`
81
93
  : null;