@webority/ui-react 0.107.0 → 0.108.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 (195) hide show
  1. package/dist/canvas-kit/kit.js +26159 -26822
  2. package/dist/canvas-kit/manifest.json +1130 -1695
  3. package/dist/canvas-kit/release.json +6 -6
  4. package/dist/components/AppAccordion.js +1 -1
  5. package/dist/components/AppActionIcon.js +1 -1
  6. package/dist/components/AppAlert.js +1 -1
  7. package/dist/components/AppAsyncBlock.js +1 -1
  8. package/dist/components/AppAutocomplete.js +1 -1
  9. package/dist/components/AppAvatar.js +1 -1
  10. package/dist/components/AppAvatarGroup.js +1 -1
  11. package/dist/components/AppBadge.js +1 -1
  12. package/dist/components/AppBanner.js +1 -1
  13. package/dist/components/AppBreadcrumbs.js +1 -1
  14. package/dist/components/AppButton.js +1 -1
  15. package/dist/components/AppButtonGroup.js +1 -1
  16. package/dist/components/AppCalendar.js +1 -1
  17. package/dist/components/AppCard.js +1 -1
  18. package/dist/components/AppCarousel.js +1 -1
  19. package/dist/components/AppChart.js +1 -1
  20. package/dist/components/AppChartCard.js +1 -1
  21. package/dist/components/AppCheckbox.js +1 -1
  22. package/dist/components/AppChip.js +1 -1
  23. package/dist/components/AppChipGroup.js +1 -1
  24. package/dist/components/AppChoiceCard.js +1 -1
  25. package/dist/components/AppChoiceChip.js +1 -1
  26. package/dist/components/AppCodeBlock.js +1 -1
  27. package/dist/components/AppColorField.js +1 -1
  28. package/dist/components/AppColumnMenu.js +1 -1
  29. package/dist/components/AppCommandPalette.js +1 -1
  30. package/dist/components/AppCommentThread.js +1 -1
  31. package/dist/components/AppCompareTable.js +1 -1
  32. package/dist/components/AppConfirmDialog.js +1 -1
  33. package/dist/components/AppConsentBanner.js +1 -1
  34. package/dist/components/AppContextMenu.js +1 -1
  35. package/dist/components/AppCopyButton.js +1 -1
  36. package/dist/components/AppCountryFlag.js +1 -1
  37. package/dist/components/AppCountrySelect.js +1 -1
  38. package/dist/components/AppDashboardCell.js +1 -1
  39. package/dist/components/AppDashboardGrid.js +1 -1
  40. package/dist/components/AppDataTable.js +1 -1
  41. package/dist/components/AppDatePicker.js +1 -1
  42. package/dist/components/AppDateRangePicker.js +1 -1
  43. package/dist/components/AppDescriptions.js +1 -1
  44. package/dist/components/AppDetailPane.js +1 -1
  45. package/dist/components/AppDrawer.js +1 -1
  46. package/dist/components/AppDropZone.js +1 -1
  47. package/dist/components/AppDropdown.js +1 -1
  48. package/dist/components/AppDueDate.js +1 -1
  49. package/dist/components/AppEmptyState.js +1 -1
  50. package/dist/components/AppErrorSummary.js +1 -1
  51. package/dist/components/AppFileAttachment.js +1 -1
  52. package/dist/components/AppFilePicker.js +1 -1
  53. package/dist/components/AppFileTiles.js +1 -1
  54. package/dist/components/AppFileViewer.js +1 -1
  55. package/dist/components/AppFilterBar.js +1 -1
  56. package/dist/components/AppFloatingDock.js +1 -1
  57. package/dist/components/AppFormActions.js +1 -1
  58. package/dist/components/AppFormRow.js +1 -1
  59. package/dist/components/AppFormSection.js +1 -1
  60. package/dist/components/AppHoverCard.js +1 -1
  61. package/dist/components/AppIcon.js +1 -1
  62. package/dist/components/AppImagePicker.js +1 -0
  63. package/dist/components/AppInfoTip.js +1 -1
  64. package/dist/components/AppInlineEdit.js +1 -1
  65. package/dist/components/AppInput.js +1 -1
  66. package/dist/components/AppInputGroup.js +1 -1
  67. package/dist/components/AppKanban.js +1 -1
  68. package/dist/components/AppKbd.js +1 -1
  69. package/dist/components/AppKpiTile.js +1 -1
  70. package/dist/components/AppLightbox.js +1 -1
  71. package/dist/components/AppLink.js +1 -1
  72. package/dist/components/AppMarkdown.js +1 -1
  73. package/dist/components/AppMentionInput.js +1 -1
  74. package/dist/components/AppMeter.js +1 -1
  75. package/dist/components/AppMetricStrip.js +1 -1
  76. package/dist/components/AppModal.js +1 -1
  77. package/dist/components/AppMultiSelect.js +1 -1
  78. package/dist/components/AppNavList.js +1 -1
  79. package/dist/components/AppNavigationMenu.js +1 -1
  80. package/dist/components/AppNotificationCenter.js +1 -1
  81. package/dist/components/AppNumberInput.js +1 -1
  82. package/dist/components/AppOnboardingChecklist.js +1 -1
  83. package/dist/components/AppOtpInput.js +1 -1
  84. package/dist/components/AppPageHeader.js +1 -1
  85. package/dist/components/AppPhoneNumberInput.js +1 -1
  86. package/dist/components/AppPricingCard.js +1 -1
  87. package/dist/components/AppProgress.js +1 -1
  88. package/dist/components/AppQrCode.js +1 -1
  89. package/dist/components/AppRadio.js +1 -1
  90. package/dist/components/AppRadioGroup.js +1 -1
  91. package/dist/components/AppRating.js +1 -1
  92. package/dist/components/AppRecordPager.js +1 -1
  93. package/dist/components/AppRelativeTime.js +1 -1
  94. package/dist/components/AppRepeater.js +1 -1
  95. package/dist/components/AppResizable.js +1 -1
  96. package/dist/components/AppResizableHandle.js +1 -1
  97. package/dist/components/AppResizablePanel.js +1 -1
  98. package/dist/components/AppResourceCard.js +1 -1
  99. package/dist/components/AppResult.js +1 -1
  100. package/dist/components/AppRichText.js +1 -1
  101. package/dist/components/AppRollingNumber.js +1 -1
  102. package/dist/components/AppRouteError.js +1 -1
  103. package/dist/components/AppScrollbar.js +1 -1
  104. package/dist/components/AppSearch.js +1 -1
  105. package/dist/components/AppSectionCallToAction.js +1 -1
  106. package/dist/components/AppSectionFaq.js +1 -1
  107. package/dist/components/AppSectionFeatures.js +1 -1
  108. package/dist/components/AppSectionHero.js +1 -1
  109. package/dist/components/AppSectionLeadCapture.js +1 -0
  110. package/dist/components/AppSectionLogos.js +1 -1
  111. package/dist/components/AppSectionPricing.js +1 -1
  112. package/dist/components/AppSectionTestimonials.js +1 -1
  113. package/dist/components/AppSegmented.js +1 -1
  114. package/dist/components/AppSelect.js +1 -1
  115. package/dist/components/AppSeoHead.js +1 -0
  116. package/dist/components/AppShell.js +1 -1
  117. package/dist/components/AppShortcutLegend.js +1 -1
  118. package/dist/components/AppShowMore.js +1 -1
  119. package/dist/components/AppSkeleton.js +1 -1
  120. package/dist/components/AppSkeletonLines.js +1 -1
  121. package/dist/components/AppSlider.js +1 -1
  122. package/dist/components/AppSortableList.js +1 -1
  123. package/dist/components/AppSparkline.js +1 -1
  124. package/dist/components/AppSpinner.js +1 -1
  125. package/dist/components/AppSplash.js +1 -1
  126. package/dist/components/AppSplitButton.js +1 -1
  127. package/dist/components/AppSplitView.js +1 -1
  128. package/dist/components/AppStatusBadge.js +1 -1
  129. package/dist/components/AppStepper.js +1 -1
  130. package/dist/components/AppSwitch.js +1 -1
  131. package/dist/components/AppTablePagination.js +1 -1
  132. package/dist/components/AppTableToolbar.js +1 -1
  133. package/dist/components/AppTabs.js +1 -1
  134. package/dist/components/AppTagInput.js +1 -1
  135. package/dist/components/AppTextarea.js +1 -1
  136. package/dist/components/AppThemeToggle.js +1 -1
  137. package/dist/components/AppTimePicker.js +1 -1
  138. package/dist/components/AppTimeline.js +1 -1
  139. package/dist/components/AppToast.js +1 -1
  140. package/dist/components/AppToolbar.js +1 -1
  141. package/dist/components/AppTooltip.js +1 -1
  142. package/dist/components/AppTour.js +1 -1
  143. package/dist/components/AppTreeView.js +1 -1
  144. package/dist/components/AppTruncate.js +1 -1
  145. package/dist/components/AppUpdateBar.js +1 -1
  146. package/dist/components/AppWhatsNew.js +1 -1
  147. package/dist/components/AppWizard.js +1 -1
  148. package/dist/components/AppWorkspaceSwitcher.js +1 -1
  149. package/dist/components/iconCatalogNames.g.js +1 -1
  150. package/dist/components/iconGlyphs.g.js +1 -1
  151. package/dist/components/iconVariants.g.js +1 -1
  152. package/dist/guidance.json +119 -600
  153. package/dist/lib/useCommandPaletteShortcut.js +1 -1
  154. package/dist/lib/useFileDrop.js +1 -0
  155. package/dist/lib/wuiMarker.js +1 -1
  156. package/dist/types/components/AppAccordion.d.ts +1 -1
  157. package/dist/types/components/AppCompareTable.d.ts +45 -10
  158. package/dist/types/components/AppDescriptions.d.ts +10 -8
  159. package/dist/types/components/AppDrawer.d.ts +37 -0
  160. package/dist/types/components/AppEmptyState.d.ts +12 -5
  161. package/dist/types/components/AppImagePicker.d.ts +149 -0
  162. package/dist/types/components/AppInlineEdit.d.ts +0 -1
  163. package/dist/types/components/AppNavigationMenu.d.ts +1 -1
  164. package/dist/types/components/AppNotificationCenter.d.ts +16 -1
  165. package/dist/types/components/AppRecordPager.d.ts +2 -2
  166. package/dist/types/components/AppSectionLeadCapture.d.ts +67 -0
  167. package/dist/types/components/AppSelect.d.ts +7 -0
  168. package/dist/types/components/AppSeoHead.d.ts +42 -0
  169. package/dist/types/components/AppShortcutLegend.d.ts +13 -1
  170. package/dist/types/components/AppStepper.d.ts +2 -2
  171. package/dist/types/components/AppTablePagination.d.ts +36 -11
  172. package/dist/types/components/AppWhatsNew.d.ts +11 -2
  173. package/dist/types/components/iconGlyphs.g.d.ts +1 -0
  174. package/dist/types/components/iconVariants.g.d.ts +5 -0
  175. package/dist/types/index.d.ts +3 -8
  176. package/dist/types/lib/useFileDrop.d.ts +24 -0
  177. package/dist/types/lib/wuiMarker.d.ts +10 -0
  178. package/dist/ui-react.js +1 -1
  179. package/package.json +5 -5
  180. package/dist/components/AppAvatarPicker.js +0 -1
  181. package/dist/components/AppInfoList.js +0 -1
  182. package/dist/components/AppLogoPicker.js +0 -1
  183. package/dist/components/AppMenubar.js +0 -1
  184. package/dist/components/AppPagination.js +0 -1
  185. package/dist/components/AppSelectMini.js +0 -1
  186. package/dist/components/AppSidebarMenu.js +0 -1
  187. package/dist/components/AppTableEmptyState.js +0 -1
  188. package/dist/types/components/AppAvatarPicker.d.ts +0 -92
  189. package/dist/types/components/AppInfoList.d.ts +0 -29
  190. package/dist/types/components/AppLogoPicker.d.ts +0 -125
  191. package/dist/types/components/AppMenubar.d.ts +0 -50
  192. package/dist/types/components/AppPagination.d.ts +0 -39
  193. package/dist/types/components/AppSelectMini.d.ts +0 -53
  194. package/dist/types/components/AppSidebarMenu.d.ts +0 -90
  195. package/dist/types/components/AppTableEmptyState.d.ts +0 -22
