@nxgt/material 3.100.1 → 3.103.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 (156) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +32 -2
  3. package/dist/{alert-dialog-DYzxchiS.js → alert-dialog-NFyAiSqc.js} +1 -1
  4. package/dist/{async-slice-drJyPvuM.js → async-slice-D35bX79S.js} +1 -1
  5. package/dist/{bubble-input-CQwVSoU3.js → bubble-input-BxI1WmNs.js} +17 -5
  6. package/dist/{button-GeIsUekU.js → button-Be7GZzF9.js} +2 -2
  7. package/dist/{calculator-BS4PAm6l.js → calculator-BGy1Q7rn.js} +261 -460
  8. package/dist/calculator-field.js +7 -7
  9. package/dist/{calculator-segment-CEdwE24M.js → calculator-segment-uixk6lBg.js} +1 -1
  10. package/dist/calculator.js +1 -1
  11. package/dist/charts.js +3 -3
  12. package/dist/{chip-BdEtFQ85.js → chip-3rWebZEM.js} +2 -2
  13. package/dist/{code-editor-BByXZOGy.js → code-editor-BqSVMfy-.js} +178 -177
  14. package/dist/code-editor.js +5 -5
  15. package/dist/{code-language-items-CSZX5zxD.js → code-language-items-Cf2LJVg2.js} +14 -5
  16. package/dist/components/ui/actions/action-card/action-card-tile.css +47 -0
  17. package/dist/components/ui/display/code/code-moonlight.css +10 -10
  18. package/dist/{components-BrZkSs3O.js → components-D2liJ9Yu.js} +17725 -17287
  19. package/dist/components.js +38 -37
  20. package/dist/{conversion-variant-DTQqAyDt.js → conversion-variant-clFZ6ZMJ.js} +5 -5
  21. package/dist/{currency-field-Dnju7ss2.js → currency-field-CBFEVNM1.js} +24 -23
  22. package/dist/{dialog-5_2__tu8.js → dialog-CrIIINTk.js} +3 -3
  23. package/dist/dnd.js +1 -1
  24. package/dist/{dropdown-menu-FdGC5kIP.js → dropdown-menu-BnfLWu8n.js} +1 -1
  25. package/dist/editor.js +9 -9
  26. package/dist/{empty-state-BoepPG5v.js → empty-state-CuUaCPY7.js} +1 -1
  27. package/dist/{field-blur-DkiZOVNV.js → field-blur-DMJwPLsg.js} +9 -9
  28. package/dist/field-blur-context-3rKussBQ.js +29 -0
  29. package/dist/{financial-variant-BhqJp5C-.js → financial-variant-BY_VCUuk.js} +5 -5
  30. package/dist/{hooks-C8MhL6hs.js → hooks-hHoZbL-4.js} +106 -61
  31. package/dist/hooks.js +6 -6
  32. package/dist/{hover-card-CmHJeBeY.js → hover-card-Do2-uzlF.js} +1 -1
  33. package/dist/i18n.js +3 -3
  34. package/dist/{icon-badge-LGUPQh_c.js → icon-badge-CHaVNEmb.js} +1 -1
  35. package/dist/{icon-button-BSVpO1jP.js → icon-button-BIAubLeJ.js} +1 -1
  36. package/dist/key-layout-D2goCDkD.js +31 -0
  37. package/dist/keypad.js +551 -0
  38. package/dist/label-DR-zZyGQ.js +47 -0
  39. package/dist/lib/components/ui/display/code/code-block-parts.d.ts +1 -1
  40. package/dist/lib/components/ui/display/code/code-block.d.ts +4 -1
  41. package/dist/lib/components/ui/display/code/languages.d.ts +2 -0
  42. package/dist/lib/components/ui/display/code/moonlight-tokens.d.ts +10 -10
  43. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog-props.d.ts +73 -0
  44. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog-rules.d.ts +12 -0
  45. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog.d.ts +5 -61
  46. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-footer.d.ts +12 -0
  47. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-phrase.d.ts +26 -0
  48. package/dist/lib/components/ui/feedback/confirm-dialog/use-confirm-action.d.ts +1 -1
  49. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  50. package/dist/lib/components/ui/layout/index.d.ts +1 -0
  51. package/dist/lib/components/ui/layout/panel-card/index.d.ts +1 -0
  52. package/dist/lib/components/ui/layout/panel-card/panel-card.d.ts +21 -0
  53. package/dist/lib/components/ui/selection/index.d.ts +1 -0
  54. package/dist/lib/components/ui/selection/status-menu/index.d.ts +3 -0
  55. package/dist/lib/components/ui/selection/status-menu/partials/status-confirm.d.ts +12 -0
  56. package/dist/lib/components/ui/selection/status-menu/partials/status-icon.d.ts +6 -0
  57. package/dist/lib/components/ui/selection/status-menu/partials/status-items.d.ts +18 -0
  58. package/dist/lib/components/ui/selection/status-menu/partials/status-menu-list.d.ts +14 -0
  59. package/dist/lib/components/ui/selection/status-menu/partials/status-sheet-row.d.ts +11 -0
  60. package/dist/lib/components/ui/selection/status-menu/partials/status-sheet.d.ts +21 -0
  61. package/dist/lib/components/ui/selection/status-menu/partials/status-trigger.d.ts +18 -0
  62. package/dist/lib/components/ui/selection/status-menu/status-menu-data.d.ts +12 -0
  63. package/dist/lib/components/ui/selection/status-menu/status-menu-form-field.d.ts +20 -0
  64. package/dist/lib/components/ui/selection/status-menu/status-menu.d.ts +13 -0
  65. package/dist/lib/components/ui/selection/status-menu/types.d.ts +76 -0
  66. package/dist/lib/components/ui/selection/status-menu/use-status-change.d.ts +18 -0
  67. package/dist/lib/components/ui/selection/status-menu/use-status-menu.d.ts +30 -0
  68. package/dist/lib/components/ui/widgets/calculator/partials/calculator-keypad.d.ts +1 -5
  69. package/dist/lib/components/ui/widgets/calculator/variants/key-layout.d.ts +3 -49
  70. package/dist/lib/components/ui/widgets/keypad/cash-model.d.ts +16 -0
  71. package/dist/lib/components/ui/widgets/keypad/index.d.ts +5 -0
  72. package/dist/lib/components/ui/widgets/keypad/key-layout.d.ts +56 -0
  73. package/dist/lib/components/ui/widgets/keypad/keypad-binding.d.ts +32 -0
  74. package/dist/lib/components/ui/widgets/keypad/keypad-cash.d.ts +28 -0
  75. package/dist/lib/components/ui/widgets/keypad/keypad-display.d.ts +11 -0
  76. package/dist/lib/components/ui/widgets/keypad/keypad-entry.d.ts +39 -0
  77. package/dist/lib/components/ui/widgets/keypad/keypad-grid.d.ts +27 -0
  78. package/dist/lib/components/ui/widgets/{calculator/partials/calculator-key.d.ts → keypad/keypad-key.d.ts} +6 -3
  79. package/dist/lib/components/ui/widgets/keypad/keypad-layout.d.ts +19 -0
  80. package/dist/lib/components/ui/widgets/{calculator/partials → keypad}/keypad-navigation.d.ts +1 -1
  81. package/dist/lib/components/ui/widgets/keypad/keypad.d.ts +9 -0
  82. package/dist/lib/components/ui/widgets/keypad/keypad.types.d.ts +91 -0
  83. package/dist/lib/components/ui/widgets/keypad/use-keypad-cash.d.ts +14 -0
  84. package/dist/lib/components/ui/widgets/keypad/use-keypad-keyboard.d.ts +7 -0
  85. package/dist/lib/components/ui/widgets/keypad/use-keypad-number.d.ts +10 -0
  86. package/dist/lib/components/ui/widgets/keypad/use-keypad-quantity.d.ts +16 -0
  87. package/dist/lib/components/ui/widgets/keypad/use-keypad-value.d.ts +17 -0
  88. package/dist/lib/components/ui/widgets/keypad/use-keypad.d.ts +23 -0
  89. package/dist/lib/hooks/index.d.ts +2 -0
  90. package/dist/lib/hooks/use-barcode-scanner.d.ts +39 -0
  91. package/dist/lib/hooks/use-latched.d.ts +18 -0
  92. package/dist/lib/i18n/resources/en/en.d.ts +25 -0
  93. package/dist/lib/i18n/resources/en/material.json.d.ts +26 -1
  94. package/dist/lib/i18n/resources/fr/fr.d.ts +25 -0
  95. package/dist/lib/i18n/resources/fr/material.json.d.ts +26 -1
  96. package/dist/lib/i18n/resources/resources.d.ts +50 -0
  97. package/dist/lib/i18n/translator.d.ts +1 -1
  98. package/dist/lib/keypad/index.d.ts +20 -0
  99. package/dist/lib.js +1 -1
  100. package/dist/main.js +54 -53
  101. package/dist/map.js +9 -9
  102. package/dist/material.css +1 -1
  103. package/dist/pdf-reader.js +1 -1
  104. package/dist/{percent-field-DGlU_xii.js → percent-field-DU8eIMD3.js} +15 -14
  105. package/dist/{picker-surface-CGhqNR8a.js → picker-surface-XmA--JVI.js} +4 -4
  106. package/dist/{popover-ZxL7ktKk.js → popover-D8iHiAbl.js} +1 -1
  107. package/dist/{pos-types-BQ0QpYMp.js → pos-types-BEAY27Rm.js} +1 -1
  108. package/dist/{pos-variant-CKy8h_5i.js → pos-variant-ClGI92Lt.js} +25 -25
  109. package/dist/print.js +1 -1
  110. package/dist/{programmer-variant-CbHstE28.js → programmer-variant-Boq2O8hB.js} +30 -30
  111. package/dist/{public-D-tdOz4b.js → public-DOrXKmcL.js} +9 -9
  112. package/dist/{rich-code-block-CTPj1LuD.js → rich-code-block-Djj2XE_u.js} +18 -18
  113. package/dist/{scientific-variant-B8U9h3II.js → scientific-variant-BzF_aMQP.js} +8 -8
  114. package/dist/{sortable-provider-CSoWE7Ce.js → sortable-provider-DCZjsIIH.js} +2 -2
  115. package/dist/{spinner-ffuwBXHl.js → spinner-Cg0y_E_K.js} +1 -1
  116. package/dist/standard-layout-DTr9yy8Z.js +48 -0
  117. package/dist/{tabs-JgRq6ZJx.js → tabs-DpessV5s.js} +1 -1
  118. package/dist/{text-field-DURkIP-v.js → text-field-Dxk9lAKM.js} +16 -15
  119. package/dist/theme-picker.js +13 -13
  120. package/dist/{theme-toggle-n_Zg7JAA.js → theme-toggle-B6Jl5Kfn.js} +1 -1
  121. package/dist/{toolbar-items-IANZdcw4.js → toolbar-items-Cs1XrZsH.js} +4 -4
  122. package/dist/{translate-material-CMHUH5Ha.js → translate-material-Du0j0t97.js} +1 -1
  123. package/dist/{translator-9zA-Um3W.js → translator-BVs4n0Fz.js} +52 -2
  124. package/dist/use-calculator-keyboard-BZ1CA4Ut.js +222 -0
  125. package/dist/{use-chat-composer-BoIN7RCA.js → use-chat-composer-B4m3OEm1.js} +241 -240
  126. package/dist/{use-heading-spy-8o20PEZH.js → use-heading-spy-CO3_AtY9.js} +240 -142
  127. package/dist/{use-material-translation-CLNaMhUf.js → use-material-translation-uNc1FyC8.js} +1 -1
  128. package/dist/{use-return-focus-DWhbTGVe.js → use-return-focus-AfLRrUm-.js} +1 -1
  129. package/docs/README.md +1 -0
  130. package/docs/components/README.md +1 -0
  131. package/docs/components/buttons-and-actions.md +34 -2
  132. package/docs/components/data-display.md +4 -1
  133. package/docs/components/feedback-and-status.md +34 -0
  134. package/docs/components/navigation-and-layout.md +28 -0
  135. package/docs/components/rich-widgets.md +28 -0
  136. package/docs/components/selection-and-choice.md +120 -0
  137. package/docs/guides/calculator.md +1 -1
  138. package/docs/guides/cards-and-tiles.md +21 -24
  139. package/docs/guides/forms.md +1 -0
  140. package/docs/guides/helpers.md +78 -0
  141. package/docs/guides/keypad.md +225 -0
  142. package/docs/previews/data-display-codeblock.webp +0 -0
  143. package/docs/previews/data-display-codegroup.webp +0 -0
  144. package/docs/previews/data-display-jsonviewer.webp +0 -0
  145. package/docs/previews/navigation-layout-panelcard.webp +0 -0
  146. package/docs/previews/rich-widgets-keypad.webp +0 -0
  147. package/docs/previews/selection-choice-statusmenu.webp +0 -0
  148. package/docs/roadmap.md +21 -0
  149. package/docs/troubleshooting.md +63 -0
  150. package/lib/components/ui/actions/action-card/action-card-tile.css +47 -0
  151. package/lib/components/ui/display/code/code-moonlight.css +10 -10
  152. package/lib/components/ui/widgets/calculator/calculator.css +87 -0
  153. package/package.json +7 -2
  154. package/dist/field-blur-context-BLGgf_3z.js +0 -73
  155. package/dist/key-layout-cR79xfGE.js +0 -38
  156. package/dist/standard-layout-BuSRr3TY.js +0 -40
