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