@danxbot/ui 20.23.2 → 21.0.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 (105) hide show
  1. package/dist/index.js +23595 -22537
  2. package/dist/index.js.map +1 -1
  3. package/dist/pure.js +290 -210
  4. package/dist/pure.js.map +1 -1
  5. package/dist/types/components/AppShell.d.ts +1 -1
  6. package/dist/types/components/Board.d.ts +4 -6
  7. package/dist/types/components/Combobox.d.ts +2 -1
  8. package/dist/types/components/CommandPalette.d.ts +2 -0
  9. package/dist/types/components/DateField.d.ts +2 -2
  10. package/dist/types/components/DragDrop.d.ts +2 -4
  11. package/dist/types/components/InlineEdit.d.ts +4 -4
  12. package/dist/types/components/InlineMarkdownEdit.d.ts +2 -2
  13. package/dist/types/components/PagedWindowList.d.ts +1 -9
  14. package/dist/types/components/Progress.d.ts +4 -4
  15. package/dist/types/components/ReadMore.d.ts +2 -2
  16. package/dist/types/components/SecretField.d.ts +1 -1
  17. package/dist/types/components/Slider.d.ts +1 -1
  18. package/dist/types/components/SortMenu.d.ts +1 -1
  19. package/dist/types/components/Stat.d.ts +1 -1
  20. package/dist/types/components/StatusSelect.d.ts +1 -1
  21. package/dist/types/components/TriStateSwitch.d.ts +1 -7
  22. package/dist/types/components/board/context.d.ts +2 -4
  23. package/dist/types/components/calendar/CalendarMonth.d.ts +2 -3
  24. package/dist/types/components/calendar/CalendarTimeGrid.d.ts +1 -2
  25. package/dist/types/components/calendar/EventActions.d.ts +1 -2
  26. package/dist/types/components/calendar/format.d.ts +10 -9
  27. package/dist/types/components/calendar/use-calendar-drag.d.ts +0 -1
  28. package/dist/types/components/calendar/use-event-keyboard.d.ts +0 -1
  29. package/dist/types/components/chart/BarList.d.ts +1 -1
  30. package/dist/types/components/chart/ShareBar.d.ts +1 -1
  31. package/dist/types/components/chart/TimeSeriesChart.d.ts +2 -4
  32. package/dist/types/components/chart/shared.d.ts +2 -2
  33. package/dist/types/components/chart/time-series-scale.d.ts +1 -1
  34. package/dist/types/components/chat/EffortControl.d.ts +2 -2
  35. package/dist/types/components/chat/MessageScroller.d.ts +1 -1
  36. package/dist/types/components/checklist/StatusChecklist.d.ts +1 -1
  37. package/dist/types/components/edit/outcome.d.ts +0 -12
  38. package/dist/types/components/file-viewer/frames.d.ts +2 -1
  39. package/dist/types/components/kanban/KanbanBoard.d.ts +2 -21
  40. package/dist/types/components/kanban/types.d.ts +1 -1
  41. package/dist/types/components/markdown/Affordances.d.ts +3 -1
  42. package/dist/types/components/openapi/resolve.d.ts +7 -3
  43. package/dist/types/components/openapi/types.d.ts +2 -1
  44. package/dist/types/components/provenance/ConfidenceBar.d.ts +1 -1
  45. package/dist/types/components/provenance/ConfidenceReadout.d.ts +2 -2
  46. package/dist/types/components/provenance/ProvenanceBadge.d.ts +4 -3
  47. package/dist/types/components/provenance/ProvenanceDetail.d.ts +4 -6
  48. package/dist/types/components/provenance/ProvenanceDisclosure.d.ts +1 -1
  49. package/dist/types/components/provenance/absence.d.ts +4 -3
  50. package/dist/types/components/rbac/RoleKeyPicker.d.ts +1 -1
  51. package/dist/types/components/rbac/permissionSections.d.ts +1 -1
  52. package/dist/types/components/rbac/stagedForm.d.ts +4 -4
  53. package/dist/types/components/roadmap/RoadmapItemCard.d.ts +0 -1
  54. package/dist/types/index.d.ts +9 -7
  55. package/dist/types/lib/board/index.d.ts +2 -1
  56. package/dist/types/lib/board/move.d.ts +2 -2
  57. package/dist/types/lib/board/rejection.d.ts +8 -0
  58. package/dist/types/lib/board/types.d.ts +46 -0
  59. package/dist/types/lib/board/use-board.d.ts +2 -2
  60. package/dist/types/lib/calendar/drag.d.ts +1 -1
  61. package/dist/types/lib/calendar/index.d.ts +1 -1
  62. package/dist/types/lib/calendar/types.d.ts +3 -3
  63. package/dist/types/lib/confidence.d.ts +5 -0
  64. package/dist/types/lib/dnd/announce.d.ts +5 -23
  65. package/dist/types/lib/dnd/index.d.ts +1 -1
  66. package/dist/types/lib/format.d.ts +19 -18
  67. package/dist/types/lib/i18n/areas/auth-provenance-flows.d.ts +258 -0
  68. package/dist/types/lib/i18n/areas/board.d.ts +51 -0
  69. package/dist/types/lib/i18n/areas/chat-chart.d.ts +164 -0
  70. package/dist/types/lib/i18n/areas/code-editor.d.ts +40 -0
  71. package/dist/types/lib/i18n/areas/dates.d.ts +103 -0
  72. package/dist/types/lib/i18n/areas/docs-views.d.ts +268 -0
  73. package/dist/types/lib/i18n/areas/feedback.d.ts +104 -0
  74. package/dist/types/lib/i18n/areas/formats.d.ts +30 -0
  75. package/dist/types/lib/i18n/areas/forms.d.ts +130 -0
  76. package/dist/types/lib/i18n/areas/markdown.d.ts +139 -0
  77. package/dist/types/lib/i18n/areas/move-rejected.d.ts +16 -0
  78. package/dist/types/lib/i18n/areas/navigation.d.ts +144 -0
  79. package/dist/types/lib/i18n/areas/rbac.d.ts +584 -0
  80. package/dist/types/lib/i18n/emphasis.d.ts +3 -0
  81. package/dist/types/lib/i18n/index.d.ts +8 -0
  82. package/dist/types/lib/i18n/number-format.d.ts +5 -0
  83. package/dist/types/lib/i18n/plural.d.ts +7 -0
  84. package/dist/types/lib/i18n/provider.d.ts +16 -0
  85. package/dist/types/lib/i18n/strings.d.ts +15 -0
  86. package/dist/types/lib/intl-cache.d.ts +31 -0
  87. package/dist/types/lib/markdown/commands.d.ts +4 -2
  88. package/dist/types/lib/markdown/dom.d.ts +27 -21
  89. package/dist/types/lib/markdown/hotkeys.d.ts +12 -5
  90. package/dist/types/lib/markdown/image-decoration.d.ts +22 -1
  91. package/dist/types/lib/markdown/image-pipeline.d.ts +2 -0
  92. package/dist/types/lib/markdown/images.d.ts +1 -1
  93. package/dist/types/lib/markdown/reconcile.d.ts +4 -2
  94. package/dist/types/lib/markdown/surface.d.ts +4 -2
  95. package/dist/types/lib/reduced-motion-help.d.ts +2 -1
  96. package/dist/types/lib/time/relativeAge.d.ts +3 -2
  97. package/dist/types/lib/time/zone.d.ts +9 -0
  98. package/dist/types/lib/values/boolean.d.ts +11 -10
  99. package/dist/types/lib/values/currency.d.ts +5 -5
  100. package/dist/types/lib/values/date.d.ts +4 -4
  101. package/dist/types/lib/values/datetime.d.ts +3 -3
  102. package/dist/types/lib/values/locale-date.d.ts +34 -0
  103. package/dist/types/lib/values/number.d.ts +5 -5
  104. package/dist/types/pure.d.ts +1 -0
  105. package/package.json +1 -1
