@moderneinc/neo-styled-components 5.0.0-next.bd2a49 → 5.0.0-next.d2d555

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 (37) hide show
  1. package/dist/Alert/Alert.d.ts +9 -1
  2. package/dist/Badge/Badge.d.ts +16 -2
  3. package/dist/DataGrid/DataGrid.d.ts +1 -1
  4. package/dist/DataGrid/DataGrid.styles.d.ts +3 -0
  5. package/dist/DataGridCell/DataGridCell.d.ts +0 -16
  6. package/dist/DataGridHeaderCell/DataGridHeaderCell.d.ts +0 -37
  7. package/dist/DatePickerListItem/DatePickerListItem.d.ts +2 -22
  8. package/dist/DatePickerMenu/DatePickerMenu.d.ts +2 -22
  9. package/dist/InputField/InputField.d.ts +12 -1
  10. package/dist/ListItemButton/ListItemButton.d.ts +12 -1
  11. package/dist/MenuItem/MenuItem.d.ts +1 -1
  12. package/dist/NavigationAvatar/NavigationAvatar.d.ts +2 -2
  13. package/dist/NavigationItem/NavigationItem.d.ts +14 -2
  14. package/dist/NeoActionsCell/NeoActionsCell.d.ts +9 -0
  15. package/dist/NeoAvatarCell/NeoAvatarCell.d.ts +27 -0
  16. package/dist/NeoIconCell/NeoIconCell.d.ts +14 -0
  17. package/dist/NeoLogoCell/NeoLogoCell.d.ts +24 -0
  18. package/dist/NeoProgressCell/NeoProgressCell.d.ts +21 -0
  19. package/dist/NeoStatusCell/NeoStatusCell.d.ts +30 -0
  20. package/dist/PageContent/PageContent.d.ts +12 -1
  21. package/dist/RadioButtonWithText/RadioButtonWithText.d.ts +2 -22
  22. package/dist/SelectField/SelectField.d.ts +64 -0
  23. package/dist/SideNav/SideNav.d.ts +2 -22
  24. package/dist/TabPanel/TabPanel.d.ts +47 -0
  25. package/dist/Table/Table.d.ts +64 -0
  26. package/dist/Tag/Tag.d.ts +1 -2
  27. package/dist/ToggleButton/ToggleButton.d.ts +13 -18
  28. package/dist/ToggleButtonGroup/ToggleButtonGroup.d.ts +26 -0
  29. package/dist/ToggleButtonWithText/ToggleButtonWithText.d.ts +2 -22
  30. package/dist/TopNav/TopNav.d.ts +2 -22
  31. package/dist/TourModal/TourModal.d.ts +2 -22
  32. package/dist/index.d.ts +499 -94
  33. package/dist/index.esm.js +800 -335
  34. package/dist/index.esm.js.map +1 -1
  35. package/dist/index.js +816 -332
  36. package/dist/index.js.map +1 -1
  37. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -7,7 +7,7 @@ import MuiAvatar from '@mui/material/Avatar';
7
7
  import SvgIcon, { svgIconClasses } from '@mui/material/SvgIcon';
8
8
  import Alert, { alertClasses } from '@mui/material/Alert';
9
9
  import ButtonBase, { buttonBaseClasses } from '@mui/material/ButtonBase';
10
- import React, { useContext, createContext, forwardRef, createElement, useState, useRef, useCallback, useMemo, useEffect } from 'react';
10
+ import React, { useContext, createContext, forwardRef, createElement, useState, useRef, useCallback, useMemo, useEffect, Children, isValidElement, cloneElement } from 'react';
11
11
  import IconButton, { iconButtonClasses } from '@mui/material/IconButton';
12
12
  import Breadcrumbs, { breadcrumbsClasses } from '@mui/material/Breadcrumbs';
13
13
  import Link from '@mui/material/Link';
