@idealyst/components 1.1.6 → 1.1.8

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 (144) hide show
  1. package/package.json +8 -3
  2. package/src/Accordion/Accordion.native.tsx +22 -14
  3. package/src/Accordion/Accordion.styles.old.tsx +298 -0
  4. package/src/Accordion/Accordion.styles.tsx +139 -248
  5. package/src/Accordion/Accordion.web.tsx +12 -7
  6. package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -2
  7. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
  8. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +43 -62
  9. package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -2
  10. package/src/Alert/Alert.native.tsx +26 -15
  11. package/src/Alert/Alert.styles.old.tsx +209 -0
  12. package/src/Alert/Alert.styles.tsx +108 -281
  13. package/src/Alert/Alert.web.tsx +6 -10
  14. package/src/Avatar/Avatar.native.tsx +5 -2
  15. package/src/Avatar/Avatar.styles.old.tsx +99 -0
  16. package/src/Avatar/Avatar.styles.tsx +47 -62
  17. package/src/Avatar/Avatar.web.tsx +2 -2
  18. package/src/Badge/Badge.native.tsx +2 -2
  19. package/src/Badge/Badge.styles.old.tsx +157 -0
  20. package/src/Badge/Badge.styles.tsx +69 -108
  21. package/src/Badge/Badge.web.tsx +6 -6
  22. package/src/Breadcrumb/Breadcrumb.native.tsx +12 -5
  23. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
  24. package/src/Breadcrumb/Breadcrumb.styles.tsx +93 -209
  25. package/src/Breadcrumb/Breadcrumb.web.tsx +39 -27
  26. package/src/Button/Button.native.tsx +39 -14
  27. package/src/Button/Button.styles.tsx +99 -253
  28. package/src/Button/Button.web.tsx +10 -8
  29. package/src/Card/Card.native.tsx +8 -4
  30. package/src/Card/Card.styles.old.tsx +160 -0
  31. package/src/Card/Card.styles.tsx +107 -142
  32. package/src/Card/Card.web.tsx +6 -4
  33. package/src/Checkbox/Checkbox.native.tsx +14 -6
  34. package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
  35. package/src/Checkbox/Checkbox.styles.tsx +109 -197
  36. package/src/Checkbox/Checkbox.web.tsx +7 -7
  37. package/src/Chip/Chip.native.tsx +5 -5
  38. package/src/Chip/Chip.styles.old.tsx +184 -0
  39. package/src/Chip/Chip.styles.tsx +34 -22
  40. package/src/Chip/Chip.web.tsx +5 -5
  41. package/src/Dialog/Dialog.native.tsx +16 -7
  42. package/src/Dialog/Dialog.styles.old.tsx +202 -0
  43. package/src/Dialog/Dialog.styles.tsx +108 -132
  44. package/src/Dialog/Dialog.web.tsx +4 -4
  45. package/src/Divider/Divider.native.tsx +29 -42
  46. package/src/Divider/Divider.styles.old.tsx +172 -0
  47. package/src/Divider/Divider.styles.tsx +116 -242
  48. package/src/Divider/Divider.web.tsx +17 -14
  49. package/src/Icon/Icon.native.tsx +12 -4
  50. package/src/Icon/Icon.styles.old.tsx +81 -0
  51. package/src/Icon/Icon.styles.tsx +52 -60
  52. package/src/Icon/Icon.web.tsx +43 -7
  53. package/src/Icon/IconSvg/IconSvg.web.tsx +2 -0
  54. package/src/Image/Image.styles.old.tsx +69 -0
  55. package/src/Image/Image.styles.tsx +45 -43
  56. package/src/Input/Input.native.tsx +140 -56
  57. package/src/Input/Input.styles.old.tsx +289 -0
  58. package/src/Input/Input.styles.tsx +177 -228
  59. package/src/Input/Input.web.tsx +5 -8
  60. package/src/Link/Link.native.tsx +4 -1
  61. package/src/List/List.native.tsx +5 -2
  62. package/src/List/List.styles.old.tsx +242 -0
  63. package/src/List/List.styles.tsx +178 -240
  64. package/src/List/ListItem.native.tsx +16 -8
  65. package/src/List/ListItem.web.tsx +26 -15
  66. package/src/Menu/Menu.native.tsx +1 -1
  67. package/src/Menu/Menu.styles.old.tsx +197 -0
  68. package/src/Menu/Menu.styles.tsx +90 -156
  69. package/src/Menu/Menu.web.tsx +2 -2
  70. package/src/Menu/MenuItem.native.tsx +9 -5
  71. package/src/Menu/MenuItem.styles.old.tsx +114 -0
  72. package/src/Menu/MenuItem.styles.tsx +71 -104
  73. package/src/Menu/MenuItem.web.tsx +23 -5
  74. package/src/Popover/Popover.native.tsx +10 -4
  75. package/src/Popover/Popover.styles.old.tsx +135 -0
  76. package/src/Popover/Popover.styles.tsx +46 -96
  77. package/src/Popover/Popover.web.tsx +1 -1
  78. package/src/Pressable/Pressable.native.tsx +3 -1
  79. package/src/Pressable/Pressable.styles.old.tsx +27 -0
  80. package/src/Pressable/Pressable.styles.tsx +35 -20
  81. package/src/Pressable/Pressable.web.tsx +1 -1
  82. package/src/Progress/Progress.native.tsx +15 -6
  83. package/src/Progress/Progress.styles.old.tsx +200 -0
  84. package/src/Progress/Progress.styles.tsx +69 -118
  85. package/src/Progress/Progress.web.tsx +10 -9
  86. package/src/RadioButton/RadioButton.native.tsx +10 -4
  87. package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
  88. package/src/RadioButton/RadioButton.styles.tsx +81 -145
  89. package/src/RadioButton/RadioButton.web.tsx +4 -4
  90. package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
  91. package/src/SVGImage/SVGImage.styles.tsx +35 -66
  92. package/src/Screen/Screen.native.tsx +30 -27
  93. package/src/Screen/Screen.styles.old.tsx +87 -0
  94. package/src/Screen/Screen.styles.tsx +120 -71
  95. package/src/Screen/Screen.web.tsx +2 -2
  96. package/src/Select/Select.native.tsx +44 -29
  97. package/src/Select/Select.styles.old.tsx +353 -0
  98. package/src/Select/Select.styles.tsx +244 -293
  99. package/src/Select/Select.web.tsx +5 -5
  100. package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
  101. package/src/Skeleton/Skeleton.styles.tsx +31 -43
  102. package/src/Slider/Slider.native.tsx +9 -5
  103. package/src/Slider/Slider.styles.old.tsx +259 -0
  104. package/src/Slider/Slider.styles.tsx +157 -227
  105. package/src/Slider/Slider.web.tsx +5 -5
  106. package/src/Switch/Switch.native.tsx +11 -5
  107. package/src/Switch/Switch.styles.old.tsx +203 -0
  108. package/src/Switch/Switch.styles.tsx +103 -149
  109. package/src/Switch/Switch.web.tsx +8 -8
  110. package/src/TabBar/TabBar.native.tsx +24 -31
  111. package/src/TabBar/TabBar.styles.old.tsx +343 -0
  112. package/src/TabBar/TabBar.styles.tsx +204 -494
  113. package/src/TabBar/TabBar.web.tsx +21 -33
  114. package/src/Table/Table.native.tsx +18 -9
  115. package/src/Table/Table.styles.old.tsx +311 -0
  116. package/src/Table/Table.styles.tsx +151 -278
  117. package/src/Table/Table.web.tsx +1 -1
  118. package/src/Text/Text.native.tsx +1 -4
  119. package/src/Text/Text.style.demo.tsx +16 -0
  120. package/src/Text/Text.styles.old.tsx +219 -0
  121. package/src/Text/Text.styles.tsx +94 -78
  122. package/src/Text/Text.web.tsx +2 -2
  123. package/src/Text/index.ts +1 -0
  124. package/src/TextArea/TextArea.styles.old.tsx +213 -0
  125. package/src/TextArea/TextArea.styles.tsx +101 -157
  126. package/src/Tooltip/Tooltip.native.tsx +2 -2
  127. package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
  128. package/src/Tooltip/Tooltip.styles.tsx +38 -53
  129. package/src/Tooltip/Tooltip.web.tsx +2 -2
  130. package/src/Video/Video.styles.old.tsx +51 -0
  131. package/src/Video/Video.styles.tsx +32 -28
  132. package/src/View/View.native.tsx +12 -12
  133. package/src/View/View.styles.old.tsx +125 -0
  134. package/src/View/View.styles.tsx +84 -103
  135. package/src/View/View.web.tsx +14 -2
  136. package/src/examples/CardExamples.tsx +0 -6
  137. package/src/extensions/applyExtension.ts +210 -0
  138. package/src/extensions/extendComponent.ts +438 -0
  139. package/src/extensions/index.ts +102 -0
  140. package/src/extensions/types.ts +497 -0
  141. package/src/globals.ts +16 -0
  142. package/src/index.native.ts +4 -0
  143. package/src/index.ts +28 -0
  144. package/src/utils/deepMerge.ts +54 -2
