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

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 (51) hide show
  1. package/dist/Alert/Alert.d.ts +15 -1
  2. package/dist/Badge/Badge.d.ts +16 -2
  3. package/dist/Breadcrumbs/Breadcrumbs.d.ts +0 -10
  4. package/dist/CanceledIcon/CanceledIcon.d.ts +11 -0
  5. package/dist/Checkbox/Checkbox.d.ts +5 -4
  6. package/dist/DataGrid/DataGrid.d.ts +1 -1
  7. package/dist/DataGrid/DataGrid.styles.d.ts +3 -0
  8. package/dist/DataGridCell/DataGridCell.d.ts +0 -16
  9. package/dist/DataGridHeaderCell/DataGridHeaderCell.d.ts +0 -37
  10. package/dist/DatePickerListItem/DatePickerListItem.d.ts +2 -22
  11. package/dist/DatePickerMenu/DatePickerMenu.d.ts +2 -22
  12. package/dist/Dot/Dot.d.ts +11 -4
  13. package/dist/FilledStatusIcons/FilledStatusIcons.d.ts +41 -0
  14. package/dist/GeneralAvatar/GeneralAvatar.d.ts +1 -7
  15. package/dist/InputField/InputField.d.ts +12 -1
  16. package/dist/ListItemButton/ListItemButton.d.ts +12 -1
  17. package/dist/MenuItem/MenuItem.d.ts +31 -9
  18. package/dist/NavigationAvatar/NavigationAvatar.d.ts +3 -3
  19. package/dist/NavigationItem/NavigationItem.d.ts +21 -2
  20. package/dist/NeoActionsCell/NeoActionsCell.d.ts +9 -0
  21. package/dist/NeoAvatarCell/NeoAvatarCell.d.ts +25 -0
  22. package/dist/NeoIconCell/NeoIconCell.d.ts +14 -0
  23. package/dist/NeoLogoCell/NeoLogoCell.d.ts +24 -0
  24. package/dist/NeoProgressCell/NeoProgressCell.d.ts +21 -0
  25. package/dist/NeoStatusCell/NeoStatusCell.d.ts +30 -0
  26. package/dist/PageContent/PageContent.d.ts +12 -1
  27. package/dist/RadioButtonWithText/RadioButtonWithText.d.ts +2 -22
  28. package/dist/RipplingDot/RipplingDot.d.ts +12 -0
  29. package/dist/SelectField/SelectField.d.ts +64 -0
  30. package/dist/SideNav/NeoSideNavContext.d.ts +5 -0
  31. package/dist/SideNav/SideNav.d.ts +18 -25
  32. package/dist/TabPanel/TabPanel.d.ts +47 -0
  33. package/dist/Table/Table.d.ts +64 -0
  34. package/dist/Tabs/Tabs.d.ts +1 -1
  35. package/dist/Tag/Tag.d.ts +1 -2
  36. package/dist/ToggleButton/ToggleButton.d.ts +13 -18
  37. package/dist/ToggleButtonGroup/ToggleButtonGroup.d.ts +26 -0
  38. package/dist/ToggleButtonWithText/ToggleButtonWithText.d.ts +2 -22
  39. package/dist/Tooltip/Tooltip.d.ts +8 -5
  40. package/dist/TopNav/TopNav.d.ts +2 -22
  41. package/dist/TourModal/TourModal.d.ts +2 -22
  42. package/dist/TypologyControl/TypologyControl.d.ts +1 -1
  43. package/dist/VibratingDot/VibratingDot.d.ts +12 -0
  44. package/dist/index.d.ts +660 -143
  45. package/dist/index.esm.js +1376 -609
  46. package/dist/index.esm.js.map +1 -1
  47. package/dist/index.js +1400 -604
  48. package/dist/index.js.map +1 -1
  49. package/dist/utils/colorHelpers.d.ts +6 -0
  50. package/package.json +5 -5
  51. package/dist/utils/avatarColors.d.ts +0 -7
package/dist/index.esm.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { semanticColors, spacing, typography, borderRadius, colors, shadows } from '@moderneinc/neo-design';
2
+ import { semanticColors, spacing, typography, borderRadius, shadows, colors, semanticTypography } from '@moderneinc/neo-design';
3
3
  import Box from '@mui/material/Box';
4
4
  import { styled, alpha } from '@mui/material/styles';
5
5
  import Chip, { chipClasses } from '@mui/material/Chip';
6
6
  import MuiAvatar from '@mui/material/Avatar';
7
- import SvgIcon, { svgIconClasses } from '@mui/material/SvgIcon';
7
+ import SvgIcon 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';
@@ -36,7 +36,6 @@ import { pickersCalendarHeaderClasses } from '@mui/x-date-pickers/PickersCalenda
36
36
  import { PickersShortcuts } from '@mui/x-date-pickers/PickersShortcuts';
37
37
  import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
38
38
  import { dateRangePickerDayClasses } from '@mui/x-date-pickers-pro/DateRangePickerDay';
39
- import Badge, { badgeClasses } from '@mui/material/Badge';
40
39
  import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress';
41
40
  import Paper, { paperClasses } from '@mui/material/Paper';
42
41
  import Stack from '@mui/material/Stack';
@@ -52,9 +51,16 @@ import Dialog, { dialogClasses } from '@mui/material/Dialog';
52
51
  import DialogActions, { dialogActionsClasses } from '@mui/material/DialogActions';
53
52
  import DialogContent, { dialogContentClasses } from '@mui/material/DialogContent';
54
53
  import Fab from '@mui/material/Fab';
55
- import Fade from '@mui/material/Fade';
54
+ import Fade$1 from '@mui/material/Fade';
56
55
  import Radio, { radioClasses } from '@mui/material/Radio';
56
+ import { keyframes, Box as Box$1 } from '@mui/material';
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,23 +139,26 @@ 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
 
147
+ const djb2Hash = (str) => {
148
+ let hash = 5381;
149
+ for (let i = 0; i < str.length; i++) {
150
+ hash = (hash * 33) ^ str.charCodeAt(i);
151
+ }
152
+ return hash >>> 0;
153
+ };
156
154
  /**
157
- * Shared color palette for avatar components (GeneralAvatar, NavigationAvatar).
158
- * Maps color index (1-7) to background color token pairs.
155
+ * Deterministically derives an HSL background color from a string seed.
156
+ * Produces pastel colors matching the aesthetic of the status.avatar.initials
157
+ * semantic tokens (fixed 80% saturation, 90% lightness; only hue varies).
159
158
  */
160
- const avatarColorPalette = {
161
- 1: { bg: colors.digitalBlue[100] },
162
- 2: { bg: colors.digitalGreen[100] },
163
- 3: { bg: colors.gold[100] },
164
- 4: { bg: colors.red[100] },
165
- 5: { bg: colors.violet[100] },
166
- 6: { bg: colors.tealGreen[100] },
167
- 7: { bg: colors.orange[100] },
159
+ const avatarColorFromSeed = (seed) => {
160
+ const hue = seed ? djb2Hash(seed) % 360 : 235;
161
+ return `hsl(${hue}, 80%, 90%)`;
168
162
  };
169
163
 
170
164
  /**
@@ -179,14 +173,13 @@ const focusRingStyles = {
179
173
  };
180
174
 
181
175
  const sizeConfig$1 = {
182
- small: { width: spacing.spacing_4, height: spacing.spacing_4, fontSize: typography.fontSize.xs },
176
+ small: { width: spacing.spacing_4, height: spacing.spacing_4, fontSize: typography.fontSize.sm },
183
177
  medium: { width: spacing.spacing_5, height: spacing.spacing_5, fontSize: typography.fontSize.sm },
184
178
  };
185
179
  const StyledAvatar = styled(MuiAvatar, {
186
- shouldForwardProp: prop => prop !== 'avatarSize' && prop !== 'colorIndex',
187
- })(({ theme, avatarSize, colorIndex }) => {
180
+ shouldForwardProp: prop => prop !== 'avatarSize' && prop !== 'backgroundColor',
181
+ })(({ theme, avatarSize, backgroundColor }) => {
188
182
  const size = sizeConfig$1[avatarSize];
189
- const palette = avatarColorPalette[colorIndex];
190
183
  return {
191
184
  boxSizing: 'border-box',
192
185
  width: size.width,
@@ -196,7 +189,7 @@ const StyledAvatar = styled(MuiAvatar, {
196
189
  fontWeight: typography.fontWeight.regular,
197
190
  lineHeight: 1,
198
191
  color: semanticColors.typography.body,
199
- backgroundColor: palette ? palette.bg : undefined,
192
+ backgroundColor,
200
193
  border: `1px solid ${semanticColors.border.primary}`,
201
194
  '&:focus-visible': {
202
195
  ...focusRingStyles,
@@ -209,8 +202,9 @@ const StyledAvatar = styled(MuiAvatar, {
209
202
  *
210
203
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=9600-185
211
204
  */
212
- const NeoGeneralAvatar = ({ size = 'medium', colorIndex = 0, children, ...props }) => {
213
- return (jsx(StyledAvatar, { avatarSize: size, colorIndex: colorIndex, ...props, children: children }));
205
+ const NeoGeneralAvatar = ({ size = 'medium', alt, children, ...props }) => {
206
+ const backgroundColor = avatarColorFromSeed(alt);
207
+ return (jsx(StyledAvatar, { avatarSize: size, backgroundColor: backgroundColor, alt: alt, ...props, children: children }));
214
208
  };
215
209
  NeoGeneralAvatar.displayName = 'NeoGeneralAvatar';
216
210
 
@@ -267,22 +261,6 @@ const NeoDataGridCellContent = ({ children, ...props }) => {
267
261
  return jsx(CellContentContainer, { ...props, children: children });
268
262
  };
269
263
  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
264
  /**
287
265
  * Row height configuration for DataGrid size variants (from Figma specs)
288
266
  * - compact: 42px
@@ -476,7 +454,7 @@ const NeoActivityIndicatorCell = ({ event = 'commit-job', secondaryEvent, scene
476
454
  NeoActivityIndicatorCell.displayName = 'NeoActivityIndicatorCell';
477
455
 
478
456
  /**
479
- * @license lucide-react v1.7.0 - ISC
457
+ * @license lucide-react v1.16.0 - ISC
480
458
  *
481
459
  * This source code is licensed under the ISC license.
482
460
  * See the LICENSE file in the root directory of this source tree.
@@ -487,7 +465,7 @@ const mergeClasses = (...classes) => classes.filter((className, index, array) =>
487
465
  }).join(" ").trim();
488
466
 
489
467
  /**
490
- * @license lucide-react v1.7.0 - ISC
468
+ * @license lucide-react v1.16.0 - ISC
491
469
  *
492
470
  * This source code is licensed under the ISC license.
493
471
  * See the LICENSE file in the root directory of this source tree.
@@ -496,7 +474,7 @@ const mergeClasses = (...classes) => classes.filter((className, index, array) =>
496
474
  const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
497
475
 
498
476
  /**
499
- * @license lucide-react v1.7.0 - ISC
477
+ * @license lucide-react v1.16.0 - ISC
500
478
  *
501
479
  * This source code is licensed under the ISC license.
502
480
  * See the LICENSE file in the root directory of this source tree.
@@ -508,7 +486,7 @@ const toCamelCase = (string) => string.replace(
508
486
  );
509
487
 
510
488
  /**
511
- * @license lucide-react v1.7.0 - ISC
489
+ * @license lucide-react v1.16.0 - ISC
512
490
  *
513
491
  * This source code is licensed under the ISC license.
514
492
  * See the LICENSE file in the root directory of this source tree.
@@ -521,7 +499,7 @@ const toPascalCase = (string) => {
521
499
  };
522
500
 
523
501
  /**
524
- * @license lucide-react v1.7.0 - ISC
502
+ * @license lucide-react v1.16.0 - ISC
525
503
  *
526
504
  * This source code is licensed under the ISC license.
527
505
  * See the LICENSE file in the root directory of this source tree.
@@ -540,7 +518,7 @@ var defaultAttributes = {
540
518
  };
541
519
 
542
520
  /**
543
- * @license lucide-react v1.7.0 - ISC
521
+ * @license lucide-react v1.16.0 - ISC
544
522
  *
545
523
  * This source code is licensed under the ISC license.
546
524
  * See the LICENSE file in the root directory of this source tree.
@@ -590,7 +568,7 @@ const Icon = forwardRef(
590
568
  );
591
569
 
592
570
  /**
593
- * @license lucide-react v1.7.0 - ISC
571
+ * @license lucide-react v1.16.0 - ISC
594
572
  *
595
573
  * This source code is licensed under the ISC license.
596
574
  * See the LICENSE file in the root directory of this source tree.
@@ -615,42 +593,42 @@ const createLucideIcon = (iconName, iconNode) => {
615
593
  };
616
594
 
617
595
  /**
618
- * @license lucide-react v1.7.0 - ISC
596
+ * @license lucide-react v1.16.0 - ISC
619
597
  *
620
598
  * This source code is licensed under the ISC license.
621
599
  * See the LICENSE file in the root directory of this source tree.
622
600
  */
623
601
 
624
602
 
625
- const __iconNode$k = [
603
+ const __iconNode$p = [
626
604
  ["path", { d: "M12 5v14", key: "s699le" }],
627
605
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
628
606
  ];
629
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$k);
607
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$p);
630
608
 
631
609
  /**
632
- * @license lucide-react v1.7.0 - ISC
610
+ * @license lucide-react v1.16.0 - ISC
633
611
  *
634
612
  * This source code is licensed under the ISC license.
635
613
  * See the LICENSE file in the root directory of this source tree.
636
614
  */
637
615
 
638
616
 
639
- const __iconNode$j = [
617
+ const __iconNode$o = [
640
618
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
641
619
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
642
620
  ];
643
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$j);
621
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$o);
644
622
 
645
623
  /**
646
- * @license lucide-react v1.7.0 - ISC
624
+ * @license lucide-react v1.16.0 - ISC
647
625
  *
648
626
  * This source code is licensed under the ISC license.
649
627
  * See the LICENSE file in the root directory of this source tree.
650
628
  */
651
629
 
652
630
 
653
- const __iconNode$i = [
631
+ const __iconNode$n = [
654
632
  [
655
633
  "path",
656
634
  {
@@ -661,17 +639,17 @@ const __iconNode$i = [
661
639
  ["line", { x1: "12", x2: "12", y1: "16", y2: "12", key: "1y1yb1" }],
662
640
  ["line", { x1: "12", x2: "12.01", y1: "8", y2: "8", key: "110wyk" }]
663
641
  ];
664
- const BadgeInfo = createLucideIcon("badge-info", __iconNode$i);
642
+ const BadgeInfo = createLucideIcon("badge-info", __iconNode$n);
665
643
 
666
644
  /**
667
- * @license lucide-react v1.7.0 - ISC
645
+ * @license lucide-react v1.16.0 - ISC
668
646
  *
669
647
  * This source code is licensed under the ISC license.
670
648
  * See the LICENSE file in the root directory of this source tree.
671
649
  */
672
650
 
673
651
 
674
- const __iconNode$h = [
652
+ const __iconNode$m = [
675
653
  ["path", { d: "M8 2v4", key: "1cmpym" }],
676
654
  ["path", { d: "M16 2v4", key: "4m81vk" }],
677
655
  ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
@@ -683,181 +661,252 @@ const __iconNode$h = [
683
661
  ["path", { d: "M12 18h.01", key: "mhygvu" }],
684
662
  ["path", { d: "M16 18h.01", key: "kzsmim" }]
685
663
  ];
686
- const CalendarDays = createLucideIcon("calendar-days", __iconNode$h);
664
+ const CalendarDays = createLucideIcon("calendar-days", __iconNode$m);
687
665
 
688
666
  /**
689
- * @license lucide-react v1.7.0 - ISC
667
+ * @license lucide-react v1.16.0 - ISC
690
668
  *
691
669
  * This source code is licensed under the ISC license.
692
670
  * See the LICENSE file in the root directory of this source tree.
693
671
  */
694
672
 
695
673
 
696
- const __iconNode$g = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
697
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$g);
674
+ const __iconNode$l = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
675
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$l);
698
676
 
699
677
  /**
700
- * @license lucide-react v1.7.0 - ISC
678
+ * @license lucide-react v1.16.0 - ISC
701
679
  *
702
680
  * This source code is licensed under the ISC license.
703
681
  * See the LICENSE file in the root directory of this source tree.
704
682
  */
705
683
 
706
684
 
707
- const __iconNode$f = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
708
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$f);
685
+ const __iconNode$k = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
686
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$k);
709
687
 
710
688
  /**
711
- * @license lucide-react v1.7.0 - ISC
689
+ * @license lucide-react v1.16.0 - ISC
712
690
  *
713
691
  * This source code is licensed under the ISC license.
714
692
  * See the LICENSE file in the root directory of this source tree.
715
693
  */
716
694
 
717
695
 
718
- const __iconNode$e = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
719
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$e);
696
+ const __iconNode$j = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
697
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$j);
720
698
 
721
699
  /**
722
- * @license lucide-react v1.7.0 - ISC
700
+ * @license lucide-react v1.16.0 - ISC
723
701
  *
724
702
  * This source code is licensed under the ISC license.
725
703
  * See the LICENSE file in the root directory of this source tree.
726
704
  */
727
705
 
728
706
 
729
- const __iconNode$d = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
730
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$d);
707
+ const __iconNode$i = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
708
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$i);
731
709
 