@@ -1 +1 @@
1
- import{useEffect as e,useRef as t}from"react";function n(n,{key:r=`k`}={}){let i=t(n);e(()=>{i.current=n}),e(()=>{let e=String(r).toLowerCase(),t=t=>{!(t.ctrlKey||t.metaKey)||t.altKey||t.shiftKey||t.repeat||String(t.key).toLowerCase()===e&&(t.preventDefault(),i.current?.())};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[r])}export{n as useCommandPaletteShortcut};
1
+ import{isCommandChord as e}from"@webority/ui-elements/helpers";import{useEffect as t,useRef as n}from"react";function r(r,{key:i=`k`}={}){let a=n(r);t(()=>{a.current=r}),t(()=>{let t=t=>{e(t,i)&&(t.preventDefault(),a.current?.())};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[i])}export{r as useCommandPaletteShortcut};
@@ -0,0 +1 @@
1
+ import{acceptDroppedFiles as e}from"@webority/ui-elements/helpers";import{useRef as t,useState as n}from"react";function r({accept:r,maxSizeMb:i,multiple:a,disabled:o=!1,onFiles:s,onReject:c}){let[l,u]=n(!1),d=t(0);return{dragOver:l,dropProps:{onDragEnter:e=>{e.preventDefault(),!o&&(d.current+=1,u(!0))},onDragOver:e=>{e.preventDefault(),o||u(!0)},onDragLeave:e=>{e.preventDefault(),!o&&(d.current=Math.max(0,d.current-1),d.current===0&&u(!1))},onDrop:t=>{if(t.preventDefault(),d.current=0,u(!1),o)return;let{files:n,rejections:l}=e(t.dataTransfer?.files,{accept:r,maxSizeMb:i,multiple:a});n.length&&s(n),l.length&&c(l[0])}}}}export{r as default};
@@ -1 +1 @@
1
- var e=`data-wui`,t=`data-wui-props`,n=`data-canvas`,r=`data-canvas-at`,i=`__WUI_MARKERS__`,a=`props`,o=new Set([`children`,`className`,`style`,`id`,`key`,`ref`,`as`,`linkComponent`,`src`]),s=e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`;function c(){return globalThis[i]===a}function l(i,a){let l={[e]:i},u=a?.[n];typeof u==`string`&&u!==``&&(l[n]=u);let d=a?.[r];if(typeof d==`string`&&d!==``&&(l[r]=d),!c())return l;let f={};for(let[e,t]of Object.entries(a||{}))o.has(e)||e.startsWith(`aria-`)||e.startsWith(`data-`)||/^on[A-Z]/.test(e)||s(t)&&(f[e]=t);return l[t]=JSON.stringify(f),l}export{r as WUI_CANVAS_AT_ATTRIBUTE,n as WUI_CANVAS_KEY_ATTRIBUTE,i as WUI_MARKERS_GLOBAL,a as WUI_MARKERS_PROPS_MODE,e as WUI_MARKER_ATTRIBUTE,t as WUI_MARKER_PROPS_ATTRIBUTE,l as wuiMarkerAttributes,c as wuiMarkerPropsOn};
1
+ var e=`data-wui`,t=`data-wui-props`,n=`data-canvas`,r=`data-canvas-at`,i=`__WUI_MARKERS__`,a=`props`,o=new Set([`children`,`className`,`style`,`id`,`key`,`ref`,`as`,`linkComponent`,`src`]),s=e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`;function c(){return globalThis[i]===a}function l(i,a){let l={[e]:i},u=a?.[n];typeof u==`string`&&u!==``&&(l[n]=u);let d=a?.[r];if(typeof d==`string`&&d!==``&&(l[r]=d),!c())return l;let f={};for(let[e,t]of Object.entries(a||{}))o.has(e)||e.startsWith(`aria-`)||e.startsWith(`data-`)||/^on[A-Z]/.test(e)||s(t)&&(f[e]=t);return l[t]=JSON.stringify(f),l}function u(e,t){let{[n]:i,[r]:a,...o}=t??{};return{marker:l(e,t),props:o}}export{r as WUI_CANVAS_AT_ATTRIBUTE,n as WUI_CANVAS_KEY_ATTRIBUTE,i as WUI_MARKERS_GLOBAL,a as WUI_MARKERS_PROPS_MODE,e as WUI_MARKER_ATTRIBUTE,t as WUI_MARKER_PROPS_ATTRIBUTE,u as splitMarkerProps,l as wuiMarkerAttributes,c as wuiMarkerPropsOn};
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Collapsible panes — an FAQ list, a set of grouped settings, a "more detail"
3
- * disclosure. Renders the theme's `.faq-list` markup, the same as the Razor
3
+ * disclosure. Renders the theme's `.wui-accordion` markup, the same as the Razor
4
4
  * `<app-accordion>`.
5
5
  *
6
6
  * Height animates through `grid-template-rows: 0fr -> 1fr` in CSS, so a pane
@@ -1,18 +1,25 @@
1
1
  /**
2
- * A feature-comparison table — one row per capability, one column per option, with
3
- * the recommended column tinted so it reads without a legend. The marketing
4
- * "us vs them" table and a plan-feature matrix are the same shape.
2
+ * A feature-comparison table: one row per capability, one column per option, with the
3
+ * recommended column tinted so it reads without a legend.
5
4
  *
6
- * A cell value of `true`/`false` renders a tick or a dash; anything else renders
7
- * as-is, so a column can mix "yes/no" with "5 GB".
5
+ * A cell value is a tick (`true`), a dash (`false`), a state (`{ state, text? }` with
6
+ * state yes, no, warn or partial, drawn as an icon beside its text), a reference code
7
+ * (`{ code }`), or any node, drawn as written so `<sub>`, links and commas work.
8
8
  *
9
- * For tabular DATA (sortable, paginated rows of records) use `AppDataTable` —
10
- * this is an editorial comparison, not a grid.
9
+ * Under 576px of container width the table stacks by default: each row becomes a card with
10
+ * its label as the title and each cell under its column name. `mobile="scroll"` keeps the
11
+ * table whole and scrolls it sideways in a focusable region named by the caption.
12
+ *
13
+ * For tabular DATA (sortable, paginated rows of records) use `AppDataTable`.
11
14
  *
12
15
  * @param {object} props
13
- * @param {{ label: string, highlight?: boolean }[]} props.columns
14
- * @param {{ key?: string, label: string, values: (boolean|import('react').ReactNode)[] }[]} props.rows
16
+ * @param {{ label: string, highlight?: boolean, align?: "start"|"center", nowrap?: boolean }[]} props.columns
17
+ * @param {{ key?: string, label: string, group?: string, values: (boolean|import('react').ReactNode|{ state: "yes"|"no"|"warn"|"partial", text?: import('react').ReactNode }|{ code: string })[] }[]} props.rows
15
18
  * @param {string} [props.caption]
19
+ * @param {"stack"|"scroll"} [props.mobile] Container under 576px: stack rows as cards (default) or scroll sideways.
20
+ * @param {boolean} [props.stickyFirstColumn] With mobile="scroll".
21
+ * @param {boolean} [props.stickyHeader]
22
+ * @param {"comfortable"|"relaxed"} [props.density]
16
23
  * @param {string} [props.className]
17
24
  */
18
25
  export default function AppCompareTable(props: {
@@ -20,15 +27,43 @@ export default function AppCompareTable(props: {
20
27
  columns: {
21
28
  label: string;
22
29
  highlight?: boolean;
30
+ align?: "start" | "center";
31
+ nowrap?: boolean;
23
32
  }[];
24
33
  /** One row per capability. */
25
34
  rows: {
26
35
  key?: string;
27
36
  label: string;
28
- values: (boolean | import('react').ReactNode)[];
37
+ group?: string;
38
+ values: (boolean | import('react').ReactNode | {
39
+ state: "yes" | "no" | "warn" | "partial";
40
+ text?: import('react').ReactNode;
41
+ } | {
42
+ code: string;
43
+ })[];
29
44
  }[];
30
45
  /** Accessible description of what is being compared. */
31
46
  caption?: string;
47
+ /**
48
+ * Under 576px of table width: stack (default) turns each row into a card; scroll keeps the columns and scrolls sideways.
49
+ * @default "stack"
50
+ */
51
+ mobile?: "stack" | "scroll";
52
+ /**
53
+ * With mobile scroll: the first column stays in place while the rest scrolls.
54
+ * @default false
55
+ */
56
+ stickyFirstColumn?: boolean;
57
+ /**
58
+ * The header row stays on screen while a long table scrolls past it.
59
+ * @default false
60
+ */
61
+ stickyHeader?: boolean;
62
+ /**
63
+ * relaxed sets a 16px body and 32px side padding for marketing tables.
64
+ * @default "comfortable"
65
+ */
66
+ density?: "comfortable" | "relaxed";
32
67
  /**
33
68
  * Extra classes on the root.
34
69
  * @default ""
@@ -4,14 +4,14 @@
4
4
  * label/value pairs.
5
5
  *
6
6
  * Each item can span multiple columns and specify a size variant. Empty/null values
7
- * render as a muted em-dash so a missing fact reads as "no value", not a broken row.
7
+ * render as a muted hyphen so a missing fact reads as "no value", not a broken row.
8
8
  *
9
9
  * @param {object} props
10
- * @param {{ label: string, value: import('react').ReactNode, span?: 1|2|3, key?: string, emphasis?: boolean }[]} props.items
11
- * @param {1|2|3} [props.columns]
10
+ * @param {{ label: string, value: import('react').ReactNode, span?: number, key?: string, emphasis?: boolean, icon?: string|import('react').ReactNode, href?: string }[]} props.items
11
+ * @param {1|2|3|4} [props.columns] Validated; default 2.
12
12
  * @param {"sm"|"md"} [props.size]
13
13
  * @param {boolean} [props.bordered]
14
- * @param {"grid"|"summary"} [props.layout]
14
+ * @param {"grid"|"summary"|"list"} [props.layout] "list": one column, a rule between rows, flush first and last row, 36px icon tile, value on one line with an ellipsis.
15
15
  * @param {import('react').ReactNode} [props.title]
16
16
  * @param {string} [props.className]
17
17
  */
@@ -20,15 +20,17 @@ export default function AppDescriptions(props: {
20
20
  items: {
21
21
  label: string;
22
22
  value: import('react').ReactNode;
23
- span?: 1 | 2 | 3;
23
+ span?: number;
24
24
  key?: string;
25
25
  emphasis?: boolean;
26
+ icon?: string | import('react').ReactNode;
27
+ href?: string;
26
28
  }[];
27
29
  /**
28
30
  * How many columns the grid should have, before the media-breakpoint collapse.
29
31
  * @default 2
30
32
  */
31
- columns?: 1 | 2 | 3;
33
+ columns?: 1 | 2 | 3 | 4;
32
34
  /**
33
35
  * Item padding and font size.
34
36
  * @default "md"
@@ -40,10 +42,10 @@ export default function AppDescriptions(props: {
40
42
  */
41
43
  bordered?: boolean;
42
44
  /**
43
- * summary puts each label left of its value, with tabular figures.
45
+ * summary puts each label left of its value, with tabular figures. list is one column of rows with a rule between them, a flush first and last row and a single-line value.
44
46
  * @default "grid"
45
47
  */
46
- layout?: "grid" | "summary";
48
+ layout?: "grid" | "summary" | "list";
47
49
  /** Optional heading above the grid. */
48
50
  title?: import('react').ReactNode;
49
51
  /**
@@ -14,19 +14,29 @@ import "@webority/ui-elements/elements/drawer";
14
14
  * @param {() => void} [props.onClose] Called when the backdrop, Escape, the close button or a drag
15
15
  * down asks to close it. It stays open until `open` becomes false.
16
16
  * @param {string} [props.title]
17
+ * @param {string} [props.titleIcon]
18
+ * @param {import('react').ReactNode} [props.header] Replaces the default header (title, subtitle, close).
17
19
  * @param {string} [props.subtitle]
18
20
  * @param {string} [props.ariaLabel]
19
21
  * @param {'end'|'start'} [props.side]
20
22
  * @param {'sm'|'md'|'lg'|'xl'} [props.size]
23
+ * @param {string} [props.width] CSS width; overrides size. Max width 92vw unless maxWidth is given.
24
+ * @param {string} [props.maxWidth]
21
25
  * @param {number[]} [props.snapPoints]
22
26
  * @param {number} [props.defaultSnap]
27
+ * @param {boolean} [props.sheet] Below md the drawer is a bottom sheet with snap points. false keeps the side panel at every width (menus). Default true.
23
28
  * @param {(index: number, percent: number) => void} [props.onSnapChange] Called when the sheet moves to another point.
29
+ * @param {() => void} [props.onOpened] After the open transition.
30
+ * @param {() => void} [props.onClosed] After the close transition.
24
31
  * @param {boolean} [props.dismissible]
32
+ * @param {string} [props.closeLabel] Default "Close".
25
33
  * @param {boolean} [props.staticBackdrop]
26
34
  * @param {string} [props.confirmDiscard]
27
35
  * @param {boolean} [props.dirty]
28
36
  * @param {import('react').ReactNode} [props.footer]
29
37
  * @param {string} [props.className]
38
+ * @param {string} [props.bodyClassName]
39
+ * @param {import('react').CSSProperties} [props.style]
30
40
  * @param {import('react').ReactNode} props.children
31
41
  */
32
42
  export default function AppDrawer(props: {
@@ -38,6 +48,10 @@ export default function AppDrawer(props: {
38
48
  onClose?: () => void;
39
49
  /** The heading, and the dialog's accessible name. */
40
50
  title?: string;
51
+ /** Library icon beside the title. */
52
+ titleIcon?: string;
53
+ /** A custom header that replaces the default one (title, subtitle and close button). */
54
+ header?: import('react').ReactNode;
41
55
  /** A line under the title. */
42
56
  subtitle?: string;
43
57
  /** The dialog's accessible name when there is no title. */
@@ -52,6 +66,10 @@ export default function AppDrawer(props: {
52
66
  * @default "md"
53
67
  */
54
68
  size?: 'sm' | 'md' | 'lg' | 'xl';
69
+ /** The panel's CSS width, such as 420px. Overrides size. */
70
+ width?: string;
71
+ /** Caps the panel's width, such as 600px. Unset, the theme caps it at 92vw. */
72
+ maxWidth?: string;
55
73
  /**
56
74
  * The sheet's resting heights, each 10 to 100 percent of the screen.
57
75
  * @default [50,90]
@@ -62,12 +80,24 @@ export default function AppDrawer(props: {
62
80
  * @default 0
63
81
  */
64
82
  defaultSnap?: number;
83
+ /**
84
+ * Below md the drawer is a bottom sheet that rests on snapPoints. false keeps the side panel at every width, for a menu or a filter panel.
85
+ * @default true
86
+ */
87
+ sheet?: boolean;
65
88
  onSnapChange?: (index: number, percent: number) => void;
89
+ onOpened?: () => void;
90
+ onClosed?: () => void;
66
91
  /**
67
92
  * Show the close button.
68
93
  * @default true
69
94
  */
70
95
  dismissible?: boolean;
96
+ /**
97
+ * The close button's accessible name, for other languages.
98
+ * @default "Close"
99
+ */
100
+ closeLabel?: string;
71
101
  /**
72
102
  * The backdrop, Escape and a drag down no longer close it; only the close button or open can.
73
103
  * @default false
@@ -87,5 +117,12 @@ export default function AppDrawer(props: {
87
117
  * @default ""
88
118
  */
89
119
  className?: string;
120
+ /**
121
+ * Classes on the scrolling body, such as p-0 to drop its padding.
122
+ * @default ""
123
+ */
124
+ bodyClassName?: string;
125
+ /** Inline style on the drawer element. */
126
+ style?: import('react').CSSProperties;
90
127
  children: import('react').ReactNode;
91
128
  }): import("react").JSX.Element;
@@ -1,10 +1,11 @@
1
1
  /**
2
- * The standalone empty / placeholder block a card or section shows when it has
3
- * nothing to display: an icon bubble, a title, optional body text, and an optional
4
- * action. Same `.empty-state` markup as before — zero visual change.
2
+ * The standalone empty / placeholder block a card, a section or a data table body shows
3
+ * when it has nothing to display: an icon bubble, a title, optional body text, and an
4
+ * optional action.
5
5
  *
6
- * For the empty body of a AppDataTable use `AppTableEmptyState` instead (a different
7
- * `.tbl-empty` design); this is the card / section version.
6
+ * `variant` picks the look: "card" (default) is the card or section empty state; "table"
7
+ * is the body of an AppDataTable, a column with a larger disc above the title. The table
8
+ * look has no tighter scale, so `size="sm"` with `variant="table"` warns in dev.
8
9
  *
9
10
  * `size` picks the type scale: "md" (default) is the page/card empty state; "sm" is
10
11
  * the tighter widget/tile variant (smaller title + text).
@@ -14,6 +15,7 @@
14
15
  * @param {string|import('react').ReactNode} [props.illustration]
15
16
  * @param {number} [props.iconSize]
16
17
  * @param {"md"|"sm"} [props.size]
18
+ * @param {"card"|"table"} [props.variant]
17
19
  * @param {import('react').ReactNode} props.title
18
20
  * @param {import('react').ReactNode} [props.text]
19
21
  * @param {import('react').ReactNode} [props.action]
@@ -35,6 +37,11 @@ export default function AppEmptyState(props: {
35
37
  * @default "md"
36
38
  */
37
39
  size?: "md" | "sm";
40
+ /**
41
+ * The look: card is the card or section empty state; table is the body of a data table, with a larger disc above the title. The table look has no sm scale, so size sm with table warns.
42
+ * @default "card"
43
+ */
44
+ variant?: "card" | "table";
38
45
  /** The headline of the empty state. */
39
46
  title: import('react').ReactNode;
40
47
  /** Body text under the title. */
@@ -0,0 +1,149 @@
1
+ import "@webority/ui-elements/elements/image-crop";
2
+ /**
3
+ * One image picker with two looks. controls="overlay": a ring with a hover label and an x to remove (the logo look). controls="buttons": the photo beside Upload or Change, Take photo and Remove (the profile photo look). `kind` picks the preset; each prop below overrides it.
4
+ * @param {object} props
5
+ * @param {"logo"|"avatar"} [props.kind] Default "logo".
6
+ * @param {"overlay"|"buttons"} [props.controls] Default "overlay" for logo, "buttons" for avatar.
7
+ * @param {string} [props.value] Current image URL.
8
+ * @param {import('react').ReactNode} [props.fallback] Shown with no image.
9
+ * @param {"initials"|"avatar"} [props.variant] With no fallback, "avatar" draws a person glyph. Default "initials".
10
+ * @param {string} [props.name] Field name; the chosen file (the crop when cropping) is written into the named file input.
11
+ * @param {(file: File) => void} [props.onPick]
12
+ * @param {() => void} [props.onRemove] Shows Remove when given.
13
+ * @param {string} [props.removeName] Hidden field set to "true" after Remove, for a posted form.
14
+ * @param {boolean} [props.loading]
15
+ * @param {boolean} [props.disabled]
16
+ * @param {string} [props.accept] Default DEFAULT_IMAGE_ACCEPT for logo, AVATAR_ACCEPT for avatar.
17
+ * @param {number} [props.maxSizeMb] 0 is no limit. Default 5 for logo, AVATAR_MAX_SIZE_MB (10) for avatar.
18
+ * @param {"circle"|"rounded"|"square"} [props.shape] Default "circle".
19
+ * @param {"sm"|"md"|"lg"|number} [props.size] logo 72, 120, 160 px; avatar 64, 96, 128 px; a number is px. Default "md".
20
+ * @param {number|"free"} [props.crop] Default none for logo, 1 for avatar.
21
+ * @param {boolean} [props.rotatable] Default false for logo, true for avatar.
22
+ * @param {boolean} [props.previews] The 96 and 48 px live previews. Default false for logo, true for avatar.
23
+ * @param {boolean} [props.camera] The Take photo button (front camera). Default false for logo, true for avatar.
24
+ * @param {number} [props.outputSize] Square output in px; only with crop 1. Default none for logo, AVATAR_OUTPUT_SIZE (512) for avatar.
25
+ * @param {"keep"|"image/webp"} [props.outputType] Default "keep" for logo, "image/webp" for avatar.
26
+ * @param {"stacked"|"inline"|"profile"} [props.layout] Default "stacked".
27
+ * @param {import('react').ReactNode} [props.title]
28
+ * @param {import('react').ReactNode} [props.subtitle]
29
+ * @param {string} [props.overlayIcon] Default "image".
30
+ * @param {string} [props.overlayLabel] Default "Update photo".
31
+ * @param {string} [props.removeLabel] Default "Remove photo".
32
+ * @param {string} [props.ariaLabel] Default "Upload photo".
33
+ * @param {import('react').ReactNode} [props.label]
34
+ * @param {string} [props.hint]
35
+ * @param {string} [props.error]
36
+ * @param {boolean} [props.required]
37
+ * @param {string} [props.className] On the picker.
38
+ * @param {string} [props.fieldClassName] On the .field wrapper.
39
+ * @param {import('react').CSSProperties} [props.style]
40
+ */
41
+ export default function AppImagePicker(props: {
42
+ /**
43
+ * The preset: logo is an identity ring, avatar is a person's profile photo. Each prop below overrides the preset.
44
+ * @default "logo"
45
+ */
46
+ kind?: "logo" | "avatar";
47
+ /** overlay is a ring with a hover label and an x to remove. buttons is the photo beside Upload or Change, Take photo and Remove. Default overlay for logo, buttons for avatar. */
48
+ controls?: "overlay" | "buttons";
49
+ /** The current image URL. Absent or empty means no image. */
50
+ value?: string;
51
+ /** Shown when there is no image, for example initials. */
52
+ fallback?: import('react').ReactNode;
53
+ /**
54
+ * With no fallback, avatar draws a person icon. The avatar kind uses avatar.
55
+ * @default "initials"
56
+ */
57
+ variant?: "initials" | "avatar";
58
+ /** The form field name. The chosen file, or the crop when cropping, is written into the file input, so an uncontrolled form posts it. */
59
+ name?: string;
60
+ onPick?: (file: File) => void;
61
+ onRemove?: () => void;
62
+ /** A form field that posts true once Remove is pressed. */
63
+ removeName?: string;
64
+ /**
65
+ * Shows a spinner and blocks every action while the picked file uploads.
66
+ * @default false
67
+ */
68
+ loading?: boolean;
69
+ /**
70
+ * Blocks every action.
71
+ * @default false
72
+ */
73
+ disabled?: boolean;
74
+ /** The file types a person may choose. Defaults to PNG, JPG and WebP for logo; JPG, PNG, WebP and HEIC for avatar. HEIC opens only where the browser can decode it. */
75
+ accept?: string;
76
+ /** The size limit in megabytes; 0 means no limit. Defaults to 5 for logo and 10 for avatar. */
77
+ maxSizeMb?: number;
78
+ /**
79
+ * The ring or frame shape.
80
+ * @default "circle"
81
+ */
82
+ shape?: "circle" | "rounded" | "square";
83
+ /**
84
+ * A preset diameter (logo 72, 120, 160 px; avatar 64, 96, 128 px) or an exact number of pixels.
85
+ * @default "md"
86
+ */
87
+ size?: "sm" | "md" | "lg" | number;
88
+ /** Adds a crop step before upload. A number is the frame's width divided by its height, such as 1 for a round avatar; free lets the person resize the frame. Default none for logo, 1 for avatar. */
89
+ crop?: number | "free";
90
+ /** Offers rotation in the crop dialog. Default false for logo, true for avatar. */
91
+ rotatable?: boolean;
92
+ /** Shows the 96 and 48 px live previews in the crop dialog. Default false for logo, true for avatar. */
93
+ previews?: boolean;
94
+ /** Shows the Take photo button, which opens the front camera. Default false for logo, true for avatar. */
95
+ camera?: boolean;
96
+ /** The width and height of the saved square, in pixels, with a crop of 1. Default none for logo, 512 for avatar. */
97
+ outputSize?: number;
98
+ /** The type of the saved crop: keep the chosen type, or WebP. Default keep for logo, WebP for avatar. */
99
+ outputType?: "keep" | "image/webp";
100
+ /**
101
+ * Stacked is the ring with the hint below. Inline puts the ring on the left with a title, subtitle and hint column beside it. Profile stacks the same identity block, centred, beneath the ring. Applies to the overlay controls.
102
+ * @default "stacked"
103
+ */
104
+ layout?: "stacked" | "inline" | "profile";
105
+ /** Bold primary text beside the ring. Inline and profile layouts only. */
106
+ title?: import('react').ReactNode;
107
+ /** Muted secondary text beside the ring. Inline and profile layouts only. */
108
+ subtitle?: import('react').ReactNode;
109
+ /**
110
+ * The icon name for the hover overlay. Overlay controls only.
111
+ * @default "image"
112
+ */
113
+ overlayIcon?: string;
114
+ /**
115
+ * The text of the hover overlay. Overlay controls only.
116
+ * @default "Update photo"
117
+ */
118
+ overlayLabel?: string;
119
+ /**
120
+ * The accessible name and tooltip of the remove control. Use Remove logo on a logo picker.
121
+ * @default "Remove photo"
122
+ */
123
+ removeLabel?: string;
124
+ /** The accessible name of the upload control. Defaults to Upload photo for the overlay and to the action's words for buttons. */
125
+ ariaLabel?: string;
126
+ /** An optional field label above the picker. */
127
+ label?: import('react').ReactNode;
128
+ /** Help text under the picker. An error replaces it. */
129
+ hint?: string;
130
+ /** An error from the caller. It wins over a rejection reason. */
131
+ error?: string;
132
+ /**
133
+ * Marks the field as required.
134
+ * @default false
135
+ */
136
+ required?: boolean;
137
+ /**
138
+ * Extra class on the picker.
139
+ * @default ""
140
+ */
141
+ className?: string;
142
+ /**
143
+ * Extra class on the field wrapper.
144
+ * @default ""
145
+ */
146
+ fieldClassName?: string;
147
+ /** Inline style on the picker. */
148
+ style?: import('react').CSSProperties;
149
+ }): import("react").JSX.Element;
@@ -1,5 +1,4 @@
1
1
  import "@webority/ui-elements/elements/datepicker";
2
- import "@webority/ui-elements/elements/select";
3
2
  /**
4
3
  * One value edited where it is shown: a table cell or a fact on a detail page. It reads as plain
5
4
  * text with a pencil on hover and focus; a click or Enter turns it into the matching library control
@@ -7,7 +7,7 @@ import "@webority/ui-elements/elements/navigation-menu";
7
7
  * a link or clicking out. One panel is open at a time, and one that would leave the screen aligns
8
8
  * to the end of its entry. Below `md` the entries stack and a panel opens in the page flow. The
9
9
  * behaviour is the shared `<wui-navigation-menu>` element, the same one the Razor
10
- * `<app-navigation-menu>` uses. For an application menubar (File, Edit) use `AppMenubar`.
10
+ * `<app-navigation-menu>` uses.
11
11
  *
12
12
  * NOTE: the exported component must stay the FIRST destructured function in this file —
13
13
  * the parity check reads the first signature it finds as the component's public props.
@@ -29,6 +29,10 @@ export type NotificationItem = {
29
29
  * A library icon name, drawn before the text.
30
30
  */
31
31
  icon?: string;
32
+ /**
33
+ * Filed away: shown only under the Archived tab.
34
+ */
35
+ archived?: boolean;
32
36
  };
33
37
  /**
34
38
  * @typedef {object} NotificationItem
@@ -40,6 +44,7 @@ export type NotificationItem = {
40
44
  * or a "YYYY-MM-DD" day. It sets the day group and the time shown, in India Standard Time.
41
45
  * @property {boolean} [read] Already read: no dot, regular weight.
42
46
  * @property {string} [icon] A library icon name, drawn before the text.
47
+ * @property {boolean} [archived] Filed away: shown only under the Archived tab.
43
48
  */
44
49
  /**
45
50
  * A bell with an unread count that opens a panel of notifications grouped by day (Today, Yesterday,
@@ -61,7 +66,10 @@ export type NotificationItem = {
61
66
  * @param {boolean} [props.defaultOpen]
62
67
  * @param {string|number|Date} [props.now]
63
68
  * @param {() => void} [props.onMarkAllRead] Called by "Mark all read". Absent: no button.
64
- * @param {(item: NotificationItem, event: import('react').MouseEvent) => void} [props.onItemClick] Called when an item is chosen, before its link is followed.
69
+ * @param {(item: NotificationItem, event: import('react').MouseEvent) => void} [props.onItemClick] Called when an item is chosen, before its link is followed. On a row from `renderItem`, only a click outside its own controls counts.
70
+ * @param {(item: NotificationItem) => import('react').ReactNode} [props.renderItem] The row's content in place of the icon, title, text and time. The dot, the Unread prefix and the read handling stay.
71
+ * @param {true | { key: "all" | "unread" | "archived", label?: string }[]} [props.tabs] `true` for All, Unread and Archived; or the tabs to show, in order. Absent: no tab strip.
72
+ * @param {(key: string) => void} [props.onTabChange] Called with the key of the tab the person picks.
65
73
  * @param {(open: boolean) => void} [props.onOpenChange] Called when the panel opens or closes.
66
74
  * @param {string} [props.className]
67
75
  */
@@ -91,6 +99,13 @@ export default function AppNotificationCenter(props: {
91
99
  now?: string | number | Date;
92
100
  onMarkAllRead?: () => void;
93
101
  onItemClick?: (item: NotificationItem, event: import('react').MouseEvent) => void;
102
+ renderItem?: (item: NotificationItem) => import('react').ReactNode;
103
+ /** true for the tabs All, Unread and Archived, or the tabs to show in order as `{ key, label? }`, where key is all, unread or archived and label defaults to the key's name. All and Unread leave out archived items; Archived shows only them. Absent: no tab strip. */
104
+ tabs?: true | {
105
+ key: "all" | "unread" | "archived";
106
+ label?: string;
107
+ }[];
108
+ onTabChange?: (key: string) => void;
94
109
  onOpenChange?: (open: boolean) => void;
95
110
  className?: string;
96
111
  }): import("react").JSX.Element;
@@ -2,8 +2,8 @@ import "@webority/ui-elements/elements/record-pager";
2
2
  /**
3
3
  * Moves between the records of a list without going back to it: "12 of 47" and previous and next
4
4
  * action icons, for a detail page's header (`AppPageHeader` `actions`) or a reading pane's header
5
- * (`AppSplitView` draws one for its open item). Distinct from `AppPagination` and
6
- * `AppTablePagination`, which move between pages of a list.
5
+ * (`AppSplitView` draws one for its open item). Distinct from `AppTablePagination`, which moves
6
+ * between pages of a list.
7
7
  *
8
8
  * Each direction is a link (`prevHref`, `nextHref`), a handler (`onPrev`, `onNext`) or both (the
9
9
  * handler runs on the link's click and may prevent it). A direction with neither, or at either end,
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The lead form section of a marketing page. The product saves the lead; the section only renders and validates.
3
+ * @param {object} props
4
+ * @param {import('react').ReactNode} props.title
5
+ * @param {import('react').ReactNode} [props.text]
6
+ * @param {{ name: "name"|"email"|"phone"|"company"|"message", label?: string, required?: boolean }[]} props.fields
7
+ * @param {(values: Record<string, string>) => Promise<void>} props.onSubmit A rejection shows its message in an AppAlert above the button.
8
+ * @param {string} [props.submitLabel] Default "Send".
9
+ * @param {import('react').ReactNode} props.successTitle
10
+ * @param {import('react').ReactNode} [props.successText]
11
+ * @param {import('react').ReactNode} [props.consent] Text under the button.
12
+ * @param {"h1"|"h2"|"h3"|"h4"|"h5"|"h6"} [props.as] The heading element.
13
+ * @param {import('react').ReactNode} [props.eyebrow] A short label above the heading.
14
+ * @param {import('react').ReactNode} [props.subtitle] A sentence under the heading.
15
+ * @param {"start"|"center"} [props.align] Where the copy and form sit in the panel.
16
+ * @param {"default"|"muted"} [props.variant] The section's background around the panel.
17
+ * @param {string} [props.className] Extra class names for the root element.
18
+ * (plus the shell props AppSectionCallToAction takes, same names)
19
+ */
20
+ export default function AppSectionLeadCapture(props: {
21
+ /** The section's heading. */
22
+ title: import('react').ReactNode;
23
+ /** A paragraph above the form. */
24
+ text?: import('react').ReactNode;
25
+ /** The fields in order: name, email, phone, company or message, each optionally labelled and required. */
26
+ fields: {
27
+ name: "name" | "email" | "phone" | "company" | "message";
28
+ label?: string;
29
+ required?: boolean;
30
+ }[];
31
+ onSubmit: (values: Record<string, string>) => Promise<void>;
32
+ /**
33
+ * The button's label.
34
+ * @default "Send"
35
+ */
36
+ submitLabel?: string;
37
+ /** The heading of the block shown after a successful send. */
38
+ successTitle: import('react').ReactNode;
39
+ /** The sentence under the success heading. */
40
+ successText?: import('react').ReactNode;
41
+ /** A line under the button, such as a privacy notice. */
42
+ consent?: import('react').ReactNode;
43
+ /**
44
+ * The heading element.
45
+ * @default "h2"
46
+ */
47
+ as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
48
+ /** A short label above the heading. */
49
+ eyebrow?: import('react').ReactNode;
50
+ /** A sentence under the heading. */
51
+ subtitle?: import('react').ReactNode;
52
+ /**
53
+ * Where the copy and form sit in the panel.
54
+ * @default "center"
55
+ */
56
+ align?: "start" | "center";
57
+ /**
58
+ * The section's background around the panel.
59
+ * @default "default"
60
+ */
61
+ variant?: "default" | "muted";
62
+ /**
63
+ * Extra class names for the root element.
64
+ * @default ""
65
+ */
66
+ className?: string;
67
+ }): import("react").JSX.Element;
@@ -87,5 +87,12 @@ declare const AppSelect: import("react").ForwardRefExoticComponent<{
87
87
  id?: string;
88
88
  /** Form field name. */
89
89
  name?: string;
90
+ /**
91
+ * Inline width, 32px control, 600 weight, menu sized to its options: the toolbar, sort and filter picker. Writes the element's compact attribute.
92
+ * @default false
93
+ */
94
+ compact?: boolean;
95
+ /** Static text inside the control before the value, such as Sort:. Not prefix, which is the bordered affix box. */
96
+ valuePrefix?: string;
90
97
  } & import("react").RefAttributes<any>>;
91
98
  export default AppSelect;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Head tags for one route: title, description, canonical, robots, Open Graph, Twitter card and JSON-LD. React 19 hoists them into <head>. The Razor counterpart is <seo-head> in Webority.Seo.AspNetCore.
3
+ * @param {object} props
4
+ * @param {string} props.title
5
+ * @param {string} props.description
6
+ * @param {string} props.canonicalUrl
7
+ * @param {string} props.siteName
8
+ * @param {string} props.robots The product decides it per environment ("index, follow", "noindex, nofollow").
9
+ * @param {string} [props.image]
10
+ * @param {string} [props.imageAlt]
11
+ * @param {"website"|"article"} [props.type] Default "website".
12
+ * @param {"summary"|"summary_large_image"} [props.twitterCard] Default "summary".
13
+ * @param {object|object[]} [props.jsonLd] Serialised with "<" escaped and written as a text child of the script, so it is for client-rendered portals only (React escapes script text under server rendering).
14
+ */
15
+ export default function AppSeoHead(props: {
16
+ /** The page title, written in full by the product. */
17
+ title: string;
18
+ /** The meta description shown in search results. */
19
+ description: string;
20
+ /** The absolute address of the page, used for the canonical link and og:url. */
21
+ canonicalUrl: string;
22
+ /** The name of the site, for og:site_name. */
23
+ siteName: string;
24
+ /** The robots directive the product picks per environment, such as "index, follow" or "noindex, nofollow". */
25
+ robots: string;
26
+ /** The absolute address of the social preview image. */
27
+ image?: string;
28
+ /** The text description of the social preview image. */
29
+ imageAlt?: string;
30
+ /**
31
+ * The Open Graph type of the page.
32
+ * @default "website"
33
+ */
34
+ type?: "website" | "article";
35
+ /**
36
+ * The Twitter card layout.
37
+ * @default "summary"
38
+ */
39
+ twitterCard?: "summary" | "summary_large_image";
40
+ /** Structured data for the page, one object or an array of objects. Written into the page as JSON-LD, as an escaped text child, so it is for client-rendered portals only (React escapes script text under server rendering). */
41
+ jsonLd?: object | object[];
42
+ }): import("react").JSX.Element;