@idealyst/components 1.2.13 → 1.2.15

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 (95) hide show
  1. package/package.json +3 -3
  2. package/src/Accordion/Accordion.web.tsx +1 -1
  3. package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -3
  4. package/src/ActivityIndicator/ActivityIndicator.web.tsx +3 -3
  5. package/src/Alert/Alert.native.tsx +1 -1
  6. package/src/Alert/Alert.web.tsx +1 -1
  7. package/src/Avatar/Avatar.native.tsx +1 -1
  8. package/src/Badge/Badge.web.tsx +6 -2
  9. package/src/Badge/types.ts +5 -0
  10. package/src/Breadcrumb/Breadcrumb.native.tsx +20 -21
  11. package/src/Button/Button.native.tsx +3 -3
  12. package/src/Button/Button.web.tsx +5 -1
  13. package/src/Button/types.ts +5 -0
  14. package/src/Card/Card.web.tsx +4 -1
  15. package/src/Card/types.ts +5 -0
  16. package/src/Dialog/Dialog.native.tsx +3 -3
  17. package/src/Divider/Divider.web.tsx +2 -2
  18. package/src/Icon/Icon.web.tsx +2 -2
  19. package/src/Icon/types.ts +3 -0
  20. package/src/Image/Image.styles.tsx +5 -5
  21. package/src/Image/Image.web.tsx +3 -3
  22. package/src/List/List.native.tsx +1 -2
  23. package/src/List/List.web.tsx +1 -2
  24. package/src/List/ListSection.web.tsx +3 -3
  25. package/src/Menu/Menu.web.tsx +8 -10
  26. package/src/Menu/MenuItem.web.tsx +1 -1
  27. package/src/Popover/Popover.web.tsx +1 -1
  28. package/src/Pressable/Pressable.web.tsx +1 -1
  29. package/src/Progress/Progress.styles.tsx +76 -30
  30. package/src/Progress/Progress.web.tsx +13 -15
  31. package/src/SVGImage/SVGImage.web.tsx +1 -1
  32. package/src/Select/Select.web.tsx +2 -2
  33. package/src/Skeleton/Skeleton.native.tsx +3 -3
  34. package/src/Skeleton/Skeleton.web.tsx +3 -3
  35. package/src/Slider/Slider.native.tsx +2 -2
  36. package/src/Slider/Slider.styles.tsx +131 -44
  37. package/src/Slider/Slider.web.tsx +22 -22
  38. package/src/TabBar/TabBar.native.tsx +2 -2
  39. package/src/Text/Text.web.tsx +29 -3
  40. package/src/Text/types.ts +14 -1
  41. package/src/TextArea/TextArea.styles.tsx +96 -57
  42. package/src/TextArea/TextArea.web.tsx +19 -28
  43. package/src/Tooltip/Tooltip.web.tsx +3 -3
  44. package/src/Video/Video.styles.tsx +3 -3
  45. package/src/Video/Video.web.tsx +1 -1
  46. package/src/View/View.styles.tsx +2 -2
  47. package/src/View/View.web.tsx +93 -9
  48. package/src/View/types.ts +5 -1
  49. package/src/examples/ViewExamples.tsx +34 -0
  50. package/src/extensions/index.ts +0 -7
  51. package/src/hooks/useMergeRefs.ts +12 -6
  52. package/src/index.native.ts +1 -1
  53. package/src/index.ts +1 -1
  54. package/src/utils/accessibility/keyboardPatterns.ts +4 -0
  55. package/src/utils/accessibility/types.ts +5 -1
  56. package/src/utils/accessibility/useAnnounce.ts +1 -1
  57. package/src/utils/accessibility/useKeyboardNavigation.ts +1 -1
  58. package/src/utils/index.ts +0 -3
  59. package/src/utils/viewStyleProps.ts +2 -0
  60. package/src/Accordion/Accordion.styles.old.tsx +0 -298
  61. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +0 -94
  62. package/src/Alert/Alert.styles.old.tsx +0 -209
  63. package/src/Avatar/Avatar.styles.old.tsx +0 -99
  64. package/src/Badge/Badge.styles.old.tsx +0 -157
  65. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +0 -231
  66. package/src/Card/Card.styles.old.tsx +0 -160
  67. package/src/Checkbox/Checkbox.styles.old.tsx +0 -271
  68. package/src/Chip/Chip.styles.old.tsx +0 -184
  69. package/src/Dialog/Dialog.styles.old.tsx +0 -202
  70. package/src/Divider/Divider.styles.old.tsx +0 -172
  71. package/src/Icon/Icon.styles.old.tsx +0 -81
  72. package/src/Image/Image.styles.old.tsx +0 -69
  73. package/src/Input/Input.styles.old.tsx +0 -289
  74. package/src/List/List.styles.old.tsx +0 -242
  75. package/src/Menu/Menu.styles.old.tsx +0 -197
  76. package/src/Menu/MenuItem.styles.old.tsx +0 -114
  77. package/src/Popover/Popover.styles.old.tsx +0 -135
  78. package/src/Pressable/Pressable.styles.old.tsx +0 -27
  79. package/src/Progress/Progress.styles.old.tsx +0 -200
  80. package/src/RadioButton/RadioButton.styles.old.tsx +0 -175
  81. package/src/SVGImage/SVGImage.styles.old.tsx +0 -86
  82. package/src/Screen/Screen.styles.old.tsx +0 -87
  83. package/src/Select/Select.styles.old.tsx +0 -353
  84. package/src/Skeleton/Skeleton.styles.old.tsx +0 -67
  85. package/src/Slider/Slider.styles.old.tsx +0 -259
  86. package/src/Switch/Switch.styles.old.tsx +0 -203
  87. package/src/TabBar/TabBar.styles.old.tsx +0 -343
  88. package/src/Table/Table.styles.old.tsx +0 -311
  89. package/src/Text/Text.styles.old.tsx +0 -219
  90. package/src/TextArea/TextArea.styles.old.tsx +0 -213
  91. package/src/Tooltip/Tooltip.styles.old.tsx +0 -82
  92. package/src/Video/Video.styles.old.tsx +0 -51
  93. package/src/View/View.styles.old.tsx +0 -125
  94. package/src/extensions/applyExtension.ts +0 -210
  95. package/src/utils/buildSizeVariants.ts +0 -16
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Progress styles using defineStyle with $iterator expansion.
2
+ * Progress styles using static styles with variants.
3
3
  */
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
- import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
5
+ import { defineStyle, ThemeStyleWrapper, CompoundVariants } from '@idealyst/theme';
6
6
  import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
