@webority/ui-react 0.53.0 → 0.54.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 (110) hide show
  1. package/dist/components/AppActionIcon.js +1 -1
  2. package/dist/components/AppAvatar.js +1 -1
  3. package/dist/components/AppButton.js +1 -1
  4. package/dist/components/AppButtonGroup.js +1 -0
  5. package/dist/components/AppCarousel.js +1 -0
  6. package/dist/components/AppChipGroup.js +1 -0
  7. package/dist/components/AppCodeBlock.js +1 -0
  8. package/dist/components/AppCommandPalette.js +1 -1
  9. package/dist/components/AppCommentThread.js +1 -0
  10. package/dist/components/AppDataTable.js +1 -1
  11. package/dist/components/AppDateRangePicker.js +1 -1
  12. package/dist/components/AppDrawer.js +1 -0
  13. package/dist/components/AppDropdown.js +1 -1
  14. package/dist/components/AppEmptyState.js +1 -1
  15. package/dist/components/AppFilterBar.js +1 -1
  16. package/dist/components/AppHoverCard.js +1 -0
  17. package/dist/components/AppInlineEdit.js +1 -0
  18. package/dist/components/AppInputGroup.js +1 -0
  19. package/dist/components/AppKbd.js +1 -0
  20. package/dist/components/AppLightbox.js +1 -0
  21. package/dist/components/AppMentionInput.js +1 -0
  22. package/dist/components/AppMenubar.js +1 -0
  23. package/dist/components/AppNavigationMenu.js +1 -0
  24. package/dist/components/AppNotificationCenter.js +1 -0
  25. package/dist/components/AppOnboardingChecklist.js +1 -0
  26. package/dist/components/AppRating.js +1 -0
  27. package/dist/components/AppRecordPager.js +1 -0
  28. package/dist/components/AppRelativeTime.js +1 -0
  29. package/dist/components/AppResizable.js +1 -0
  30. package/dist/components/AppResizableHandle.js +1 -0
  31. package/dist/components/AppResizablePanel.js +1 -0
  32. package/dist/components/AppRollingNumber.js +1 -0
  33. package/dist/components/AppSectionCallToAction.js +1 -0
  34. package/dist/components/AppSectionFaq.js +1 -0
  35. package/dist/components/AppSectionFeatures.js +1 -0
  36. package/dist/components/AppSectionHero.js +1 -0
  37. package/dist/components/AppSectionLogos.js +1 -0
  38. package/dist/components/AppSectionPricing.js +1 -0
  39. package/dist/components/AppSectionTestimonials.js +1 -0
  40. package/dist/components/AppShortcutLegend.js +1 -0
  41. package/dist/components/AppShowMore.js +1 -0
  42. package/dist/components/AppSplitButton.js +1 -0
  43. package/dist/components/AppSplitView.js +1 -0
  44. package/dist/components/AppTableEmptyState.js +1 -1
  45. package/dist/components/AppTableToolbar.js +1 -1
  46. package/dist/components/AppTabs.js +1 -1
  47. package/dist/components/AppTooltip.js +1 -1
  48. package/dist/components/AppTruncate.js +1 -0
  49. package/dist/components/AppWhatsNew.js +1 -0
  50. package/dist/components/withTooltip.js +1 -1
  51. package/dist/lib/emptyIllustration.js +1 -0
  52. package/dist/lib/sectionShell.js +1 -0
  53. package/dist/lib/shortcutChip.js +1 -0
  54. package/dist/lib/useListShortcuts.js +1 -0
  55. package/dist/types/components/AppActionIcon.d.ts +4 -1
  56. package/dist/types/components/AppButton.d.ts +2 -1
  57. package/dist/types/components/AppButtonGroup.d.ts +23 -0
  58. package/dist/types/components/AppCarousel.d.ts +52 -0
  59. package/dist/types/components/AppChipGroup.d.ts +22 -0
  60. package/dist/types/components/AppCodeBlock.d.ts +28 -0
  61. package/dist/types/components/AppCommandPalette.d.ts +44 -2
  62. package/dist/types/components/AppCommentThread.d.ts +115 -0
  63. package/dist/types/components/AppDataTable.d.ts +44 -1
  64. package/dist/types/components/AppDateRangePicker.d.ts +5 -0
  65. package/dist/types/components/AppDrawer.d.ts +46 -0
  66. package/dist/types/components/AppDropdown.d.ts +4 -1
  67. package/dist/types/components/AppEmptyState.d.ts +4 -1
  68. package/dist/types/components/AppFilterBar.d.ts +9 -1
  69. package/dist/types/components/AppHoverCard.d.ts +35 -0
  70. package/dist/types/components/AppInlineEdit.d.ts +57 -0
  71. package/dist/types/components/AppInputGroup.d.ts +29 -0
  72. package/dist/types/components/AppKbd.d.ts +15 -0
  73. package/dist/types/components/AppLightbox.d.ts +40 -0
  74. package/dist/types/components/AppMentionInput.d.ts +41 -0
  75. package/dist/types/components/AppMenubar.d.ts +45 -0
  76. package/dist/types/components/AppNavigationMenu.d.ts +41 -0
  77. package/dist/types/components/AppNotificationCenter.d.ts +81 -0
  78. package/dist/types/components/AppOnboardingChecklist.d.ts +48 -0
  79. package/dist/types/components/AppRating.d.ts +48 -0
  80. package/dist/types/components/AppRecordPager.d.ts +38 -0
  81. package/dist/types/components/AppRelativeTime.d.ts +18 -0
  82. package/dist/types/components/AppResizable.d.ts +30 -0
  83. package/dist/types/components/AppResizableHandle.d.ts +13 -0
  84. package/dist/types/components/AppResizablePanel.d.ts +20 -0
  85. package/dist/types/components/AppRollingNumber.d.ts +27 -0
  86. package/dist/types/components/AppSectionCallToAction.d.ts +24 -0
  87. package/dist/types/components/AppSectionFaq.d.ts +28 -0
  88. package/dist/types/components/AppSectionFeatures.d.ts +37 -0
  89. package/dist/types/components/AppSectionHero.d.ts +32 -0
  90. package/dist/types/components/AppSectionLogos.d.ts +36 -0
  91. package/dist/types/components/AppSectionPricing.d.ts +28 -0
  92. package/dist/types/components/AppSectionTestimonials.d.ts +34 -0
  93. package/dist/types/components/AppShortcutLegend.d.ts +34 -0
  94. package/dist/types/components/AppShowMore.d.ts +29 -0
  95. package/dist/types/components/AppSplitButton.d.ts +53 -0
  96. package/dist/types/components/AppSplitView.d.ts +85 -0
  97. package/dist/types/components/AppTableEmptyState.d.ts +4 -1
  98. package/dist/types/components/AppTableToolbar.d.ts +13 -1
  99. package/dist/types/components/AppTabs.d.ts +12 -6
  100. package/dist/types/components/AppTooltip.d.ts +4 -1
  101. package/dist/types/components/AppTruncate.d.ts +21 -0
  102. package/dist/types/components/AppWhatsNew.d.ts +44 -0
  103. package/dist/types/components/withTooltip.d.ts +1 -1
  104. package/dist/types/index.d.ts +37 -0
  105. package/dist/types/lib/emptyIllustration.d.ts +22 -0
  106. package/dist/types/lib/sectionShell.d.ts +43 -0
  107. package/dist/types/lib/shortcutChip.d.ts +11 -0
  108. package/dist/types/lib/useListShortcuts.d.ts +24 -0
  109. package/dist/ui-react.js +1 -1
  110. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- export default function AppButton({ children, variant, size, type, loading, disabled, block, leftIcon, rightIcon, href, static: isStatic, tooltip, tooltipPlacement, className, ...rest }: {
1
+ export default function AppButton({ children, variant, size, type, loading, disabled, block, leftIcon, rightIcon, href, static: isStatic, tooltip, tooltipPlacement, shortcut, className, ...rest }: {
2
2
  [x: string]: any;
3
3
  block?: boolean;
4
4
  children: any;
@@ -8,6 +8,7 @@ export default function AppButton({ children, variant, size, type, loading, disa
8
8
  leftIcon?: any;
9
9
  loading?: boolean;
10
10
  rightIcon?: any;
11
+ shortcut: any;
11
12
  size?: string;
12
13
  static?: boolean;
13
14
  tooltip: any;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Related buttons joined into one control: a view switch, a bulk-action row, a text-style set
3
+ * ("Bold", "Italic"). The buttons touch, share one outline and keep their own variants and
4
+ * handlers; give every button in the group the same `variant` and leave `size` to the group.
5
+ * The group is announced by `label`; each button is still its own tab stop (this is a set of
6
+ * actions, not a single-choice control; for one choice of several use `AppSegmented`).
7
+ *
8
+ * @param {object} props
9
+ * @param {string} props.label Accessible name for the group ("Text style").
10
+ * @param {import('react').ReactNode} props.children `AppButton`s (or button-styled links).
11
+ * @param {'sm'|'md'|'lg'} [props.size='md'] One size for every button in the group.
12
+ * @param {boolean} [props.vertical=false] Stack the buttons top to bottom.
13
+ * @param {boolean} [props.fullWidth=false] Fill the container, the buttons sharing the row equally.
14
+ * @param {string} [props.className]
15
+ */
16
+ export default function AppButtonGroup({ label, children, size, vertical, fullWidth, className, ...rest }: {
17
+ label: string;
18
+ children: import('react').ReactNode;
19
+ size?: 'sm' | 'md' | 'lg';
20
+ vertical?: boolean;
21
+ fullWidth?: boolean;
22
+ className?: string;
23
+ }): import("react").JSX.Element;
@@ -0,0 +1,52 @@
1
+ import "@webority/ui-elements/elements/carousel";
2
+ /**
3
+ * A row of slides you can step through, drag or swipe: previous and next buttons, a dot per page, and
4
+ * optional auto-advance that can always be stopped. Each child is one slide.
5
+ *
6
+ * With `autoplay` it advances every that many milliseconds and shows a visible Pause / Play button
7
+ * before the slides. It holds while the pointer is over it or focus is inside, while the tab is hidden,
8
+ * and not at all when the user prefers reduced motion (the button is hidden then). It wraps to the
9
+ * first slide; the buttons wrap only with `loop`. The slides are named "2 of 5", and the page that
10
+ * comes into view is announced politely when the user, not the autoplay, moved it. The focused slide
11
+ * row also takes Left, Right, Home and End.
12
+ *
13
+ * `perView` shows several slides at once (its `Md` and `Lg` forms apply from those breakpoints), and
14
+ * the dots then stand for pages of slides. Wraps the shared `<wui-carousel>` element, which owns the
15
+ * stepping and the autoplay; the Razor `<app-carousel>` renders the same markup.
16
+ *
17
+ * @param {object} props
18
+ * @param {string} props.label What the slides are ("Customer stories"): the carousel's accessible name.
19
+ * @param {number} [props.autoplay] Milliseconds between automatic steps (5000 is typical). Omit for none.
20
+ * @param {boolean} [props.loop=false] The previous and next buttons wrap around at the ends.
21
+ * @param {number} [props.perView=1] Slides in view on a phone.
22
+ * @param {number} [props.perViewMd] Slides in view from the md breakpoint. Defaults to `perView`.
23
+ * @param {number} [props.perViewLg] Slides in view from the lg breakpoint. Defaults to `perViewMd`.
24
+ * @param {boolean} [props.arrows=true] Show the previous and next buttons.
25
+ * @param {boolean} [props.dots=true] Show the page dots.
26
+ * @param {string} [props.previousLabel="Previous slide"] The previous button's name.
27
+ * @param {string} [props.nextLabel="Next slide"] The next button's name.
28
+ * @param {string} [props.dotLabel="Go to slide"] The words before the slide number in each dot's name.
29
+ * @param {string} [props.pauseLabel="Pause"] The pause button's text and name while playing.
30
+ * @param {string} [props.playLabel="Play"] The pause button's text and name while paused.
31
+ * @param {string} [props.className]
32
+ * @param {import('react').CSSProperties} [props.style] Merged after the per-view custom properties.
33
+ * @param {import('react').ReactNode} props.children The slides.
34
+ */
35
+ export default function AppCarousel({ label, autoplay, loop, perView, perViewMd, perViewLg, arrows, dots, previousLabel, nextLabel, dotLabel, pauseLabel, playLabel, className, children, style, ...rest }: {
36
+ label: string;
37
+ autoplay?: number;
38
+ loop?: boolean;
39
+ perView?: number;
40
+ perViewMd?: number;
41
+ perViewLg?: number;
42
+ arrows?: boolean;
43
+ dots?: boolean;
44
+ previousLabel?: string;
45
+ nextLabel?: string;
46
+ dotLabel?: string;
47
+ pauseLabel?: string;
48
+ playLabel?: string;
49
+ className?: string;
50
+ style?: import('react').CSSProperties;
51
+ children: import('react').ReactNode;
52
+ }): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import "@webority/ui-elements/elements/overflow";
2
+ /**
3
+ * A row of chips (`AppChip`, `AppChoiceChip`) that either wraps onto more lines or, with
4
+ * `overflow="menu"`, keeps one line and moves the chips that do not fit into a More menu
5
+ * (`<wui-overflow>`, which Razor `<app-chip-group>` renders too). Choosing a chip in the menu
6
+ * clicks that chip's own control, so a clickable `AppChip` runs its `onClick` and an
7
+ * `AppChoiceChip` toggles. A chip with no control (static or only removable) is listed greyed out.
8
+ *
9
+ * @param {object} props
10
+ * @param {import('react').ReactNode} props.children The chips.
11
+ * @param {"wrap"|"menu"} [props.overflow="wrap"] `wrap` lets the chips wrap; `menu` moves the extras into a More menu.
12
+ * @param {string} [props.moreLabel="More"] The More button's text when `overflow="menu"`.
13
+ * @param {string} [props.label] Accessible name for the group.
14
+ * @param {string} [props.className]
15
+ */
16
+ export default function AppChipGroup({ children, overflow, moreLabel, label, className, ...rest }: {
17
+ children: import('react').ReactNode;
18
+ overflow?: "wrap" | "menu";
19
+ moreLabel?: string;
20
+ label?: string;
21
+ className?: string;
22
+ }): import("react").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import "@webority/ui-elements/elements/code-block";
2
+ /**
3
+ * Source code with syntax colours (light and dark), a Copy button with a confirmation, optional
4
+ * line numbers and optional wrapping, for docs pages, API keys, webhook payloads and request
5
+ * examples. The colouring is a small built-in tokenizer in `<wui-code-block>`, which Razor
6
+ * `<app-code-block>` renders too; the source is only ever drawn as text, never as HTML. Source
7
+ * beyond 100,000 characters is shown uncoloured. Not an editor: it shows code, it does not edit it.
8
+ *
9
+ * @param {object} props
10
+ * @param {string} props.code The source text. A single trailing newline is dropped.
11
+ * @param {"text"|"json"|"js"|"cs"|"sql"|"bash"|"http"|"html"|"css"} [props.language="text"] What to colour; `text` shows it as written.
12
+ * @param {boolean} [props.lineNumbers=false] Number the lines. The numbers are not copied or selected.
13
+ * @param {boolean} [props.wrap=false] Wrap long lines instead of scrolling sideways.
14
+ * @param {string} [props.label] The header title ("webhook.json") and the code region's accessible name. Without it the header names the language.
15
+ * @param {string} [props.copyLabel="Copy"] The copy button's label.
16
+ * @param {string} [props.copiedLabel="Copied"] The copy button's label for two seconds after a copy.
17
+ * @param {string} [props.className]
18
+ */
19
+ export default function AppCodeBlock({ code, language, lineNumbers, wrap, label, copyLabel, copiedLabel, className, ...rest }: {
20
+ code: string;
21
+ language?: "text" | "json" | "js" | "cs" | "sql" | "bash" | "http" | "html" | "css";
22
+ lineNumbers?: boolean;
23
+ wrap?: boolean;
24
+ label?: string;
25
+ copyLabel?: string;
26
+ copiedLabel?: string;
27
+ className?: string;
28
+ }): import("react").JSX.Element;
@@ -12,6 +12,15 @@ import "@webority/ui-elements/elements/command-palette";
12
12
  * You own the search: `query` is controlled, and `groups` is whatever your search returned
13
13
  * for it. The palette does not filter. Selecting a result calls its `onSelect`, then `onClose`.
14
14
  *
15
+ * Nested pages are controlled the same way. An item with a `page` opens it instead of acting:
16
+ * the palette calls `onPathChange` with the new path and `onQueryChange("")`, and you pass the
17
+ * groups of the page `path` names. A Back button and a breadcrumb appear while the path is not
18
+ * empty; Backspace in an empty search goes back. Reset `path` yourself when you close the palette.
19
+ *
20
+ * With `recentsKey` the palette remembers what was chosen on this device and lists it first, under
21
+ * "Recent", while the search is empty on the first page. Items are remembered by group key and
22
+ * item key, so keep both stable, and only items present in the root `groups` are listed again.
23
+ *
15
24
  * @param {object} props
16
25
  * @param {boolean} props.open
17
26
  * @param {() => void} props.onClose Called on Escape, a backdrop click, and after a selection.
@@ -21,13 +30,28 @@ import "@webority/ui-elements/elements/command-palette";
21
30
  * @param {{ key: string, label: import('react').ReactNode, items: { key: string,
22
31
  * label: import('react').ReactNode, description?: import('react').ReactNode,
23
32
  * icon?: string | import('react').ReactNode, meta?: import('react').ReactNode,
24
- * disabled?: boolean, ariaLabel?: string, onSelect?: () => void }[] }[]} [props.groups=[]]
33
+ * disabled?: boolean, ariaLabel?: string, shortcut?: string,
34
+ * page?: { key: string, label: string }, onSelect?: () => void }[] }[]} [props.groups=[]]
25
35
  * Results, rendered in order under their group headings. Keys must be unique within their
26
36
  * group; groups with no items are left out. `icon` is a library icon name or a node; `meta` is
27
37
  * short trailing text or a node. A `disabled` item is listed but cannot be chosen: the arrow
28
38
  * keys skip it. `ariaLabel` is the option's accessible name, by default a string `label`, so a
29
39
  * screen reader reads the name whole rather than in the pieces the search emphasis splits it
30
40
  * into; give it for a label passed as a node. The description and meta describe the option.
41
+ * `shortcut` is the key that runs the item elsewhere ("N", "Ctrl K"), drawn as a key chip at
42
+ * the end of the row; it is a hint, your page binds the key. `page` makes the item open a
43
+ * nested page ({ key, label }, the label shows in the breadcrumb) instead of calling `onSelect`.
44
+ * @param {{ key: string, label: string }[]} [props.path=[]] The open nested pages, outermost first
45
+ * (controlled). Empty shows the first page.
46
+ * @param {(path: { key: string, label: string }[]) => void} [props.onPathChange] Called with the
47
+ * new path when the user opens a page, presses Back, picks a breadcrumb entry, or presses
48
+ * Backspace in an empty search. The search is cleared with it.
49
+ * @param {string} [props.rootLabel='All'] Breadcrumb text for the first page.
50
+ * @param {string} [props.backLabel='Back'] Accessible name of the Back button.
51
+ * @param {string} [props.recentsKey] localStorage key to remember chosen items under; omit for no
52
+ * recents. Make it per user, for example from the user's public id.
53
+ * @param {number} [props.recentsLimit=5] How many recent items to keep (at most 20).
54
+ * @param {string} [props.recentsLabel='Recent'] Heading of the recent items.
31
55
  * @param {boolean} [props.loading=false] Shows the library spinner in the input.
32
56
  * @param {import('react').ReactNode} [props.emptyText='No results'] Shown when the query is
33
57
  * not blank, nothing is loading, and no group has items.
@@ -38,7 +62,7 @@ import "@webority/ui-elements/elements/command-palette";
38
62
  * @param {string} [props.id] Seeds the result and heading ids; defaults to a generated id.
39
63
  * @param {string} [props.className] Extra classes on the dialog card.
40
64
  */
41
- export default function AppCommandPalette({ open, onClose, query, onQueryChange, placeholder, groups, loading, emptyText, footer, ariaLabel, highlight, id, className, ...rest }: {
65
+ export default function AppCommandPalette({ open, onClose, query, onQueryChange, placeholder, groups, path, onPathChange, rootLabel, backLabel, recentsKey, recentsLimit, recentsLabel, loading, emptyText, footer, ariaLabel, highlight, id, className, ...rest }: {
42
66
  open: boolean;
43
67
  onClose: () => void;
44
68
  query?: string;
@@ -55,9 +79,27 @@ export default function AppCommandPalette({ open, onClose, query, onQueryChange,
55
79
  meta?: import('react').ReactNode;
56
80
  disabled?: boolean;
57
81
  ariaLabel?: string;
82
+ shortcut?: string;
83
+ page?: {
84
+ key: string;
85
+ label: string;
86
+ };
58
87
  onSelect?: () => void;
59
88
  }[];
60
89
  }[];
90
+ path?: {
91
+ key: string;
92
+ label: string;
93
+ }[];
94
+ onPathChange?: (path: {
95
+ key: string;
96
+ label: string;
97
+ }[]) => void;
98
+ rootLabel?: string;
99
+ backLabel?: string;
100
+ recentsKey?: string;
101
+ recentsLimit?: number;
102
+ recentsLabel?: string;
61
103
  loading?: boolean;
62
104
  emptyText?: import('react').ReactNode;
63
105
  footer?: import('react').ReactNode;
@@ -0,0 +1,115 @@
1
+ export type CommentThreadItem = {
2
+ /**
3
+ * The comment's public id.
4
+ */
5
+ id: string;
6
+ /**
7
+ * Who wrote it; `src` is a photo URL.
8
+ */
9
+ author: {
10
+ name: string;
11
+ src?: string;
12
+ };
13
+ /**
14
+ * When it was written: an ISO instant with its zone, epoch ms or a Date. Shown in IST.
15
+ */
16
+ at: string | number | Date;
17
+ /**
18
+ * The stored body, with mentions as `@[Label](id)`.
19
+ */
20
+ value?: string;
21
+ /**
22
+ * Shows "Edited" beside the time.
23
+ */
24
+ edited?: boolean;
25
+ /**
26
+ * Shows "This comment was deleted." in place of the body; replies stay.
27
+ */
28
+ deleted?: boolean;
29
+ /**
30
+ * This person may edit it.
31
+ */
32
+ canEdit?: boolean;
33
+ /**
34
+ * This person may delete it.
35
+ */
36
+ canDelete?: boolean;
37
+ reactions?: {
38
+ emoji: string;
39
+ count: number;
40
+ mine?: boolean;
41
+ }[];
42
+ /**
43
+ * Replies, oldest first. Replies to a reply are not nested.
44
+ */
45
+ replies?: CommentThreadItem[];
46
+ };
47
+ /**
48
+ * A discussion: comments with their author, time in IST, replies one level deep, reactions and
49
+ * mentions. People reply, edit and delete in place (Delete asks first), react from a small panel,
50
+ * and write with "@" to mention someone (see `AppMentionInput`). Ctrl or Cmd+Enter sends a box,
51
+ * Escape closes it and returns focus. Changes are announced to screen readers.
52
+ *
53
+ * The comments are yours: each callback persists a change and the thread waits for it, then you
54
+ * pass the updated `comments` back. Throw (or reject) with a message written for the person and it
55
+ * shows where they acted. Bodies are stored mention values (`Thanks @[Asha Rao](u-12)`) and always
56
+ * render as text, never HTML.
57
+ *
58
+ * Wraps the shared `<wui-comment-thread>` element, which owns the boxes, keys and states; Razor
59
+ * `<app-comment-thread>` renders the same markup.
60
+ *
61
+ * @typedef {object} CommentThreadItem
62
+ * @property {string} id The comment's public id.
63
+ * @property {{ name: string, src?: string }} author Who wrote it; `src` is a photo URL.
64
+ * @property {string | number | Date} at When it was written: an ISO instant with its zone, epoch ms or a Date. Shown in IST.
65
+ * @property {string} [value] The stored body, with mentions as `@[Label](id)`.
66
+ * @property {boolean} [edited] Shows "Edited" beside the time.
67
+ * @property {boolean} [deleted] Shows "This comment was deleted." in place of the body; replies stay.
68
+ * @property {boolean} [canEdit] This person may edit it.
69
+ * @property {boolean} [canDelete] This person may delete it.
70
+ * @property {{ emoji: string, count: number, mine?: boolean }[]} [reactions]
71
+ * @property {CommentThreadItem[]} [replies] Replies, oldest first. Replies to a reply are not nested.
72
+ *
73
+ * @param {object} props
74
+ * @param {CommentThreadItem[]} [props.comments] Top-level comments, oldest first.
75
+ * @param {(body: string) => unknown | Promise<unknown>} [props.onPost] A new comment.
76
+ * @param {(parentId: string, body: string) => unknown | Promise<unknown>} [props.onReply]
77
+ * @param {(commentId: string, body: string) => unknown | Promise<unknown>} [props.onEdit]
78
+ * @param {(commentId: string) => unknown | Promise<unknown>} [props.onDelete]
79
+ * @param {(commentId: string, emoji: string) => unknown | Promise<unknown>} [props.onReact] Toggle
80
+ * this person's reaction.
81
+ * @param {{ value: string, label: string, description?: string, src?: string }[]} [props.people]
82
+ * The people the boxes offer after "@".
83
+ * @param {(query: string) => Promise<{ value: string, label: string, description?: string, src?: string }[]>} [props.loadPeople]
84
+ * Look people up instead of `people`.
85
+ * @param {string[]} [props.reactionChoices] The reactions the panel offers (default 👍 ❤️ 🎉 😄 👀 🙏).
86
+ * @param {boolean} [props.readOnly=false] Show the thread without the box, actions or reacting.
87
+ * @param {string} [props.label="Comments"] The list's accessible name.
88
+ * @param {string} [props.id] The root's id. Generated when omitted.
89
+ * @param {string} [props.className] Extra classes on the root.
90
+ */
91
+ export default function AppCommentThread({ comments, onPost, onReply, onEdit, onDelete, onReact, people, loadPeople, reactionChoices, readOnly, label, id, className, ...rest }: {
92
+ comments?: CommentThreadItem[];
93
+ onPost?: (body: string) => unknown | Promise<unknown>;
94
+ onReply?: (parentId: string, body: string) => unknown | Promise<unknown>;
95
+ onEdit?: (commentId: string, body: string) => unknown | Promise<unknown>;
96
+ onDelete?: (commentId: string) => unknown | Promise<unknown>;
97
+ onReact?: (commentId: string, emoji: string) => unknown | Promise<unknown>;
98
+ people?: {
99
+ value: string;
100
+ label: string;
101
+ description?: string;
102
+ src?: string;
103
+ }[];
104
+ loadPeople?: (query: string) => Promise<{
105
+ value: string;
106
+ label: string;
107
+ description?: string;
108
+ src?: string;
109
+ }[]>;
110
+ reactionChoices?: string[];
111
+ readOnly?: boolean;
112
+ label?: string;
113
+ id?: string;
114
+ className?: string;
115
+ }): import("react").JSX.Element;
@@ -48,14 +48,48 @@
48
48
  * on it, for in-page actions (open a drawer). Same nested-control rule as rowHref.
49
49
  * @param {(row: object) => 'success'|'warning'|'danger'|'info'|undefined} [props.rowStatus] A coloured
50
50
  * bar on the row's leading edge, e.g. danger for an overdue invoice. Undefined draws none.
51
+ * @param {string|number} [props.activeRowKey] The key (what `rowKey` returns) of the row whose record is
52
+ * open, e.g. in a detail pane beside the table. That row gets `aria-current="true"` and the subtle
53
+ * primary background; it is separate from `rowStatus`'s edge bar and from selected (checkbox) rows.
54
+ * Razor: `active-row-key` against each row's `data-row-key`.
51
55
  * @param {boolean} [props.selectable=false] Render a leading checkbox column.
52
56
  * @param {Set<string|number>} [props.selectedIds] Currently selected row keys.
53
57
  * @param {(id: string|number) => void} [props.onToggleRow]
54
58
  * @param {(checked: boolean) => void} [props.onToggleAll] Toggle all current rows.
59
+ * @param {(keys: Array<string|number>, checked: boolean) => void} [props.onSelectRange] Shift+click on a row
60
+ * checkbox selects (or clears) every row from the last clicked one to this one; this receives the keys
61
+ * of the other rows that change. Without it, `onToggleRow` is called once per key, so it must be safe
62
+ * to call several times in a row (a functional state update). Razor: built in.
55
63
  * @param {(row: object) => import('react').ReactNode} [props.renderExpanded] When given, each row
56
64
  * gets a leading expand toggle; the returned content renders in a full-width row beneath it.
65
+ * @param {boolean} [props.resizableColumns=false] Each column but the last gets a handle on its end edge:
66
+ * drag it, or focus it and press the arrow keys (Shift for bigger steps, Home or a double-click to
67
+ * undo). The table then keeps fixed widths measured from its rows, and the last column takes the rest.
68
+ * Razor: `resizable-columns`.
69
+ * @param {string} [props.viewKey] Remembers resized widths in this browser under this name (the same name
70
+ * `useTableView` takes). Razor: `view-key`, with `data-key` on each header cell.
71
+ * @param {string} [props.groupBy] A column key: rows gather under a header row per value of it, in the
72
+ * order each value first appears (sort within groups by sorting `rows`), each header collapsing its
73
+ * rows and showing their count. Razor: `group-by`, against the header cells' `data-key`.
74
+ * @param {(value: unknown, rows: object[]) => import('react').ReactNode} [props.groupLabel] A group
75
+ * header's label; without it the value shows as a cell would.
76
+ * @param {boolean} [props.virtual=false] Renders only the rows in view (plus a margin) for a long
77
+ * client-side list. Needs `maxHeight`; rows are taken to share one height, so it is not for
78
+ * `renderExpanded` or `stackOnMobile`. Razor: `virtual`.
79
+ * @param {(row: object) => boolean} [props.rowSaving] True while the row's add or change is on its way to
80
+ * the server: the row shows at once, tinted and marked busy, instead of waiting for the answer. Put an
81
+ * added row in `rows` straight away with this true (give it its final key if you can, so the outcome is
82
+ * announced). Razor: `data-wui-save-state="saving"` on the <tr>, or a server table's `saveRow`.
83
+ * @param {(row: object) => string|undefined} [props.rowSaveError] Why the row's last save failed: the row
84
+ * shows the error look with this line under its first cell. Put a changed row's old values back in `rows`
85
+ * as you set it, so the row shows what is really saved; keep a failed added row until the person retries
86
+ * or removes it. When a row leaves `rowSaving`, screen readers hear "Ana Rao saved." or "Ana Rao was not
87
+ * saved. <reason>" (the name is the first column's value). Razor: `data-wui-save-state="error"`.
88
+ *
89
+ * A sort or reorder of up to 200 rows glides each row to its new place; not under reduced motion, and not
90
+ * on a `virtual` table.
57
91
  */
58
- export default function AppDataTable({ columns, rows, rowKey, sort, onSort, loading, skeletonRows, empty, emptyFiltered, sourceCount, rowActions, rowActionsLabel, pagination, ariaLabel, className, wrapperClassName, selectable, selectedIds, onToggleRow, onToggleAll, renderExpanded, density, striped, maxHeight, stickyFirstColumn, stickyActions, stackOnMobile, hiddenColumns, rowStatus, rowHref, onRowClick, ...rest }: {
92
+ export default function AppDataTable({ columns, rows, rowKey, sort, onSort, loading, skeletonRows, empty, emptyFiltered, sourceCount, rowActions, rowActionsLabel, pagination, ariaLabel, className, wrapperClassName, selectable, selectedIds, onToggleRow, onToggleAll, onSelectRange, renderExpanded, density, striped, maxHeight, stickyFirstColumn, stickyActions, stackOnMobile, hiddenColumns, rowStatus, rowHref, onRowClick, activeRowKey, resizableColumns, viewKey, groupBy, groupLabel, virtual, rowSaving, rowSaveError, ...rest }: {
59
93
  columns: object[];
60
94
  rows: object[];
61
95
  rowKey?: (row: object, index: number) => string | number;
@@ -85,9 +119,18 @@ export default function AppDataTable({ columns, rows, rowKey, sort, onSort, load
85
119
  rowHref?: (row: object) => string;
86
120
  onRowClick?: (row: object) => void;
87
121
  rowStatus?: (row: object) => 'success' | 'warning' | 'danger' | 'info' | undefined;
122
+ activeRowKey?: string | number;
88
123
  selectable?: boolean;
89
124
  selectedIds?: Set<string | number>;
90
125
  onToggleRow?: (id: string | number) => void;
91
126
  onToggleAll?: (checked: boolean) => void;
127
+ onSelectRange?: (keys: Array<string | number>, checked: boolean) => void;
92
128
  renderExpanded?: (row: object) => import('react').ReactNode;
129
+ resizableColumns?: boolean;
130
+ viewKey?: string;
131
+ groupBy?: string;
132
+ groupLabel?: (value: unknown, rows: object[]) => import('react').ReactNode;
133
+ virtual?: boolean;
134
+ rowSaving?: (row: object) => boolean;
135
+ rowSaveError?: (row: object) => string | undefined;
93
136
  }): import("react").JSX.Element;
@@ -25,6 +25,11 @@ import "@webority/ui-elements/elements/date-range";
25
25
  * @param {'sm'|'md'|'lg'} [props.size] Control height tier, matching AppInput.
26
26
  * @param {0|1|2|3|4|5|6} [props.firstDay] First weekday of the calendar, 0 Sunday to 6 Saturday. Unset, it
27
27
  * follows the theme's `--wui-first-day` token, which is 1 (Monday) unless the product sets it.
28
+ * @param {(('today'|'last7Days'|'thisMonth'|'lastMonth'|'thisFinancialYear')|{ label: string, start: string, end: string })[]} [props.presets]
29
+ * Quick ranges, listed beside the calendar (above it on a phone); picking one fills the range and
30
+ * closes the calendar. An item is a name, resolved against today in IST (`thisFinancialYear` runs
31
+ * 1 April to 31 March; `thisMonth` and `lastMonth` span the whole month), or `{ label, start, end }`
32
+ * with ISO dates. A preset outside `min`/`max` is disabled.
28
33
  * @param {string} [props.id]
29
34
  * @param {string} [props.ariaLabel]
30
35
  * @param {string} [props.className] Class to apply to the control element.
@@ -0,0 +1,46 @@
1
+ import "@webority/ui-elements/elements/drawer";
2
+ /**
3
+ * A panel over the page that is a side drawer from md up and a bottom sheet below it. The sheet
4
+ * rests on `snapPoints` (percent of the screen height), follows a finger on its handle or header,
5
+ * flicks to the next point and is dragged down to close; its handle is a vertical slider the arrow
6
+ * keys, Home and End also move. Focus moves in on open, Tab stays inside, Escape closes, and
7
+ * focus returns to what opened it. Controlled: set `open` and close it in `onClose`. Distinct from
8
+ * `AppModal`, which is a centred dialog on every screen. Wraps `<wui-drawer>`, which Razor
9
+ * `<app-drawer>` renders too. Place it where no ancestor has a transform, since it is fixed to the
10
+ * viewport.
11
+ *
12
+ * @param {object} props
13
+ * @param {boolean} [props.open=false]
14
+ * @param {() => void} [props.onClose] Called when the backdrop, Escape, the close button or a drag
15
+ * down asks to close it. It stays open until `open` becomes false.
16
+ * @param {string} [props.title] The heading, and the dialog's accessible name.
17
+ * @param {string} [props.subtitle] A line under the title.
18
+ * @param {string} [props.ariaLabel] The dialog's accessible name when there is no `title`.
19
+ * @param {'end'|'start'} [props.side="end"] Which edge the side drawer slides from.
20
+ * @param {'sm'|'md'|'lg'} [props.size="md"] The side drawer's width: 360, 480 or 640 px.
21
+ * @param {number[]} [props.snapPoints=[50, 90]] The sheet's resting heights, each 10 to 100 percent of the screen.
22
+ * @param {number} [props.defaultSnap=0] Which of the sorted snap points it opens on.
23
+ * @param {(index: number, percent: number) => void} [props.onSnapChange] Called when the sheet moves to another point.
24
+ * @param {boolean} [props.dismissible=true] Show the close button.
25
+ * @param {boolean} [props.staticBackdrop=false] The backdrop, Escape and a drag down no longer close it; only the close button or `open` can.
26
+ * @param {import('react').ReactNode} [props.footer] Pinned below the scrolling body.
27
+ * @param {string} [props.className]
28
+ * @param {import('react').ReactNode} props.children
29
+ */
30
+ export default function AppDrawer({ open, onClose, title, subtitle, ariaLabel, side, size, snapPoints, defaultSnap, onSnapChange, dismissible, staticBackdrop, footer, className, children, ...rest }: {
31
+ open?: boolean;
32
+ onClose?: () => void;
33
+ title?: string;
34
+ subtitle?: string;
35
+ ariaLabel?: string;
36
+ side?: 'end' | 'start';
37
+ size?: 'sm' | 'md' | 'lg';
38
+ snapPoints?: number[];
39
+ defaultSnap?: number;
40
+ onSnapChange?: (index: number, percent: number) => void;
41
+ dismissible?: boolean;
42
+ staticBackdrop?: boolean;
43
+ footer?: import('react').ReactNode;
44
+ className?: string;
45
+ children: import('react').ReactNode;
46
+ }): import("react").JSX.Element;
@@ -15,8 +15,10 @@
15
15
  * @param {string} [props.label] Tooltip + accessible-name fallback for the toggle.
16
16
  * @param {"start"|"end"} [props.align="end"] Menu alignment.
17
17
  * @param {string} [props.ariaLabel]
18
- * @param {{ key: string, label?: string, icon?: string|import('react').ReactNode, image?: string, to?: string, onClick?: () => void, danger?: boolean, divider?: true }[]} [props.items]
18
+ * @param {{ key: string, label?: string, icon?: string|import('react').ReactNode, image?: string, to?: string, onClick?: () => void, danger?: boolean, shortcut?: string, divider?: true }[]} [props.items]
19
19
  * `icon` is a glyph name OR a custom node (e.g. an iconsax glyph); `image` is a picture URL (external logo/avatar) — pass one.
20
+ * `shortcut` is the key that runs the item ("E"), drawn as a key chip at the end of the row; the
21
+ * page binds the key itself (useListShortcuts).
20
22
  * An item with `divider: true` renders a separator instead of an action; it needs no
21
23
  * `label`/`onClick`, just a unique `key`.
22
24
  * @param {string} [props.menuClassName]
@@ -53,6 +55,7 @@ export default function AppDropdown({ icon, iconSize, toggleClassName, label, ar
53
55
  to?: string;
54
56
  onClick?: () => void;
55
57
  danger?: boolean;
58
+ shortcut?: string;
56
59
  divider?: true;
57
60
  }[];
58
61
  menuClassName?: string;
@@ -11,6 +11,8 @@
11
11
  *
12
12
  * @param {object} props
13
13
  * @param {string|import('react').ReactNode} props.icon Semantic icon name for the bubble, or a custom node
14
+ * @param {"no-results"|"no-data"|"empty-inbox"|"no-notifications"|"no-files"|"no-access"|"offline"|"error"} [props.illustration]
15
+ * Decorative drawing by name, in theme colours. Replaces the icon bubble when set.
14
16
  * @param {number} [props.iconSize=24]
15
17
  * @param {"md"|"sm"} [props.size="md"]
16
18
  * @param {import('react').ReactNode} props.title
@@ -19,8 +21,9 @@
19
21
  * @param {string} [props.className]
20
22
  * @param {import('react').CSSProperties} [props.style]
21
23
  */
22
- export default function AppEmptyState({ icon, iconSize, size, title, text, action, className, style, ...rest }: {
24
+ export default function AppEmptyState({ icon, illustration, iconSize, size, title, text, action, className, style, ...rest }: {
23
25
  icon: string | import('react').ReactNode;
26
+ illustration?: "no-results" | "no-data" | "empty-inbox" | "no-notifications" | "no-files" | "no-access" | "offline" | "error";
24
27
  iconSize?: number;
25
28
  size?: "md" | "sm";
26
29
  title: import('react').ReactNode;
@@ -10,6 +10,12 @@
10
10
  * and clears itself. The controls, chips and Clear all share one row, the search box wider and
11
11
  * selects and date ranges narrow; it wraps only when full, and each facet takes its own line on a phone.
12
12
  *
13
+ * Only the first `inline` facets sit in the row. The rest go in a panel behind a "Filters (n)" button,
14
+ * n counting the active ones among them (no number while none is active); their chips stay in the row.
15
+ * The panel is a `<details>` that closes on an outside click or Escape. On a phone every facet folds
16
+ * into that one button and the panel becomes a sheet from the bottom edge. The button and Clear all
17
+ * never wrap.
18
+ *
13
19
  * @param {object} props
14
20
  * @param {{ key: string, label: string, type: 'enum'|'multiEnum'|'dateRange'|'text',
15
21
  * options?: { value: string, label: string }[] }[]} props.facets `options` fills an `enum` or `multiEnum`;
@@ -17,9 +23,10 @@
17
23
  * @param {Record<string, string|string[]|{ from: string, to: string }>} props.value The current filters.
18
24
  * @param {(key: string, value: string|string[]|{ from: string, to: string }) => void} props.onChange
19
25
  * Called with the facet key and its new value. Clear all calls it once per active facet, with the empty value.
26
+ * @param {number} [props.inline=3] How many facets stay in the row; the rest fold into the Filters button.
20
27
  * @param {string} [props.className]
21
28
  */
22
- export default function AppFilterBar({ facets: allFacets, value, onChange, className, ...rest }: {
29
+ export default function AppFilterBar({ facets: allFacets, value, onChange, inline, className, ...rest }: {
23
30
  facets: {
24
31
  key: string;
25
32
  label: string;
@@ -37,5 +44,6 @@ export default function AppFilterBar({ facets: allFacets, value, onChange, class
37
44
  from: string;
38
45
  to: string;
39
46
  }) => void;
47
+ inline?: number;
40
48
  className?: string;
41
49
  }): import("react").JSX.Element;
@@ -0,0 +1,35 @@
1
+ import "@webority/ui-elements/elements/hover-card";
2
+ /**
3
+ * A small preview card that opens beside a name or record link: who someone is, a record's status,
4
+ * without opening the record. It opens after `openDelay` ms of mouse hover or when the trigger takes
5
+ * keyboard focus, and closes `closeDelay` ms after the pointer or focus leaves the trigger and the
6
+ * card (the pointer can cross into the card to read or click inside it). Escape closes it. Touch
7
+ * never opens it, so the trigger must itself lead to the same information (a link to the record).
8
+ * Distinct from `AppPopover` (opened by a click, for a panel of actions) and `AppTooltip` (one line of
9
+ * text, no interactive content). Wraps `<wui-hover-card>`, which Razor `<app-hover-card>` renders too.
10
+ *
11
+ * @param {object} props
12
+ * @param {import('react').ReactNode} props.trigger The name or link the card belongs to. Make it a link
13
+ * or button so keyboard users can focus it.
14
+ * @param {import('react').ReactNode} [props.children] The card's content. The card is phrasing content, so it can
15
+ * sit on a name inside a sentence; there, build the content from spans (a `<div>` cannot be inside a `<p>`).
16
+ * @param {boolean} [props.loading=false] Shows a spinner and `loadingLabel` in place of the children while
17
+ * the preview is fetched; open the fetch from `onOpenChange`.
18
+ * @param {string} [props.loadingLabel="Loading"] The text beside the spinner.
19
+ * @param {string} [props.label] The card's accessible name ("Asha Verma, profile").
20
+ * @param {number} [props.openDelay=300] Milliseconds of hover or focus before it opens.
21
+ * @param {number} [props.closeDelay=150] Milliseconds after leaving before it closes.
22
+ * @param {(open: boolean) => void} [props.onOpenChange] Called when the card opens or closes.
23
+ * @param {string} [props.className]
24
+ */
25
+ export default function AppHoverCard({ trigger, children, loading, loadingLabel, label, openDelay, closeDelay, onOpenChange, className, ...rest }: {
26
+ trigger: import('react').ReactNode;
27
+ children?: import('react').ReactNode;
28
+ loading?: boolean;
29
+ loadingLabel?: string;
30
+ label?: string;
31
+ openDelay?: number;
32
+ closeDelay?: number;
33
+ onOpenChange?: (open: boolean) => void;
34
+ className?: string;
35
+ }): import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ import "@webority/ui-elements/elements/datepicker";
2
+ import "@webority/ui-elements/elements/select";
3
+ /**
4
+ * One value edited where it is shown: a table cell or a fact on a detail page. It reads as plain
5
+ * text with a pencil on hover and focus; a click or Enter turns it into the matching library control
6
+ * (a text or number input, a textarea, a select or a date picker, whose list opens at once).
7
+ *
8
+ * Enter saves a text or number, Ctrl or Cmd+Enter a textarea, picking saves a select or date, and
9
+ * leaving the control saves whatever it holds; Escape cancels. An unchanged value closes without
10
+ * saving. While `onSave` runs the new value shows with a spinner, then a tick for two seconds; a
11
+ * rejection puts the old value back and shows the rejection's message under it (so write it for the
12
+ * person editing), and the next edit starts from the value that failed. Saved and failed are
13
+ * announced to screen readers.
14
+ *
15
+ * Inside an `AppDataTable` row that opens on click or Enter, clicks and keys on the value never
16
+ * reach the row.
17
+ *
18
+ * Wraps the shared `<wui-inline-edit>` element, which owns the editing, the keys and the states;
19
+ * the Razor `<app-inline-edit>` renders the same markup.
20
+ *
21
+ * @param {object} props
22
+ * @param {string | number | null} [props.value] The saved value. A date is `yyyy-MM-dd`; a select
23
+ * value is one of the `options` values.
24
+ * @param {(next: string | number | null) => void | Promise<unknown>} [props.onSave] Persist the new
25
+ * value. A number field passes a number (null when cleared); the others pass a string. Reject to
26
+ * refuse it: the rejection's message is shown.
27
+ * @param {'text'|'number'|'select'|'date'|'textarea'} [props.type='text'] The control it turns into.
28
+ * @param {{ value: string | number, label: string }[]} [props.options] The choices of a select.
29
+ * @param {string} props.label What the value is ("Owner"): the accessible name of the value and
30
+ * the control, and the subject of what screen readers hear ("Owner saved.").
31
+ * @param {string} [props.placeholder] Shown, muted, when there is no value, and in the empty
32
+ * control. Without it an empty value shows a hyphen.
33
+ * @param {(next: string | number | null) => string | null | undefined} [props.validate] Checked
34
+ * before saving: return a message to keep the control open with that message, or nothing to save.
35
+ * @param {(value: string | number | null) => import('react').ReactNode} [props.renderValue] How a
36
+ * saved, non-empty value reads (a formatted amount, a status badge). Text and markup only: the
37
+ * value is a button, so it must not hold its own controls or links.
38
+ * @param {boolean} [props.disabled=false] Show the value without the edit affordance.
39
+ * @param {string} [props.className] Extra classes on the root element.
40
+ * @param {string} [props.id] The root's id; the control and error ids derive from it. Generated when omitted.
41
+ */
42
+ export default function AppInlineEdit({ value, onSave, type, options, label, placeholder, validate, renderValue, disabled, className, id, ...rest }: {
43
+ value?: string | number | null;
44
+ onSave?: (next: string | number | null) => void | Promise<unknown>;
45
+ type?: 'text' | 'number' | 'select' | 'date' | 'textarea';
46
+ options?: {
47
+ value: string | number;
48
+ label: string;
49
+ }[];
50
+ label: string;
51
+ placeholder?: string;
52
+ validate?: (next: string | number | null) => string | null | undefined;
53
+ renderValue?: (value: string | number | null) => import('react').ReactNode;
54
+ disabled?: boolean;
55
+ className?: string;
56
+ id?: string;
57
+ }): import("react").JSX.Element;