@cdx-ui/components 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +8 -12
  2. package/lib/commonjs/components/Radio/index.js +14 -3
  3. package/lib/commonjs/components/Radio/index.js.map +1 -1
  4. package/lib/commonjs/components/Radio/styles.js +24 -8
  5. package/lib/commonjs/components/Radio/styles.js.map +1 -1
  6. package/lib/commonjs/components/Switch/styles.js +14 -14
  7. package/lib/commonjs/components/Switch/styles.js.map +1 -1
  8. package/lib/commonjs/figma/Field.Radio.figma.js +58 -0
  9. package/lib/commonjs/figma/Field.Radio.figma.js.map +1 -0
  10. package/lib/commonjs/figma/Radio.Group.figma.js +24 -0
  11. package/lib/commonjs/figma/Radio.Group.figma.js.map +1 -0
  12. package/lib/commonjs/figma/Radio.figma.js +12 -6
  13. package/lib/commonjs/figma/Radio.figma.js.map +1 -1
  14. package/lib/module/components/Radio/index.js +14 -3
  15. package/lib/module/components/Radio/index.js.map +1 -1
  16. package/lib/module/components/Radio/styles.js +25 -9
  17. package/lib/module/components/Radio/styles.js.map +1 -1
  18. package/lib/module/components/Switch/styles.js +14 -14
  19. package/lib/module/components/Switch/styles.js.map +1 -1
  20. package/lib/module/figma/Field.Radio.figma.js +52 -0
  21. package/lib/module/figma/Field.Radio.figma.js.map +1 -0
  22. package/lib/module/figma/Radio.Group.figma.js +18 -0
  23. package/lib/module/figma/Radio.Group.figma.js.map +1 -0
  24. package/lib/module/figma/Radio.figma.js +12 -6
  25. package/lib/module/figma/Radio.figma.js.map +1 -1
  26. package/lib/typescript/components/Radio/index.d.ts.map +1 -1
  27. package/lib/typescript/components/Radio/styles.d.ts.map +1 -1
  28. package/lib/typescript/components/Switch/styles.d.ts.map +1 -1
  29. package/lib/typescript/figma/Field.Radio.figma.d.ts +8 -0
  30. package/lib/typescript/figma/Field.Radio.figma.d.ts.map +1 -0
  31. package/lib/typescript/figma/Radio.Group.figma.d.ts +8 -0
  32. package/lib/typescript/figma/Radio.Group.figma.d.ts.map +1 -0
  33. package/lib/typescript/figma/Radio.figma.d.ts.map +1 -1
  34. package/package.json +5 -5
  35. package/src/components/Radio/index.tsx +22 -6
  36. package/src/components/Radio/styles.ts +46 -6
  37. package/src/components/Switch/styles.ts +23 -15
@@ -2,12 +2,14 @@
2
2
 
3
3
  import { Platform } from 'react-native';
4
4
  import { cva } from '@cdx-ui/utils';