@@ -112,9 +112,11 @@ export declare function cellAt(source: string, table: TableSpan, offset: number)
112
112
  row: number;
113
113
  column: number;
114
114
  } | null;
115
- export declare function insertTable(columns?: number, bodyRows?: number): Command;
115
+ /** `columnHeader(n)` names the n-th (1-based) header cell; the editor passes its provider string. */
116
+ export declare function insertTable(columnHeader: (position: number) => string, columns?: number, bodyRows?: number): Command;
116
117
  export declare function insertRow(below: boolean): Command;
117
- export declare function insertColumn(after: boolean): Command;
118
+ /** `header` is the new column's header cell text. */
119
+ export declare function insertColumn(after: boolean, header: string): Command;
118
120
  export declare const deleteRow: Command;
119
121
  export declare const deleteColumn: Command;
120
122
  export declare const deleteTable: Command;
@@ -1,5 +1,5 @@
1
1
  import type { Frame } from "../syntax/markdown/frames";
2
- import { type DecorationSpec, type ImageResolver } from "./image-decoration";
2
+ import { type DecorationSpec, type ImageDecorationStrings, type ImageResolver } from "./image-decoration";
3
3
  /** Marks the wrapper around a run of markup, for the collapse rule. */
4
4
  export declare const SYNTAX_ATTR = "data-md-syntax";