@@ -16,7 +16,7 @@ import MuiToggleButton, { toggleButtonClasses } from '@mui/material/ToggleButton
16
16
  import MuiToggleButtonGroup, { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup';
17
17
  import MuiCard from '@mui/material/Card';
18
18
  import Checkbox, { checkboxClasses } from '@mui/material/Checkbox';
19
- import { useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, GridFilterPanel, gridClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
19
+ import { useGridApiContext, useGridSelector, gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, GridFilterPanel, gridClasses, ColumnsPanelTrigger, ToolbarButton, gridFilterModelSelector, FilterPanelTrigger, gridPaginationModelSelector, gridRowCountSelector, gridRowSelectionCountSelector, GridActionsCell, QuickFilter, QuickFilterControl, QuickFilterClear, Toolbar } from '@mui/x-data-grid';
20
20
  import { useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro';
21
21
  import Button, { buttonClasses } from '@mui/material/Button';
22
22
  import Divider from '@mui/material/Divider';
@@ -55,6 +55,12 @@ import Fab from '@mui/material/Fab';
55
55
  import Fade from '@mui/material/Fade';
56
56
  import Radio, { radioClasses } from '@mui/material/Radio';
57
57
  import Skeleton from '@mui/material/Skeleton';
58
+ import MuiTable from '@mui/material/Table';
59
+ import TableBody from '@mui/material/TableBody';
60
+ import TableCell, { tableCellClasses } from '@mui/material/TableCell';
61
+ import TableContainer from '@mui/material/TableContainer';
62
+ import TableHead from '@mui/material/TableHead';
63
+ import TableRow from '@mui/material/TableRow';
58
64
  import MuiTab, { tabClasses } from '@mui/material/Tab';
59
65
  import MuiTabs, { tabsClasses } from '@mui/material/Tabs';
60
66
  import Switch, { switchClasses } from '@mui/material/Switch';
@@ -62,8 +68,37 @@ import { useTreeItemModel } from '@mui/x-tree-view/hooks';
62
68
  import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem';
63
69
  import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro';
64
70
 
65
- const StyledChip$2 = styled(Chip)(({ theme }) => ({
66
- height: 24,
71
+ const STATUS_COLOR_CLASSES = [
72
+ [chipClasses.colorDefault, semanticColors.status.neutral],
73
+ [chipClasses.colorError, semanticColors.status.error],
74
+ [chipClasses.colorWarning, semanticColors.status.warning],
75
+ [chipClasses.colorSuccess, semanticColors.status.success],
76
+ [chipClasses.colorInfo, semanticColors.status.info],
77
+ ];
78
+ const outlinedColorOverrides = {
79
+ backgroundColor: 'transparent',
80
+ color: semanticColors.typography.bodySecondary,
81
+ border: `1px solid ${semanticColors.border.secondary}`,
82
+ [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
83
+ color: semanticColors.typography.bodySecondary,
84
+ },
85
+ };
86
+ const filledColorRules = Object.fromEntries(STATUS_COLOR_CLASSES.map(([className, palette]) => [
87
+ `&.${className}`,
88
+ {
89
+ backgroundColor: palette.light,
90
+ color: palette.dark,
91
+ border: `1px solid ${palette.transparent}`,
92
+ [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
93
+ color: palette.dark,
94
+ },
95
+ },
96
+ ]));
97
+ const outlinedColorRules = Object.fromEntries(STATUS_COLOR_CLASSES.map(([className]) => [`&.${className}`, outlinedColorOverrides]));
98
+ const StyledChip$3 = styled(Chip, {
99
+ shouldForwardProp: prop => prop !== 'badgeSize' && prop !== 'badgeVariant',
100
+ })(({ theme, badgeSize, badgeVariant }) => ({
101
+ height: badgeSize === 'small' ? 20 : 24,
67
102
  paddingTop: spacing.spacing_1_4,
68
103
  paddingBottom: spacing.spacing_1_4,
69
104
  paddingLeft: spacing.spacing_1,
@@ -91,51 +126,7 @@ const StyledChip$2 = styled(Chip)(({ theme }) => ({
91
126
  width: 12,
92
127
  height: 12,
93
128
  },
94
- // Default (Neutral) state
95
- [`&.${chipClasses.colorDefault}`]: {
96
- backgroundColor: semanticColors.status.neutral.light,
97
- color: semanticColors.status.neutral.dark,
98
- border: `1px solid ${semanticColors.status.neutral.default}80`,
99
- [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
100
- color: semanticColors.status.neutral.dark,
101
- },
102
- },
103
- // Error state
104
- [`&.${chipClasses.colorError}`]: {
105
- backgroundColor: semanticColors.status.error.light,
106
- color: semanticColors.status.error.dark,
107
- border: `1px solid ${semanticColors.status.error.default}80`,
108
- [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
109
- color: semanticColors.status.error.dark,
110
- },
111
- },
112
- // Warning state
113
- [`&.${chipClasses.colorWarning}`]: {
114
- backgroundColor: semanticColors.status.warning.light,
115
- color: semanticColors.status.warning.dark,
116
- border: `1px solid ${semanticColors.status.warning.default}80`,
117
- [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
118
- color: semanticColors.status.warning.dark,
119
- },
120
- },
121
- // Success state
122
- [`&.${chipClasses.colorSuccess}`]: {
123
- backgroundColor: semanticColors.status.success.light,
124
- color: semanticColors.status.success.dark,
125
- border: `1px solid ${semanticColors.status.success.default}80`,
126
- [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
127
- color: semanticColors.status.success.dark,
128
- },
129
- },
130
- // Info state
131
- [`&.${chipClasses.colorInfo}`]: {
132
- backgroundColor: semanticColors.status.info.light,
133
- color: semanticColors.status.info.dark,
134
- border: `1px solid ${semanticColors.status.info.default}80`,
135
- [`& .${chipClasses.icon}, & .${chipClasses.deleteIcon}`]: {
136
- color: semanticColors.status.info.dark,
137
- },
138
- },
129
+ ...(badgeVariant === 'outlined' ? outlinedColorRules : filledColorRules),
139
130
  }));
140
131
  /**
141
132
  * NeoBadge - Status badge component based on MUI Chip
@@ -148,8 +139,8 @@ const StyledChip$2 = styled(Chip)(({ theme }) => ({
148
139
  * - TrailingIcon → deleteIcon prop (pass React element)
149
140
  * - Label → label prop
150
141
  */
151
- const NeoBadge = (props) => {
152
- return jsx(StyledChip$2, { ...props });
142
+ const NeoBadge = ({ size = 'medium', variant = 'filled', ...props }) => {
143
+ return jsx(StyledChip$3, { ...props, badgeSize: size, badgeVariant: variant });
153
144
  };
154
145
  NeoBadge.displayName = 'NeoBadge';
155
146
 
@@ -267,22 +258,6 @@ const NeoDataGridCellContent = ({ children, ...props }) => {
267
258
  return jsx(CellContentContainer, { ...props, children: children });
268
259
  };
269
260
  NeoDataGridCellContent.displayName = 'NeoDataGridCellContent';
270
- /**
271
- * Utility function to get DataGrid sx styles for consistent cell appearance
272
- *
273
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4212-41631
274
- *
275
- * Apply this to DataGrid's `sx` prop to ensure cells are properly aligned and styled.
276
- *
277
- * @param size - Row size variant (affects row height)
278
- * @returns SxProps for DataGrid
279
- *
280
- * @example
281
- * <DataGrid
282
- * rows={rows}
283
- * columns={columns}
284
- * />
285
- */
286
261
  /**
287
262
  * Row height configuration for DataGrid size variants (from Figma specs)
288
263
  * - compact: 42px
@@ -937,14 +912,17 @@ const intentColors$2 = {
937
912
  };
938
913
  // biome-ignore lint/suspicious/noExplicitAny: Type cast required to override MUI Alert variant type without global augmentation
939
914
  const StyledAlert$2 = styled(Alert, {
940
- shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType',
941
- })(({ theme, intent = 'success', alertType = 'outlined' }) => {
915
+ shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType' && prop !== 'alertSize',
916
+ })(({ theme, intent = 'success', alertType = 'outlined', alertSize = 'default' }) => {
942
917
  const palette = intentColors$2[intent];
943
918
  const isFilled = alertType === 'filled';
919
+ const isCompact = alertSize === 'compact';
944
920
  const iconColor = isFilled ? semanticColors.typography.tooltip : palette.default;
945
- const messageColor = isFilled ? semanticColors.typography.tooltip : semanticColors.typography.body;
921
+ const messageColor = isFilled
922
+ ? semanticColors.typography.tooltip
923
+ : semanticColors.typography.body;
946
924
  return {
947
- height: spacing.spacing_8,
925
+ ...(isCompact ? { minHeight: spacing.spacing_5 } : { height: spacing.spacing_8 }),
948
926
  width: '100%',
949
927
  borderRadius: borderRadius.xS,
950
928
  alignItems: 'center',
@@ -1007,9 +985,9 @@ const iconMap = {
1007
985
  * - Show supporting text → description prop presence
1008
986
  * - Show Button → action prop presence
1009
987
  */
1010
- const NeoAlert = ({ intent = 'success', type = 'outlined', title, description, icon, action, ...props }) => {
988
+ const NeoAlert = ({ intent = 'success', type = 'outlined', size = 'default', title, description, icon, action, ...props }) => {
1011
989
  const defaultIcon = iconMap[intent];
1012
- return (jsxs(StyledAlert$2, { ...props, intent: intent, alertType: type, icon: icon ?? defaultIcon, action: action, children: [jsx("span", { children: title }), description && jsx("span", { children: description })] }));
990
+ return (jsxs(StyledAlert$2, { ...props, intent: intent, alertType: type, alertSize: size, icon: icon ?? defaultIcon, action: action, children: [jsx("span", { children: title }), description && jsx("span", { children: description })] }));
1013
991
  };
1014
992
  NeoAlert.displayName = 'NeoAlert';
1015
993
 
@@ -2183,7 +2161,7 @@ const StyledMenuItem = styled(MenuItem)(({ theme }) => ({
2183
2161
  gap: theme.spacing(2),
2184
2162
  borderRadius: 0,
2185
2163
  color: semanticColors.icons.default,
2186
- fontSize: theme.typography.pxToRem(typography.fontSize.sm),
2164
+ fontSize: theme.typography.pxToRem(typography.fontSize.default),
2187
2165
  fontWeight: typography.fontWeight.regular,
2188
2166
  lineHeight: `${typography.lineHeight.s}px`,
2189
2167
  transition: theme.transitions.create(['background-color'], {
@@ -2249,7 +2227,7 @@ const Shortcut = styled('span')(({ theme }) => ({
2249
2227
  /**
2250
2228
  * NeoMenuItem - Menu item component based on MUI MenuItem
2251
2229
  *
2252
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4159-8584
2230
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025-26?node-id=4159-8714
2253
2231
  *
2254
2232
  * @example
2255
2233
  * ```tsx
@@ -2544,56 +2522,24 @@ function SortedAscendingIcon() {
2544
2522
  function UnsortedIcon() {
2545
2523
  return jsx(ChevronsUpDown, { size: 16, color: semanticColors.icons.utility });
2546
2524
  }
2547
- /**
2548
- * Utility function to get DataGrid sx styles for header cells
2549
- *
2550
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4212-41618
2551
- *
2552
- * Figma prop mappings:
2553
- * - `size` → `size`: Figma "condensed" → MUI 'compact', Figma "default" → MUI 'standard', Figma "relaxed" → MUI 'comfortable'
2554
- *
2555
- * Design tokens used:
2556
- * - Background: colors.grey[50] (#f9fafb)
2557
- * - Border: semanticColors.border.primary
2558
- * - Padding: 12px vertical, 24px horizontal
2559
- * - Gap: 12px
2560
- *
2561
- *
2562
- * @param size - Header row size variant (affects header cell height)
2563
- * @returns SxProps for DataGrid header cells
2564
- *
2565
- * @example
2566
- * import { getDataGridHeaderStyles, SortedDescendingIcon, SortedAscendingIcon, UnsortedIcon } from './DataGridHeaderCell'
2567
- *
2568
- * <DataGrid
2569
- * columnHeaderHeight={38} // for compact (Figma: condensed)
2570
- * sx={{
2571
- * ...getDataGridHeaderStyles(),
2572
- * }}
2573
- * slots={{
2574
- * columnSortedDescendingIcon: SortedDescendingIcon,
2575
- * columnSortedAscendingIcon: SortedAscendingIcon,
2576
- * columnUnsortedIcon: UnsortedIcon,
2577
- * }}
2578
- * rows={rows}
2579
- * columns={columns}
2580
- * />
2581
- */
2525
+
2582
2526
  const getDataGridHeaderStyles = () => {
2583
2527
  return {
2584
2528
  // Header cell container styles - from Figma: bg, border, padding
2585
2529
  // Height is set via density-specific selectors in DataGrid.tsx
2586
2530
  [`& .${gridClasses.columnHeader}`]: {
2587
- backgroundColor: colors.grey[50],
2531
+ backgroundColor: semanticColors.surfaces.dataGrid.header,
2588
2532
  borderBottom: `1px solid ${semanticColors.border.primary}`,
2589
- paddingLeft: `${spacing.spacing_3}px`,
2590
- paddingRight: `${spacing.spacing_3}px`,
2533
+ paddingTop: `${spacing.spacing_1_1_2}px`,
2534
+ paddingBottom: `${spacing.spacing_1_1_2}px`,
2535
+ paddingLeft: `${spacing.spacing_2}px`,
2536
+ paddingRight: `${spacing.spacing_2}px`,
2591
2537
  boxSizing: 'border-box',
2592
2538
  },
2593
2539
  // Style the filler element to match header
2594
2540
  // Height is set via density-specific selectors in DataGrid.tsx
2595
2541
  [`& .${gridClasses.filler}`]: {
2596
- backgroundColor: colors.grey[50],
2542
+ backgroundColor: semanticColors.surfaces.dataGrid.header,
2597
2543
  borderBottom: `1px solid ${semanticColors.border.primary}`,
2598
2544
  boxSizing: 'border-box',
2599
2545
  },
@@ -2643,6 +2589,20 @@ const getDataGridHeaderStyles = () => {
2643
2589
  },
2644
2590
  };
2645
2591
  };
2592
+ const getDataGridRowStyles = () => ({
2593
+ [`& .${gridClasses.row}`]: {
2594
+ backgroundColor: semanticColors.surfaces.dataGrid.default,
2595
+ },
2596
+ [`& .${gridClasses.row}:hover`]: {
2597
+ backgroundColor: semanticColors.surfaces.dataGrid.hover,
2598
+ },
2599
+ [`& .${gridClasses.row}.Mui-selected`]: {
2600
+ backgroundColor: semanticColors.surfaces.dataGrid.selected,
2601
+ },
2602
+ [`& .${gridClasses.row}.Mui-selected:hover`]: {
2603
+ backgroundColor: semanticColors.surfaces.dataGrid.selectedHover,
2604
+ },
2605
+ });
2646
2606
 
2647
2607
  /**
2648
2608
  * Adapter to use NeoCheckbox in DataGrid's baseCheckbox slot
@@ -2677,7 +2637,7 @@ const DataGridCheckbox = ({ slotProps, ...props }) => (jsx(NeoCheckbox, { size:
2677
2637
  * - `size` → Row heights (compact: 42px, standard: 48px, comfortable: 56px) and header heights (compact: 38px, standard: 44px, comfortable: 52px)
2678
2638
  *
2679
2639
  * Design tokens used:
2680
- * - Colors: semanticColors.border.primary, semanticColors.background.*
2640
+ * - Colors: semanticColors.border.primary, semanticColors.surfaces.dataGrid.*
2681
2641
  * - Typography: typography.fontFamily.body, typography.fontSize.sm
2682
2642
  * - Spacing: spacing.spacing_*
2683
2643
  *
@@ -2721,13 +2681,14 @@ function NeoDataGrid({ autoHeight = false, toolbar, slots, sx, density = 'standa
2721
2681
  // See: https://github.com/mui/mui-x/issues/20107
2722
2682
  // This must be set to prevent scroll shadow artifacts
2723
2683
  [`& .${gridClasses.main}`]: {
2724
- backgroundColor: semanticColors.surfaces.white,
2684
+ backgroundColor: semanticColors.surfaces.dataGrid.background,
2725
2685
  },
2726
2686
  // White background for empty/loading overlays
2727
2687
  [`& .${gridClasses.overlay}`]: {
2728
- backgroundColor: semanticColors.surfaces.white,
2688
+ backgroundColor: semanticColors.surfaces.dataGrid.background,
2729
2689
  },
2730
2690
  ...getDataGridHeaderStyles(),
2691
+ ...getDataGridRowStyles(),
2731
2692
  border: `1px solid ${semanticColors.border.secondary}`,
2732
2693
  // Style row selection checkboxes to match header (16px, proper spacing)
2733
2694
  [`& .${gridClasses.cellCheckbox}`]: {
@@ -2782,7 +2743,7 @@ function NeoDataGridColumnsButton() {
2782
2743
  }
2783
2744
  NeoDataGridColumnsButton.displayName = 'NeoDataGridColumnsButton';
2784
2745
 
2785
- const sizeStyles = {
2746
+ const sizeStyles$1 = {
2786
2747
  small: {
2787
2748
  height: 16,
2788
2749
  minWidth: 16,
@@ -2848,14 +2809,14 @@ const filledColorStyles = {
2848
2809
  violet: colors.violet[500],
2849
2810
  beta: colors.digitalBlue[300],
2850
2811
  };
2851
- const StyledChip$1 = styled(Chip)(({ theme, size, variant, color }) => ({
2812
+ const StyledChip$2 = styled(Chip)(({ theme, size, variant, color }) => ({
2852
2813
  padding: 0,
2853
2814
  boxSizing: 'border-box',
2854
2815
  borderRadius: borderRadius.full,
2855
2816
  fontSize: theme.typography.pxToRem(typography.fontSize.xs),
2856
2817
  lineHeight: 1,
2857
2818
  fontWeight: typography.fontWeight.medium,
2858
- ...(size && sizeStyles[size]),
2819
+ ...(size && sizeStyles$1[size]),
2859
2820
  [`& .${chipClasses.label}`]: {
2860
2821
  padding: 0,
2861
2822
  },
@@ -2882,7 +2843,7 @@ const StyledChip$1 = styled(Chip)(({ theme, size, variant, color }) => ({
2882
2843
  * - TEXT Label → label prop
2883
2844
  */
2884
2845
  function NeoTag({ size = 'small', variant = 'outlined', intent = 'default', ...props }) {
2885
- return jsx(StyledChip$1, { size: size, variant: variant, color: intent, ...props });
2846
+ return jsx(StyledChip$2, { size: size, variant: variant, color: intent, ...props });
2886
2847
  }
2887
2848
  NeoTag.displayName = 'NeoTag';
2888
2849
 
@@ -2941,7 +2902,7 @@ const LabelContainer$2 = styled('div')({
2941
2902
  alignItems: 'center',
2942
2903
  gap: `${spacing.spacing_1_2}px`,
2943
2904
  });
2944
- const LabelText = styled('p')({
2905
+ const LabelText$1 = styled('p')({
2945
2906
  fontFamily: `${typography.fontFamily.body}, sans-serif`,
2946
2907
  fontSize: typography.fontSize.sm,
2947
2908
  fontWeight: typography.fontWeight.semiBold, // Always semiBold (600)
@@ -2970,7 +2931,7 @@ const IconWrapper = styled('div')({
2970
2931
  },
2971
2932
  });
2972
2933
  function NeoDataGridHeaderLabel({ children, helpTooltip, className, }) {
2973
- return (jsxs(LabelContainer$2, { className: className, "data-neo-header-label": true, children: [children && jsx(LabelText, { children: children }), helpTooltip && (jsx(Tooltip, { title: helpTooltip, placement: "top", children: jsx(IconWrapper, { children: jsx(CircleQuestionMark, {}) }) }))] }));
2934
+ return (jsxs(LabelContainer$2, { className: className, "data-neo-header-label": true, children: [children && jsx(LabelText$1, { children: children }), helpTooltip && (jsx(Tooltip, { title: helpTooltip, placement: "top", children: jsx(IconWrapper, { children: jsx(CircleQuestionMark, {}) }) }))] }));
2974
2935
  }
2975
2936
 
2976
2937
  /**
@@ -3508,7 +3469,8 @@ const StyledNavButton = styled(IconButton, {
3508
3469
  */
3509
3470
  const NeoIconButton = ({ size = 'medium', variant = 'tertiary', active = false, loading, children, ...props }) => {
3510
3471
  if (variant === 'nav') {
3511
- return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...props, children: children }));
3472
+ const { color, ...navProps } = props;
3473
+ return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...navProps, children: children }));
3512
3474
  }
3513
3475
  return (jsx(StyledIconOnlyButton, { variant: variant, size: size, loading: loading, ...props, children: children }));
3514
3476
  };
@@ -3761,6 +3723,20 @@ const NeoDatePicker = ({ type = 'single', open, label, value, rangeValue, onChan
3761
3723
  };
3762
3724
  NeoDatePicker.displayName = 'NeoDatePicker';
3763
3725
 
3726
+ /**
3727
+ * NeoDatePickerListItem
3728
+ *
3729
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8521
3730
+ */
3731
+ const NeoDatePickerListItem = styled('div')({});
3732
+
3733
+ /**
3734
+ * NeoDatePickerMenu
3735
+ *
3736
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8593
3737
+ */
3738
+ const NeoDatePickerMenu = styled('div')({});
3739
+
3764
3740
  const StyledDivider = styled(Divider)(({ theme }) => ({
3765
3741
  borderColor: semanticColors.border.secondary,
3766
3742
  marginTop: theme.spacing(1),
@@ -3931,7 +3907,7 @@ const NeoDownloadToast = ({ title, fileName, progress, showClose = true, showPau
3931
3907
  NeoDownloadToast.displayName = 'NeoDownloadToast';
3932
3908
 
3933
3909
  const filterChipOnlyProps = ['selected', 'expanded', 'selectedLabel', 'count', 'onClear'];
3934
- const StyledChip = styled(Chip, {
3910
+ const StyledChip$1 = styled(Chip, {
3935
3911
  shouldForwardProp: prop => !filterChipOnlyProps.includes(prop),
3936
3912
  })(({ theme, selected }) => ({
3937
3913
  borderRadius: borderRadius.full,
@@ -4021,7 +3997,7 @@ const CountBadge = styled('span')(({ theme }) => ({
4021
3997
  */
4022
3998
  const NeoFilterChip = ({ label, selected = false, expanded, selectedLabel, count = 0, onClear, onClick, ...props }) => {
4023
3999
  const chipLabel = selected ? (jsxs(LabelContent, { children: [jsxs(TextStack, { children: [jsx(HeaderLabel, { children: label }), jsx(SelectedLabel, { children: selectedLabel ?? label })] }), count > 0 && jsx(CountBadge, { children: count })] })) : (label);
4024
- return (jsx(StyledChip, { label: chipLabel, selected: selected, clickable: true, onClick: onClick, onDelete: selected && onClear ? onClear : undefined, deleteIcon: jsx(X, { size: 24 }), "aria-expanded": expanded, ...props }));
4000
+ return (jsx(StyledChip$1, { label: chipLabel, selected: selected, clickable: true, onClick: onClick, onDelete: selected && onClear ? onClear : undefined, deleteIcon: jsx(X, { size: 24 }), "aria-expanded": expanded, ...props }));
4025
4001
  };
4026
4002
  NeoFilterChip.displayName = 'NeoFilterChip';
4027
4003
 
@@ -4819,87 +4795,127 @@ const NeoListItem = ({ size = 'medium', primaryText, secondaryText, badge, icon,
4819
4795
  };
4820
4796
  NeoListItem.displayName = 'NeoListItem';
4821
4797
 
4822
- /**
4823
- * Styled ListItemButton with Neo design tokens
4824
- * Uses MUI's ListItemButton as base for proper accessibility and interaction
4825
- */
4826
- const StyledListItemButton = styled(ListItemButton)(({ theme }) => ({
4827
- display: 'flex',
4828
- alignItems: 'center',
4829
- gap: spacing.spacing_2,
4830
- borderRadius: borderRadius.m,
4831
- paddingTop: spacing.spacing_1,
4832
- paddingBottom: spacing.spacing_1,
4833
- paddingLeft: spacing.spacing_3_4,
4834
- paddingRight: spacing.spacing_3_4,
4835
- border: `1px solid ${semanticColors.border.primary}`,
4836
- backgroundColor: theme.palette.common.white,
4837
- transition: theme.transitions.create(['border', 'background-color']),
4838
- // Active (selected) state
4839
- [`&.${listItemButtonClasses.selected}`]: {
4840
- border: `2px solid ${semanticColors.buttons.primary.default}`,
4841
- backgroundColor: theme.palette.common.white,
4842
- '&:hover': {
4843
- backgroundColor: theme.palette.common.white,
4844
- },
4845
- // Icon color in selected state
4846
- [`& .${listItemIconClasses.root}`]: {
4847
- color: semanticColors.icons.default,
4848
- },
4849
- // Text colors in selected state
4850
- [`& .${listItemTextClasses.primary}`]: {
4851
- color: colors.grey[800],
4852
- },
4853
- [`& .${listItemTextClasses.secondary}`]: {
4854
- color: semanticColors.typography.bodySecondary,
4855
- },
4856
- },
4857
- // Deselected (default) state
4858
- [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
4859
- '&:hover': {
4860
- backgroundColor: colors.grey[50],
4798
+ const StyledListItemButton = styled(ListItemButton, {
4799
+ shouldForwardProp: prop => prop !== 'listVariant',
4800
+ })(({ theme, listVariant = 'card' }) => listVariant === 'nav' ? navVariantStyles(theme) : cardVariantStyles(theme));
4801
+ // Nav variant — sidebar list item: no border, compact, subtle highlights.
4802
+ // Renders children inline; no ListItemIcon/ListItemText wrappers required.
4803
+ function navVariantStyles(theme) {
4804
+ return {
4805
+ display: 'flex',
4806
+ alignItems: 'center',
4807
+ gap: spacing.spacing_2,
4808
+ borderRadius: borderRadius.s,
4809
+ paddingTop: spacing.spacing_1,
4810
+ paddingBottom: spacing.spacing_1,
4811
+ paddingLeft: spacing.spacing_2,
4812
+ paddingRight: spacing.spacing_2,
4813
+ border: 'none',
4814
+ color: semanticColors.typography.bodySecondary,
4815
+ backgroundColor: 'transparent',
4816
+ transition: theme.transitions.create(['background-color', 'color']),
4817
+ [`&.${listItemButtonClasses.selected}`]: {
4818
+ backgroundColor: semanticColors.surfaces.activeHighlight,
4819
+ color: semanticColors.typography.body,
4820
+ '&:hover': {
4821
+ backgroundColor: semanticColors.surfaces.activeHighlight,
4822
+ },
4861
4823
  },
4862
- [`& .${listItemIconClasses.root}`]: {
4863
- color: semanticColors.icons.disabled,
4824
+ [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
4825
+ '&:hover': {
4826
+ backgroundColor: semanticColors.surfaces.listHover,
4827
+ color: semanticColors.typography.body,
4828
+ },
4864
4829
  },
4865
- [`& .${listItemTextClasses.primary}`]: {
4866
- color: semanticColors.buttons.tertiary.disabled,
4830
+ [`&.${listItemButtonClasses.focusVisible}`]: {
4831
+ outline: `2px solid ${semanticColors.border.focus}`,
4832
+ outlineOffset: -2,
4867
4833
  },
4868
- [`& .${listItemTextClasses.secondary}`]: {
4834
+ [`&.${listItemButtonClasses.disabled}`]: {
4869
4835
  color: semanticColors.typography.button.disabled,
4836
+ opacity: 1,
4870
4837
  },
4871
- },
4872
- // Focus state
4873
- [`&.${listItemButtonClasses.focusVisible}`]: {
4874
- outline: `2px solid ${semanticColors.buttons.primary.default}`,
4875
- outlineOffset: 2,
4876
- border: `2px solid ${semanticColors.buttons.primary.default}`,
4838
+ };
4839
+ }
4840
+ function cardVariantStyles(theme) {
4841
+ return {
4842
+ display: 'flex',
4843
+ alignItems: 'center',
4844
+ gap: spacing.spacing_2,
4845
+ borderRadius: borderRadius.m,
4846
+ paddingTop: spacing.spacing_1,
4847
+ paddingBottom: spacing.spacing_1,
4848
+ paddingLeft: spacing.spacing_3_4,
4849
+ paddingRight: spacing.spacing_3_4,
4850
+ border: `1px solid ${semanticColors.border.primary}`,
4877
4851
  backgroundColor: theme.palette.common.white,
4878
- [`& .${listItemIconClasses.root}`]: {
4879
- color: semanticColors.icons.default,
4880
- },
4881
- [`& .${listItemTextClasses.primary}`]: {
4882
- color: colors.grey[800],
4883
- },
4884
- [`& .${listItemTextClasses.secondary}`]: {
4885
- color: semanticColors.typography.bodySecondary,
4852
+ transition: theme.transitions.create(['border', 'background-color']),
4853
+ // Active (selected) state
4854
+ [`&.${listItemButtonClasses.selected}`]: {
4855
+ border: `2px solid ${semanticColors.buttons.primary.default}`,
4856
+ backgroundColor: theme.palette.common.white,
4857
+ '&:hover': {
4858
+ backgroundColor: theme.palette.common.white,
4859
+ },
4860
+ // Icon color in selected state
4861
+ [`& .${listItemIconClasses.root}`]: {
4862
+ color: semanticColors.icons.default,
4863
+ },
4864
+ // Text colors in selected state
4865
+ [`& .${listItemTextClasses.primary}`]: {
4866
+ color: colors.grey[800],
4867
+ },
4868
+ [`& .${listItemTextClasses.secondary}`]: {
4869
+ color: semanticColors.typography.bodySecondary,
4870
+ },
4886
4871
  },
4887
- },
4888
- // Disabled state
4889
- [`&.${listItemButtonClasses.disabled}`]: {
4890
- backgroundColor: colors.grey[50],
4891
- opacity: 1, // Override MUI default opacity
4892
- [`& .${listItemIconClasses.root}`]: {
4893
- color: semanticColors.icons.disabled,
4872
+ // Deselected (default) state
4873
+ [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
4874
+ '&:hover': {
4875
+ backgroundColor: colors.grey[50],
4876
+ },
4877
+ [`& .${listItemIconClasses.root}`]: {
4878
+ color: semanticColors.icons.disabled,
4879
+ },
4880
+ [`& .${listItemTextClasses.primary}`]: {
4881
+ color: semanticColors.buttons.tertiary.disabled,
4882
+ },
4883
+ [`& .${listItemTextClasses.secondary}`]: {
4884
+ color: semanticColors.typography.button.disabled,
4885
+ },
4894
4886
  },
4895
- [`& .${listItemTextClasses.primary}`]: {
4896
- color: colors.grey[300],
4887
+ // Focus state
4888
+ [`&.${listItemButtonClasses.focusVisible}`]: {
4889
+ outline: `2px solid ${semanticColors.buttons.primary.default}`,
4890
+ outlineOffset: 2,
4891
+ border: `2px solid ${semanticColors.buttons.primary.default}`,
4892
+ backgroundColor: theme.palette.common.white,
4893
+ [`& .${listItemIconClasses.root}`]: {
4894
+ color: semanticColors.icons.default,
4895
+ },
4896
+ [`& .${listItemTextClasses.primary}`]: {
4897
+ color: colors.grey[800],
4898
+ },
4899
+ [`& .${listItemTextClasses.secondary}`]: {
4900
+ color: semanticColors.typography.bodySecondary,
4901
+ },
4897
4902
  },
4898
- [`& .${listItemTextClasses.secondary}`]: {
4899
- color: colors.grey[300],
4903
+ // Disabled state
4904
+ [`&.${listItemButtonClasses.disabled}`]: {
4905
+ backgroundColor: colors.grey[50],
4906
+ opacity: 1, // Override MUI default opacity
4907
+ [`& .${listItemIconClasses.root}`]: {
4908
+ color: semanticColors.icons.disabled,
4909
+ },
4910
+ [`& .${listItemTextClasses.primary}`]: {
4911
+ color: colors.grey[300],
4912
+ },
4913
+ [`& .${listItemTextClasses.secondary}`]: {
4914
+ color: colors.grey[300],
4915
+ },
4900
4916
  },
4901
- },
4902
- }));
4917
+ };
4918
+ }
4903
4919
  /**
4904
4920
  * NeoListItemButton - Selectable list item with icon and text
4905
4921
  *
@@ -4943,8 +4959,8 @@ const StyledListItemButton = styled(ListItemButton)(({ theme }) => ({
4943
4959
  * - colors.grey[300] (#d1d5db) - Disabled text
4944
4960
  * - colors.grey[50] (#f9fafb) - Disabled background
4945
4961
  */
4946
- const NeoListItemButton = ({ children, selected = false, disabled = false, ...props }) => {
4947
- return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, ...props, children: children }));
4962
+ const NeoListItemButton = ({ children, selected = false, disabled = false, variant = 'card', ...props }) => {
4963
+ return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, listVariant: variant, ...props, children: children }));
4948
4964
  };
4949
4965
  NeoListItemButton.displayName = 'NeoListItemButton';
4950
4966
 
@@ -5181,9 +5197,9 @@ NeoModalFooter.displayName = 'NeoModalFooter';
5181
5197
  const NavigationAvatarContainer = styled('div')({
5182
5198
  display: 'flex',
5183
5199
  boxSizing: 'border-box',
5184
- width: spacing.spacing_5_1_2,
5185
- height: spacing.spacing_5_1_2,
5186
- padding: spacing.spacing_3_4,
5200
+ width: spacing.spacing_5,
5201
+ height: spacing.spacing_5,
5202
+ padding: spacing.spacing_1_2,
5187
5203
  justifyContent: 'center',
5188
5204
  alignItems: 'center',
5189
5205
  borderRadius: '50%',
@@ -5196,8 +5212,8 @@ const NavigationAvatarContainer = styled('div')({
5196
5212
  /**
5197
5213
  * NeoNavigationAvatar - Compact avatar for navigation contexts
5198
5214
  *
5199
- * Wraps NeoGeneralAvatar (size="small") in a 44px container with 6px padding,
5200
- * providing a larger interactive area for navigation UI.
5215
+ * Wraps NeoGeneralAvatar (size="small") in a 40px container,
5216
+ * providing an interactive area for navigation UI.
5201
5217
  *
5202
5218
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11325-102
5203
5219
  */
@@ -5229,15 +5245,14 @@ const StyledRoot = styled(ButtonBase, {
5229
5245
  '&:hover .neo-nav-label': {
5230
5246
  color: semanticColors.buttons.primary.hover,
5231
5247
  },
5248
+ [`& .${chipClasses.root}`]: {
5249
+ flexShrink: 0,
5250
+ },
5232
5251
  '&:focus-visible': {
5233
- ...focusRingStyles,
5252
+ outline: 'none',
5234
5253
  },
5235
5254
  '&:focus-visible .neo-nav-icon-padding': {
5236
- backgroundColor: semanticColors.buttons.secondary.hoverBackground,
5237
- borderColor: colors.digitalBlue[100],
5238
- },
5239
- '&:focus-visible .neo-nav-label': {
5240
- color: semanticColors.buttons.primary.hover,
5255
+ ...focusRingStyles,
5241
5256
  },
5242
5257
  ...(selected && {
5243
5258
  '& .neo-nav-icon-padding': {
@@ -5253,12 +5268,6 @@ const StyledRoot = styled(ButtonBase, {
5253
5268
  '&:hover .neo-nav-label': {
5254
5269
  color: semanticColors.buttons.primary.pressed,
5255
5270
  },
5256
- '&:focus-visible .neo-nav-icon-padding': {
5257
- backgroundColor: colors.digitalBlue[100],
5258
- },
5259
- '&:focus-visible .neo-nav-label': {
5260
- color: semanticColors.buttons.primary.pressed,
5261
- },
5262
5271
  }),
5263
5272
  }));
5264
5273
  const IconPadding = styled('span')({
@@ -5279,56 +5288,331 @@ const Label$2 = styled('span')(({ theme }) => ({
5279
5288
  width: '100%',
5280
5289
  transition: 'color 150ms',
5281
5290
  }));
5282
- const TagPill = styled('span')(({ theme }) => ({
5283
- display: 'inline-flex',
5284
- alignItems: 'center',
5285
- justifyContent: 'center',
5286
- height: 18,
5287
- paddingLeft: spacing.spacing_3_4, // 6px
5288
- paddingRight: spacing.spacing_3_4, // 6px
5289
- borderRadius: borderRadius.full,
5290
- backgroundColor: colors.digitalBlue[300], // #8D99FF
5291
- color: semanticColors.typography.tooltip, // white
5292
- fontFamily: typography.fontFamily.body,
5293
- fontWeight: typography.fontWeight.medium,
5294
- fontSize: theme.typography.pxToRem(typography.fontSize.xs), // 12px
5295
- lineHeight: 1,
5296
- }));
5297
5291
  /**
5298
5292
  * NeoNavigationItem - Vertical navigation item with icon, label, and optional tag
5299
5293
  *
5300
5294
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=8455-6120
5301
5295
  */
5302
- function NeoNavigationItem({ icon, label, selected = false, tag, children, ...props }) {
5303
- return (jsxs(StyledRoot, { selected: selected, disableRipple: true, ...props, children: [jsx(IconPadding, { className: "neo-nav-icon-padding", children: icon }), label && jsx(Label$2, { className: "neo-nav-label", children: label }), tag && jsx(TagPill, { children: tag }), children] }));
5296
+ function NeoNavigationItem({ icon, label, selected = false, tag, slotProps, children, ...props }) {
5297
+ return (jsxs(StyledRoot, { selected: selected, disableRipple: true, ...props, children: [jsx(IconPadding, { className: "neo-nav-icon-padding", children: icon }), label && jsx(Label$2, { className: "neo-nav-label", children: label }), tag && (jsx(NeoTag, { size: "medium", variant: "filled", intent: "beta", label: tag, ...slotProps?.badge })), children] }));
5304
5298
  }
5305
5299
  NeoNavigationItem.displayName = 'NeoNavigationItem';
5306
5300
 
5307
- /**
5308
- * Sticky header wrapper - sticks to top when scrolling
5309
- */
5310
- const StickyHeader = styled(Box)(({ theme }) => ({
5311
- position: 'sticky',
5312
- top: 0,
5313
- zIndex: theme.zIndex.appBar,
5314
- backgroundColor: semanticColors.surfaces.white,
5315
- flexShrink: 0,
5301
+ const StyledActionsCell = styled(GridActionsCell)({
5302
+ gap: spacing.spacing_1,
5303
+ paddingLeft: spacing.spacing_1_1_2,
5304
+ paddingRight: spacing.spacing_1_1_2,
5305
+ });
5306
+ function NeoActionsCell(props) {
5307
+ return jsx(StyledActionsCell, { ...props });
5308
+ }
5309
+
5310
+ const StyledCell$1 = styled('div', {
5311
+ shouldForwardProp: prop => prop !== 'disabled',
5312
+ })(({ disabled }) => ({
5313
+ display: 'flex',
5314
+ alignItems: 'center',
5315
+ gap: spacing.spacing_1, // 8px between avatar and label
5316
+ width: '100%',
5317
+ height: '100%',
5318
+ paddingLeft: spacing.spacing_1_1_2, // 12px — input-horizontal
5319
+ paddingRight: spacing.spacing_1_1_2,
5320
+ paddingTop: spacing.spacing_1_2, // 4px — input-vertical
5321
+ paddingBottom: spacing.spacing_1_2,
5322
+ backgroundColor: disabled
5323
+ ? semanticColors.surfaces.dataGrid.disabled
5324
+ : semanticColors.surfaces.dataGrid.default,
5325
+ boxSizing: 'border-box',
5316
5326
  }));
5317
- /**
5318
- * Page title typography
5319
- */
5320
- const PageTitle = styled(Typography)(() => ({
5321
- fontSize: typography.fontSize.h3,
5322
- fontWeight: typography.fontWeight.medium,
5323
- lineHeight: 1.4,
5324
- color: colors.grey['900'], // #111827 - matches Figma typography/page-header
5327
+ const LabelText = styled('span', {
5328
+ shouldForwardProp: prop => prop !== 'disabled',
5329
+ })(({ disabled }) => ({
5330
+ overflow: 'hidden',
5331
+ textOverflow: 'ellipsis',
5332
+ whiteSpace: 'nowrap',
5333
+ fontFamily: typography.fontFamily.body,
5334
+ fontSize: typography.fontSize.xs,
5335
+ fontWeight: typography.fontWeight.regular,
5336
+ lineHeight: 1.5,
5337
+ color: disabled ? semanticColors.typography.bodySecondary : semanticColors.typography.body,
5325
5338
  }));
5326
5339
  /**
5327
- * Subtitle typography
5340
+ * NeoAvatarCell — DataGrid cell displaying a user avatar with optional label.
5341
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=13425-1725
5328
5342
  */
5329
- const Subtitle = styled(Typography)(() => ({
5330
- fontSize: typography.fontSize.sm,
5331
- color: semanticColors.typography.bodySecondary,
5343
+ const NeoAvatarCell = ({ name, src, colorIndex = 0, label, disabled = false, empty = false, }) => {
5344
+ if (empty) {
5345
+ return jsx(StyledCell$1, { disabled: disabled });
5346
+ }
5347
+ return (jsxs(StyledCell$1, { disabled: disabled, children: [jsx(NeoGeneralAvatar, { size: "small", src: src, alt: name, colorIndex: colorIndex, children: !src && name ? name.charAt(0).toUpperCase() : undefined }), label && jsx(LabelText, { disabled: disabled, children: label })] }));
5348
+ };
5349
+ NeoAvatarCell.displayName = 'NeoAvatarCell';
5350
+
5351
+ const CellRoot = styled('div', {
5352
+ shouldForwardProp: prop => prop !== 'disabled',
5353
+ })(({ disabled }) => ({
5354
+ display: 'flex',
5355
+ alignItems: 'center',
5356
+ justifyContent: 'center',
5357
+ width: '100%',
5358
+ height: '100%',
5359
+ color: disabled ? semanticColors.icons.disabled : semanticColors.icons.default,
5360
+ }));
5361
+ /**
5362
+ * NeoIconCell — Icon cell for DataGrid. Renders an icon centered in the cell.
5363
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-9345
5364
+ */
5365
+ const NeoIconCell = ({ icon, ariaLabel, disabled = false }) => {
5366
+ if (!icon)
5367
+ return null;
5368
+ return (jsx(CellRoot, { disabled: disabled, "aria-label": ariaLabel, children: jsx(NeoIconWrapper, { size: 16, children: icon }) }));
5369
+ };
5370
+ NeoIconCell.displayName = 'NeoIconCell';
5371
+
5372
+ const CellWrapper = styled('div', {
5373
+ shouldForwardProp: prop => prop !== 'disabled',
5374
+ })(({ disabled }) => ({
5375
+ display: 'flex',
5376
+ alignItems: 'center',
5377
+ justifyContent: 'flex-start',
5378
+ width: '100%',
5379
+ height: '100%',
5380
+ paddingLeft: spacing.spacing_1,
5381
+ paddingRight: spacing.spacing_1,
5382
+ backgroundColor: disabled
5383
+ ? semanticColors.surfaces.dataGrid.disabled
5384
+ : semanticColors.surfaces.dataGrid.default,
5385
+ '& img': {
5386
+ display: 'block',
5387
+ maxHeight: 32,
5388
+ width: 'auto',
5389
+ maxWidth: '100%',
5390
+ objectFit: 'contain',
5391
+ opacity: disabled ? 0.4 : 1,
5392
+ },
5393
+ }));
5394
+ /**
5395
+ * NeoLogoCell — DataGrid cell displaying a raster or SVG logo image.
5396
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13278-9558
5397
+ *
5398
+ * Kept separate from NeoIconCell to match Neo's Icon/Logo component split:
5399
+ * - NeoIconCell: MUI SvgIcon components
5400
+ * - NeoLogoCell: raster or SVG image URLs (img tag)
5401
+ */
5402
+ const NeoLogoCell = ({ src, alt = '', disabled = false }) => {
5403
+ if (!src) {
5404
+ return jsx(CellWrapper, { disabled: disabled });
5405
+ }
5406
+ return (jsx(CellWrapper, { disabled: disabled, children: jsx(NeoIconWrapper, { size: 32, children: jsx("img", { src: src, alt: alt }) }) }));
5407
+ };
5408
+ NeoLogoCell.displayName = 'NeoLogoCell';
5409
+
5410
+ const StyledLinearProgress = styled(LinearProgress, {
5411
+ shouldForwardProp: prop => prop !== 'labelPosition',
5412
+ })(() => ({
5413
+ height: 8,
5414
+ borderRadius: borderRadius.xS,
5415
+ backgroundColor: colors.grey[200],
5416
+ [`& .${linearProgressClasses.bar}`]: {
5417
+ borderRadius: borderRadius.xS,
5418
+ backgroundColor: colors.digitalBlue[500],
5419
+ },
5420
+ [`&.${linearProgressClasses.colorPrimary}`]: {
5421
+ backgroundColor: colors.grey[200],
5422
+ [`& .${linearProgressClasses.bar}`]: {
5423
+ backgroundColor: colors.digitalBlue[500],
5424
+ },
5425
+ },
5426
+ // Cancelled variant uses warning color
5427
+ '&[data-variant="cancelled"]': {
5428
+ [`& .${linearProgressClasses.bar}`]: {
5429
+ backgroundColor: semanticColors.status.warning.default,
5430
+ },
5431
+ },
5432
+ }));
5433
+ const ProgressWrapper = styled('div')(({ labelPosition }) => ({
5434
+ display: 'flex',
5435
+ width: '100%',
5436
+ ...(labelPosition === 'right' && {
5437
+ flexDirection: 'row',
5438
+ alignItems: 'center',
5439
+ gap: spacing.spacing_3,
5440
+ }),
5441
+ ...(labelPosition === 'top' && {
5442
+ flexDirection: 'column-reverse',
5443
+ alignItems: 'flex-end',
5444
+ gap: spacing.spacing_2,
5445
+ }),
5446
+ ...(labelPosition === 'bottom' && {
5447
+ flexDirection: 'column',
5448
+ alignItems: 'flex-end',
5449
+ gap: spacing.spacing_2,
5450
+ }),
5451
+ ...(labelPosition === 'none' && {
5452
+ flexDirection: 'row',
5453
+ }),
5454
+ }));
5455
+ const ProgressLabel = styled(Typography)(({ theme }) => ({
5456
+ fontSize: theme.typography.pxToRem(typography.fontSize.sm),
5457
+ fontWeight: typography.fontWeight.medium,
5458
+ color: colors.grey[800],
5459
+ lineHeight: 1.4,
5460
+ whiteSpace: 'nowrap',
5461
+ flexShrink: 0,
5462
+ }));
5463
+ const ProgressBarContainer = styled('div')(({ labelPosition }) => ({
5464
+ flexGrow: labelPosition === 'right' ? 1 : 0,
5465
+ width: labelPosition === 'right' ? 'auto' : '100%',
5466
+ }));
5467
+ /**
5468
+ * NeoProgressbar - Linear progress indicator based on MUI LinearProgress
5469
+ *
5470
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4120-36679
5471
+ *
5472
+ * Figma Props Mapping:
5473
+ * - progress (0%-100% | Cancelled) → value (0-100) + variant (default|cancelled)
5474
+ * - label (False|Right|Top|Bottom) → labelPosition (none|right|top|bottom)
5475
+ *
5476
+ * Design Decisions (from Issue #75):
5477
+ * - MUI Base Component: LinearProgress (provides accessibility, animations, progress tracking)
5478
+ * - Label Positioning: Single labelPosition prop with values 'none', 'right', 'top', 'bottom'
5479
+ * - Cancelled State: Separate variant prop (variant='cancelled') alongside value prop
5480
+ */
5481
+ const NeoProgressbar = ({ value = 0, labelPosition = 'none', variant = 'default', labelText, ...props }) => {
5482
+ const showLabel = labelPosition !== 'none';
5483
+ const displayLabel = labelText || (variant === 'cancelled' ? 'Canceled' : `${Math.round(value)}%`);
5484
+ return (jsxs(ProgressWrapper, { labelPosition: labelPosition, children: [jsx(ProgressBarContainer, { labelPosition: labelPosition, children: jsx(StyledLinearProgress, { variant: "determinate", value: variant === 'cancelled' ? 100 : value, "data-variant": variant, labelPosition: labelPosition, ...props }) }), showLabel && jsx(ProgressLabel, { children: displayLabel })] }));
5485
+ };
5486
+ NeoProgressbar.displayName = 'NeoProgressbar';
5487
+
5488
+ const StyledCell = styled('div', {
5489
+ shouldForwardProp: prop => prop !== 'disabled',
5490
+ })(({ disabled }) => ({
5491
+ display: 'flex',
5492
+ alignItems: 'center',
5493
+ width: '100%',
5494
+ height: '100%',
5495
+ paddingLeft: spacing.spacing_1_1_2, // 12px input-horizontal
5496
+ paddingRight: spacing.spacing_1_1_2,
5497
+ backgroundColor: disabled
5498
+ ? semanticColors.surfaces.dataGrid.disabled
5499
+ : semanticColors.surfaces.dataGrid.default,
5500
+ boxSizing: 'border-box',
5501
+ }));
5502
+ /**
5503
+ * NeoProgressCell — DataGrid cell displaying a linear progress indicator.
5504
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13425-5378
5505
+ */
5506
+ const NeoProgressCell = ({ value = 0, disabled = false, empty = false, }) => {
5507
+ const clampedValue = Math.min(100, Math.max(0, value));
5508
+ return (jsx(StyledCell, { disabled: disabled, children: !empty && jsx(NeoProgressbar, { value: clampedValue, labelPosition: "none" }) }));
5509
+ };
5510
+ NeoProgressCell.displayName = 'NeoProgressCell';
5511
+
5512
+ const variantColors = (variant) => ({
5513
+ bg: semanticColors.status[variant].light,
5514
+ fg: semanticColors.status[variant].dark,
5515
+ border: semanticColors.status[variant].transparent,
5516
+ });
5517
+ const StyledChip = styled('div', {
5518
+ shouldForwardProp: prop => prop !== 'disabled' && prop !== 'variant',
5519
+ })(({ disabled, variant }) => {
5520
+ const colors = variantColors(variant);
5521
+ return {
5522
+ display: 'inline-flex',
5523
+ alignItems: 'center',
5524
+ gap: spacing.spacing_3_4,
5525
+ paddingTop: spacing.spacing_1_2,
5526
+ paddingBottom: spacing.spacing_1_2,
5527
+ paddingLeft: spacing.spacing_1_1_2,
5528
+ paddingRight: spacing.spacing_1_1_2,
5529
+ borderRadius: borderRadius.full,
5530
+ border: `1px solid ${disabled ? semanticColors.border.secondary : colors.border}`,
5531
+ backgroundColor: disabled ? semanticColors.surfaces.dataGrid.disabled : colors.bg,
5532
+ color: disabled ? semanticColors.icons.disabled : colors.fg,
5533
+ fontFamily: typography.fontFamily.body,
5534
+ fontSize: typography.fontSize.xs,
5535
+ fontWeight: typography.fontWeight.medium,
5536
+ lineHeight: 1,
5537
+ whiteSpace: 'nowrap',
5538
+ overflow: 'hidden',
5539
+ maxWidth: '100%',
5540
+ '& svg': {
5541
+ flexShrink: 0,
5542
+ width: '1em',
5543
+ height: '1em',
5544
+ fontSize: typography.fontSize.xs,
5545
+ },
5546
+ };
5547
+ });
5548
+ const TooltipErrorPre = styled('pre')({
5549
+ margin: 0,
5550
+ padding: 0,
5551
+ fontFamily: typography.fontFamily.code,
5552
+ fontSize: typography.fontSize.sm,
5553
+ fontWeight: typography.fontWeight.regular,
5554
+ lineHeight: 1.5,
5555
+ color: semanticColors.typography.tooltip,
5556
+ whiteSpace: 'pre-wrap',
5557
+ wordBreak: 'break-all',
5558
+ maxHeight: 200,
5559
+ overflowY: 'auto',
5560
+ });
5561
+ const StyledTooltip$1 = styled(Tooltip)({
5562
+ [`& .${tooltipClasses.tooltip}`]: {
5563
+ backgroundColor: semanticColors.surfaces.tooltip,
5564
+ maxWidth: 400,
5565
+ padding: `${spacing.spacing_1}px ${spacing.spacing_1_1_2}px`,
5566
+ },
5567
+ [`& .${tooltipClasses.arrow}`]: {
5568
+ color: semanticColors.surfaces.tooltip,
5569
+ },
5570
+ });
5571
+ /**
5572
+ * NeoStatusCell — DataGrid cell displaying an icon + label chip with optional error tooltip.
5573
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-8705
5574
+ */
5575
+ const NeoStatusCell = ({ icon, label, details, disabled = false, variant = 'success', empty = false, }) => {
5576
+ if (empty) {
5577
+ return (jsx(Box, { component: "span", sx: {
5578
+ color: semanticColors.typography.body,
5579
+ fontSize: typography.fontSize.sm,
5580
+ lineHeight: 1,
5581
+ }, children: '—' }));
5582
+ }
5583
+ const chip = (jsxs(StyledChip, { disabled: disabled, variant: variant, children: [icon, label] }));
5584
+ if (details) {
5585
+ return (jsx(StyledTooltip$1, { title: jsx(TooltipErrorPre, { children: details }), arrow: true, placement: "bottom-start", children: jsx(Box, { component: "span", sx: { display: 'inline-flex' }, children: chip }) }));
5586
+ }
5587
+ return chip;
5588
+ };
5589
+ NeoStatusCell.displayName = 'NeoStatusCell';
5590
+
5591
+ /**
5592
+ * Sticky header wrapper - sticks to top when scrolling
5593
+ */
5594
+ const StickyHeader = styled(Box)(({ theme }) => ({
5595
+ position: 'sticky',
5596
+ top: 0,
5597
+ zIndex: theme.zIndex.appBar,
5598
+ backgroundColor: semanticColors.surfaces.white,
5599
+ flexShrink: 0,
5600
+ }));
5601
+ /**
5602
+ * Page title typography
5603
+ */
5604
+ const PageTitle = styled(Typography)(() => ({
5605
+ fontSize: typography.fontSize.h3,
5606
+ fontWeight: typography.fontWeight.medium,
5607
+ lineHeight: 1.4,
5608
+ color: colors.grey['900'], // #111827 - matches Figma typography/page-header
5609
+ }));
5610
+ /**
5611
+ * Subtitle typography
5612
+ */
5613
+ const Subtitle = styled(Typography)(() => ({
5614
+ fontSize: typography.fontSize.sm,
5615
+ color: semanticColors.typography.bodySecondary,
5332
5616
  }));
5333
5617
  /**
5334
5618
  * NeoPageContent - Page content surface from the Moderne Design System
@@ -5385,7 +5669,12 @@ const Subtitle = styled(Typography)(() => ({
5385
5669
  * </NeoPageContent>
5386
5670
  * ```
5387
5671
  */
5388
- function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = false, contentMaxWidth = false, centerContent = true, disableGutters = false, isLoading = false, showBackToTop = true, children, sx, ...boxProps }) {
5672
+ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = false, contentMaxWidth: contentMaxWidthProp = false, centerContent = true, disableGutters: disableGuttersProp = false, isLoading = false, showBackToTop = true, layout = 'default', children, sx, ...boxProps }) {
5673
+ // fullBleed forces no max-width, no gutters, and zero bottom padding
5674
+ // so children can fill the viewport edge-to-edge.
5675
+ const isFullBleed = layout === 'fullBleed';
5676
+ const contentMaxWidth = isFullBleed ? false : contentMaxWidthProp;
5677
+ const disableGutters = isFullBleed || disableGuttersProp;
5389
5678
  const [showBackToTopButton, setShowBackToTopButton] = useState(false);
5390
5679
  const headerRef = useRef(null);
5391
5680
  const containerRef = useRef(null);
@@ -5437,7 +5726,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
5437
5726
  flexDirection: 'column',
5438
5727
  px: disableGutters ? 0 : `${spacing.spacing_2_1_2}px`,
5439
5728
  pt: sticky ? 0 : `${spacing.spacing_2}px`,
5440
- pb: `${spacing.spacing_2_1_2}px`,
5729
+ pb: isFullBleed ? 0 : `${spacing.spacing_2_1_2}px`,
5441
5730
  height: '100%',
5442
5731
  overflow: 'auto',
5443
5732
  }, children: [sticky ? (jsx(StickyHeader, { ref: headerRef, sx: {
@@ -5525,84 +5814,6 @@ function NeoPaginatedGrid({ slots, pageSizeOptions, slotProps: userSlotProps, ..
5525
5814
  }
5526
5815
  NeoPaginatedGrid.displayName = 'NeoPaginatedGrid';
5527
5816
 
5528
- const StyledLinearProgress = styled(LinearProgress, {
5529
- shouldForwardProp: prop => prop !== 'labelPosition',
5530
- })(() => ({
5531
- height: 8,
5532
- borderRadius: borderRadius.xS,
5533
- backgroundColor: colors.grey[200],
5534
- [`& .${linearProgressClasses.bar}`]: {
5535
- borderRadius: borderRadius.xS,
5536
- backgroundColor: colors.digitalBlue[500],
5537
- },
5538
- [`&.${linearProgressClasses.colorPrimary}`]: {
5539
- backgroundColor: colors.grey[200],
5540
- [`& .${linearProgressClasses.bar}`]: {
5541
- backgroundColor: colors.digitalBlue[500],
5542
- },
5543
- },
5544
- // Cancelled variant uses warning color
5545
- '&[data-variant="cancelled"]': {
5546
- [`& .${linearProgressClasses.bar}`]: {
5547
- backgroundColor: semanticColors.status.warning.default,
5548
- },
5549
- },
5550
- }));
5551
- const ProgressWrapper = styled('div')(({ labelPosition }) => ({
5552
- display: 'flex',
5553
- width: '100%',
5554
- ...(labelPosition === 'right' && {
5555
- flexDirection: 'row',
5556
- alignItems: 'center',
5557
- gap: spacing.spacing_3,
5558
- }),
5559
- ...(labelPosition === 'top' && {
5560
- flexDirection: 'column-reverse',
5561
- alignItems: 'flex-end',
5562
- gap: spacing.spacing_2,
5563
- }),
5564
- ...(labelPosition === 'bottom' && {
5565
- flexDirection: 'column',
5566
- alignItems: 'flex-end',
5567
- gap: spacing.spacing_2,
5568
- }),
5569
- ...(labelPosition === 'none' && {
5570
- flexDirection: 'row',
5571
- }),
5572
- }));
5573
- const ProgressLabel = styled(Typography)(({ theme }) => ({
5574
- fontSize: theme.typography.pxToRem(typography.fontSize.sm),
5575
- fontWeight: typography.fontWeight.medium,
5576
- color: colors.grey[800],
5577
- lineHeight: 1.4,
5578
- whiteSpace: 'nowrap',
5579
- flexShrink: 0,
5580
- }));
5581
- const ProgressBarContainer = styled('div')(({ labelPosition }) => ({
5582
- flexGrow: labelPosition === 'right' ? 1 : 0,
5583
- width: labelPosition === 'right' ? 'auto' : '100%',
5584
- }));
5585
- /**
5586
- * NeoProgressbar - Linear progress indicator based on MUI LinearProgress
5587
- *
5588
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4120-36679
5589
- *
5590
- * Figma Props Mapping:
5591
- * - progress (0%-100% | Cancelled) → value (0-100) + variant (default|cancelled)
5592
- * - label (False|Right|Top|Bottom) → labelPosition (none|right|top|bottom)
5593
- *
5594
- * Design Decisions (from Issue #75):
5595
- * - MUI Base Component: LinearProgress (provides accessibility, animations, progress tracking)
5596
- * - Label Positioning: Single labelPosition prop with values 'none', 'right', 'top', 'bottom'
5597
- * - Cancelled State: Separate variant prop (variant='cancelled') alongside value prop
5598
- */
5599
- const NeoProgressbar = ({ value = 0, labelPosition = 'none', variant = 'default', labelText, ...props }) => {
5600
- const showLabel = labelPosition !== 'none';
5601
- const displayLabel = labelText || (variant === 'cancelled' ? 'Canceled' : `${Math.round(value)}%`);
5602
- return (jsxs(ProgressWrapper, { labelPosition: labelPosition, children: [jsx(ProgressBarContainer, { labelPosition: labelPosition, children: jsx(StyledLinearProgress, { variant: "determinate", value: variant === 'cancelled' ? 100 : value, "data-variant": variant, labelPosition: labelPosition, ...props }) }), showLabel && jsx(ProgressLabel, { children: displayLabel })] }));
5603
- };
5604
- NeoProgressbar.displayName = 'NeoProgressbar';
5605
-
5606
5817
  const StyledTextField = styled(TextField)(({ theme }) => ({
5607
5818
  [`& .${inputBaseClasses.root}`]: {
5608
5819
  height: spacing.spacing_5,
@@ -5845,6 +6056,13 @@ const NeoRadio = ({ size = 'medium', label, helperText, disabled, ...props }) =>
5845
6056
  };
5846
6057
  NeoRadio.displayName = 'NeoRadio';
5847
6058
 
6059
+ /**
6060
+ * NeoRadioButtonWithText
6061
+ *
6062
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-7682
6063
+ */
6064
+ const NeoRadioButtonWithText = styled('div')({});
6065
+
5848
6066
  const StyledSearchChip = styled(InputBase)(({ theme }) => ({
5849
6067
  borderRadius: borderRadius.full,
5850
6068
  border: `1px solid ${semanticColors.buttons.secondary.defaultBorder}`,
@@ -5910,6 +6128,38 @@ const NeoSearchChip = ({ onClear, value, ...props }) => {
5910
6128
  };
5911
6129
  NeoSearchChip.displayName = 'NeoSearchChip';
5912
6130
 
6131
+ /**
6132
+ * NeoSelectField — composite of NeoInputField's form chrome (label,
6133
+ * helper text, error state) wrapped around NeoSelect. Mirrors the
6134
+ * MUI `<TextField select>` ergonomics with Neo design tokens, so
6135
+ * consumers don't have to compose the two manually.
6136
+ *
6137
+ * @example
6138
+ * <NeoSelectField
6139
+ * label="Response format"
6140
+ * value={format}
6141
+ * onChange={e => setFormat(e.target.value)}
6142
+ * options={[
6143
+ * { value: 'json', label: 'JSON' },
6144
+ * { value: 'plain', label: 'Plain text' },
6145
+ * ]}
6146
+ * />
6147
+ */
6148
+ const NeoSelectField = ({ size = 'medium', destructive = false, label, required = false, infoIcon, helperText, errorMessage, options, children, disabled, id, ...selectProps }) => {
6149
+ const inputId = id || `neo-select-${Math.random().toString(36).substring(7)}`;
6150
+ const helperTextId = helperText || errorMessage ? `${inputId}-helper-text` : undefined;
6151
+ return (jsxs(StyledFormControl, { size: size, error: destructive, disabled: disabled, children: [label && (jsxs(StyledInputLabel, { htmlFor: inputId, size: size, infoIcon: !!infoIcon, disabled: disabled, error: destructive, shrink: true, children: [label, required && jsx("span", { "aria-hidden": "true", children: "*" }), infoIcon && jsx(InfoIconWrapper, { children: infoIcon })] })), jsx(NeoSelect, { id: inputId, disabled: disabled, error: destructive, "aria-describedby": helperTextId, ...selectProps, children: children ??
6152
+ options?.map(opt => (jsx(NeoMenuItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, String(opt.value)))) }), (helperText || errorMessage) && (jsx(StyledFormHelperText, { id: helperTextId, error: destructive, disabled: disabled, sx: { marginTop: `${spacing.spacing_3_4}px` }, children: destructive ? errorMessage : helperText }))] }));
6153
+ };
6154
+ NeoSelectField.displayName = 'NeoSelectField';
6155
+
6156
+ /**
6157
+ * NeoSideNav
6158
+ *
6159
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4065-3425
6160
+ */
6161
+ const NeoSideNav = styled('div')({});
6162
+
5913
6163
  const StyledSkeleton = styled(Skeleton, {
5914
6164
  shouldForwardProp: prop => prop !== 'colorTheme' && prop !== 'position',
5915
6165
  })(({ theme, colorTheme = 'light', position = 'start' }) => ({
@@ -5957,6 +6207,111 @@ const NeoSkeleton = ({ colorTheme = 'light', position = 'start', ...props }) =>
5957
6207
  };
5958
6208
  NeoSkeleton.displayName = 'NeoSkeleton';
5959
6209
 
6210
+ const sizePadding = {
6211
+ small: `${spacing.spacing_3_4}px ${spacing.spacing_1_1_2}px`,
6212
+ medium: `${spacing.spacing_1_1_2}px ${spacing.spacing_2}px`,
6213
+ };
6214
+ const sizeFontSize = {
6215
+ small: typography.fontSize.xs,
6216
+ medium: typography.fontSize.sm,
6217
+ };
6218
+ const StyledTable = styled(MuiTable, {
6219
+ shouldForwardProp: prop => prop !== 'tableSize',
6220
+ })(({ theme, tableSize = 'small' }) => ({
6221
+ borderCollapse: 'separate',
6222
+ borderSpacing: 0,
6223
+ [`& .${tableCellClasses.head}`]: {
6224
+ backgroundColor: colors.grey[50],
6225
+ color: semanticColors.typography.body,
6226
+ fontFamily: typography.fontFamily.body,
6227
+ fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
6228
+ fontWeight: typography.fontWeight.semiBold,
6229
+ lineHeight: 1.4,
6230
+ padding: sizePadding[tableSize],
6231
+ borderBottom: `1px solid ${semanticColors.border.secondary}`,
6232
+ },
6233
+ [`& .${tableCellClasses.body}`]: {
6234
+ color: semanticColors.typography.body,
6235
+ fontFamily: typography.fontFamily.body,
6236
+ fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
6237
+ fontWeight: typography.fontWeight.regular,
6238
+ lineHeight: 1.4,
6239
+ padding: sizePadding[tableSize],
6240
+ borderBottom: `1px solid ${semanticColors.border.secondary}`,
6241
+ },
6242
+ // Drop the trailing row's bottom border so the container border (if
6243
+ // any) is the visual edge.
6244
+ [`& tbody tr:last-of-type .${tableCellClasses.body}`]: {
6245
+ borderBottom: 'none',
6246
+ },
6247
+ }));
6248
+ const StyledContainer = styled('div', {
6249
+ shouldForwardProp: prop => prop !== 'tableVariant',
6250
+ })(({ tableVariant = 'bordered' }) => tableVariant === 'bordered'
6251
+ ? {
6252
+ border: `1px solid ${semanticColors.border.secondary}`,
6253
+ borderRadius: borderRadius.card,
6254
+ overflow: 'hidden',
6255
+ backgroundColor: semanticColors.surfaces.white,
6256
+ }
6257
+ : { backgroundColor: 'transparent' });
6258
+ /**
6259
+ * NeoTable — lightweight read-only table for static data (schema rows,
6260
+ * key/value summaries, response metadata). For interactive grids with
6261
+ * sorting / filtering / pagination, use NeoDataGrid instead.
6262
+ *
6263
+ * @example
6264
+ * <NeoTable
6265
+ * columns={[
6266
+ * { key: 'name', header: 'Property' },
6267
+ * { key: 'type', header: 'Type', align: 'center', width: '120px' },
6268
+ * { key: 'description', header: 'Description' },
6269
+ * ]}
6270
+ * rows={[
6271
+ * { name: 'id', type: 'string', description: 'Resource identifier' },
6272
+ * { name: 'count', type: 'number', description: 'Item count' },
6273
+ * ]}
6274
+ * size="small"
6275
+ * />
6276
+ */
6277
+ const NeoTable = ({ columns, rows, size = 'small', variant = 'bordered', ariaLabel, ...tableProps }) => (jsx(StyledContainer, { tableVariant: variant, children: jsx(TableContainer, { children: jsxs(StyledTable, { tableSize: size, "aria-label": ariaLabel, ...tableProps, children: [jsx(TableHead, { children: jsx(TableRow, { children: columns.map(col => (jsx(TableCell, { align: col.align ?? 'left', style: col.width ? { width: col.width } : undefined, children: col.header }, col.key))) }) }), jsx(TableBody, { children: rows.map((row, i) => (jsx(TableRow, { children: columns.map(col => (jsx(TableCell, { align: col.align ?? 'left', children: row[col.key] ?? '' }, col.key))) }, i))) })] }) }) }));
6278
+ NeoTable.displayName = 'NeoTable';
6279
+
6280
+ const StyledTabPanel = styled(Box, {
6281
+ shouldForwardProp: prop => prop !== 'tabPanelVariant',
6282
+ })(({ tabPanelVariant = 'default' }) => ({
6283
+ backgroundColor: semanticColors.surfaces.white,
6284
+ // default: 16px top padding for content-driven pages.
6285
+ // flush: zero padding so content sits directly against the tab bar's
6286
+ // bottom border (sidebars, panels, builders, canvases).
6287
+ padding: 0,
6288
+ ...(tabPanelVariant === 'flush' ? {} : { paddingTop: spacing.spacing_2 }),
6289
+ }));
6290
+ /**
6291
+ * NeoTabPanel — completes the NeoTabs + NeoTab + NeoTabPanel set.
6292
+ *
6293
+ * Lightweight ARIA-compliant tab panel that renders children when its
6294
+ * `value` matches `currentValue`. No MUI Lab / TabContext dependency.
6295
+ *
6296
+ * @example
6297
+ * const [tab, setTab] = useState('overview')
6298
+ * return (
6299
+ * <>
6300
+ * <NeoTabs value={tab} onChange={(_, v) => setTab(v)}>
6301
+ * <NeoTab value="overview" label="Overview" />
6302
+ * <NeoTab value="details" label="Details" />
6303
+ * </NeoTabs>
6304
+ * <NeoTabPanel value="overview" currentValue={tab}>...</NeoTabPanel>
6305
+ * <NeoTabPanel value="details" currentValue={tab} variant="flush">...</NeoTabPanel>
6306
+ * </>
6307
+ * )
6308
+ */
6309
+ const NeoTabPanel = ({ value, currentValue, variant = 'default', children, ...boxProps }) => {
6310
+ const selected = value === currentValue;
6311
+ return (jsx(StyledTabPanel, { role: "tabpanel", hidden: !selected, tabPanelVariant: variant, id: `tabpanel-${value}`, "aria-labelledby": `tab-${value}`, ...boxProps, children: selected ? children : null }));
6312
+ };
6313
+ NeoTabPanel.displayName = 'NeoTabPanel';
6314
+
5960
6315
  /**
5961
6316
  * NeoTabs - Tabs container component based on MUI Tabs
5962
6317
  *
@@ -6336,6 +6691,102 @@ const NeoToggle = ({ size = 'medium', label, helperText, disabled, ...props }) =
6336
6691
  };
6337
6692
  NeoToggle.displayName = 'NeoToggle';
6338
6693
 
6694
+ const sizeStyles = {
6695
+ small: {
6696
+ height: 24,
6697
+ fontSize: typography.fontSize.xs,
6698
+ },
6699
+ medium: {
6700
+ height: 32,
6701
+ fontSize: typography.fontSize.sm,
6702
+ },
6703
+ };
6704
+ const StyledToggleButton$1 = styled(MuiToggleButton, {
6705
+ shouldForwardProp: prop => prop !== 'toggleSize',
6706
+ })(({ theme, toggleSize = 'medium' }) => ({
6707
+ height: sizeStyles[toggleSize].height,
6708
+ padding: `0 ${spacing.spacing_1_1_2}px`,
6709
+ fontFamily: typography.fontFamily.body,
6710
+ fontSize: theme.typography.pxToRem(sizeStyles[toggleSize].fontSize),
6711
+ fontWeight: typography.fontWeight.regular,
6712
+ lineHeight: 1,
6713
+ color: semanticColors.typography.bodySecondary,
6714
+ backgroundColor: 'transparent',
6715
+ border: 'none',
6716
+ textTransform: 'none',
6717
+ transition: theme.transitions.create(['background-color', 'color'], {
6718
+ duration: theme.transitions.duration.short,
6719
+ }),
6720
+ '&:hover': {
6721
+ backgroundColor: colors.grey[100],
6722
+ color: semanticColors.typography.body,
6723
+ },
6724
+ '&.Mui-selected, &.Mui-selected:hover': {
6725
+ backgroundColor: colors.grey[100],
6726
+ color: semanticColors.typography.body,
6727
+ fontWeight: typography.fontWeight.semiBold,
6728
+ },
6729
+ '&.Mui-focusVisible': {
6730
+ outline: `2px solid ${semanticColors.border.focus}`,
6731
+ outlineOffset: -2,
6732
+ },
6733
+ '&.Mui-disabled': {
6734
+ color: semanticColors.typography.button.disabled,
6735
+ cursor: 'default',
6736
+ pointerEvents: 'none',
6737
+ },
6738
+ }));
6739
+ /**
6740
+ * NeoToggleButton — a single button in a segmented control. Use inside
6741
+ * NeoToggleButtonGroup; the group manages selection state and forwards
6742
+ * size to its children. Suitable for inline toolbar mode switches
6743
+ * ("Table" / "Raw"). For page-level tabs, prefer NeoButtonTab.
6744
+ */
6745
+ const NeoToggleButton = ({ children, size = 'medium', ...props }) => (jsx(StyledToggleButton$1, { toggleSize: size, ...props, children: children }));
6746
+ NeoToggleButton.displayName = 'NeoToggleButton';
6747
+
6748
+ const StyledToggleButtonGroup$1 = styled(MuiToggleButtonGroup)({
6749
+ borderRadius: borderRadius.button,
6750
+ border: `1px solid ${semanticColors.border.secondary}`,
6751
+ overflow: 'hidden',
6752
+ display: 'inline-flex',
6753
+ // Children fill the pill — first/last get the rounded corners, middles
6754
+ // are square. MUI applies positional classes via ToggleButtonGroup
6755
+ // context; we rely on borderRadius inheritance from the container.
6756
+ [`& .${toggleButtonClasses.root}`]: {
6757
+ borderRadius: 0,
6758
+ },
6759
+ });
6760
+ /**
6761
+ * NeoToggleButtonGroup — pill-shaped segmented control wrapping
6762
+ * MUI ToggleButtonGroup with Neo tokens. Use for inline toolbar mode
6763
+ * switches (e.g. "Table" / "Raw" in a panel header). For page-level
6764
+ * tab navigation, prefer NeoButtonTabGroup.
6765
+ *
6766
+ * @example
6767
+ * <NeoToggleButtonGroup value={mode} exclusive onChange={(_, v) => v && setMode(v)} size="small">
6768
+ * <NeoToggleButton value="table">Table</NeoToggleButton>
6769
+ * <NeoToggleButton value="raw">Raw</NeoToggleButton>
6770
+ * </NeoToggleButtonGroup>
6771
+ */
6772
+ const NeoToggleButtonGroup = ({ size = 'medium', children, ...props }) => {
6773
+ // Forward size to each NeoToggleButton child so consumers don't have to
6774
+ // set it on every button. MUI's group already does this via context for
6775
+ // its own size prop, but our `size` shape doesn't pass through unchanged.
6776
+ const sized = Children.map(children, child => isValidElement(child) && child.type === NeoToggleButton
6777
+ ? cloneElement(child, { size })
6778
+ : child);
6779
+ return jsx(StyledToggleButtonGroup$1, { ...props, children: sized });
6780
+ };
6781
+ NeoToggleButtonGroup.displayName = 'NeoToggleButtonGroup';
6782
+
6783
+ /**
6784
+ * NeoToggleButtonWithText
6785
+ *
6786
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-10485
6787
+ */
6788
+ const NeoToggleButtonWithText = styled('div')({});
6789
+
6339
6790
  const StyledToolbar = styled(Toolbar)(({ theme }) => ({
6340
6791
  backgroundColor: semanticColors.surfaces.white,
6341
6792
  minHeight: 'auto',
@@ -6477,6 +6928,20 @@ const NeoTooltip = ({ variant = 'light', title, description, children, arrow = f
6477
6928
  };
6478
6929
  NeoTooltip.displayName = 'NeoTooltip';
6479
6930
 
6931
+ /**
6932
+ * NeoTopNav
6933
+ *
6934
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4618-185228
6935
+ */
6936
+ const NeoTopNav = styled('div')({});
6937
+
6938
+ /**
6939
+ * NeoTourModal
6940
+ *
6941
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=12408-1800
6942
+ */
6943
+ const NeoTourModal = styled('div')({});
6944
+
6480
6945
  /**
6481
6946
  * Custom label component that reads extra slot data from the item model.
6482
6947
  * Used as `slots.label` on the TreeItem.
@@ -6681,5 +7146,5 @@ NeoTypologyControl.displayName = 'NeoTypologyControl';
6681
7146
 
6682
7147
  const version = '0.0.0-development';
6683
7148
 
6684
- export { ActivityScene, CIRCLE_RADIUS, NeoActivityHeader, NeoActivityIndicatorCell, NeoAlert, NeoBadge, NeoBanner, NeoBreadcrumbLink, NeoBreadcrumbs, NeoButton, NeoButtonTab, NeoButtonTabGroup, NeoCard, NeoCheckbox, NeoCheckboxWithText, NeoCodeSnippet, NeoDataGrid, NeoDataGridCellContent, NeoDataGridColumnsButton, NeoDataGridColumnsPanel, NeoDataGridFilterPanel, NeoDataGridFilterPanelAddIcon, NeoDataGridFilterPanelDeleteIcon, NeoDataGridFilterPanelRemoveAllIcon, NeoDataGridFiltersButton, NeoDataGridHeaderLabel, NeoSelect as NeoDataGridSelect, NeoDatePicker, NeoDivider, NeoDot, NeoDownloadToast, NeoSelect as NeoDropdown, NeoMenu as NeoDropdownMenu, NeoMenuItem as NeoDropdownMenuItem, NeoMenuItem as NeoDropdownOption, NeoFilterChip, NeoFooter, NeoGeneralAvatar, NeoIconButton, NeoIconWrapper, NeoInfiniteScrollGrid, NeoInputField, NeoListItem, NeoListItemButton, NeoLoadingSpinner, NeoMenu, NeoMenuItem, NeoModal, NeoModalContent, NeoModalFooter, NeoModalHeader, NeoMultiBadgesCell, NeoNavigationAvatar, NeoNavigationItem, NeoPageContent, NeoPaginatedGrid, NeoProgressbar, NeoQuickFilter, NeoRadio, NeoSearchChip, NeoSelect, NeoMenuItem as NeoSelectOption, NeoSkeleton, NeoStatusBadgeCell, NeoTab, NeoTabs, NeoTag, NeoToast, NeoToastButton, NeoToggle, NeoToolbar, NeoTooltip, NeoTreeItem, NeoTreeView, StyledToggleButton as NeoTypologyButton, NeoTypologyControl, NeoUserAvatarCell, SortedAscendingIcon, SortedDescendingIcon, UnsortedIcon, focusRingStyles, getDataGridHeaderStyles, neoRowHeights, version };
7149
+ export { ActivityScene, CIRCLE_RADIUS, NeoActionsCell, NeoActivityHeader, NeoActivityIndicatorCell, NeoAlert, NeoAvatarCell, NeoBadge, NeoBanner, NeoBreadcrumbLink, NeoBreadcrumbs, NeoButton, NeoButtonTab, NeoButtonTabGroup, NeoCard, NeoCheckbox, NeoCheckboxWithText, NeoCodeSnippet, NeoDataGrid, NeoDataGridCellContent, NeoDataGridColumnsButton, NeoDataGridColumnsPanel, NeoDataGridFilterPanel, NeoDataGridFilterPanelAddIcon, NeoDataGridFilterPanelDeleteIcon, NeoDataGridFilterPanelRemoveAllIcon, NeoDataGridFiltersButton, NeoDataGridHeaderLabel, NeoSelect as NeoDataGridSelect, NeoDatePicker, NeoDatePickerListItem, NeoDatePickerMenu, NeoDivider, NeoDot, NeoDownloadToast, NeoSelect as NeoDropdown, NeoMenu as NeoDropdownMenu, NeoMenuItem as NeoDropdownMenuItem, NeoMenuItem as NeoDropdownOption, NeoFilterChip, NeoFooter, NeoGeneralAvatar, NeoIconButton, NeoIconCell, NeoIconWrapper, NeoInfiniteScrollGrid, NeoInputField, NeoListItem, NeoListItemButton, NeoLoadingSpinner, NeoLogoCell, NeoMenu, NeoMenuItem, NeoModal, NeoModalContent, NeoModalFooter, NeoModalHeader, NeoMultiBadgesCell, NeoNavigationAvatar, NeoNavigationItem, NeoPageContent, NeoPaginatedGrid, NeoProgressCell, NeoProgressbar, NeoQuickFilter, NeoRadio, NeoRadioButtonWithText, NeoSearchChip, NeoSelect, NeoSelectField, NeoMenuItem as NeoSelectOption, NeoSideNav, NeoSkeleton, NeoStatusBadgeCell, NeoStatusCell, NeoTab, NeoTabPanel, NeoTable, NeoTabs, NeoTag, NeoToast, NeoToastButton, NeoToggle, NeoToggleButton, NeoToggleButtonGroup, NeoToggleButtonWithText, NeoToolbar, NeoTooltip, NeoTopNav, NeoTourModal, NeoTreeItem, NeoTreeView, StyledToggleButton as NeoTypologyButton, NeoTypologyControl, NeoUserAvatarCell, SortedAscendingIcon, SortedDescendingIcon, UnsortedIcon, focusRingStyles, getDataGridHeaderStyles, getDataGridRowStyles, neoRowHeights, version };
6685
7150
  //# sourceMappingURL=index.esm.js.map