@@ -17,6 +17,7 @@ export * from './navigation-rail/index.js';
17
17
  export * from './navigation-toolbar/index.js';
18
18
  export * from './pager/index.js';
19
19
  export * from './pane-layout/index.js';
20
+ export * from './panel-card/index.js';
20
21
  export * from './record-page/index.js';
21
22
  export * from './resizable/index.js';
22
23
  export * from './responsive-grid/index.js';
@@ -0,0 +1 @@
1
+ export * from './panel-card.js';
@@ -0,0 +1,21 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ export type PanelCardHeadingLevel = 2 | 3 | 4 | 5 | 6;
3
+ export type PanelCardProps = Omit<ComponentProps<'div'>, 'title'> & {
4
+ /** The panel's name: its heading, and the accessible name of the card. */
5
+ title: ReactNode;
6
+ /** One line under the title. */
7
+ description?: ReactNode;
8
+ /**
9
+ * The heading level of the title, `2` by default: a panel sits under the
10
+ * page's `h1`. Use `3` inside a section that already has an `h2`.
11
+ */
12
+ headingLevel?: PanelCardHeadingLevel;
13
+ /** A header slot at the end of the title row (a button, a `RowMenu`). */
14
+ actions?: ReactNode;
15
+ };
16
+ /**
17
+ * A titled card for the side of a page (an `ActivityContent` aside) or its
18
+ * sections: a heading, an optional description and header actions over the
19
+ * content. The card is a named region, labelled by its heading.
20
+ */
21
+ export declare function PanelCard({ title, description, headingLevel, actions, className, children, ...props }: PanelCardProps): import("react").JSX.Element;
@@ -13,6 +13,7 @@ export * from './radio-group/index.js';
13
13
  export * from './select/index.js';
