@aircall/blocks 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Anchor, Badge, Button, CounterBadge, DropdownMenu, DropdownMenuAddon, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldLabel, FieldLabelAside, FieldLabelInfo, FieldLabelRow, HoverCard, HoverCardContent, HoverCardTrigger, InputGroup, InputGroupButton, InputGroupTextarea, Item, ItemActions, ItemContent, ItemGroup, ItemMedia, ItemTitle, Popover, PopoverContent, PopoverTrigger, Separator, Sidebar, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarProvider, Spinner, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, TabsList, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipTrigger, cn, registerI18nNamespace, useDsLocale, useDsTranslation, useSidebar } from "@aircall/ds";
1
+ import { Anchor, Badge, Button, Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, CounterBadge, DropdownMenu, DropdownMenuAddon, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldLabel, FieldLabelAside, FieldLabelInfo, FieldLabelRow, HoverCard, HoverCardContent, HoverCardTrigger, InputGroup, InputGroupButton, InputGroupTextarea, Item, ItemActions, ItemContent, ItemGroup, ItemMedia, ItemTitle, Popover, PopoverContent, PopoverTrigger, Separator, Sidebar, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarProvider, Spinner, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, TabsList, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipTrigger, cn, registerI18nNamespace, useDsLocale, useDsTranslation, useSidebar } from "@aircall/ds";
2
2
  import * as React from "react";
3
3
  import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -360,6 +360,7 @@ const EmptyStateMedia = React.forwardRef((componentProps, forwardRef) => {
360
360
  });
361
361
  });
362
362
  EmptyStateMedia.displayName = "EmptyStateMedia";