5
5
  /** Names the frame an element came from, for styling and for the reconciler. */
@@ -8,25 +8,6 @@ export interface TagSpec {
8
8
  tag: string;
9
9
  /** Attributes the element carries, beyond `data-md`. */
10
10
  attrs?: Record<string, string>;
11
- /**
12
- * A rendered decoration appended after the frame's own characters.
13
- *
14
- * THE ONLY WAY TO SHOW A PICTURE WITHOUT LYING ABOUT THE TEXT. An image's
15
- * source is `![alt](src)` and every one of those characters must stay in the
16
- * DOM and stay reachable — so the picture cannot replace them. It is an extra
17
- * node that holds NO TEXT, which is exactly why it is invisible to the
18
- * projection invariant and to position mapping: both walk text nodes only.
19
- *
20
- * Marked with its own attribute so the reconciler can lift it out before
21
- * diffing children and put it back after, the same way the trailing-line
22
- * filler is handled. Without that it would occupy a child index and shift
23
- * every sibling the positional diff is counting.
24
- *
25
- * A TREE, not one element (DX-3134): an image being uploaded draws its state
26
- * on top of the picture, so the decoration is a wrapper with children. Every
27
- * node in it is still text-free — see ./image-decoration.ts.
28
- */
29
- decoration?: DecorationSpec;
30
11
  }
31
12
  /** Marks a rendered decoration, which carries no text and no source range. */
32
13
  export declare const DECORATION_ATTR = "data-md-decoration";
@@ -39,7 +20,32 @@ export declare const DECORATION_ATTR = "data-md-decoration";
39
20
  * being edited. The link's appearance is a class; its behaviour belongs to the
40
21
  * editor, which knows whether a modifier key was held.
41
22
  */
42
- export declare function tagFor(frame: Frame, images?: ImageResolver): TagSpec;
23
+ export declare function tagFor(frame: Frame): TagSpec;
24
+ /**
25
+ * The decoration a frame carries beside its children, if any: today only an image's picture and
26
+ * state overlay, appended after the frame's own characters.
27
+ *
28
+ * THE ONLY WAY TO SHOW A PICTURE WITHOUT LYING ABOUT THE TEXT. An image's source is `![alt](src)` and
29
+ * every one of those characters must stay in the DOM and stay reachable, so the picture cannot replace
30
+ * them. It is an extra node that holds NO TEXT, which is why it is invisible to the projection
31
+ * invariant and to position mapping (both walk text nodes only). Marked with `DECORATION_ATTR` so the
32
+ * reconciler lifts it out before diffing children and puts it back after. A TREE, not one element
33
+ * (DX-3134): an uploading image draws its state on top of the picture.
34
+ *
35
+ * `sanitizeImageSrc` (inside `imageDecoration`) is the renderer's rule
36
+ * and it applies here for the same reason: `javascript:` and
37
+ * `data:text/html` are working attacks against anything that passes a URL
38
+ * through untouched, and the interesting cases are the ones that do not
39
+ * look like attacks — `JaVaScRiPt:` and a tab inside the scheme both
40
+ * survive a naive prefix test and both execute.
41
+ *
42
+ * A REFUSED OR EMPTY URL RENDERS A VISIBLE BROKEN-IMAGE BOX (DX-3134),
43
+ * never nothing. The source characters are markup the caret cannot see,
44
+ * so "no picture" used to mean "no trace on screen at all" — the toolbar's
45
+ * `![]()` was exactly that. The resolver is consulted first so an object
46
+ * URL THIS editor minted renders, and every other `blob:` stays refused.
47
+ */
48
+ export declare function decorationFor(frame: Frame, images: ImageResolver | undefined, strings: ImageDecorationStrings): DecorationSpec | undefined;
43
49
  /**
44
50
  * Whether two frames describe the same element, for reuse during a patch.
45
51
  *
@@ -1,5 +1,11 @@
1
1
  import { type Command } from "./commands";
2
2
  export type HotkeyGroup = "formatting" | "headings" | "lists" | "blocks" | "tables";
3
+ /**
4
+ * What a row does, in the words of no language: the help surface looks the row's
5
+ * description up under this id in the active `UiLocaleProvider`'s strings
6
+ * (`markdownEditor.hotkeys`), so the table holds chords and commands only.
7
+ */
8
+ export type HotkeyId = "bold" | "italic" | "inlineCode" | "strikethrough" | "link" | "image" | "paragraph" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "decreaseHeading" | "increaseHeading" | "bulletList" | "numberedList" | "taskCheckbox" | "indent" | "outdent" | "codeBlock" | "blockquote" | "horizontalRule" | "table" | "rowAbove" | "rowBelow" | "columnLeft" | "columnRight" | "deleteRow" | "deleteColumn" | "deleteTable" | "alignLeft" | "alignCenter" | "alignRight";
3
9
  /**
4
10
  * Something only the editor itself can do, because it is not a function of the
5
11
  * source (DX-3134).
@@ -10,8 +16,9 @@ export type HotkeyGroup = "formatting" | "headings" | "lists" | "blocks" | "tabl
10
16
  * editor for the picker instead, and the chosen files go through the same
11
17
  * pipeline as a paste or a drop.
12
18
  */
