@moderneinc/neo-styled-components 2.8.0-next.94ceac → 2.8.0-next.9bca98

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.
@@ -1,13 +1,22 @@
1
1
  import { type AlertProps } from '@mui/material/Alert';
2
2
  import type { ReactNode } from 'react';
3
+ type Intent = 'info' | 'success' | 'error' | 'warning' | 'neutral';
4
+ type BannerType = 'outlined' | 'filled';
3
5
  export interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity' | 'color'> {
4
6
  /**
5
- * The visual style variant of the banner
6
- * @default "light"
7
+ * The intent/purpose of the banner
8
+ * @default "info"
7
9
  *
8
- * @figmaPropMapping color (Dark|Light|Success|Error|Warning) → variant
10
+ * @figmaPropMapping Intention (Info|Success|Error|Warning|Neutral) → intent
9
11
  */
10
- variant?: 'dark' | 'light' | 'success' | 'error' | 'warning';
12
+ intent?: Intent;
13
+ /**
14
+ * Visual type: outlined (light bg) or filled (solid bg)
15
+ * @default "outlined"
16
+ *
17
+ * @figmaPropMapping Type (Outlined|Filled) → type
18
+ */
19
+ type?: BannerType;
11
20
  /**
12
21
  * The message text to display
13
22
  *
@@ -18,20 +27,20 @@ export interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity'
18
27
  * Horizontal alignment of the message content
19
28
  * @default "left"
20
29
  *
21
- * @figmaPropMapping messagePosition (Left|Center) → messagePosition
30
+ * @figmaPropMapping Message Position (Left|Center) → messagePosition
22
31
  */
23
32
  messagePosition?: 'left' | 'center';
24
33
  /**
25
34
  * Optional link text to display after the message
26
35
  *
27
- * @figmaPropMapping link (boolean) → linkText (string)
36
+ * @figmaPropMapping Show Link (boolean) → linkText (string)
28
37
  */
29
38
  linkText?: string;
30
39
  /**
31
40
  * Whether to show the close button
32
41
  * @default true
33
42
  *
34
- * @figmaPropMapping closeIcon → showClose
43
+ * @figmaPropMapping Dismissible → showClose
35
44
  */
36
45
  showClose?: boolean;
37
46
  /**
@@ -48,19 +57,8 @@ export interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity'
48
57
  */
49
58
  onLinkClick?: () => void;
50
59
  }
51
- /**
52
- * NeoBanner - Inline banner/alert component based on MUI Alert
53
- *
54
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4170-2158
55
- *
56
- * Figma Props Mapping:
57
- * - color (Dark|Light|Success|Error|Warning) → variant (dark|light|success|error|warning)
58
- * - messagePosition (Left|Center) → messagePosition ("left"|"center")
59
- * - closeIcon (boolean) → showClose (boolean)
60
- * - link (boolean) → linkText (string)
61
- * - {Message} → message (string)
62
- */
63
60
  export declare const NeoBanner: {
64
- ({ variant, message, messagePosition, linkText, showClose, icon, onClose, onLinkClick, ...props }: NeoBannerProps): import("react/jsx-runtime").JSX.Element;
61
+ ({ intent, type, message, messagePosition, linkText, showClose, icon, onClose, onLinkClick, ...props }: NeoBannerProps): import("react/jsx-runtime").JSX.Element;
65
62
  displayName: string;
66
63
  };
64
+ export {};
@@ -13,7 +13,7 @@ export interface NeoCardSmallProps extends Omit<CardProps, 'children' | 'title'>
13
13
  }