7
7
 
8
8
  // Required: Unistyles must see StyleSheet usage in original source to process this file
@@ -11,26 +11,34 @@ void StyleSheet;
11
11
  // Wrap theme for $iterator support
12
12
  type Theme = ThemeStyleWrapper<BaseTheme>;
13
13
 
14
- export type ProgressDynamicProps = {
15
- size?: Size;
16
- intent?: Intent;
17
- rounded?: boolean;
14
+ export type ProgressVariants = {
15
+ size: Size;
16
+ intent: Intent;
17
+ rounded: boolean;
18
18
  };
19
19
 
20
+ // Create intent variants dynamically from theme
21
+ function createIntentVariants(theme: Theme) {
22
+ const variants: Record<string, object> = {};
23
+ for (const intent in theme.intents) {
24
+ variants[intent] = {};
25
+ }
26
+ return variants;
27
+ }
28
+
20
29
  /**
21
- * Progress styles with intent-based coloring.
30
+ * Progress styles with static styles and variants.
22
31
  */
23
32
  export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
24
- container: (_props: ProgressDynamicProps) => ({
33
+ container: {
25
34
  gap: 4 as const,
26
- }),
35
+ },
27
36
 
28
- linearTrack: (_props: ProgressDynamicProps) => ({
37
+ linearTrack: {
29
38
  backgroundColor: theme.colors.border.secondary,
30
39
  overflow: 'hidden' as const,
31
40
  position: 'relative' as const,
32
41
  variants: {
33
- // $iterator expands for each progress size
34
42
  size: {
35
43
  height: theme.sizes.$progress.linearHeight,
36
44
  },
@@ -39,36 +47,60 @@ export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
39
47
  false: { borderRadius: 0 },
40
48
  },
41
49
  },
42
- }),
50
+ },
43
51
 