732
710
  /**
733
- * @license lucide-react v1.7.0 - ISC
711
+ * @license lucide-react v1.16.0 - ISC
734
712
  *
735
713
  * This source code is licensed under the ISC license.
736
714
  * See the LICENSE file in the root directory of this source tree.
737
715
  */
738
716
 
739
717
 
740
- const __iconNode$c = [
718
+ const __iconNode$h = [
741
719
  ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
742
720
  ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
743
721
  ];
744
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$c);
722
+ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$h);
745
723
 
746
724
  /**
747
- * @license lucide-react v1.7.0 - ISC
725
+ * @license lucide-react v1.16.0 - ISC
748
726
  *
749
727
  * This source code is licensed under the ISC license.
750
728
  * See the LICENSE file in the root directory of this source tree.
751
729
  */
752
730
 
753
731
 
754
- const __iconNode$b = [
732
+ const __iconNode$g = [
755
733
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
756
734
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
757
735
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
758
736
  ];
759
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$b);
737
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$g);
760
738
 
761
739
  /**
762
- * @license lucide-react v1.7.0 - ISC
740
+ * @license lucide-react v1.16.0 - ISC
763
741
  *
764
742
  * This source code is licensed under the ISC license.
765
743
  * See the LICENSE file in the root directory of this source tree.
766
744
  */
767
745
 
768
746
 
769
- const __iconNode$a = [
747
+ const __iconNode$f = [
770
748
  ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
771
749
  ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
772
750
  ];
773
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$a);
751
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$f);
774
752
 
775
753
  /**
776
- * @license lucide-react v1.7.0 - ISC
754
+ * @license lucide-react v1.16.0 - ISC
777
755
  *
778
756
  * This source code is licensed under the ISC license.
779
757
  * See the LICENSE file in the root directory of this source tree.
780
758
  */
781
759
 
782
760
 
783
- const __iconNode$9 = [
761
+ const __iconNode$e = [
784
762
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
785
763
  ["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
786
764
  ["path", { d: "M12 17h.01", key: "p32p05" }]
787
765
  ];
788
- const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$9);
766
+ const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$e);
789
767
 
790
768
  /**
791
- * @license lucide-react v1.7.0 - ISC
769
+ * @license lucide-react v1.16.0 - ISC
792
770
  *
793
771
  * This source code is licensed under the ISC license.
794
772
  * See the LICENSE file in the root directory of this source tree.
795
773
  */
796
774
 
797
775
 
798
- const __iconNode$8 = [
776
+ const __iconNode$d = [
799
777
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
800
778
  ["path", { d: "M9 3v18", key: "fh3hqa" }],
801
779
  ["path", { d: "M15 3v18", key: "14nvp0" }]
802
780
  ];
803
- const Columns3 = createLucideIcon("columns-3", __iconNode$8);
781
+ const Columns3 = createLucideIcon("columns-3", __iconNode$d);
804
782
 
805
783
  /**
806
- * @license lucide-react v1.7.0 - ISC
784
+ * @license lucide-react v1.16.0 - ISC
807
785
  *
808
786
  * This source code is licensed under the ISC license.
809
787
  * See the LICENSE file in the root directory of this source tree.
810
788
  */
811
789
 
812
790
 
813
- const __iconNode$7 = [
791
+ const __iconNode$c = [
814
792
  ["path", { d: "M2 5h20", key: "1fs1ex" }],
815
793
  ["path", { d: "M6 12h12", key: "8npq4p" }],
816
794
  ["path", { d: "M9 19h6", key: "456am0" }]
817
795
  ];
818
- const ListFilter = createLucideIcon("list-filter", __iconNode$7);
796
+ const ListFilter = createLucideIcon("list-filter", __iconNode$c);
819
797
 
820
798
  /**
821
- * @license lucide-react v1.7.0 - ISC
799
+ * @license lucide-react v1.16.0 - ISC
822
800
  *
823
801
  * This source code is licensed under the ISC license.
824
802
  * See the LICENSE file in the root directory of this source tree.
825
803
  */
826
804
 
827
805
 
828
- const __iconNode$6 = [["path", { d: "M5 12h14", key: "1ays0h" }]];
829
- const Minus = createLucideIcon("minus", __iconNode$6);
806
+ const __iconNode$b = [["path", { d: "M5 12h14", key: "1ays0h" }]];
807
+ const Minus = createLucideIcon("minus", __iconNode$b);
830
808
 
831
809
  /**
832
- * @license lucide-react v1.7.0 - ISC
810
+ * @license lucide-react v1.16.0 - ISC
833
811
  *
834
812
  * This source code is licensed under the ISC license.
835
813
  * See the LICENSE file in the root directory of this source tree.
836
814
  */
837
815
 
838
816
 
839
- const __iconNode$5 = [
817
+ const __iconNode$a = [
818
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
819
+ ["path", { d: "M9 3v18", key: "fh3hqa" }],
820
+ ["path", { d: "m16 15-3-3 3-3", key: "14y99z" }]
821
+ ];
822
+ const PanelLeftClose = createLucideIcon("panel-left-close", __iconNode$a);
823
+
824
+ /**
825
+ * @license lucide-react v1.16.0 - ISC
826
+ *
827
+ * This source code is licensed under the ISC license.
828
+ * See the LICENSE file in the root directory of this source tree.
829
+ */
830
+
831
+
832
+ const __iconNode$9 = [
833
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
834
+ ["path", { d: "M9 3v18", key: "fh3hqa" }],
835
+ ["path", { d: "m14 9 3 3-3 3", key: "8010ee" }]
836
+ ];
837
+ const PanelLeftOpen = createLucideIcon("panel-left-open", __iconNode$9);
838
+
839
+ /**
840
+ * @license lucide-react v1.16.0 - ISC
841
+ *
842
+ * This source code is licensed under the ISC license.
843
+ * See the LICENSE file in the root directory of this source tree.
844
+ */
845
+
846
+
847
+ const __iconNode$8 = [
840
848
  ["path", { d: "M5 12h14", key: "1ays0h" }],
841
849
  ["path", { d: "M12 5v14", key: "s699le" }]
842
850
  ];
843
- const Plus = createLucideIcon("plus", __iconNode$5);
851
+ const Plus = createLucideIcon("plus", __iconNode$8);
844
852
 
845
853
  /**
846
- * @license lucide-react v1.7.0 - ISC
854
+ * @license lucide-react v1.16.0 - ISC
847
855
  *
848
856
  * This source code is licensed under the ISC license.
849
857
  * See the LICENSE file in the root directory of this source tree.
850
858
  */
851
859
 
852
860
 
853
- const __iconNode$4 = [
861
+ const __iconNode$7 = [
854
862
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
855
863
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
856
864
  ];
857
- const Search = createLucideIcon("search", __iconNode$4);
865
+ const Search = createLucideIcon("search", __iconNode$7);
866
+
867
+ /**
868
+ * @license lucide-react v1.16.0 - ISC
869
+ *
870
+ * This source code is licensed under the ISC license.
871
+ * See the LICENSE file in the root directory of this source tree.
872
+ */
873
+
874
+
875
+ const __iconNode$6 = [
876
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
877
+ ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
878
+ ];
879
+ const SquareCheck = createLucideIcon("square-check", __iconNode$6);
880
+
881
+ /**
882
+ * @license lucide-react v1.16.0 - ISC
883
+ *
884
+ * This source code is licensed under the ISC license.
885
+ * See the LICENSE file in the root directory of this source tree.
886
+ */
887
+
888
+
889
+ const __iconNode$5 = [
890
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
891
+ ["path", { d: "M8 12h8", key: "1wcyev" }]
892
+ ];
893
+ const SquareMinus = createLucideIcon("square-minus", __iconNode$5);
894
+
895
+ /**
896
+ * @license lucide-react v1.16.0 - ISC
897
+ *
898
+ * This source code is licensed under the ISC license.
899
+ * See the LICENSE file in the root directory of this source tree.
900
+ */
901
+
902
+
903
+ const __iconNode$4 = [
904
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]
905
+ ];
906
+ const Square = createLucideIcon("square", __iconNode$4);
858
907
 
859
908
  /**
860
- * @license lucide-react v1.7.0 - ISC
909
+ * @license lucide-react v1.16.0 - ISC
861
910
  *
862
911
  * This source code is licensed under the ISC license.
863
912
  * See the LICENSE file in the root directory of this source tree.
@@ -874,7 +923,7 @@ const __iconNode$3 = [
874
923
  const Trash2 = createLucideIcon("trash-2", __iconNode$3);
875
924
 
876
925
  /**
877
- * @license lucide-react v1.7.0 - ISC
926
+ * @license lucide-react v1.16.0 - ISC
878
927
  *
879
928
  * This source code is licensed under the ISC license.
880
929
  * See the LICENSE file in the root directory of this source tree.
@@ -895,7 +944,7 @@ const __iconNode$2 = [
895
944
  const TriangleAlert = createLucideIcon("triangle-alert", __iconNode$2);
896
945
 
897
946
  /**
898
- * @license lucide-react v1.7.0 - ISC
947
+ * @license lucide-react v1.16.0 - ISC
899
948
  *
900
949
  * This source code is licensed under the ISC license.
901
950
  * See the LICENSE file in the root directory of this source tree.
@@ -914,7 +963,7 @@ const __iconNode$1 = [
914
963
  const WifiOff = createLucideIcon("wifi-off", __iconNode$1);
915
964
 
916
965
  /**
917
- * @license lucide-react v1.7.0 - ISC
966
+ * @license lucide-react v1.16.0 - ISC
918
967
  *
919
968
  * This source code is licensed under the ISC license.
920
969
  * See the LICENSE file in the root directory of this source tree.
@@ -937,22 +986,29 @@ const intentColors$2 = {
937
986
  };
938
987
  // biome-ignore lint/suspicious/noExplicitAny: Type cast required to override MUI Alert variant type without global augmentation
939
988
  const StyledAlert$2 = styled(Alert, {
940
- shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType',
941
- })(({ theme, intent = 'success', alertType = 'outlined' }) => {
989
+ shouldForwardProp: prop => prop !== 'intent' && prop !== 'alertType' && prop !== 'alertSize' && prop !== 'hasChildren',
990
+ })(({ theme, intent = 'success', alertType = 'outlined', alertSize = 'default', hasChildren = false, }) => {
942
991
  const palette = intentColors$2[intent];
943
992
  const isFilled = alertType === 'filled';
993
+ const isCompact = alertSize === 'compact';
944
994
  const iconColor = isFilled ? semanticColors.typography.tooltip : palette.default;
945
- const messageColor = isFilled ? semanticColors.typography.tooltip : semanticColors.typography.body;
995
+ const messageColor = isFilled
996
+ ? semanticColors.typography.tooltip
997
+ : semanticColors.typography.body;
946
998
  return {
947
- height: spacing.spacing_8,
999
+ ...(isCompact
1000
+ ? { minHeight: spacing.spacing_5 }
1001
+ : hasChildren
1002
+ ? { minHeight: spacing.spacing_8, height: 'auto' }
1003
+ : { height: spacing.spacing_8 }),
948
1004
  width: '100%',
949
1005
  borderRadius: borderRadius.xS,
950
- alignItems: 'center',
1006
+ alignItems: hasChildren ? 'flex-start' : 'center',
951
1007
  fontFamily: typography.fontFamily.body,
952
1008
  fontSize: theme.typography.pxToRem(typography.fontSize.default),
953
1009
  fontWeight: typography.fontWeight.semiBold,
954
1010
  lineHeight: 1.5,
955
- padding: theme.spacing(0, 2),
1011
+ padding: hasChildren ? theme.spacing(1.5, 2) : theme.spacing(0, 2),
956
1012
  backgroundColor: isFilled ? palette.dark : palette.light,
957
1013
  border: isFilled ? 'none' : `1px solid ${palette.transparent}`,
958
1014
  color: isFilled ? semanticColors.typography.tooltip : semanticColors.typography.body,
@@ -969,7 +1025,7 @@ const StyledAlert$2 = styled(Alert, {
969
1025
  flex: 1,
970
1026
  display: 'flex',
971
1027
  flexDirection: 'column',
972
- justifyContent: 'center',
1028
+ justifyContent: hasChildren ? 'flex-start' : 'center',
973
1029
  '& span:last-child': {
974
1030
  fontSize: theme.typography.pxToRem(typography.fontSize.sm),
975
1031
  fontWeight: typography.fontWeight.medium,
@@ -1007,9 +1063,9 @@ const iconMap = {
1007
1063
  * - Show supporting text → description prop presence
1008
1064
  * - Show Button → action prop presence
1009
1065
  */
1010
- const NeoAlert = ({ intent = 'success', type = 'outlined', title, description, icon, action, ...props }) => {
1066
+ const NeoAlert = ({ intent = 'success', type = 'outlined', size = 'default', title, description, icon, action, children, ...props }) => {
1011
1067
  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 })] }));
1068
+ return (jsxs(StyledAlert$2, { ...props, intent: intent, alertType: type, alertSize: size, hasChildren: Boolean(children), icon: icon ?? defaultIcon, action: action, children: [jsx("span", { children: title }), description && jsx("span", { children: description }), children] }));
1013
1069
  };
1014
1070
  NeoAlert.displayName = 'NeoAlert';
1015
1071
 
@@ -1036,38 +1092,43 @@ const StyledAlert$1 = styled(Alert, {
1036
1092
  };
1037
1093
  return {
1038
1094
  width: '100%',
1039
- minHeight: 52,
1040
- paddingTop: spacing.spacing_3_4,
1041
- paddingBottom: spacing.spacing_3_4,
1042
- paddingLeft: spacing.spacing_3,
1043
- paddingRight: spacing.spacing_3,
1044
- gap: spacing.spacing_2,
1095
+ // Include padding in the width so the full-width banner never overflows its
1096
+ // container (don't rely on a global border-box reset being present).
1097
+ boxSizing: 'border-box',
1098
+ // Square corners by default: banners are full-width and typically sit flush
1099
+ // against the top of the viewport, so rounded corners would break the seam.
1100
+ borderRadius: 0,
1101
+ minHeight: 32,
1102
+ paddingTop: spacing.spacing_1_2,
1103
+ paddingBottom: spacing.spacing_1_2,
1104
+ paddingLeft: spacing.spacing_2,
1105
+ paddingRight: spacing.spacing_2,
1106
+ gap: spacing.spacing_1,
1045
1107
  alignItems: 'center',
1046
1108
  justifyContent: messagePosition === 'center' ? 'center' : 'flex-start',
1047
1109
  ...(messagePosition === 'center' && { position: 'relative' }),
1048
- boxShadow: `${shadows.neutral.small.x}px ${shadows.neutral.small.y}px ${shadows.neutral.small.blur}px ${shadows.neutral.small.spread}px ${shadows.neutral.small.shadow}`,
1049
- fontSize: typography.fontSize.default,
1110
+ fontSize: typography.fontSize.sm,
1050
1111
  fontWeight: typography.fontWeight.medium,
1051
1112
  lineHeight: 1.5,
1052
1113
  ...typeStyles,
1053
1114
  [`& .${alertClasses.icon}`]: {
1054
1115
  padding: 0,
1055
1116
  opacity: 1,
1056
- fontSize: typography.fontSize.h2,
1117
+ fontSize: typography.fontSize.default,
1057
1118
  color: 'inherit',
1058
1119
  },
1059
1120
  [`& .${alertClasses.message}`]: {
1060
1121
  padding: 0,
1061
1122
  display: 'flex',
1062
1123
  alignItems: 'center',
1063
- gap: spacing.spacing_2,
1124
+ gap: spacing.spacing_1,
1064
1125
  ...(messagePosition === 'left' && { flex: 1 }),
1065
1126
  },
1066
1127
  [`& .${alertClasses.action}`]: {
1067
1128
  padding: 0,
1068
1129
  ...(messagePosition === 'center' && {
1069
1130
  position: 'absolute',
1070
- right: spacing.spacing_3,
1131
+ right: spacing.spacing_2,
1071
1132
  }),
1072
1133
  },
1073
1134
  };
@@ -1085,6 +1146,8 @@ const LinkText = styled('span')(({ bannerType = 'outlined' }) => ({
1085
1146
  },
1086
1147
  }));