14
14
  export * from './select-field/index.js';
15
15
  export * from './sortable-list/index.js';
16
+ export * from './status-menu/index.js';
16
17
  export * from './switcher/index.js';
17
18
  export * from './transfer-list/index.js';
18
19
  export * from './tree-select-field/index.js';
@@ -0,0 +1,3 @@
1
+ export { StatusMenu } from './status-menu.js';
2
+ export { StatusMenuFormField, type StatusMenuFormFieldProps, } from './status-menu-form-field.js';
3
+ export type { StatusChoice, StatusConfirm, StatusMenuProps } from './types.js';
@@ -0,0 +1,12 @@
1
+ import { StatusChoice } from '../types.js';
2
+ /**
3
+ * The confirmation a status asks for before it is picked, through the
4
+ * library's `ConfirmDialog` (busy buttons, the failure kept in the dialog,
5
+ * focus back to the chip on close).
6
+ */
7
+ export declare function StatusConfirm({ choice, onConfirm, onCancel, onCloseAutoFocus, }: {
8
+ choice: StatusChoice | null;
9
+ onConfirm: (value: string) => Promise<void>;
10
+ onCancel: () => void;
11
+ onCloseAutoFocus: (event: Event) => void;
12
+ }): import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { StatusChoice } from '../types.js';
2
+ /** A status's decorative icon in its tone's text colour; the words carry the meaning. */
3
+ export declare function StatusIcon({ choice, className, }: {
4
+ choice: Pick<StatusChoice, 'icon' | 'tone'>;
5
+ className?: string;
6
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,18 @@
1
+ import { StatusEntry } from '@nxgt/material-core/status-menu';
2
+ import { StatusChoice } from '../types.js';
3
+ /**
4
+ * One status row: its icon, label and a second line (the reason when
5
+ * blocked, else the description). The held one is checked and inert; a
6
+ * blocked one is greyed and says why.
7
+ */
8
+ export declare function StatusItem({ entry, choice, reason, }: {
9
+ entry: StatusEntry;
10
+ choice: StatusChoice;
11
+ reason?: string;
12
+ }): import("react").JSX.Element;
13
+ /** A status row's content, in the menu and in the phone sheet: icon, label, and the reason or description. */
14
+ export declare function StatusItemBody({ entry, choice, reason, }: {
15
+ entry: StatusEntry;
16
+ choice: StatusChoice;
17
+ reason?: string;
18
+ }): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { StatusEntry } from '@nxgt/material-core/status-menu';
2
+ import { StatusChoice } from '../types.js';
3
+ /** The open menu: the lock reason first when locked, then one radio row per status. */
4
+ export declare function StatusMenuList({ value, lockedReason, rows, onPick, className, }: {
5
+ value: string;
6
+ lockedReason?: string;
7
+ rows: {
8
+ entry: StatusEntry;
9
+ choice: StatusChoice;
10
+ reason?: string;
11
+ }[];
12
+ onPick: (next: string) => void;
13
+ className?: string;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { StatusEntry } from '@nxgt/material-core/status-menu';
2
+ import { StatusChoice } from '../types.js';
3
+ /**
4
+ * One 44px radio row of the phone sheet. The held status is checked and
5
+ * inert; a blocked one is greyed, disabled and says why in its own text.
6
+ */
7
+ export declare function StatusSheetRow({ entry, choice, reason, }: {
8
+ entry: StatusEntry;
9
+ choice: StatusChoice;
10
+ reason?: string;
11
+ }): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { StatusEntry } from '@nxgt/material-core/status-menu';
2
+ import { StatusChoice } from '../types.js';
3
+ /**
4
+ * The phone's choices: a bottom sheet named by the record's label, a close
5
+ * button, and a radiogroup of 44px rows. A blocked row says why in its own
6
+ * text (touch has no tooltip); the held one is checked and inert. Picking a
7
+ * row closes the sheet, and focus returns to the chip.
8
+ */
9
+ export declare function StatusSheet({ label, value, lockedReason, rows, onPick, onClose, className, }: {
10
+ label: string;
11
+ value: string;
12
+ lockedReason?: string;
13
+ rows: {
14
+ entry: StatusEntry;
15
+ choice: StatusChoice;
16
+ reason?: string;
17
+ }[];
18
+ onPick: (next: string) => void;
19
+ onClose: () => void;
20
+ className?: string;
21
+ }): import("react").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { ComponentProps } from 'react';
2
+ import { StatusChoice, StatusMenuProps } from '../types.js';
3
+ /**
4
+ * The chip: a soft Badge pill (tone container, tone icon, words, chevron) as a
5
+ * button. It forwards its props and ref, so it works as the child of a
6
+ * `DropdownMenuTrigger asChild` and a `Tooltip`.
7
+ */
8
+ export declare function StatusTrigger({ choice, size, busy, locked, className, ...props }: {
9
+ choice: Pick<StatusChoice, 'label' | 'icon' | 'tone'>;
10
+ size?: StatusMenuProps['size'];
11
+ busy?: boolean;
12
+ locked?: boolean;
13
+ } & Omit<ComponentProps<'button'>, 'children'>): import("react").JSX.Element;
14
+ /** Read-only: the status as a plain label, no button and no chevron. */
15
+ export declare function StatusReadOnly({ choice, size, className, ...props }: {
16
+ choice: Pick<StatusChoice, 'label' | 'icon' | 'tone'>;
17
+ size?: StatusMenuProps['size'];
18
+ } & ComponentProps<'span'>): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { StatusChoice } from './types.js';
2
+ export type TicketStatus = 'todo' | 'progress' | 'waiting' | 'done' | 'cancelled';
3
+ /** Generic statuses: a ticket, an order or a task has a set like this. */
4
+ export declare const TICKET_STATUSES: StatusChoice<TicketStatus>[];
5
+ /** What a task in Done may become: a reopen to In progress only. */
6
+ export declare const TICKET_TRANSITIONS: {
7
+ todo: ("progress" | "waiting" | "cancelled")[];
8
+ progress: ("done" | "waiting" | "cancelled" | "todo")[];
9
+ waiting: ("progress" | "cancelled")[];
10
+ done: "progress"[];
11
+ cancelled: "todo"[];
12
+ };
@@ -0,0 +1,20 @@
1
+ import { UseControllerProps } from 'react-hook-form';
2
+ import { StatusMenuProps } from './types.js';
3
+ export type StatusMenuFormFieldProps<T extends Record<string, any>, V extends string = string> = Pick<UseControllerProps<T>, 'control' | 'name' | 'rules'> & Omit<StatusMenuProps<V>, 'value' | 'onSelect'> & {
4
+ /**
5
+ * Runs first; the form takes the new status once it resolves (a promise
6
+ * keeps the pending state and the old status). A rejection keeps the old
7
+ * value and goes to `onError`.
8
+ */
9
+ onSelect?: StatusMenuProps<V>['onSelect'];
10
+ /** Nothing can be picked, as `locked` (React Hook Form's `disabled` sets it too). */
11
+ disabled?: boolean;
12
+ /** Shown under the chip while there is no error. */
13
+ helperText?: string;
14
+ };
15
+ /**
16
+ * `StatusMenu` bound to React Hook Form: the form holds the status (a
17
+ * `choices` value), a pick calls `field.onChange`, the error message is written
18
+ * under the chip and linked to it, and a refused submit focuses the chip.
19
+ */
20
+ export declare function StatusMenuFormField<T extends Record<string, any>, V extends string = string>({ control, name, rules, onSelect, disabled, helperText, locked, triggerProps, ...props }: StatusMenuFormFieldProps<T, V>): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { StatusMenuProps } from './types.js';
2
+ /**
3
+ * A record's status as a chip (a soft Badge pill: tone container, tone icon,
4
+ * words, chevron) that opens a menu of the other statuses. The held one is
5
+ * checked and inert; the ones `transitions` do not reach are greyed with their
6
+ * reason; `locked` shows its reason (tooltip and first menu line) and picks
7
+ * nothing; `busy` (or an `onSelect` that returns a promise, until it settles) keeps the old
8
+ * status with a spinner and announces a failure through `onError`; a choice with
9
+ * `confirm` asks first; `readOnly` is a plain
10
+ * label. Under 768px (`presentation="auto"`) the statuses open in a bottom sheet of 44px rows,
11
+ * each blocked reason written in its row.
12
+ */
13
+ export declare function StatusMenu<V extends string = string>(props: StatusMenuProps<V>): import("react").JSX.Element;
@@ -0,0 +1,76 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ import { IconName } from '../../primitives/icon/icon.js';
3
+ import { Tone } from '../../tones.js';
4
+ /** One status a record can hold. */
5
+ export type StatusChoice<V extends string = string> = {
6
+ value: V;
7
+ /** The status in words: what the chip and the menu say. */
8
+ label: string;
9
+ /** Its colour (neutral without one). */
10
+ tone?: Tone;
11
+ /** A decorative icon: a Font Awesome name or a node. The words name the status. */
12
+ icon?: ReactNode | IconName;
13
+ /** A second line under its label in the menu. */
14
+ description?: string;
15
+ /** Cannot be picked. */
16
+ disabled?: boolean;
17
+ /** Why it cannot be picked, shown under its label. */
18
+ disabledReason?: string;
19
+ /** Picking it first asks for a confirmation (a `ConfirmDialog`); `onSelect` runs on confirm. */
20
+ confirm?: StatusConfirm;
21
+ };
22
+ /** The confirmation a status asks for before it is picked. */
23
+ export type StatusConfirm = {
24
+ title: string;
25
+ description?: ReactNode;
26
+ /** The confirm button's words (default "Confirm"). */
27
+ confirmLabel?: string;
28
+ /** A red confirm button, for a move that cannot be undone. */
29
+ destructive?: boolean;
30
+ };
31
+ export type StatusMenuProps<V extends string = string> = {
32
+ /** What the status belongs to ("Ticket 42"): the button is named "Status of Ticket 42: Open". */
33
+ label: string;
34
+ /** The held status: the `value` of one of `choices`. */
35
+ value: V;
36
+ choices: readonly StatusChoice<V>[];
37
+ /**
38
+ * A different status was picked (never the held one, never when locked or
39
+ * busy). Return a promise to show the pending state until it settles.
40
+ */
41
+ onSelect: (next: V, prev: V) => void | Promise<void>;
42
+ /** An `onSelect` that rejects (or a confirmed one): the failure is announced and reported here. */
43
+ onError?: (error: unknown) => void;
44
+ /**
45
+ * The statuses reachable from each status. A status with no key allows every
46
+ * move.
47
+ */
48
+ transitions?: Partial<Record<V, readonly V[]>>;
49
+ /** A status the transitions do not reach: greyed with its reason (default) or `'hidden'`. */
50
+ unavailable?: 'disabled' | 'hidden';
51
+ /** Nothing can be picked: a tooltip and the first line of the menu say `reason`. */
52
+ locked?: boolean;
53
+ reason?: string;
54
+ /**
55
+ * A change is being saved: a spinner replaces the chevron, the old status
56
+ * stays. An `onSelect` that returns a promise sets it by itself until the
57
+ * promise settles; this prop is for a save the parent runs.
58
+ */
59
+ busy?: boolean;
60
+ /** A plain label: no button, no menu. */
61
+ readOnly?: boolean;
62
+ size?: 'sm' | 'md';
63
+ /**
64
+ * How the statuses open: `'menu'` (a dropdown), `'sheet'` (a bottom sheet of
65
+ * 44px rows, with each blocked reason written in its row) or `'auto'` (the
66
+ * default): a sheet under 768px, a menu above.
67
+ */
68
+ presentation?: 'auto' | 'menu' | 'sheet';
69
+ /** Controlled state, as `DropdownMenu`'s. */
70
+ open?: boolean;
71
+ onOpenChange?: (open: boolean) => void;
72
+ /** Props for the trigger button (`data-*`, `id`, `aria-describedby`…). */
73
+ triggerProps?: Omit<ComponentProps<'button'>, 'children' | 'type'>;
74
+ /** On the menu. */
75
+ className?: string;
76
+ };
@@ -0,0 +1,18 @@
1
+ import { StatusChoice, StatusMenuProps } from './types.js';
2
+ export declare const isThenable: (v: unknown) => v is PromiseLike<unknown>;
3
+ /**
4
+ * Runs a pick: an `onSelect` that returns a promise is pending until it
5
+ * settles (the old status stays), a rejection is announced and sent to
6
+ * `onError`. `message` is what the live region says; `confirming` is the
7
+ * choice waiting for its confirmation.
8
+ */
9
+ export declare function useStatusChange<V extends string>(props: StatusMenuProps<V>, labelOf: (value: V) => string): {
10
+ pending: boolean;
11
+ message: string | null;
12
+ confirming: StatusChoice<V> | null;
13
+ start: (next: V) => void;
14
+ ask: (choice: StatusChoice<V>) => void;
15
+ cancelAsk: () => void;
16
+ /** What the confirm dialog runs: a throw stays in the dialog and goes to `onError`. */
17
+ confirmRun: (next: V) => Promise<void>;
18
+ };
@@ -0,0 +1,30 @@
1
+ import { StatusChoice, StatusMenuProps } from './types.js';
2
+ /** The model of a StatusMenu: its entries, names and the open state. */
3
+ export declare function useStatusMenu<V extends string>(props: StatusMenuProps<V>): {
4
+ sheet: boolean;
5
+ change: {
6
+ pending: boolean;
7
+ message: string | null;
8
+ confirming: StatusChoice<V> | null;
9
+ start: (next: V) => void;
10
+ ask: (choice: StatusChoice<V>) => void;
11
+ cancelAsk: () => void;
12
+ confirmRun: (next: V) => Promise<void>;
13
+ };
14
+ busy: boolean;
15
+ entries: {
16
+ entry: import('@nxgt/material-core/status-menu').StatusEntry<V>;
17
+ choice: StatusChoice<V>;
18
+ }[];
19
+ current: StatusChoice<V> | undefined;
20
+ reasonId: string;
21
+ open: boolean;
22
+ reasonOf: ({ entry, choice }: {
23
+ entry: import('@nxgt/material-core/status-menu').StatusEntry<V>;
24
+ choice: StatusChoice<V>;
25
+ }) => string | undefined;
26
+ lockedReason: string | undefined;
27
+ name: string;
28
+ setOpen: (next: boolean) => void;
29
+ pick: (next: string) => void;
30
+ };
@@ -1,8 +1,4 @@
1
- /**
2
- * The keys as native buttons in one `role="group"`. The group is one tab
3
- * stop (a roving tabindex); the arrow keys move over the grid in two
4
- * dimensions, Home and End along a row, with Ctrl to the first and last key.
5
- */
1
+ /** The calculator's keys: the shared keypad grid bound to the engine's press. */
6
2
  export declare function CalculatorKeypad({ helpId }: {
7
3
  helpId: string;
8
4
  }): import("react").JSX.Element;
@@ -1,51 +1,5 @@
1
- import { CalcKey } from '@nxgt/material-core/calculator';
2
- import { CalculatorMessage } from '../types.js';
3
- import { POS_NAMES } from './pos/pos-names.js';
4
- import { PROGRAMMER_NAMES } from './programmer/programmer-names.js';
5
- import { SCIENTIFIC_NAMES } from './scientific/scientific-names.js';
6
- /** What a key looks like: its shape and colour follow the role. */
7
- export type KeyRole = 'digit' | 'operator' | 'equals' | 'utility' | 'function' | 'memory'
8
- /** ( and ): small keys like the memory ones. */
9
- | 'bracket';
10
- export type KeyDef = {
11
- readonly id: string;
12
- /** The engine key it presses. */
13
- readonly key: CalcKey;
14
- /** What is drawn; `aria-hidden`, the spoken name is `name`. */
15
- readonly glyph: string;
16
- readonly role: KeyRole;
17
- /** The spoken name, the button's `aria-label`. */
18
- readonly name: CalculatorMessage;
19
- /** Grid units spanned, 1 by default. */
20
- readonly span?: number;
21
- /** What the key is on the second page (2nd): same place, another key. */
22
- readonly alt?: KeyAlt;
23
- /** Keys pressed one after the other, instead of `key` (`EE` is `* 10 ^`). */
24
- readonly sequence?: readonly CalcKey[];
25
- };
26
- /** A key's second-page face: it keeps the button, so focus stays put. */
27
- export type KeyAlt = Pick<KeyDef, 'key' | 'glyph' | 'name'>;
28
- /** Keys by rows on a grid of `columns`. */
29
- export type KeyLayout = {
30
- readonly columns: number;
31
- readonly rows: readonly (readonly KeyDef[])[];
32
- /**
33
- * The first `split` rows are a pane of their own (the scientific
34
- * functions): above the rest on a phone, beside it from 600px.
35
- */
36
- readonly split?: number;
37
- };
38
- /** The spoken names, as the `material.calculator.keys.*` leaves. */
39
- export type KeyName = (typeof DIGIT_NAMES)[number] | 'decimal' | 'add' | 'subtract' | 'multiply' | 'divide' | 'equals' | 'clear' | 'backspace' | 'sign' | 'percent' | 'open-paren' | 'close-paren' | 'memory-clear' | 'memory-recall' | 'memory-add' | 'memory-subtract' | (typeof SCIENTIFIC_NAMES)[number] | (typeof POS_NAMES)[number] | (typeof PROGRAMMER_NAMES)[number];
40
- export declare const msg: (name: KeyName, fallback: string) => CalculatorMessage;
41
- export declare const key: (id: string, k: CalcKey, glyph: string, role: KeyRole, name: KeyName, fallback: string, span?: number) => KeyDef;
42
- export declare const DIGIT_NAMES: readonly ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
43
- export declare const digit: (n: number, span?: number) => KeyDef;
1
+ import { KeyDef } from '../../keypad/key-layout.js';
44
2
  /** `( ) MC MR M+ M-`: six small keys, two grid units each (twelve units a row). */
45
3
  export declare const MEMORY_ROW: readonly KeyDef[];
46
- /** A row of four keys, three grid units each, on the twelve-unit grid. */
47
- export declare const wide: (keys: readonly KeyDef[]) => readonly KeyDef[];
48
- /** The key a pressed `def` stands for on page one or, with 2nd, page two. */
49
- export declare const faceOf: (def: KeyDef, second: boolean) => KeyDef;
50
- /** The keys a press of `def` sends to the engine, in order. */
51
- export declare const keysOf: (def: KeyDef) => readonly CalcKey[];
4
+ export type { KeyAlt, KeyDef, KeyLayout, KeyName, KeyRole, } from '../../keypad/key-layout.js';
5
+ export { DIGIT_NAMES, digit, faceOf, key, keysOf, msg, wide, } from '../../keypad/key-layout.js';
@@ -0,0 +1,16 @@
1
+ import { KeypadSettlement } from './keypad.types.js';
2
+ /**
3
+ * The total as the till charges it: rounded half-up, once, to the decimals
4
+ * kept (a float sum such as `0.1 + 0.2` is `0.3`, `19.999` is `20`), as
5
+ * canonical text. `undefined` when it is missing or not a number. Settlement,
6
+ * shortcuts and the summary all start from this one amount.
7
+ */
8
+ export declare function cashTotal(total: number | string | undefined, digits?: number): string | undefined;
9
+ /** The settlement of `tendered` against `total`; `undefined` while nothing is tendered or an amount is invalid. */
10
+ export declare function cashSettlement(total: number | string | undefined, tendered: string): KeypadSettlement | undefined;
11
+ /**
12
+ * The amounts to offer as one-tap tenders: the exact total, then the round
13
+ * amounts above it, at most four, rounded to `digits` and none above `max`
14
+ * (the keypad would hold less than the button says).
15
+ */
16
+ export declare function cashShortcuts(total: number | string | undefined, denominations: readonly number[] | undefined, max?: number, digits?: number, limit?: number): string[];
@@ -0,0 +1,5 @@
1
+ export { Keypad } from './keypad.js';
2
+ export type { KeypadBinding, KeypadEntry, KeypadOperation, KeypadProps, KeypadSettlement, KeypadVariant, } from './keypad.types.js';
3
+ export type { UseKeypadNumberOptions } from './keypad-binding.js';
4
+ export { useKeypadNumber } from './use-keypad-number.js';
5
+ export { type UseKeypadQuantityOptions, useKeypadQuantity, } from './use-keypad-quantity.js';
@@ -0,0 +1,56 @@
1
+ import { CalcKey } from '@nxgt/material-core/calculator';
2
+ import { MaterialLocaleKey } from '../../../../i18n/types.js';
3
+ import { POS_NAMES } from '../calculator/variants/pos/pos-names.js';
4
+ import { PROGRAMMER_NAMES } from '../calculator/variants/programmer/programmer-names.js';
5
+ import { SCIENTIFIC_NAMES } from '../calculator/variants/scientific/scientific-names.js';
6
+ /** What a key looks like: its shape and colour follow the role. */
7
+ export type KeyRole = 'digit' | 'operator' | 'equals' | 'utility' | 'function' | 'memory'
8
+ /** ( and ): small keys like the memory ones. */
9
+ | 'bracket';
10
+ /** A UI string: the `material.*` key and the English text used without a provider. */
11
+ export type KeyMessage = {
12
+ readonly key: MaterialLocaleKey;
13
+ readonly fallback: string;
14
+ };
15
+ export type KeyDef = {
16
+ readonly id: string;
17
+ /** The engine key it presses. */
18
+ readonly key: CalcKey;
19
+ /** What is drawn; `aria-hidden`, the spoken name is `name`. */
20
+ readonly glyph: string;
21
+ readonly role: KeyRole;
22
+ /** The spoken name, the button's `aria-label`. */
23
+ readonly name: KeyMessage;
24
+ /** An app's own spoken name, which replaces the translated `name`. */
25
+ readonly label?: string;
26
+ /** Grid units spanned, 1 by default. */
27
+ readonly span?: number;
28
+ /** What the key is on the second page (2nd): same place, another key. */
29
+ readonly alt?: KeyAlt;
30
+ /** Keys pressed one after the other, instead of `key` (`EE` is `* 10 ^`). */
31
+ readonly sequence?: readonly CalcKey[];
32
+ };
33
+ /** A key's second-page face: it keeps the button, so focus stays put. */
34
+ export type KeyAlt = Pick<KeyDef, 'key' | 'glyph' | 'name'>;
35
+ /** Keys by rows on a grid of `columns`. */
36
+ export type KeyLayout = {
37
+ readonly columns: number;
38
+ readonly rows: readonly (readonly KeyDef[])[];
39
+ /**
40
+ * The first `split` rows are a pane of their own (the scientific
41
+ * functions): above the rest on a phone, beside it from 600px.
42
+ */
43
+ readonly split?: number;
44
+ };
45
+ /** A row of four keys, three grid units each, on the twelve-unit grid. */
46
+ export declare const wide: (keys: readonly KeyDef[]) => readonly KeyDef[];
47
+ /** The key a pressed `def` stands for on page one or, with 2nd, page two. */
48
+ export declare const faceOf: (def: KeyDef, second: boolean) => KeyDef;
49
+ /** The keys a press of `def` sends to the engine, in order. */
50
+ export declare const keysOf: (def: KeyDef) => readonly CalcKey[];
51
+ /** The spoken names, as the `material.calculator.keys.*` leaves. */
52
+ export type KeyName = (typeof DIGIT_NAMES)[number] | 'decimal' | 'add' | 'subtract' | 'multiply' | 'divide' | 'equals' | 'clear' | 'backspace' | 'sign' | 'percent' | 'open-paren' | 'close-paren' | 'memory-clear' | 'memory-recall' | 'memory-add' | 'memory-subtract' | (typeof SCIENTIFIC_NAMES)[number] | (typeof POS_NAMES)[number] | (typeof PROGRAMMER_NAMES)[number];
53
+ export declare const msg: (name: KeyName, fallback: string) => KeyMessage;
54
+ export declare const key: (id: string, k: CalcKey, glyph: string, role: KeyRole, name: KeyName, fallback: string, span?: number) => KeyDef;
55
+ export declare const DIGIT_NAMES: readonly ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
56
+ export declare const digit: (n: number, span?: number) => KeyDef;
@@ -0,0 +1,32 @@
1
+ import { KeypadBinding, KeypadProps } from './keypad.types.js';
2
+ export type UseKeypadNumberOptions = {
3
+ /** The field's number (`null` or `undefined` while empty). */
4
+ value: number | null | undefined;
5
+ onChange?: (value: number | null) => void;
6
+ min?: number;
7
+ max?: number;
8
+ /** Decimals kept; a `currency`'s own by default. */
9
+ fractionDigits?: number;
10
+ currency?: string;
11
+ /** The field holds whole minor units (CurrencyField's `minorUnits`): 1250 is 12.50. */
12
+ minorUnits?: boolean;
13
+ };
14
+ /** The decimals a binding keeps; `undefined` for any number of them. */
15
+ export declare function bindingDigits(o: UseKeypadNumberOptions): number | undefined;
16
+ /** A field number as the keypad's value text; `''` when empty or not a finite number. */
17
+ export declare function numberToText(value: number | null | undefined, o: Pick<UseKeypadNumberOptions, 'minorUnits'> & {
18
+ digits?: number;
19
+ }): string;
20
+ /** The keypad's value text as the field's number: `null` when empty. */
21
+ export declare function textToNumber(text: string, o: Pick<UseKeypadNumberOptions, 'minorUnits'> & {
22
+ digits?: number;
23
+ }): number | null;
24
+ /** The keypad binding of a number held by a field. */
25
+ export declare function numberBinding(o: UseKeypadNumberOptions): KeypadBinding;
26
+ /**
27
+ * The props a keypad runs with: an explicit prop wins over the binding's, both
28
+ * `onValueChange` handlers are called, and the display is off for a bound
29
+ * keypad unless asked for or `operations` are offered (the field shows the
30
+ * number, but not the calculation in progress).
31
+ */
32
+ export declare function resolveBinding(props: KeypadProps): KeypadProps;
@@ -0,0 +1,28 @@
1
+ import { KeypadSettlement } from './keypad.types.js';
2
+ type Format = {
3
+ digits: number | undefined;
4
+ locale?: string;
5
+ currency?: string;
6
+ };
7
+ /** The total, and under it the change or what is still due once something is tendered. */
8
+ export declare function KeypadCashSummary({ total, settlement, digits, locale, currency, }: Format & {
9
+ total: string;
10
+ settlement: KeypadSettlement | undefined;
11
+ }): import("react").JSX.Element;
12
+ /** One-tap tendered amounts: the exact total, then the round amounts above it. */
13
+ export declare function KeypadShortcuts({ amounts, onPick, disabled, digits, locale, currency, }: Format & {
14
+ amounts: readonly string[];
15
+ onPick: (amount: string) => void;
16
+ disabled?: boolean;
17
+ }): import("react").JSX.Element | null;
18
+ /** The cash variant's parts above the keys: the total with its settlement, then the shortcuts. */
19
+ export declare function KeypadCash({ cash, total, onPick, disabled, digits, locale, currency, }: Format & {
20
+ cash: {
21
+ settlement: KeypadSettlement | undefined;
22
+ shortcuts: readonly string[];
23
+ };
24
+ total: string;
25
+ onPick: (amount: string) => void;
26
+ disabled?: boolean;
27
+ }): import("react").JSX.Element;
28
+ export {};
@@ -0,0 +1,11 @@
1
+ import { useKeypad } from './use-keypad.js';
2
+ /** A canonical amount for a locale at fixed decimals, with the currency's symbol when given. */
3
+ export declare function formatAmount(text: string, digits: number | undefined, locale: string | undefined, currency: string | undefined): string;
4
+ type Props = {
5
+ keypad: ReturnType<typeof useKeypad>;
6
+ locale?: string;
7
+ currency?: string;
8
+ };
9
+ /** The amount above the keys; after `=` it is the result, not the expression. */
10
+ export declare function KeypadDisplay({ keypad: k, locale, currency }: Props): import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,39 @@
1
+ import { CalcKey, CalcSession } from '@nxgt/material-core/calculator';
2
+ import { KeypadOperation } from './keypad.types.js';
3
+ export declare const ALL_OPERATIONS: readonly KeypadOperation[];
4
+ /** The operations a keypad offers for its `operations` prop. */
5
+ export declare function operationsOf(operations: boolean | readonly KeypadOperation[] | undefined): readonly KeypadOperation[];
6
+ /** The operations a keypad runs with: none in minor entry nor in the cash variant. */
7
+ export declare function keypadOperations(o: {
8
+ entry?: 'decimal' | 'minor';
9
+ variant?: 'standard' | 'cash';
10
+ operations?: boolean | readonly KeypadOperation[];
11
+ }): readonly KeypadOperation[];
12
+ export declare const operationKey: (o: KeypadOperation) => CalcKey;
13
+ export type EntryConfig = {
14
+ entry: 'decimal' | 'minor';
15
+ /** Decimals kept; `undefined` for any number of them. */
16
+ digits: number | undefined;
17
+ operations: readonly KeypadOperation[];
18
+ max?: number;
19
+ };
20
+ /** A session that holds `value` as typed. */
21
+ export declare function seedSession(value: string): CalcSession;
22
+ /** The value text of a session: the result after `=`, the number typed, `''` mid-calculation. */
23
+ export declare function sessionValue(s: CalcSession): string;
24
+ /** True while the expression is more than one number (a calculation to evaluate). */
25
+ export declare const isPending: (s: CalcSession) => boolean;
26
+ /**
27
+ * One key of a keypad. Pure: the next session comes back, or the same one
28
+ * when the key does nothing here (an operation not offered, a decimal key at
29
+ * no decimals, a digit past `max` or past the decimals kept).
30
+ */
31
+ export declare function pressEntry(s: CalcSession, key: CalcKey, cfg: EntryConfig): CalcSession;
32
+ /** `value` held between `min` and `max` (either may be absent); `''` stays `''`. */
33
+ export declare function clampValue(value: string, min?: number, max?: number): string;
34
+ /**
35
+ * The value to tell the app after a key, or `undefined` when there is nothing
36
+ * to tell: while a calculation waits the field keeps the number it had, and a
37
+ * key that leaves the value as reported says nothing.
38
+ */
39
+ export declare function valueToReport(next: CalcSession, reported: string): string | undefined;
@@ -0,0 +1,27 @@
1
+ import { KeyDef, KeyLayout } from './key-layout.js';
2
+ export type KeypadGridProps = {
3
+ layout: KeyLayout;
4
+ /** The group's accessible name. */
5
+ label: string;
6
+ /** The id of the element that describes the group. */
7
+ describedBy?: string;
8
+ /** What the decimal key draws: the locale's separator. */
9
+ decimal: string;
10
+ /** The face a key shows (the calculator's 2nd page); the key itself by default. */
11
+ faceOf?: (def: KeyDef) => KeyDef;
12
+ /** A key that stays focusable, says so, and presses nothing. */
13
+ unavailable?: (def: KeyDef) => boolean;
14
+ onPress: (def: KeyDef) => void;
15
+ /** The group's `data-slot` and class, then its keys' and panes' (the calculator's by default). */
16
+ slot?: string;
17
+ className?: string;
18
+ keySlot?: string;
19
+ keyClassName?: string;
20
+ paneClassName?: string;
21
+ };
22
+ /**
23
+ * The keys as native buttons in one `role="group"`. The group is one tab
24
+ * stop (a roving tabindex); the arrow keys move over the grid in two
25
+ * dimensions, Home and End along a row, with Ctrl to the first and last key.
26
+ */
27
+ export declare function KeypadGrid({ layout, label, describedBy, decimal, faceOf, unavailable, onPress, slot, className, keySlot, keyClassName, paneClassName, }: KeypadGridProps): import("react").JSX.Element;