@@ -1,234 +1,118 @@
1
+ /**
2
+ * Breadcrumb styles using defineStyle with $iterator expansion.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles, CompoundVariants, Size } from '@idealyst/theme';
3
- import { buildSizeVariants } from '../utils/buildSizeVariants';
4
-
5
- type BreadcrumbSize = Size;
6
- type BreadcrumbIntent = 'primary' | 'neutral';
7
-
8
- type BreadcrumbVariants = {
9
- size: BreadcrumbSize;
10
- intent: BreadcrumbIntent;
11
- disabled: boolean;
12
- isLast: boolean;
13
- clickable: boolean;
14
- }
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Size } from '@idealyst/theme';
15
7
 
16
- export type ExpandedBreadcrumbStyles = StylesheetStyles<keyof BreadcrumbVariants>;
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
17
10
 
18
- export type BreadcrumbStylesheet = {
19
- container: ExpandedBreadcrumbStyles;
20
- item: ExpandedBreadcrumbStyles;
21
- itemText: ExpandedBreadcrumbStyles;
22
- icon: ExpandedBreadcrumbStyles;
23
- separator: ExpandedBreadcrumbStyles;
24
- ellipsis: ExpandedBreadcrumbStyles;
25
- ellipsisIcon: ExpandedBreadcrumbStyles;
26
- menuButton: ExpandedBreadcrumbStyles;
27
- menuButtonIcon: ExpandedBreadcrumbStyles;
28
- }
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
29
13
 
30
- /**
31
- * Create size variants for item text
32
- */
33
- function createItemTextSizeVariants(theme: Theme) {
34
- return buildSizeVariants(theme, 'breadcrumb', (size) => ({
35
- fontSize: size.fontSize,
36
- lineHeight: size.lineHeight,
37
- }));
38
- }
39
-
40
- /**
41
- * Create compound variants for item text
42
- */
43
- function createItemTextCompoundVariants(theme: Theme): CompoundVariants<keyof BreadcrumbVariants> {
44
- return [
45
- {
46
- clickable: true,
47
- intent: 'primary',
48
- isLast: false,
49
- disabled: false,
50
- styles: { color: theme.intents.primary.primary },
51
- },
52
- {
53
- clickable: true,
54
- intent: 'neutral',
55
- isLast: false,
56
- disabled: false,
57
- styles: { color: theme.colors.text.secondary },
58
- },
59
- {
60
- clickable: false,
61
- isLast: false,
62
- disabled: false,
63
- styles: { color: theme.colors.text.secondary },
64
- },
65
- ];
66
- }
14
+ type BreadcrumbIntent = 'primary' | 'neutral';
67
15
 