44
- linearBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
52
+ linearBar: {
45
53
  height: '100%' as const,
46
- backgroundColor: theme.intents[intent].primary,
47
54
  variants: {
48
55
  rounded: {
49
56
  true: { borderRadius: 9999 },
50
57
  false: { borderRadius: 0 },
51
58
  },
59
+ intent: createIntentVariants(theme),
52
60
  },
61
+ compoundVariants: (() => {
62
+ const cv: CompoundVariants<keyof ProgressVariants> = [];
63
+ for (const intent in theme.intents) {
64
+ cv.push({
65
+ intent,
66
+ styles: {
67
+ backgroundColor: theme.intents[intent as Intent].primary,
68
+ },
69
+ });
70
+ }
71
+ return cv;
72
+ })(),
53
73
  _web: {
54
74
  transition: 'width 0.3s ease' as const,
55
75
  },
56
- }),
76
+ },
57
77
 
58
- indeterminateBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
78
+ indeterminateBar: {
59
79
  position: 'absolute' as const,
60
80
  height: '100%' as const,
61
81
  width: '40%' as const,
62
- backgroundColor: theme.intents[intent].primary,
63
82
  variants: {
64
83
  rounded: {
65
84
  true: { borderRadius: 9999 },
66
85
  false: { borderRadius: 0 },
67
86
  },
87
+ intent: createIntentVariants(theme),
68
88
  },
69
- }),
89
+ compoundVariants: (() => {
90
+ const cv: CompoundVariants<keyof ProgressVariants> = [];
91
+ for (const intent in theme.intents) {
92
+ cv.push({
93
+ intent,
94
+ styles: {
95
+ backgroundColor: theme.intents[intent as Intent].primary,
96
+ },
97
+ });
98
+ }
99
+ return cv;
100
+ })(),
101
+ },
70
102
 
71
- circularContainer: (_props: ProgressDynamicProps) => ({
103
+ circularContainer: {
72
104
  alignItems: 'center' as const,
73
105
  justifyContent: 'center' as const,
74
106
  position: 'relative' as const,
@@ -78,21 +110,35 @@ export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
78
110
  height: theme.sizes.$progress.circularSize,
79
111
  },
80
112
  },
81
- }),
113
+ },
82
114
 
83
- circularTrack: (_props: ProgressDynamicProps) => ({
115
+ circularTrack: {
84
116
  _web: {
85
117
  stroke: theme.colors.border.secondary,
86
118
  },
87
- }),
119
+ },
88
120
 
89
- circularBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
90
- _web: {
91
- stroke: theme.intents[intent].primary,
121
+ circularBar: {
122
+ variants: {
123
+ intent: createIntentVariants(theme),
92
124
  },
93
- }),
125
+ compoundVariants: (() => {
126
+ const cv: CompoundVariants<keyof ProgressVariants> = [];
127
+ for (const intent in theme.intents) {
128
+ cv.push({
129
+ intent,
130
+ styles: {
131
+ _web: {
132
+ stroke: theme.intents[intent as Intent].primary,
133
+ },
134
+ },
135
+ });
136
+ }
137
+ return cv;
138
+ })(),
139
+ },
94
140
 
95
- label: (_props: ProgressDynamicProps) => ({
141
+ label: {
96
142
  color: theme.colors.text.primary,
97
143
  textAlign: 'center' as const,
98
144
  variants: {
@@ -100,9 +146,9 @@ export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
100
146
  fontSize: theme.sizes.$progress.labelFontSize,
101
147
  },
102
148
  },
103
- }),
149
+ },
104
150
 
105
- circularLabel: (_props: ProgressDynamicProps) => ({
151
+ circularLabel: {
106
152
  position: 'absolute' as const,
107
153
  fontWeight: '600' as const,
108
154
  color: theme.colors.text.primary,
@@ -111,5 +157,5 @@ export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
111
157
  fontSize: theme.sizes.$progress.circularLabelFontSize,
112
158
  },
113
159
  },
114
- }),
160
+ },
115
161
  }));
