@payfit/unity-components 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/esm/components/action-bar/ActionBar.js +14 -14
  2. package/dist/esm/components/actionable/Actionable.js +31 -28
  3. package/dist/esm/components/app-layout/AppLayout.js +17 -17
  4. package/dist/esm/components/app-menu/parts/AppMenuHeader.d.ts +86 -4
  5. package/dist/esm/components/app-menu/parts/AppMenuHeader.js +25 -25
  6. package/dist/esm/components/breadcrumbs/Breadcrumbs.context.js +3 -3
  7. package/dist/esm/components/breadcrumbs/Breadcrumbs.d.ts +19 -11
  8. package/dist/esm/components/breadcrumbs/Breadcrumbs.js +29 -18
  9. package/dist/esm/components/breadcrumbs/parts/Breadcrumb.d.ts +30 -5
  10. package/dist/esm/components/breadcrumbs/parts/Breadcrumb.js +35 -27
  11. package/dist/esm/components/breadcrumbs/parts/RawBreadcrumbLink.d.ts +37 -0
  12. package/dist/esm/components/breadcrumbs/parts/RawBreadcrumbLink.js +36 -0
  13. package/dist/esm/components/client-side-pagination/ClientSidePagination.d.ts +103 -0
  14. package/dist/esm/components/client-side-pagination/ClientSidePagination.js +177 -0
  15. package/dist/esm/components/client-side-pagination/parts/PaginationEllipsis.d.ts +11 -0
  16. package/dist/esm/components/client-side-pagination/parts/PaginationEllipsis.js +30 -0
  17. package/dist/esm/components/client-side-pagination/parts/PaginationJumpDialog.d.ts +8 -0
  18. package/dist/esm/components/{pagination/parts/PaginationLink.d.ts → client-side-pagination/parts/RawPaginationLink.d.ts} +2 -2
  19. package/dist/esm/components/{pagination/parts/PaginationLink.js → client-side-pagination/parts/RawPaginationLink.js} +2 -2
  20. package/dist/esm/components/client-side-pagination/utils/pagination-window.d.ts +8 -0
  21. package/dist/esm/components/client-side-pagination/utils/pagination-window.js +33 -0
  22. package/dist/esm/components/error-state/ErrorState.d.ts +13 -1
  23. package/dist/esm/components/error-state/ErrorState.js +133 -92
  24. package/dist/esm/components/error-state/initConfig.js +1 -1
  25. package/dist/esm/components/fieldset/Fieldset.d.ts +19 -0
  26. package/dist/esm/components/fieldset/Fieldset.js +32 -26
  27. package/dist/esm/components/flex/Flex.js +52 -37
  28. package/dist/esm/components/form-field/FormField.js +12 -12
  29. package/dist/esm/components/form-field/parts/{FormContextualLink.d.ts → RawFormContextualLink.d.ts} +2 -2
  30. package/dist/esm/components/form-field/parts/RawFormContextualLink.js +39 -0
  31. package/dist/esm/components/funnel-layout/parts/FunnelSidebar.d.ts +2 -2
  32. package/dist/esm/components/icon/Icon.js +23 -19
  33. package/dist/esm/components/link/{Link.variants.d.ts → RawLink.d.ts} +92 -0
  34. package/dist/esm/components/link/{Link.variants.js → RawLink.js} +70 -4
  35. package/dist/esm/components/menu/parts/{MenuItem.d.ts → RawMenuItem.d.ts} +3 -4
  36. package/dist/esm/components/menu/parts/{MenuItem.js → RawMenuItem.js} +9 -9
  37. package/dist/esm/components/nav/parts/NavGroup.d.ts +3 -3
  38. package/dist/esm/components/nav/parts/NavGroup.js +62 -51
  39. package/dist/esm/components/nav/parts/{NavItem.d.ts → RawNavItem.d.ts} +102 -5
  40. package/dist/esm/components/nav/parts/RawNavItem.js +106 -0
  41. package/dist/esm/components/page/Page.js +1 -1
  42. package/dist/esm/components/page/parts/PageHeader.d.ts +79 -9
  43. package/dist/esm/components/page/parts/PageHeader.js +22 -20
  44. package/dist/esm/components/pagination/Pagination.d.ts +23 -44
  45. package/dist/esm/components/pagination/Pagination.js +89 -163
  46. package/dist/esm/components/pagination/PaginationContext.d.ts +11 -0
  47. package/dist/esm/components/pagination/PaginationContext.js +15 -0
  48. package/dist/esm/components/pagination/hooks/use-pagination-state.d.ts +63 -0
  49. package/dist/esm/components/pagination/hooks/use-pagination-state.js +27 -0
  50. package/dist/esm/components/pagination/hooks/use-pagination-window.d.ts +64 -0
  51. package/dist/esm/components/pagination/hooks/use-pagination-window.js +15 -0
  52. package/dist/esm/components/pagination/parts/PaginationContent.d.ts +30 -0
  53. package/dist/esm/components/pagination/parts/PaginationContent.js +37 -0
  54. package/dist/esm/components/pagination/parts/PaginationEllipsis.d.ts +23 -4
  55. package/dist/esm/components/pagination/parts/PaginationEllipsis.js +20 -16
  56. package/dist/esm/components/pagination/parts/PaginationItem.d.ts +38 -0
  57. package/dist/esm/components/pagination/parts/PaginationItem.js +22 -0
  58. package/dist/esm/components/pagination/parts/RawPaginationLink.d.ts +11 -0
  59. package/dist/esm/components/pagination/parts/RawPaginationLink.js +60 -0
  60. package/dist/esm/components/pagination/parts/RawPaginationNext.d.ts +22 -0
  61. package/dist/esm/components/pagination/parts/RawPaginationNext.js +70 -0
  62. package/dist/esm/components/pagination/parts/RawPaginationPrevious.d.ts +22 -0
  63. package/dist/esm/components/pagination/parts/RawPaginationPrevious.js +67 -0
  64. package/dist/esm/components/pagination/utils/pagination-window.js +29 -20
  65. package/dist/esm/components/select/Select.js +63 -45
  66. package/dist/esm/components/select/parts/SelectOption.js +9 -9
  67. package/dist/esm/components/skip-links/SkipLinks.js +1 -1
  68. package/dist/esm/components/table/Table.d.ts +1 -0
  69. package/dist/esm/components/table/Table.js +82 -73
  70. package/dist/esm/components/table/hooks/useTableKeyboardNavigation.js +6 -6
  71. package/dist/esm/components/table/parts/TableCell.js +29 -26
  72. package/dist/esm/components/table/parts/TablePagination.d.ts +5 -5
  73. package/dist/esm/components/table/parts/TablePagination.js +10 -10
  74. package/dist/esm/components/table/parts/TableRow.js +21 -18
  75. package/dist/esm/components/tabs/parts/{Tab.d.ts → RawTab.d.ts} +2 -2
  76. package/dist/esm/components/tabs/parts/{Tab.js → RawTab.js} +6 -6
  77. package/dist/esm/components/task-menu/TaskMenu.d.ts +4 -4
  78. package/dist/esm/components/task-menu/parts/{SubTask.d.ts → RawSubTask.d.ts} +7 -7
  79. package/dist/esm/components/task-menu/parts/{SubTask.js → RawSubTask.js} +19 -19
  80. package/dist/esm/components/task-menu/parts/{Task.d.ts → RawTask.d.ts} +7 -7
  81. package/dist/esm/components/task-menu/parts/{Task.js → RawTask.js} +17 -17
  82. package/dist/esm/components/task-menu/parts/TaskGroup.d.ts +5 -5
  83. package/dist/esm/components/text/Text.js +30 -27
  84. package/dist/esm/hooks/use-container-query-level.d.ts +42 -0
  85. package/dist/esm/hooks/use-container-query-level.js +33 -0
  86. package/dist/esm/index.d.ts +21 -11
  87. package/dist/esm/index.js +424 -399
  88. package/dist/esm/integrations/tanstack-router/components/breadcrumbs/Breadcrumb.d.ts +23 -0
  89. package/dist/esm/integrations/tanstack-router/components/breadcrumbs/BreadcrumbLink.d.ts +38 -0
  90. package/dist/esm/integrations/tanstack-router/components/breadcrumbs/BreadcrumbLink.js +7 -0
  91. package/dist/esm/integrations/tanstack-router/components/breadcrumbs/Breadcrumbs.d.ts +23 -0
  92. package/dist/esm/integrations/tanstack-router/components/breadcrumbs/use-route-breadcrumb.d.ts +53 -0
  93. package/dist/esm/integrations/tanstack-router/components/form-contextual-link/FormContextualLink.d.ts +40 -0
  94. package/dist/esm/integrations/tanstack-router/components/form-contextual-link/FormContextualLink.js +7 -0
  95. package/dist/esm/integrations/tanstack-router/components/link/Link.d.ts +33 -0
  96. package/dist/esm/integrations/tanstack-router/components/link/Link.js +7 -0
  97. package/dist/esm/integrations/tanstack-router/components/menu-item/MenuItem.d.ts +49 -0
  98. package/dist/esm/integrations/tanstack-router/components/menu-item/MenuItem.js +16 -0
  99. package/dist/esm/integrations/tanstack-router/components/nav-item/NavItem.d.ts +52 -0
  100. package/dist/esm/integrations/tanstack-router/components/nav-item/NavItem.js +29 -0
  101. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationLink.d.ts +54 -0
  102. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationLink.js +21 -0
  103. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationNext.d.ts +52 -0
  104. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationNext.js +22 -0
  105. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationPrevious.d.ts +51 -0
  106. package/dist/esm/integrations/tanstack-router/components/pagination/PaginationPrevious.js +22 -0
  107. package/dist/esm/integrations/tanstack-router/components/tabs/Tabs.d.ts +82 -0
  108. package/dist/esm/integrations/tanstack-router/components/tabs/Tabs.js +41 -0
  109. package/dist/esm/integrations/tanstack-router/components/tabs/parts/Tab.d.ts +52 -0
  110. package/dist/esm/integrations/tanstack-router/components/tabs/parts/Tab.js +15 -0
  111. package/dist/esm/integrations/tanstack-router/components/tabs/parts/TabList.d.ts +5 -0
  112. package/dist/esm/integrations/tanstack-router/components/tabs/parts/TabPanel.d.ts +77 -0
  113. package/dist/esm/integrations/tanstack-router/components/tabs/parts/TabPanel.js +16 -0
  114. package/dist/esm/integrations/tanstack-router/components/task-menu/SubTask.d.ts +69 -0
  115. package/dist/esm/integrations/tanstack-router/components/task-menu/SubTask.js +14 -0
  116. package/dist/esm/integrations/tanstack-router/components/task-menu/Task.d.ts +64 -0
  117. package/dist/esm/integrations/tanstack-router/components/task-menu/Task.js +14 -0
  118. package/dist/esm/integrations/tanstack-router/index.d.ts +16 -0
  119. package/dist/esm/integrations/tanstack-router/utils/decorators.d.ts +23 -0
  120. package/dist/esm/integrations/tanstack-router.js +34 -0
  121. package/dist/esm/providers/router/RouterProvider.d.ts +7 -2
  122. package/dist/esm/providers/router/RouterProvider.js +14 -10
  123. package/dist/esm/types/DataAttributes.d.ts +1 -1
  124. package/i18n/en-GB.json +1 -0
  125. package/i18n/es-ES.json +1 -0
  126. package/i18n/fr-FR.json +1 -0
  127. package/package.json +47 -25
  128. package/dist/esm/components/form-field/parts/FormContextualLink.js +0 -37
  129. package/dist/esm/components/link/Link.d.ts +0 -93
  130. package/dist/esm/components/link/Link.js +0 -68
  131. package/dist/esm/components/nav/parts/NavItem.js +0 -95
  132. /package/dist/esm/components/{pagination → client-side-pagination}/hooks/use-pagination.d.ts +0 -0
  133. /package/dist/esm/components/{pagination → client-side-pagination}/hooks/use-pagination.js +0 -0
  134. /package/dist/esm/components/{pagination → client-side-pagination}/parts/PaginationJumpDialog.js +0 -0
  135. /package/dist/esm/components/{pagination → client-side-pagination}/parts/PaginationNavButton.d.ts +0 -0
  136. /package/dist/esm/components/{pagination → client-side-pagination}/parts/PaginationNavButton.js +0 -0