14
14
  export interface NeoCardLargeProps extends Omit<CardProps, 'children' | 'title'> {
15
15
  size: 'large';
16
- state?: 'default' | 'active' | 'disabled' | 'focused';
16
+ disabled?: boolean;
17
17
  cardTheme?: 'light' | 'dark';
18
18
  showIcon?: boolean;
19
19
  showGel?: boolean;
@@ -2,7 +2,7 @@ import { type CheckboxProps } from '@mui/material/Checkbox';
2
2
  import type { ReactNode } from 'react';
3
3
  /**
4
4
  * Custom checkbox icons matching Figma design
5
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-39311
5
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=11487-81
6
6
  *
7
7
  * Checkbox sizes: xs=12x12, small=16x16, medium=20x20
8
8
  * Check/minus paths scaled from Untitled UI (originally 24x24)
@@ -43,7 +43,7 @@ export interface NeoCheckboxProps extends Omit<CheckboxProps, 'size'> {
43
43
  /**
44
44
  * NeoCheckbox - Checkbox component based on MUI Checkbox
45
45
  *
46
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-39311
46
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=11487-81
47
47
  *
48
48
  * Figma Props Mapping:
49
49
  * - Checked (True|False) → checked prop
@@ -20,7 +20,7 @@ export interface NeoCodeSnippetProps extends Omit<ButtonBaseProps, 'children'> {
20
20
  * The size of the code snippet
21
21
  * @default "small"
22
22
  *
23
- * @figma Size (Single line|multiline|inline)
23
+ * @figma Content (Multi|Inline)
24
24
  */
25
25
  size?: CodeSnippetSize;
26
26
  /**
@@ -38,9 +38,9 @@ export interface NeoCodeSnippetProps extends Omit<ButtonBaseProps, 'children'> {
38
38
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4187-30353
39
39
  *
40
40
  * Figma Props Mapping:
41
- * - Color (Light|Dark) → variant (outlined|filled)
42
- * - size (Single line|multiline|inline) → size prop + auto-detected multiline
43
- * - Copy button → endIcon (ReactNode)
41
+ * - Theme (Dark|Light) → variant (filled|outlined)
42
+ * - Content (Multi|Inline) → size prop + auto-detected multiline
43
+ * - Show icon → endIcon (ReactNode, unmappable: boolean vs ReactNode)
44
44
  * - Text content → children prop
45
45
  */
46
46
  export declare const NeoCodeSnippet: {
@@ -32,7 +32,6 @@ export interface NeoRadioProps extends Omit<RadioProps, 'size'> {
32
32
  * NeoRadio - Radio button component based on MUI Radio
33
33
  *
34
34
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40039
35
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40150
36
35
  *
37
36
  * Figma Props Mapping:
38
37
  * - Checked (True|False) → checked prop
package/dist/index.d.ts CHANGED
@@ -362,14 +362,23 @@ declare const NeoBadge: {
362
362
  displayName: string;
363
363
  };
364
364
 
365
+ type Intent = 'info' | 'success' | 'error' | 'warning' | 'neutral';
366
+ type BannerType = 'outlined' | 'filled';
365
367
  interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity' | 'color'> {
366
368
  /**
367
- * The visual style variant of the banner
368
- * @default "light"
369
+ * The intent/purpose of the banner
370
+ * @default "info"
371
+ *
372
+ * @figmaPropMapping Intention (Info|Success|Error|Warning|Neutral) → intent
373
+ */
374
+ intent?: Intent;
375
+ /**
376
+ * Visual type: outlined (light bg) or filled (solid bg)
377
+ * @default "outlined"
369
378
  *
370
- * @figmaPropMapping color (Dark|Light|Success|Error|Warning) → variant
379
+ * @figmaPropMapping Type (Outlined|Filled) → type
371
380
  */
372
- variant?: 'dark' | 'light' | 'success' | 'error' | 'warning';
381
+ type?: BannerType;
373
382
  /**
374
383
  * The message text to display
375
384
  *
@@ -380,20 +389,20 @@ interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity' | 'colo
380
389
  * Horizontal alignment of the message content
381
390
  * @default "left"
382
391
  *
383
- * @figmaPropMapping messagePosition (Left|Center) → messagePosition
392
+ * @figmaPropMapping Message Position (Left|Center) → messagePosition
384
393
  */
385
394
  messagePosition?: 'left' | 'center';
386
395
  /**
387
396
  * Optional link text to display after the message
388
397
  *
389
- * @figmaPropMapping link (boolean) → linkText (string)
398
+ * @figmaPropMapping Show Link (boolean) → linkText (string)
390
399
  */
391
400
  linkText?: string;
392
401
  /**
393
402
  * Whether to show the close button
394
403
  * @default true
395
404
  *
396
- * @figmaPropMapping closeIcon → showClose
405
+ * @figmaPropMapping Dismissible → showClose
397
406
  */
398
407
  showClose?: boolean;
399
408
  /**
@@ -410,20 +419,8 @@ interface NeoBannerProps extends Omit<AlertProps, 'variant' | 'severity' | 'colo
410
419
  */
411
420
  onLinkClick?: () => void;
412
421
  }
413
- /**
414
- * NeoBanner - Inline banner/alert component based on MUI Alert
415
- *
416
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4170-2158
417
- *
418
- * Figma Props Mapping:
419
- * - color (Dark|Light|Success|Error|Warning) → variant (dark|light|success|error|warning)
420
- * - messagePosition (Left|Center) → messagePosition ("left"|"center")
421
- * - closeIcon (boolean) → showClose (boolean)
422
- * - link (boolean) → linkText (string)
423
- * - {Message} → message (string)
424
- */
425
422
  declare const NeoBanner: {
426
- ({ variant, message, messagePosition, linkText, showClose, icon, onClose, onLinkClick, ...props }: NeoBannerProps): react_jsx_runtime.JSX.Element;
423
+ ({ intent, type, message, messagePosition, linkText, showClose, icon, onClose, onLinkClick, ...props }: NeoBannerProps): react_jsx_runtime.JSX.Element;
427
424
  displayName: string;
428
425
  };
429
426
 
@@ -684,7 +681,7 @@ interface StyledComponent<ComponentProps extends {}, SpecificComponentProps exte
684
681
 
685
682
  /**
686
683
  * Custom checkbox icons matching Figma design
687
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-39311
684
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=11487-81
688
685
  *
689
686
  * Checkbox sizes: xs=12x12, small=16x16, medium=20x20
690
687
  * Check/minus paths scaled from Untitled UI (originally 24x24)
@@ -721,7 +718,7 @@ interface NeoCheckboxProps extends Omit<CheckboxProps, 'size'> {
721
718
  /**
722
719
  * NeoCheckbox - Checkbox component based on MUI Checkbox
723
720
  *
724
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-39311
721
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=11487-81
725
722
  *
726
723
  * Figma Props Mapping:
727
724
  * - Checked (True|False) → checked prop
@@ -787,7 +784,7 @@ interface NeoCodeSnippetProps extends Omit<ButtonBaseProps, 'children'> {
787
784
  * The size of the code snippet
788
785
  * @default "small"
789
786
  *
790
- * @figma Size (Single line|multiline|inline)
787
+ * @figma Content (Multi|Inline)
791
788
  */
792
789
  size?: CodeSnippetSize;
793
790
  /**
@@ -805,9 +802,9 @@ interface NeoCodeSnippetProps extends Omit<ButtonBaseProps, 'children'> {
805
802
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4187-30353
806
803
  *
807
804
  * Figma Props Mapping:
808
- * - Color (Light|Dark) → variant (outlined|filled)
809
- * - size (Single line|multiline|inline) → size prop + auto-detected multiline
810
- * - Copy button → endIcon (ReactNode)
805
+ * - Theme (Dark|Light) → variant (filled|outlined)
806
+ * - Content (Multi|Inline) → size prop + auto-detected multiline
807
+ * - Show icon → endIcon (ReactNode, unmappable: boolean vs ReactNode)
811
808
  * - Text content → children prop
812
809
  */
813
810
  declare const NeoCodeSnippet: {
@@ -2006,7 +2003,6 @@ interface NeoRadioProps extends Omit<RadioProps, 'size'> {
2006
2003
  * NeoRadio - Radio button component based on MUI Radio
2007
2004
  *
2008
2005
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40039
2009
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40150
2010
2006
  *
2011
2007
  * Figma Props Mapping:
2012
2008
  * - Checked (True|False) → checked prop
@@ -2688,7 +2684,7 @@ interface NeoCardSmallProps extends Omit<CardProps, 'children' | 'title'> {
2688
2684
  }
2689
2685
  interface NeoCardLargeProps extends Omit<CardProps, 'children' | 'title'> {
2690
2686
  size: 'large';
2691
- state?: 'default' | 'active' | 'disabled' | 'focused';
2687
+ disabled?: boolean;
2692
2688
  cardTheme?: 'light' | 'dark';
2693
2689
  showIcon?: boolean;
2694
2690
  showGel?: boolean;
package/dist/index.esm.js CHANGED
@@ -955,33 +955,27 @@ const __iconNode = [
955
955
  ];
956
956
  const X = createLucideIcon("x", __iconNode);
957
957
 
958
+ const intentColors = {
959
+ info: semanticColors.status.info,
960
+ success: semanticColors.status.success,
961
+ error: semanticColors.status.error,
962
+ warning: semanticColors.status.warning,
963
+ neutral: semanticColors.status.neutral,
964
+ };
958
965
  // biome-ignore lint/suspicious/noExplicitAny: Type cast required to override MUI Alert variant type without global augmentation
959
966
  const StyledAlert$2 = styled(Alert, {
960
- shouldForwardProp: prop => prop !== 'messagePosition' && prop !== 'variant',
961
- })(({ variant = 'light', messagePosition = 'left' }) => {
962
- // Variant-specific styles
963
- const variantStyles = {
964
- dark: {
965
- backgroundColor: semanticColors.surfaces.snackbarBrand,
967
+ shouldForwardProp: prop => prop !== 'messagePosition' && prop !== 'intent' && prop !== 'bannerType',
968
+ })(({ intent = 'info', bannerType = 'outlined', messagePosition = 'left' }) => {
969
+ const palette = intentColors[intent];
970
+ const typeStyles = bannerType === 'filled'
971
+ ? {
972
+ backgroundColor: palette.dark,
966
973
  color: semanticColors.surfaces.white,
967
- },
968
- light: {
969
- backgroundColor: semanticColors.status.info.light,
970
- color: colors.grey['800'],
971
- },
972
- success: {
973
- backgroundColor: semanticColors.status.success.light,
974
- color: colors.grey['800'],
975
- },
976
- error: {
977
- backgroundColor: semanticColors.status.error.light,
978
- color: colors.grey['800'],
979
- },
980
- warning: {
981
- backgroundColor: semanticColors.status.warning.light,
974
+ }
975
+ : {
976
+ backgroundColor: palette.light,
982
977
  color: colors.grey['800'],
983
- },
984
- };
978
+ };
985
979
  return {
986
980
  width: '100%',
987
981
  minHeight: 52,
@@ -995,9 +989,9 @@ const StyledAlert$2 = styled(Alert, {
995
989
  ...(messagePosition === 'center' && { position: 'relative' }),
996
990
  boxShadow: `${shadows.neutralSmall.x}px ${shadows.neutralSmall.y}px ${shadows.neutralSmall.blur}px ${shadows.neutralSmall.spread}px ${shadows.neutralSmall.shadow}`,
997
991
  fontSize: typography.fontSize.default,
998
- fontWeight: typography.fontWeight.regular,
992
+ fontWeight: typography.fontWeight.medium,
999
993
  lineHeight: 1.5,
1000
- ...variantStyles[variant],
994
+ ...typeStyles,
1001
995
  [`& .${alertClasses.icon}`]: {
1002
996
  padding: 0,
1003
997
  opacity: 1,
@@ -1020,26 +1014,18 @@ const StyledAlert$2 = styled(Alert, {
1020
1014
  },
1021
1015
  };
1022
1016
  });
1023
- const LinkText = styled('span')(({ variant = 'light' }) => {
1024
- const getLinkColor = () => {
1025
- if (variant === 'dark') {
1026
- return semanticColors.typography.link.default; // #f9fafb (light gray/white)
1027
- }
1028
- if (variant === 'light') {
1029
- return semanticColors.typography.link.primary; // #2f42ff (blue)
1030
- }
1031
- // For success, error, warning - use dark body color #1f2937
1032
- return colors.grey['800'];
1033
- };
1034
- return {
1035
- fontWeight: typography.fontWeight.semiBold,
1036
- color: getLinkColor(),
1037
- cursor: 'pointer',
1038
- '&:hover': {
1039
- textDecoration: 'underline',
1040
- },
1041
- };
1042
- });
1017
+ const LinkText = styled('span')(({ bannerType = 'outlined' }) => ({
1018
+ marginLeft: 'auto',
1019
+ fontWeight: typography.fontWeight.semiBold,
1020
+ color: bannerType === 'filled'
1021
+ ? semanticColors.typography.link.white
1022
+ : semanticColors.typography.link.primary,
1023
+ cursor: 'pointer',
1024
+ whiteSpace: 'nowrap',
1025
+ '&:hover': {
1026
+ textDecoration: 'underline',
1027
+ },
1028
+ }));
1043
1029
  const StyledIconButton$1 = styled(IconButton)(({ closeIconColor }) => ({
1044
1030
  padding: 0,
1045
1031
  color: closeIconColor,
@@ -1047,35 +1033,9 @@ const StyledIconButton$1 = styled(IconButton)(({ closeIconColor }) => ({
1047
1033
  backgroundColor: 'transparent',
1048
1034
  },
1049
1035
  }));
1050
- /**
1051
- * NeoBanner - Inline banner/alert component based on MUI Alert
1052
- *
1053
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4170-2158
1054
- *
1055
- * Figma Props Mapping:
1056
- * - color (Dark|Light|Success|Error|Warning) → variant (dark|light|success|error|warning)
1057
- * - messagePosition (Left|Center) → messagePosition ("left"|"center")
1058
- * - closeIcon (boolean) → showClose (boolean)
1059
- * - link (boolean) → linkText (string)
1060
- * - {Message} → message (string)
1061
- */
1062
- const NeoBanner = ({ variant = 'light', message, messagePosition = 'left', linkText, showClose = true, icon, onClose, onLinkClick, ...props }) => {
1063
- const getCloseIconColor = () => {
1064
- if (variant === 'dark') {
1065
- return semanticColors.surfaces.white;
1066
- }
1067
- if (variant === 'success') {
1068
- return semanticColors.status.success.default;
1069
- }
1070
- if (variant === 'error') {
1071
- return semanticColors.status.error.default;
1072
- }
1073
- if (variant === 'warning') {
1074
- return semanticColors.status.warning.default;
1075
- }
1076
- return colors.grey['800'];
1077
- };
1078
- return (jsx(StyledAlert$2, { ...props, variant: variant, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton$1, { size: "small", onClick: onClose, closeIconColor: getCloseIconColor(), children: jsx(X, { size: 24 }) })) : undefined, children: messagePosition === 'center' ? (jsxs(Fragment, { children: [icon, jsx("span", { children: message }), linkText && (jsx(LinkText, { variant: variant, onClick: onLinkClick, children: linkText }))] })) : (jsxs(Fragment, { children: [jsx("span", { children: message }), linkText && (jsx(LinkText, { variant: variant, onClick: onLinkClick, children: linkText }))] })) }));
1036
+ const NeoBanner = ({ intent = 'info', type = 'outlined', message, messagePosition = 'left', linkText, showClose = true, icon, onClose, onLinkClick, ...props }) => {
1037
+ const closeIconColor = type === 'filled' ? semanticColors.surfaces.white : intentColors[intent].default;
1038
+ return (jsx(StyledAlert$2, { ...props, intent: intent, bannerType: type, messagePosition: messagePosition, icon: messagePosition === 'left' ? icon || false : false, action: showClose ? (jsx(StyledIconButton$1, { size: "small", onClick: onClose, 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 }))] })) }));
1079
1039
  };
1080
1040
  NeoBanner.displayName = 'NeoBanner';
1081
1041
 
@@ -1606,12 +1566,9 @@ const SmallDescription = styled('p')(({ theme }) => ({
1606
1566
  textOverflow: 'ellipsis',
1607
1567
  }));
1608
1568
  const LargeStyledCard = styled(MuiCard, {
1609
- shouldForwardProp: prop => prop !== 'cardState' && prop !== 'cardTheme',
1610
- })(({ cardState = 'default', cardTheme = 'light' }) => {
1569
+ shouldForwardProp: prop => prop !== 'disabled' && prop !== 'cardTheme',
1570
+ })(({ disabled = false, cardTheme = 'light' }) => {
1611
1571
  const isLight = cardTheme === 'light';
1612
- const isActive = cardState === 'active';
1613
- const isDisabled = cardState === 'disabled';
1614
- const isFocused = cardState === 'focused';
1615
1572
  const activeBorderColor = isLight
1616
1573
  ? semanticColors.buttons.primary.default
1617
1574
  : colors.digitalGreen[300];
@@ -1628,15 +1585,24 @@ const LargeStyledCard = styled(MuiCard, {
1628
1585
  padding: spacing.spacing_2,
1629
1586
  borderRadius: borderRadius.xS,
1630
1587
  backgroundColor: isLight ? semanticColors.surfaces.card : colors.grey[800],
1631
- border: `1px solid ${isActive || isFocused ? activeBorderColor : defaultBorderColor}`,
1632
- boxShadow: isActive ? activeShadow : 'none',
1588
+ border: `1px solid ${defaultBorderColor}`,
1589
+ boxShadow: 'none',
1633
1590
  overflow: 'hidden',
1634
- ...(isFocused && focusRingStyles),
1591
+ cursor: 'pointer',
1592
+ transition: 'border-color 0.2s, box-shadow 0.2s',
1593
+ '&:hover': {
1594
+ borderColor: activeBorderColor,
1595
+ boxShadow: activeShadow,
1596
+ },
1597
+ '&:active': {
1598
+ borderColor: activeBorderColor,
1599
+ boxShadow: activeShadow,
1600
+ },
1635
1601
  '&:focus-visible': {
1636
- borderColor: isLight ? semanticColors.buttons.primary.default : colors.digitalGreen[300],
1602
+ borderColor: activeBorderColor,
1637
1603
  ...focusRingStyles,
1638
1604
  },
1639
- ...(isDisabled && {
1605
+ ...(disabled && {
1640
1606
  opacity: 0.5,
1641
1607
  pointerEvents: 'none',
1642
1608
  cursor: 'not-allowed',
@@ -1698,9 +1664,8 @@ const LargeButtonsRow = styled('div')({
1698
1664
  const SmallCardImpl = ({ logo, recipeCount, title, description, selected = false, disabled = false, onClick, ...props }) => {
1699
1665
  return (jsxs(SmallStyledCard, { selected: selected, disabled: disabled, onClick: disabled ? undefined : onClick, tabIndex: disabled ? -1 : 0, role: "button", "aria-disabled": disabled, "aria-pressed": selected, ...props, children: [jsxs(SmallCardHeader, { children: [jsx(SmallLogoContainer, { children: logo }), jsx(SmallRecipeCount, { children: recipeCount })] }), jsxs(SmallCardContent, { children: [jsx(SmallTitle, { children: title }), jsx(SmallDescription, { children: description })] })] }));
1700
1666
  };
1701
- const LargeCardImpl = ({ state = 'default', cardTheme = 'light', showIcon = true, showGel = true, showButtons = true, icon, gel, title, children, actions, onClick, ...props }) => {
1702
- const isDisabled = state === 'disabled';
1703
- return (jsxs(LargeStyledCard, { cardState: state, cardTheme: cardTheme, onClick: isDisabled ? undefined : onClick, tabIndex: isDisabled ? -1 : 0, "aria-disabled": isDisabled || undefined, ...props, children: [jsxs(LargeTopSection, { children: [jsxs(LargeHeaderRow, { children: [showIcon && icon && jsx(LargeHeaderSlot, { children: icon }), showGel && gel && jsx(LargeHeaderSlot, { children: gel }), title && jsx(LargeHeaderTitle, { cardTheme: cardTheme, children: title })] }), children && jsx(LargeDescription, { cardTheme: cardTheme, children: children })] }), showButtons && actions && jsx(LargeButtonsRow, { children: actions })] }));
1667
+ const LargeCardImpl = ({ disabled = false, cardTheme = 'light', showIcon = true, showGel = true, showButtons = true, icon, gel, title, children, actions, onClick, ...props }) => {
1668
+ return (jsxs(LargeStyledCard, { disabled: disabled, cardTheme: cardTheme, onClick: disabled ? undefined : onClick, tabIndex: disabled ? -1 : 0, "aria-disabled": disabled || undefined, ...props, children: [jsxs(LargeTopSection, { children: [jsxs(LargeHeaderRow, { children: [showIcon && icon && jsx(LargeHeaderSlot, { children: icon }), showGel && gel && jsx(LargeHeaderSlot, { children: gel }), title && jsx(LargeHeaderTitle, { cardTheme: cardTheme, children: title })] }), children && jsx(LargeDescription, { cardTheme: cardTheme, children: children })] }), showButtons && actions && jsx(LargeButtonsRow, { children: actions })] }));
1704
1669
  };
1705
1670
  // ─── Exported component ──────────────────────────────────────────────────────
1706
1671
  const NeoCard = (props) => {
@@ -1786,6 +1751,7 @@ const StyledCheckbox = styled(Checkbox, {
1786
1751
  padding: 0,
1787
1752
  marginTop: size === 'xs' ? 3 : 2,
1788
1753
  color: semanticColors.border.primary,
1754
+ borderRadius: config.borderRadius,
1789
1755
  flexShrink: 0,
1790
1756
  // Root element
1791
1757
  [`&.${checkboxClasses.root}`]: {
@@ -1836,7 +1802,7 @@ const StyledCheckbox = styled(Checkbox, {
1836
1802
  /**
1837
1803
  * NeoCheckbox - Checkbox component based on MUI Checkbox
1838
1804
  *
1839
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-39311
1805
+ * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=11487-81
1840
1806
  *
1841
1807
  * Figma Props Mapping:
1842
1808
  * - Checked (True|False) → checked prop
@@ -1992,9 +1958,9 @@ const IconWrapper$2 = styled('span')(({ theme, isMultiline }) => ({
1992
1958
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4187-30353
1993
1959
  *
1994
1960
  * Figma Props Mapping:
1995
- * - Color (Light|Dark) → variant (outlined|filled)
1996
- * - size (Single line|multiline|inline) → size prop + auto-detected multiline
1997
- * - Copy button → endIcon (ReactNode)
1961
+ * - Theme (Dark|Light) → variant (filled|outlined)
1962
+ * - Content (Multi|Inline) → size prop + auto-detected multiline
1963
+ * - Show icon → endIcon (ReactNode, unmappable: boolean vs ReactNode)
1998
1964
  * - Text content → children prop
1999
1965
  */
2000
1966
  const NeoCodeSnippet = ({ variant = 'outlined', size = 'small', endIcon, children, ...props }) => {
@@ -5663,17 +5629,19 @@ const NeoQuickFilter = ({ placeholder = 'Search...', onKeyDown, autoFocus = fals
5663
5629
  NeoQuickFilter.displayName = 'NeoQuickFilter';
5664
5630
 
5665
5631
  // Custom radio icons to match Figma design
5666
- const UncheckedIcon = ({ size }) => {
5632
+ const UncheckedIcon = ({ size, disabled }) => {
5667
5633
  const dimensions = size === 'small' ? 16 : 20;
5668
5634
  const radius = size === 'small' ? 8 : 10;
5669
- return (jsxs("svg", { width: dimensions, height: dimensions, viewBox: `0 0 ${dimensions} ${dimensions}`, fill: "none", "aria-hidden": "true", children: [jsx("title", { children: "Unchecked radio button" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: radius - 0.5, stroke: semanticColors.border.primary, strokeWidth: "1", fill: "transparent" })] }));
5635
+ return (jsxs("svg", { width: dimensions, height: dimensions, viewBox: `0 0 ${dimensions} ${dimensions}`, fill: "none", "aria-hidden": "true", children: [jsx("title", { children: "Unchecked radio button" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: radius - 0.5, stroke: semanticColors.border.primary, strokeWidth: "1", fill: disabled ? semanticColors.buttons.primary.disabled : 'transparent' })] }));
5670
5636
  };
5671
- const CheckedIcon = ({ size }) => {
5637
+ const CheckedIcon = ({ size, disabled }) => {
5672
5638
  const dimensions = size === 'small' ? 16 : 20;
5673
5639
  const radius = size === 'small' ? 8 : 10;
5674
5640
  const inset = size === 'small' ? 0.3125 : 0.3; // 31.25% or 30%
5675
5641
  const innerRadius = radius * (1 - 2 * inset);
5676
- return (jsxs("svg", { width: dimensions, height: dimensions, viewBox: `0 0 ${dimensions} ${dimensions}`, fill: "none", "aria-hidden": "true", children: [jsx("title", { children: "Checked radio button" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: radius - 0.5, fill: semanticColors.buttons.primary.default, stroke: semanticColors.buttons.primary.default, strokeWidth: "1" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: innerRadius, fill: semanticColors.surfaces.white })] }));
5642
+ return (jsxs("svg", { width: dimensions, height: dimensions, viewBox: `0 0 ${dimensions} ${dimensions}`, fill: "none", "aria-hidden": "true", children: [jsx("title", { children: "Checked radio button" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: radius - 0.5, fill: disabled
5643
+ ? semanticColors.buttons.primary.disabled
5644
+ : semanticColors.buttons.primary.default, stroke: disabled ? semanticColors.border.primary : semanticColors.buttons.primary.default, strokeWidth: "1" }), jsx("circle", { cx: dimensions / 2, cy: dimensions / 2, r: innerRadius, fill: disabled ? semanticColors.icons.disabled : semanticColors.surfaces.white })] }));
5677
5645
  };
5678
5646
  const RadioContainer = styled('label')(({ disabled }) => ({
5679
5647
  display: 'inline-flex',
@@ -5718,6 +5686,10 @@ const StyledRadio = styled(Radio, {
5718
5686
  height: dimensions,
5719
5687
  flexShrink: 0,
5720
5688
  borderRadius: radius,
5689
+ color: semanticColors.border.primary,
5690
+ [`&.${radioClasses.checked}`]: {
5691
+ color: semanticColors.buttons.primary.default,
5692
+ },
5721
5693
  '&:hover': {
5722
5694
  backgroundColor: 'transparent',
5723
5695
  },
@@ -5735,9 +5707,12 @@ const StyledRadio = styled(Radio, {
5735
5707
  backgroundColor: 'transparent',
5736
5708
  },
5737
5709
  },
5738
- // Disabled state
5710
+ // Disabled state — icons handle their own disabled colors
5739
5711
  [`&.${radioClasses.disabled}`]: {
5740
- opacity: 0.5,
5712
+ color: semanticColors.border.primary,
5713
+ [`&.${radioClasses.checked}`]: {
5714
+ color: semanticColors.border.primary,
5715
+ },
5741
5716
  },
5742
5717
  };
5743
5718
  });
@@ -5745,7 +5720,6 @@ const StyledRadio = styled(Radio, {
5745
5720
  * NeoRadio - Radio button component based on MUI Radio
5746
5721
  *
5747
5722
  * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40039
5748
- * @figma https://www.figma.com/design/fQTkGSFbYyE7LiHuQJsENC/Neo---Moderne-Design-system---2025?node-id=4122-40150
5749
5723
  *
5750
5724
  * Figma Props Mapping:
5751
5725
  * - Checked (True|False) → checked prop
@@ -5785,9 +5759,9 @@ const StyledRadio = styled(Radio, {
5785
5759
  * </RadioGroup>
5786
5760
  */
5787
5761
  const NeoRadio = ({ size = 'medium', label, helperText, disabled, ...props }) => {
5788
- // Custom icons based on size
5789
- const uncheckedIcon = jsx(UncheckedIcon, { size: size });
5790
- const checkedIcon = jsx(CheckedIcon, { size: size });
5762
+ // Custom icons based on size and disabled state
5763
+ const uncheckedIcon = jsx(UncheckedIcon, { size: size, disabled: disabled });
5764
+ const checkedIcon = jsx(CheckedIcon, { size: size, disabled: disabled });
5791
5765
  // If no label, return just the radio button
5792
5766
  if (!label && !helperText) {
5793
5767
  return (jsx(StyledRadio, { size: size, disabled: disabled, icon: uncheckedIcon, checkedIcon: checkedIcon, ...props }));