13
- export type EditorRequest = "pickImages";
19
+ export type EditorRequest = "pickImages" | "insertTable" | "insertColumnLeft" | "insertColumnRight";
14
20
  interface HotkeyBase {
21
+ id: HotkeyId;
15
22
  /**
16
23
  * The chord this matches: lower-case, modifiers first, in the order ctrl,
17
24
  * alt, shift.
@@ -23,19 +30,19 @@ interface HotkeyBase {
23
30
  * which character the modifier produced.
24
31
  */
25
32
  key: string;
26
- /** What the help surface shows, which is the chord as a person types it. */
33
+ /** What the help surface shows, which is the chord as a person types it ("Ctrl+Shift+["), derived from `key`. */
27
34
  label: string;
28
- description: string;
29
35
  group: HotkeyGroup;
30
36
  }
31
37
  /** A chord, and EITHER the pure edit it makes OR the editor request it raises. */
32
- export type Hotkey = HotkeyBase & ({
38
+ type HotkeyAction = {
33
39
  command: Command;
34
40
  request?: never;
35
41
  } | {
36
42
  request: EditorRequest;
37
43
  command?: never;
38
- });
44
+ };
45
+ export type Hotkey = HotkeyBase & HotkeyAction;
39
46
  export declare const HOTKEYS: readonly Hotkey[];
40
47
  /**
41
48
  * The chords a key event could be, most specific first.
@@ -62,6 +62,27 @@ export type ImageDecorationState = LocalImageState | "stored" | "broken";
62
62
  /** The attribute the pipeline's click listener looks for. */
63
63
  export declare const IMAGE_ACTION_ATTR = "data-md-image-action";
64
64
  export type ImageAction = "retry" | "remove";
65
+ /** The words an image decoration carries as attributes (never as text nodes: see the file header). */
66
+ export interface ImageDecorationStrings {
67
+ /** Alt text inserted for a pasted or dropped image whose file name says nothing. */
68
+ defaultAlt: string;
69
+ /** Accessible name of the broken-image box when the image has no description. */
70
+ unavailable: string;
71
+ /** Same, naming the image by its alt text or source. */
72
+ unavailableNamed: (described: string) => string;
73
+ /** Accessible name of the overlay on an image still being stored. */
74
+ uploading: string;
75
+ /** Accessible name of the failed-upload group when the uploader gave no message. */
76
+ failed: string;
77
+ /** Same, carrying the uploader's own message. */
78
+ failedNamed: (message: string) => string;
79
+ /** Name of the retry button on a failed upload. */
80
+ retryUpload: string;
81
+ /** Name of the remove button on a failed upload. */
82
+ removeImage: string;
83
+ /** Accessible name of the badge on an image that is shown but will not be saved. */
84
+ notSaved: string;
85
+ }
65
86
  /**
66
87
  * The decoration for one image frame.
67
88
  *
@@ -70,4 +91,4 @@ export type ImageAction = "retry" | "remove";
70
91
  */
