@moderneinc/neo-styled-components 2.5.0-next.f787ac → 2.5.0-next.fbda18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -62,21 +62,39 @@ var Switch = require('@mui/material/Switch');
62
62
  var ToggleButton = require('@mui/material/ToggleButton');
63
63
  var ToggleButtonGroup = require('@mui/material/ToggleButtonGroup');
64
64
 
65
+ const focusRingShadow$2 = `${neoDesign.shadows.focusWhite1.x}px ${neoDesign.shadows.focusWhite1.y}px ${neoDesign.shadows.focusWhite1.blur}px ${neoDesign.shadows.focusWhite1.spread}px ${neoDesign.shadows.focusWhite1.shadow}, ${neoDesign.shadows.focusBlue2.x}px ${neoDesign.shadows.focusBlue2.y}px ${neoDesign.shadows.focusBlue2.blur}px ${neoDesign.shadows.focusBlue2.spread}px ${neoDesign.shadows.focusBlue2.shadow}`;
65
66
  // biome-ignore lint/suspicious/noExplicitAny: Type cast required to override MUI Avatar variant type without global augmentation
66
67
  const StyledAvatar = styles.styled(Avatar, {
67
68
  shouldForwardProp: prop => prop !== 'size' && prop !== 'variant',
68
69
  })(({ theme, size = 'medium', variant = 'circular' }) => ({
70
+ boxSizing: 'border-box',
69
71
  borderRadius: neoDesign.borderRadius.full,
70
72
  fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs),
71
73
  fontWeight: neoDesign.typography.fontWeight.regular,
72
74
  lineHeight: 1.5,
73
- // Size variants
74
- ...(size === 'small' && {
75
+ // Size variants — dimensions match Figma bounding boxes (border-box)
76
+ ...(size === 'small' &&
77
+ variant === 'circular' && {
78
+ width: neoDesign.spacing.spacing_4,
79
+ height: neoDesign.spacing.spacing_4,
80
+ fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs),
81
+ }),
82
+ ...(size === 'small' &&
83
+ variant === 'initials' && {
75
84
  width: neoDesign.spacing.spacing_2_1_2,
76
85
  height: neoDesign.spacing.spacing_2_1_2,
77
86
  fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs),
78
87
  }),
79
- ...(size === 'medium' && {
88
+ // Medium circular fills its AvatarContainer (container owns the 44px dimension)
89
+ ...(size === 'medium' &&
90
+ variant === 'circular' && {
91
+ width: '100%',
92
+ height: '100%',
93
+ fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.sm),
94
+ }),
95
+ // Medium initials has no container, so it owns its 44px dimension
96
+ ...(size === 'medium' &&
97
+ variant === 'initials' && {
80
98
  width: neoDesign.spacing.spacing_5_1_2,
81
99
  height: neoDesign.spacing.spacing_5_1_2,
82
100
  fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.sm),
@@ -92,20 +110,29 @@ const StyledAvatar = styles.styled(Avatar, {
92
110
  backgroundColor: 'transparent',
93
111
  border: `2px solid ${neoDesign.semanticColors.surfaces.white}`,
94
112
  }),
113
+ '&:focus-visible': {
114
+ outline: 'none',
115
+ boxShadow: focusRingShadow$2,
116
+ },
95
117
  }));
96
118
  const AvatarContainer = styles.styled(Box)(({ size = 'medium' }) => ({
119
+ boxSizing: 'border-box',
97
120
  ...(size === 'medium' && {
98
121
  width: neoDesign.spacing.spacing_5_1_2,
99
122
  height: neoDesign.spacing.spacing_5_1_2,
100
123
  backgroundColor: neoDesign.semanticColors.surfaces.white,
101
124
  borderRadius: neoDesign.borderRadius.full,
102
- padding: neoDesign.spacing.spacing_1_2,
125
+ padding: neoDesign.spacing.spacing_1_4,
103
126
  display: 'flex',
104
127
  alignItems: 'center',
105
128
  justifyContent: 'center',
106
129
  overflow: 'hidden',
107
130
  boxShadow: `${neoDesign.shadows.neutralSmall.x}px ${neoDesign.shadows.neutralSmall.y}px ${neoDesign.shadows.neutralSmall.blur}px ${neoDesign.shadows.neutralSmall.spread}px ${neoDesign.shadows.neutralSmall.shadow}`,
108
131
  }),
132
+ '&:focus-within': {
133
+ outline: 'none',
134
+ boxShadow: focusRingShadow$2,
135
+ },
109
136
  }));
110
137
  /**
111
138
  * NeoAvatar - User avatar component based on MUI Avatar
@@ -114,8 +141,9 @@ const AvatarContainer = styles.styled(Box)(({ size = 'medium' }) => ({
114
141
  *
115
142
  * Figma Props Mapping:
116
143
  * - Figma Type "Initials" → variant="initials", size="small" (20px)
117
- * - Figma Type "Small" → variant="circular", size="small" (20px with image)
144
+ * - Figma Type "Small" → variant="circular", size="small" (32px with image)
118
145
  * - Figma Type "Medium" → variant="circular", size="medium" (44px white container with image)
146
+ * - State: Focus → CSS :focus-visible ring (2px white inner + 4px blue outer)
119
147
  * - State: Hover (tooltip) → Wrap component with MUI Tooltip
120
148
  *
121
149
  * Usage:
@@ -1439,7 +1467,7 @@ const LabelContainer$4 = styles.styled('div')(({ size = 'medium' }) => ({
1439
1467
  flexDirection: 'column',
1440
1468
  gap: size === 'medium' ? 2 : 0,
1441
1469
  }));
1442
- const Label$3 = styles.styled('span')(({ theme, size = 'medium' }) => ({
1470
+ const Label$4 = styles.styled('span')(({ theme, size = 'medium' }) => ({
1443
1471
  fontSize: theme.typography.pxToRem(size === 'xs'
1444
1472
  ? neoDesign.typography.fontSize.xs
1445
1473
  : size === 'small'
@@ -1459,6 +1487,8 @@ const HelperText$2 = styles.styled('span')(({ theme, size = 'medium' }) => ({
1459
1487
  lineHeight: size === 'xs' ? 1.5 : size === 'small' ? 1.4 : 1.5,
1460
1488
  color: neoDesign.semanticColors.typography.bodySecondary,
1461
1489
  }));
1490
+ // Figma-exact border radius for xs checkbox — no matching design token
1491
+ const FIGMA_XS_BORDER_RADIUS = 1;
1462
1492
  const StyledCheckbox = styles.styled(Checkbox, {
1463
1493
  shouldForwardProp: prop => prop !== 'size',
1464
1494
  })(({ size = 'medium' }) => {
@@ -1466,8 +1496,7 @@ const StyledCheckbox = styles.styled(Checkbox, {
1466
1496
  const sizeConfig = {
1467
1497
  xs: {
1468
1498
  size: 12,
1469
- // biome-ignore plugin: Figma-exact 1px for xs — no matching token
1470
- borderRadius: 1, // From Figma: 1px for xs
1499
+ borderRadius: FIGMA_XS_BORDER_RADIUS,
1471
1500
  },
1472
1501
  small: {
1473
1502
  size: 16,
@@ -1588,7 +1617,7 @@ const NeoCheckbox = ({ size = 'medium', label, helperText, disabled, icon, check
1588
1617
  return (jsxRuntime.jsx(StyledCheckbox, { size: size, disabled: disabled, icon: defaultIcon, checkedIcon: defaultCheckedIcon, indeterminateIcon: defaultIndeterminateIcon, className: combinedClassName, ...props }));
1589
1618
  }
1590
1619
  // With label, wrap in container for proper layout
1591
- return (jsxRuntime.jsxs(CheckboxContainer, { disabled: disabled, children: [jsxRuntime.jsx(StyledCheckbox, { size: size, disabled: disabled, icon: defaultIcon, checkedIcon: defaultCheckedIcon, indeterminateIcon: defaultIndeterminateIcon, className: combinedClassName, ...props }), jsxRuntime.jsxs(LabelContainer$4, { size: size, children: [label && jsxRuntime.jsx(Label$3, { size: size, children: label }), helperText && jsxRuntime.jsx(HelperText$2, { size: size, children: helperText })] })] }));
1620
+ return (jsxRuntime.jsxs(CheckboxContainer, { disabled: disabled, children: [jsxRuntime.jsx(StyledCheckbox, { size: size, disabled: disabled, icon: defaultIcon, checkedIcon: defaultCheckedIcon, indeterminateIcon: defaultIndeterminateIcon, className: combinedClassName, ...props }), jsxRuntime.jsxs(LabelContainer$4, { size: size, children: [label && jsxRuntime.jsx(Label$4, { size: size, children: label }), helperText && jsxRuntime.jsx(HelperText$2, { size: size, children: helperText })] })] }));
1592
1621
  };
1593
1622
  NeoCheckbox.displayName = 'NeoCheckbox';
1594
1623
 
@@ -1634,7 +1663,9 @@ const StyledButtonBase = styles.styled(ButtonBase, {
1634
1663
  width: isMultiline ? '100%' : 'fit-content',
1635
1664
  maxWidth: isMultiline ? '100%' : 'none',
1636
1665
  overflowX: isMultiline ? 'auto' : 'visible',
1637
- padding: isMultiline && 'paddingMultiline' in sizeStyles ? sizeStyles.paddingMultiline : sizeStyles.paddingSingleLine,
1666
+ padding: isMultiline && 'paddingMultiline' in sizeStyles
1667
+ ? sizeStyles.paddingMultiline
1668
+ : sizeStyles.paddingSingleLine,
1638
1669
  paddingRight: isMultiline ? theme.spacing(7) : undefined, // Extra space for copy button in multiline only
1639
1670
  fontSize: sizeStyles.fontSize,
1640
1671
  fontFamily: neoDesign.typography.fontFamily.code,
@@ -1758,13 +1789,14 @@ const ColumnItemContainer = styles.styled(Box)(({ theme }) => ({
1758
1789
  paddingLeft: theme.spacing(0.75),
1759
1790
  paddingRight: theme.spacing(0.75),
1760
1791
  }));
1792
+ // Figma-exact border radius for menu items — no matching design token
1793
+ const MENU_ITEM_BORDER_RADIUS = 6;
1761
1794
  const MenuItemContent$1 = styles.styled('div')(({ theme }) => ({
1762
1795
  display: 'flex',
1763
1796
  alignItems: 'center',
1764
1797
  gap: theme.spacing(1),
1765
1798
  padding: theme.spacing(1),
1766
- // biome-ignore plugin: no exact token for 6px
1767
- borderRadius: 6,
1799
+ borderRadius: MENU_ITEM_BORDER_RADIUS,
1768
1800
  width: '100%',
1769
1801
  '&:hover': {
1770
1802
  backgroundColor: neoDesign.semanticColors.surfaces.listHover,
@@ -1908,7 +1940,7 @@ const LabelContainer$3 = styles.styled('div')({
1908
1940
  gap: neoDesign.spacing.spacing_1,
1909
1941
  minWidth: 0,
1910
1942
  });
1911
- const Label$2 = styles.styled('span')({
1943
+ const Label$3 = styles.styled('span')({
1912
1944
  color: neoDesign.semanticColors.icons.default,
1913
1945
  flexShrink: 0,
1914
1946
  });
@@ -1960,7 +1992,7 @@ const Shortcut = styles.styled('span')(({ theme }) => ({
1960
1992
  * ```
1961
1993
  */
1962
1994
  const NeoMenuItem = ({ icon, shortcut, secondaryText, children, ...props }) => {
1963
- return (jsxRuntime.jsx(StyledMenuItem, { ...props, children: jsxRuntime.jsxs(MenuItemContent, { children: [icon && jsxRuntime.jsx(IconWrapper$1, { children: icon }), jsxRuntime.jsxs(LabelContainer$3, { children: [jsxRuntime.jsx(Label$2, { children: children }), secondaryText && jsxRuntime.jsx(SecondaryLabel, { children: secondaryText })] }), shortcut && jsxRuntime.jsx(Shortcut, { children: shortcut })] }) }));
1995
+ return (jsxRuntime.jsx(StyledMenuItem, { ...props, children: jsxRuntime.jsxs(MenuItemContent, { children: [icon && jsxRuntime.jsx(IconWrapper$1, { children: icon }), jsxRuntime.jsxs(LabelContainer$3, { children: [jsxRuntime.jsx(Label$3, { children: children }), secondaryText && jsxRuntime.jsx(SecondaryLabel, { children: secondaryText })] }), shortcut && jsxRuntime.jsx(Shortcut, { children: shortcut })] }) }));
1964
1996
  };
1965
1997
  NeoMenuItem.displayName = 'NeoMenuItem';
1966
1998
 
@@ -2476,111 +2508,85 @@ function NeoDataGridColumnsButton() {
2476
2508
  }
2477
2509
  NeoDataGridColumnsButton.displayName = 'NeoDataGridColumnsButton';
2478
2510
 
2479
- const StyledChip$1 = styles.styled(Chip)(({ theme, size, variant, color }) => ({
2480
- padding: 0,
2481
- borderRadius: neoDesign.borderRadius.full,
2482
- fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs),
2483
- fontWeight: neoDesign.typography.fontWeight.medium,
2484
- // Size variants
2485
- ...(size === 'small' && {
2511
+ const sizeStyles = {
2512
+ small: {
2486
2513
  height: 16,
2487
2514
  paddingLeft: neoDesign.spacing.spacing_1_2, // 4px
2488
2515
  paddingRight: neoDesign.spacing.spacing_1_2, // 4px
2489
- }),
2490
- ...(size === 'medium' && {
2516
+ },
2517
+ medium: {
2491
2518
  height: 18,
2492
2519
  paddingLeft: neoDesign.spacing.spacing_3_4, // 6px
2493
2520
  paddingRight: neoDesign.spacing.spacing_3_4, // 6px
2494
- }),
2495
- ...(size === 'large' && {
2521
+ },
2522
+ large: {
2496
2523
  height: 20,
2497
2524
  paddingLeft: neoDesign.spacing.spacing_3_4, // 6px
2498
2525
  paddingRight: neoDesign.spacing.spacing_3_4, // 6px
2499
- }),
2500
- [`& .${Chip.chipClasses.label}`]: {
2501
- padding: 0,
2502
2526
  },
2503
- // Outlined variant (light type in Figma) - Neutral/Default
2504
- ...(variant === 'outlined' &&
2505
- color === 'default' && {
2527
+ };
2528
+ const outlinedColorStyles = {
2529
+ default: {
2506
2530
  backgroundColor: neoDesign.semanticColors.status.neutral.light,
2507
2531
  color: neoDesign.semanticColors.status.neutral.dark,
2508
- borderColor: neoDesign.colors.grey[200], // base/grey/200
2509
- }),
2510
- // Outlined variant - Error
2511
- ...(variant === 'outlined' &&
2512
- color === 'error' && {
2532
+ borderColor: neoDesign.colors.grey[200],
2533
+ },
2534
+ error: {
2513
2535
  backgroundColor: neoDesign.semanticColors.status.error.light,
2514
2536
  color: neoDesign.semanticColors.status.error.dark,
2515
- borderColor: neoDesign.colors.red[100], // base/red/100
2516
- }),
2517
- // Outlined variant - Warning
2518
- ...(variant === 'outlined' &&
2519
- color === 'warning' && {
2537
+ borderColor: neoDesign.colors.red[100],
2538
+ },
2539
+ warning: {
2520
2540
  backgroundColor: neoDesign.semanticColors.status.warning.light,
2521
2541
  color: neoDesign.semanticColors.status.warning.dark,
2522
- borderColor: neoDesign.colors.orange[100], // base/orange/100
2523
- }),
2524
- // Outlined variant - Success
2525
- ...(variant === 'outlined' &&
2526
- color === 'success' && {
2542
+ borderColor: neoDesign.colors.orange[100],
2543
+ },
2544
+ success: {
2527
2545
  backgroundColor: neoDesign.semanticColors.status.success.light,
2528
2546
  color: neoDesign.semanticColors.status.success.dark,
2529
- borderColor: 'rgba(94, 196, 111, 0.24)', // rgba from Figma
2530
- }),
2531
- // Outlined variant - Info
2532
- ...(variant === 'outlined' &&
2533
- color === 'info' && {
2547
+ borderColor: 'rgba(94, 196, 111, 0.24)',
2548
+ },
2549
+ info: {
2534
2550
  backgroundColor: neoDesign.semanticColors.status.info.light,
2535
2551
  color: neoDesign.semanticColors.status.info.dark,
2536
- borderColor: neoDesign.colors.digitalBlue[100], // base/digital-blue/100
2537
- }),
2538
- // Outlined variant - Violet
2539
- ...(variant === 'outlined' &&
2540
- color === 'violet' && {
2552
+ borderColor: neoDesign.colors.digitalBlue[100],
2553
+ },
2554
+ violet: {
2541
2555
  backgroundColor: `${neoDesign.colors.violet[100]}66`, // rgba(235,213,241,0.4)
2542
2556
  color: neoDesign.colors.violet[600],
2543
- borderColor: neoDesign.colors.violet[100], // base/violet/100
2544
- }),
2545
- // Filled variant (dark type in Figma) - Neutral/Default
2546
- ...(variant === 'filled' &&
2547
- color === 'default' && {
2548
- backgroundColor: neoDesign.semanticColors.status.neutral.medium,
2549
- color: theme.palette.common.white,
2550
- border: 'none',
2551
- }),
2552
- // Filled variant - Error
2553
- ...(variant === 'filled' &&
2554
- color === 'error' && {
2555
- backgroundColor: neoDesign.semanticColors.status.error.medium,
2556
- color: theme.palette.common.white,
2557
- border: 'none',
2558
- }),
2559
- // Filled variant - Warning
2560
- ...(variant === 'filled' &&
2561
- color === 'warning' && {
2562
- backgroundColor: neoDesign.semanticColors.status.warning.medium,
2563
- color: theme.palette.common.white,
2564
- border: 'none',
2565
- }),
2566
- // Filled variant - Success
2567
- ...(variant === 'filled' &&
2568
- color === 'success' && {
2569
- backgroundColor: neoDesign.semanticColors.status.success.medium,
2570
- color: theme.palette.common.white,
2571
- border: 'none',
2572
- }),
2573
- // Filled variant - Info
2574
- ...(variant === 'filled' &&
2575
- color === 'info' && {
2576
- backgroundColor: neoDesign.semanticColors.status.info.medium,
2577
- color: theme.palette.common.white,
2578
- border: 'none',
2579
- }),
2580
- // Filled variant - Violet
2557
+ borderColor: neoDesign.colors.violet[100],
2558
+ },
2559
+ beta: {
2560
+ backgroundColor: neoDesign.colors.digitalBlue[100],
2561
+ color: neoDesign.colors.digitalBlue[400],
2562
+ borderColor: neoDesign.colors.digitalBlue[100],
2563
+ },
2564
+ };
2565
+ const filledColorStyles = {
2566
+ default: neoDesign.semanticColors.status.neutral.medium,
2567
+ error: neoDesign.semanticColors.status.error.medium,
2568
+ warning: neoDesign.semanticColors.status.warning.medium,
2569
+ success: neoDesign.semanticColors.status.success.medium,
2570
+ info: neoDesign.semanticColors.status.info.medium,
2571
+ violet: neoDesign.colors.violet[500],
2572
+ beta: neoDesign.colors.digitalBlue[300],
2573
+ };
2574
+ const StyledChip$1 = styles.styled(Chip)(({ theme, size, variant, color }) => ({
2575
+ padding: 0,
2576
+ borderRadius: neoDesign.borderRadius.full,
2577
+ fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs),
2578
+ fontWeight: neoDesign.typography.fontWeight.medium,
2579
+ ...(size && sizeStyles[size]),
2580
+ [`& .${Chip.chipClasses.label}`]: {
2581
+ padding: 0,
2582
+ },
2583
+ ...(variant === 'outlined' &&
2584
+ color &&
2585
+ outlinedColorStyles[color]),
2581
2586
  ...(variant === 'filled' &&
2582
- color === 'violet' && {
2583
- backgroundColor: neoDesign.colors.violet[500],
2587
+ color &&
2588
+ color in filledColorStyles && {
2589
+ backgroundColor: filledColorStyles[color],
2584
2590
  color: theme.palette.common.white,
2585
2591
  border: 'none',
2586
2592
  }),
@@ -2593,7 +2599,7 @@ const StyledChip$1 = styles.styled(Chip)(({ theme, size, variant, color }) => ({
2593
2599
  * Figma Props Mapping:
2594
2600
  * - m (sm|md|lg) → size (small|medium|large)
2595
2601
  * - type (light|dark) → variant (outlined|filled)
2596
- * - state (Neutral|Error|Warning|Success|Info|Violet) → color (default|error|warning|success|info|violet)
2602
+ * - state (Neutral|Error|Warning|Success|Info|Violet|Beta) → color (default|error|warning|success|info|violet|beta)
2597
2603
  * - Label text → label prop
2598
2604
  */
2599
2605
  const NeoTag = ({ size = 'small', variant = 'outlined', ...props }) => {
@@ -3894,6 +3900,31 @@ const NeoFooter = ({ variant = 'pagination', showShadow = false, loading = false
3894
3900
  };
3895
3901
  NeoFooter.displayName = 'NeoFooter';
3896
3902
 
3903
+ const customProps$1 = ['iconSize'];
3904
+ const StyledIconWrapper = styles.styled('div', {
3905
+ shouldForwardProp: prop => !customProps$1.includes(prop),
3906
+ })(({ iconSize }) => ({
3907
+ display: 'inline-flex',
3908
+ alignItems: 'center',
3909
+ justifyContent: 'center',
3910
+ width: iconSize,
3911
+ height: iconSize,
3912
+ flexShrink: 0,
3913
+ '& svg': {
3914
+ width: iconSize,
3915
+ height: iconSize,
3916
+ },
3917
+ }));
3918
+ /**
3919
+ * NeoIconWrapper - Flex-centered container that sizes icons
3920
+ *
3921
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4061-9955
3922
+ */
3923
+ const NeoIconWrapper = ({ size = 20, children, ...props }) => {
3924
+ return (jsxRuntime.jsx(StyledIconWrapper, { iconSize: size, ...props, children: children }));
3925
+ };
3926
+ NeoIconWrapper.displayName = 'NeoIconWrapper';
3927
+
3897
3928
  /**
3898
3929
  * NeoInfiniteScrollGrid - DataGrid with infinite scroll and load-more functionality
3899
3930
  *
@@ -4528,11 +4559,11 @@ NeoListItemButton.displayName = 'NeoListItemButton';
4528
4559
  * Focus ring box-shadow using Neo design tokens
4529
4560
  * Combines focusWhite1 (inner white ring) and focusBlue2 (outer blue ring)
4530
4561
  */
4531
- const focusRingShadow = `${neoDesign.shadows.focusWhite1.x}px ${neoDesign.shadows.focusWhite1.y}px ${neoDesign.shadows.focusWhite1.blur}px ${neoDesign.shadows.focusWhite1.spread}px ${neoDesign.shadows.focusWhite1.shadow}, ${neoDesign.shadows.focusBlue2.x}px ${neoDesign.shadows.focusBlue2.y}px ${neoDesign.shadows.focusBlue2.blur}px ${neoDesign.shadows.focusBlue2.spread}px ${neoDesign.shadows.focusBlue2.shadow}`;
4562
+ const focusRingShadow$1 = `${neoDesign.shadows.focusWhite1.x}px ${neoDesign.shadows.focusWhite1.y}px ${neoDesign.shadows.focusWhite1.blur}px ${neoDesign.shadows.focusWhite1.spread}px ${neoDesign.shadows.focusWhite1.shadow}, ${neoDesign.shadows.focusBlue2.x}px ${neoDesign.shadows.focusBlue2.y}px ${neoDesign.shadows.focusBlue2.blur}px ${neoDesign.shadows.focusBlue2.spread}px ${neoDesign.shadows.focusBlue2.shadow}`;
4532
4563
  /**
4533
4564
  * Card box-shadow using Neo design tokens for hover and selected states
4534
4565
  */
4535
- const activeShadow = `${neoDesign.shadows.card.x}px ${neoDesign.shadows.card.y}px ${neoDesign.shadows.card.blur}px ${neoDesign.shadows.card.spread}px ${neoDesign.shadows.card.shadow}`;
4566
+ const activeShadow$1 = `${neoDesign.shadows.card.x}px ${neoDesign.shadows.card.y}px ${neoDesign.shadows.card.blur}px ${neoDesign.shadows.card.spread}px ${neoDesign.shadows.card.shadow}`;
4536
4567
  /**
4537
4568
  * Styled Card component with Neo design tokens
4538
4569
  */
@@ -4548,16 +4579,16 @@ const StyledCard = styles.styled(MuiCard, {
4548
4579
  backgroundColor: neoDesign.semanticColors.surfaces.card,
4549
4580
  border: `1px solid ${selected ? neoDesign.semanticColors.border.tabActive : neoDesign.semanticColors.border.card}`,
4550
4581
  borderRadius: neoDesign.borderRadius.xS,
4551
- boxShadow: selected ? activeShadow : 'none',
4582
+ boxShadow: selected ? activeShadow$1 : 'none',
4552
4583
  transition: theme.transitions.create(['border-color', 'background-color', 'box-shadow']),
4553
4584
  cursor: 'pointer',
4554
4585
  '&:hover': {
4555
4586
  borderColor: neoDesign.semanticColors.border.tabActive,
4556
- boxShadow: activeShadow,
4587
+ boxShadow: activeShadow$1,
4557
4588
  },
4558
4589
  '&:focus-visible': {
4559
4590
  borderColor: neoDesign.semanticColors.border.tabActive,
4560
- boxShadow: focusRingShadow,
4591
+ boxShadow: focusRingShadow$1,
4561
4592
  outline: 'none',
4562
4593
  },
4563
4594
  ...(disabled && {
@@ -4617,7 +4648,7 @@ const Title = styles.styled('p')(({ theme }) => ({
4617
4648
  /**
4618
4649
  * Description text
4619
4650
  */
4620
- const Description = styles.styled('p')(({ theme }) => ({
4651
+ const Description$1 = styles.styled('p')(({ theme }) => ({
4621
4652
  margin: 0,
4622
4653
  fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs), // 12px
4623
4654
  fontWeight: neoDesign.typography.fontWeight.regular, // 400
@@ -4672,10 +4703,131 @@ const Description = styles.styled('p')(({ theme }) => ({
4672
4703
  * - typography.fontWeight.regular (400) - Description
4673
4704
  */
4674
4705
  const NeoMarketplaceCard = ({ logo, recipeCount, title, description, selected = false, disabled = false, onClick, ...props }) => {
4675
- return (jsxRuntime.jsxs(StyledCard, { selected: selected, disabled: disabled, onClick: disabled ? undefined : onClick, tabIndex: disabled ? -1 : 0, role: "button", "aria-disabled": disabled, "aria-pressed": selected, ...props, children: [jsxRuntime.jsxs(CardHeader, { children: [jsxRuntime.jsx(LogoContainer, { children: logo }), jsxRuntime.jsx(RecipeCount, { children: recipeCount })] }), jsxRuntime.jsxs(CardContent, { children: [jsxRuntime.jsx(Title, { children: title }), jsxRuntime.jsx(Description, { children: description })] })] }));
4706
+ return (jsxRuntime.jsxs(StyledCard, { selected: selected, disabled: disabled, onClick: disabled ? undefined : onClick, tabIndex: disabled ? -1 : 0, role: "button", "aria-disabled": disabled, "aria-pressed": selected, ...props, children: [jsxRuntime.jsxs(CardHeader, { children: [jsxRuntime.jsx(LogoContainer, { children: logo }), jsxRuntime.jsx(RecipeCount, { children: recipeCount })] }), jsxRuntime.jsxs(CardContent, { children: [jsxRuntime.jsx(Title, { children: title }), jsxRuntime.jsx(Description$1, { children: description })] })] }));
4676
4707
  };
4677
4708
  NeoMarketplaceCard.displayName = 'NeoMarketplaceCard';
4678
4709
 
4710
+ const focusRingShadow = `${neoDesign.shadows.focusWhite1.x}px ${neoDesign.shadows.focusWhite1.y}px ${neoDesign.shadows.focusWhite1.blur}px ${neoDesign.shadows.focusWhite1.spread}px ${neoDesign.shadows.focusWhite1.shadow}, ${neoDesign.shadows.focusBlue2.x}px ${neoDesign.shadows.focusBlue2.y}px ${neoDesign.shadows.focusBlue2.blur}px ${neoDesign.shadows.focusBlue2.spread}px ${neoDesign.shadows.focusBlue2.shadow}`;
4711
+ const activeShadow = `${neoDesign.shadows.card.x}px ${neoDesign.shadows.card.y}px ${neoDesign.shadows.card.blur}px ${neoDesign.shadows.card.spread}px ${neoDesign.shadows.card.shadow}`;
4712
+ const StyledLargeCard = styles.styled(MuiCard, {
4713
+ shouldForwardProp: prop => prop !== 'cardState' && prop !== 'cardTheme',
4714
+ })(({ cardState = 'default', cardTheme = 'light' }) => {
4715
+ const isLight = cardTheme === 'light';
4716
+ const isActive = cardState === 'active';
4717
+ const isDisabled = cardState === 'disabled';
4718
+ const isFocused = cardState === 'focused';
4719
+ const activeBorderColor = isLight ? neoDesign.semanticColors.border.tabActive : neoDesign.colors.digitalGreen[300];
4720
+ const defaultBorderColor = isLight
4721
+ ? neoDesign.semanticColors.border.card
4722
+ : `${neoDesign.semanticColors.border.card}80`;
4723
+ return {
4724
+ width: 340,
4725
+ height: 162,
4726
+ display: 'flex',
4727
+ flexDirection: 'column',
4728
+ justifyContent: 'space-between',
4729
+ alignItems: 'flex-start',
4730
+ padding: neoDesign.spacing.spacing_2,
4731
+ borderRadius: neoDesign.borderRadius.xS,
4732
+ backgroundColor: isLight ? neoDesign.semanticColors.surfaces.card : neoDesign.colors.grey[800],
4733
+ border: `1px solid ${isActive || isFocused ? activeBorderColor : defaultBorderColor}`,
4734
+ boxShadow: isActive ? activeShadow : isFocused ? focusRingShadow : 'none',
4735
+ overflow: 'hidden',
4736
+ '&:focus-visible': {
4737
+ borderColor: isLight ? neoDesign.semanticColors.border.tabActive : neoDesign.colors.digitalGreen[300],
4738
+ boxShadow: focusRingShadow,
4739
+ outline: 'none',
4740
+ },
4741
+ ...(isDisabled && {
4742
+ opacity: 0.5,
4743
+ pointerEvents: 'none',
4744
+ cursor: 'not-allowed',
4745
+ }),
4746
+ };
4747
+ });
4748
+ const TopSection = styles.styled('div')({
4749
+ display: 'flex',
4750
+ flexDirection: 'column',
4751
+ gap: neoDesign.spacing.spacing_2,
4752
+ alignItems: 'flex-start',
4753
+ width: '100%',
4754
+ flexShrink: 0,
4755
+ });
4756
+ const HeaderRow = styles.styled('div')({
4757
+ display: 'flex',
4758
+ gap: neoDesign.spacing.spacing_1,
4759
+ alignItems: 'center',
4760
+ flexShrink: 0,
4761
+ });
4762
+ const HeaderSlot = styles.styled('div')({
4763
+ display: 'flex',
4764
+ flexDirection: 'column',
4765
+ alignItems: 'center',
4766
+ justifyContent: 'center',
4767
+ width: 20,
4768
+ height: 20,
4769
+ flexShrink: 0,
4770
+ });
4771
+ const HeaderTitle = styles.styled('span', {
4772
+ shouldForwardProp: prop => prop !== 'cardTheme',
4773
+ })(({ cardTheme = 'light' }) => ({
4774
+ fontFamily: `${neoDesign.typography.fontFamily.heading}, sans-serif`,
4775
+ fontWeight: neoDesign.typography.fontWeight.semiBold,
4776
+ fontSize: neoDesign.typography.fontSize.h6,
4777
+ lineHeight: 1.4,
4778
+ color: cardTheme === 'light' ? neoDesign.colors.grey[800] : neoDesign.semanticColors.surfaces.white,
4779
+ flexShrink: 0,
4780
+ }));
4781
+ const Description = styles.styled('p', {
4782
+ shouldForwardProp: prop => prop !== 'cardTheme',
4783
+ })(({ cardTheme = 'light' }) => ({
4784
+ fontFamily: `${neoDesign.typography.fontFamily.body}, sans-serif`,
4785
+ fontWeight: neoDesign.typography.fontWeight.regular,
4786
+ fontSize: neoDesign.typography.fontSize.xs,
4787
+ lineHeight: 1.5,
4788
+ color: cardTheme === 'light' ? neoDesign.colors.grey[800] : neoDesign.semanticColors.surfaces.white,
4789
+ margin: 0,
4790
+ minWidth: '100%',
4791
+ wordWrap: 'break-word',
4792
+ }));
4793
+ const ButtonsRow = styles.styled('div')({
4794
+ display: 'flex',
4795
+ gap: neoDesign.spacing.spacing_3,
4796
+ alignItems: 'flex-start',
4797
+ flexShrink: 0,
4798
+ });
4799
+ /**
4800
+ * NeoMarketplaceLargeCard - A large marketplace card with state and theme variants
4801
+ *
4802
+ * A 340x162px card with optional icon, gel brand icon, title, description, and action buttons.
4803
+ * Icon, gel, and title display inline in a header row.
4804
+ * Supports 4 states (default, active, disabled, focused) and 2 themes (light, dark).
4805
+ *
4806
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC?node-id=5925-11
4807
+ *
4808
+ * Figma Props Mapping:
4809
+ * - Property 1 → state (default/active/disabled/focused)
4810
+ * - Property 2 → cardTheme (light/dark)
4811
+ * - Show Icon → showIcon
4812
+ * - Show gel → showGel
4813
+ * - show buttons → showButtons
4814
+ *
4815
+ * Design Tokens Used:
4816
+ * - semanticColors.surfaces.card (#ffffff) - Light theme background
4817
+ * - colors.grey[800] (#1f2937) - Dark theme background
4818
+ * - semanticColors.border.card (#d1d5db) - Default border (50% opacity on dark)
4819
+ * - semanticColors.border.tabActive (#2f42ff) - Active/focused border (light theme)
4820
+ * - colors.digitalGreen[300] (#88fe9b) - Active/focused border (dark theme)
4821
+ * - borderRadius.xS (4px) - Corner radius
4822
+ * - shadows.focusWhite1 + shadows.focusBlue2 - Focus ring
4823
+ * - shadows.card - Active state shadow
4824
+ */
4825
+ const NeoMarketplaceLargeCard = ({ state = 'default', cardTheme = 'light', showIcon = true, showGel = true, showButtons = true, icon, gel, title, children, actions, onClick, ...props }) => {
4826
+ const isDisabled = state === 'disabled';
4827
+ return (jsxRuntime.jsxs(StyledLargeCard, { cardState: state, cardTheme: cardTheme, onClick: isDisabled ? undefined : onClick, tabIndex: isDisabled ? -1 : 0, "aria-disabled": isDisabled || undefined, ...props, children: [jsxRuntime.jsxs(TopSection, { children: [jsxRuntime.jsxs(HeaderRow, { children: [showIcon && icon && jsxRuntime.jsx(HeaderSlot, { children: icon }), showGel && gel && jsxRuntime.jsx(HeaderSlot, { children: gel }), title && jsxRuntime.jsx(HeaderTitle, { cardTheme: cardTheme, children: title })] }), children && jsxRuntime.jsx(Description, { cardTheme: cardTheme, children: children })] }), showButtons && actions && jsxRuntime.jsx(ButtonsRow, { children: actions })] }));
4828
+ };
4829
+ NeoMarketplaceLargeCard.displayName = 'NeoMarketplaceLargeCard';
4830
+
4679
4831
  const StyledMenu = styles.styled(Menu)(({ theme }) => ({
4680
4832
  [`& .${Paper.paperClasses.root}`]: {
4681
4833
  backgroundColor: neoDesign.semanticColors.surfaces.white,
@@ -4919,6 +5071,87 @@ const NeoModalFooter = ({ leadingContent, children }) => {
4919
5071
  };
4920
5072
  NeoModalFooter.displayName = 'NeoModalFooter';
4921
5073
 
5074
+ const customProps = ['selected'];
5075
+ const StyledRoot = styles.styled(ButtonBase, {
5076
+ shouldForwardProp: prop => !customProps.includes(prop),
5077
+ })(({ selected }) => ({
5078
+ display: 'flex',
5079
+ flexDirection: 'column',
5080
+ gap: neoDesign.spacing.spacing_1_4, // 2px
5081
+ alignItems: 'center',
5082
+ justifyContent: 'center',
5083
+ paddingTop: neoDesign.spacing.spacing_1, // 8px
5084
+ paddingBottom: neoDesign.spacing.spacing_1, // 8px
5085
+ paddingLeft: neoDesign.spacing.spacing_1_2, // 4px
5086
+ paddingRight: neoDesign.spacing.spacing_1_2, // 4px
5087
+ borderRadius: neoDesign.borderRadius.xS, // 4px
5088
+ width: 95,
5089
+ cursor: 'pointer',
5090
+ textDecoration: 'none',
5091
+ '&:hover .neo-nav-icon-padding': {
5092
+ backgroundColor: neoDesign.semanticColors.buttons.secondary.hoverBackground, // #F2F3FF
5093
+ },
5094
+ '&:hover .neo-nav-label': {
5095
+ color: neoDesign.semanticColors.buttons.primary.hover, // #1E2EC2
5096
+ },
5097
+ ...(selected && {
5098
+ '& .neo-nav-icon-padding': {
5099
+ backgroundColor: `${neoDesign.colors.digitalBlue[100]}BF`, // rgba(220,224,255,0.75)
5100
+ },
5101
+ '& .neo-nav-label': {
5102
+ color: neoDesign.semanticColors.buttons.primary.pressed, // #131E7A
5103
+ fontWeight: neoDesign.typography.fontWeight.semiBold,
5104
+ },
5105
+ '&:hover .neo-nav-icon-padding': {
5106
+ backgroundColor: `${neoDesign.colors.digitalBlue[100]}BF`,
5107
+ },
5108
+ '&:hover .neo-nav-label': {
5109
+ color: neoDesign.semanticColors.buttons.primary.pressed,
5110
+ },
5111
+ }),
5112
+ }));
5113
+ const IconPadding = styles.styled('span')({
5114
+ display: 'flex',
5115
+ alignItems: 'center',
5116
+ padding: neoDesign.spacing.spacing_1, // 8px
5117
+ borderRadius: neoDesign.spacing.spacing_1, // 8px
5118
+ transition: 'background-color 150ms',
5119
+ });
5120
+ const Label$2 = styles.styled('span')(({ theme }) => ({
5121
+ fontFamily: neoDesign.typography.fontFamily.body,
5122
+ fontWeight: neoDesign.typography.fontWeight.regular,
5123
+ fontSize: theme.typography.pxToRem(10),
5124
+ lineHeight: 1.2,
5125
+ textAlign: 'center',
5126
+ color: neoDesign.semanticColors.typography.navigation.default, // #1F2937
5127
+ width: '100%',
5128
+ transition: 'color 150ms',
5129
+ }));
5130
+ const TagPill = styles.styled('span')(({ theme }) => ({
5131
+ display: 'inline-flex',
5132
+ alignItems: 'center',
5133
+ justifyContent: 'center',
5134
+ height: 18,
5135
+ paddingLeft: neoDesign.spacing.spacing_3_4, // 6px
5136
+ paddingRight: neoDesign.spacing.spacing_3_4, // 6px
5137
+ borderRadius: neoDesign.borderRadius.full,
5138
+ backgroundColor: neoDesign.colors.digitalBlue[300], // #8D99FF
5139
+ color: neoDesign.semanticColors.typography.tooltip, // white
5140
+ fontFamily: neoDesign.typography.fontFamily.body,
5141
+ fontWeight: neoDesign.typography.fontWeight.medium,
5142
+ fontSize: theme.typography.pxToRem(neoDesign.typography.fontSize.xs), // 12px
5143
+ lineHeight: 1,
5144
+ }));
5145
+ /**
5146
+ * NeoNavigationItem - Vertical navigation item with icon, label, and optional tag
5147
+ *
5148
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=8455-6120
5149
+ */
5150
+ const NeoNavigationItem = ({ icon, label, selected = false, tag, children, ...props }) => {
5151
+ return (jsxRuntime.jsxs(StyledRoot, { selected: selected, disableRipple: true, ...props, children: [jsxRuntime.jsx(IconPadding, { className: "neo-nav-icon-padding", children: icon }), label && jsxRuntime.jsx(Label$2, { className: "neo-nav-label", children: label }), tag && jsxRuntime.jsx(TagPill, { children: tag }), children] }));
5152
+ };
5153
+ NeoNavigationItem.displayName = 'NeoNavigationItem';
5154
+
4922
5155
  /**
4923
5156
  * Sticky header wrapper - sticks to top when scrolling
4924
5157
  */
@@ -6214,6 +6447,8 @@ const NeoTooltip = ({ variant = 'light', title, description, children, arrow = f
6214
6447
  };
6215
6448
  NeoTooltip.displayName = 'NeoTooltip';
6216
6449
 
6450
+ // Figma-exact border radius for toggle buttons — no matching design token
6451
+ const TOGGLE_BUTTON_BORDER_RADIUS = 14;
6217
6452
  const StyledToggleButtonGroup = styles.styled(ToggleButtonGroup)(({ theme }) => ({
6218
6453
  backgroundColor: neoDesign.colors.grey[50],
6219
6454
  padding: theme.spacing(0.625, 0.875),
@@ -6221,17 +6456,14 @@ const StyledToggleButtonGroup = styles.styled(ToggleButtonGroup)(({ theme }) =>
6221
6456
  gap: 0,
6222
6457
  [`& .${ToggleButtonGroup.toggleButtonGroupClasses.grouped}`]: {
6223
6458
  border: 'none',
6224
- // biome-ignore plugin: no exact token for 14px
6225
- borderRadius: 14,
6459
+ borderRadius: TOGGLE_BUTTON_BORDER_RADIUS,
6226
6460
  margin: 0,
6227
6461
  '&:not(:first-of-type)': {
6228
- // biome-ignore plugin: no exact token for 14px
6229
- borderRadius: 14,
6462
+ borderRadius: TOGGLE_BUTTON_BORDER_RADIUS,
6230
6463
  marginLeft: 0,
6231
6464
  },
6232
6465
  '&:not(:last-of-type)': {
6233
- // biome-ignore plugin: no exact token for 14px
6234
- borderRadius: 14,
6466
+ borderRadius: TOGGLE_BUTTON_BORDER_RADIUS,
6235
6467
  },
6236
6468
  },
6237
6469
  }));
@@ -6313,12 +6545,14 @@ exports.NeoDot = NeoDot;
6313
6545
  exports.NeoFilterChip = NeoFilterChip;
6314
6546
  exports.NeoFooter = NeoFooter;
6315
6547
  exports.NeoIconButton = NeoIconButton;
6548
+ exports.NeoIconWrapper = NeoIconWrapper;
6316
6549
  exports.NeoInfiniteScrollGrid = NeoInfiniteScrollGrid;
6317
6550
  exports.NeoInputField = NeoInputField;
6318
6551
  exports.NeoListItem = NeoListItem;
6319
6552
  exports.NeoListItemButton = NeoListItemButton;
6320
6553
  exports.NeoLoadingSpinner = NeoLoadingSpinner;
6321
6554
  exports.NeoMarketplaceCard = NeoMarketplaceCard;
6555
+ exports.NeoMarketplaceLargeCard = NeoMarketplaceLargeCard;
6322
6556
  exports.NeoMenu = NeoMenu;
6323
6557
  exports.NeoMenuItem = NeoMenuItem;
6324
6558
  exports.NeoModal = NeoModal;
@@ -6326,6 +6560,7 @@ exports.NeoModalContent = NeoModalContent;
6326
6560
  exports.NeoModalFooter = NeoModalFooter;
6327
6561
  exports.NeoModalHeader = NeoModalHeader;
6328
6562
  exports.NeoMultiBadgesCell = NeoMultiBadgesCell;
6563
+ exports.NeoNavigationItem = NeoNavigationItem;
6329
6564
  exports.NeoPageContent = NeoPageContent;
6330
6565
  exports.NeoPaginatedGrid = NeoPaginatedGrid;
6331
6566
  exports.NeoProgressbar = NeoProgressbar;