68
- /**
69
- * Create size variants for icons
70
- */
71
- function createIconSizeVariants(theme: Theme) {
72
- return buildSizeVariants(theme, 'breadcrumb', (size) => ({
73
- width: size.iconSize,
74
- height: size.iconSize,
75
- }));
76
- }
16
+ export type BreadcrumbDynamicProps = {
17
+ size?: Size;
18
+ intent?: BreadcrumbIntent;
19
+ disabled?: boolean;
20
+ isLast?: boolean;
21
+ clickable?: boolean;
22
+ };
77
23
 
78
24
  /**
79
- * Get icon color based on intent
25
+ * Breadcrumb styles with intent and state handling.
80
26
  */
81
- function getIconColor(theme: Theme, intent: BreadcrumbIntent) {
82
- if (intent === 'primary') {
83
- return theme.intents.primary.primary;
84
- }
85
- return theme.colors.text.secondary;
86
- }
27
+ export const breadcrumbStyles = defineStyle('Breadcrumb', (theme: Theme) => ({
28
+ container: (_props: BreadcrumbDynamicProps) => ({
29
+ display: 'flex' as const,
30
+ flexDirection: 'row' as const,
31
+ alignItems: 'center' as const,
32
+ flexWrap: 'wrap' as const,
33
+ gap: 8,
34
+ }),
35
+
36
+ item: (_props: BreadcrumbDynamicProps) => ({
37
+ display: 'flex' as const,
38
+ flexDirection: 'row' as const,
39
+ alignItems: 'center' as const,
40
+ gap: 4,
41
+ }),
42
+
43
+ itemText: ({ intent = 'primary', isLast = false, disabled = false, clickable = true }: BreadcrumbDynamicProps) => {
44
+ // Get color based on state - inline for Unistyles to trace
45
+ const color = disabled
46
+ ? theme.colors.text.secondary
47
+ : isLast
48
+ ? theme.colors.text.primary
49
+ : clickable
50
+ ? (intent === 'primary' ? theme.intents.primary.primary : theme.colors.text.secondary)
51
+ : theme.colors.text.secondary;
87
52
 
88
- const createItemTextStyles = (theme: Theme) => {
89
- return {
90
- variants: {
91
- size: createItemTextSizeVariants(theme),
92
- intent: { primary: {}, neutral: {} },
93
- disabled: {
94
- true: {
95
- opacity: 0.5,
96
- color: theme.colors.text.secondary,
53
+ return {
54
+ color,
55
+ opacity: disabled ? 0.5 : 1,
56
+ variants: {
57
+ // $iterator expands for each breadcrumb size
58
+ size: {
59
+ fontSize: theme.sizes.$breadcrumb.fontSize,
60
+ lineHeight: theme.sizes.$breadcrumb.lineHeight,
97
61
  },
98
- false: {},
99
- },
100
- isLast: {
101
- true: { color: theme.colors.text.primary },
102
- false: {},
103
62
  },
104
- clickable: { true: {}, false: {} },
105
- },
106
- compoundVariants: createItemTextCompoundVariants(theme),
107
- } as const;
108
- }
63
+ } as const;
64
+ },
109
65
 
110
- const createIconStyles = (theme: Theme) => {
111
- return {
66
+ icon: (_props: BreadcrumbDynamicProps) => ({
112
67
  variants: {
113
- size: createIconSizeVariants(theme),
68
+ size: {
69
+ width: theme.sizes.$breadcrumb.iconSize,
70
+ height: theme.sizes.$breadcrumb.iconSize,
71
+ fontSize: theme.sizes.$breadcrumb.iconSize,
72
+ },
114
73
  },
115
- } as const;
116
- }
74
+ }),
117
75
 
118
- const createSeparatorStyles = (theme: Theme) => {
119
- return {
76
+ separator: (_props: BreadcrumbDynamicProps) => ({
120
77
  color: theme.colors.text.tertiary,
121
78
  variants: {
122
- size: createItemTextSizeVariants(theme),
123
- },
124
- } as const;
125
- }
126
-
127
- const createEllipsisIconStyles = (theme: Theme) => {
128
- return ({ intent }: Partial<BreadcrumbVariants>) => {
129
- return {
130
- color: getIconColor(theme, intent),
131
- variants: {
132
- size: createIconSizeVariants(theme),
79
+ size: {
80
+ fontSize: theme.sizes.$breadcrumb.fontSize,
81
+ lineHeight: theme.sizes.$breadcrumb.lineHeight,
133
82
  },
134
- } as const;
135
- }
136
- }
137
-
138
- const createMenuButtonIconStyles = (theme: Theme) => {
139
- return ({ intent }: Partial<BreadcrumbVariants>) => {
140
- return {
141
- color: getIconColor(theme, intent),
142
- variants: {
143
- size: createIconSizeVariants(theme),
144
- },
145
- } as const;
146
- }
147
- }
148
-
149
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
150
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
151
- export const breadcrumbStyles = StyleSheet.create((theme: Theme) => {
152
- return {
153
- container: {
154
- display: 'flex',
155
- flexDirection: 'row',
156
- alignItems: 'center',
157
- flexWrap: 'wrap',
158
- gap: 8,
159
- },
160
- item: {
161
- display: 'flex',
162
- flexDirection: 'row',
163
- alignItems: 'center',
164
- gap: 4,
165
- },
166
- itemText: createItemTextStyles(theme),
167
- icon: createIconStyles(theme),
168
- separator: createSeparatorStyles(theme),
169
- ellipsis: {
170
- display: 'flex',
171
- alignItems: 'center',
172
- justifyContent: 'center',
173
83
  },
174
- ellipsisIcon: createEllipsisIconStyles(theme),
175
- menuButton: {
176
- paddingVertical: 4,
177
- paddingHorizontal: 8,
178
- },
179
- menuButtonIcon: createMenuButtonIconStyles(theme),
180
- };
181
- });
84
+ }),
182
85
 
183
- // Export individual style sheets for backwards compatibility
184
- export const breadcrumbContainerStyles = StyleSheet.create((theme: Theme) => {
185
- return {
186
- container: {
187
- display: 'flex',
188
- flexDirection: 'row',
189
- alignItems: 'center',
190
- flexWrap: 'wrap',
191
- gap: 8,
192
- },
193
- };
194
- });
86
+ ellipsis: (_props: BreadcrumbDynamicProps) => ({
87
+ display: 'flex' as const,
88
+ alignItems: 'center' as const,
89
+ justifyContent: 'center' as const,
90
+ }),
195
91
 
196
- export const breadcrumbItemStyles = StyleSheet.create((theme: Theme) => {
197
- return {
198
- item: {
199
- display: 'flex',
200
- flexDirection: 'row',
201
- alignItems: 'center',
202
- gap: 4,
92
+ ellipsisIcon: ({ intent = 'primary' }: BreadcrumbDynamicProps) => ({
93
+ color: intent === 'primary' ? theme.intents.primary.primary : theme.colors.text.secondary,
94
+ variants: {
95
+ size: {
96
+ width: theme.sizes.$breadcrumb.iconSize,
97
+ height: theme.sizes.$breadcrumb.iconSize,
98
+ fontSize: theme.sizes.$breadcrumb.iconSize,
99
+ },
203
100
  },
204
- itemText: createItemTextStyles(theme),
205
- icon: createIconStyles(theme),
206
- } as const;
207
- });
208
-
209
- export const breadcrumbSeparatorStyles = StyleSheet.create((theme: Theme) => {
210
- return {
211
- separator: createSeparatorStyles(theme),
212
- } as const;
213
- });
101
+ }),
214
102
 
215
- export const breadcrumbEllipsisStyles = StyleSheet.create((theme: Theme) => {
216
- return {
217
- ellipsis: {
218
- display: 'flex',
219
- alignItems: 'center',
220
- justifyContent: 'center',
221
- },
222
- icon: createEllipsisIconStyles(theme),
223
- } as const;
224
- });
103
+ menuButton: (_props: BreadcrumbDynamicProps) => ({
104
+ paddingVertical: 4,
105
+ paddingHorizontal: 8,
106
+ }),
225
107
 
226
- export const breadcrumbMenuButtonStyles = StyleSheet.create((theme: Theme) => {
227
- return {
228
- button: {
229
- paddingVertical: 4,
230
- paddingHorizontal: 8,
108
+ menuButtonIcon: ({ intent = 'primary' }: BreadcrumbDynamicProps) => ({
109
+ color: intent === 'primary' ? theme.intents.primary.primary : theme.colors.text.secondary,
110
+ variants: {
111
+ size: {
112
+ width: theme.sizes.$breadcrumb.iconSize,
113
+ height: theme.sizes.$breadcrumb.iconSize,
114
+ fontSize: theme.sizes.$breadcrumb.iconSize,
115
+ },
231
116
  },
232
- icon: createMenuButtonIconStyles(theme),
233
- } as const;
234
- });
117
+ }),
118
+ }));
@@ -1,12 +1,6 @@
1
- import React, { isValidElement, useState, useRef, useEffect } from 'react';
1
+ import React, { isValidElement, useState } from 'react';
2
2
  import { getWebProps } from 'react-native-unistyles/web';
3
- import {
4
- breadcrumbContainerStyles,
5
- breadcrumbItemStyles,
6
- breadcrumbSeparatorStyles,
7
- breadcrumbEllipsisStyles,
8
- breadcrumbMenuButtonStyles
9
- } from './Breadcrumb.styles';
3
+ import { breadcrumbStyles } from './Breadcrumb.styles';
10
4
  import type { BreadcrumbProps, BreadcrumbItem as BreadcrumbItemType } from './types';
11
5
  import { IconSvg } from '../Icon/IconSvg/IconSvg.web';
12
6
  import { resolveIconPath, isIconName } from '../Icon/icon-resolver';
@@ -22,18 +16,27 @@ interface BreadcrumbItemProps {
22
16
  }
23
17
 
24
18
  const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ item, isLast, size, intent, itemStyle }) => {
25
- // Apply variants for this item only
26
- breadcrumbItemStyles.useVariants({
19
+ const isClickable = !!item.onPress && !item.disabled;
20
+ const isDisabled = item.disabled || false;
21
+
22
+ // Apply size variant
23
+ breadcrumbStyles.useVariants({
27
24
  size,
25
+ });
26
+
27
+ // Get dynamic styles - call as functions for theme reactivity
28
+ const itemStyle_ = (breadcrumbStyles.item as any)({});
29
+ const itemTextStyle = (breadcrumbStyles.itemText as any)({
28
30
  intent,
29
- disabled: item.disabled || false,
30
31
  isLast,
31
- clickable: !!item.onPress && !item.disabled,
32
+ disabled: isDisabled,
33
+ clickable: isClickable,
32
34
  });
35
+ const iconStyle = (breadcrumbStyles.icon as any)({});
33
36
 
34
- const itemProps = getWebProps([breadcrumbItemStyles.item]);
35
- const itemTextProps = getWebProps([breadcrumbItemStyles.itemText, itemStyle]);
36
- const iconProps = getWebProps([breadcrumbItemStyles.icon]);
37
+ const itemProps = getWebProps([itemStyle_]);
38
+ const itemTextProps = getWebProps([itemTextStyle, itemStyle]);
39
+ const iconProps = getWebProps([iconStyle]);
37
40
 
38
41
  const handleClick = () => {
39
42
  if (!item.disabled && item.onPress) {
@@ -46,10 +49,10 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ item, isLast, size, int
46
49
 
47
50
  if (isIconName(item.icon)) {
48
51
  const iconPath = resolveIconPath(item.icon);
52
+ // IconSvg uses size="1em" by default, sized by container's fontSize from styles
49
53
  return (
50
54
  <IconSvg
51
55
  path={iconPath}
52
- {...iconProps}
53
56
  aria-label={item.icon}
54
57
  />
55
58
  );
@@ -80,7 +83,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ item, isLast, size, int
80
83
  </div>
81
84
  );
82
85
 
83
- if (item.onPress && !item.disabled) {
86
+ if (isClickable) {
84
87
  return (
85
88
  <button
86
89
  onClick={handleClick}
@@ -91,7 +94,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ item, isLast, size, int
91
94
  cursor: 'pointer',
92
95
  textDecoration: 'none',
93
96
  }}
94
- disabled={item.disabled}
97
+ disabled={isDisabled}
95
98
  aria-current={isLast ? 'page' : undefined}
96
99
  >
97
100
  {content}
@@ -113,8 +116,9 @@ interface BreadcrumbSeparatorProps {
113
116
  }
114
117
 
115
118
  const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = ({ separator, size, separatorStyle }) => {
116
- breadcrumbSeparatorStyles.useVariants({ size });
117
- const separatorProps = getWebProps([breadcrumbSeparatorStyles.separator, separatorStyle]);
119
+ breadcrumbStyles.useVariants({ size });
120
+ const separatorStyle_ = (breadcrumbStyles.separator as any)({});
121
+ const separatorProps = getWebProps([separatorStyle_, separatorStyle]);
118
122
 
119
123
  return (
120
124
  <span {...separatorProps} aria-hidden="true">
@@ -129,9 +133,11 @@ interface BreadcrumbEllipsisProps {
129
133
  }
130
134
 
131
135
  const BreadcrumbEllipsis: React.FC<BreadcrumbEllipsisProps> = ({ size, intent }) => {
132
- breadcrumbEllipsisStyles.useVariants({ size });
133
- const ellipsisProps = getWebProps([breadcrumbEllipsisStyles.ellipsis]);
134
- const iconProps = getWebProps([breadcrumbEllipsisStyles.icon({ intent })]);
136
+ breadcrumbStyles.useVariants({ size });
137
+ const ellipsisStyle = (breadcrumbStyles.ellipsis as any)({});
138
+ const ellipsisIconStyle = (breadcrumbStyles.ellipsisIcon as any)({ intent });
139
+ const ellipsisProps = getWebProps([ellipsisStyle]);
140
+ const iconProps = getWebProps([ellipsisIconStyle]);
135
141
  const ellipsisIconPath = resolveIconPath('dots-horizontal');
136
142
 
137
143
  return (
@@ -160,13 +166,19 @@ const Breadcrumb: React.FC<BreadcrumbProps> = ({
160
166
  id,
161
167
  }) => {
162
168
  const [menuOpen, setMenuOpen] = useState(false);
163
- const containerProps = getWebProps([breadcrumbContainerStyles.container, style as any]);
169
+
170
+ // Get dynamic styles - call as functions for theme reactivity
171
+ const containerStyle = (breadcrumbStyles.container as any)({});
172
+ const menuButtonStyle = (breadcrumbStyles.menuButton as any)({});
173
+ const menuButtonIconStyle = (breadcrumbStyles.menuButtonIcon as any)({ intent });
174
+
175
+ const containerProps = getWebProps([containerStyle, style as any]);
164
176
  const menuIconPath = resolveIconPath('dots-horizontal');
165
177
 
166
178
  // Apply variants for menu button
167
- breadcrumbMenuButtonStyles.useVariants({ size });
168
- const menuButtonProps = getWebProps([breadcrumbMenuButtonStyles.button]);
169
- const menuIconProps = getWebProps([breadcrumbMenuButtonStyles.icon({ intent })]);
179
+ breadcrumbStyles.useVariants({ size });
180
+ const menuButtonProps = getWebProps([menuButtonStyle]);
181
+ const menuIconProps = getWebProps([menuButtonIconStyle]);
170
182
 
171
183
  // Handle responsive collapsing
172
184
  let displayItems = items;
@@ -34,29 +34,30 @@ const Button = forwardRef<ComponentRef<typeof TouchableOpacity>, ButtonProps>((p
34
34
  accessibilityPressed,
35
35
  } = props;
36
36
 
37
- // Apply variants
37
+ // Apply variants for size, disabled, gradient
38
38
  buttonStyles.useVariants({
39
- type,
40
- intent,
41
39
  size,
42
40
  disabled,
43
41
  gradient,
44
42
  });
45
43
 
46
- // Compute dynamic styles
47
- const buttonStyle = buttonStyles.button;
48
- const textStyle = buttonStyles.text;
49
- const iconStyle = buttonStyles.icon;
44
+ // Compute dynamic styles with all props for full flexibility
45
+ const dynamicProps = { intent, type, size, disabled, gradient };
46
+ const buttonStyle = (buttonStyles.button as any)(dynamicProps);
47
+ const textStyle = (buttonStyles.text as any)(dynamicProps);
48
+ const iconStyle = (buttonStyles.icon as any)(dynamicProps);
49
+ const iconContainerStyle = (buttonStyles.iconContainer as any)(dynamicProps);
50
50
 
51
51
  // Gradient is only applicable to contained buttons
52
52
  const showGradient = gradient && type === 'contained';
53
53
 
54
54
  // Get gradient overlay colors (transparent to semi-transparent black/white)
55
+ // Note: Use explicit rgba(0,0,0,0) instead of 'transparent' for RN SVG compatibility
55
56
  const getGradientColors = (): [string, string] => {
56
57
  switch (gradient) {
57
- case 'darken': return ['transparent', 'rgba(0, 0, 0, 0.15)'];
58
- case 'lighten': return ['transparent', 'rgba(255, 255, 255, 0.2)'];
59
- default: return ['transparent', 'transparent'];
58
+ case 'darken': return ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0.15)'];
59
+ case 'lighten': return ['rgba(255, 255, 255, 0)', 'rgba(255, 255, 255, 0.2)'];
60
+ default: return ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0)'];
60
61
  }
61
62
  };
62
63
 
@@ -133,14 +134,38 @@ const Button = forwardRef<ComponentRef<typeof TouchableOpacity>, ButtonProps>((p
133
134
  const renderGradientLayer = () => {
134
135
  if (!showGradient) return null;
135
136
 
136
- const [startColor, endColor] = getGradientColors();
137
+ const [startColor, endColor] = useMemo(() => {
138
+ switch (gradient) {
139
+ case 'darken': return [{
140
+ stopColor: 'black',
141
+ stopOpacity: 0,
142
+ }, {
143
+ stopColor: 'black',
144
+ stopOpacity: 0.15,
145
+ }];
146
+ case 'lighten': return [{
147
+ stopColor: 'white',
148
+ stopOpacity: 0,
149
+ }, {
150
+ stopColor: 'white',
151
+ stopOpacity: 0.2,
152
+ }];
153
+ default: return [{
154
+ stopColor: 'black',
155
+ stopOpacity: 0,
156
+ }, {
157
+ stopColor: 'black',
158
+ stopOpacity: 0,
159
+ }];
160
+ }
161
+ }, [gradient]);
137
162
 
138
163
  return (
139
164
  <Svg style={RNStyleSheet.absoluteFill}>
140
165
  <Defs>
141
166
  <LinearGradient id="buttonGradient" x1="0%" y1="0%" x2="100%" y2="100%">
142
- <Stop offset="0%" stopColor={startColor} />
143
- <Stop offset="100%" stopColor={endColor} />
167
+ <Stop offset="0%" {...startColor} />
168
+ <Stop offset="100%" {...endColor} />
144
169
  </LinearGradient>
145
170
  </Defs>
146
171
  <Rect
@@ -174,7 +199,7 @@ const Button = forwardRef<ComponentRef<typeof TouchableOpacity>, ButtonProps>((p
174
199
  <TouchableOpacity {...touchableProps as any}>
175
200
  {renderGradientLayer()}
176
201
  {hasIcons ? (
177
- <View style={buttonStyles.iconContainer}>
202
+ <View style={iconContainerStyle}>
178
203
  {leftIcon && renderIcon(leftIcon)}
179
204
  <Text style={textStyle}>
180
205
  {buttonContent}