71
92
  export declare function imageDecoration(frame: Extract<Frame, {
72
93
  kind: "image";
73
- }>, local: LocalImageInfo | null): DecorationSpec;
94
+ }>, local: LocalImageInfo | null, strings: ImageDecorationStrings): DecorationSpec;
@@ -69,6 +69,8 @@ export interface ImagePipelineEnvironment {
69
69
  export interface ImagePipelineOptions {
70
70
  /** The uploader in force right now, or null when there is no storage. */
71
71
  uploader: () => ImageUploader | null;
72
+ /** The alt text of a pasted file whose name says nothing ("image.png" has none): the provider's `images.defaultAlt`. */
73
+ defaultAlt: () => string;
72
74
  /** Called whenever the snapshot changes, and once when attached. */
73
75
  onChange: (snapshot: ImagePipelineSnapshot) => void;
74
76
  environment?: Partial<ImagePipelineEnvironment>;
@@ -44,7 +44,7 @@ export declare function imageMarkdown(src: string, alt: string): string;
44
44
  * and replace, which is better than the empty alt that makes an image
45
45
  * invisible to a screen reader.
46
46
  */
47
- export declare function altFromFileName(name: string): string;
47
+ export declare function altFromFileName(name: string, fallback: string): string;
48
48
  /** The result of replacing every occurrence of one string with another. */
49
49
  export interface Substitution {
50
50
  source: string;
@@ -1,5 +1,5 @@
1
1
  import type { PNode } from "./project";
2
- import type { ImageResolver } from "./image-decoration";
2
+ import type { ImageDecorationStrings, ImageResolver } from "./image-decoration";
3
3
  /**
4
4
  * Thrown when a patch would have had to disturb the node the browser is
5
5
  * composing into.
@@ -23,6 +23,8 @@ export interface PatchOptions {
23
23
  * Absent means "none" — every `blob:` is then refused, as it always was.
24
24
  */
25
25
  images?: ImageResolver;
26
+ /** The words an image decoration carries; the editor's own strings, never a default. */
27
+ imageStrings: ImageDecorationStrings;
26
28
  }
27
29
  export interface PatchStats {
28
30
  /** Text nodes whose `data` was assigned. */
@@ -45,7 +47,7 @@ export interface PatchStats {
45
47
  * Position is stable under exactly the edits that matter — a change in the
46
48
  * middle of a paragraph leaves the paragraph at the same index.
47
49
  */
48
- export declare function patch(parent: HTMLElement, nodes: readonly PNode[], options?: PatchOptions): PatchStats;
50
+ export declare function patch(parent: HTMLElement, nodes: readonly PNode[], options: PatchOptions): PatchStats;
49
51
  /**
50
52
  * The source range a text node carries, or null if it was not built here.
51
53
  *
@@ -2,7 +2,7 @@ import { type CaretMap } from "./caret-map";
2
2
  import { type Projection, type ProjectOptions } from "./project";
3
3
  import { type SourceSelection } from "./position";
4
4
  import { type EditKind, type HistoryOptions } from "./history";
5
- import type { ImageResolver } from "./image-decoration";
5
+ import type { ImageDecorationStrings, ImageResolver } from "./image-decoration";
6
6
  export interface SurfaceOptions {
7
7
  /** Called after every committed change, with the new source. */
8
8
  onChange?: (source: string) => void;
@@ -27,6 +27,8 @@ export interface SurfaceOptions {
27
27
  * `refresh()`. Absent: no `blob:` src ever renders.
28
28
  */
29
29
  images?: ImageResolver;
30
+ /** The words an image decoration carries (the editor's `markdownEditor.images`); read on every render so a locale change needs only `refresh()`. */
31
+ imageStrings: () => ImageDecorationStrings;
30
32
  }
31
33
  export interface Splice {
32
34
  start: number;
@@ -76,7 +78,7 @@ export declare class MarkdownSurface {
76
78
  * them, and re-projecting to ask would parse the document twice per keypress.
77
79
  */
78
80
  private projection;
79
- constructor(root: HTMLElement, source: string, options?: SurfaceOptions);
81
+ constructor(root: HTMLElement, source: string, options: SurfaceOptions);
80
82
  getSource(): string;
81
83
  /** The projection the DOM currently shows, for callers that must read it. */
82
84
  getProjection(): Projection;
@@ -19,4 +19,5 @@ export interface ReducedMotionHelp {
19
19
  /** A link that opens the setting directly, where the OS has one. */
20
20
  href?: string;
21
21
  }
22
- export declare function reducedMotionHelp(platform: HostPlatform): ReducedMotionHelp;
22
+ /** `steps` is the wording per OS (the active `UiLocaleProvider`'s `themeMenu.osSteps`); this picks the one for `platform` and its settings link. */
23
+ export declare function reducedMotionHelp(platform: HostPlatform, steps: Record<HostPlatform, string>): ReducedMotionHelp;
@@ -1,5 +1,6 @@
1
+ import type { RelativeAgeStrings } from "../i18n/areas/formats";
1
2
  /**
2
- * A moment's age in words: "just now", "4m ago", "4h ago", "1d 6h ago",
3
+ * A moment's age in words (English shown; the words come from `strings`): "just now", "4m ago", "4h ago", "1d 6h ago",
3
4
  * "2w ago".
4
5
  *
5
6
  * Stays two-unit only in the day range (a message from earlier today reads
@@ -11,4 +12,4 @@
11
12
  * of "1w 2d ago", and nobody needs either instead of a calendar date, but a
12
13
  * chat message's hover row has no room for a calendar date, so weeks it is.
13
14
  */
14
- export declare function relativeAge(when: string | number | Date): string;
15
+ export declare function relativeAge(when: string | number | Date, strings: RelativeAgeStrings, locale: string): string;
@@ -1,6 +1,15 @@
1
1
  import { type Disambiguation, type Instant, type PlainDate, type PlainDateTime, type TimeZone } from "./types";
2
2
  /** The wall-clock reading in `zone` at `instant`. */
3
3
  export declare function instantToPlainDateTime(zone: TimeZone, instant: Instant): PlainDateTime;
4
+ /**
5
+ * The same wall-clock fields, but as though they were UTC.
6
+ *
7
+ * `Date.UTC` is NOT used directly anywhere in this file: it maps years 0–99
8
+ * onto 1900–1999, so a year-40 date silently becomes 1940. `setUTCFullYear` has
9
+ * no such rule. The calendar will never render year 40, but a helper that is
10
+ * wrong for an input it never receives is a trap left for whoever reuses it.
11
+ */
12
+ export declare function wallAsUtcMs(wall: PlainDateTime): number;
4
13
  /**
5
14
  * `zone`'s offset from UTC at `instant`, in milliseconds. East is positive.
6
15
  *
@@ -1,28 +1,29 @@
1
+ import type { BooleanStrings } from "../i18n/areas/formats";
1
2
  export interface FormatBooleanOptions {
2
- /** Word for `true`. Default `"Yes"`. */
3
+ /** Word for `true`. Default `strings.yes`. */
3
4
  trueLabel?: string;
4
- /** Word for `false`. Default `"No"`. */
5
+ /** Word for `false`. Default `strings.no`. */
5
6
  falseLabel?: string;
6
- /** Word for `null` / `undefined`. Default `"Unknown"` — see the module doc
7
+ /** Word for `null` / `undefined`. Default `strings.unknown` — see the module doc
7
8
  * for why this is not the em dash the rest of this package uses for
8
9
  * absence. */
9
10
  unknownLabel?: string;
10
11
  }
11
12
  /**
12
- * `true` → `"Yes"`, `false` → `"No"`, `null` / `undefined` → `"Unknown"`
13
- * (all three overridable via `options`).
13
+ * `true` → `strings.yes`, `false` → `strings.no`, `null` / `undefined` →
14
+ * `strings.unknown` (all three overridable via `options`).
14
15
  */
15
- export declare function formatBoolean(value: boolean | null | undefined, options?: FormatBooleanOptions): string;
16
+ export declare function formatBoolean(value: boolean | null | undefined, strings: BooleanStrings, options?: FormatBooleanOptions): string;
16
17
  /**
17
18
  * A human-typed word → `true`, `false`, or `null` for anything else
18
19
  * (including an empty string — a caller cannot distinguish "typed nothing"
19
20
  * from "typed a real value" if both return `false`).
20
21
  *
21
- * Matches case-insensitively against the common spellings a person actually
22
- * types into a Yes/No field: `yes`/`y`/`true`/`t`/`1` and `no`/`n`/`false`/
23
- * `f`/`0`. Deliberately does NOT guess at anything outside that list — a
22
+ * Matches case-insensitively against the spellings in `strings.trueWords` /
23
+ * `strings.falseWords` (English: `yes`/`y`/`true`/`t`/`1` and `no`/`n`/`false`/
24
+ * `f`/`0`). Deliberately does NOT guess at anything outside that list — a
24
25
  * typo like `"yse"` returning `null` for a caller to reject is correct;
25
26
  * returning `false` for it (or any other unrecognised text) would silently
26
27
  * record the opposite of an unreadable answer.
27
28
  */
28
- export declare function parseBoolean(input: string): boolean | null;
29
+ export declare function parseBoolean(input: string, strings: BooleanStrings): boolean | null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `1234.5` → `"$1,234.50"`. `null` / `undefined` → `"—"`. `0` → `"$0.00"`.
2
+ * `1234.5` → `"$1,234.50"` in `en-US`, `"1.234,50 $"` in `de-DE`. `null` / `undefined` → `"—"`. `0` → `"$0.00"`.
3
3
  *
4
4
  * `NaN` / `Infinity` are not real amounts either and render as the em dash —
5
5
  * grouped with absence rather than with a malformed string, because unlike
@@ -7,16 +7,16 @@
7
7
  * user-facing string to show back: the caller already has a `number`, and a
8
8
  * non-finite one is a computation defect upstream, not a typo to surface.
9
9
  */
10
- export declare function formatCurrency(value: number | null | undefined): string;
10
+ export declare function formatCurrency(value: number | null | undefined, locale: string): string;
11
11
  /**
12
12
  * A human-typed amount → a `number` in dollars, or `null`.
13
13
  *
14
- * Tolerates the punctuation someone actually types or pastes: a leading `$`,
15
- * thousands commas, surrounding whitespace, and ACCOUNTING-style negatives —
14
+ * Tolerates the punctuation someone actually types or pastes: the dollar sign
15
+ * (and `locale`'s own symbol for it), `locale`'s thousands separator, surrounding whitespace, and ACCOUNTING-style negatives —
16
16
  * `"($1,234.56)"` for `-1234.56`, the convention every US invoice and EOB
17
17
  * already uses for a credit or a refund. A leading `-` is accepted too.
18
18
  * Returns `null` — never `NaN`, never a silent `0` — for anything that is not
19
19
  * recognizably a number once that punctuation is stripped, so a caller can
20
20
  * reject a bad edit instead of storing garbage.
21
21
  */
22
- export declare function parseCurrency(input: string): number | null;
22
+ export declare function parseCurrency(input: string, locale: string): number | null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `"2026-09-11"` → `"09/11/2026"`.
2
+ * `"2026-09-11"` → `"09/11/2026"` in `en-US`, `"11.09.2026"` in `de-DE`.
3
3
  *
4
4
  * `null` / `undefined` / `""` render as the em dash — no date entered, the
5
5
  * convention the rest of this package's formatters share (`formatTokens`,
@@ -12,11 +12,11 @@
12
12
  * date" hides a data problem behind a blank field; showing the raw string
13
13
  * puts it in front of whoever is looking at the row.
14
14
  */
15
- export declare function formatDate(value: string | null | undefined): string;
15
+ export declare function formatDate(value: string | null | undefined, locale: string): string;
16
16
  /**
17
17
  * A human-typed date → the stored `YYYY-MM-DD`, or `null` if it is not one.
18
18
  *
19
- * Accepts `MM/DD/YYYY` (what `formatDate` prints, and what a person types
19
+ * Accepts the numeric date in `locale`'s own order (what `formatDate` prints, and what a person types
20
20
  * into a text field) and bare ISO `YYYY-MM-DD` (what a paste from another
21
21
  * system, or this library's own storage form, looks like) — nothing looser.
22
22
  * `Date`-style leniency (`new Date("2026-2-30")` silently becoming the 2nd of
@@ -27,4 +27,4 @@ export declare function formatDate(value: string | null | undefined): string;
27
27
  * Returns `null`, never throws — a form validating a field checks the return
28
28
  * value; it should not have to wrap every keystroke in `try`/`catch`.
29
29
  */
30
- export declare function parseDate(input: string): string | null;
30
+ export declare function parseDate(input: string, locale: string): string | null;
@@ -9,14 +9,14 @@ export interface FormatDateTimeOptions {
9
9
  zone?: string;
10
10
  }
11
11
  /**
12
- * A stored instant → `"09/11/2026, 1:18 PM"` in `options.zone` (default: the
12
+ * A stored instant → `"09/11/2026, 1:18 PM"` (`en-US`) in `options.zone` (default: the
13
13
  * reader's own).
14
14
  *
15
15
  * `null` / `undefined` / `""` render as the em dash. A non-empty value that
16
16
  * does not parse as an instant is returned UNCHANGED — see `date.ts`'s
17
17
  * docblock for why absence and corruption get different treatment.
18
18
  */
19
- export declare function formatDateTime(value: string | number | null | undefined, options?: FormatDateTimeOptions): string;
19
+ export declare function formatDateTime(value: string | number | null | undefined, locale: string, options?: FormatDateTimeOptions): string;
20
20
  export interface ParseDateTimeOptions {
21
21
  /**
22
22
  * The zone a bare (no AM/PM-less midnight, no offset) typed value's
@@ -45,4 +45,4 @@ export interface ParseDateTimeOptions {
45
45
  * matching every other date library's default and `Temporal`'s own. See
46
46
  * `time-dst.test.ts` for what that resolves to at a transition.
47
47
  */
48
- export declare function parseDateTime(input: string, options?: ParseDateTimeOptions): string | null;
48
+ export declare function parseDateTime(input: string, locale: string, options?: ParseDateTimeOptions): string | null;
@@ -0,0 +1,34 @@
1
+ import type { PlainDateTime } from "../time/types";
2
+ type DateField = "year" | "month" | "day";
3
+ export declare const DATE_OPTIONS: Intl.DateTimeFormatOptions;
4
+ export declare const TIME_OPTIONS: Intl.DateTimeFormatOptions;
5
+ /** A wall-clock reading as a `Date` whose UTC fields ARE the reading, so `timeZone: "UTC"` prints it untouched. */
6
+ export declare function wallDate(wall: PlainDateTime): Date;
7
+ export declare function plainSpaces(text: string): string;
8
+ export interface DatePattern {
9
+ order: DateField[];
10
+ /** Regex source matching one numeric date in the locale's order and separator. */
11
+ source: string;
12
+ }
13
+ /**
14
+ * The locale's own digits and bidi marks → plain Latin digits and nothing, so a number typed in
15
+ * Eastern Arabic or Persian digits (ar-EG, fa-IR) reads the same as one typed in Latin.
16
+ */
17
+ export declare function normalizeDigits(text: string, locale: string): string;
18
+ export declare function datePattern(locale: string): DatePattern;
19
+ /** The three captured numbers of a `datePattern` match, by field. */
20
+ export declare function dateFields(order: DateField[], match: RegExpExecArray, offset?: number): {
21
+ year: number;
22
+ month: number;
23
+ day: number;
24
+ };
25
+ export interface ClockPattern {
26
+ /** True when the locale shows 1-12 with a day period ("AM"/"PM"), false for a 0-23 clock. */
27
+ twelveHour: boolean;
28
+ /** Lower-case, space-free forms of the locale's morning and afternoon words (12-hour clocks only). */
29
+ am: string;
30
+ pm: string;
31
+ }
32
+ export declare function normalizePeriod(text: string): string;
33
+ export declare function clockPattern(locale: string): ClockPattern;
34
+ export {};
@@ -7,21 +7,21 @@ export interface FormatNumberOptions {
7
7
  decimals?: number;
8
8
  }
9
9
  /**
10
- * `1234.5` → `"1,234.5"`. `null` / `undefined` → `"—"`.
10
+ * `1234.5` → `"1,234.5"` in `en-US`, `"1.234,5"` in `de-DE`. `null` / `undefined` → `"—"`.
11
11
  *
12
12
  * `NaN` / `Infinity` render as the em dash too, for the same reason
13
13
  * `formatCurrency` groups them with absence rather than showing them back:
14
14
  * the caller holds a `number`, not a string a person typed, so there is no
15
15
  * original text to preserve.
16
16
  */
17
- export declare function formatNumber(value: number | null | undefined, options?: FormatNumberOptions): string;
17
+ export declare function formatNumber(value: number | null | undefined, locale: string, options?: FormatNumberOptions): string;
18
18
  /**
19
19
  * A human-typed number → a `number`, or `null`.
20
20
  *
21
- * Strips thousands-separator commas (`"1,234.5"` → `1234.5`) before parsing,
22
- * and accepts a leading `-` for a negative value. Rejects, rather than
21
+ * Reads `locale`'s own convention — `"1,234.5"` in `en-US` and `"1.234,5"` in
22
+ * `de-DE` are both `1234.5` — and accepts a leading `-` for a negative value. Rejects, rather than
23
23
  * silently truncating, anything `parseFloat` would otherwise accept a PREFIX
24
24
  * of — `"12abc"` is not twelve, it is a typo, and `parseFloat` alone would
25
25
  * return `12` and hide that.
26
26
  */
27
- export declare function parseNumber(input: string): number | null;
27
+ export declare function parseNumber(input: string, locale: string): number | null;
@@ -40,6 +40,7 @@
40
40
  */
41
41
  export { formatBytes, formatTokens, formatCompactNumber } from "./lib/format";
42
42
  export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions, formatCurrency, parseCurrency, formatNumber, parseNumber, type FormatNumberOptions, formatBoolean, parseBoolean, type FormatBooleanOptions, } from "./lib/values";
43
+ export type { BooleanStrings, FormatsStrings, ReadErrorStrings, RelativeAgeStrings } from "./lib/i18n/areas/formats";
43
44
  export { confidenceLevel, CONFIDENCE_LEVEL_LABELS, type ConfidenceLevel } from "./lib/confidence";
44
45
  export { CHART_SERIES_COUNT, CHART_SERIES_TOKENS, CHART_SEQUENTIAL_TOKEN, CHART_SEQUENTIAL_COLOR, chartSeriesColor, } from "./lib/chart-palette";
45
46
  export type { LegalBlock, LegalDocumentValue, LegalSection } from "./lib/legal-document";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "20.23.2",
3
+ "version": "21.0.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",