@@ -23,21 +23,19 @@ const Progress: React.FC<ProgressProps> = ({
23
23
  }) => {
24
24
  const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
25
25
 
26
- // Apply variants (for size and rounded)
26
+ // Apply variants (for size, intent, and rounded)
27
27
  progressStyles.useVariants({
28
28
  size,
29
+ intent,
29
30
  rounded,
30
31
  });
31
32
 
32
- // Compute dynamic styles with intent
33
- const dynamicProps = { intent };
34
-
35
33
  // Linear progress
36
- const containerProps = getWebProps([(progressStyles.container as any)({}), style as any]);
37
- const trackProps = getWebProps([(progressStyles.linearTrack as any)({})]);
38
- const barProps = getWebProps([(progressStyles.linearBar as any)(dynamicProps), { width: `${percentage}%` }]);
39
- const indeterminateProps = getWebProps([(progressStyles.indeterminateBar as any)(dynamicProps)]);
40
- const labelProps = getWebProps([progressStyles.label]);
34
+ const containerProps = getWebProps([progressStyles.container as any, style as any]);
35
+ const trackProps = getWebProps([progressStyles.linearTrack as any]);
36
+ const barProps = getWebProps([progressStyles.linearBar as any, { width: `${percentage}%` }]);
37
+ const indeterminateProps = getWebProps([progressStyles.indeterminateBar as any]);
38
+ const labelProps = getWebProps([progressStyles.label as any]);
41
39
 
42
40
  const getCircularSize = () => {
43
41
  if (size === 'sm') return 32;
@@ -53,13 +51,13 @@ const Progress: React.FC<ProgressProps> = ({
53
51
  const strokeDashoffset = indeterminate ? circumference * 0.25 : circumference - (percentage / 100) * circumference;
54
52
 
55
53
  const computedContainerProps = getWebProps([
56
- progressStyles.circularContainer,
57
- style,
54
+ progressStyles.circularContainer as any,
55
+ style as any,
58
56
  { display: 'inline-flex' }
59
57
  ]);
60
- const labelProps = getWebProps([progressStyles.circularLabel]);
61
- const trackColorProps = getWebProps([progressStyles.circularTrack]);
62
- const barColorProps = getWebProps([(progressStyles.circularBar as any)(dynamicProps)]);
58
+ const circularLabelProps = getWebProps([progressStyles.circularLabel as any]);
59
+ const trackColorProps = getWebProps([progressStyles.circularTrack as any]);
60
+ const barColorProps = getWebProps([progressStyles.circularBar as any]);
63
61
 
64
62
  return (
65
63
  <div {...computedContainerProps} id={id} data-testid={testID}>
@@ -93,7 +91,7 @@ const Progress: React.FC<ProgressProps> = ({
93
91
  />
94
92
  </svg>
95
93
  {showLabel && (
96
- <span {...labelProps}>
94
+ <span {...circularLabelProps}>
97
95
  {label || `${Math.round(percentage)}%`}
98
96
  </span>
99
97
  )}
@@ -56,7 +56,7 @@ const SVGImage = forwardRef<HTMLDivElement, SVGImageProps>(({
56
56
 
57
57
  // Use getWebProps to generate className and ref for web
58
58
  const containerWebProps = getWebProps(containerStyleArray);
59
- const imageWebProps = getWebProps(svgImageStyles.image);
59
+ const imageWebProps = getWebProps([svgImageStyles.image as any]);
60
60
 
61
61
  // Apply custom color if provided
62
62
  // Convert React Native resize modes to CSS object-fit values
@@ -258,7 +258,7 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
258
258
  </div>
259
259
  <PositionedPortal
260
260
  open={isOpen}
261
- anchor={triggerRef}
261
+ anchor={triggerRef as React.RefObject<HTMLElement>}
262
262
  placement="bottom-start"
263
263
  offset={4}
264
264
  onClickOutside={handleClose}
@@ -280,12 +280,12 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
280
280
  {searchable && (
281
281
  <div {...getWebProps([searchContainerStyle])}>
282
282
  <input
283
+ {...getWebProps([searchInputStyle])}
283
284
  ref={searchInputRef}
284
285
  type="text"
285
286
  placeholder="Search options..."
286
287
  value={searchTerm}
287
288
  onChange={handleSearchChange}
288
- {...getWebProps([searchInputStyle])}
289
289
  />
290
290
  </div>
291
291
  )}
@@ -23,17 +23,17 @@ const Skeleton = forwardRef<View, SkeletonProps>(({
23
23
  id,
24
24
  // Accessibility props
25
25
  accessibilityLabel,
26
- accessibilityLiveRegion,
26
+ accessibilityLive,
27
27
  accessibilityBusy,
28
28
  }, ref) => {
29
29
  // Generate native accessibility props
30
30
  const nativeA11yProps = useMemo(() => {
31
31
  return getNativeLiveRegionAccessibilityProps({
32
32
  accessibilityLabel: accessibilityLabel ?? 'Loading content',
33
- accessibilityLiveRegion: accessibilityLiveRegion ?? 'polite',
33
+ accessibilityLive: accessibilityLive ?? 'polite',
34
34
  accessibilityBusy: accessibilityBusy ?? true,
35
35
  });
36
- }, [accessibilityLabel, accessibilityLiveRegion, accessibilityBusy]);
36
+ }, [accessibilityLabel, accessibilityLive, accessibilityBusy]);
37
37
  skeletonStyles.useVariants({
38
38
  shape,
39
39
  animation,
@@ -19,7 +19,7 @@ const Skeleton: React.FC<SkeletonProps> = ({
19
19
  id,
20
20
  // Accessibility props
21
21
  accessibilityLabel,
22
- accessibilityLiveRegion,
22
+ accessibilityLive,
23
23
  accessibilityBusy,
24
24
  accessibilityAtomic,
25
25
  accessibilityRelevant,
@@ -28,12 +28,12 @@ const Skeleton: React.FC<SkeletonProps> = ({
28
28
  const ariaProps = useMemo(() => {
29
29
  return getWebLiveRegionAriaProps({
30
30
  accessibilityLabel: accessibilityLabel ?? 'Loading content',
31
- accessibilityLiveRegion: accessibilityLiveRegion ?? 'polite',
31
+ accessibilityLive: accessibilityLive ?? 'polite',
32
32
  accessibilityBusy: accessibilityBusy ?? true,
33
33
  accessibilityAtomic,
34
34
  accessibilityRelevant,
35
35
  });
36
- }, [accessibilityLabel, accessibilityLiveRegion, accessibilityBusy, accessibilityAtomic, accessibilityRelevant]);
36
+ }, [accessibilityLabel, accessibilityLive, accessibilityBusy, accessibilityAtomic, accessibilityRelevant]);
37
37
  skeletonStyles.useVariants({
38
38
  shape,
39
39
  animation,
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useCallback, forwardRef, useMemo } from 'react';
2
- import { View } from 'react-native';
2
+ import { View, LayoutChangeEvent } from 'react-native';
3
3
  import { GestureDetector, Gesture } from 'react-native-gesture-handler';
4
4
  import Animated, { useSharedValue, useAnimatedStyle, runOnJS, withSpring } from 'react-native-reanimated';
5
5
  import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons';
@@ -222,7 +222,7 @@ const Slider = forwardRef<View, SliderProps>(({
222
222
  <GestureDetector gesture={composedGesture}>
223
223
  <View
224
224
  style={trackStyle}
225
- onLayout={(e) => {
225
+ onLayout={(e: LayoutChangeEvent) => {
226
226
  const width = e.nativeEvent.layout.width;
227
227
  trackWidth.value = width;
228
228
  setTrackWidthState(width);
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Slider styles using defineStyle with dynamic props.
2
+ * Slider styles using static styles with variants.
3
3
  */
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
- import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
5
+ import { defineStyle, ThemeStyleWrapper, CompoundVariants } from '@idealyst/theme';
6
6
  import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
7
7
  import { ViewStyleSize } from '../utils/viewStyleProps';
8
8
 
@@ -12,20 +12,47 @@ void StyleSheet;
12
12
  // Wrap theme for $iterator support
13
13
  type Theme = ThemeStyleWrapper<BaseTheme>;
14
14
 
15
- export type SliderDynamicProps = {
16
- size?: Size;
17
- intent?: Intent;
18
- disabled?: boolean;
15
+ export type SliderVariants = {
16
+ size: Size;
17
+ intent: Intent;
18
+ disabled: boolean;
19
19
  margin?: ViewStyleSize;
20
20
  marginVertical?: ViewStyleSize;
21
21
  marginHorizontal?: ViewStyleSize;
22
22
  };
23
23
 
24
+ // Create intent variants dynamically from theme
25
+ function createIntentVariants(theme: Theme) {
26
+ const variants: Record<string, object> = {};
27
+ for (const intent in theme.intents) {
28
+ variants[intent] = {};
29
+ }
30
+ return variants;
31
+ }
32
+
33
+ // Create compound variants for intent-specific styles
34
+ function createSliderCompoundVariants(theme: Theme): CompoundVariants<keyof SliderVariants> {
35
+ const compoundVariants: CompoundVariants<keyof SliderVariants> = [];
36
+
37
+ for (const intent in theme.intents) {
38
+ const intentValue = theme.intents[intent as Intent];
39
+
40
+ // filledTrack intent colors are handled inline since they need per-element targeting
41
+ // thumb border color by intent
42
+ compoundVariants.push({
43
+ intent,
44
+ styles: {},
45
+ });
46
+ }
47
+
48
+ return compoundVariants;
49
+ }
50
+
24
51
  /**
25
- * Slider styles with intent/disabled handling.
52
+ * Slider styles with static styles and variants.
26
53
  */
27
54
  export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
28
- container: (_props: SliderDynamicProps) => ({
55
+ container: {
29
56
  gap: 4,
30
57
  paddingVertical: 8,
31
58
  variants: {
@@ -39,44 +66,67 @@ export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
39
66
  marginHorizontal: theme.sizes.$view.padding,
40
67
  },
41
68
  },
42
- }),
69
+ },
43
70
 
44
- sliderWrapper: (_props: SliderDynamicProps) => ({
71
+ sliderWrapper: {
45
72
  position: 'relative' as const,
46
73
  paddingVertical: 4,
47
- }),
74
+ },
48
75
 
49
- track: ({ disabled = false }: SliderDynamicProps) => ({
76
+ track: {
50
77
  backgroundColor: theme.colors.surface.tertiary,
51
78
  borderRadius: 9999,
52
79
  position: 'relative' as const,
53
- opacity: disabled ? 0.5 : 1,
54
80
  variants: {
55
81
  size: {
56
82
  height: theme.sizes.$slider.trackHeight,
57
83
  },
84
+ disabled: {
85
+ true: {
86
+ opacity: 0.5,
87
+ _web: {
88
+ cursor: 'not-allowed',
89
+ },
90
+ },
91
+ false: {
92
+ opacity: 1,
93
+ _web: {
94
+ cursor: 'pointer',
95
+ },
96
+ },
97
+ },
58
98
  },
59
- _web: {
60
- cursor: disabled ? 'not-allowed' : 'pointer',
61
- },
62
- }),
99
+ },
63
100
 
64
- filledTrack: ({ intent = 'primary' }: SliderDynamicProps) => ({
101
+ filledTrack: {
65
102
  position: 'absolute' as const,
66
103
  height: '100%',
67
104
  borderRadius: 9999,
68
105
  top: 0,
69
106
  left: 0,
70
- backgroundColor: theme.intents[intent].primary,
71
- }),
107
+ variants: {
108
+ intent: createIntentVariants(theme),
109
+ },
110
+ compoundVariants: (() => {
111
+ const cv: CompoundVariants<keyof SliderVariants> = [];
112
+ for (const intent in theme.intents) {
113
+ cv.push({
114
+ intent,
115
+ styles: {
116
+ backgroundColor: theme.intents[intent as Intent].primary,
117
+ },
118
+ });
119
+ }
120
+ return cv;
121
+ })(),
122
+ },
72
123
 
73
- thumb: ({ intent = 'primary', disabled = false }: SliderDynamicProps) => ({
124
+ thumb: {
74
125
  position: 'absolute' as const,
75
126
  backgroundColor: theme.colors.surface.primary,
76
127
  borderRadius: 9999,
77
128
  borderWidth: 2,
78
129
  borderStyle: 'solid' as const,
79
- borderColor: theme.intents[intent].primary,
80
130
  top: '50%',
81
131
  display: 'flex' as const,
82
132
  alignItems: 'center' as const,
@@ -86,35 +136,59 @@ export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
86
136
  shadowOpacity: 0.2,
87
137
  shadowRadius: 4,
88
138
  elevation: 2,
89
- opacity: disabled ? 0.6 : 1,
90
139
  variants: {
91
140
  size: {
92
141
  width: theme.sizes.$slider.thumbSize,
93
142
  height: theme.sizes.$slider.thumbSize,
94
143
  },
144
+ intent: createIntentVariants(theme),
145
+ disabled: {
146
+ true: {
147
+ opacity: 0.6,
148
+ _web: {
149
+ cursor: 'not-allowed',
150
+ },
151
+ },
152
+ false: {
153
+ opacity: 1,
154
+ _web: {
155
+ cursor: 'grab',
156
+ },
157
+ },
158
+ },
95
159
  },
160
+ compoundVariants: (() => {
161
+ const cv: CompoundVariants<keyof SliderVariants> = [];
162
+ for (const intent in theme.intents) {
163
+ cv.push({
164
+ intent,
165
+ styles: {
166
+ borderColor: theme.intents[intent as Intent].primary,
167
+ },
168
+ });
169
+ }
170
+ return cv;
171
+ })(),
96
172
  _web: {
97
173
  boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',
98
174
  transform: 'translate(-50%, -50%)',
99
175
  transition: 'transform 0.15s ease, box-shadow 0.2s ease',
100
- cursor: disabled ? 'not-allowed' : 'grab',
101
- _hover: disabled ? {} : { transform: 'translate(-50%, -50%) scale(1.05)' },
102
- _active: disabled ? {} : { cursor: 'grabbing', transform: 'translate(-50%, -50%) scale(1.1)' },
176
+ _hover: { transform: 'translate(-50%, -50%) scale(1.05)' },
177
+ _active: { cursor: 'grabbing', transform: 'translate(-50%, -50%) scale(1.1)' },
103
178
  },
104
- }),
179
+ },
105
180
 
106
- thumbActive: (_props: SliderDynamicProps) => ({
181
+ thumbActive: {
107
182
  _web: {
108
183
  transform: 'translate(-50%, -50%) scale(1.1)',
109
184
  },
110
- }),
185
+ },
111
186
 
112
- thumbIcon: ({ intent = 'primary' }: SliderDynamicProps) => ({
187
+ thumbIcon: {
113
188
  display: 'flex' as const,
114
189
  alignItems: 'center' as const,
115
190
  justifyContent: 'center' as const,
116
191
  flexShrink: 0,
117
- color: theme.intents[intent].primary,
118
192
  variants: {
119
193
  size: {
120
194
  width: theme.sizes.$slider.thumbIconSize,
@@ -124,36 +198,49 @@ export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
124
198
  minHeight: theme.sizes.$slider.thumbIconSize,
125
199
  maxHeight: theme.sizes.$slider.thumbIconSize,
126
200
  },
201
+ intent: createIntentVariants(theme),
127
202
  },
128
- }),
203
+ compoundVariants: (() => {
204
+ const cv: CompoundVariants<keyof SliderVariants> = [];
205
+ for (const intent in theme.intents) {
206
+ cv.push({
207
+ intent,
208
+ styles: {
209
+ color: theme.intents[intent as Intent].primary,
210
+ },
211
+ });
212
+ }
213
+ return cv;
214
+ })(),
215
+ },
129
216
 
130
- valueLabel: (_props: SliderDynamicProps) => ({
217
+ valueLabel: {
131
218
  fontSize: 12,
132
219
  fontWeight: '600' as const,
133
220
  color: theme.colors.text.primary,
134
221
  textAlign: 'center' as const,
135
- }),
222
+ },
136
223
 
137
- minMaxLabels: (_props: SliderDynamicProps) => ({
224
+ minMaxLabels: {
138
225
  flexDirection: 'row' as const,
139
226
  justifyContent: 'space-between' as const,
140
227
  marginTop: 4,
141
- }),
228
+ },
142
229
 
143
- minMaxLabel: (_props: SliderDynamicProps) => ({
230
+ minMaxLabel: {
144
231
  fontSize: 12,
145
232
  color: theme.colors.text.secondary,
146
- }),
233
+ },
147
234
 
148
- marks: (_props: SliderDynamicProps) => ({
235
+ marks: {
149
236
  position: 'absolute' as const,
150
237
  width: '100%',
151
238
  height: '100%',
152
239
  top: 0,
153
240
  left: 0,
154
- }),
241
+ },
155
242
 
156
- mark: (_props: SliderDynamicProps) => ({
243
+ mark: {
157
244
  position: 'absolute' as const,
158
245
  width: 2,
159
246
  backgroundColor: theme.colors.border.secondary,
@@ -166,9 +253,9 @@ export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
166
253
  _web: {
167
254
  transform: 'translate(-50%, -50%)',
168
255
  },
169
- }),
256
+ },
170
257
 
171
- markLabel: (_props: SliderDynamicProps) => ({
258
+ markLabel: {
172
259
  position: 'absolute' as const,
173
260
  fontSize: 10,
174
261
  color: theme.colors.text.secondary,
@@ -178,5 +265,5 @@ export const sliderStyles = defineStyle('Slider', (theme: Theme) => ({
178
265
  transform: 'translateX(-50%)',
179
266
  whiteSpace: 'nowrap',
180
267
  },
181
- }),
268
+ },
182
269
  }));