1087
1148
  const StyledIconButton = styled(IconButton)(({ closeIconColor }) => ({
1149
+ minWidth: 24,
1150
+ minHeight: 24,
1088
1151
  padding: 0,
1089
1152
  color: closeIconColor,
1090
1153
  '&:hover': {
@@ -1101,7 +1164,7 @@ const NeoBanner = ({ intent = 'info', type = 'outlined', message, messagePositio
1101
1164
  return null;
1102
1165
  }
1103
1166
  const closeIconColor = type === 'filled' ? semanticColors.surfaces.white : intentColors$1[intent].default;
1104
- return (jsx(StyledAlert$1, { ...props, intent: intent, bannerType: type, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton, { size: "small", onClick: handleClose, closeIconColor: closeIconColor, children: jsx(X, { size: 24 }) })) : undefined, children: messagePosition === 'center' ? (jsxs(Fragment, { children: [icon, jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) : (jsxs(Fragment, { children: [jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) }));
1167
+ return (jsx(StyledAlert$1, { ...props, intent: intent, bannerType: type, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton, { size: "small", onClick: handleClose, closeIconColor: closeIconColor, children: jsx(X, { size: 16 }) })) : undefined, children: messagePosition === 'center' ? (jsxs(Fragment, { children: [icon, jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) : (jsxs(Fragment, { children: [jsx("span", { children: message }), linkText && (jsx(LinkText, { bannerType: type, onClick: onLinkClick, children: linkText }))] })) }));
1105
1168
  };
1106
1169
  NeoBanner.displayName = 'NeoBanner';
1107
1170
 
@@ -1121,12 +1184,12 @@ const StyledBreadcrumbLink = styled(Link, {
1121
1184
  fontWeight: typography.fontWeight.medium,
1122
1185
  lineHeight: 1,
1123
1186
  textDecoration: 'none',
1124
- color: current ? semanticColors.buttons.primary.default : semanticColors.typography.bodySecondary,
1187
+ color: current ? semanticColors.typography.bodySecondary : semanticColors.typography.link.primary,
1125
1188
  cursor: current ? 'default' : 'pointer',
1126
1189
  borderRadius: borderRadius.xS,
1127
1190
  transition: 'color 0.2s ease-in-out',
1128
1191
  '&:hover': {
1129
- color: current ? semanticColors.buttons.tertiary.hover : semanticColors.icons.hover,
1192
+ color: current ? semanticColors.icons.hover : semanticColors.buttons.tertiary.hover,
1130
1193
  },
1131
1194
  '&:focus-visible': {
1132
1195
  outline: `2px solid ${semanticColors.border.focus}`,
@@ -1509,6 +1572,15 @@ const NeoButtonTabGroup = ({ size = 'medium', exclusive = true, ...props }) => {
1509
1572
  };
1510
1573
  NeoButtonTabGroup.displayName = 'NeoButtonTabGroup';
1511
1574
 
1575
+ /**
1576
+ * NeoCanceledIcon - Outlined circle struck through by a horizontal line.
1577
+ *
1578
+ * Marks a CANCELED state. Color comes entirely from `currentColor` (stroke plus
1579
+ * a 10% fill tint); set it via the `color`/`sx` prop or a parent.
1580
+ */
1581
+ const NeoCanceledIcon = (props) => (jsx(SvgIcon, { viewBox: "0 0 24 24", fill: "none", ...props, children: jsxs("g", { stroke: "currentColor", strokeWidth: "1.35", children: [jsx("path", { fill: "currentColor", fillOpacity: "0.1", d: "M2.55 11.95c0 2.405.918 4.812 2.753 6.647a9.4 9.4 0 0 0 6.647 2.753c2.489 0 4.877-.99 6.646-2.753a9.3 9.3 0 0 0 2.039-3.044 9.4 9.4 0 0 0 .715-3.602m-18.8-.001a9.37 9.37 0 0 1 2.753-6.647A9.4 9.4 0 0 1 11.95 2.55c2.489 0 4.877.99 6.646 2.753a9.3 9.3 0 0 1 2.039 3.045 9.4 9.4 0 0 1 .715 3.603" }), jsx("path", { fill: "none", d: "M3 11.825h18" })] }) }));
1582
+ NeoCanceledIcon.displayName = 'NeoCanceledIcon';
1583
+
1512
1584
  // ─── Shared ──────────────────────────────────────────────────────────────────
1513
1585
  const activeShadow = `${shadows.card.x}px ${shadows.card.y}px ${shadows.card.blur}px ${shadows.card.spread}px ${shadows.card.shadow}`;
1514
1586
  // ─── Small card styled components ────────────────────────────────────────────
@@ -1700,20 +1772,6 @@ const NeoCard = (props) => {
1700
1772
  };
1701
1773
  NeoCard.displayName = 'NeoCard';
1702
1774
 
1703
- // Border radius per size (from Figma)
1704
- const borderRadiusConfig = {
1705
- xs: 2,
1706
- small: 3,
1707
- medium: 4,
1708
- };
1709
- // Unchecked: Rounded square outline (20x20 viewBox)
1710
- const UncheckedIcon$1 = ({ size = 'medium' }) => (jsx(SvgIcon, { viewBox: "0 0 20 20", children: jsx("rect", { x: "1", y: "1", width: "18", height: "18", rx: borderRadiusConfig[size], fill: "none", stroke: "currentColor", strokeWidth: "1.5" }) }));
1711
- // Checked: Filled rounded square with white checkmark
1712
- // Path scaled from Untitled UI 24x24 (M20 6L9 17L4 12) to 20x20
1713
- const CheckedIcon$1 = ({ size = 'medium' }) => (jsxs(SvgIcon, { viewBox: "0 0 20 20", children: [jsx("rect", { width: "20", height: "20", rx: borderRadiusConfig[size], fill: "currentColor" }), jsx("path", { d: "M15 6L8.5 13L5 9.5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })] }));
1714
- // Indeterminate: Filled rounded square with white minus
1715
- // Path scaled from Untitled UI 24x24 (M5 12H19) to 20x20
1716
- const IndeterminateIcon = ({ size = 'medium' }) => (jsxs(SvgIcon, { viewBox: "0 0 20 20", children: [jsx("rect", { width: "20", height: "20", rx: borderRadiusConfig[size], fill: "currentColor" }), jsx("path", { d: "M5 10H15", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", fill: "none" })] }));
1717
1775
  const CheckboxContainer = styled('label')(({ disabled }) => ({
1718
1776
  display: 'inline-flex',
1719
1777
  alignItems: 'flex-start',
@@ -1746,7 +1804,7 @@ const HelperText$2 = styled('span')(({ theme, size = 'medium' }) => ({
1746
1804
  lineHeight: size === 'xs' ? 1.5 : size === 'small' ? 1.4 : 1.5,
1747
1805
  color: semanticColors.typography.bodySecondary,
1748
1806
  }));
1749
- // Figma-exact border radius for xs checkbox — no matching design token
1807
+ // xs focus-ring radius — no matching design token (box corner comes from the icon)
1750
1808
  const FIGMA_XS_BORDER_RADIUS = 1;
1751
1809
  const StyledCheckbox = styled(Checkbox, {
1752
1810
  shouldForwardProp: prop => prop !== 'size',
@@ -1759,11 +1817,11 @@ const StyledCheckbox = styled(Checkbox, {
1759
1817
  },
1760
1818
  small: {
1761
1819
  size: 16,
1762
- borderRadius: borderRadius.xXS, // From Figma: 2px for small
1820
+ borderRadius: borderRadius.xXS, // focus-ring radius (small)
1763
1821
  },
1764
1822
  medium: {
1765
1823
  size: 20,
1766
- borderRadius: borderRadius.xS, // From Figma: 4px for medium
1824
+ borderRadius: borderRadius.xS, // focus-ring radius (medium)
1767
1825
  },
1768
1826
  };
1769
1827
  const config = sizeConfig[size];
@@ -1775,37 +1833,30 @@ const StyledCheckbox = styled(Checkbox, {
1775
1833
  color: semanticColors.border.primary,
1776
1834
  borderRadius: config.borderRadius,
1777
1835
  flexShrink: 0,
1778
- // Root element
1779
- [`&.${checkboxClasses.root}`]: {
1780
- '&:hover': {
1781
- backgroundColor: 'transparent',
1782
- },
1836
+ // Suppress MUI's grey hover background
1837
+ '&:hover': {
1838
+ backgroundColor: 'transparent',
1783
1839
  },
1784
- // Checkbox icon (unchecked)
1785
- [`& .${checkboxClasses.root}`]: {
1786
- width: config.size,
1787
- height: config.size,
1840
+ // Hover on the unchecked box — subtle blue outline affordance (enabled only)
1841
+ [`&:hover:not(.${checkboxClasses.checked}):not(.${checkboxClasses.indeterminate}):not(.${checkboxClasses.disabled})`]: {
1842
+ color: colors.digitalBlue[300],
1788
1843
  },
1789
- // Checked state
1844
+ // Checked / Indeterminate — primary blue outline + mark
1790
1845
  [`&.${checkboxClasses.checked}`]: {
1791
- color: semanticColors.buttons.primary.default,
1846
+ color: colors.digitalBlue[600],
1792
1847
  },
1793
- // Indeterminate state
1794
1848
  [`&.${checkboxClasses.indeterminate}`]: {
1795
- color: semanticColors.buttons.primary.default,
1849
+ color: colors.digitalBlue[600],
1796
1850
  },
1797
- // Disabled state
1851
+ // Disabled — enabled colors dimmed to 40%. Checked/indeterminate keep
1852
+ // digitalBlue[600] via the rules above; re-assert the unchecked outline
1853
+ // token so it beats MUI's default `.Mui-disabled` color.
1798
1854
  [`&.${checkboxClasses.disabled}`]: {
1799
- color: semanticColors.border.primary,
1855
+ opacity: 0.4,
1800
1856
  cursor: 'not-allowed',
1801
- // When checked and disabled
1802
- [`&.${checkboxClasses.checked}`]: {
1803
- color: semanticColors.border.primary,
1804
- },
1805
- // When indeterminate and disabled
1806
- [`&.${checkboxClasses.indeterminate}`]: {
1807
- color: semanticColors.border.primary,
1808
- },
1857
+ },
1858
+ [`&.${checkboxClasses.disabled}:not(.${checkboxClasses.checked}):not(.${checkboxClasses.indeterminate})`]: {
1859
+ color: semanticColors.border.primary,
1809
1860
  },
1810
1861
  // Focus visible for keyboard navigation
1811
1862
  '&.Mui-focusVisible': {
@@ -1813,11 +1864,10 @@ const StyledCheckbox = styled(Checkbox, {
1813
1864
  outlineOffset: 2,
1814
1865
  borderRadius: config.borderRadius,
1815
1866
  },
1816
- // Custom SVG icons
1867
+ // Size the Lucide icon (color comes from `color` → currentColor → stroke)
1817
1868
  '& svg': {
1818
1869
  width: config.size,
1819
1870
  height: config.size,
1820
- fill: 'currentColor',
1821
1871
  },
1822
1872
  };
1823
1873
  });
@@ -1868,10 +1918,10 @@ const StyledCheckbox = styled(Checkbox, {
1868
1918
  const NeoCheckbox = ({ size = 'medium', label, helperText, disabled, icon, checkedIcon, indeterminateIcon, className, ...props }) => {
1869
1919
  // Add custom class to identify NeoCheckbox instances
1870
1920
  const combinedClassName = className ? `neo-checkbox ${className}` : 'neo-checkbox';
1871
- // Create size-specific icons
1872
- const defaultIcon = icon || jsx(UncheckedIcon$1, { size: size });
1873
- const defaultCheckedIcon = checkedIcon || jsx(CheckedIcon$1, { size: size });
1874
- const defaultIndeterminateIcon = indeterminateIcon || jsx(IndeterminateIcon, { size: size });
1921
+ // Default icons (sized via CSS on the SVG); overridable per instance
1922
+ const defaultIcon = icon || jsx(Square, {});
1923
+ const defaultCheckedIcon = checkedIcon || jsx(SquareCheck, {});
1924
+ const defaultIndeterminateIcon = indeterminateIcon || jsx(SquareMinus, {});
1875
1925
  // If no label, return just the checkbox
1876
1926
  if (!label && !helperText) {
1877
1927
  return (jsx(StyledCheckbox, { size: size, disabled: disabled, icon: defaultIcon, checkedIcon: defaultCheckedIcon, indeterminateIcon: defaultIndeterminateIcon, className: combinedClassName, ...props }));
@@ -2183,7 +2233,8 @@ const StyledMenuItem = styled(MenuItem)(({ theme }) => ({
2183
2233
  gap: theme.spacing(2),
2184
2234
  borderRadius: 0,
2185
2235
  color: semanticColors.icons.default,
2186
- fontSize: theme.typography.pxToRem(typography.fontSize.sm),
2236
+ textDecoration: 'none',
2237
+ fontSize: theme.typography.pxToRem(typography.fontSize.default),
2187
2238
  fontWeight: typography.fontWeight.regular,
2188
2239
  lineHeight: `${typography.lineHeight.s}px`,
2189
2240
  transition: theme.transitions.create(['background-color'], {
@@ -2249,7 +2300,7 @@ const Shortcut = styled('span')(({ theme }) => ({
2249
2300
  /**
2250
2301
  * NeoMenuItem - Menu item component based on MUI MenuItem
2251
2302
  *
2252
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4159-8584
2303
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025-26?node-id=4159-8714
2253
2304
  *
2254
2305
  * @example
2255
2306
  * ```tsx
@@ -2264,11 +2315,22 @@ const Shortcut = styled('span')(({ theme }) => ({
2264
2315
  *
2265
2316
  * // Disabled state
2266
2317
  * <NeoMenuItem disabled>Disabled item</NeoMenuItem>
2318
+ *
2319
+ * // As an anchor — middle-click/right-click open in a new tab
2320
+ * <NeoMenuItem href="/api-explorer">API explorer</NeoMenuItem>
2321
+ *
2322
+ * // External link
2323
+ * <NeoMenuItem href="https://docs.example.com" target="_blank" rel="noopener noreferrer">
2324
+ * Documentation
2325
+ * </NeoMenuItem>
2326
+ *
2327
+ * // Client-side routing (Next.js)
2328
+ * <NeoMenuItem component={NextLink} href="/api-explorer">API explorer</NeoMenuItem>
2267
2329
  * ```
2268
2330
  */
2269
- const NeoMenuItem = ({ icon, shortcut, secondaryText, children, ...props }) => {
2270
- return (jsx(StyledMenuItem, { ...props, children: jsxs(MenuItemContent, { children: [icon && jsx(IconWrapper$1, { children: icon }), jsxs(LabelContainer$3, { children: [jsx(Label$3, { children: children }), secondaryText && jsx(SecondaryLabel, { children: secondaryText })] }), shortcut && jsx(Shortcut, { children: shortcut })] }) }));
2271
- };
2331
+ function NeoMenuItem({ icon, shortcut, secondaryText, children, ...rest }) {
2332
+ return (jsx(StyledMenuItem, { ...rest, children: jsxs(MenuItemContent, { children: [icon && jsx(IconWrapper$1, { children: icon }), jsxs(LabelContainer$3, { children: [jsx(Label$3, { children: children }), secondaryText && jsx(SecondaryLabel, { children: secondaryText })] }), shortcut && jsx(Shortcut, { children: shortcut })] }) }));
2333
+ }
2272
2334
  NeoMenuItem.displayName = 'NeoMenuItem';
2273
2335
 
2274
2336
  /**
@@ -2544,56 +2606,24 @@ function SortedAscendingIcon() {
2544
2606
  function UnsortedIcon() {
2545
2607
  return jsx(ChevronsUpDown, { size: 16, color: semanticColors.icons.utility });
2546
2608
  }
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
- */
2609
+
2582
2610
  const getDataGridHeaderStyles = () => {
2583
2611
  return {
2584
2612
  // Header cell container styles - from Figma: bg, border, padding
2585
2613
  // Height is set via density-specific selectors in DataGrid.tsx
2586
2614
  [`& .${gridClasses.columnHeader}`]: {
2587
- backgroundColor: colors.grey[50],
2615
+ backgroundColor: semanticColors.surfaces.dataGrid.header,
2588
2616
  borderBottom: `1px solid ${semanticColors.border.primary}`,
2589
- paddingLeft: `${spacing.spacing_3}px`,
2590
- paddingRight: `${spacing.spacing_3}px`,
2617
+ paddingTop: `${spacing.spacing_1_1_2}px`,
2618
+ paddingBottom: `${spacing.spacing_1_1_2}px`,
2619
+ paddingLeft: `${spacing.spacing_2}px`,
2620
+ paddingRight: `${spacing.spacing_2}px`,
2591
2621
  boxSizing: 'border-box',
2592
2622
  },
2593
2623
  // Style the filler element to match header
2594
2624
  // Height is set via density-specific selectors in DataGrid.tsx
2595
2625
  [`& .${gridClasses.filler}`]: {
2596
- backgroundColor: colors.grey[50],
2626
+ backgroundColor: semanticColors.surfaces.dataGrid.header,
2597
2627
  borderBottom: `1px solid ${semanticColors.border.primary}`,
2598
2628
  boxSizing: 'border-box',
2599
2629
  },
@@ -2625,12 +2655,19 @@ const getDataGridHeaderStyles = () => {
2625
2655
  },
2626
2656
  },
2627
2657
  },
2658
+ // MUI clips this container when header vertical padding leaves < 16px of content
2659
+ // area (e.g. compact: 38px − 24px padding = 14px). overflow:visible lets the
2660
+ // sort icon render at full 16px without being cropped.
2661
+ [`& .${gridClasses.columnHeaderTitleContainer}`]: {
2662
+ overflow: 'visible',
2663
+ lineHeight: 1,
2664
+ },
2628
2665
  // Style MUI's sort icon to match Neo design (16x16)
2629
2666
  [`& .${gridClasses.iconButtonContainer}`]: {
2630
2667
  width: 16,
2631
2668
  height: 16,
2632
2669
  marginLeft: `${spacing.spacing_1_2}px`,
2633
- [`& .${checkboxClasses.root}`]: {
2670
+ '& button': {
2634
2671
  padding: 0,
2635
2672
  width: 16,
2636
2673
  height: 16,
@@ -2643,6 +2680,20 @@ const getDataGridHeaderStyles = () => {
2643
2680
  },
2644
2681
  };
2645
2682
  };
2683
+ const getDataGridRowStyles = () => ({
2684
+ [`& .${gridClasses.row}`]: {
2685
+ backgroundColor: semanticColors.surfaces.dataGrid.default,
2686
+ },
2687
+ [`& .${gridClasses.row}:hover`]: {
2688
+ backgroundColor: semanticColors.surfaces.dataGrid.hover,
2689
+ },
2690
+ [`& .${gridClasses.row}.Mui-selected`]: {
2691
+ backgroundColor: semanticColors.surfaces.dataGrid.selected,
2692
+ },
2693
+ [`& .${gridClasses.row}.Mui-selected:hover`]: {
2694
+ backgroundColor: semanticColors.surfaces.dataGrid.selectedHover,
2695
+ },
2696
+ });
2646
2697
 
2647
2698
  /**
2648
2699
  * Adapter to use NeoCheckbox in DataGrid's baseCheckbox slot
@@ -2677,7 +2728,7 @@ const DataGridCheckbox = ({ slotProps, ...props }) => (jsx(NeoCheckbox, { size:
2677
2728
  * - `size` → Row heights (compact: 42px, standard: 48px, comfortable: 56px) and header heights (compact: 38px, standard: 44px, comfortable: 52px)
2678
2729
  *
2679
2730
  * Design tokens used:
2680
- * - Colors: semanticColors.border.primary, semanticColors.background.*
2731
+ * - Colors: semanticColors.border.primary, semanticColors.surfaces.dataGrid.*
2681
2732
  * - Typography: typography.fontFamily.body, typography.fontSize.sm
2682
2733
  * - Spacing: spacing.spacing_*
2683
2734
  *
@@ -2721,19 +2772,22 @@ function NeoDataGrid({ autoHeight = false, toolbar, slots, sx, density = 'standa
2721
2772
  // See: https://github.com/mui/mui-x/issues/20107
2722
2773
  // This must be set to prevent scroll shadow artifacts
2723
2774
  [`& .${gridClasses.main}`]: {
2724
- backgroundColor: semanticColors.surfaces.white,
2775
+ backgroundColor: semanticColors.surfaces.dataGrid.background,
2725
2776
  },
2726
2777
  // White background for empty/loading overlays
2727
2778
  [`& .${gridClasses.overlay}`]: {
2728
- backgroundColor: semanticColors.surfaces.white,
2779
+ backgroundColor: semanticColors.surfaces.dataGrid.background,
2729
2780
  },
2730
2781
  ...getDataGridHeaderStyles(),
2782
+ ...getDataGridRowStyles(),
2731
2783
  border: `1px solid ${semanticColors.border.secondary}`,
2732
- // Style row selection checkboxes to match header (16px, proper spacing)
2784
+ // Style row selection checkboxes to match header (16px, proper spacing).
2785
+ // Target `& svg` (not `.MuiSvgIcon-root`) so the rule also matches the
2786
+ // lucide `<svg>` icons NeoCheckbox renders, mirroring the header rule.
2733
2787
  [`& .${gridClasses.cellCheckbox}`]: {
2734
2788
  [`& .${checkboxClasses.root}`]: {
2735
2789
  padding: `${spacing.spacing_1}px`,
2736
- [`& .${svgIconClasses.root}`]: {
2790
+ '& svg': {
2737
2791
  width: 16,
2738
2792
  height: 16,
2739
2793
  },
@@ -2782,7 +2836,7 @@ function NeoDataGridColumnsButton() {
2782
2836
  }
2783
2837
  NeoDataGridColumnsButton.displayName = 'NeoDataGridColumnsButton';
2784
2838
 
2785
- const sizeStyles = {
2839
+ const sizeStyles$1 = {
2786
2840
  small: {
2787
2841
  height: 16,
2788
2842
  minWidth: 16,
@@ -2848,16 +2902,18 @@ const filledColorStyles = {
2848
2902
  violet: colors.violet[500],
2849
2903
  beta: colors.digitalBlue[300],
2850
2904
  };
2851
- const StyledChip$1 = styled(Chip)(({ theme, size, variant, color }) => ({
2905
+ const StyledChip$2 = styled(Chip)(({ theme, size, variant, color }) => ({
2852
2906
  padding: 0,
2853
2907
  boxSizing: 'border-box',
2854
2908
  borderRadius: borderRadius.full,
2855
2909
  fontSize: theme.typography.pxToRem(typography.fontSize.xs),
2856
2910
  lineHeight: 1,
2857
2911
  fontWeight: typography.fontWeight.medium,
2858
- ...(size && sizeStyles[size]),
2912
+ overflow: 'visible',
2913
+ ...(size && sizeStyles$1[size]),
2859
2914
  [`& .${chipClasses.label}`]: {
2860
2915
  padding: 0,
2916
+ overflow: 'visible',
2861
2917
  },
2862
2918
  ...(variant === 'outlined' &&
2863
2919
  color &&
@@ -2882,7 +2938,7 @@ const StyledChip$1 = styled(Chip)(({ theme, size, variant, color }) => ({
2882
2938
  * - TEXT Label → label prop
2883
2939
  */
2884
2940
  function NeoTag({ size = 'small', variant = 'outlined', intent = 'default', ...props }) {
2885
- return jsx(StyledChip$1, { size: size, variant: variant, color: intent, ...props });
2941
+ return jsx(StyledChip$2, { size: size, variant: variant, color: intent, ...props });
2886
2942
  }
2887
2943
  NeoTag.displayName = 'NeoTag';
2888
2944
 
@@ -2941,7 +2997,7 @@ const LabelContainer$2 = styled('div')({
2941
2997
  alignItems: 'center',
2942
2998
  gap: `${spacing.spacing_1_2}px`,
2943
2999
  });
2944
- const LabelText = styled('p')({
3000
+ const LabelText$1 = styled('p')({
2945
3001
  fontFamily: `${typography.fontFamily.body}, sans-serif`,
2946
3002
  fontSize: typography.fontSize.sm,
2947
3003
  fontWeight: typography.fontWeight.semiBold, // Always semiBold (600)
@@ -2970,7 +3026,7 @@ const IconWrapper = styled('div')({
2970
3026
  },
2971
3027
  });
2972
3028
  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, {}) }) }))] }));
3029
+ 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
3030
  }
2975
3031
 
2976
3032
  /**
@@ -3508,7 +3564,8 @@ const StyledNavButton = styled(IconButton, {
3508
3564
  */
3509
3565
  const NeoIconButton = ({ size = 'medium', variant = 'tertiary', active = false, loading, children, ...props }) => {
3510
3566
  if (variant === 'nav') {
3511
- return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...props, children: children }));
3567
+ const { color, ...navProps } = props;
3568
+ return (jsx(StyledNavButton, { size: size, active: active, disableRipple: true, ...navProps, children: children }));
3512
3569
  }
3513
3570
  return (jsx(StyledIconOnlyButton, { variant: variant, size: size, loading: loading, ...props, children: children }));
3514
3571
  };
@@ -3761,6 +3818,20 @@ const NeoDatePicker = ({ type = 'single', open, label, value, rangeValue, onChan
3761
3818
  };
3762
3819
  NeoDatePicker.displayName = 'NeoDatePicker';
3763
3820
 
3821
+ /**
3822
+ * NeoDatePickerListItem
3823
+ *
3824
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8521
3825
+ */
3826
+ const NeoDatePickerListItem = styled('div')({});
3827
+
3828
+ /**
3829
+ * NeoDatePickerMenu
3830
+ *
3831
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4176-8593
3832
+ */
3833
+ const NeoDatePickerMenu = styled('div')({});
3834
+
3764
3835
  const StyledDivider = styled(Divider)(({ theme }) => ({
3765
3836
  borderColor: semanticColors.border.secondary,
3766
3837
  marginTop: theme.spacing(1),
@@ -3801,26 +3872,34 @@ const sizeMap = {
3801
3872
  medium: 10,
3802
3873
  large: 12,
3803
3874
  };
3804
- const StyledBadge = styled(Badge)(({ ownerState }) => {
3875
+ const StyledDot = styled('span', {
3876
+ shouldForwardProp: prop => prop !== 'ownerState',
3877
+ })(({ ownerState }) => {
3805
3878
  const size = sizeMap[ownerState.size];
3806
- const color = semanticColors.status[ownerState.color].default;
3879
+ const palette = semanticColors.status[ownerState.color];
3807
3880
  return {
3808
- [`& .${badgeClasses.badge}`]: {
3809
- width: size,
3810
- height: size,
3811
- minWidth: size,
3812
- borderRadius: ownerState.variant === 'solid' ? '50%' : 0,
3813
- padding: 0,
3814
- backgroundColor: ownerState.variant === 'solid' ? color : 'transparent',
3815
- // Remove default badge positioning - make it standalone
3816
- position: 'static',
3817
- transform: 'none',
3818
- overflow: 'visible',
3881
+ display: 'inline-flex',
3882
+ alignItems: 'center',
3883
+ justifyContent: 'center',
3884
+ width: size,
3885
+ height: size,
3886
+ minWidth: size,
3887
+ borderRadius: '50%',
3888
+ flexShrink: 0,
3889
+ boxSizing: 'border-box',
3890
+ backgroundColor: palette.default,
3891
+ color: semanticColors.typography.tooltip,
3892
+ ...(ownerState.variant === 'outline' && {
3893
+ border: `3px solid ${palette.light}`,
3894
+ }),
3895
+ '& > svg': {
3896
+ width: '70%',
3897
+ height: '70%',
3819
3898
  },
3820
3899
  };
3821
3900
  });
3822
3901
  /**
3823
- * NeoDot - Status indicator dot component based on MUI Badge
3902
+ * NeoDot - Status indicator dot.
3824
3903
  *
3825
3904
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4163-3577
3826
3905
  *
@@ -3829,26 +3908,8 @@ const StyledBadge = styled(Badge)(({ ownerState }) => {
3829
3908
  * - outline (False|True) → variant prop (solid|outline)
3830
3909
  * - Color is configurable via color prop (success|error|warning|info|neutral)
3831
3910
  */
3832
- const NeoDot = ({ size = 'medium', variant = 'solid', color = 'neutral', ...props }) => {
3833
- const dotSize = sizeMap[size];
3834
- const mediumColor = semanticColors.status[color].default;
3835
- const lightColor = semanticColors.status[color].light;
3836
- // For outline variant, use SVG for precise control
3837
- const renderDot = () => {
3838
- if (variant === 'outline') {
3839
- // SVG approach: outer circle with light fill, inner circle with medium fill
3840
- // Stroke width of ~3px creates the ring effect
3841
- const strokeWidth = 3;
3842
- const radius = dotSize / 2;
3843
- const innerRadius = radius - strokeWidth;
3844
- return (jsxs("svg", { width: dotSize, height: dotSize, viewBox: `0 0 ${dotSize} ${dotSize}`, style: {
3845
- display: 'block',
3846
- borderRadius: '50%',
3847
- }, role: "img", "aria-label": `${color} status indicator`, children: [jsx("title", { children: `${color} status indicator` }), jsx("circle", { cx: radius, cy: radius, r: radius, fill: lightColor }), jsx("circle", { cx: radius, cy: radius, r: innerRadius, fill: mediumColor })] }));
3848
- }
3849
- return jsx("span", { style: { display: 'inline-block', width: 0, height: 0 } });
3850
- };
3851
- return (jsx(StyledBadge, { ...props, ownerState: { size, variant, color }, variant: "dot", children: renderDot() }));
3911
+ const NeoDot = ({ size = 'medium', variant = 'solid', color = 'neutral', children, ...props }) => {
3912
+ return (jsx(StyledDot, { ...props, ownerState: { size, variant, color }, role: "img", "aria-label": props['aria-label'] ?? `${color} status indicator`, children: children }));
3852
3913
  };
3853
3914
  NeoDot.displayName = 'NeoDot';
3854
3915
 
@@ -3930,8 +3991,57 @@ const NeoDownloadToast = ({ title, fileName, progress, showClose = true, showPau
3930
3991
  };
3931
3992
  NeoDownloadToast.displayName = 'NeoDownloadToast';
3932
3993
 
3994
+ const buildFilledIcon = ({ displayName, fillColor, body, knockout }) => {
3995
+ const Component = (props) => (jsxs(SvgIcon, { viewBox: "0 0 16 16", ...props, children: [jsx("g", { fill: fillColor, children: body }), jsx("g", { stroke: "#FFFFFF", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", fill: "none", children: knockout })] }));
3996
+ Component.displayName = displayName;
3997
+ return Component;
3998
+ };
3999
+ const CIRCLE_BODY = (jsx("path", { d: "M8.00001 14.6666C11.6819 14.6666 14.6667 11.6818 14.6667 7.99992C14.6667 4.31802 11.6819 1.33325 8.00001 1.33325C4.31811 1.33325 1.33334 4.31802 1.33334 7.99992C1.33334 11.6818 4.31811 14.6666 8.00001 14.6666Z" }));
4000
+ const NeoFilledSuccess = buildFilledIcon({
4001
+ displayName: 'NeoFilledSuccess',
4002
+ fillColor: '#3B8948',
4003
+ body: CIRCLE_BODY,
4004
+ knockout: jsx("path", { d: "M6 8.00008L7.33333 9.33341L10 6.66675" }),
4005
+ });
4006
+ const NeoFilledQueued = buildFilledIcon({
4007
+ displayName: 'NeoFilledQueued',
4008
+ fillColor: '#992FB9',
4009
+ body: CIRCLE_BODY,
4010
+ knockout: jsx("path", { d: "M8 4V8L10.6667 9.33333" }),
4011
+ });
4012
+ const NeoFilledInfo = buildFilledIcon({
4013
+ displayName: 'NeoFilledInfo',
4014
+ fillColor: '#2F42FF',
4015
+ body: CIRCLE_BODY,
4016
+ knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 10.6667V8" }), jsx("path", { d: "M8 5.33325H8.00667" })] })),
4017
+ });
4018
+ const NeoFilledWarning = buildFilledIcon({
4019
+ displayName: 'NeoFilledWarning',
4020
+ fillColor: '#BD9319',
4021
+ body: (jsx("path", { d: "M14.4867 12L9.15335 2.66665C9.03706 2.46146 8.86842 2.29078 8.66463 2.17203C8.46084 2.05329 8.22921 1.99072 7.99335 1.99072C7.75749 1.99072 7.52585 2.05329 7.32206 2.17203C7.11828 2.29078 6.94964 2.46146 6.83335 2.66665L1.50001 12C1.38247 12.2036 1.32083 12.4346 1.32135 12.6697C1.32187 12.9047 1.38453 13.1355 1.50298 13.3385C1.62142 13.5416 1.79145 13.7097 1.99581 13.8259C2.20018 13.942 2.43162 14.0021 2.66668 14H13.3333C13.5673 13.9997 13.797 13.938 13.9995 13.8208C14.202 13.7037 14.3702 13.5354 14.487 13.3327C14.6039 13.1301 14.6654 12.9002 14.6653 12.6663C14.6653 12.4324 14.6036 12.2026 14.4867 12Z" })),
4022
+ knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 6V8.66667" }), jsx("path", { d: "M8 11.3333H8.00667" })] })),
4023
+ });
4024
+ const NeoFilledError = buildFilledIcon({
4025
+ displayName: 'NeoFilledError',
4026
+ fillColor: '#CB3446',
4027
+ body: (jsx("path", { d: "M10.208 1.33325C10.5616 1.33333 10.9007 1.47385 11.1507 1.72392L14.276 4.84925C14.5261 5.09924 14.6666 5.43832 14.6667 5.79192V10.2079C14.6666 10.5615 14.5261 10.9006 14.276 11.1506L11.1507 14.2759C10.9007 14.526 10.5616 14.6665 10.208 14.6666H5.79201C5.43842 14.6665 5.09933 14.526 4.84934 14.2759L1.72401 11.1506C1.47394 10.9006 1.33342 10.5615 1.33334 10.2079V5.79192C1.33342 5.43832 1.47394 5.09924 1.72401 4.84925L4.84934 1.72392C5.09933 1.47385 5.43842 1.33333 5.79201 1.33325H10.208Z" })),
4028
+ knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M8 5.33325V7.99992" }), jsx("path", { d: "M8 10.6667H8.00667" })] })),
4029
+ });
4030
+ const NeoFilledNeutral = buildFilledIcon({
4031
+ displayName: 'NeoFilledNeutral',
4032
+ fillColor: '#6B7280',
4033
+ body: CIRCLE_BODY,
4034
+ knockout: jsx("path", { d: "M5.33334 8H10.6667" }),
4035
+ });
4036
+ const NeoFilledCanceled = buildFilledIcon({
4037
+ displayName: 'NeoFilledCanceled',
4038
+ fillColor: '#7B7263',
4039
+ body: CIRCLE_BODY,
4040
+ knockout: (jsxs(Fragment, { children: [jsx("path", { d: "M10 6L6 10" }), jsx("path", { d: "M6 6L10 10" })] })),
4041
+ });
4042
+
3933
4043
  const filterChipOnlyProps = ['selected', 'expanded', 'selectedLabel', 'count', 'onClear'];
3934
- const StyledChip = styled(Chip, {
4044
+ const StyledChip$1 = styled(Chip, {
3935
4045
  shouldForwardProp: prop => !filterChipOnlyProps.includes(prop),
3936
4046
  })(({ theme, selected }) => ({
3937
4047
  borderRadius: borderRadius.full,
@@ -4021,7 +4131,7 @@ const CountBadge = styled('span')(({ theme }) => ({
4021
4131
  */
4022
4132
  const NeoFilterChip = ({ label, selected = false, expanded, selectedLabel, count = 0, onClear, onClick, ...props }) => {
4023
4133
  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 }));
4134
+ 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
4135
  };
4026
4136
  NeoFilterChip.displayName = 'NeoFilterChip';
4027
4137
 
@@ -4062,6 +4172,7 @@ const StyledFooter = styled(Box, {
4062
4172
  shouldForwardProp: prop => prop !== 'showShadow',
4063
4173
  })(({ theme, showShadow = false }) => ({
4064
4174
  backgroundColor: semanticColors.surfaces.white,
4175
+ borderTop: `1px solid ${semanticColors.border.primary}`,
4065
4176
  display: 'flex',
4066
4177
  alignItems: 'center',
4067
4178
  justifyContent: 'center',
@@ -4387,13 +4498,7 @@ function NeoInfiniteScrollGrid({ onLoadMore, hasNextPage = true, loadMoreAtScrol
4387
4498
  showShadow: isScrolling,
4388
4499
  ...userSlotProps?.footer,
4389
4500
  },
4390
- }, sx: {
4391
- // Add border at bottom of rows section (above footer)
4392
- [`& .${gridClasses.virtualScrollerContent}`]: {
4393
- borderBottom: `1px solid ${semanticColors.border.primary}`,
4394
- },
4395
- ...userSx,
4396
- }, pagination: false, ...props,
4501
+ }, sx: userSx, pagination: false, ...props,
4397
4502
  // Only show loading overlay when loading AND no rows exist yet
4398
4503
  // This keeps existing rows visible while loading more data (footer shows loading spinner)
4399
4504
  loading: props.loading && !hasRows }));
@@ -4819,87 +4924,127 @@ const NeoListItem = ({ size = 'medium', primaryText, secondaryText, badge, icon,
4819
4924
  };
4820
4925
  NeoListItem.displayName = 'NeoListItem';
4821
4926
 
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,
4927
+ const StyledListItemButton = styled(ListItemButton, {
4928
+ shouldForwardProp: prop => prop !== 'listVariant',
4929
+ })(({ theme, listVariant = 'card' }) => listVariant === 'nav' ? navVariantStyles(theme) : cardVariantStyles(theme));
4930
+ // Nav variant — sidebar list item: no border, compact, subtle highlights.
4931
+ // Renders children inline; no ListItemIcon/ListItemText wrappers required.
4932
+ function navVariantStyles(theme) {
4933
+ return {
4934
+ display: 'flex',
4935
+ alignItems: 'center',
4936
+ gap: spacing.spacing_2,
4937
+ borderRadius: borderRadius.s,
4938
+ paddingTop: spacing.spacing_1,
4939
+ paddingBottom: spacing.spacing_1,
4940
+ paddingLeft: spacing.spacing_2,
4941
+ paddingRight: spacing.spacing_2,
4942
+ border: 'none',
4943
+ color: semanticColors.typography.bodySecondary,
4944
+ backgroundColor: 'transparent',
4945
+ transition: theme.transitions.create(['background-color', 'color']),
4946
+ [`&.${listItemButtonClasses.selected}`]: {
4947
+ backgroundColor: semanticColors.surfaces.activeHighlight,
4948
+ color: semanticColors.typography.body,
4949
+ '&:hover': {
4950
+ backgroundColor: semanticColors.surfaces.activeHighlight,
4951
+ },
4848
4952
  },
4849
- // Text colors in selected state
4850
- [`& .${listItemTextClasses.primary}`]: {
4851
- color: colors.grey[800],
4953
+ [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
4954
+ '&:hover': {
4955
+ backgroundColor: semanticColors.surfaces.listHover,
4956
+ color: semanticColors.typography.body,
4957
+ },
4852
4958
  },
4853
- [`& .${listItemTextClasses.secondary}`]: {
4854
- color: semanticColors.typography.bodySecondary,
4959
+ [`&.${listItemButtonClasses.focusVisible}`]: {
4960
+ outline: `2px solid ${semanticColors.border.focus}`,
4961
+ outlineOffset: -2,
4855
4962
  },
4856
- },
4857
- // Deselected (default) state
4858
- [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
4859
- '&:hover': {
4860
- backgroundColor: colors.grey[50],
4861
- },
4862
- [`& .${listItemIconClasses.root}`]: {
4863
- color: semanticColors.icons.disabled,
4864
- },
4865
- [`& .${listItemTextClasses.primary}`]: {
4866
- color: semanticColors.buttons.tertiary.disabled,
4867
- },
4868
- [`& .${listItemTextClasses.secondary}`]: {
4963
+ [`&.${listItemButtonClasses.disabled}`]: {
4869
4964
  color: semanticColors.typography.button.disabled,
4965
+ opacity: 1,
4870
4966
  },
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}`,
4967
+ };
4968
+ }
4969
+ function cardVariantStyles(theme) {
4970
+ return {
4971
+ display: 'flex',
4972
+ alignItems: 'center',
4973
+ gap: spacing.spacing_2,
4974
+ borderRadius: borderRadius.m,
4975
+ paddingTop: spacing.spacing_1,
4976
+ paddingBottom: spacing.spacing_1,
4977
+ paddingLeft: spacing.spacing_3_4,
4978
+ paddingRight: spacing.spacing_3_4,
4979
+ border: `1px solid ${semanticColors.border.primary}`,
4877
4980
  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,
4981
+ transition: theme.transitions.create(['border', 'background-color']),
4982
+ // Active (selected) state
4983
+ [`&.${listItemButtonClasses.selected}`]: {
4984
+ border: `2px solid ${semanticColors.buttons.primary.default}`,
4985
+ backgroundColor: theme.palette.common.white,
4986
+ '&:hover': {
4987
+ backgroundColor: theme.palette.common.white,
4988
+ },
4989
+ // Icon color in selected state
4990
+ [`& .${listItemIconClasses.root}`]: {
4991
+ color: semanticColors.icons.default,
4992
+ },
4993
+ // Text colors in selected state
4994
+ [`& .${listItemTextClasses.primary}`]: {
4995
+ color: colors.grey[800],
4996
+ },
4997
+ [`& .${listItemTextClasses.secondary}`]: {
4998
+ color: semanticColors.typography.bodySecondary,
4999
+ },
4886
5000
  },
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,
5001
+ // Deselected (default) state
5002
+ [`&:not(.${listItemButtonClasses.selected}):not(.${listItemButtonClasses.disabled})`]: {
5003
+ '&:hover': {
5004
+ backgroundColor: colors.grey[50],
5005
+ },
5006
+ [`& .${listItemIconClasses.root}`]: {
5007
+ color: semanticColors.icons.disabled,
5008
+ },
5009
+ [`& .${listItemTextClasses.primary}`]: {
5010
+ color: semanticColors.buttons.tertiary.disabled,
5011
+ },
5012
+ [`& .${listItemTextClasses.secondary}`]: {
5013
+ color: semanticColors.typography.button.disabled,
5014
+ },
4894
5015
  },
4895
- [`& .${listItemTextClasses.primary}`]: {
4896
- color: colors.grey[300],
5016
+ // Focus state
5017
+ [`&.${listItemButtonClasses.focusVisible}`]: {
5018
+ outline: `2px solid ${semanticColors.buttons.primary.default}`,
5019
+ outlineOffset: 2,
5020
+ border: `2px solid ${semanticColors.buttons.primary.default}`,
5021
+ backgroundColor: theme.palette.common.white,
5022
+ [`& .${listItemIconClasses.root}`]: {
5023
+ color: semanticColors.icons.default,
5024
+ },
5025
+ [`& .${listItemTextClasses.primary}`]: {
5026
+ color: colors.grey[800],
5027
+ },
5028
+ [`& .${listItemTextClasses.secondary}`]: {
5029
+ color: semanticColors.typography.bodySecondary,
5030
+ },
4897
5031
  },
4898
- [`& .${listItemTextClasses.secondary}`]: {
4899
- color: colors.grey[300],
5032
+ // Disabled state
5033
+ [`&.${listItemButtonClasses.disabled}`]: {
5034
+ backgroundColor: colors.grey[50],
5035
+ opacity: 1, // Override MUI default opacity
5036
+ [`& .${listItemIconClasses.root}`]: {
5037
+ color: semanticColors.icons.disabled,
5038
+ },
5039
+ [`& .${listItemTextClasses.primary}`]: {
5040
+ color: colors.grey[300],
5041
+ },
5042
+ [`& .${listItemTextClasses.secondary}`]: {
5043
+ color: colors.grey[300],
5044
+ },
4900
5045
  },
4901
- },
4902
- }));
5046
+ };
5047
+ }
4903
5048
  /**
4904
5049
  * NeoListItemButton - Selectable list item with icon and text
4905
5050
  *
@@ -4943,8 +5088,8 @@ const StyledListItemButton = styled(ListItemButton)(({ theme }) => ({
4943
5088
  * - colors.grey[300] (#d1d5db) - Disabled text
4944
5089
  * - colors.grey[50] (#f9fafb) - Disabled background
4945
5090
  */
4946
- const NeoListItemButton = ({ children, selected = false, disabled = false, ...props }) => {
4947
- return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, ...props, children: children }));
5091
+ const NeoListItemButton = ({ children, selected = false, disabled = false, variant = 'card', ...props }) => {
5092
+ return (jsx(StyledListItemButton, { selected: selected, disabled: disabled, listVariant: variant, ...props, children: children }));
4948
5093
  };
4949
5094
  NeoListItemButton.displayName = 'NeoListItemButton';
4950
5095
 
@@ -4954,7 +5099,6 @@ const StyledMenu = styled(Menu)(({ theme }) => ({
4954
5099
  borderRadius: borderRadius.s,
4955
5100
  border: `1px solid ${semanticColors.border.primary}`,
4956
5101
  boxShadow: `${shadows.dropdown.x}px ${shadows.dropdown.y}px ${shadows.dropdown.blur}px ${shadows.dropdown.spread}px ${shadows.dropdown.shadow}`,
4957
- minWidth: 200,
4958
5102
  marginTop: theme.spacing(1),
4959
5103
  paddingTop: theme.spacing(1),
4960
5104
  paddingBottom: theme.spacing(1),
@@ -5181,9 +5325,8 @@ NeoModalFooter.displayName = 'NeoModalFooter';
5181
5325
  const NavigationAvatarContainer = styled('div')({
5182
5326
  display: 'flex',
5183
5327
  boxSizing: 'border-box',
5184
- width: spacing.spacing_5_1_2,
5185
- height: spacing.spacing_5_1_2,
5186
- padding: spacing.spacing_3_4,
5328
+ padding: spacing.spacing_1_2,
5329
+ aspectRatio: '1 / 1',
5187
5330
  justifyContent: 'center',
5188
5331
  alignItems: 'center',
5189
5332
  borderRadius: '50%',
@@ -5196,16 +5339,103 @@ const NavigationAvatarContainer = styled('div')({
5196
5339
  /**
5197
5340
  * NeoNavigationAvatar - Compact avatar for navigation contexts
5198
5341
  *
5199
- * Wraps NeoGeneralAvatar (size="small") in a 44px container with 6px padding,
5200
- * providing a larger interactive area for navigation UI.
5342
+ * Wraps NeoGeneralAvatar (size="small") in a 40px container,
5343
+ * providing an interactive area for navigation UI.
5201
5344
  *
5202
5345
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11325-102
5203
5346
  */
5204
- const NeoNavigationAvatar = ({ colorIndex = 0, children, ...props }) => {
5205
- return (jsx(NavigationAvatarContainer, { children: jsx(NeoGeneralAvatar, { size: "small", colorIndex: colorIndex, ...props, children: children }) }));
5347
+ const NeoNavigationAvatar = ({ children, ...props }) => {
5348
+ return (jsx(NavigationAvatarContainer, { children: jsx(NeoGeneralAvatar, { size: "small", ...props, children: children }) }));
5206
5349
  };
5207
5350
  NeoNavigationAvatar.displayName = 'NeoNavigationAvatar';
5208
5351
 
5352
+ const NeoSideNavContext = createContext({
5353
+ collapsed: false,
5354
+ });
5355
+ const useNeoSideNav = () => useContext(NeoSideNavContext);
5356
+
5357
+ /**
5358
+ * Variant color configuration
5359
+ */
5360
+ const variantConfig = {
5361
+ light: {
5362
+ backgroundColor: semanticColors.surfaces.tooltip, // #4b5563 - medium gray
5363
+ color: semanticColors.typography.tooltip, // #ffffff - white
5364
+ },
5365
+ dark: {
5366
+ backgroundColor: colors.grey[50], // #f9fafb - very light gray
5367
+ color: colors.grey[800], // #1f2937 - dark gray
5368
+ },
5369
+ brand: {
5370
+ backgroundColor: colors.digitalBlue[800], // #131e7a - dark blue
5371
+ color: semanticColors.typography.tooltip, // #ffffff - white
5372
+ },
5373
+ };
5374
+ /**
5375
+ * Styled MUI Tooltip with Neo design system tokens
5376
+ */
5377
+ const StyledTooltip$1 = styled(Tooltip, {
5378
+ shouldForwardProp: prop => prop !== 'variant' && prop !== 'description',
5379
+ })(({ variant = 'light', description }) => {
5380
+ const hasDescription = Boolean(description);
5381
+ const variantStyles = variantConfig[variant];
5382
+ return {
5383
+ // Style the tooltip content
5384
+ [`& .${tooltipClasses.tooltip}`]: {
5385
+ backgroundColor: variantStyles.backgroundColor,
5386
+ color: variantStyles.color,
5387
+ fontSize: typography.fontSize.xs,
5388
+ fontWeight: typography.fontWeight.medium,
5389
+ lineHeight: hasDescription ? 1.5 : 1,
5390
+ borderRadius: hasDescription ? borderRadius.s : borderRadius.xS,
5391
+ padding: hasDescription ? spacing.spacing_1_1_2 : `0 ${spacing.spacing_1}px`,
5392
+ ...(hasDescription && {
5393
+ maxWidth: 296,
5394
+ }),
5395
+ ...(!hasDescription && {
5396
+ height: spacing.spacing_3_1_4,
5397
+ display: 'flex',
5398
+ alignItems: 'center',
5399
+ justifyContent: 'center',
5400
+ }),
5401
+ boxShadow: `${shadows.neutral.medium.x}px ${shadows.neutral.medium.y}px ${shadows.neutral.medium.blur}px ${shadows.neutral.medium.spread}px ${shadows.neutral.medium.shadow}`,
5402
+ },
5403
+ // Style the arrow
5404
+ [`& .${tooltipClasses.arrow}`]: {
5405
+ color: variantStyles.backgroundColor,
5406
+ },
5407
+ };
5408
+ });
5409
+ /**
5410
+ * NeoTooltip - Tooltip component following Neo design system
5411
+ *
5412
+ * Provides contextual information when users hover over or focus on an element.
5413
+ * Supports three visual variants (light, dark, brand) and optional supporting text.
5414
+ *
5415
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4091-26557&t=Bo58EpFmg6ILJtmv-11
5416
+ *
5417
+ * Figma Props Mapping:
5418
+ * - Theme (Light mode|Dark mode|Brand color) → variant ('light'|'dark'|'brand')
5419
+ * - Placement → arrow (boolean) + placement (top/bottom/left/right/etc)
5420
+ * - Supporting text (True|False) → description (string|undefined)
5421
+ * - text → title (string, literal content)
5422
+ *
5423
+ * Design Tokens Used:
5424
+ * - Light: surfaces.tooltip (#4b5563), typography.tooltip (#ffffff)
5425
+ * - Dark: grey[50] (#f9fafb), grey[800] (#1f2937)
5426
+ * - Brand: digitalBlue[800] (#131e7a), typography.tooltip (#ffffff)
5427
+ * - Shadow: neutralMedium (0px 8px 15px 0px rgba(31,41,55,0.1))
5428
+ * - Typography: fontSize.xs (12), fontSize.caption (13), fontWeight.medium (500), fontWeight.semiBold (600)
5429
+ */
5430
+ const NeoTooltip = ({ variant = 'light', title, description, children, arrow = false, placement, ...props }) => {
5431
+ // Build the title content
5432
+ // If description is provided, create a structured layout with title + description
5433
+ // Otherwise, just show the title text
5434
+ const titleContent = description ? (jsxs(Stack, { gap: 0.5, children: [jsx(Typography, { fontSize: typography.fontSize.caption, fontWeight: typography.fontWeight.semiBold, children: title }), jsx(Typography, { fontSize: typography.fontSize.xs, fontWeight: typography.fontWeight.medium, sx: { opacity: 0.75 }, children: description })] })) : (title);
5435
+ return (jsx(StyledTooltip$1, { variant: variant, description: description, title: titleContent, arrow: arrow, placement: placement, ...props, children: children }));
5436
+ };
5437
+ NeoTooltip.displayName = 'NeoTooltip';
5438
+
5209
5439
  const customProps = ['selected'];
5210
5440
  const StyledRoot = styled(ButtonBase, {
5211
5441
  shouldForwardProp: prop => !customProps.includes(prop),
@@ -5224,41 +5454,34 @@ const StyledRoot = styled(ButtonBase, {
5224
5454
  textDecoration: 'none',
5225
5455
  '&:hover .neo-nav-icon-padding': {
5226
5456
  backgroundColor: semanticColors.buttons.secondary.hoverBackground,
5227
- borderColor: colors.digitalBlue[100],
5457
+ borderColor: semanticColors.buttons.secondary.pressedBackground,
5228
5458
  },
5229
5459
  '&:hover .neo-nav-label': {
5230
5460
  color: semanticColors.buttons.primary.hover,
5231
5461
  },
5462
+ [`& .${chipClasses.root}`]: {
5463
+ flexShrink: 0,
5464
+ },
5232
5465
  '&:focus-visible': {
5233
- ...focusRingStyles,
5466
+ outline: 'none',
5234
5467
  },
5235
5468
  '&: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,
5469
+ ...focusRingStyles,
5241
5470
  },
5242
5471
  ...(selected && {
5243
5472
  '& .neo-nav-icon-padding': {
5244
- backgroundColor: colors.digitalBlue[100],
5473
+ backgroundColor: semanticColors.buttons.secondary.pressedBackground,
5245
5474
  },
5246
5475
  '& .neo-nav-label': {
5247
5476
  color: semanticColors.buttons.primary.pressed,
5248
5477
  fontWeight: typography.fontWeight.semiBold,
5249
5478
  },
5250
5479
  '&:hover .neo-nav-icon-padding': {
5251
- backgroundColor: colors.digitalBlue[100],
5480
+ backgroundColor: semanticColors.buttons.secondary.pressedBackground,
5252
5481
  },
5253
5482
  '&:hover .neo-nav-label': {
5254
5483
  color: semanticColors.buttons.primary.pressed,
5255
5484
  },
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
5485
  }),
5263
5486
  }));
5264
5487
  const IconPadding = styled('span')({
@@ -5279,31 +5502,314 @@ const Label$2 = styled('span')(({ theme }) => ({
5279
5502
  width: '100%',
5280
5503
  transition: 'color 150ms',
5281
5504
  }));
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
5505
  /**
5298
5506
  * NeoNavigationItem - Vertical navigation item with icon, label, and optional tag
5299
5507
  *
5300
5508
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=8455-6120
5301
5509
  */
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] }));
5510
+ function NeoNavigationItem({ icon, label, selected = false, tag, tooltip, slotProps, children, ...props }) {
5511
+ const { collapsed } = useNeoSideNav();
5512
+ // When collapsed the label is hidden, so fall back to it for the tooltip and
5513
+ // accessible name — otherwise an icon-only button has no name (WCAG 4.1.2).
5514
+ const collapsedTooltip = tooltip ?? label;
5515
+ const item = (jsxs(StyledRoot, { selected: selected, "aria-label": collapsed && typeof label === 'string' ? label : undefined, disableRipple: true, ...props, children: [jsx(IconPadding, { className: "neo-nav-icon-padding", children: icon }), !collapsed && label && jsx(Label$2, { className: "neo-nav-label", children: label }), !collapsed && tag && (jsx(NeoTag, { size: "medium", variant: "filled", intent: "beta", label: tag, ...slotProps?.badge })), children] }));
5516
+ if (collapsed && collapsedTooltip) {
5517
+ return (jsx(NeoTooltip, { title: collapsedTooltip, placement: "right", arrow: true, children: item }));
5518
+ }
5519
+ return item;
5304
5520
  }
5305
5521
  NeoNavigationItem.displayName = 'NeoNavigationItem';
5306
5522
 
5523
+ const StyledActionsCell = styled(GridActionsCell)({
5524
+ gap: spacing.spacing_1,
5525
+ paddingLeft: spacing.spacing_1_1_2,
5526
+ paddingRight: spacing.spacing_1_1_2,
5527
+ });
5528
+ function NeoActionsCell(props) {
5529
+ return jsx(StyledActionsCell, { ...props });
5530
+ }
5531
+
5532
+ const StyledCell$1 = styled('div', {
5533
+ shouldForwardProp: prop => prop !== 'disabled',
5534
+ })(({ disabled }) => ({
5535
+ display: 'flex',
5536
+ alignItems: 'center',
5537
+ gap: spacing.spacing_1, // 8px between avatar and label
5538
+ width: '100%',
5539
+ height: '100%',
5540
+ paddingLeft: spacing.spacing_1_1_2, // 12px — input-horizontal
5541
+ paddingRight: spacing.spacing_1_1_2,
5542
+ paddingTop: spacing.spacing_1_2, // 4px — input-vertical
5543
+ paddingBottom: spacing.spacing_1_2,
5544
+ backgroundColor: disabled
5545
+ ? semanticColors.surfaces.dataGrid.disabled
5546
+ : semanticColors.surfaces.dataGrid.default,
5547
+ boxSizing: 'border-box',
5548
+ }));
5549
+ const LabelText = styled('span', {
5550
+ shouldForwardProp: prop => prop !== 'disabled',
5551
+ })(({ disabled }) => ({
5552
+ overflow: 'hidden',
5553
+ textOverflow: 'ellipsis',
5554
+ whiteSpace: 'nowrap',
5555
+ fontFamily: typography.fontFamily.body,
5556
+ fontSize: typography.fontSize.xs,
5557
+ fontWeight: typography.fontWeight.regular,
5558
+ lineHeight: 1.5,
5559
+ color: disabled ? semanticColors.typography.bodySecondary : semanticColors.typography.body,
5560
+ }));
5561
+ /**
5562
+ * NeoAvatarCell — DataGrid cell displaying a user avatar with optional label.
5563
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=13425-1725
5564
+ */
5565
+ const NeoAvatarCell = ({ name, src, label, disabled = false, empty = false, }) => {
5566
+ if (empty) {
5567
+ return jsx(StyledCell$1, { disabled: disabled });
5568
+ }
5569
+ return (jsxs(StyledCell$1, { disabled: disabled, children: [jsx(NeoGeneralAvatar, { size: "small", src: src, alt: name, children: !src && name ? name.charAt(0).toUpperCase() : undefined }), label && jsx(LabelText, { disabled: disabled, children: label })] }));
5570
+ };
5571
+ NeoAvatarCell.displayName = 'NeoAvatarCell';
5572
+
5573
+ const CellRoot = styled('div', {
5574
+ shouldForwardProp: prop => prop !== 'disabled',
5575
+ })(({ disabled }) => ({
5576
+ display: 'flex',
5577
+ alignItems: 'center',
5578
+ justifyContent: 'center',
5579
+ width: '100%',
5580
+ height: '100%',
5581
+ color: disabled ? semanticColors.icons.disabled : semanticColors.icons.default,
5582
+ }));
5583
+ /**
5584
+ * NeoIconCell — Icon cell for DataGrid. Renders an icon centered in the cell.
5585
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-9345
5586
+ */
5587
+ const NeoIconCell = ({ icon, ariaLabel, disabled = false }) => {
5588
+ if (!icon)
5589
+ return null;
5590
+ return (jsx(CellRoot, { disabled: disabled, "aria-label": ariaLabel, children: jsx(NeoIconWrapper, { size: 16, children: icon }) }));
5591
+ };
5592
+ NeoIconCell.displayName = 'NeoIconCell';
5593
+
5594
+ const CellWrapper = styled('div', {
5595
+ shouldForwardProp: prop => prop !== 'disabled',
5596
+ })(({ disabled }) => ({
5597
+ display: 'flex',
5598
+ alignItems: 'center',
5599
+ justifyContent: 'flex-start',
5600
+ width: '100%',
5601
+ height: '100%',
5602
+ paddingLeft: spacing.spacing_1,
5603
+ paddingRight: spacing.spacing_1,
5604
+ backgroundColor: disabled
5605
+ ? semanticColors.surfaces.dataGrid.disabled
5606
+ : semanticColors.surfaces.dataGrid.default,
5607
+ '& img': {
5608
+ display: 'block',
5609
+ maxHeight: 32,
5610
+ width: 'auto',
5611
+ maxWidth: '100%',
5612
+ objectFit: 'contain',
5613
+ opacity: disabled ? 0.4 : 1,
5614
+ },
5615
+ }));
5616
+ /**
5617
+ * NeoLogoCell — DataGrid cell displaying a raster or SVG logo image.
5618
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13278-9558
5619
+ *
5620
+ * Kept separate from NeoIconCell to match Neo's Icon/Logo component split:
5621
+ * - NeoIconCell: MUI SvgIcon components
5622
+ * - NeoLogoCell: raster or SVG image URLs (img tag)
5623
+ */
5624
+ const NeoLogoCell = ({ src, alt = '', disabled = false }) => {
5625
+ if (!src) {
5626
+ return jsx(CellWrapper, { disabled: disabled });
5627
+ }
5628
+ return (jsx(CellWrapper, { disabled: disabled, children: jsx(NeoIconWrapper, { size: 32, children: jsx("img", { src: src, alt: alt }) }) }));
5629
+ };
5630
+ NeoLogoCell.displayName = 'NeoLogoCell';
5631
+
5632
+ const StyledLinearProgress = styled(LinearProgress, {
5633
+ shouldForwardProp: prop => prop !== 'labelPosition',
5634
+ })(() => ({
5635
+ height: 8,
5636
+ borderRadius: borderRadius.xS,
5637
+ backgroundColor: colors.grey[200],
5638
+ [`& .${linearProgressClasses.bar}`]: {
5639
+ borderRadius: borderRadius.xS,
5640
+ backgroundColor: colors.digitalBlue[500],
5641
+ },
5642
+ [`&.${linearProgressClasses.colorPrimary}`]: {
5643
+ backgroundColor: colors.grey[200],
5644
+ [`& .${linearProgressClasses.bar}`]: {
5645
+ backgroundColor: colors.digitalBlue[500],
5646
+ },
5647
+ },
5648
+ // Cancelled variant uses warning color
5649
+ '&[data-variant="cancelled"]': {
5650
+ [`& .${linearProgressClasses.bar}`]: {
5651
+ backgroundColor: semanticColors.status.warning.default,
5652
+ },
5653
+ },
5654
+ }));
5655
+ const ProgressWrapper = styled('div')(({ labelPosition }) => ({
5656
+ display: 'flex',
5657
+ width: '100%',
5658
+ ...(labelPosition === 'right' && {
5659
+ flexDirection: 'row',
5660
+ alignItems: 'center',
5661
+ gap: spacing.spacing_3,
5662
+ }),
5663
+ ...(labelPosition === 'top' && {
5664
+ flexDirection: 'column-reverse',
5665
+ alignItems: 'flex-end',
5666
+ gap: spacing.spacing_2,
5667
+ }),
5668
+ ...(labelPosition === 'bottom' && {
5669
+ flexDirection: 'column',
5670
+ alignItems: 'flex-end',
5671
+ gap: spacing.spacing_2,
5672
+ }),
5673
+ ...(labelPosition === 'none' && {
5674
+ flexDirection: 'row',
5675
+ }),
5676
+ }));
5677
+ const ProgressLabel = styled(Typography)(({ theme }) => ({
5678
+ fontSize: theme.typography.pxToRem(typography.fontSize.sm),
5679
+ fontWeight: typography.fontWeight.medium,
5680
+ color: colors.grey[800],
5681
+ lineHeight: 1.4,
5682
+ whiteSpace: 'nowrap',
5683
+ flexShrink: 0,
5684
+ }));
5685
+ const ProgressBarContainer = styled('div')(({ labelPosition }) => ({
5686
+ flexGrow: labelPosition === 'right' ? 1 : 0,
5687
+ width: labelPosition === 'right' ? 'auto' : '100%',
5688
+ }));
5689
+ /**
5690
+ * NeoProgressbar - Linear progress indicator based on MUI LinearProgress
5691
+ *
5692
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4120-36679
5693
+ *
5694
+ * Figma Props Mapping:
5695
+ * - progress (0%-100% | Cancelled) → value (0-100) + variant (default|cancelled)
5696
+ * - label (False|Right|Top|Bottom) → labelPosition (none|right|top|bottom)
5697
+ *
5698
+ * Design Decisions (from Issue #75):
5699
+ * - MUI Base Component: LinearProgress (provides accessibility, animations, progress tracking)
5700
+ * - Label Positioning: Single labelPosition prop with values 'none', 'right', 'top', 'bottom'
5701
+ * - Cancelled State: Separate variant prop (variant='cancelled') alongside value prop
5702
+ */
5703
+ const NeoProgressbar = ({ value = 0, labelPosition = 'none', variant = 'default', labelText, ...props }) => {
5704
+ const showLabel = labelPosition !== 'none';
5705
+ const displayLabel = labelText || (variant === 'cancelled' ? 'Canceled' : `${Math.round(value)}%`);
5706
+ 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 })] }));
5707
+ };
5708
+ NeoProgressbar.displayName = 'NeoProgressbar';
5709
+
5710
+ const StyledCell = styled('div', {
5711
+ shouldForwardProp: prop => prop !== 'disabled',
5712
+ })(({ disabled }) => ({
5713
+ display: 'flex',
5714
+ alignItems: 'center',
5715
+ width: '100%',
5716
+ height: '100%',
5717
+ paddingLeft: spacing.spacing_1_1_2, // 12px input-horizontal
5718
+ paddingRight: spacing.spacing_1_1_2,
5719
+ backgroundColor: disabled
5720
+ ? semanticColors.surfaces.dataGrid.disabled
5721
+ : semanticColors.surfaces.dataGrid.default,
5722
+ boxSizing: 'border-box',
5723
+ }));
5724
+ /**
5725
+ * NeoProgressCell — DataGrid cell displaying a linear progress indicator.
5726
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13425-5378
5727
+ */
5728
+ const NeoProgressCell = ({ value = 0, disabled = false, empty = false, }) => {
5729
+ const clampedValue = Math.min(100, Math.max(0, value));
5730
+ return (jsx(StyledCell, { disabled: disabled, children: !empty && jsx(NeoProgressbar, { value: clampedValue, labelPosition: "none" }) }));
5731
+ };
5732
+ NeoProgressCell.displayName = 'NeoProgressCell';
5733
+
5734
+ const variantColors = (variant) => ({
5735
+ bg: semanticColors.status[variant].light,
5736
+ fg: semanticColors.status[variant].dark,
5737
+ border: semanticColors.status[variant].transparent,
5738
+ });
5739
+ const StyledChip = styled('div', {
5740
+ shouldForwardProp: prop => prop !== 'disabled' && prop !== 'variant',
5741
+ })(({ disabled, variant }) => {
5742
+ const colors = variantColors(variant);
5743
+ return {
5744
+ display: 'inline-flex',
5745
+ alignItems: 'center',
5746
+ gap: spacing.spacing_3_4,
5747
+ paddingTop: spacing.spacing_1_2,
5748
+ paddingBottom: spacing.spacing_1_2,
5749
+ paddingLeft: spacing.spacing_1_1_2,
5750
+ paddingRight: spacing.spacing_1_1_2,
5751
+ borderRadius: borderRadius.full,
5752
+ border: `1px solid ${disabled ? semanticColors.border.secondary : colors.border}`,
5753
+ backgroundColor: disabled ? semanticColors.surfaces.dataGrid.disabled : colors.bg,
5754
+ color: disabled ? semanticColors.icons.disabled : colors.fg,
5755
+ fontFamily: typography.fontFamily.body,
5756
+ fontSize: typography.fontSize.xs,
5757
+ fontWeight: typography.fontWeight.medium,
5758
+ lineHeight: 1,
5759
+ whiteSpace: 'nowrap',
5760
+ overflow: 'hidden',
5761
+ maxWidth: '100%',
5762
+ '& svg': {
5763
+ flexShrink: 0,
5764
+ width: '1em',
5765
+ height: '1em',
5766
+ fontSize: typography.fontSize.xs,
5767
+ },
5768
+ };
5769
+ });
5770
+ const TooltipErrorPre = styled('pre')({
5771
+ margin: 0,
5772
+ padding: 0,
5773
+ fontFamily: typography.fontFamily.code,
5774
+ fontSize: typography.fontSize.sm,
5775
+ fontWeight: typography.fontWeight.regular,
5776
+ lineHeight: 1.5,
5777
+ color: semanticColors.typography.tooltip,
5778
+ whiteSpace: 'pre-wrap',
5779
+ wordBreak: 'break-all',
5780
+ maxHeight: 200,
5781
+ overflowY: 'auto',
5782
+ });
5783
+ const StyledTooltip = styled(Tooltip)({
5784
+ [`& .${tooltipClasses.tooltip}`]: {
5785
+ backgroundColor: semanticColors.surfaces.tooltip,
5786
+ maxWidth: 400,
5787
+ padding: `${spacing.spacing_1}px ${spacing.spacing_1_1_2}px`,
5788
+ },
5789
+ [`& .${tooltipClasses.arrow}`]: {
5790
+ color: semanticColors.surfaces.tooltip,
5791
+ },
5792
+ });
5793
+ /**
5794
+ * NeoStatusCell — DataGrid cell displaying an icon + label chip with optional error tooltip.
5795
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=13272-8705
5796
+ */
5797
+ const NeoStatusCell = ({ icon, label, details, disabled = false, variant = 'success', empty = false, }) => {
5798
+ if (empty) {
5799
+ return (jsx(Box, { component: "span", sx: {
5800
+ color: semanticColors.typography.body,
5801
+ fontSize: typography.fontSize.sm,
5802
+ lineHeight: 1,
5803
+ }, children: '—' }));
5804
+ }
5805
+ const chip = (jsxs(StyledChip, { disabled: disabled, variant: variant, children: [icon, label] }));
5806
+ if (details) {
5807
+ return (jsx(StyledTooltip, { title: jsx(TooltipErrorPre, { children: details }), arrow: true, placement: "bottom-start", children: jsx(Box, { component: "span", sx: { display: 'inline-flex' }, children: chip }) }));
5808
+ }
5809
+ return chip;
5810
+ };
5811
+ NeoStatusCell.displayName = 'NeoStatusCell';
5812
+
5307
5813
  /**
5308
5814
  * Sticky header wrapper - sticks to top when scrolling
5309
5815
  */
@@ -5318,10 +5824,9 @@ const StickyHeader = styled(Box)(({ theme }) => ({
5318
5824
  * Page title typography
5319
5825
  */
5320
5826
  const PageTitle = styled(Typography)(() => ({
5321
- fontSize: typography.fontSize.h3,
5322
- fontWeight: typography.fontWeight.medium,
5827
+ ...semanticTypography.titles.pageHeader,
5323
5828
  lineHeight: 1.4,
5324
- color: colors.grey['900'], // #111827 - matches Figma typography/page-header
5829
+ color: colors.grey['900'],
5325
5830
  }));
5326
5831
  /**
5327
5832
  * Subtitle typography
@@ -5385,7 +5890,12 @@ const Subtitle = styled(Typography)(() => ({
5385
5890
  * </NeoPageContent>
5386
5891
  * ```
5387
5892
  */
5388
- function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = false, contentMaxWidth = false, centerContent = true, disableGutters = false, isLoading = false, showBackToTop = true, children, sx, ...boxProps }) {
5893
+ 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 }) {
5894
+ // fullBleed forces no max-width, no gutters, and zero bottom padding
5895
+ // so children can fill the viewport edge-to-edge.
5896
+ const isFullBleed = layout === 'fullBleed';
5897
+ const contentMaxWidth = isFullBleed ? false : contentMaxWidthProp;
5898
+ const disableGutters = isFullBleed || disableGuttersProp;
5389
5899
  const [showBackToTopButton, setShowBackToTopButton] = useState(false);
5390
5900
  const headerRef = useRef(null);
5391
5901
  const containerRef = useRef(null);
@@ -5415,7 +5925,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
5415
5925
  // Also try to scroll window in case component is in a different context
5416
5926
  window.scrollTo({ top: 0, behavior: 'smooth' });
5417
5927
  };
5418
- const headerContent = (jsxs(Stack, { ref: headerRef, sx: { flexShrink: 0, gap: '0.5rem' }, children: [breadcrumbs && breadcrumbs.items.length > 0 && (jsx(NeoBreadcrumbs, { children: breadcrumbs.items.map((item, index) => (jsx(NeoBreadcrumbLink, { href: item.href, component: item.href && breadcrumbs.linkComponent ? breadcrumbs.linkComponent : undefined, current: index === breadcrumbs.items.length - 1, children: item.label }, item.href ?? index))) })), jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "flex-start", sx: { gap: '1rem' }, children: [jsxs(Stack, { sx: { gap: '0.5rem', flexGrow: 1 }, children: [jsx(PageTitle, { children: pageTitle }), subtitle &&
5928
+ const headerContent = (jsxs(Stack, { ref: headerRef, sx: { flexShrink: 0, gap: '0.5rem' }, children: [breadcrumbs && breadcrumbs.items.length > 0 && (jsx(NeoBreadcrumbs, { children: breadcrumbs.items.map((item, index) => (jsx(NeoBreadcrumbLink, { href: item.href, component: item.href && breadcrumbs.linkComponent ? breadcrumbs.linkComponent : undefined, current: index === breadcrumbs.items.length - 1, children: item.label }, item.href ?? index))) })), jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "flex-start", sx: { gap: '1rem' }, children: [jsxs(Stack, { sx: { gap: '0.5rem', flexGrow: 1 }, children: [typeof pageTitle === 'string' ? (jsx(PageTitle, { component: "h1", children: pageTitle })) : (pageTitle), subtitle &&
5419
5929
  (typeof subtitle === 'string' ? (jsx(Subtitle, { variant: "caption", children: subtitle })) : (subtitle))] }), action] })] }));
5420
5930
  const content = isLoading ? (jsx(Box, { sx: {
5421
5931
  display: 'flex',
@@ -5437,7 +5947,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
5437
5947
  flexDirection: 'column',
5438
5948
  px: disableGutters ? 0 : `${spacing.spacing_2_1_2}px`,
5439
5949
  pt: sticky ? 0 : `${spacing.spacing_2}px`,
5440
- pb: `${spacing.spacing_2_1_2}px`,
5950
+ pb: isFullBleed ? 0 : `${spacing.spacing_2_1_2}px`,
5441
5951
  height: '100%',
5442
5952
  overflow: 'auto',
5443
5953
  }, children: [sticky ? (jsx(StickyHeader, { ref: headerRef, sx: {
@@ -5462,7 +5972,7 @@ function NeoPageContent({ pageTitle, subtitle, breadcrumbs, action, sticky = fal
5462
5972
  width: '100%',
5463
5973
  ...(centerContent ? { mx: 'auto' } : { alignSelf: 'flex-start' }),
5464
5974
  }),
5465
- }, children: content })] }) }), showBackToTop && (jsx(Fade, { in: showBackToTopButton, children: jsx(Box, { sx: {
5975
+ }, children: content })] }) }), showBackToTop && (jsx(Fade$1, { in: showBackToTopButton, children: jsx(Box, { sx: {
5466
5976
  position: 'fixed',
5467
5977
  bottom: spacing.spacing_2,
5468
5978
  right: spacing.spacing_4,
@@ -5509,99 +6019,21 @@ function NeoPaginatedGrid({ slots, pageSizeOptions, slotProps: userSlotProps, ..
5509
6019
  // Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
5510
6020
  // Set defaults first, then spread props to allow overrides
5511
6021
  , {
5512
- // Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
5513
- // Set defaults first, then spread props to allow overrides
5514
- pagination: true, paginationMode: "client", pageSizeOptions: pageSizeOptions ?? [25, 50, 100], autoHeight: false, ...props,
5515
- // Merge slots after props to ensure footer is set
5516
- slots: mergedSlots, slotProps: {
5517
- basePopper: {
5518
- placement: 'bottom-start',
5519
- },
5520
- footer: {
5521
- variant: 'pagination',
5522
- },
5523
- ...userSlotProps,
5524
- } }));
5525
- }
5526
- NeoPaginatedGrid.displayName = 'NeoPaginatedGrid';
5527
-
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';
6022
+ // Explicitly enable pagination (matching moderne-ui ModerneDataGrid defaults)
6023
+ // Set defaults first, then spread props to allow overrides
6024
+ pagination: true, paginationMode: "client", pageSizeOptions: pageSizeOptions ?? [25, 50, 100], autoHeight: false, ...props,
6025
+ // Merge slots after props to ensure footer is set
6026
+ slots: mergedSlots, slotProps: {
6027
+ basePopper: {
6028
+ placement: 'bottom-start',
6029
+ },
6030
+ footer: {
6031
+ variant: 'pagination',
6032
+ },
6033
+ ...userSlotProps,
6034
+ } }));
6035
+ }
6036
+ NeoPaginatedGrid.displayName = 'NeoPaginatedGrid';
5605
6037
 
5606
6038
  const StyledTextField = styled(TextField)(({ theme }) => ({
5607
6039
  [`& .${inputBaseClasses.root}`]: {
@@ -5845,6 +6277,55 @@ const NeoRadio = ({ size = 'medium', label, helperText, disabled, ...props }) =>
5845
6277
  };
5846
6278
  NeoRadio.displayName = 'NeoRadio';
5847
6279
 
6280
+ /**
6281
+ * NeoRadioButtonWithText
6282
+ *
6283
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-7682
6284
+ */
6285
+ const NeoRadioButtonWithText = styled('div')({});
6286
+
6287
+ // Box-breathing rhythm: appear (inhale) → hold → expand+fade (exhale) → rest.
6288
+ // Max scale is capped so the ring fits within a parent row's line-height.
6289
+ const ripple = keyframes `
6290
+ 0% { opacity: 0; transform: scale(0.7); }
6291
+ 20% { opacity: 0.9; transform: scale(0.7); }
6292
+ 35% { opacity: 0.9; transform: scale(0.7); }
6293
+ 80% { opacity: 0; transform: scale(1.7); }
6294
+ 100% { opacity: 0; transform: scale(0.7); }
6295
+ `;
6296
+ /**
6297
+ * NeoRipplingDot - Animated status dot with an expanding ripple ring.
6298
+ *
6299
+ * Indicates an in-progress, indeterminate state (RUNNING / SYNCING / PROCESSING).
6300
+ * Color is inherited from `currentColor`; set it via the `color`/`sx` prop or a
6301
+ * parent. Sized to the lowercase-letter height regardless of parent fontSize.
6302
+ */
6303
+ const NeoRipplingDot = props => (jsx(Box$1, { "aria-hidden": "true", ...props, style: {
6304
+ width: spacing.spacing_1,
6305
+ height: spacing.spacing_1,
6306
+ ...props.style,
6307
+ }, sx: {
6308
+ position: 'relative',
6309
+ display: 'inline-block',
6310
+ borderRadius: '50%',
6311
+ backgroundColor: 'currentColor',
6312
+ verticalAlign: 'middle',
6313
+ flexShrink: 0,
6314
+ '&::before': {
6315
+ content: '""',
6316
+ position: 'absolute',
6317
+ inset: '-25%',
6318
+ borderRadius: '50%',
6319
+ border: '1px solid currentColor',
6320
+ animation: `${ripple} 5.6s ease-in-out infinite`,
6321
+ '@media (prefers-reduced-motion: reduce)': {
6322
+ display: 'none',
6323
+ },
6324
+ },
6325
+ ...props.sx,
6326
+ } }));
6327
+ NeoRipplingDot.displayName = 'NeoRipplingDot';
6328
+
5848
6329
  const StyledSearchChip = styled(InputBase)(({ theme }) => ({
5849
6330
  borderRadius: borderRadius.full,
5850
6331
  border: `1px solid ${semanticColors.buttons.secondary.defaultBorder}`,
@@ -5910,6 +6391,126 @@ const NeoSearchChip = ({ onClear, value, ...props }) => {
5910
6391
  };
5911
6392
  NeoSearchChip.displayName = 'NeoSearchChip';
5912
6393
 
6394
+ /**
6395
+ * NeoSelectField — composite of NeoInputField's form chrome (label,
6396
+ * helper text, error state) wrapped around NeoSelect. Mirrors the
6397
+ * MUI `<TextField select>` ergonomics with Neo design tokens, so
6398
+ * consumers don't have to compose the two manually.
6399
+ *
6400
+ * @example
6401
+ * <NeoSelectField
6402
+ * label="Response format"
6403
+ * value={format}
6404
+ * onChange={e => setFormat(e.target.value)}
6405
+ * options={[
6406
+ * { value: 'json', label: 'JSON' },
6407
+ * { value: 'plain', label: 'Plain text' },
6408
+ * ]}
6409
+ * />
6410
+ */
6411
+ const NeoSelectField = ({ size = 'medium', destructive = false, label, required = false, infoIcon, helperText, errorMessage, options, children, disabled, id, ...selectProps }) => {
6412
+ const inputId = id || `neo-select-${Math.random().toString(36).substring(7)}`;
6413
+ const helperTextId = helperText || errorMessage ? `${inputId}-helper-text` : undefined;
6414
+ 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 ??
6415
+ 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 }))] }));
6416
+ };
6417
+ NeoSelectField.displayName = 'NeoSelectField';
6418
+
6419
+ const EXPANDED_WIDTH = 98;
6420
+ const COLLAPSED_WIDTH = 56;
6421
+ // The fade overlay must end on the same color as the rail to blend cleanly.
6422
+ const RAIL_BACKGROUND = colors.grey[100];
6423
+ /**
6424
+ * NeoSideNav
6425
+ *
6426
+ * Collapsible vertical navigation rail with fixed `header`/`footer` slots and a
6427
+ * scrolling content area. Controlled via `collapsed` + `onCollapsedChange`;
6428
+ * broadcasts collapsed state to descendant `NeoNavigationItem`s through context.
6429
+ *
6430
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4065-3425
6431
+ */
6432
+ const Root = styled('nav', {
6433
+ shouldForwardProp: prop => prop !== 'collapsed',
6434
+ })(({ collapsed, theme }) => ({
6435
+ display: 'flex',
6436
+ flexDirection: 'column',
6437
+ height: '100%',
6438
+ width: collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
6439
+ minWidth: collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
6440
+ backgroundColor: RAIL_BACKGROUND,
6441
+ transition: theme.transitions.create(['width', 'min-width'], {
6442
+ duration: theme.transitions.duration.shorter,
6443
+ }),
6444
+ overflow: 'hidden',
6445
+ }));
6446
+ const Header = styled('div')({
6447
+ flexShrink: 0,
6448
+ display: 'flex',
6449
+ flexDirection: 'column',
6450
+ alignItems: 'center',
6451
+ });
6452
+ const Scroll = styled('div')({
6453
+ flex: 1,
6454
+ minHeight: 0,
6455
+ overflowY: 'auto',
6456
+ overflowX: 'hidden',
6457
+ display: 'flex',
6458
+ flexDirection: 'column',
6459
+ alignItems: 'center',
6460
+ gap: spacing.spacing_1_2,
6461
+ paddingInline: spacing.spacing_1,
6462
+ '&::-webkit-scrollbar': { width: spacing.spacing_1_2 },
6463
+ '&::-webkit-scrollbar-thumb': {
6464
+ backgroundColor: semanticColors.border.primary,
6465
+ borderRadius: borderRadius.xXS,
6466
+ },
6467
+ });
6468
+ const FooterRegion = styled('div')({
6469
+ position: 'relative',
6470
+ flexShrink: 0,
6471
+ display: 'flex',
6472
+ flexDirection: 'column',
6473
+ alignItems: 'center',
6474
+ gap: spacing.spacing_1_2,
6475
+ paddingInline: spacing.spacing_1,
6476
+ paddingBottom: spacing.spacing_1,
6477
+ });
6478
+ // Gradient fade so scrolling items dissolve into the footer instead of butting against it.
6479
+ const Fade = styled('div')({
6480
+ position: 'absolute',
6481
+ top: -spacing.spacing_3,
6482
+ left: 0,
6483
+ right: 0,
6484
+ height: spacing.spacing_3,
6485
+ pointerEvents: 'none',
6486
+ background: `linear-gradient(to bottom, transparent, ${RAIL_BACKGROUND})`,
6487
+ });
6488
+ const Toggle = styled(ButtonBase)(({ theme }) => ({
6489
+ display: 'flex',
6490
+ alignItems: 'center',
6491
+ justifyContent: 'center',
6492
+ flexDirection: 'column',
6493
+ gap: spacing.spacing_1_2,
6494
+ width: '100%',
6495
+ paddingBlock: spacing.spacing_1,
6496
+ borderRadius: borderRadius.s,
6497
+ border: `1px solid ${semanticColors.border.secondary}`,
6498
+ color: semanticColors.typography.bodySecondary,
6499
+ fontFamily: typography.fontFamily.body,
6500
+ fontSize: theme.typography.pxToRem(11),
6501
+ lineHeight: 1,
6502
+ '&:hover': {
6503
+ color: semanticColors.typography.body,
6504
+ borderColor: semanticColors.border.primary,
6505
+ },
6506
+ }));
6507
+ function NeoSideNav({ collapsed, onCollapsedChange, header, footer, children, collapseLabel = 'Less', ...rest }) {
6508
+ const ToggleIcon = collapsed ? PanelLeftOpen : PanelLeftClose;
6509
+ const contextValue = useMemo(() => ({ collapsed }), [collapsed]);
6510
+ return (jsx(NeoSideNavContext.Provider, { value: contextValue, children: jsxs(Root, { collapsed: collapsed, ...rest, children: [header && jsx(Header, { children: header }), jsx(Scroll, { children: children }), jsxs(FooterRegion, { children: [jsx(Fade, {}), footer, jsxs(Toggle, { "data-testid": "neo-side-nav-toggle", "aria-label": collapsed ? 'Expand navigation' : 'Collapse navigation', disableRipple: true, onClick: () => onCollapsedChange(!collapsed), children: [jsx(ToggleIcon, { size: 18 }), !collapsed && jsx("span", { children: collapseLabel })] })] })] }) }));
6511
+ }
6512
+ NeoSideNav.displayName = 'NeoSideNav';
6513
+
5913
6514
  const StyledSkeleton = styled(Skeleton, {
5914
6515
  shouldForwardProp: prop => prop !== 'colorTheme' && prop !== 'position',
5915
6516
  })(({ theme, colorTheme = 'light', position = 'start' }) => ({
@@ -5957,6 +6558,111 @@ const NeoSkeleton = ({ colorTheme = 'light', position = 'start', ...props }) =>
5957
6558
  };
5958
6559
  NeoSkeleton.displayName = 'NeoSkeleton';
5959
6560
 
6561
+ const sizePadding = {
6562
+ small: `${spacing.spacing_3_4}px ${spacing.spacing_1_1_2}px`,
6563
+ medium: `${spacing.spacing_1_1_2}px ${spacing.spacing_2}px`,
6564
+ };
6565
+ const sizeFontSize = {
6566
+ small: typography.fontSize.xs,
6567
+ medium: typography.fontSize.sm,
6568
+ };
6569
+ const StyledTable = styled(MuiTable, {
6570
+ shouldForwardProp: prop => prop !== 'tableSize',
6571
+ })(({ theme, tableSize = 'small' }) => ({
6572
+ borderCollapse: 'separate',
6573
+ borderSpacing: 0,
6574
+ [`& .${tableCellClasses.head}`]: {
6575
+ backgroundColor: colors.grey[50],
6576
+ color: semanticColors.typography.body,
6577
+ fontFamily: typography.fontFamily.body,
6578
+ fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
6579
+ fontWeight: typography.fontWeight.semiBold,
6580
+ lineHeight: 1.4,
6581
+ padding: sizePadding[tableSize],
6582
+ borderBottom: `1px solid ${semanticColors.border.secondary}`,
6583
+ },
6584
+ [`& .${tableCellClasses.body}`]: {
6585
+ color: semanticColors.typography.body,
6586
+ fontFamily: typography.fontFamily.body,
6587
+ fontSize: theme.typography.pxToRem(sizeFontSize[tableSize]),
6588
+ fontWeight: typography.fontWeight.regular,
6589
+ lineHeight: 1.4,
6590
+ padding: sizePadding[tableSize],
6591
+ borderBottom: `1px solid ${semanticColors.border.secondary}`,
6592
+ },
6593
+ // Drop the trailing row's bottom border so the container border (if
6594
+ // any) is the visual edge.
6595
+ [`& tbody tr:last-of-type .${tableCellClasses.body}`]: {
6596
+ borderBottom: 'none',
6597
+ },
6598
+ }));
6599
+ const StyledContainer = styled('div', {
6600
+ shouldForwardProp: prop => prop !== 'tableVariant',
6601
+ })(({ tableVariant = 'bordered' }) => tableVariant === 'bordered'
6602
+ ? {
6603
+ border: `1px solid ${semanticColors.border.secondary}`,
6604
+ borderRadius: borderRadius.card,
6605
+ overflow: 'hidden',
6606
+ backgroundColor: semanticColors.surfaces.white,
6607
+ }
6608
+ : { backgroundColor: 'transparent' });
6609
+ /**
6610
+ * NeoTable — lightweight read-only table for static data (schema rows,
6611
+ * key/value summaries, response metadata). For interactive grids with
6612
+ * sorting / filtering / pagination, use NeoDataGrid instead.
6613
+ *
6614
+ * @example
6615
+ * <NeoTable
6616
+ * columns={[
6617
+ * { key: 'name', header: 'Property' },
6618
+ * { key: 'type', header: 'Type', align: 'center', width: '120px' },
6619
+ * { key: 'description', header: 'Description' },
6620
+ * ]}
6621
+ * rows={[
6622
+ * { name: 'id', type: 'string', description: 'Resource identifier' },
6623
+ * { name: 'count', type: 'number', description: 'Item count' },
6624
+ * ]}
6625
+ * size="small"
6626
+ * />
6627
+ */
6628
+ 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))) })] }) }) }));
6629
+ NeoTable.displayName = 'NeoTable';
6630
+
6631
+ const StyledTabPanel = styled(Box, {
6632
+ shouldForwardProp: prop => prop !== 'tabPanelVariant',
6633
+ })(({ tabPanelVariant = 'default' }) => ({
6634
+ backgroundColor: semanticColors.surfaces.white,
6635
+ // default: 16px top padding for content-driven pages.
6636
+ // flush: zero padding so content sits directly against the tab bar's
6637
+ // bottom border (sidebars, panels, builders, canvases).
6638
+ padding: 0,
6639
+ ...(tabPanelVariant === 'flush' ? {} : { paddingTop: spacing.spacing_2 }),
6640
+ }));
6641
+ /**
6642
+ * NeoTabPanel — completes the NeoTabs + NeoTab + NeoTabPanel set.
6643
+ *
6644
+ * Lightweight ARIA-compliant tab panel that renders children when its
6645
+ * `value` matches `currentValue`. No MUI Lab / TabContext dependency.
6646
+ *
6647
+ * @example
6648
+ * const [tab, setTab] = useState('overview')
6649
+ * return (
6650
+ * <>
6651
+ * <NeoTabs value={tab} onChange={(_, v) => setTab(v)}>
6652
+ * <NeoTab value="overview" label="Overview" />
6653
+ * <NeoTab value="details" label="Details" />
6654
+ * </NeoTabs>
6655
+ * <NeoTabPanel value="overview" currentValue={tab}>...</NeoTabPanel>
6656
+ * <NeoTabPanel value="details" currentValue={tab} variant="flush">...</NeoTabPanel>
6657
+ * </>
6658
+ * )
6659
+ */
6660
+ const NeoTabPanel = ({ value, currentValue, variant = 'default', children, ...boxProps }) => {
6661
+ const selected = value === currentValue;
6662
+ return (jsx(StyledTabPanel, { role: "tabpanel", hidden: !selected, tabPanelVariant: variant, id: `tabpanel-${value}`, "aria-labelledby": `tab-${value}`, ...boxProps, children: selected ? children : null }));
6663
+ };
6664
+ NeoTabPanel.displayName = 'NeoTabPanel';
6665
+
5960
6666
  /**
5961
6667
  * NeoTabs - Tabs container component based on MUI Tabs
5962
6668
  *
@@ -6336,6 +7042,102 @@ const NeoToggle = ({ size = 'medium', label, helperText, disabled, ...props }) =
6336
7042
  };
6337
7043
  NeoToggle.displayName = 'NeoToggle';
6338
7044
 
7045
+ const sizeStyles = {
7046
+ small: {
7047
+ height: 24,
7048
+ fontSize: typography.fontSize.xs,
7049
+ },
7050
+ medium: {
7051
+ height: 32,
7052
+ fontSize: typography.fontSize.sm,
7053
+ },
7054
+ };
7055
+ const StyledToggleButton$1 = styled(MuiToggleButton, {
7056
+ shouldForwardProp: prop => prop !== 'toggleSize',
7057
+ })(({ theme, toggleSize = 'medium' }) => ({
7058
+ height: sizeStyles[toggleSize].height,
7059
+ padding: `0 ${spacing.spacing_1_1_2}px`,
7060
+ fontFamily: typography.fontFamily.body,
7061
+ fontSize: theme.typography.pxToRem(sizeStyles[toggleSize].fontSize),
7062
+ fontWeight: typography.fontWeight.regular,
7063
+ lineHeight: 1,
7064
+ color: semanticColors.typography.bodySecondary,
7065
+ backgroundColor: 'transparent',
7066
+ border: 'none',
7067
+ textTransform: 'none',
7068
+ transition: theme.transitions.create(['background-color', 'color'], {
7069
+ duration: theme.transitions.duration.short,
7070
+ }),
7071
+ '&:hover': {
7072
+ backgroundColor: colors.grey[100],
7073
+ color: semanticColors.typography.body,
7074
+ },
7075
+ '&.Mui-selected, &.Mui-selected:hover': {
7076
+ backgroundColor: colors.grey[100],
7077
+ color: semanticColors.typography.body,
7078
+ fontWeight: typography.fontWeight.semiBold,
7079
+ },
7080
+ '&.Mui-focusVisible': {
7081
+ outline: `2px solid ${semanticColors.border.focus}`,
7082
+ outlineOffset: -2,
7083
+ },
7084
+ '&.Mui-disabled': {
7085
+ color: semanticColors.typography.button.disabled,
7086
+ cursor: 'default',
7087
+ pointerEvents: 'none',
7088
+ },
7089
+ }));
7090
+ /**
7091
+ * NeoToggleButton — a single button in a segmented control. Use inside
7092
+ * NeoToggleButtonGroup; the group manages selection state and forwards
7093
+ * size to its children. Suitable for inline toolbar mode switches
7094
+ * ("Table" / "Raw"). For page-level tabs, prefer NeoButtonTab.
7095
+ */
7096
+ const NeoToggleButton = ({ children, size = 'medium', ...props }) => (jsx(StyledToggleButton$1, { toggleSize: size, ...props, children: children }));
7097
+ NeoToggleButton.displayName = 'NeoToggleButton';
7098
+
7099
+ const StyledToggleButtonGroup$1 = styled(MuiToggleButtonGroup)({
7100
+ borderRadius: borderRadius.button,
7101
+ border: `1px solid ${semanticColors.border.secondary}`,
7102
+ overflow: 'hidden',
7103
+ display: 'inline-flex',
7104
+ // Children fill the pill — first/last get the rounded corners, middles
7105
+ // are square. MUI applies positional classes via ToggleButtonGroup
7106
+ // context; we rely on borderRadius inheritance from the container.
7107
+ [`& .${toggleButtonClasses.root}`]: {
7108
+ borderRadius: 0,
7109
+ },
7110
+ });
7111
+ /**
7112
+ * NeoToggleButtonGroup — pill-shaped segmented control wrapping
7113
+ * MUI ToggleButtonGroup with Neo tokens. Use for inline toolbar mode
7114
+ * switches (e.g. "Table" / "Raw" in a panel header). For page-level
7115
+ * tab navigation, prefer NeoButtonTabGroup.
7116
+ *
7117
+ * @example
7118
+ * <NeoToggleButtonGroup value={mode} exclusive onChange={(_, v) => v && setMode(v)} size="small">
7119
+ * <NeoToggleButton value="table">Table</NeoToggleButton>
7120
+ * <NeoToggleButton value="raw">Raw</NeoToggleButton>
7121
+ * </NeoToggleButtonGroup>
7122
+ */
7123
+ const NeoToggleButtonGroup = ({ size = 'medium', children, ...props }) => {
7124
+ // Forward size to each NeoToggleButton child so consumers don't have to
7125
+ // set it on every button. MUI's group already does this via context for
7126
+ // its own size prop, but our `size` shape doesn't pass through unchanged.
7127
+ const sized = Children.map(children, child => isValidElement(child) && child.type === NeoToggleButton
7128
+ ? cloneElement(child, { size })
7129
+ : child);
7130
+ return jsx(StyledToggleButtonGroup$1, { ...props, children: sized });
7131
+ };
7132
+ NeoToggleButtonGroup.displayName = 'NeoToggleButtonGroup';
7133
+
7134
+ /**
7135
+ * NeoToggleButtonWithText
7136
+ *
7137
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=11565-10485
7138
+ */
7139
+ const NeoToggleButtonWithText = styled('div')({});
7140
+
6339
7141
  const StyledToolbar = styled(Toolbar)(({ theme }) => ({
6340
7142
  backgroundColor: semanticColors.surfaces.white,
6341
7143
  minHeight: 'auto',
@@ -6396,86 +7198,18 @@ const NeoToolbar = ({ children, ...props }) => {
6396
7198
  NeoToolbar.displayName = 'NeoToolbar';
6397
7199
 
6398
7200
  /**
6399
- * Variant color configuration
6400
- */
6401
- const variantConfig = {
6402
- light: {
6403
- backgroundColor: semanticColors.surfaces.tooltip, // #4b5563 - medium gray
6404
- color: semanticColors.typography.tooltip, // #ffffff - white
6405
- },
6406
- dark: {
6407
- backgroundColor: colors.grey[50], // #f9fafb - very light gray
6408
- color: colors.grey[800], // #1f2937 - dark gray
6409
- },
6410
- brand: {
6411
- backgroundColor: colors.digitalBlue[800], // #131e7a - dark blue
6412
- color: semanticColors.typography.tooltip, // #ffffff - white
6413
- },
6414
- };
6415
- /**
6416
- * Styled MUI Tooltip with Neo design system tokens
7201
+ * NeoTopNav
7202
+ *
7203
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=4618-185228
6417
7204
  */
6418
- const StyledTooltip = styled(Tooltip, {
6419
- shouldForwardProp: prop => prop !== 'variant' && prop !== 'description',
6420
- })(({ variant = 'light', description }) => {
6421
- const hasDescription = Boolean(description);
6422
- const variantStyles = variantConfig[variant];
6423
- return {
6424
- // Style the tooltip content
6425
- [`& .${tooltipClasses.tooltip}`]: {
6426
- backgroundColor: variantStyles.backgroundColor,
6427
- color: variantStyles.color,
6428
- fontSize: typography.fontSize.xs,
6429
- fontWeight: typography.fontWeight.medium,
6430
- lineHeight: hasDescription ? 1.5 : 1,
6431
- borderRadius: hasDescription ? borderRadius.s : borderRadius.xS,
6432
- padding: hasDescription ? spacing.spacing_1_1_2 : `0 ${spacing.spacing_1}px`,
6433
- ...(hasDescription && {
6434
- maxWidth: 296,
6435
- }),
6436
- ...(!hasDescription && {
6437
- height: spacing.spacing_3_1_4,
6438
- display: 'flex',
6439
- alignItems: 'center',
6440
- justifyContent: 'center',
6441
- }),
6442
- boxShadow: `${shadows.neutral.medium.x}px ${shadows.neutral.medium.y}px ${shadows.neutral.medium.blur}px ${shadows.neutral.medium.spread}px ${shadows.neutral.medium.shadow}`,
6443
- },
6444
- // Style the arrow
6445
- [`& .${tooltipClasses.arrow}`]: {
6446
- color: variantStyles.backgroundColor,
6447
- },
6448
- };
6449
- });
7205
+ const NeoTopNav = styled('div')({});
7206
+
6450
7207
  /**
6451
- * NeoTooltip - Tooltip component following Neo design system
6452
- *
6453
- * Provides contextual information when users hover over or focus on an element.
6454
- * Supports three visual variants (light, dark, brand) and optional supporting text.
6455
- *
6456
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4091-26557&t=Bo58EpFmg6ILJtmv-11
6457
- *
6458
- * Figma Props Mapping:
6459
- * - Theme (Light mode|Dark mode|Brand color) → variant ('light'|'dark'|'brand')
6460
- * - Placement → arrow (boolean) + placement (top/bottom/left/right/etc)
6461
- * - Supporting text (True|False) → description (string|undefined)
6462
- * - text → title (string, literal content)
7208
+ * NeoTourModal
6463
7209
  *
6464
- * Design Tokens Used:
6465
- * - Light: surfaces.tooltip (#4b5563), typography.tooltip (#ffffff)
6466
- * - Dark: grey[50] (#f9fafb), grey[800] (#1f2937)
6467
- * - Brand: digitalBlue[800] (#131e7a), typography.tooltip (#ffffff)
6468
- * - Shadow: neutralMedium (0px 8px 15px 0px rgba(31,41,55,0.1))
6469
- * - Typography: fontSize.xs (12), fontWeight.medium (500), fontWeight.semiBold (600)
7210
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=12408-1800
6470
7211
  */
6471
- const NeoTooltip = ({ variant = 'light', title, description, children, arrow = false, placement, ...props }) => {
6472
- // Build the title content
6473
- // If description is provided, create a structured layout with title + description
6474
- // Otherwise, just show the title text
6475
- const titleContent = description ? (jsxs(Stack, { gap: 0.25, children: [jsx(Typography, { fontWeight: typography.fontWeight.semiBold, children: title }), jsx(Typography, { fontWeight: typography.fontWeight.medium, children: description })] })) : (title);
6476
- return (jsx(StyledTooltip, { variant: variant, description: description, title: titleContent, arrow: arrow, placement: placement, ...props, children: children }));
6477
- };
6478
- NeoTooltip.displayName = 'NeoTooltip';
7212
+ const NeoTourModal = styled('div')({});
6479
7213
 
6480
7214
  /**
6481
7215
  * Custom label component that reads extra slot data from the item model.
@@ -6673,6 +7407,39 @@ const NeoTypologyControl = ({ children, ...props }) => {
6673
7407
  };
6674
7408
  NeoTypologyControl.displayName = 'NeoTypologyControl';
6675
7409
 
7410
+ // Box-breathing rhythm: inhale (grow) → hold → exhale (shadow expand+fade) → rest.
7411
+ const vibrate = keyframes `
7412
+ 0% { transform: scale(0.9); box-shadow: 0 0 0 0 transparent; }
7413
+ 25% { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
7414
+ 50% { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
7415
+ 75% { transform: scale(0.9); box-shadow: 0 0 0 ${spacing.spacing_3_4}px transparent; }
7416
+ 100% { transform: scale(0.9); box-shadow: 0 0 0 0 transparent; }
7417
+ `;
7418
+ /**
7419
+ * NeoVibratingDot - Animated status dot with a breathing pulse halo.
7420
+ *
7421
+ * Indicates a waiting/pending state (QUEUED / CREATED). Color is inherited from
7422
+ * `currentColor`; set it via the `color`/`sx` prop or a parent. Sized to the
7423
+ * lowercase-letter height regardless of parent fontSize.
7424
+ */
7425
+ const NeoVibratingDot = props => (jsx(Box$1, { "aria-hidden": "true", ...props, style: {
7426
+ width: spacing.spacing_1,
7427
+ height: spacing.spacing_1,
7428
+ ...props.style,
7429
+ }, sx: {
7430
+ display: 'inline-block',
7431
+ borderRadius: '50%',
7432
+ backgroundColor: 'currentColor',
7433
+ verticalAlign: 'middle',
7434
+ flexShrink: 0,
7435
+ animation: `${vibrate} 5.6s ease-in-out infinite`,
7436
+ '@media (prefers-reduced-motion: reduce)': {
7437
+ animation: 'none',
7438
+ },
7439
+ ...props.sx,
7440
+ } }));
7441
+ NeoVibratingDot.displayName = 'NeoVibratingDot';
7442
+
6676
7443
  /**
6677
7444
  * @moderneinc/neo-styled-components
6678
7445
  *
@@ -6681,5 +7448,5 @@ NeoTypologyControl.displayName = 'NeoTypologyControl';
6681
7448
 
6682
7449
  const version = '0.0.0-development';
6683
7450
 
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 };
7451
+ export { ActivityScene, CIRCLE_RADIUS, NeoActionsCell, NeoActivityHeader, NeoActivityIndicatorCell, NeoAlert, NeoAvatarCell, NeoBadge, NeoBanner, NeoBreadcrumbLink, NeoBreadcrumbs, NeoButton, NeoButtonTab, NeoButtonTabGroup, NeoCanceledIcon, 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, NeoFilledCanceled, NeoFilledError, NeoFilledInfo, NeoFilledNeutral, NeoFilledQueued, NeoFilledSuccess, NeoFilledWarning, 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, NeoRipplingDot, 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, NeoVibratingDot, SortedAscendingIcon, SortedDescendingIcon, UnsortedIcon, focusRingStyles, getDataGridHeaderStyles, getDataGridRowStyles, neoRowHeights, version };
6685
7452
  //# sourceMappingURL=index.esm.js.map