363
+ /** Title line of an empty state. Wraps the DS `EmptyTitle`. */
363
364
  const EmptyStateTitle = React.forwardRef((componentProps, forwardRef) => {
364
365
  return /* @__PURE__ */ jsx(EmptyTitle, {
365
366
  ref: forwardRef,
@@ -367,6 +368,7 @@ const EmptyStateTitle = React.forwardRef((componentProps, forwardRef) => {
367
368
  });
368
369
  });
369
370
  EmptyStateTitle.displayName = "EmptyStateTitle";
371
+ /** Supporting description text of an empty state. Wraps the DS `EmptyDescription`. */
370
372
  const EmptyStateDescription = React.forwardRef((componentProps, forwardRef) => {
371
373
  return /* @__PURE__ */ jsx(EmptyDescription, {
372
374
  ref: forwardRef,
@@ -388,6 +390,11 @@ const EmptyStateActions = React.forwardRef((componentProps, forwardRef) => {
388
390
  });
389
391
  });
390
392
  EmptyStateActions.displayName = "EmptyStateActions";
393
+ /**
394
+ * Action button for an empty state — the only button allowed inside one. Wraps
395
+ * the DS `Button` with `size` locked to `default` for visual consistency across
396
+ * empty states; consumers still choose the `variant`.
397
+ */
391
398
  const EmptyStateButton = React.forwardRef((componentProps, forwardRef) => {
392
399
  return /* @__PURE__ */ jsx(Button, {
393
400
  ref: forwardRef,
@@ -396,6 +403,13 @@ const EmptyStateButton = React.forwardRef((componentProps, forwardRef) => {
396
403
  });
397
404
  });
398
405
  EmptyStateButton.displayName = "EmptyStateButton";
406
+ /**
407
+ * External "Learn more"-style link for an empty state. Renders a real `<a>` (via
408
+ * `EmptyStateButton` with `variant="link"`) that opens in a new tab. Pass
409
+ * `children` to override the default "Learn more" label, including any icon.
410
+ *
411
+ * @default children "Learn more"
412
+ */
399
413
  const EmptyStateExternalLink = React.forwardRef((componentProps, forwardRef) => {
400
414
  const { href, children = "Learn more", ...props } = componentProps;
401
415
  return /* @__PURE__ */ jsx(EmptyStateButton, {
@@ -411,6 +425,11 @@ const EmptyStateExternalLink = React.forwardRef((componentProps, forwardRef) =>
411
425
  });
412
426
  });
413
427
  EmptyStateExternalLink.displayName = "EmptyStateExternalLink";
428
+ /**
429
+ * Builds one preset's per-variant parts (`Root`, `Media`, `Title`, `Description`)
430
+ * from its icon, default copy, and a11y role. Returns an object of `forwardRef`
431
+ * components that reuse the shared empty-state parts; renders no DOM itself.
432
+ */
414
433
  function createEmptyStateVariant(config) {
415
434
  const Root = React.forwardRef((componentProps, forwardRef) => /* @__PURE__ */ jsx(EmptyState, {
416
435
  ref: forwardRef,
@@ -452,10 +471,18 @@ function createEmptyStateVariant(config) {
452
471
 
453
472
  //#endregion
454
473
  //#region src/components/coming-soon.tsx
474
+ const ComingSoon = createEmptyStateVariant({
475
+ name: "ComingSoon",
476
+ icon: /* @__PURE__ */ jsx(Sprout, {}),
477
+ titleKey: "emptyState.comingSoon.title",
478
+ descriptionKey: "emptyState.comingSoon.description"
479
+ });
455
480
  /**
456
- * ComingSoon empty state shown when a feature exists in the UI but is not yet
457
- * available. Compose it from its parts:
481
+ * Root of the "Coming soon" empty state shown when a feature exists in the UI
482
+ * but is not yet available. Renders a `<div>` (the DS `Empty` container); compose
483
+ * it from its parts.
458
484
  *
485
+ * @example
459
486
  * ```tsx
460
487
  * <ComingSoonEmptyState>
461
488
  * <EmptyStateHeader>
@@ -469,62 +496,87 @@ function createEmptyStateVariant(config) {
469
496
  * </EmptyStateActions>
470
497
  * </ComingSoonEmptyState>
471
498
  * ```
472
- *
473
- * `ComingSoonTitle` / `ComingSoonDescription` render the design copy by default;
474
- * pass children to override (e.g. for i18n).
475
499
  */
476
- const ComingSoon = createEmptyStateVariant({
477
- name: "ComingSoon",
478
- icon: /* @__PURE__ */ jsx(Sprout, {}),
479
- titleKey: "emptyState.comingSoon.title",
480
- descriptionKey: "emptyState.comingSoon.description"
481
- });
482
500
  const ComingSoonEmptyState = ComingSoon.Root;
501
+ /** Decorative media slot of the "Coming soon" empty state (a sprout icon). Renders a `<div>`, hidden from assistive tech. */
483
502
  const ComingSoonMedia = ComingSoon.Media;
503
+ /** Title line of the "Coming soon" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
484
504
  const ComingSoonTitle = ComingSoon.Title;
505
+ /** Supporting description text of the "Coming soon" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
485
506
  const ComingSoonDescription = ComingSoon.Description;
486
507
 
487
508
  //#endregion
488
509
  //#region src/components/restricted-access.tsx
489
- /**
490
- * RestrictedAccess — shown when the user lacks permission to view a page.
491
- * Pair it with an `EmptyStateExternalLink` for the "Learn more" action.
492
- */
493
510
  const RestrictedAccess = createEmptyStateVariant({
494
511
  name: "RestrictedAccess",
495
512
  icon: /* @__PURE__ */ jsx(LockKeyhole, {}),
496
513
  titleKey: "emptyState.restrictedAccess.title",
497
514
  descriptionKey: "emptyState.restrictedAccess.description"
498
515
  });
516
+ /**
517
+ * Root of the "Restricted access" empty state — shown when the user lacks
518
+ * permission to view a page. Renders a `<div>` (the DS `Empty` container); pair
519
+ * it with an `EmptyStateExternalLink` for the "Learn more" action.
520
+ *
521
+ * @example
522
+ * ```tsx
523
+ * <RestrictedAccessEmptyState>
524
+ * <EmptyStateHeader>
525
+ * <RestrictedAccessMedia />
526
+ * <RestrictedAccessTitle />
527
+ * <RestrictedAccessDescription />
528
+ * </EmptyStateHeader>
529
+ * <EmptyStateActions>
530
+ * <EmptyStateExternalLink href={docsUrl} />
531
+ * </EmptyStateActions>
532
+ * </RestrictedAccessEmptyState>
533
+ * ```
534
+ */
499
535
  const RestrictedAccessEmptyState = RestrictedAccess.Root;
536
+ /** Decorative media slot of the "Restricted access" empty state (a locked padlock icon). Renders a `<div>`, hidden from assistive tech. */
500
537
  const RestrictedAccessMedia = RestrictedAccess.Media;
538
+ /** Title line of the "Restricted access" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
501
539
  const RestrictedAccessTitle = RestrictedAccess.Title;
540
+ /** Supporting description text of the "Restricted access" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
502
541
  const RestrictedAccessDescription = RestrictedAccess.Description;
503
542
 
504
543
  //#endregion
505
544
  //#region src/components/not-found.tsx
506
- /**
507
- * NotFound — shown when a page/route cannot be found. Pair it with an
508
- * `EmptyStateButton` for the navigation action (e.g. "Go to inbox").
509
- */
510
545
  const NotFound = createEmptyStateVariant({
511
546
  name: "NotFound",
512
547
  icon: /* @__PURE__ */ jsx(Search, {}),
513
548
  titleKey: "emptyState.notFound.title",
514
549
  descriptionKey: "emptyState.notFound.description"
515
550
  });
551
+ /**
552
+ * Root of the "Not found" empty state — shown when a page or route cannot be
553
+ * found. Renders a `<div>` (the DS `Empty` container); pair it with an
554
+ * `EmptyStateButton` for the navigation action (e.g. "Go to inbox").
555
+ *
556
+ * @example
557
+ * ```tsx
558
+ * <NotFoundEmptyState>
559
+ * <EmptyStateHeader>
560
+ * <NotFoundMedia />
561
+ * <NotFoundTitle />
562
+ * <NotFoundDescription />
563
+ * </EmptyStateHeader>
564
+ * <EmptyStateActions>
565
+ * <EmptyStateButton onClick={goToInbox}>Go to inbox</EmptyStateButton>
566
+ * </EmptyStateActions>
567
+ * </NotFoundEmptyState>
568
+ * ```
569
+ */
516
570
  const NotFoundEmptyState = NotFound.Root;
571
+ /** Decorative media slot of the "Not found" empty state (a search icon). Renders a `<div>`, hidden from assistive tech. */
517
572
  const NotFoundMedia = NotFound.Media;
573
+ /** Title line of the "Not found" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
518
574
  const NotFoundTitle = NotFound.Title;
575
+ /** Supporting description text of the "Not found" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
519
576
  const NotFoundDescription = NotFound.Description;
520
577
 
521
578
  //#endregion
522
579
  //#region src/components/no-data.tsx
523
- /**
524
- * NoData — shown when a search or filter returns no results. Pair it with an
525
- * `EmptyStateButton` for the "Reset" action. Appears in response to a user
526
- * action, so it announces politely via `role="status"`.
527
- */
528
580
  const NoData = createEmptyStateVariant({
529
581
  name: "NoData",
530
582
  icon: /* @__PURE__ */ jsx(Search, {}),
@@ -532,35 +584,71 @@ const NoData = createEmptyStateVariant({
532
584
  descriptionKey: "emptyState.noData.description",
533
585
  role: "status"
534
586
  });
587
+ /**
588
+ * Root of the "No data" empty state — shown when a search or filter returns no
589
+ * results. Renders a `<div>` (the DS `Empty` container) with `role="status"` so
590
+ * it announces politely after a user action; pair it with an `EmptyStateButton`
591
+ * for the "Reset" action.
592
+ *
593
+ * @example
594
+ * ```tsx
595
+ * <NoDataEmptyState>
596
+ * <EmptyStateHeader>
597
+ * <NoDataMedia />
598
+ * <NoDataTitle />
599
+ * <NoDataDescription />
600
+ * </EmptyStateHeader>
601
+ * <EmptyStateActions>
602
+ * <EmptyStateButton variant="outline" onClick={resetFilters}>Reset</EmptyStateButton>
603
+ * </EmptyStateActions>
604
+ * </NoDataEmptyState>
605
+ * ```
606
+ */
535
607
  const NoDataEmptyState = NoData.Root;
608
+ /** Decorative media slot of the "No data" empty state (a search icon). Renders a `<div>`, hidden from assistive tech. */
536
609
  const NoDataMedia = NoData.Media;
610
+ /** Title line of the "No data" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
537
611
  const NoDataTitle = NoData.Title;
612
+ /** Supporting description text of the "No data" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
538
613
  const NoDataDescription = NoData.Description;
539
614
 
540
615
  //#endregion
541
616
  //#region src/components/no-support.tsx
542
- /**
543
- * NoSupport — shown when the current browser can't render a page. Pair it with
544
- * an `EmptyStateExternalLink` for the "Learn more" action.
545
- */
546
617
  const NoSupport = createEmptyStateVariant({
547
618
  name: "NoSupport",
548
619
  icon: /* @__PURE__ */ jsx(Settings, {}),
549
620
  titleKey: "emptyState.noSupport.title",
550
621
  descriptionKey: "emptyState.noSupport.description"
551
622
  });
623
+ /**
624
+ * Root of the "No support" empty state — shown when the current browser can't
625
+ * render a page. Renders a `<div>` (the DS `Empty` container); pair it with an
626
+ * `EmptyStateExternalLink` for the "Learn more" action.
627
+ *
628
+ * @example
629
+ * ```tsx
630
+ * <NoSupportEmptyState>
631
+ * <EmptyStateHeader>
632
+ * <NoSupportMedia />
633
+ * <NoSupportTitle />
634
+ * <NoSupportDescription />
635
+ * </EmptyStateHeader>
636
+ * <EmptyStateActions>
637
+ * <EmptyStateExternalLink href={docsUrl} />
638
+ * </EmptyStateActions>
639
+ * </NoSupportEmptyState>
640
+ * ```
641
+ */
552
642
  const NoSupportEmptyState = NoSupport.Root;
643
+ /** Decorative media slot of the "No support" empty state (a settings icon). Renders a `<div>`, hidden from assistive tech. */
553
644
  const NoSupportMedia = NoSupport.Media;
645
+ /** Title line of the "No support" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
554
646
  const NoSupportTitle = NoSupport.Title;
647
+ /** Supporting description text of the "No support" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
555
648
  const NoSupportDescription = NoSupport.Description;
556
649
 
557
650
  //#endregion
558
651
  //#region src/components/unknown-error.tsx
559
- /**
560
- * UnknownError — shown when content fails to load unexpectedly. Pair it with an
561
- * `EmptyStateButton` (primary) for the "Try again" action. As an error state it
562
- * announces assertively via `role="alert"`.
563
- */
564
652
  const UnknownError = createEmptyStateVariant({
565
653
  name: "UnknownError",
566
654
  icon: /* @__PURE__ */ jsx(TriangleAlert, {}),
@@ -568,9 +656,32 @@ const UnknownError = createEmptyStateVariant({
568
656
  descriptionKey: "emptyState.unknownError.description",
569
657
  role: "alert"
570
658
  });
659
+ /**
660
+ * Root of the "Unknown error" empty state — shown when content fails to load
661
+ * unexpectedly. Renders a `<div>` (the DS `Empty` container) with `role="alert"`
662
+ * so it announces assertively; pair it with a primary `EmptyStateButton` for the
663
+ * "Try again" action.
664
+ *
665
+ * @example
666
+ * ```tsx
667
+ * <UnknownErrorEmptyState>
668
+ * <EmptyStateHeader>
669
+ * <UnknownErrorMedia />
670
+ * <UnknownErrorTitle />
671
+ * <UnknownErrorDescription />
672
+ * </EmptyStateHeader>
673
+ * <EmptyStateActions>
674
+ * <EmptyStateButton onClick={retry}>Try again</EmptyStateButton>
675
+ * </EmptyStateActions>
676
+ * </UnknownErrorEmptyState>
677
+ * ```
678
+ */
571
679
  const UnknownErrorEmptyState = UnknownError.Root;
680
+ /** Decorative media slot of the "Unknown error" empty state (a warning triangle icon). Renders a `<div>`, hidden from assistive tech. */
572
681
  const UnknownErrorMedia = UnknownError.Media;
682
+ /** Title line of the "Unknown error" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
573
683
  const UnknownErrorTitle = UnknownError.Title;
684
+ /** Supporting description text of the "Unknown error" empty state. Renders a `<div>` with the design copy by default; pass children to override. */
574
685
  const UnknownErrorDescription = UnknownError.Description;
575
686
 
576
687
  //#endregion
@@ -904,6 +1015,19 @@ function useCopyButtonContext() {
904
1015
  if (ctx === null) throw new Error("CopyButtonIcon and CopyButtonLabel must be rendered inside a CopyButton.");
905
1016
  return ctx;
906
1017
  }
1018
+ /**
1019
+ * Copy-to-clipboard button. Composes DS `Button`; copies `value` on click and
1020
+ * exposes a `copied` state (auto-reset after `timeout`) to its `CopyButtonIcon`
1021
+ * and `CopyButtonLabel` children via context. Renders a `<button>`.
1022
+ *
1023
+ * @example
1024
+ * ```tsx
1025
+ * <CopyButton value="npm i @aircall/ds">
1026
+ * <CopyButtonIcon />
1027
+ * <CopyButtonLabel />
1028
+ * </CopyButton>
1029
+ * ```
1030
+ */
907
1031
  const CopyButton = React.forwardRef((componentProps, forwardRef) => {
908
1032
  const { value, timeout, onCopied, variant = "outline", children, ...buttonProps } = componentProps;
909
1033
  const { copy, copied } = useCopyToClipboard(value, {
@@ -924,6 +1048,10 @@ const CopyButton = React.forwardRef((componentProps, forwardRef) => {
924
1048
  });
925
1049
  });
926
1050
  CopyButton.displayName = "CopyButton";
1051
+ /**
1052
+ * Icon for `CopyButton` that swaps between a copy glyph and a check glyph based on
1053
+ * the parent's copied state. Renders an `<svg>`. Must be used inside a `CopyButton`.
1054
+ */
927
1055
  const CopyButtonIcon = React.forwardRef((componentProps, forwardRef) => {
928
1056
  const { className } = componentProps;
929
1057
  const { copied } = useCopyButtonContext();
@@ -933,6 +1061,10 @@ const CopyButtonIcon = React.forwardRef((componentProps, forwardRef) => {
933
1061
  });
934
1062
  });
935
1063
  CopyButtonIcon.displayName = "CopyButtonIcon";
1064
+ /**
1065
+ * Text label for `CopyButton` that shows `label` normally and `copiedLabel` after a
1066
+ * successful copy. Renders a `<span>`. Must be used inside a `CopyButton`.
1067
+ */
936
1068
  const CopyButtonLabel = React.forwardRef((componentProps, forwardRef) => {
937
1069
  const { label = "Copy", copiedLabel = "Copied", className } = componentProps;
938
1070
  const { copied } = useCopyButtonContext();
@@ -1039,6 +1171,22 @@ const MARKDOWN_COMPONENTS = {
1039
1171
  ...props
1040
1172
  })
1041
1173
  };
1174
+ /**
1175
+ * Renders a chatbot response from markdown, splitting it into markdown text and
1176
+ * embedded component blocks (table, audio, transcript, loading), with a sources
1177
+ * hover card and copy / thumbs-up / thumbs-down feedback controls. Renders a
1178
+ * `<div>` (`data-slot="chatbot-response-block"`).
1179
+ *
1180
+ * @example
1181
+ * ```tsx
1182
+ * <ChatbotResponseBlock
1183
+ * messageId="msg-1"
1184
+ * markdown="**Hello** from the assistant"
1185
+ * sources={[{ title: 'Help center', url: 'https://help.aircall.io' }]}
1186
+ * onFeedback={value => console.log(value)}
1187
+ * />
1188
+ * ```
1189
+ */
1042
1190
  function ChatbotResponseBlock({ messageId, markdown, streaming = false, sources, onFeedback, className }) {
1043
1191
  const t = useDsTranslation("blocks");
1044
1192
  const [feedback, setFeedback] = useState(null);
@@ -1156,6 +1304,26 @@ function ChatbotResponseLoading({ text, className }) {
1156
1304
 
1157
1305
  //#endregion
1158
1306
  //#region src/components/chatbot-page.tsx
1307
+ /**
1308
+ * Root layout shell for the AI chatbot experience; provides the `SidebarProvider`
1309
+ * context required by `ChatbotSidebar` and lays out the sidebar and content
1310
+ * columns. Renders a `SidebarProvider` (a `<div>` wrapper) with the sidebar width
1311
+ * preset and full-height overrides for panel/modal contexts.
1312
+ *
1313
+ * @example
1314
+ * ```tsx
1315
+ * <ChatbotPage>
1316
+ * <ChatbotSidebar conversations={[...]} />
1317
+ * <ChatbotPageContent>
1318
+ * <ChatbotPageBody>
1319
+ * <ChatbotPageHeading>Need help?</ChatbotPageHeading>
1320
+ * <ChatbotInput />
1321
+ * </ChatbotPageBody>
1322
+ * <ChatbotPageFooter betaTermsHref="https://legal.aircall.io/..." />
1323
+ * </ChatbotPageContent>
1324
+ * </ChatbotPage>
1325
+ * ```
1326
+ */
1159
1327
  const ChatbotPage = React.forwardRef((componentProps, forwardRef) => {
1160
1328
  const { children, className } = componentProps;
1161
1329
  return /* @__PURE__ */ jsx(SidebarProvider, {
@@ -1474,6 +1642,19 @@ function ChatbotPanelHeader({ title = "Ask Aircall", onMenu, menuContent, menuOp
1474
1642
  //#region src/components/chatbot-sidebar.tsx
1475
1643
  const SIDEBAR_MIN_WIDTH = 140;
1476
1644
  const SIDEBAR_MAX_WIDTH = 480;
1645
+ /**
1646
+ * Conversation-history sidebar: an optional "New Chat" entry plus a scrollable,
1647
+ * resizable list of recent conversations, each with an optional trailing ⋯ menu.
1648
+ * Renders the DS `Sidebar` (a `<div>`), or a plain `<div>` when `popup`. Must be
1649
+ * rendered inside a `SidebarProvider`.
1650
+ *
1651
+ * @example
1652
+ * ```tsx
1653
+ * <SidebarProvider>
1654
+ * <ChatbotSidebar conversations={items} onSelectConversation={open} />
1655
+ * </SidebarProvider>
1656
+ * ```
1657
+ */
1477
1658
  const ChatbotSidebar = React.forwardRef((componentProps, forwardRef) => {
1478
1659
  const { conversations, activeConversationId, onNewChat, onSelectConversation, renderConversationMenuContent, recentLabel = "Recent", showNewChat = true, popup = false, className } = componentProps;
1479
1660
  const t = useDsTranslation("blocks");
@@ -1565,6 +1746,17 @@ ChatbotSidebar.displayName = "ChatbotSidebar";
1565
1746
 
1566
1747
  //#endregion
1567
1748
  //#region src/components/chatbot-panel-suggestion.tsx
1749
+ /**
1750
+ * Pill-shaped prompt suggestion shown in the chatbot panel; a preset styling of
1751
+ * `Button` with a green border and surface background. Renders a `<button>`.
1752
+ *
1753
+ * @example
1754
+ * ```tsx
1755
+ * <ChatbotPanelSuggestion onClick={() => ask('How do I set my phone line?')}>
1756
+ * How do I set my phone line?
1757
+ * </ChatbotPanelSuggestion>
1758
+ * ```
1759
+ */
1568
1760
  function ChatbotPanelSuggestion({ className, ...props }) {
1569
1761
  return /* @__PURE__ */ jsx(Button, {
1570
1762
  "data-slot": "chatbot-panel-suggestion",
@@ -1597,6 +1789,18 @@ const textareaVariants = cva([
1597
1789
  expanded: false
1598
1790
  }
1599
1791
  });
1792
+ /**
1793
+ * Chatbot message composer: an auto-growing `InputGroup` textarea with a send/stop
1794
+ * button, plus optional suggestion pills and a conversation-history popover. Works
1795
+ * controlled (`value` + `onValueChange`) or uncontrolled. Enter submits;
1796
+ * Shift+Enter inserts a newline. Renders the DS `InputGroup` (a `<div>`) wrapping a
1797
+ * `<textarea>`.
1798
+ *
1799
+ * @example
1800
+ * ```tsx
1801
+ * <ChatbotInput value={text} onValueChange={setText} onSubmit={send} />
1802
+ * ```
1803
+ */
1600
1804
  function ChatbotInput({ className, value, onValueChange, onSubmit, onStop, placeholder, loading = false, size = "default", expanded = false, disabled, suggestions, onSuggestionClick, conversations, activeConversationId, onSelectConversation, ...textareaProps }) {
1601
1805
  const t = useDsTranslation("blocks");
1602
1806
  const [currentValue = "", setCurrentValue] = useControllableState({
@@ -1715,6 +1919,16 @@ function ChatbotInput({ className, value, onValueChange, onSubmit, onStop, place
1715
1919
 
1716
1920
  //#endregion
1717
1921
  //#region src/components/chatbot-user-message.tsx
1922
+ /**
1923
+ * Right-aligned chat bubble for a user's message; clamps long content to six
1924
+ * lines with a "Show more" / "Show less" toggle. Renders a `<div>`
1925
+ * (`data-slot="chatbot-user-message"`).
1926
+ *
1927
+ * @example
1928
+ * ```tsx
1929
+ * <ChatbotUserMessage>How do I set up my phone number?</ChatbotUserMessage>
1930
+ * ```
1931
+ */
1718
1932
  function ChatbotUserMessage({ className, children, ...props }) {
1719
1933
  const [expanded, setExpanded] = useState(false);
1720
1934
  const [showToggle, setShowToggle] = useState(false);
@@ -1744,6 +1958,25 @@ function ChatbotUserMessage({ className, children, ...props }) {
1744
1958
 
1745
1959
  //#endregion
1746
1960
  //#region src/components/dashboard-standalone-page.tsx
1961
+ /**
1962
+ * Full-screen takeover shell for focused, sidebar-less flows; renders a flex-row `<div>`
1963
+ * holding one or more `DashboardStandalonePageContent` panels side by side.
1964
+ *
1965
+ * @example
1966
+ * ```tsx
1967
+ * <DashboardStandalonePage>
1968
+ * <DashboardStandalonePageContent>
1969
+ * <DashboardStandalonePageHeader>
1970
+ * <DashboardStandalonePageTitle>Create user</DashboardStandalonePageTitle>
1971
+ * <DashboardStandalonePageActions side="start">
1972
+ * <DashboardStandalonePageAction>Cancel</DashboardStandalonePageAction>
1973
+ * </DashboardStandalonePageActions>
1974
+ * </DashboardStandalonePageHeader>
1975
+ * <DashboardStandalonePageMain>…</DashboardStandalonePageMain>
1976
+ * </DashboardStandalonePageContent>
1977
+ * </DashboardStandalonePage>
1978
+ * ```
1979
+ */
1747
1980
  const DashboardStandalonePage = React.forwardRef((componentProps, forwardRef) => {
1748
1981
  const { className, ...props } = componentProps;
1749
1982
  return /* @__PURE__ */ jsx("div", {
@@ -1754,6 +1987,10 @@ const DashboardStandalonePage = React.forwardRef((componentProps, forwardRef) =>
1754
1987
  });
1755
1988
  });
1756
1989
  DashboardStandalonePage.displayName = "DashboardStandalonePage";
1990
+ /**
1991
+ * Rounded, bordered content panel that fills the shell; renders a `<div>`.
1992
+ * Typically wraps a `DashboardStandalonePageHeader` above a `DashboardStandalonePageMain`.
1993
+ */
1757
1994
  const DashboardStandalonePageContent = React.forwardRef((componentProps, forwardRef) => {
1758
1995
  const { className, ...props } = componentProps;
1759
1996
  return /* @__PURE__ */ jsx("div", {
@@ -1764,6 +2001,10 @@ const DashboardStandalonePageContent = React.forwardRef((componentProps, forward
1764
2001
  });
1765
2002
  });
1766
2003
  DashboardStandalonePageContent.displayName = "DashboardStandalonePageContent";
2004
+ /**
2005
+ * Fixed-height (64px) header bar with an optically centered title and absolutely
2006
+ * positioned action slots; renders a `<header>`.
2007
+ */
1767
2008
  const DashboardStandalonePageHeader = React.forwardRef((componentProps, forwardRef) => {
1768
2009
  const { className, ...props } = componentProps;
1769
2010
  return /* @__PURE__ */ jsx("header", {
@@ -1774,6 +2015,9 @@ const DashboardStandalonePageHeader = React.forwardRef((componentProps, forwardR
1774
2015
  });
1775
2016
  });
1776
2017
  DashboardStandalonePageHeader.displayName = "DashboardStandalonePageHeader";
2018
+ /**
2019
+ * Centered, truncated page title in the header; renders an `<h1>`.
2020
+ */
1777
2021
  const DashboardStandalonePageTitle = React.forwardRef((componentProps, forwardRef) => {
1778
2022
  const { className, ...props } = componentProps;
1779
2023
  return /* @__PURE__ */ jsx("h1", {
@@ -1784,6 +2028,9 @@ const DashboardStandalonePageTitle = React.forwardRef((componentProps, forwardRe
1784
2028
  });
1785
2029
  });
1786
2030
  DashboardStandalonePageTitle.displayName = "DashboardStandalonePageTitle";
2031
+ /**
2032
+ * Optional subtitle stacked beneath the title in the header; renders a `<p>`.
2033
+ */
1787
2034
  const DashboardStandalonePageDescription = React.forwardRef((componentProps, forwardRef) => {
1788
2035
  const { className, ...props } = componentProps;
1789
2036
  return /* @__PURE__ */ jsx("p", {
@@ -1794,6 +2041,10 @@ const DashboardStandalonePageDescription = React.forwardRef((componentProps, for
1794
2041
  });
1795
2042
  });
1796
2043
  DashboardStandalonePageDescription.displayName = "DashboardStandalonePageDescription";
2044
+ /**
2045
+ * Action slot absolutely pinned to the header's left or right edge; renders a `<div>`.
2046
+ * Sitting outside the flow, it never shifts the centered title.
2047
+ */
1797
2048
  const DashboardStandalonePageActions = React.forwardRef((componentProps, forwardRef) => {
1798
2049
  const { side = "end", className, ...props } = componentProps;
1799
2050
  return /* @__PURE__ */ jsx("div", {
@@ -1805,6 +2056,9 @@ const DashboardStandalonePageActions = React.forwardRef((componentProps, forward
1805
2056
  });
1806
2057
  });
1807
2058
  DashboardStandalonePageActions.displayName = "DashboardStandalonePageActions";
2059
+ /**
2060
+ * Header action button rendering a ds `Button` (ghost, `lg` by default); renders a `<button>`.
2061
+ */
1808
2062
  const DashboardStandalonePageAction = React.forwardRef((componentProps, forwardRef) => {
1809
2063
  const { variant = "ghost", ...props } = componentProps;
1810
2064
  return /* @__PURE__ */ jsx(Button, {
@@ -1815,6 +2069,9 @@ const DashboardStandalonePageAction = React.forwardRef((componentProps, forwardR
1815
2069
  });
1816
2070
  });
1817
2071
  DashboardStandalonePageAction.displayName = "DashboardStandalonePageAction";
2072
+ /**
2073
+ * Scrollable, transparent content area below the header inside the panel; renders a `<main>`.
2074
+ */
1818
2075
  const DashboardStandalonePageMain = React.forwardRef((componentProps, forwardRef) => {
1819
2076
  const { className, ...props } = componentProps;
1820
2077
  return /* @__PURE__ */ jsx("main", {
@@ -1828,6 +2085,21 @@ DashboardStandalonePageMain.displayName = "DashboardStandalonePageMain";
1828
2085
 
1829
2086
  //#endregion
1830
2087
  //#region src/components/dashboard-page.tsx
2088
+ /**
2089
+ * Full-screen outer shell for a dashboard view; renders a `<div>`.
2090
+ * Stacks an optional `DashboardPageBanner` above a `DashboardSidebarProvider`
2091
+ * that holds the sidebar and a `DashboardPageContent`.
2092
+ *
2093
+ * @example
2094
+ * ```tsx
2095
+ * <DashboardPage>
2096
+ * <DashboardSidebarProvider>
2097
+ * <DashboardSidebar>…</DashboardSidebar>
2098
+ * <DashboardPageContent>…</DashboardPageContent>
2099
+ * </DashboardSidebarProvider>
2100
+ * </DashboardPage>
2101
+ * ```
2102
+ */
1831
2103
  const DashboardPage = React.forwardRef((componentProps, forwardRef) => {
1832
2104
  const { className, ...props } = componentProps;
1833
2105
  return /* @__PURE__ */ jsx("div", {
@@ -1838,6 +2110,10 @@ const DashboardPage = React.forwardRef((componentProps, forwardRef) => {
1838
2110
  });
1839
2111
  });
1840
2112
  DashboardPage.displayName = "DashboardPage";
2113
+ /**
2114
+ * Full-width top row that sits flush above the sidebar/content row; renders a `<div>`.
2115
+ * Use to host trial notices, announcements, or any ds `Banner`.
2116
+ */
1841
2117
  const DashboardPageBanner = React.forwardRef((componentProps, forwardRef) => {
1842
2118
  const { className, ...props } = componentProps;
1843
2119
  return /* @__PURE__ */ jsx("div", {
@@ -1848,16 +2124,22 @@ const DashboardPageBanner = React.forwardRef((componentProps, forwardRef) => {
1848
2124
  });
1849
2125
  });
1850
2126
  DashboardPageBanner.displayName = "DashboardPageBanner";
2127
+ /**
2128
+ * White content card filling the right column beside the sidebar; renders a `<div>`.
2129
+ */
1851
2130
  const DashboardPageContent = React.forwardRef((componentProps, forwardRef) => {
1852
2131
  const { className, ...props } = componentProps;
1853
2132
  return /* @__PURE__ */ jsx("div", {
1854
2133
  ref: forwardRef,
1855
2134
  "data-slot": "dashboard-page-content",
1856
- className: cn("flex-1 min-w-0 flex flex-col bg-background rounded-xl border border-border overflow-hidden", "[&:has([data-slot=dph-tabs])>[data-slot=dph]]:border-b-0", className),
2135
+ className: cn("flex-1 min-w-0 h-full flex flex-col bg-background rounded-xl border border-border overflow-hidden", "[&:has([data-slot=dph-tabs])>[data-slot=dph]]:border-b-0", className),
1857
2136
  ...props
1858
2137
  });
1859
2138
  });
1860
2139
  DashboardPageContent.displayName = "DashboardPageContent";
2140
+ /**
2141
+ * Scrollable content area inside `DashboardPageContent`; renders a `<main>`.
2142
+ */
1861
2143
  const DashboardPageMain = React.forwardRef((componentProps, forwardRef) => {
1862
2144
  const { className, ...props } = componentProps;
1863
2145
  return /* @__PURE__ */ jsx("main", {
@@ -1868,6 +2150,9 @@ const DashboardPageMain = React.forwardRef((componentProps, forwardRef) => {
1868
2150
  });
1869
2151
  });
1870
2152
  DashboardPageMain.displayName = "DashboardPageMain";
2153
+ /**
2154
+ * Left-aligned tab bar placed as a sibling of `DashboardPageHeader`; renders a ds `TabsList`.
2155
+ */
1871
2156
  const DashboardPageTabs = React.forwardRef((componentProps, forwardRef) => {
1872
2157
  const { className, ...props } = componentProps;
1873
2158
  return /* @__PURE__ */ jsx(TabsList, {
@@ -1881,6 +2166,20 @@ DashboardPageTabs.displayName = "DashboardPageTabs";
1881
2166
 
1882
2167
  //#endregion
1883
2168
  //#region src/components/dashboard-page-header.tsx
2169
+ /**
2170
+ * Header for a `DashboardPageContent`; renders a `<div>` that establishes a
2171
+ * `@container` context with an inner CSS-grid its sub-components self-place into.
2172
+ *
2173
+ * @example
2174
+ * ```tsx
2175
+ * <DashboardPageHeader>
2176
+ * <DashboardPageHeaderTitle>Team</DashboardPageHeaderTitle>
2177
+ * <DashboardPageHeaderActions>
2178
+ * <DashboardPageHeaderAction>Invite</DashboardPageHeaderAction>
2179
+ * </DashboardPageHeaderActions>
2180
+ * </DashboardPageHeader>
2181
+ * ```
2182
+ */
1884
2183
  const DashboardPageHeader = React.forwardRef((componentProps, forwardRef) => {
1885
2184
  const { className, children, ...props } = componentProps;
1886
2185
  return /* @__PURE__ */ jsx("div", {
@@ -1896,6 +2195,9 @@ const DashboardPageHeader = React.forwardRef((componentProps, forwardRef) => {
1896
2195
  });
1897
2196
  });
1898
2197
  DashboardPageHeader.displayName = "DashboardPageHeader";
2198
+ /**
2199
+ * Back-navigation row for Level 2 headers; renders a `<div>` in the grid `nav` area.
2200
+ */
1899
2201
  const DashboardPageHeaderNav = React.forwardRef((componentProps, forwardRef) => {
1900
2202
  const { className, children, ...props } = componentProps;
1901
2203
  return /* @__PURE__ */ jsx("div", {
@@ -1907,6 +2209,10 @@ const DashboardPageHeaderNav = React.forwardRef((componentProps, forwardRef) =>
1907
2209
  });
1908
2210
  });
1909
2211
  DashboardPageHeaderNav.displayName = "DashboardPageHeaderNav";
2212
+ /**
2213
+ * Back button rendering a ghost, small ds `Button` with a leading chevron icon.
2214
+ * Accepts a render prop so it can become an `<a>` or router `<Link>`.
2215
+ */
1910
2216
  const DashboardPageHeaderNavBack = React.forwardRef((componentProps, forwardRef) => {
1911
2217
  const { children, ...props } = componentProps;
1912
2218
  return /* @__PURE__ */ jsxs(Button, {
@@ -1919,6 +2225,9 @@ const DashboardPageHeaderNavBack = React.forwardRef((componentProps, forwardRef)
1919
2225
  });
1920
2226
  });
1921
2227
  DashboardPageHeaderNavBack.displayName = "DashboardPageHeaderNavBack";
2228
+ /**
2229
+ * Icon/flag slot shown left of the title; renders a `<div>` in the grid `prefix` area.
2230
+ */
1922
2231
  const DashboardPageHeaderPrefix = React.forwardRef((componentProps, forwardRef) => {
1923
2232
  const { className, children, ...props } = componentProps;
1924
2233
  return /* @__PURE__ */ jsx("div", {
@@ -1930,6 +2239,9 @@ const DashboardPageHeaderPrefix = React.forwardRef((componentProps, forwardRef)
1930
2239
  });
1931
2240
  });
1932
2241
  DashboardPageHeaderPrefix.displayName = "DashboardPageHeaderPrefix";
2242
+ /**
2243
+ * Wrapper that stacks the title and subtitle; renders a `<div>` in the grid `info` area.
2244
+ */
1933
2245
  const DashboardPageHeaderTitleGroup = React.forwardRef((componentProps, forwardRef) => {
1934
2246
  const { className, children, ...props } = componentProps;
1935
2247
  return /* @__PURE__ */ jsx("div", {
@@ -1941,6 +2253,10 @@ const DashboardPageHeaderTitleGroup = React.forwardRef((componentProps, forwardR
1941
2253
  });
1942
2254
  });
1943
2255
  DashboardPageHeaderTitleGroup.displayName = "DashboardPageHeaderTitleGroup";
2256
+ /**
2257
+ * Page title; renders an `<h1>`, self-placing in the grid `info` area or deferring
2258
+ * layout to `DashboardPageHeaderTitleGroup` when nested inside one.
2259
+ */
1944
2260
  const DashboardPageHeaderTitle = React.forwardRef((componentProps, forwardRef) => {
1945
2261
  const { size = "lg", className, children, ...props } = componentProps;
1946
2262
  return /* @__PURE__ */ jsx("h1", {
@@ -1952,6 +2268,9 @@ const DashboardPageHeaderTitle = React.forwardRef((componentProps, forwardRef) =
1952
2268
  });
1953
2269
  });
1954
2270
  DashboardPageHeaderTitle.displayName = "DashboardPageHeaderTitle";
2271
+ /**
2272
+ * Optional subtitle line/block placed beneath the title; renders a `<div>`.
2273
+ */
1955
2274
  const DashboardPageHeaderSubtitle = React.forwardRef((componentProps, forwardRef) => {
1956
2275
  const { className, children, ...props } = componentProps;
1957
2276
  return /* @__PURE__ */ jsx("div", {
@@ -1963,6 +2282,9 @@ const DashboardPageHeaderSubtitle = React.forwardRef((componentProps, forwardRef
1963
2282
  });
1964
2283
  });
1965
2284
  DashboardPageHeaderSubtitle.displayName = "DashboardPageHeaderSubtitle";
2285
+ /**
2286
+ * Muted, clamped description text under the title; renders a `<div>`.
2287
+ */
1966
2288
  const DashboardPageHeaderDescription = React.forwardRef((componentProps, forwardRef) => {
1967
2289
  const { className, children, ...props } = componentProps;
1968
2290
  return /* @__PURE__ */ jsx("div", {
@@ -1974,6 +2296,9 @@ const DashboardPageHeaderDescription = React.forwardRef((componentProps, forward
1974
2296
  });
1975
2297
  });
1976
2298
  DashboardPageHeaderDescription.displayName = "DashboardPageHeaderDescription";
2299
+ /**
2300
+ * Flex container for header actions; renders a `<div>` in the grid `actions` area.
2301
+ */
1977
2302
  const DashboardPageHeaderActions = React.forwardRef((componentProps, forwardRef) => {
1978
2303
  const { className, children, ...props } = componentProps;
1979
2304
  return /* @__PURE__ */ jsx("div", {
@@ -1985,6 +2310,10 @@ const DashboardPageHeaderActions = React.forwardRef((componentProps, forwardRef)
1985
2310
  });
1986
2311
  });
1987
2312
  DashboardPageHeaderActions.displayName = "DashboardPageHeaderActions";
2313
+ /**
2314
+ * Header action button rendering a ds `Button` locked to the actions area sizes;
2315
+ * renders a `<button>` (defaults to a labeled `lg` CTA, or `icon-lg` for icon-only triggers).
2316
+ */
1988
2317
  const DashboardPageHeaderAction = React.forwardRef((componentProps, forwardRef) => {
1989
2318
  const { size = "lg", ...props } = componentProps;
1990
2319
  return /* @__PURE__ */ jsx(Button, {
@@ -2275,6 +2604,20 @@ function ChatbotPanelTrigger({ children = "Ask anything", icon = /* @__PURE__ */
2275
2604
 
2276
2605
  //#endregion
2277
2606
  //#region src/components/chatbot-expand-suggestion.tsx
2607
+ /**
2608
+ * Displays category filter pills and a list of clickable suggestion rows for the
2609
+ * chatbot idle state. Renders a `<div>` wrapping an optional `ToggleGroup` of
2610
+ * category pills and a list of `Item` rows separated by `Separator`.
2611
+ *
2612
+ * @example
2613
+ * ```tsx
2614
+ * <ChatbotExpandSuggestion
2615
+ * categories={[{ value: 'billing', label: 'Billing' }]}
2616
+ * suggestions={[{ id: '1', text: 'How do I reset my password?' }]}
2617
+ * onSuggestionClick={suggestion => console.log(suggestion.text)}
2618
+ * />
2619
+ * ```
2620
+ */
2278
2621
  const ChatbotExpandSuggestion = React.forwardRef((componentProps, forwardRef) => {
2279
2622
  const { categories, selectedCategory: selectedCategoryProp, onCategoryChange, label = "Suggestions", suggestions, onSuggestionClick, className, ...props } = componentProps;
2280
2623
  const [selectedCategory, setSelectedCategory] = useControllableState({
@@ -2327,6 +2670,21 @@ const MAX_WIDTH = 768;
2327
2670
  const KEYBOARD_RESIZE_STEP = 16;
2328
2671
  const DISCLAIMER_LINK_HREF = "https://legal.aircall.io/#template-9jw4r0usl";
2329
2672
  const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
2673
+ /**
2674
+ * Presentational chatbot surface — header, scrollable conversation area (or a
2675
+ * built-in empty state), composer, and disclaimer — in a width-resizable shell.
2676
+ * Owns no visibility state (the consumer controls show/hide); pass the conversation
2677
+ * as `children`, and no children renders the empty state. Renders a `<div>`
2678
+ * container.
2679
+ *
2680
+ * @example
2681
+ * ```tsx
2682
+ * <ChatbotPanel onClose={close} onSubmit={send}>
2683
+ * <ChatbotUserMessage>Hi</ChatbotUserMessage>
2684
+ * <ChatbotResponseBlock>Hello!</ChatbotResponseBlock>
2685
+ * </ChatbotPanel>
2686
+ * ```
2687
+ */
2330
2688
  function ChatbotPanel({ title, onMenu, conversations, activeConversationId, onNewChat, onSelectConversation, renderConversationMenuContent, onExpand, onClose, emptyTitle, emptyDescription, suggestions = [], onSuggestionSelect, inputValue, onInputValueChange, onSubmit, onStop, loading = false, loadingText, placeholder, autoFocus, disclaimer, resizable = true, defaultWidth = DEFAULT_WIDTH, minWidth = MIN_WIDTH, maxWidth = MAX_WIDTH, onWidthChange, className, style, children, ...props }) {
2331
2689
  const t = useDsTranslation("blocks");
2332
2690
  const [menuOpen, setMenuOpen] = React.useState(false);
@@ -2538,9 +2896,49 @@ function ChatbotPanel({ title, onMenu, conversations, activeConversationId, onNe
2538
2896
  */
2539
2897
  const { fieldContext, formContext, useFieldContext, useFormContext } = createFormHookContexts();
2540
2898
 
2899
+ //#endregion
2900
+ //#region src/components/save-bar.tsx
2901
+ function SaveBar({ isDirty, isSubmitting, canSubmit, onReset, submitLabel = "Save changes", savingLabel = "Saving…", resetLabel = "Discard", className }) {
2902
+ return /* @__PURE__ */ jsx("div", {
2903
+ "data-slot": "card-footer",
2904
+ className: cn("grid transition-[grid-template-rows] duration-300 ease-in-out", isDirty ? "grid-rows-[1fr]" : "grid-rows-[0fr]", className),
2905
+ children: /* @__PURE__ */ jsx("div", {
2906
+ className: "overflow-hidden",
2907
+ children: /* @__PURE__ */ jsxs("div", {
2908
+ className: "flex items-center justify-end gap-2 border-t p-4",
2909
+ children: [/* @__PURE__ */ jsx(Button, {
2910
+ type: "button",
2911
+ variant: "ghost",
2912
+ onClick: onReset,
2913
+ disabled: !isDirty || isSubmitting,
2914
+ children: resetLabel
2915
+ }), /* @__PURE__ */ jsx(Button, {
2916
+ type: "submit",
2917
+ disabled: !isDirty || !canSubmit || isSubmitting,
2918
+ children: isSubmitting ? savingLabel : submitLabel
2919
+ })]
2920
+ })
2921
+ })
2922
+ });
2923
+ }
2924
+
2541
2925
  //#endregion
2542
2926
  //#region src/components/card-save-bar.tsx
2543
- function CardSaveBar({ submitLabel = "Save changes", savingLabel = "Saving…", resetLabel = "Discard" }) {
2927
+ /**
2928
+ * Save/discard bar for card-layout forms — the TanStack Form adapter around
2929
+ * `SaveBar`. Reads `isDirty`, `isSubmitting`, and `canSubmit` from form context
2930
+ * and renders `SaveBar` (which owns the animation, buttons, and the
2931
+ * `data-slot="card-footer"` that flushes it to the card edge).
2932
+ *
2933
+ * Must be placed **inside** the `<form>` element and wrapped by `form.AppForm`
2934
+ * (or any `formContext` provider).
2935
+ *
2936
+ * @example
2937
+ * <form.AppForm>
2938
+ * <form.CardSaveBar submitLabel="Save" resetLabel="Discard" />
2939
+ * </form.AppForm>
2940
+ */
2941
+ function CardSaveBar({ submitLabel, savingLabel, resetLabel }) {
2544
2942
  const form = useFormContext();
2545
2943
  return /* @__PURE__ */ jsx(form.Subscribe, {
2546
2944
  selector: (s) => ({
@@ -2548,31 +2946,34 @@ function CardSaveBar({ submitLabel = "Save changes", savingLabel = "Saving…",
2548
2946
  isSubmitting: s.isSubmitting,
2549
2947
  canSubmit: s.canSubmit
2550
2948
  }),
2551
- children: ({ isDirty, isSubmitting, canSubmit }) => /* @__PURE__ */ jsx("div", {
2552
- className: cn("grid transition-[grid-template-rows] duration-300 ease-in-out", isDirty ? "grid-rows-[1fr]" : "grid-rows-[0fr]"),
2553
- children: /* @__PURE__ */ jsx("div", {
2554
- className: "overflow-hidden",
2555
- children: /* @__PURE__ */ jsxs("div", {
2556
- className: "flex items-center justify-end gap-2 border-t px-6 py-3",
2557
- children: [/* @__PURE__ */ jsx(Button, {
2558
- type: "button",
2559
- variant: "ghost",
2560
- onClick: () => form.reset(),
2561
- disabled: !isDirty || isSubmitting,
2562
- children: resetLabel
2563
- }), /* @__PURE__ */ jsx(Button, {
2564
- type: "submit",
2565
- disabled: !isDirty || !canSubmit || isSubmitting,
2566
- children: isSubmitting ? savingLabel : submitLabel
2567
- })]
2568
- })
2569
- })
2949
+ children: ({ isDirty, isSubmitting, canSubmit }) => /* @__PURE__ */ jsx(SaveBar, {
2950
+ isDirty,
2951
+ isSubmitting,
2952
+ canSubmit,
2953
+ onReset: () => form.reset(),
2954
+ submitLabel,
2955
+ savingLabel,
2956
+ resetLabel
2570
2957
  })
2571
2958
  });
2572
2959
  }
2573
2960
 
2574
2961
  //#endregion
2575
2962
  //#region src/components/submit-button.tsx
2963
+ /**
2964
+ * Context-aware submit button. Disables itself when the form cannot be submitted or is submitting.
2965
+ * Shows `loadingLabel` (default `"Saving…"`) while submitting.
2966
+ *
2967
+ * Renders a DS `<Button type="submit">` (a `<button>` element).
2968
+ * Must be a descendant of `form.AppForm` (or any `formContext` provider).
2969
+ * Use for inline/flat layouts where `CardSaveBar` is not needed.
2970
+ * Accepts all `Button` props except `type` and `disabled` (managed internally).
2971
+ *
2972
+ * @example
2973
+ * <form.AppForm>
2974
+ * <form.SubmitButton loadingLabel="Saving…">Save</form.SubmitButton>
2975
+ * </form.AppForm>
2976
+ */
2576
2977
  function SubmitButton({ children = "Submit", loadingLabel, className, ...buttonProps }) {
2577
2978
  return /* @__PURE__ */ jsx(useFormContext().Subscribe, {
2578
2979
  selector: (s) => ({
@@ -2636,6 +3037,13 @@ function toFieldErrors(errors) {
2636
3037
 
2637
3038
  //#endregion
2638
3039
  //#region src/components/form-field.tsx
3040
+ /**
3041
+ * Internal layout shell shared by every `Form*Field` wrapper. Normalizes the
3042
+ * `label` / `description` props, lays out the `Field → label row → description →
3043
+ * control → error` skeleton per `orientation` / `controlVariant`, and applies the
3044
+ * error-display policy plus `data-invalid`. Reads the bound field from context,
3045
+ * so it must render inside `form.AppField`. Renders a DS `Field`.
3046
+ */
2639
3047
  function FormFieldShell({ label, description, necessityIndicator, id, children, orientation = "vertical", controlPosition = "end", controlVariant = "fill" }) {
2640
3048
  const errors = useFieldContext().state.meta.errors;
2641
3049
  const labelContent = typeof label === "string" ? label : label?.content;
@@ -3131,34 +3539,147 @@ function FormToggleGroupField(props) {
3131
3539
  }
3132
3540
 
3133
3541
  //#endregion
3134
- //#region src/components/save-bar.tsx
3135
- function SaveBar({ isDirty, isSubmitting, canSubmit, onReset, submitLabel = "Save changes", savingLabel = "Saving…", resetLabel = "Discard", className }) {
3136
- return /* @__PURE__ */ jsx("div", {
3137
- className: cn("grid transition-[grid-template-rows] duration-300 ease-in-out", isDirty ? "grid-rows-[1fr]" : "grid-rows-[0fr]", className),
3138
- children: /* @__PURE__ */ jsx("div", {
3139
- className: "overflow-hidden",
3140
- children: /* @__PURE__ */ jsxs("div", {
3141
- className: "flex items-center justify-end gap-2 border-t px-4 py-2",
3142
- children: [/* @__PURE__ */ jsx(Button, {
3143
- type: "button",
3144
- variant: "ghost",
3145
- size: "sm",
3146
- onClick: onReset,
3147
- disabled: !isDirty || isSubmitting,
3148
- children: resetLabel
3149
- }), /* @__PURE__ */ jsx(Button, {
3150
- type: "submit",
3151
- size: "sm",
3152
- disabled: !isDirty || !canSubmit || isSubmitting,
3153
- children: isSubmitting ? savingLabel : submitLabel
3154
- })]
3155
- })
3156
- })
3542
+ //#region src/components/setting-card.tsx
3543
+ /**
3544
+ * Root container for a setting card. Renders the DS `Card`.
3545
+ *
3546
+ * By default the level (and therefore the background) is detected automatically:
3547
+ * a top-level card is level 1 (muted background, borderless); a card nested
3548
+ * inside another card's `SettingCardContent` becomes level 2 (white background,
3549
+ * border). Pass `level` to force a specific level — needed for the rare third
3550
+ * nesting level, which reuses the level-1 look (`level={1}`).
3551
+ *
3552
+ * @example
3553
+ * ```tsx
3554
+ * <SettingCard>
3555
+ * <SettingCardHeader>
3556
+ * <SettingCardTitle>Call recording</SettingCardTitle>
3557
+ * <SettingCardDescription>Record inbound and outbound calls.</SettingCardDescription>
3558
+ * <SettingCardAction>
3559
+ * <Switch checked={enabled} onCheckedChange={setEnabled} />
3560
+ * </SettingCardAction>
3561
+ * </SettingCardHeader>
3562
+ * {enabled && <SettingCardContent>…</SettingCardContent>}
3563
+ * </SettingCard>
3564
+ * ```
3565
+ *
3566
+ * @example
3567
+ * ```tsx
3568
+ * // With a save/discard bar: put the form on the OUTER level and drop
3569
+ * // `form.CardSaveBar` in as the last child. It reads dirty/submitting/canSubmit
3570
+ * // from form context, slides in when dirty, and carries `data-slot="card-footer"`
3571
+ * // so the card flushes it to the edge automatically. No `className` needed.
3572
+ * <form onSubmit={e => { e.preventDefault(); void form.handleSubmit(); }}>
3573
+ * <SettingCard>
3574
+ * <SettingCardHeader>
3575
+ * <SettingCardTitle>Profile</SettingCardTitle>
3576
+ * <SettingCardDescription>Update your display name.</SettingCardDescription>
3577
+ * </SettingCardHeader>
3578
+ * <SettingCardContent>…</SettingCardContent>
3579
+ * <form.AppForm>
3580
+ * <form.CardSaveBar resetLabel="Undo" />
3581
+ * </form.AppForm>
3582
+ * </SettingCard>
3583
+ * </form>
3584
+ * ```
3585
+ */
3586
+ const SettingCard = React.forwardRef((componentProps, forwardRef) => {
3587
+ const { className, level, ...props } = componentProps;
3588
+ const isAuto = level === void 0;
3589
+ return /* @__PURE__ */ jsx(Card, {
3590
+ ref: forwardRef,
3591
+ "data-level": level,
3592
+ className: cn(isAuto && "bg-accent border-transparent [[data-setting-card-content]_&]:border-border [[data-setting-card-content]_&]:bg-card", level === 1 && "bg-accent border-transparent", level === 2 && "border-border bg-card", className),
3593
+ ...props
3157
3594
  });
3158
- }
3595
+ });
3596
+ SettingCard.displayName = "SettingCard";
3597
+ /**
3598
+ * Header row of a setting card. Wraps DS `CardHeader`, which lays out the
3599
+ * title/description on the left and the `SettingCardAction` on the right.
3600
+ */
3601
+ const SettingCardHeader = React.forwardRef((componentProps, forwardRef) => /* @__PURE__ */ jsx(CardHeader, {
3602
+ ref: forwardRef,
3603
+ ...componentProps
3604
+ }));
3605
+ SettingCardHeader.displayName = "SettingCardHeader";
3606
+ /**
3607
+ * Title of a setting card. Wraps DS `CardTitle`, overriding its type ramp so
3608
+ * weight and size follow the card's level (auto-detected from nesting, like the
3609
+ * background): level 1 is 18px bold, level 2 (nested) is 16px medium. A forced
3610
+ * level-1 card that is still nested (the rare 3rd level) keeps the 16px-medium
3611
+ * title, matching the design guidance for that case.
3612
+ */
3613
+ const SettingCardTitle = React.forwardRef((componentProps, forwardRef) => {
3614
+ const { className, ...props } = componentProps;
3615
+ return /* @__PURE__ */ jsx(CardTitle, {
3616
+ ref: forwardRef,
3617
+ "data-slot": "setting-card-title",
3618
+ className: cn("text-lg font-bold", "[[data-setting-card-content]_&]:text-base [[data-setting-card-content]_&]:font-medium", className),
3619
+ ...props
3620
+ });
3621
+ });
3622
+ SettingCardTitle.displayName = "SettingCardTitle";
3623
+ /**
3624
+ * Supporting description under the title. Wraps DS `CardDescription` (14px muted).
3625
+ * Inline links (e.g. "Learn more") can be placed inside its children.
3626
+ */
3627
+ const SettingCardDescription = React.forwardRef((componentProps, forwardRef) => /* @__PURE__ */ jsx(CardDescription, {
3628
+ ref: forwardRef,
3629
+ ...componentProps
3630
+ }));
3631
+ SettingCardDescription.displayName = "SettingCardDescription";
3632
+ /**
3633
+ * Top-right control slot of the header — holds a single control, either a
3634
+ * `<Switch>` (toggle card) or a `<Button>` (action card). Wraps DS `CardAction`.
3635
+ * The two never co-occur, so this is one slot, not two.
3636
+ */
3637
+ const SettingCardAction = React.forwardRef((componentProps, forwardRef) => /* @__PURE__ */ jsx(CardAction, {
3638
+ ref: forwardRef,
3639
+ ...componentProps
3640
+ }));
3641
+ SettingCardAction.displayName = "SettingCardAction";
3642
+ /**
3643
+ * Body of a setting card. Wraps DS `CardContent` and carries the
3644
+ * `data-setting-card-content` marker that drives nesting detection: any
3645
+ * `SettingCard` rendered inside here auto-detects level 2.
3646
+ *
3647
+ * For progressive disclosure, render this conditionally — mount it only when
3648
+ * the header's toggle is on — so gated fields never mount while disabled.
3649
+ */
3650
+ const SettingCardContent = React.forwardRef((componentProps, forwardRef) => {
3651
+ const { className, ...props } = componentProps;
3652
+ return /* @__PURE__ */ jsx(CardContent, {
3653
+ ref: forwardRef,
3654
+ "data-setting-card-content": "",
3655
+ className: cn("flex flex-col gap-4", className),
3656
+ ...props
3657
+ });
3658
+ });
3659
+ SettingCardContent.displayName = "SettingCardContent";
3159
3660
 
3160
3661
  //#endregion
3161
3662
  //#region src/components/dashboard-sidebar.tsx
3663
+ /**
3664
+ * Context provider and flex-row layout wrapping the sidebar and page content;
3665
+ * renders a ds `SidebarProvider`. Provides the state consumed by `useDashboardSidebar`.
3666
+ *
3667
+ * @example
3668
+ * ```tsx
3669
+ * <DashboardSidebarProvider>
3670
+ * <DashboardSidebar>
3671
+ * <DashboardSidebarContent>
3672
+ * <DashboardSidebarMenu>
3673
+ * <DashboardSidebarMenuItem>
3674
+ * <DashboardSidebarMenuButton icon={<Home />}>Home</DashboardSidebarMenuButton>
3675
+ * </DashboardSidebarMenuItem>
3676
+ * </DashboardSidebarMenu>
3677
+ * </DashboardSidebarContent>
3678
+ * </DashboardSidebar>
3679
+ * <DashboardPageContent>…</DashboardPageContent>
3680
+ * </DashboardSidebarProvider>
3681
+ * ```
3682
+ */
3162
3683
  const DashboardSidebarProvider = React.forwardRef((componentProps, forwardRef) => {
3163
3684
  const { className, style, ...props } = componentProps;
3164
3685
  return /* @__PURE__ */ jsx(SidebarProvider, {
@@ -3173,6 +3694,10 @@ const DashboardSidebarProvider = React.forwardRef((componentProps, forwardRef) =
3173
3694
  });
3174
3695
  });
3175
3696
  DashboardSidebarProvider.displayName = "DashboardSidebarProvider";
3697
+ /**
3698
+ * Root sidebar column that grows/shrinks with the collapse state; renders a `<div>`.
3699
+ * Holds `DashboardSidebarHeader`, `DashboardSidebarContent`, and `DashboardSidebarFooter`.
3700
+ */
3176
3701
  const DashboardSidebar = React.forwardRef((componentProps, forwardRef) => {
3177
3702
  const { className, children, ...props } = componentProps;
3178
3703
  const { state } = useSidebar();
@@ -3187,6 +3712,9 @@ const DashboardSidebar = React.forwardRef((componentProps, forwardRef) => {
3187
3712
  });
3188
3713
  });
3189
3714
  DashboardSidebar.displayName = "DashboardSidebar";
3715
+ /**
3716
+ * Top bar of the sidebar that houses the collapse toggle; renders a `<div>`.
3717
+ */
3190
3718
  const DashboardSidebarHeader = React.forwardRef((componentProps, forwardRef) => {
3191
3719
  const { className, children, ...props } = componentProps;
3192
3720
  return /* @__PURE__ */ jsx("div", {
@@ -3198,6 +3726,10 @@ const DashboardSidebarHeader = React.forwardRef((componentProps, forwardRef) =>
3198
3726
  });
3199
3727
  });
3200
3728
  DashboardSidebarHeader.displayName = "DashboardSidebarHeader";
3729
+ /**
3730
+ * Collapse/expand toggle rendering a ghost, icon ds `Button`; renders a `<button>`.
3731
+ * Swaps its icon and aria-label based on the sidebar state.
3732
+ */
3201
3733
  const DashboardSidebarTrigger = React.forwardRef((componentProps, forwardRef) => {
3202
3734
  const { className, onClick, ...props } = componentProps;
3203
3735
  const { toggleSidebar, state } = useSidebar();
@@ -3217,6 +3749,9 @@ const DashboardSidebarTrigger = React.forwardRef((componentProps, forwardRef) =>
3217
3749
  });
3218
3750
  });
3219
3751
  DashboardSidebarTrigger.displayName = "DashboardSidebarTrigger";
3752
+ /**
3753
+ * Scrollable middle section of the sidebar (scrollbar hidden); renders a `<div>`.
3754
+ */
3220
3755
  const DashboardSidebarContent = React.forwardRef((componentProps, forwardRef) => {
3221
3756
  const { className, ...props } = componentProps;
3222
3757
  return /* @__PURE__ */ jsx("div", {
@@ -3227,6 +3762,9 @@ const DashboardSidebarContent = React.forwardRef((componentProps, forwardRef) =>
3227
3762
  });
3228
3763
  });
3229
3764
  DashboardSidebarContent.displayName = "DashboardSidebarContent";
3765
+ /**
3766
+ * Frosted-glass bottom section of the sidebar; renders a `<div>`.
3767
+ */
3230
3768
  const DashboardSidebarFooter = React.forwardRef((componentProps, forwardRef) => {
3231
3769
  const { className, ...props } = componentProps;
3232
3770
  return /* @__PURE__ */ jsx("div", {
@@ -3237,6 +3775,9 @@ const DashboardSidebarFooter = React.forwardRef((componentProps, forwardRef) =>
3237
3775
  });
3238
3776
  });
3239
3777
  DashboardSidebarFooter.displayName = "DashboardSidebarFooter";
3778
+ /**
3779
+ * Groups a set of menu items (optionally labelled); renders a `<div>`.
3780
+ */
3240
3781
  const DashboardSidebarGroup = React.forwardRef((componentProps, forwardRef) => {
3241
3782
  const { className, ...props } = componentProps;
3242
3783
  return /* @__PURE__ */ jsx("div", {
@@ -3247,6 +3788,10 @@ const DashboardSidebarGroup = React.forwardRef((componentProps, forwardRef) => {
3247
3788
  });
3248
3789
  });
3249
3790
  DashboardSidebarGroup.displayName = "DashboardSidebarGroup";
3791
+ /**
3792
+ * Section heading for a group, hidden when the sidebar is collapsed; renders a `<div>`
3793
+ * by default, overridable via the `render` prop.
3794
+ */
3250
3795
  const DashboardSidebarGroupLabel = React.forwardRef((componentProps, forwardRef) => {
3251
3796
  const { className, render, ...props } = componentProps;
3252
3797
  return useRender({
@@ -3260,6 +3805,9 @@ const DashboardSidebarGroupLabel = React.forwardRef((componentProps, forwardRef)
3260
3805
  });
3261
3806
  });
3262
3807
  DashboardSidebarGroupLabel.displayName = "DashboardSidebarGroupLabel";
3808
+ /**
3809
+ * List container for menu items; renders a `<ul>`.
3810
+ */
3263
3811
  const DashboardSidebarMenu = React.forwardRef((componentProps, forwardRef) => {
3264
3812
  const { className, ...props } = componentProps;
3265
3813
  return /* @__PURE__ */ jsx("ul", {
@@ -3270,6 +3818,9 @@ const DashboardSidebarMenu = React.forwardRef((componentProps, forwardRef) => {
3270
3818
  });
3271
3819
  });
3272
3820
  DashboardSidebarMenu.displayName = "DashboardSidebarMenu";
3821
+ /**
3822
+ * Wrapper for a single menu row; renders a `<li>` (relative, for badge positioning).
3823
+ */
3273
3824
  const DashboardSidebarMenuItem = React.forwardRef((componentProps, forwardRef) => {
3274
3825
  const { className, ...props } = componentProps;
3275
3826
  return /* @__PURE__ */ jsx("li", {
@@ -3280,6 +3831,10 @@ const DashboardSidebarMenuItem = React.forwardRef((componentProps, forwardRef) =
3280
3831
  });
3281
3832
  });
3282
3833
  DashboardSidebarMenuItem.displayName = "DashboardSidebarMenuItem";
3834
+ /**
3835
+ * Pill-shaped navigation item with a leading icon circle and optional trailing action;
3836
+ * renders a `<button>` by default, overridable via the `render` prop (e.g. a router `<Link>`).
3837
+ */
3283
3838
  const DashboardSidebarMenuButton = React.forwardRef((componentProps, forwardRef) => {
3284
3839
  const { className, render, isActive = false, disabled = false, icon, action, children, ...props } = componentProps;
3285
3840
  const buttonContent = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3313,6 +3868,9 @@ const DashboardSidebarMenuButton = React.forwardRef((componentProps, forwardRef)
3313
3868
  });
3314
3869
  });
3315
3870
  DashboardSidebarMenuButton.displayName = "DashboardSidebarMenuButton";
3871
+ /**
3872
+ * Right-aligned slot (ml-auto) for trailing content inside a menu row; renders a `<div>`.
3873
+ */
3316
3874
  const DashboardSidebarMenuAddon = React.forwardRef((componentProps, forwardRef) => {
3317
3875
  const { className, ...props } = componentProps;
3318
3876
  return /* @__PURE__ */ jsx("div", {
@@ -3323,6 +3881,11 @@ const DashboardSidebarMenuAddon = React.forwardRef((componentProps, forwardRef)
3323
3881
  });
3324
3882
  });
3325
3883
  DashboardSidebarMenuAddon.displayName = "DashboardSidebarMenuAddon";
3884
+ /**
3885
+ * Notification count badge for a menu item; renders a ds `CounterBadge` positioned
3886
+ * absolutely at the row's right edge (moves to the icon corner when collapsed).
3887
+ * Place it inside `DashboardSidebarMenuItem`, as a sibling of the button.
3888
+ */
3326
3889
  const DashboardSidebarMenuBadge = React.forwardRef((componentProps, forwardRef) => {
3327
3890
  const { className, ...props } = componentProps;
3328
3891
  return /* @__PURE__ */ jsx(CounterBadge, {
@@ -3333,6 +3896,10 @@ const DashboardSidebarMenuBadge = React.forwardRef((componentProps, forwardRef)
3333
3896
  });
3334
3897
  });
3335
3898
  DashboardSidebarMenuBadge.displayName = "DashboardSidebarMenuBadge";
3899
+ /**
3900
+ * Popover-style panel (white card with border and shadow) opening beside a trigger;
3901
+ * renders a `<div>`. Hosts `DashboardSidebarSubmenuItem` and `DashboardSidebarSubmenuSeparator`.
3902
+ */
3336
3903
  const DashboardSidebarSubmenu = React.forwardRef((componentProps, forwardRef) => {
3337
3904
  const { className, ...props } = componentProps;
3338
3905
  return /* @__PURE__ */ jsx("div", {
@@ -3343,6 +3910,10 @@ const DashboardSidebarSubmenu = React.forwardRef((componentProps, forwardRef) =>
3343
3910
  });
3344
3911
  });
3345
3912
  DashboardSidebarSubmenu.displayName = "DashboardSidebarSubmenu";
3913
+ /**
3914
+ * One row inside a submenu; renders a `<div>` by default, overridable via the `render`
3915
+ * prop (e.g. an `<a>` or router `<Link>` for navigation).
3916
+ */
3346
3917
  const DashboardSidebarSubmenuItem = React.forwardRef((componentProps, forwardRef) => {
3347
3918
  const { className, render, isActive = false, ...props } = componentProps;
3348
3919
  return useRender({
@@ -3359,6 +3930,9 @@ const DashboardSidebarSubmenuItem = React.forwardRef((componentProps, forwardRef
3359
3930
  });
3360
3931
  });
3361
3932
  DashboardSidebarSubmenuItem.displayName = "DashboardSidebarSubmenuItem";
3933
+ /**
3934
+ * Thin horizontal divider between submenu items; renders a `<div>`.
3935
+ */
3362
3936
  const DashboardSidebarSubmenuSeparator = React.forwardRef((componentProps, forwardRef) => {
3363
3937
  const { className } = componentProps;
3364
3938
  return /* @__PURE__ */ jsx("div", {
@@ -3455,6 +4029,20 @@ function NavItem({ item, renderLink }) {
3455
4029
  })] }), countBadge] });
3456
4030
  return /* @__PURE__ */ jsxs(DashboardSidebarMenuItem, { children: [React.cloneElement(buttonEl, {}, item.label, trailing), countBadge] });
3457
4031
  }
4032
+ /**
4033
+ * Data-driven sidebar navigation. Maps a `groups` array into the
4034
+ * `DashboardSidebar` primitives, rendering each item as a link, a dropdown
4035
+ * submenu, or an action button (with optional badges, counts, and tooltips).
4036
+ *
4037
+ * Renders a fragment of `DashboardSidebarGroup` sections — it has no wrapper
4038
+ * element of its own, so place it inside a `DashboardSidebarContent`.
4039
+ *
4040
+ * @example
4041
+ * <DashboardSidebarNav
4042
+ * groups={groups}
4043
+ * renderLink={href => <Link to={href} />}
4044
+ * />
4045
+ */
3458
4046
  function DashboardSidebarNav({ groups, renderLink }) {
3459
4047
  return /* @__PURE__ */ jsx(Fragment, { children: groups.map((group) => /* @__PURE__ */ jsxs(DashboardSidebarGroup, { children: [group.label && /* @__PURE__ */ jsx(DashboardSidebarGroupLabel, { children: group.label }), /* @__PURE__ */ jsx(DashboardSidebarMenu, { children: group.items.map((item) => /* @__PURE__ */ jsx(NavItem, {
3460
4048
  item,
@@ -3463,4 +4051,4 @@ function DashboardSidebarNav({ groups, renderLink }) {
3463
4051
  }
3464
4052
 
3465
4053
  //#endregion
3466
- export { BetaBadge, CardSaveBar, ChatbotExpandSuggestion, ChatbotInput, ChatbotPage, ChatbotPageBody, ChatbotPageContent, ChatbotPageConversation, ChatbotPageFooter, ChatbotPageHeading, ChatbotPageInputBar, ChatbotPanel, ChatbotPanelHeader, ChatbotPanelSuggestion, ChatbotPanelTrigger, ChatbotResponseBlock, ChatbotResponseLoading, ChatbotSidebar, ChatbotUserMessage, ComingSoonDescription, ComingSoonEmptyState, ComingSoonMedia, ComingSoonTitle, CommonForm, CopyButton, CopyButtonIcon, CopyButtonLabel, DashboardPage, DashboardPageBanner, DashboardPageContent, DashboardPageHeader, DashboardPageHeaderAction, DashboardPageHeaderActions, DashboardPageHeaderDescription, DashboardPageHeaderNav, DashboardPageHeaderNavBack, DashboardPageHeaderPrefix, DashboardPageHeaderSubtitle, DashboardPageHeaderTitle, DashboardPageHeaderTitleGroup, DashboardPageMain, DashboardPageTabs, DashboardSidebar, DashboardSidebarContent, DashboardSidebarFooter, DashboardSidebarGroup, DashboardSidebarGroupLabel, DashboardSidebarHeader, DashboardSidebarMenu, DashboardSidebarMenuBadge, DashboardSidebarMenuButton, DashboardSidebarMenuItem, DashboardSidebarNav, DashboardSidebarProvider, DashboardSidebarSubmenu, DashboardSidebarSubmenuItem, DashboardSidebarSubmenuSeparator, DashboardSidebarTrigger, DashboardStandalonePage, DashboardStandalonePageAction, DashboardStandalonePageActions, DashboardStandalonePageContent, DashboardStandalonePageDescription, DashboardStandalonePageHeader, DashboardStandalonePageMain, DashboardStandalonePageTitle, DeprecatedBadge, EmptyState, EmptyStateActions, EmptyStateButton, EmptyStateDescription, EmptyStateExternalLink, EmptyStateHeader, EmptyStateMedia, EmptyStateTitle, FormArrayField, FormComboboxField, FormFieldBase, FormFieldShell, FormInputField, FormMultiComboboxField, FormNumericField, FormOTPField, FormRadioGroupField, FormSelectField, FormSliderField, FormSwitchField, FormTextareaField, FormToggleGroupField, NewBadge, NoDataDescription, NoDataEmptyState, NoDataMedia, NoDataTitle, NoSupportDescription, NoSupportEmptyState, NoSupportMedia, NoSupportTitle, NotFoundDescription, NotFoundEmptyState, NotFoundMedia, NotFoundTitle, PERCENTAGE_THRESHOLDS, ProfessionalBadge, RestrictedAccessDescription, RestrictedAccessEmptyState, RestrictedAccessMedia, RestrictedAccessTitle, RoleBadge, SaveBar, ScoreBadge, SentimentBadge, SubmitButton, TrialBadge, UnknownErrorDescription, UnknownErrorEmptyState, UnknownErrorMedia, UnknownErrorTitle, fieldContext, formContext, toFieldErrors, useCopyToClipboard, useSidebar as useDashboardSidebar, useFieldContext, useForm, useFormContext, withFieldGroup, withForm };
4054
+ export { BetaBadge, CardSaveBar, ChatbotExpandSuggestion, ChatbotInput, ChatbotPage, ChatbotPageBody, ChatbotPageContent, ChatbotPageConversation, ChatbotPageFooter, ChatbotPageHeading, ChatbotPageInputBar, ChatbotPanel, ChatbotPanelHeader, ChatbotPanelSuggestion, ChatbotPanelTrigger, ChatbotResponseBlock, ChatbotResponseLoading, ChatbotSidebar, ChatbotUserMessage, ComingSoonDescription, ComingSoonEmptyState, ComingSoonMedia, ComingSoonTitle, CommonForm, CopyButton, CopyButtonIcon, CopyButtonLabel, DashboardPage, DashboardPageBanner, DashboardPageContent, DashboardPageHeader, DashboardPageHeaderAction, DashboardPageHeaderActions, DashboardPageHeaderDescription, DashboardPageHeaderNav, DashboardPageHeaderNavBack, DashboardPageHeaderPrefix, DashboardPageHeaderSubtitle, DashboardPageHeaderTitle, DashboardPageHeaderTitleGroup, DashboardPageMain, DashboardPageTabs, DashboardSidebar, DashboardSidebarContent, DashboardSidebarFooter, DashboardSidebarGroup, DashboardSidebarGroupLabel, DashboardSidebarHeader, DashboardSidebarMenu, DashboardSidebarMenuBadge, DashboardSidebarMenuButton, DashboardSidebarMenuItem, DashboardSidebarNav, DashboardSidebarProvider, DashboardSidebarSubmenu, DashboardSidebarSubmenuItem, DashboardSidebarSubmenuSeparator, DashboardSidebarTrigger, DashboardStandalonePage, DashboardStandalonePageAction, DashboardStandalonePageActions, DashboardStandalonePageContent, DashboardStandalonePageDescription, DashboardStandalonePageHeader, DashboardStandalonePageMain, DashboardStandalonePageTitle, DeprecatedBadge, EmptyState, EmptyStateActions, EmptyStateButton, EmptyStateDescription, EmptyStateExternalLink, EmptyStateHeader, EmptyStateMedia, EmptyStateTitle, FormArrayField, FormComboboxField, FormFieldBase, FormFieldShell, FormInputField, FormMultiComboboxField, FormNumericField, FormOTPField, FormRadioGroupField, FormSelectField, FormSliderField, FormSwitchField, FormTextareaField, FormToggleGroupField, NewBadge, NoDataDescription, NoDataEmptyState, NoDataMedia, NoDataTitle, NoSupportDescription, NoSupportEmptyState, NoSupportMedia, NoSupportTitle, NotFoundDescription, NotFoundEmptyState, NotFoundMedia, NotFoundTitle, PERCENTAGE_THRESHOLDS, ProfessionalBadge, RestrictedAccessDescription, RestrictedAccessEmptyState, RestrictedAccessMedia, RestrictedAccessTitle, RoleBadge, SaveBar, ScoreBadge, SentimentBadge, SettingCard, SettingCardAction, SettingCardContent, SettingCardDescription, SettingCardHeader, SettingCardTitle, SubmitButton, TrialBadge, UnknownErrorDescription, UnknownErrorEmptyState, UnknownErrorMedia, UnknownErrorTitle, fieldContext, formContext, toFieldErrors, useCopyToClipboard, useSidebar as useDashboardSidebar, useFieldContext, useForm, useFormContext, withFieldGroup, withForm };