@@ -0,0 +1,82 @@
1
+ import { TabsProps as BaseTabsProps } from '../../../../components/tabs/Tabs.js';
2
+ export interface TabsProps extends Omit<BaseTabsProps, 'selectedKey' | 'isExact'> {
3
+ /**
4
+ * The currently selected tab key. If not provided, automatically uses the current route pathname.
5
+ * @default location.pathname
6
+ */
7
+ selectedKey?: BaseTabsProps['selectedKey'];
8
+ /**
9
+ * Whether to use exact matching for active tab detection. Possible values are:
10
+ * - 'exact' - The tab will be active if the current route pathname matches the tab's pathname exactly
11
+ * - 'fuzzy' - The tab will be active if the current route pathname is a substring of the tab's pathname
12
+ * @default 'fuzzy'
13
+ */
14
+ routeMatch?: 'exact' | 'fuzzy';
15
+ }
16
+ /**
17
+ * A Tabs component that integrates with Tanstack Router for navigation.
18
+ * Provides both selection state management and routing capabilities with automatic route synchronization.
19
+ * @param {TabsProps} props - Standard Tabs props plus Tanstack Router integration options
20
+ * @example
21
+ * ```tsx
22
+ * import { Tabs, Tab, TabList, TabPanel } from '@payfit/unity-components/integrations/tanstack-router'
23
+ * import { Outlet } from '@tanstack/react-router'
24
+ *
25
+ * // Pattern 1: Single auto-updating TabPanel (recommended for consistent layouts)
26
+ * // Tabs automatically resolve their IDs from route definitions
27
+ * function NavigationTabs() {
28
+ * return (
29
+ * <Tabs>
30
+ * <TabList aria-label="Main navigation">
31
+ * <Tab to="/dashboard">Dashboard</Tab>
32
+ * <Tab to="/employees/$employeeId" params={{employeeId: '1'}}>Employee</Tab>
33
+ * </TabList>
34
+ * <TabPanel>
35
+ * <Outlet />
36
+ * </TabPanel>
37
+ * </Tabs>
38
+ * )
39
+ * }
40
+ *
41
+ * // Pattern 2: Multiple explicit TabPanels (for different layouts per tab)
42
+ * // When Tab has explicit id, you MUST provide matching TabPanel with same id
43
+ * function CustomLayoutTabs() {
44
+ * return (
45
+ * <Tabs>
46
+ * <TabList aria-label="Custom layouts">
47
+ * <Tab to="/dashboard" id="dashboard">Dashboard</Tab>
48
+ * <Tab to="/analytics" id="analytics">Analytics</Tab>
49
+ * </TabList>
50
+ * <TabPanel id="dashboard" className="uy:grid uy:grid-cols-3">
51
+ * <Outlet />
52
+ * </TabPanel>
53
+ * <TabPanel id="analytics" className="uy:w-full uy:h-screen">
54
+ * <Outlet />
55
+ * </TabPanel>
56
+ * </Tabs>
57
+ * )
58
+ * }
59
+ * ```
60
+ * @remarks
61
+ * - Automatically syncs selectedKey with current route using sophisticated route matching
62
+ * - Tab IDs are automatically resolved from route definitions (no manual IDs needed)
63
+ * - Handles nested routes properly (e.g., /settings/security matches /settings tab)
64
+ * - Supports both exact and fuzzy route matching via routeMatch prop
65
+ * - Integrates seamlessly with Tanstack Router's navigation system
66
+ * - Maintains all accessibility features from the base Tabs component
67
+ * - **TabPanel Pattern Constraint**: Choose ONE of two patterns:
68
+ * - Pattern 1 (Auto-sync): Single TabPanel without id prop - automatically shows active route content
69
+ * - Pattern 2 (Explicit): Multiple TabPanels with explicit id props - each Tab with explicit id MUST have matching TabPanel
70
+ * - Never mix auto-sync and explicit id patterns in the same Tabs component
71
+ * - When using explicit Tab IDs, provide corresponding TabPanel for each one
72
+ * - selectedKey and onSelectionChange can be overridden for custom behavior
73
+ * @see {@link TabsProps} for all available props
74
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/integrations/tanstack-router/tabs GitHub}
75
+ * @see Design specs {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
76
+ * @see Design docs in {@link https://www.payfit.design/ Payfit.design}
77
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/ unity-components.payfit.io}
78
+ */
79
+ export declare function Tabs({ children, selectedKey: selectedKeyProp, onSelectionChange, routeMatch, ...tabsProps }: TabsProps): import("react/jsx-runtime").JSX.Element;
80
+ export declare namespace Tabs {
81
+ var displayName: string;
82
+ }
@@ -0,0 +1,41 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { useLocation as f, useNavigate as I, useChildMatches as p } from "@tanstack/react-router";
3
+ import { RouterProvider as v } from "react-aria-components";
4
+ import { Tabs as R } from "../../../../components/tabs/Tabs.js";
5
+ function S({
6
+ children: i,
7
+ selectedKey: a,
8
+ onSelectionChange: u,
9
+ routeMatch: c = "fuzzy",
10
+ ...d
11
+ }) {
12
+ const s = f(), g = I(), l = p({
13
+ select: (e) => {
14
+ if (e.length !== 0)
15
+ return c === "exact" ? e.reduce((t, o) => {
16
+ const n = String(t.routeId);
17
+ return String(o.routeId).length > n.length ? o : t;
18
+ }) : e.reduce((t, o) => {
19
+ const n = String(t.routeId);
20
+ return String(o.routeId).length < n.length ? o : t;
21
+ });
22
+ }
23
+ }), h = a ?? l?.id ?? s.pathname;
24
+ return /* @__PURE__ */ r(v, { navigate: (e) => {
25
+ g({ to: e });
26
+ }, children: /* @__PURE__ */ r(
27
+ R,
28
+ {
29
+ ...d,
30
+ selectedKey: h,
31
+ onSelectionChange: (e) => {
32
+ u?.(e);
33
+ },
34
+ children: i
35
+ }
36
+ ) });
37
+ }
38
+ S.displayName = "Tabs";
39
+ export {
40
+ S as Tabs
41
+ };
@@ -0,0 +1,52 @@
1
+ import { RegisteredRouter, ValidateLinkOptions } from '@tanstack/react-router';
2
+ import { ReactNode } from 'react';
3
+ import { TabProps as RawTabProps } from '../../../../../components/tabs/parts/RawTab.js';
4
+ type TabProps<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown> = Omit<RawTabProps, 'onPress' | 'children' | 'suffix' | 'id'> & ValidateLinkOptions<TRouter, TOptions> & {
5
+ children?: ReactNode;
6
+ suffixElement?: RawTabProps['suffix'];
7
+ id?: RawTabProps['id'];
8
+ };
9
+ /**
10
+ * A tab component that integrates with Tanstack Router for navigation.
11
+ * Provides seamless routing capabilities for tab-based navigation interfaces.
12
+ * @param props - Either router-based props (with 'to') or button-based props (with 'onPress')
13
+ * @example
14
+ * ```tsx
15
+ * import { Tab } from '@payfit/unity-components/integrations/tanstack-router'
16
+ *
17
+ * function NavigationTabs() {
18
+ * return (
19
+ * <Tabs>
20
+ * <TabList aria-label="Main navigation">
21
+ * <Tab to="/dashboard" id="dashboard">
22
+ * Dashboard
23
+ * </Tab>
24
+ * <Tab to="/employees" id="employees">
25
+ * Employees
26
+ * </Tab>
27
+ * <Tab onPress={() => alert('Action triggered')} id="action">
28
+ * Perform Action
29
+ * </Tab>
30
+ * </TabList>
31
+ * </Tabs>
32
+ * )
33
+ * }
34
+ * ```
35
+ * @remarks
36
+ * - When 'to' prop is provided, the component renders as a router link
37
+ * - When 'onPress' prop is provided (without 'to'), it renders as a button
38
+ * - Supports all Tanstack Router link features like preloading, search params, and route params
39
+ * - Maintains accessibility features from the underlying RawTab component
40
+ * - Must be used within a TabsProvider context for proper styling and behavior
41
+ * @see {@link TabProps} for all available props
42
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/integrations/tanstack-router/tabs GitHub}
43
+ * @see Design specs {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
44
+ * @see Design docs in {@link https://www.payfit.design/ Payfit.design}
45
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/ unity-components.payfit.io}
46
+ */
47
+ declare function Tab<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown>(props: TabProps<TRouter, TOptions>): import("react/jsx-runtime").JSX.Element;
48
+ declare namespace Tab {
49
+ var displayName: string;
50
+ }
51
+ export { Tab };
52
+ export type { TabProps };
@@ -0,0 +1,15 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { useLinkProps as f, createLink as a } from "@tanstack/react-router";
3
+ import { RawTab as m } from "../../../../../components/tabs/parts/RawTab.js";
4
+ const p = a(m);
5
+ function c(r) {
6
+ const { suffixElement: t, id: s, ...o } = r, e = f(o), i = s ?? e.href ?? o.to;
7
+ return (
8
+ // @ts-expect-error - Complex type intersection between router props and component props
9
+ /* @__PURE__ */ n(p, { ...o, suffix: t, id: i })
10
+ );
11
+ }
12
+ c.displayName = "Tab";
13
+ export {
14
+ c as Tab
15
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-export of the base TabList component for convenience.
3
+ * This allows importing all tab-related components from the same tanstack-router integration.
4
+ */
5
+ export { TabList } from '../../../../../components/tabs/parts/TabList.js';
@@ -0,0 +1,77 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { TabPanelProps as BaseTabPanelProps } from '../../../../../components/tabs/parts/TabPanel.js';
3
+ export interface TabPanelProps extends Omit<BaseTabPanelProps, 'id'> {
4
+ /**
5
+ * The panel ID. When provided, this TabPanel will only render when its ID matches the selected tab.
6
+ * When omitted, automatically uses the selectedKey from the parent Tabs component.
7
+ * @default selectedKey from Tabs context
8
+ */
9
+ id?: BaseTabPanelProps['id'];
10
+ }
11
+ /**
12
+ * A TabPanel component that integrates with Tanstack Router for automatic ID management.
13
+ * Uses the same sophisticated route matching logic as the Tabs component to determine the panel ID.
14
+ * @param {TabPanelProps} props - Standard TabPanel props with optional id and route matching options
15
+ * @param {ReactNode} props.children - The content to display in the tab panel
16
+ * @param {string} [props.id] - The panel ID. If not provided, uses matched route or current pathname
17
+ * @param {'exact' | 'fuzzy'} [props.routeMatch] - Route matching strategy for automatic ID detection
18
+ * @example
19
+ * ```tsx
20
+ * import { Tabs, Tab, TabList, TabPanel } from '@payfit/unity-components/integrations/tanstack-router'
21
+ * import { Outlet } from '@tanstack/react-router'
22
+ *
23
+ * // Single auto-updating TabPanel (recommended)
24
+ * function SinglePanelTabs() {
25
+ * return (
26
+ * <Tabs>
27
+ * <TabList aria-label="Main navigation">
28
+ * <Tab to="/dashboard">Dashboard</Tab>
29
+ * <Tab to="/employees">Employees</Tab>
30
+ * </TabList>
31
+ * <TabPanel>
32
+ * <Outlet />
33
+ * </TabPanel>
34
+ * </Tabs>
35
+ * )
36
+ * }
37
+ *
38
+ * // Multiple explicit TabPanels (for different layouts)
39
+ * function MultiPanelTabs() {
40
+ * return (
41
+ * <Tabs>
42
+ * <TabList aria-label="Custom layouts">
43
+ * <Tab to="/dashboard">Dashboard</Tab>
44
+ * <Tab to="/analytics">Analytics</Tab>
45
+ * </TabList>
46
+ * <TabPanel id="/dashboard" className="uy:grid uy:grid-cols-3">
47
+ * <Outlet />
48
+ * </TabPanel>
49
+ * <TabPanel id="/analytics" className="uy:w-full uy:h-screen">
50
+ * <Outlet />
51
+ * </TabPanel>
52
+ * </Tabs>
53
+ * )
54
+ * }
55
+ * ```
56
+ * @remarks
57
+ * - Automatically syncs id with the same route matching logic as Tabs component
58
+ * - Handles nested routes properly (e.g., /settings/security matches /settings tab)
59
+ * - Supports both exact and fuzzy route matching via routeMatch prop
60
+ * - Maintains all accessibility features from the base TabPanel component
61
+ * - Must be used within a Tabs component from tanstack-router integration
62
+ * - **Pattern Constraint**: Choose ONE approach per Tabs component:
63
+ * - Single TabPanel without id prop (auto-syncs with active route)
64
+ * - Multiple TabPanels with explicit id props (one per tab)
65
+ * - Never mix auto-sync and explicit TabPanels in the same Tabs component
66
+ * - When using explicit ids, ensure count(Tab) equals count(TabPanel)
67
+ * - id and routeMatch can be overridden for custom behavior
68
+ * @see {@link TabPanelProps} for all available props
69
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/integrations/tanstack-router/tabs GitHub}
70
+ * @see Design specs {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
71
+ * @see Design docs in {@link https://www.payfit.design/ Payfit.design}
72
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/ unity-components.payfit.io}
73
+ */
74
+ export declare function TabPanel({ children, id: idProp, ...tabPanelProps }: PropsWithChildren<TabPanelProps>): import("react/jsx-runtime").JSX.Element;
75
+ export declare namespace TabPanel {
76
+ var displayName: string;
77
+ }
@@ -0,0 +1,16 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { useContext as s } from "react";
3
+ import { TabListStateContext as i } from "react-aria-components";
4
+ import { TabPanel as r } from "../../../../../components/tabs/parts/TabPanel.js";
5
+ function m({
6
+ children: t,
7
+ id: e,
8
+ ...o
9
+ }) {
10
+ const a = s(i)?.selectedKey ?? void 0;
11
+ return /* @__PURE__ */ n(r, { ...o, id: e ?? a, children: t });
12
+ }
13
+ m.displayName = "TabPanel";
14
+ export {
15
+ m as TabPanel
16
+ };
@@ -0,0 +1,69 @@
1
+ import { RegisteredRouter, ValidateLinkOptions } from '@tanstack/react-router';
2
+ import { SubTaskProps as RawSubTaskProps } from '../../../../components/task-menu/parts/RawSubTask.js';
3
+ type SubTaskRouterProps<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown> = Omit<RawSubTaskProps, 'href' | 'onPress'> & ValidateLinkOptions<TRouter, TOptions>;
4
+ type SubTaskButtonProps = Omit<RawSubTaskProps, 'href'> & {
5
+ onPress: NonNullable<RawSubTaskProps['onPress']>;
6
+ };
7
+ export type SubTaskProps<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown> = SubTaskRouterProps<TRouter, TOptions> | SubTaskButtonProps;
8
+ /**
9
+ * A subtask component that integrates with Tanstack Router for seamless navigation within task groups.
10
+ * Represents individual subtask items within a TaskGroup that can be either links for navigation or buttons
11
+ * for custom interactions, with support for various visual states including completed, uncompleted, and locked.
12
+ * @param {SubTaskProps} props - Either router-based props (with 'to') or button-based props (with 'onPress')
13
+ * @example
14
+ * ```tsx
15
+ * import { SubTask } from '@payfit/unity-components/integrations/tanstack-router'
16
+ * import { TaskMenu, TaskGroup } from '@payfit/unity-components'
17
+ *
18
+ * function OnboardingTaskGroup() {
19
+ * return (
20
+ * <TaskMenu label="Onboarding tasks">
21
+ * <TaskGroup
22
+ * uniqueId="onboarding"
23
+ * label="Complete Onboarding"
24
+ * taskNumber={1}
25
+ * taskStatus="uncompleted"
26
+ * >
27
+ * <SubTask
28
+ * uniqueId="profile-setup"
29
+ * label="Complete Profile Information"
30
+ * taskStatus="uncompleted"
31
+ * to="/onboarding/profile"
32
+ * />
33
+ * <SubTask
34
+ * uniqueId="validate-email"
35
+ * label="Validate Email Address"
36
+ * taskStatus="completed"
37
+ * onPress={() => console.log('Email validation triggered')}
38
+ * />
39
+ * <SubTask
40
+ * uniqueId="final-approval"
41
+ * label="Manager Approval"
42
+ * taskStatus="locked"
43
+ * to="/onboarding/approval"
44
+ * />
45
+ * </TaskGroup>
46
+ * </TaskMenu>
47
+ * )
48
+ * }
49
+ * ```
50
+ * @remarks
51
+ * - Automatically renders as a link when 'to' prop is provided, or as a button when 'onPress' is provided
52
+ * - Supports type-safe route parameters, search params, and relative navigation with Tanstack Router
53
+ * - Integrates with TaskGroup component for hierarchical task organization
54
+ * - Provides automatic active state styling based on current route
55
+ * - Supports multiple task states: completed, uncompleted, and locked
56
+ * - Displays a dot indicator instead of a numbered badge to distinguish from main Task components
57
+ * - Maintains all accessibility features from the underlying RawSubTask component
58
+ * - SubTask selection state is automatically managed based on routing context
59
+ * @see {@link SubTaskProps} for all available props
60
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/integrations/tanstack-router/components/task-menu GitHub}
61
+ * @see Design specs {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
62
+ * @see Design docs in {@link https://www.payfit.design/ Payfit.design}
63
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/ unity-components.payfit.io}
64
+ */
65
+ declare function SubTask<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown>(props: SubTaskProps<TRouter, TOptions>): import("react/jsx-runtime").JSX.Element;
66
+ declare namespace SubTask {
67
+ var displayName: string;
68
+ }
69
+ export { SubTask };
@@ -0,0 +1,14 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { createLink as e } from "@tanstack/react-router";
3
+ import { RawSubTask as o } from "../../../../components/task-menu/parts/RawSubTask.js";
4
+ const i = e(o);
5
+ function a(r) {
6
+ return "to" in r || "href" in r ? (
7
+ // @ts-expect-error - Complex type intersection between router props and component props
8
+ /* @__PURE__ */ t(i, { ...r, activeProps: { "data-current": !0 } })
9
+ ) : /* @__PURE__ */ t(o, { ...r });
10
+ }
11
+ a.displayName = "SubTask";
12
+ export {
13
+ a as SubTask
14
+ };
@@ -0,0 +1,64 @@
1
+ import { RegisteredRouter, ValidateLinkOptions } from '@tanstack/react-router';
2
+ import { TaskProps as RawTaskProps } from '../../../../components/task-menu/parts/RawTask.js';
3
+ type TaskRouterProps<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown> = Omit<RawTaskProps, 'href' | 'onPress'> & ValidateLinkOptions<TRouter, TOptions>;
4
+ type TaskButtonProps = Omit<RawTaskProps, 'href'> & {
5
+ onPress: NonNullable<RawTaskProps['onPress']>;
6
+ };
7
+ export type TaskProps<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown> = TaskRouterProps<TRouter, TOptions> | TaskButtonProps;
8
+ /**
9
+ * A task component that integrates with Tanstack Router for seamless navigation within task menus.
10
+ * Represents individual task items that can be either links for navigation or buttons for custom interactions,
11
+ * with support for various visual states including completed, uncompleted, locked, and selected states.
12
+ * @param {TaskProps} props - Either router-based props (with 'to') or button-based props (with 'onPress')
13
+ * @example
14
+ * ```tsx
15
+ * import { Task } from '@payfit/unity-components/integrations/tanstack-router'
16
+ * import { TaskMenu } from '@payfit/unity-components'
17
+ *
18
+ * function OnboardingTasks() {
19
+ * return (
20
+ * <TaskMenu label="Onboarding tasks">
21
+ * <Task
22
+ * uniqueId="setup-profile"
23
+ * label="Complete Profile Setup"
24
+ * taskNumber={1}
25
+ * taskStatus="uncompleted"
26
+ * to="/profile/setup"
27
+ * />
28
+ * <Task
29
+ * uniqueId="validate-data"
30
+ * label="Validate Information"
31
+ * taskNumber={2}
32
+ * taskStatus="completed"
33
+ * onPress={() => console.log('Validation triggered')}
34
+ * />
35
+ * <Task
36
+ * uniqueId="final-review"
37
+ * label="Final Review"
38
+ * taskNumber={3}
39
+ * taskStatus="locked"
40
+ * to="/review"
41
+ * />
42
+ * </TaskMenu>
43
+ * )
44
+ * }
45
+ * ```
46
+ * @remarks
47
+ * - Automatically renders as a link when 'to' prop is provided, or as a button when 'onPress' is provided
48
+ * - Supports type-safe route parameters, search params, and relative navigation with Tanstack Router
49
+ * - Integrates with TaskMenu component for consistent task navigation UI patterns
50
+ * - Provides automatic active state styling based on current route
51
+ * - Supports multiple task states: completed, uncompleted, and locked
52
+ * - Maintains all accessibility features from the underlying RawTask component
53
+ * - Task selection state is automatically managed based on routing context
54
+ * @see {@link TaskProps} for all available props
55
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/integrations/tanstack-router/components/task-menu GitHub}
56
+ * @see Design specs {@link https://www.figma.com/design/poaMyU7abAgL9VRhx4ygyy/Unity-DS-%3E-Components-Library Figma}
57
+ * @see Design docs in {@link https://www.payfit.design/ Payfit.design}
58
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/ unity-components.payfit.io}
59
+ */
60
+ declare function Task<TRouter extends RegisteredRouter = RegisteredRouter, TOptions = unknown>(props: TaskProps<TRouter, TOptions>): import("react/jsx-runtime").JSX.Element;
61
+ declare namespace Task {
62
+ var displayName: string;
63
+ }
64
+ export { Task };
@@ -0,0 +1,14 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { createLink as e } from "@tanstack/react-router";
3
+ import { RawTask as o } from "../../../../components/task-menu/parts/RawTask.js";
4
+ const i = e(o);
5
+ function a(r) {
6
+ return "to" in r || "href" in r ? (
7
+ // @ts-expect-error - Complex type intersection between router props and component props
8
+ /* @__PURE__ */ t(i, { ...r, activeProps: { "data-current": !0 } })
9
+ ) : /* @__PURE__ */ t(o, { ...r });
10
+ }
11
+ a.displayName = "Task";
12
+ export {
13
+ a as Task
14
+ };
@@ -0,0 +1,16 @@
1
+ export * from './components/breadcrumbs/Breadcrumb.js';
2
+ export * from './components/breadcrumbs/BreadcrumbLink.js';
3
+ export * from './components/breadcrumbs/Breadcrumbs.js';
4
+ export * from './components/form-contextual-link/FormContextualLink.js';
5
+ export * from './components/link/Link.js';
6
+ export * from './components/menu-item/MenuItem.js';
7
+ export * from './components/nav-item/NavItem.js';
8
+ export * from './components/pagination/PaginationLink.js';
9
+ export * from './components/pagination/PaginationNext.js';
10
+ export * from './components/pagination/PaginationPrevious.js';
11
+ export * from './components/tabs/parts/Tab.js';
12
+ export * from './components/tabs/parts/TabPanel.js';
13
+ export * from './components/tabs/parts/TabList.js';
14
+ export * from './components/tabs/Tabs.js';
15
+ export * from './components/task-menu/Task.js';
16
+ export * from './components/task-menu/SubTask.js';
@@ -0,0 +1,23 @@
1
+ import { Decorator, StoryContext } from '@storybook/react-vite';
2
+ import { AnyContext, LoaderFnContext, RootRoute, RouteComponent } from '@tanstack/react-router';
3
+ interface RouteConfig {
4
+ path: string;
5
+ element: RouteComponent | 'story';
6
+ loader?: ((ctx: LoaderFnContext<RootRoute<undefined, object, AnyContext, AnyContext, object>, any, any, any, AnyContext, any, any>) => any) | undefined;
7
+ children?: RouteConfig[];
8
+ beforeLoad?: ((ctx: LoaderFnContext<RootRoute<undefined, object, AnyContext, AnyContext, object>, any, any, any, AnyContext, any, any>) => any) | undefined;
9
+ validateSearch?: (search: Record<string, unknown>) => any;
10
+ loaderDeps?: (deps: Record<string, unknown>) => Record<string, unknown>;
11
+ }
12
+ export interface TanstackRouterDecoratorContext extends StoryContext {
13
+ parameters: {
14
+ router?: {
15
+ initialPath?: string;
16
+ renderRootRoute?: (Story: Parameters<Decorator>[0]) => React.ReactNode;
17
+ routes: RouteConfig[];
18
+ };
19
+ tanstackRouterDevTools?: boolean;
20
+ };
21
+ }
22
+ export declare const TanstackRouterDecorator: Decorator;
23
+ export {};
@@ -0,0 +1,34 @@
1
+ import { BreadcrumbLink as e } from "./tanstack-router/components/breadcrumbs/BreadcrumbLink.js";
2
+ import { FormContextualLink as m } from "./tanstack-router/components/form-contextual-link/FormContextualLink.js";
3
+ import { Link as x } from "./tanstack-router/components/link/Link.js";
4
+ import { MenuItem as p } from "./tanstack-router/components/menu-item/MenuItem.js";
5
+ import { NavItem as i } from "./tanstack-router/components/nav-item/NavItem.js";
6
+ import { PaginationLink as u } from "./tanstack-router/components/pagination/PaginationLink.js";
7
+ import { PaginationNext as s } from "./tanstack-router/components/pagination/PaginationNext.js";
8
+ import { PaginationPrevious as L } from "./tanstack-router/components/pagination/PaginationPrevious.js";
9
+ import { Tab as c } from "./tanstack-router/components/tabs/parts/Tab.js";
10
+ import { TabPanel as g } from "./tanstack-router/components/tabs/parts/TabPanel.js";
11
+ import { Tabs as l } from "./tanstack-router/components/tabs/Tabs.js";
12
+ import { Task as I } from "./tanstack-router/components/task-menu/Task.js";
13
+ import { SubTask as C } from "./tanstack-router/components/task-menu/SubTask.js";
14
+ import { Breadcrumb as M } from "../components/breadcrumbs/parts/Breadcrumb.js";
15
+ import { Breadcrumbs as h } from "../components/breadcrumbs/Breadcrumbs.js";
16
+ import { TabList as q } from "../components/tabs/parts/TabList.js";
17
+ export {
18
+ M as Breadcrumb,
19
+ e as BreadcrumbLink,
20
+ h as Breadcrumbs,
21
+ m as FormContextualLink,
22
+ x as Link,
23
+ p as MenuItem,
24
+ i as NavItem,
25
+ u as PaginationLink,
26
+ s as PaginationNext,
27
+ L as PaginationPrevious,
28
+ C as SubTask,
29
+ c as Tab,
30
+ q as TabList,
31
+ g as TabPanel,
32
+ l as Tabs,
33
+ I as Task
34
+ };
@@ -1,4 +1,4 @@
1
- import { ComponentProps } from 'react';
1
+ import { ComponentProps, PropsWithChildren } from 'react';
2
2
  import { RouterProvider as AriaRouterProvider } from 'react-aria-components';
3
3
  export interface ExtendedRouterContextValue {
4
4
  /**
@@ -26,7 +26,7 @@ export interface RouterProviderProps extends ComponentProps<typeof AriaRouterPro
26
26
  isActive: (to: string) => boolean;
27
27
  }
28
28
  /**
29
- * The `RouterProvider` component is a provider that allows for integrations between Unity components that render links (such as `Link`, `NavItem`, etc.) and any client-side routing library in a single or multi-page application.
29
+ * The `RouterProvider` component is a provider that allows for integrations between Unity components that render links (such as `RawLink`, `RawNavItem`, etc.) and any client-side routing library in a single or multi-page application.
30
30
  *
31
31
  * By default, links perform native browser navigation when they are interacted with. However, many apps and frameworks use client side routers to avoid a full page reload when navigating between pages. The `RouterProvider` component configures all Unity components that support it to navigate using the client side router you provide. Set this up once in the root of your app, and any component with the href prop will automatically navigate using your router.
32
32
  */
@@ -34,4 +34,9 @@ export declare function RouterProvider({ isActive, children, ...routerProps }: R
34
34
  export declare namespace RouterProvider {
35
35
  var displayName: string;
36
36
  }
37
+ /**
38
+ * The `NoopRouterProvider` should only be use when transitioning between routers to bail out of the previous provider
39
+ * that is rendered upper in the react tree.
40
+ */
41
+ export declare function NoopRouterProvider({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
37
42
  export {};
@@ -1,18 +1,22 @@
1
1
  import { jsx as e } from "react/jsx-runtime";
2
- import { useContext as u, createContext as i } from "react";
2
+ import { useContext as n, createContext as i } from "react";
3
3
  import { RouterProvider as d } from "react-aria-components";
4
4
  const o = i(
5
5
  null
6
- ), R = () => u(o);
7
- function m({
8
- isActive: t,
9
- children: n,
10
- ...r
6
+ ), a = () => n(o);
7
+ function v({
8
+ isActive: r,
9
+ children: u,
10
+ ...t
11
11
  }) {
12
- return /* @__PURE__ */ e(o.Provider, { value: { isActive: t, ...r }, children: /* @__PURE__ */ e(d, { ...r, children: n }) });
12
+ return /* @__PURE__ */ e(o.Provider, { value: { isActive: r, ...t }, children: /* @__PURE__ */ e(d, { ...t, children: u }) });
13
13
  }
14
- m.displayName = "RouterProvider";
14
+ function c({ children: r }) {
15
+ return /* @__PURE__ */ e(o.Provider, { value: null, children: r });
16
+ }
17
+ v.displayName = "RouterProvider";
15
18
  export {
16
- m as RouterProvider,
17
- R as useRouter
19
+ c as NoopRouterProvider,
20
+ v as RouterProvider,
21
+ a as useRouter
18
22
  };
@@ -1 +1 @@
1
- export type DataAttributes = Record<`data-${string}`, string | number>;
1
+ export type DataAttributes = Record<`data-${string}`, unknown>;
package/i18n/en-GB.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "unity:component:common:clear:title": "Clear",
4
4
  "unity:component:common:close:label": "Close",
5
5
  "unity:component:common:loading:label": "Loading...",
6
+ "unity:component:common:unknown": "unknown",
6
7
  "unity:component:common:previous": "Previous",
7
8
  "unity:component:common:next": "Next",
8
9
  "unity:component:common:customer-support:url": "https://support.payfit.com/en/inbox/",
package/i18n/es-ES.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "unity:component:common:clear:title": "Borrar",
4
4
  "unity:component:common:close:label": "Cerrar",
5
5
  "unity:component:common:loading:label": "Cargando...",
6
+ "unity:component:common:unknown": "desconocido",
6
7
  "unity:component:common:previous": "Anterior",
7
8
  "unity:component:common:next": "Siguiente",
8
9
  "unity:component:common:customer-support:url": "https://support.payfit.com/es/inbox/",
package/i18n/fr-FR.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "unity:component:common:clear:title": "Effacer",
4
4
  "unity:component:common:close:label": "Fermer",
5
5
  "unity:component:common:loading:label": "Chargement...",
6
+ "unity:component:common:unknown": "inconnu",
6
7
  "unity:component:common:previous": "Précédent",
7
8
  "unity:component:common:next": "Suivant",
8
9
  "unity:component:common:customer-support:url": "https://support.payfit.com/fr/inbox/",