5
- import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants';
6
- export const radioRootVariants = cva(['flex-row items-center gap-2', 'data-[disabled=true]:opacity-[var(--opacity-disabled)]', DISABLED_CURSOR,
5
+ import { DISABLED_CURSOR, DISABLED_OPACITY, TRANSITION_COLORS } from '../../styles/constants';
6
+ export const radioRootVariants = cva(['flex-row items-center gap-2', DISABLED_OPACITY, DISABLED_CURSOR, 'data-[readonly=true]:cursor-default',
7
7
  // Suppress default :focus-visible outline on the role="radio" Pressable;
8
8
  // focus ring is drawn on the indicator instead of wrapping the whole control.
9
9
  'web:outline-none web:focus:outline-none web:focus-visible:outline-none']);
10
- export const radioIndicatorVariants = cva(['items-center justify-center', 'rounded-[var(--border-radius-round)]', 'border-[length:var(--border-width-selected)]', 'h-5 w-5', 'bg-surface-primary', 'data-[checked=false]:border-content-secondary', 'data-[checked=true]:border-stroke-action', 'data-[invalid=true]:border-stroke-danger', Platform.select({
10
+ export const radioIndicatorVariants = cva(['items-center justify-center', 'rounded-[var(--border-radius-round)]', 'border-[length:var(--border-width-selected)]', 'h-5 w-5',
11
+ // Figma: indicator fill is transparent; selection reads via border + inner dot only.
12
+ 'bg-transparent', 'data-[checked=false]:border-content-secondary', 'data-[checked=true]:border-stroke-action', 'data-[invalid=true]:border-stroke-danger', Platform.select({
11
13
  web: [TRANSITION_COLORS, 'group',
12
14
  // Hover — unchecked (Figma: border unchanged, bg overlay at opacity/hover)
13
15
  'data-[hover=true]:data-[checked=false]:bg-content-secondary/[0.08]',
@@ -15,19 +17,33 @@ export const radioIndicatorVariants = cva(['items-center justify-center', 'round
15
17
  'data-[hover=true]:data-[invalid=true]:data-[checked=false]:bg-surface-danger-strong/[0.08]', 'data-[hover=true]:data-[checked=true]:border-surface-action-strong-hover', 'data-[hover=true]:data-[invalid=true]:border-surface-danger-strong-hover',
16
18
  // Active — CSS :active (web root does not track press via data-active).
17
19
  // data-[hover=true] guard ensures active beats hover by specificity (0,3,0 > 0,2,0).
18
- 'web:active:data-[hover=true]:data-[checked=false]:border-stroke-hover', 'web:active:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-surface-danger-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:border-surface-action-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-surface-danger-strong-active', 'web:data-[focus-visible=true]:outline-none', 'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-stroke-focus web:data-[focus-visible=true]:ring-offset-2'].join(' '),
20
+ 'web:active:data-[hover=true]:data-[checked=false]:border-stroke-hover', 'web:active:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-surface-danger-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:border-surface-action-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-surface-danger-strong-active',
21
+ // Focus ring — applies to read-only as well (focusable + aria-readonly).
22
+ 'web:data-[focus-visible=true]:outline-none', 'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-stroke-focus web:data-[focus-visible=true]:ring-offset-2',
23
+ // Read-only — Figma: transparent fill + content-tertiary border (checked and unchecked).
24
+ // After hover/active so equal-or-higher specificity keeps the static treatment.
25
+ // Invalid is not a Figma readonly variant; retain danger so error remains visible.
26
+ 'data-[readonly=true]:data-[checked=false]:border-content-tertiary', 'data-[readonly=true]:data-[checked=true]:border-content-tertiary', 'data-[readonly=true]:data-[invalid=true]:border-stroke-danger', 'data-[readonly=true]:data-[hover=true]:data-[checked=false]:bg-transparent', 'data-[readonly=true]:data-[hover=true]:data-[invalid=true]:data-[checked=false]:bg-transparent', 'data-[readonly=true]:data-[hover=true]:data-[checked=false]:border-content-tertiary', 'data-[readonly=true]:data-[hover=true]:data-[checked=true]:border-content-tertiary', 'data-[readonly=true]:data-[hover=true]:data-[invalid=true]:border-stroke-danger', 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=false]:border-content-tertiary', 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:border-content-tertiary', 'web:active:data-[readonly=true]:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-stroke-danger', 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-stroke-danger'].join(' '),
19
27
  default: [
20
28
  // Native: Uniwind only evaluates the last data-[] condition in a compound chain.
21
29
  // Use single-condition data-[field-state=...] selectors (emitted by RadioIndicator).
22
- 'data-[field-state=active]:border-stroke-hover', 'data-[field-state=invalid-active]:border-surface-danger-strong-active', 'data-[field-state=checked-active]:border-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:border-surface-danger-strong-active'].join(' ')
30
+ 'data-[field-state=readonly-unchecked]:border-content-tertiary', 'data-[field-state=readonly-checked]:border-content-tertiary', 'data-[field-state=readonly-unchecked-invalid]:border-stroke-danger', 'data-[field-state=readonly-checked-invalid]:border-stroke-danger', 'data-[field-state=active]:border-stroke-hover', 'data-[field-state=invalid-active]:border-surface-danger-strong-active', 'data-[field-state=checked-active]:border-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:border-surface-danger-strong-active'].join(' ')
23
31
  })]);
24
- export const radioInnerDotVariants = cva(['rounded-[var(--border-radius-round)]', 'h-2.5 w-2.5', 'scale-0', 'data-[checked=true]:scale-100', 'bg-surface-action-strong', 'data-[invalid=true]:bg-surface-danger-strong', Platform.select({
32
+ export const radioInnerDotVariants = cva(['rounded-[var(--border-radius-round)]', 'overflow-hidden', 'h-2.5 w-2.5',
33
+ // Opacity (not scale): iOS compositing of scale-0 views samples the parent ring, so the
34
+ // checked fill never paints and the dot looks content-tertiary instead of content-primary.
35
+ 'opacity-0', 'data-[checked=true]:opacity-100', 'bg-surface-action-strong', 'data-[invalid=true]:bg-surface-danger-strong', Platform.select({
25
36
  web: ['data-[hover=true]:bg-surface-action-strong-hover', 'data-[hover=true]:data-[invalid=true]:bg-surface-danger-strong-hover',
26
37
  // Active via group-active on indicator (inner dot is not the :active target).
27
- 'web:group-active:data-[hover=true]:data-[checked=true]:bg-surface-action-strong-active', 'web:group-active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong-active'].join(' '),
28
- default: ['data-[field-state=checked-active]:bg-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:bg-surface-danger-strong-active'].join(' ')
38
+ 'web:group-active:data-[hover=true]:data-[checked=true]:bg-surface-action-strong-active', 'web:group-active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong-active',
39
+ // Read-only checked — Figma: content-primary dot; invalid retains danger.
40
+ 'data-[readonly=true]:data-[checked=true]:bg-content-primary', 'data-[readonly=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong', 'web:group-active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:bg-content-primary', 'web:group-active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong'].join(' '),
41
+ default: ['data-[field-state=checked-active]:bg-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:bg-surface-danger-strong-active',
42
+ // `!` beats the base `bg-surface-action-strong` — Uniwind native does not cascade
43
+ // data-attribute backgrounds over an unconditional bg on the same View.
44
+ 'data-[readonly=true]:bg-content-primary!', 'data-[field-state=readonly-checked]:bg-content-primary!', 'data-[field-state=readonly-checked-invalid]:bg-surface-danger-strong!'].join(' ')
29
45
  })]);
30
- export const radioLabelVariants = cva(['body-md', 'text-content-primary']);
46
+ export const radioLabelVariants = cva(['body-md', 'text-content-primary', 'data-[disabled=true]:text-content-tertiary', 'data-[readonly=true]:cursor-default']);
31
47
  export const radioGroupVariants = cva([], {
32
48
  variants: {
33
49
  direction: {
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","cva","DISABLED_CURSOR","TRANSITION_COLORS","radioRootVariants","radioIndicatorVariants","select","web","join","default","radioInnerDotVariants","radioLabelVariants","radioGroupVariants","variants","direction","column","row","defaultVariants"],"sourceRoot":"../../../../src","sources":["components/Radio/styles.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,GAAG,QAAQ,eAAe;AACnC,SAASC,eAAe,EAAEC,iBAAiB,QAAQ,wBAAwB;AAE3E,OAAO,MAAMC,iBAAiB,GAAGH,GAAG,CAAC,CACnC,6BAA6B,EAC7B,wDAAwD,EACxDC,eAAe;AACf;AACA;AACA,wEAAwE,CACzE,CAAC;AAEF,OAAO,MAAMG,sBAAsB,GAAGJ,GAAG,CAAC,CACxC,6BAA6B,EAC7B,sCAAsC,EACtC,8CAA8C,EAC9C,SAAS,EACT,oBAAoB,EACpB,+CAA+C,EAC/C,0CAA0C,EAC1C,0CAA0C,EAC1CD,QAAQ,CAACM,MAAM,CAAC;EACdC,GAAG,EAAE,CACHJ,iBAAiB,EACjB,OAAO;EACP;EACA,oEAAoE;EACpE;EACA,4FAA4F,EAC5F,0EAA0E,EAC1E,0EAA0E;EAC1E;EACA;EACA,uEAAuE,EACvE,2GAA2G,EAC3G,sFAAsF,EACtF,0GAA0G,EAC1G,4CAA4C,EAC5C,kIAAkI,CACnI,CAACK,IAAI,CAAC,GAAG,CAAC;EACXC,OAAO,EAAE;EACP;EACA;EACA,+CAA+C,EAC/C,uEAAuE,EACvE,uEAAuE,EACvE,+EAA+E,CAChF,CAACD,IAAI,CAAC,GAAG;AACZ,CAAC,CAAC,CACH,CAAC;AAEF,OAAO,MAAME,qBAAqB,GAAGT,GAAG,CAAC,CACvC,sCAAsC,EACtC,aAAa,EACb,SAAS,EACT,+BAA+B,EAC/B,0BAA0B,EAC1B,8CAA8C,EAC9CD,QAAQ,CAACM,MAAM,CAAC;EACdC,GAAG,EAAE,CACH,kDAAkD,EAClD,sEAAsE;EACtE;EACA,wFAAwF,EACxF,4GAA4G,CAC7G,CAACC,IAAI,CAAC,GAAG,CAAC;EACXC,OAAO,EAAE,CACP,mEAAmE,EACnE,2EAA2E,CAC5E,CAACD,IAAI,CAAC,GAAG;AACZ,CAAC,CAAC,CACH,CAAC;AAEF,OAAO,MAAMG,kBAAkB,GAAGV,GAAG,CAAC,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;AAE1E,OAAO,MAAMW,kBAAkB,GAAGX,GAAG,CAAC,EAAE,EAAE;EACxCY,QAAQ,EAAE;IACRC,SAAS,EAAE;MACTC,MAAM,EAAE,OAAO;MACfC,GAAG,EAAE;IACP;EACF,CAAC;EACDC,eAAe,EAAE;IAAEH,SAAS,EAAE;EAAS;AACzC,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Platform","cva","DISABLED_CURSOR","DISABLED_OPACITY","TRANSITION_COLORS","radioRootVariants","radioIndicatorVariants","select","web","join","default","radioInnerDotVariants","radioLabelVariants","radioGroupVariants","variants","direction","column","row","defaultVariants"],"sourceRoot":"../../../../src","sources":["components/Radio/styles.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,GAAG,QAAQ,eAAe;AACnC,SAASC,eAAe,EAAEC,gBAAgB,EAAEC,iBAAiB,QAAQ,wBAAwB;AAE7F,OAAO,MAAMC,iBAAiB,GAAGJ,GAAG,CAAC,CACnC,6BAA6B,EAC7BE,gBAAgB,EAChBD,eAAe,EACf,qCAAqC;AACrC;AACA;AACA,wEAAwE,CACzE,CAAC;AAEF,OAAO,MAAMI,sBAAsB,GAAGL,GAAG,CAAC,CACxC,6BAA6B,EAC7B,sCAAsC,EACtC,8CAA8C,EAC9C,SAAS;AACT;AACA,gBAAgB,EAChB,+CAA+C,EAC/C,0CAA0C,EAC1C,0CAA0C,EAC1CD,QAAQ,CAACO,MAAM,CAAC;EACdC,GAAG,EAAE,CACHJ,iBAAiB,EACjB,OAAO;EACP;EACA,oEAAoE;EACpE;EACA,4FAA4F,EAC5F,0EAA0E,EAC1E,0EAA0E;EAC1E;EACA;EACA,uEAAuE,EACvE,2GAA2G,EAC3G,sFAAsF,EACtF,0GAA0G;EAC1G;EACA,4CAA4C,EAC5C,kIAAkI;EAClI;EACA;EACA;EACA,mEAAmE,EACnE,kEAAkE,EAClE,+DAA+D,EAC/D,4EAA4E,EAC5E,gGAAgG,EAChG,qFAAqF,EACrF,oFAAoF,EACpF,iFAAiF,EACjF,gGAAgG,EAChG,+FAA+F,EAC/F,iHAAiH,EACjH,gHAAgH,CACjH,CAACK,IAAI,CAAC,GAAG,CAAC;EACXC,OAAO,EAAE;EACP;EACA;EACA,+DAA+D,EAC/D,6DAA6D,EAC7D,oEAAoE,EACpE,kEAAkE,EAClE,+CAA+C,EAC/C,uEAAuE,EACvE,uEAAuE,EACvE,+EAA+E,CAChF,CAACD,IAAI,CAAC,GAAG;AACZ,CAAC,CAAC,CACH,CAAC;AAEF,OAAO,MAAME,qBAAqB,GAAGV,GAAG,CAAC,CACvC,sCAAsC,EACtC,iBAAiB,EACjB,aAAa;AACb;AACA;AACA,WAAW,EACX,iCAAiC,EACjC,0BAA0B,EAC1B,8CAA8C,EAC9CD,QAAQ,CAACO,MAAM,CAAC;EACdC,GAAG,EAAE,CACH,kDAAkD,EAClD,sEAAsE;EACtE;EACA,wFAAwF,EACxF,4GAA4G;EAC5G;EACA,6DAA6D,EAC7D,uFAAuF,EACvF,gGAAgG,EAChG,0HAA0H,CAC3H,CAACC,IAAI,CAAC,GAAG,CAAC;EACXC,OAAO,EAAE,CACP,mEAAmE,EACnE,2EAA2E;EAC3E;EACA;EACA,0CAA0C,EAC1C,yDAAyD,EACzD,uEAAuE,CACxE,CAACD,IAAI,CAAC,GAAG;AACZ,CAAC,CAAC,CACH,CAAC;AAEF,OAAO,MAAMG,kBAAkB,GAAGX,GAAG,CAAC,CACpC,SAAS,EACT,sBAAsB,EACtB,4CAA4C,EAC5C,qCAAqC,CACtC,CAAC;AAEF,OAAO,MAAMY,kBAAkB,GAAGZ,GAAG,CAAC,EAAE,EAAE;EACxCa,QAAQ,EAAE;IACRC,SAAS,EAAE;MACTC,MAAM,EAAE,OAAO;MACfC,GAAG,EAAE;IACP;EACF,CAAC;EACDC,eAAe,EAAE;IAAEH,SAAS,EAAE;EAAS;AACzC,CAAC,CAAC","ignoreList":[]}
@@ -6,10 +6,10 @@ import { cva } from '@cdx-ui/utils';
6
6
  // NATIVE — Uniwind className bindings for RN Switch
7
7
  // =============================================================================
8
8
 
9
- export const switchThumbColorVariants = cva(['accent-white'], {
9
+ export const switchThumbColorVariants = cva(['accent-surface-primary'], {
10
10
  variants: {
11
11
  isDisabled: {
12
- true: 'accent-gray-200',
12
+ true: 'accent-surface-neutral-subtle',
13
13
  false: ''
14
14
  }
15
15
  },
@@ -17,10 +17,10 @@ export const switchThumbColorVariants = cva(['accent-white'], {
17
17
  isDisabled: false
18
18
  }
19
19
  });
20
- export const switchTrackOnVariants = cva(['accent-blue-500'], {
20
+ export const switchTrackOnVariants = cva(['accent-surface-action-strong'], {
21
21
  variants: {
22
22
  isInvalid: {
23
- true: 'accent-red-500',
23
+ true: 'accent-surface-danger-strong',
24
24
  false: ''
25
25
  }
26
26
  },
@@ -28,10 +28,10 @@ export const switchTrackOnVariants = cva(['accent-blue-500'], {
28
28
  isInvalid: false
29
29
  }
30
30
  });
31
- export const switchTrackOffVariants = cva(['accent-gray-300'], {
31
+ export const switchTrackOffVariants = cva(['accent-surface-neutral-subtle'], {
32
32
  variants: {
33
33
  isInvalid: {
34
- true: 'accent-red-300',
34
+ true: 'accent-surface-danger-subtle',
35
35
  false: ''
36
36
  }
37
37
  },
@@ -39,10 +39,10 @@ export const switchTrackOffVariants = cva(['accent-gray-300'], {
39
39
  isInvalid: false
40
40
  }
41
41
  });
42
- export const switchIosBgVariants = cva(['accent-gray-300'], {
42
+ export const switchIosBgVariants = cva(['accent-surface-neutral-subtle'], {
43
43
  variants: {
44
44
  isInvalid: {
45
- true: 'accent-red-300',
45
+ true: 'accent-surface-danger-subtle',
46
46
  false: ''
47
47
  }
48
48
  },
@@ -55,7 +55,7 @@ export const switchIosBgVariants = cva(['accent-gray-300'], {
55
55
  // WEB — Tailwind classes for custom Pressable toggle
56
56
  // =============================================================================
57
57
 
58
- export const switchTrackVariants = cva(['flex-row items-center rounded-full cursor-pointer', 'transition-colors duration-200', 'data-[disabled=true]:opacity-50 data-[disabled=true]:cursor-not-allowed', 'web:data-[focus-visible=true]:ring-3 web:data-[focus-visible=true]:ring-blue-300/50', 'web:data-[invalid=true]:data-[focus-visible=true]:ring-red-300/50'], {
58
+ export const switchTrackVariants = cva(['flex-row items-center rounded-full cursor-pointer', 'transition-colors duration-200', 'data-[disabled=true]:opacity-50 data-[disabled=true]:cursor-not-allowed', 'web:data-[focus-visible=true]:ring-3 web:data-[focus-visible=true]:ring-stroke-focus/50', 'web:data-[invalid=true]:data-[focus-visible=true]:ring-stroke-danger/50'], {
59
59
  variants: {
60
60
  size: {
61
61
  sm: 'w-9 h-5 p-0.5',
@@ -70,8 +70,8 @@ export const switchTrackVariants = cva(['flex-row items-center rounded-full curs
70
70
  export const switchWebTrackColorVariants = cva([], {
71
71
  variants: {
72
72
  isChecked: {
73
- true: 'bg-blue-500 data-[hover=true]:bg-blue-600',
74
- false: 'bg-gray-300 data-[hover=true]:bg-gray-400'
73
+ true: 'bg-surface-action-strong data-[hover=true]:bg-surface-action-strong-hover',
74
+ false: 'bg-surface-neutral-subtle data-[hover=true]:bg-surface-neutral-subtle-hover'
75
75
  },
76
76
  isInvalid: {
77
77
  true: '',
@@ -81,18 +81,18 @@ export const switchWebTrackColorVariants = cva([], {
81
81
  compoundVariants: [{
82
82
  isChecked: true,
83
83
  isInvalid: true,
84
- className: 'bg-red-500 data-[hover=true]:bg-red-600'
84
+ className: 'bg-surface-danger-strong data-[hover=true]:bg-surface-danger-strong-hover'
85
85
  }, {
86
86
  isChecked: false,
87
87
  isInvalid: true,
88
- className: 'bg-red-300 data-[hover=true]:bg-red-400'
88
+ className: 'bg-surface-danger-subtle data-[hover=true]:bg-surface-danger-subtle-hover'
89
89
  }],
90
90
  defaultVariants: {
91
91
  isChecked: false,
92
92
  isInvalid: false
93
93
  }
94
94
  });
95
- export const switchThumbVariants = cva(['rounded-full bg-white shadow-sm', 'transition-transform duration-200'], {
95
+ export const switchThumbVariants = cva(['rounded-full bg-surface-primary shadow-sm', 'transition-transform duration-200'], {
96
96
  variants: {
97
97
  size: {
98
98
  sm: 'w-4 h-4',
@@ -1 +1 @@
1
- {"version":3,"names":["cva","switchThumbColorVariants","variants","isDisabled","true","false","defaultVariants","switchTrackOnVariants","isInvalid","switchTrackOffVariants","switchIosBgVariants","switchTrackVariants","size","sm","md","lg","switchWebTrackColorVariants","isChecked","compoundVariants","className","switchThumbVariants"],"sourceRoot":"../../../../src","sources":["components/Switch/styles.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["cva","switchThumbColorVariants","variants","isDisabled","true","false","defaultVariants","switchTrackOnVariants","isInvalid","switchTrackOffVariants","switchIosBgVariants","switchTrackVariants","size","sm","md","lg","switchWebTrackColorVariants","isChecked","compoundVariants","className","switchThumbVariants"],"sourceRoot":"../../../../src","sources":["components/Switch/styles.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ // url=https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=5531-6635
4
+ // source=packages/components/src/components/Field/index.tsx
5
+ // component=Field
6
+ import figma from 'figma';
7
+ const instance = figma.selectedInstance;
8
+ const showLabel = instance.getBoolean('Show Label?');
9
+ const showHelperText = instance.getBoolean('Show Helper Text?');
10
+ const showErrorText = instance.getBoolean('Show Error Text?');
11
+
12
+ // Enum-as-boolean: isInvalid / isDisabled are VARIANT properties in Figma (string values "true"/"false").
13
+ // Map "false" to undefined so renderProp omits them from the snippet.
14
+ // isFocused is a runtime interaction state and is intentionally omitted.
15
+ const isInvalid = instance.getEnum('isInvalid', {
16
+ true: true,
17
+ false: undefined
18
+ });
19
+ const isDisabled = instance.getEnum('isDisabled', {
20
+ true: true,
21
+ false: undefined
22
+ });
23
+ const isInvalidProp = figma.helpers.react.renderProp('isInvalid', isInvalid);
24
+ const isDisabledProp = figma.helpers.react.renderProp('isDisabled', isDisabled);
25
+ const labelText = instance.findText('{label}', {
26
+ traverseInstances: true
27
+ }).textContent;
28
+ const helperText = instance.findText('{HelperText}', {
29
+ traverseInstances: true
30
+ }).textContent;
31
+ const errorText = instance.findText('{ErrorText}', {
32
+ traverseInstances: true
33
+ }).textContent;
34
+ const radioGroup = instance.findInstance('Radio.Group');
35
+ let radioGroupSnippet;
36
+ if (radioGroup?.type === 'INSTANCE') {
37
+ radioGroupSnippet = radioGroup.executeTemplate().example;
38
+ }
39
+ export default {
40
+ id: 'field-radio',
41
+ // Only import Field here; the nested Radio.Group template provides its own "import { Radio } …" line.
42
+ // Code Connect merges the two separate import statements from the same package automatically.
43
+ imports: ["import { Field } from '@cdx-ui/components'"],
44
+ example: figma.code`
45
+ <Field${isInvalidProp}${isDisabledProp}>
46
+ ${showLabel ? figma.code`<Field.Label>${labelText}</Field.Label>` : null}
47
+ ${radioGroupSnippet}
48
+ ${!isInvalid && showHelperText ? figma.code`<Field.Helper>${helperText}</Field.Helper>` : null}
49
+ ${isInvalid && showErrorText ? figma.code`<Field.Error>${errorText}</Field.Error>` : null}
50
+ </Field>`
51
+ };
52
+ //# sourceMappingURL=Field.Radio.figma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["figma","instance","selectedInstance","showLabel","getBoolean","showHelperText","showErrorText","isInvalid","getEnum","true","false","undefined","isDisabled","isInvalidProp","helpers","react","renderProp","isDisabledProp","labelText","findText","traverseInstances","textContent","helperText","errorText","radioGroup","findInstance","radioGroupSnippet","type","executeTemplate","example","id","imports","code"],"sourceRoot":"../../../src","sources":["figma/Field.Radio.figma.ts"],"mappings":";;AAAA;AACA;AACA;AACA,OAAOA,KAAK,MAAM,OAAO;AAEzB,MAAMC,QAAQ,GAAGD,KAAK,CAACE,gBAAgB;AAEvC,MAAMC,SAAS,GAAGF,QAAQ,CAACG,UAAU,CAAC,aAAa,CAAC;AACpD,MAAMC,cAAc,GAAGJ,QAAQ,CAACG,UAAU,CAAC,mBAAmB,CAAC;AAC/D,MAAME,aAAa,GAAGL,QAAQ,CAACG,UAAU,CAAC,kBAAkB,CAAC;;AAE7D;AACA;AACA;AACA,MAAMG,SAAS,GAAGN,QAAQ,CAACO,OAAO,CAAC,WAAW,EAAE;EAC9CC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAEC;AACT,CAAC,CAAC;AACF,MAAMC,UAAU,GAAGX,QAAQ,CAACO,OAAO,CAAC,YAAY,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAEC;AACT,CAAC,CAAC;AAEF,MAAME,aAAa,GAAGb,KAAK,CAACc,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,WAAW,EAAET,SAAS,CAAC;AAC5E,MAAMU,cAAc,GAAGjB,KAAK,CAACc,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,YAAY,EAAEJ,UAAU,CAAC;AAE/E,MAAMM,SAAS,GACbjB,QAAQ,CAACkB,QAAQ,CAAC,SAAS,EAAE;EAC3BC,iBAAiB,EAAE;AACrB,CAAC,CAAC,CACFC,WAAW;AACb,MAAMC,UAAU,GACdrB,QAAQ,CAACkB,QAAQ,CAAC,cAAc,EAAE;EAChCC,iBAAiB,EAAE;AACrB,CAAC,CAAC,CACFC,WAAW;AACb,MAAME,SAAS,GACbtB,QAAQ,CAACkB,QAAQ,CAAC,aAAa,EAAE;EAC/BC,iBAAiB,EAAE;AACrB,CAAC,CAAC,CACFC,WAAW;AAEb,MAAMG,UAAU,GAAGvB,QAAQ,CAACwB,YAAY,CAAC,aAAa,CAAC;AACvD,IAAIC,iBAA8D;AAClE,IAAIF,UAAU,EAAEG,IAAI,KAAK,UAAU,EAAE;EACnCD,iBAAiB,GAAGF,UAAU,CAACI,eAAe,CAAC,CAAC,CAACC,OAAO;AAC1D;AAEA,eAAe;EACbC,EAAE,EAAE,aAAa;EACjB;EACA;EACAC,OAAO,EAAE,CAAC,4CAA4C,CAAC;EACvDF,OAAO,EAAE7B,KAAK,CAACgC,IAAI;AACrB,QAAQnB,aAAa,GAAGI,cAAc;AACtC,IAAId,SAAS,GAAGH,KAAK,CAACgC,IAAI,gBAAgBd,SAAS,gBAAgB,GAAG,IAAI;AAC1E,IAAIQ,iBAAiB;AACrB,IAAI,CAACnB,SAAS,IAAIF,cAAc,GAAGL,KAAK,CAACgC,IAAI,iBAAiBV,UAAU,iBAAiB,GAAG,IAAI;AAChG,IAAIf,SAAS,IAAID,aAAa,GAAGN,KAAK,CAACgC,IAAI,gBAAgBT,SAAS,gBAAgB,GAAG,IAAI;AAC3F;AACA,CAAC","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ // url=https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=5531-5344
4
+ // source=packages/components/src/components/Radio/index.tsx
5
+ // component=Radio.Group
6
+ import figma from 'figma';
7
+ const instance = figma.selectedInstance;
8
+ const optionsSlot = instance.getSlot('options');
9
+ const optionsChildren = optionsSlot ? figma.helpers.react.renderChildren(optionsSlot) : null;
10
+ export default {
11
+ id: 'radio-group',
12
+ imports: ["import { Radio } from '@cdx-ui/components'"],
13
+ example: figma.code`
14
+ <Radio.Group>
15
+ ${optionsChildren}
16
+ </Radio.Group>`
17
+ };
18
+ //# sourceMappingURL=Radio.Group.figma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["figma","instance","selectedInstance","optionsSlot","getSlot","optionsChildren","helpers","react","renderChildren","id","imports","example","code"],"sourceRoot":"../../../src","sources":["figma/Radio.Group.figma.ts"],"mappings":";;AAAA;AACA;AACA;AACA,OAAOA,KAAK,MAAM,OAAO;AAEzB,MAAMC,QAAQ,GAAGD,KAAK,CAACE,gBAAgB;AAEvC,MAAMC,WAAW,GAAGF,QAAQ,CAACG,OAAO,CAAC,SAAS,CAAC;AAC/C,MAAMC,eAAe,GAAGF,WAAW,GAAGH,KAAK,CAACM,OAAO,CAACC,KAAK,CAACC,cAAc,CAACL,WAAW,CAAC,GAAG,IAAI;AAE5F,eAAe;EACbM,EAAE,EAAE,aAAa;EACjBC,OAAO,EAAE,CAAC,4CAA4C,CAAC;EACvDC,OAAO,EAAEX,KAAK,CAACY,IAAI;AACrB;AACA,IAAIP,eAAe;AACnB;AACA,CAAC","ignoreList":[]}
@@ -6,28 +6,34 @@
6
6
  import figma from 'figma';
7
7
  const instance = figma.selectedInstance;
8
8
 
9
- // Enum-as-boolean: isDisabled and isInvalid are VARIANT properties in Figma (string values "true"/"false").
10
- // Rendered via renderProp so JSX formatting matches Code Connect conventions.
9
+ // Enum-as-boolean: isDisabled, isInvalid, and isReadOnly are VARIANT properties in Figma (string values "true"/"false").
10
+ // Map "false" to undefined so renderProp omits them from the snippet.
11
+ // isChecked, isHovered, and isFocused are runtime/visual states and are intentionally omitted.
11
12
  const isDisabled = instance.getEnum('isDisabled', {
12
13
  true: true,
13
- false: false
14
+ false: undefined
14
15
  });
15
16
  const isInvalid = instance.getEnum('isInvalid', {
16
17
  true: true,
17
- false: false
18
+ false: undefined
19
+ });
20
+ const isReadOnly = instance.getEnum('isReadOnly', {
21
+ true: true,
22
+ false: undefined
18
23
  });
19
24
  const isDisabledProp = figma.helpers.react.renderProp('isDisabled', isDisabled);
20
25
  const isInvalidProp = figma.helpers.react.renderProp('isInvalid', isInvalid);
26
+ const isReadOnlyProp = figma.helpers.react.renderProp('isReadOnly', isReadOnly);
21
27
  const showLabel = instance.getEnum('Show Label?', {
22
28
  true: true,
23
29
  false: false
24
30
  });
25
- const labelText = instance.findText('Label').textContent;
31
+ const labelText = instance.findText('Radio.Label').textContent;
26
32
  export default {
27
33
  id: 'radio',
28
34
  imports: ["import { Radio } from '@cdx-ui/components'"],
29
35
  example: figma.code`
30
- <Radio value="option"${isDisabledProp}${isInvalidProp}>
36
+ <Radio value="option"${isDisabledProp}${isInvalidProp}${isReadOnlyProp}>
31
37
  ${showLabel ? figma.code`<Radio.Label>${labelText}</Radio.Label>` : null}
32
38
  </Radio>`
33
39
  };
@@ -1 +1 @@
1
- {"version":3,"names":["figma","instance","selectedInstance","isDisabled","getEnum","true","false","isInvalid","isDisabledProp","helpers","react","renderProp","isInvalidProp","showLabel","labelText","findText","textContent","id","imports","example","code"],"sourceRoot":"../../../src","sources":["figma/Radio.figma.ts"],"mappings":";;AAAA;AACA;AACA;AACA,OAAOA,KAAK,MAAM,OAAO;AAEzB,MAAMC,QAAQ,GAAGD,KAAK,CAACE,gBAAgB;;AAEvC;AACA;AACA,MAAMC,UAAU,GAAGF,QAAQ,CAACG,OAAO,CAAC,YAAY,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAE;AACT,CAAC,CAAC;AACF,MAAMC,SAAS,GAAGN,QAAQ,CAACG,OAAO,CAAC,WAAW,EAAE;EAC9CC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAE;AACT,CAAC,CAAC;AACF,MAAME,cAAc,GAAGR,KAAK,CAACS,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,YAAY,EAAER,UAAU,CAAC;AAC/E,MAAMS,aAAa,GAAGZ,KAAK,CAACS,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,WAAW,EAAEJ,SAAS,CAAC;AAE5E,MAAMM,SAAS,GAAGZ,QAAQ,CAACG,OAAO,CAAC,aAAa,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAE;AACT,CAAC,CAAC;AAEF,MAAMQ,SAAS,GAAIb,QAAQ,CAACc,QAAQ,CAAC,OAAO,CAAC,CAAgCC,WAAW;AAExF,eAAe;EACbC,EAAE,EAAE,OAAO;EACXC,OAAO,EAAE,CAAC,4CAA4C,CAAC;EACvDC,OAAO,EAAEnB,KAAK,CAACoB,IAAI;AACrB,uBAAuBZ,cAAc,GAAGI,aAAa;AACrD,IAAIC,SAAS,GAAGb,KAAK,CAACoB,IAAI,gBAAgBN,SAAS,gBAAgB,GAAG,IAAI;AAC1E;AACA,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["figma","instance","selectedInstance","isDisabled","getEnum","true","false","undefined","isInvalid","isReadOnly","isDisabledProp","helpers","react","renderProp","isInvalidProp","isReadOnlyProp","showLabel","labelText","findText","textContent","id","imports","example","code"],"sourceRoot":"../../../src","sources":["figma/Radio.figma.ts"],"mappings":";;AAAA;AACA;AACA;AACA,OAAOA,KAAK,MAAM,OAAO;AAEzB,MAAMC,QAAQ,GAAGD,KAAK,CAACE,gBAAgB;;AAEvC;AACA;AACA;AACA,MAAMC,UAAU,GAAGF,QAAQ,CAACG,OAAO,CAAC,YAAY,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAEC;AACT,CAAC,CAAC;AACF,MAAMC,SAAS,GAAGP,QAAQ,CAACG,OAAO,CAAC,WAAW,EAAE;EAC9CC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAEC;AACT,CAAC,CAAC;AACF,MAAME,UAAU,GAAGR,QAAQ,CAACG,OAAO,CAAC,YAAY,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAEC;AACT,CAAC,CAAC;AACF,MAAMG,cAAc,GAAGV,KAAK,CAACW,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,YAAY,EAAEV,UAAU,CAAC;AAC/E,MAAMW,aAAa,GAAGd,KAAK,CAACW,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,WAAW,EAAEL,SAAS,CAAC;AAC5E,MAAMO,cAAc,GAAGf,KAAK,CAACW,OAAO,CAACC,KAAK,CAACC,UAAU,CAAC,YAAY,EAAEJ,UAAU,CAAC;AAE/E,MAAMO,SAAS,GAAGf,QAAQ,CAACG,OAAO,CAAC,aAAa,EAAE;EAChDC,IAAI,EAAE,IAAI;EACVC,KAAK,EAAE;AACT,CAAC,CAAC;AAEF,MAAMW,SAAS,GAAIhB,QAAQ,CAACiB,QAAQ,CAAC,aAAa,CAAC,CAAgCC,WAAW;AAE9F,eAAe;EACbC,EAAE,EAAE,OAAO;EACXC,OAAO,EAAE,CAAC,4CAA4C,CAAC;EACvDC,OAAO,EAAEtB,KAAK,CAACuB,IAAI;AACrB,uBAAuBb,cAAc,GAAGI,aAAa,GAAGC,cAAc;AACtE,IAAIC,SAAS,GAAGhB,KAAK,CAACuB,IAAI,gBAAgBN,SAAS,gBAAgB,GAAG,IAAI;AAC1E;AACA,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAc5B,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,SAAS,6FAeb,CAAC;AAoBH,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,cAAc,sGAgDnB,CAAC;AAQF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,kGAiBf,CAAC;AAQF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,QAAA,MAAM,UAAU,kGA0Cf,CAAC;AAQF,KAAK,sBAAsB,GAAG,OAAO,SAAS,GAAG;IAC/C,SAAS,EAAE,OAAO,cAAc,CAAC;IACjC,KAAK,EAAE,OAAO,UAAU,CAAC;IACzB,KAAK,EAAE,OAAO,UAAU,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,KAAK,EAIZ,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAc5B,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,SAAS,6FAeb,CAAC;AAoBH,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,cAAc,sGAwDnB,CAAC;AAQF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,kGAyBf,CAAC;AAQF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,QAAA,MAAM,UAAU,kGA0Cf,CAAC;AAQF,KAAK,sBAAsB,GAAG,OAAO,SAAS,GAAG;IAC/C,SAAS,EAAE,OAAO,cAAc,CAAC;IACjC,KAAK,EAAE,OAAO,UAAU,CAAC;IACzB,KAAK,EAAE,OAAO,UAAU,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,KAAK,EAIZ,sBAAsB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,oFAO5B,CAAC;AAEH,eAAO,MAAM,sBAAsB,oFAqCjC,CAAC;AAEH,eAAO,MAAM,qBAAqB,oFAoBhC,CAAC;AAEH,eAAO,MAAM,kBAAkB,oFAA2C,CAAC;AAE3E,eAAO,MAAM,kBAAkB;;8EAQ7B,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,oFAQ5B,CAAC;AAEH,eAAO,MAAM,sBAAsB,oFA0DjC,CAAC;AAEH,eAAO,MAAM,qBAAqB,oFAiChC,CAAC;AAEH,eAAO,MAAM,kBAAkB,oFAK7B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;8EAQ7B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/components/Switch/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAMvD,eAAO,MAAM,wBAAwB;;8EAQnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;8EAQhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;8EAQjC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;8EAQ9B,CAAC;AAMH,eAAO,MAAM,mBAAmB;;8EAoB/B,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;8EAmBtC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;8EAwB/B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/components/Switch/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAMvD,eAAO,MAAM,wBAAwB;;8EAQnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;8EAQhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;8EAQjC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;8EAQ9B,CAAC;AAMH,eAAO,MAAM,mBAAmB;;8EAoB/B,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;8EA2BtC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;8EAwB/B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import figma from 'figma';
2
+ declare const _default: {
3
+ id: string;
4
+ imports: string[];
5
+ example: figma.TemplateStringResult;
6
+ };
7
+ export default _default;
8
+ //# sourceMappingURL=Field.Radio.figma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Field.Radio.figma.d.ts","sourceRoot":"","sources":["../../../src/figma/Field.Radio.figma.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;;;;;;AA6C1B,wBAYE"}
@@ -0,0 +1,8 @@
1
+ import figma from 'figma';
2
+ declare const _default: {
3
+ id: string;
4
+ imports: string[];
5
+ example: figma.TemplateStringResult;
6
+ };
7
+ export default _default;
8
+ //# sourceMappingURL=Radio.Group.figma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Radio.Group.figma.d.ts","sourceRoot":"","sources":["../../../src/figma/Radio.Group.figma.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;;;;;;AAO1B,wBAOE"}
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.figma.d.ts","sourceRoot":"","sources":["../../../src/figma/Radio.figma.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;;;;;;AAwB1B,wBAOE"}
1
+ {"version":3,"file":"Radio.figma.d.ts","sourceRoot":"","sources":["../../../src/figma/Radio.figma.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;;;;;;AA8B1B,wBAOE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdx-ui/components",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -81,10 +81,10 @@
81
81
  "@marceloterreiro/flash-calendar": "2.0.0",
82
82
  "react-native-reanimated-carousel": "5.0.0-beta.5",
83
83
  "uniwind": "1.10.0",
84
- "@cdx-ui/icons": "0.1.1",
85
- "@cdx-ui/primitives": "0.1.1",
86
- "@cdx-ui/utils": "0.1.1",
87
- "@cdx-ui/formatters": "0.1.1"
84
+ "@cdx-ui/formatters": "0.1.3",
85
+ "@cdx-ui/utils": "0.1.3",
86
+ "@cdx-ui/primitives": "0.1.3",
87
+ "@cdx-ui/icons": "0.1.3"
88
88
  },
89
89
  "devDependencies": {
90
90
  "@react-navigation/bottom-tabs": "*",
@@ -74,10 +74,11 @@ const RadioIndicator = forwardRef<View, RadioIndicatorProps>(
74
74
  useRadioContext();
75
75
 
76
76
  const checkState = isChecked ? 'checked' : 'unchecked';
77
- const fieldState =
78
- INDICATOR_STATES[
79
- `${checkState}:${isInvalid ? 'true' : 'false'}:${isPressed ? 'true' : 'false'}`
80
- ];
77
+ const fieldState = isReadOnly
78
+ ? (`readonly-${checkState}${isInvalid ? '-invalid' : ''}` as const)
79
+ : INDICATOR_STATES[
80
+ `${checkState}:${isInvalid ? 'true' : 'false'}:${isPressed ? 'true' : 'false'}`
81
+ ];
81
82
 
82
83
  const computedClassName = cn(radioIndicatorVariants(), className);
83
84
  const Comp = asChild ? Slot : View;
@@ -104,11 +105,18 @@ const RadioIndicator = forwardRef<View, RadioIndicatorProps>(
104
105
  )}
105
106
  >
106
107
  <View
107
- className={cn(radioInnerDotVariants())}
108
+ collapsable={false}
109
+ className={cn(
110
+ radioInnerDotVariants(),
111
+ // Native: unconditional bg so Uniwind does not have to win a data-attribute
112
+ // background over `bg-surface-action-strong` (web keeps compound selectors).
113
+ isReadOnly && isChecked && !isInvalid && 'bg-content-primary',
114
+ )}
108
115
  {...dataAttributes({
109
116
  checked: isChecked,
110
117
  invalid: isInvalid,
111
118
  hover: isHovered,
119
+ readonly: isReadOnly,
112
120
  fieldState,
113
121
  })}
114
122
  />
@@ -132,6 +140,7 @@ export interface RadioLabelProps extends TextProps {
132
140
 
133
141
  const RadioLabel = forwardRef<Text, RadioLabelProps>(
134
142
  ({ asChild, className, children, style, ...props }, ref) => {
143
+ const { isDisabled, isReadOnly } = useRadioContext();
135
144
  const computedClassName = cn(radioLabelVariants(), className);
136
145
  const Comp = asChild ? Slot : Text;
137
146
 
@@ -141,7 +150,14 @@ const RadioLabel = forwardRef<Text, RadioLabelProps>(
141
150
  className={computedClassName}
142
151
  style={style}
143
152
  {...props}
144
- {...mergeDataAttributes(props, dataAttributes({ slot: 'radio-label' }))}
153
+ {...mergeDataAttributes(
154
+ props,
155
+ dataAttributes({
156
+ slot: 'radio-label',
157
+ disabled: isDisabled,
158
+ readonly: isReadOnly,
159
+ }),
160
+ )}
145
161
  >
146
162
  {children}
147
163
  </Comp>
@@ -1,11 +1,12 @@
1
1
  import { Platform } from 'react-native';
2
2
  import { cva } from '@cdx-ui/utils';
3
- import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants';
3
+ import { DISABLED_CURSOR, DISABLED_OPACITY, TRANSITION_COLORS } from '../../styles/constants';
4
4
 
5
5
  export const radioRootVariants = cva([
6
6
  'flex-row items-center gap-2',
7
- 'data-[disabled=true]:opacity-[var(--opacity-disabled)]',
7
+ DISABLED_OPACITY,
8
8
  DISABLED_CURSOR,
9
+ 'data-[readonly=true]:cursor-default',
9
10
  // Suppress default :focus-visible outline on the role="radio" Pressable;
10
11
  // focus ring is drawn on the indicator instead of wrapping the whole control.
11
12
  'web:outline-none web:focus:outline-none web:focus-visible:outline-none',
@@ -16,7 +17,8 @@ export const radioIndicatorVariants = cva([
16
17
  'rounded-[var(--border-radius-round)]',
17
18
  'border-[length:var(--border-width-selected)]',
18
19
  'h-5 w-5',
19
- 'bg-surface-primary',
20
+ // Figma: indicator fill is transparent; selection reads via border + inner dot only.
21
+ 'bg-transparent',
20
22
  'data-[checked=false]:border-content-secondary',
21
23
  'data-[checked=true]:border-stroke-action',
22
24
  'data-[invalid=true]:border-stroke-danger',
@@ -36,12 +38,32 @@ export const radioIndicatorVariants = cva([
36
38
  'web:active:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-surface-danger-strong-active',
37
39
  'web:active:data-[hover=true]:data-[checked=true]:border-surface-action-strong-active',
38
40
  'web:active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-surface-danger-strong-active',
41
+ // Focus ring — applies to read-only as well (focusable + aria-readonly).
39
42
  'web:data-[focus-visible=true]:outline-none',
40
43
  'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-stroke-focus web:data-[focus-visible=true]:ring-offset-2',
44
+ // Read-only — Figma: transparent fill + content-tertiary border (checked and unchecked).
45
+ // After hover/active so equal-or-higher specificity keeps the static treatment.
46
+ // Invalid is not a Figma readonly variant; retain danger so error remains visible.
47
+ 'data-[readonly=true]:data-[checked=false]:border-content-tertiary',
48
+ 'data-[readonly=true]:data-[checked=true]:border-content-tertiary',
49
+ 'data-[readonly=true]:data-[invalid=true]:border-stroke-danger',
50
+ 'data-[readonly=true]:data-[hover=true]:data-[checked=false]:bg-transparent',
51
+ 'data-[readonly=true]:data-[hover=true]:data-[invalid=true]:data-[checked=false]:bg-transparent',
52
+ 'data-[readonly=true]:data-[hover=true]:data-[checked=false]:border-content-tertiary',
53
+ 'data-[readonly=true]:data-[hover=true]:data-[checked=true]:border-content-tertiary',
54
+ 'data-[readonly=true]:data-[hover=true]:data-[invalid=true]:border-stroke-danger',
55
+ 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=false]:border-content-tertiary',
56
+ 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:border-content-tertiary',
57
+ 'web:active:data-[readonly=true]:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-stroke-danger',
58
+ 'web:active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-stroke-danger',
41
59
  ].join(' '),
42
60
  default: [
43
61
  // Native: Uniwind only evaluates the last data-[] condition in a compound chain.
44
62
  // Use single-condition data-[field-state=...] selectors (emitted by RadioIndicator).
63
+ 'data-[field-state=readonly-unchecked]:border-content-tertiary',
64
+ 'data-[field-state=readonly-checked]:border-content-tertiary',
65
+ 'data-[field-state=readonly-unchecked-invalid]:border-stroke-danger',
66
+ 'data-[field-state=readonly-checked-invalid]:border-stroke-danger',
45
67
  'data-[field-state=active]:border-stroke-hover',
46
68
  'data-[field-state=invalid-active]:border-surface-danger-strong-active',
47
69
  'data-[field-state=checked-active]:border-surface-action-strong-active',
@@ -52,9 +74,12 @@ export const radioIndicatorVariants = cva([
52
74
 
53
75
  export const radioInnerDotVariants = cva([
54
76
  'rounded-[var(--border-radius-round)]',
77
+ 'overflow-hidden',
55
78
  'h-2.5 w-2.5',
56
- 'scale-0',
57
- 'data-[checked=true]:scale-100',
79
+ // Opacity (not scale): iOS compositing of scale-0 views samples the parent ring, so the
80
+ // checked fill never paints and the dot looks content-tertiary instead of content-primary.
81
+ 'opacity-0',
82
+ 'data-[checked=true]:opacity-100',
58
83
  'bg-surface-action-strong',
59
84
  'data-[invalid=true]:bg-surface-danger-strong',
60
85
  Platform.select({
@@ -64,15 +89,30 @@ export const radioInnerDotVariants = cva([
64
89
  // Active via group-active on indicator (inner dot is not the :active target).
65
90
  'web:group-active:data-[hover=true]:data-[checked=true]:bg-surface-action-strong-active',
66
91
  'web:group-active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong-active',
92
+ // Read-only checked — Figma: content-primary dot; invalid retains danger.
93
+ 'data-[readonly=true]:data-[checked=true]:bg-content-primary',
94
+ 'data-[readonly=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong',
95
+ 'web:group-active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:bg-content-primary',
96
+ 'web:group-active:data-[readonly=true]:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong',
67
97
  ].join(' '),
68
98
  default: [
69
99
  'data-[field-state=checked-active]:bg-surface-action-strong-active',
70
100
  'data-[field-state=checked-invalid-active]:bg-surface-danger-strong-active',
101
+ // `!` beats the base `bg-surface-action-strong` — Uniwind native does not cascade
102
+ // data-attribute backgrounds over an unconditional bg on the same View.
103
+ 'data-[readonly=true]:bg-content-primary!',
104
+ 'data-[field-state=readonly-checked]:bg-content-primary!',
105
+ 'data-[field-state=readonly-checked-invalid]:bg-surface-danger-strong!',
71
106
  ].join(' '),
72
107
  }),
73
108
  ]);
74
109
 
75
- export const radioLabelVariants = cva(['body-md', 'text-content-primary']);
110
+ export const radioLabelVariants = cva([
111
+ 'body-md',
112
+ 'text-content-primary',
113
+ 'data-[disabled=true]:text-content-tertiary',
114
+ 'data-[readonly=true]:cursor-default',
115
+ ]);
76
116
 
77
117
  export const radioGroupVariants = cva([], {
78
118
  variants: {