@idealyst/components 1.1.6 → 1.1.7

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 (104) hide show
  1. package/package.json +8 -3
  2. package/src/Accordion/Accordion.native.tsx +15 -9
  3. package/src/Accordion/Accordion.styles.tsx +193 -168
  4. package/src/Accordion/Accordion.web.tsx +12 -7
  5. package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -2
  6. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +22 -11
  7. package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -2
  8. package/src/Alert/Alert.native.tsx +11 -10
  9. package/src/Alert/Alert.styles.tsx +162 -253
  10. package/src/Alert/Alert.web.tsx +6 -10
  11. package/src/Avatar/Avatar.native.tsx +5 -2
  12. package/src/Avatar/Avatar.styles.tsx +48 -18
  13. package/src/Avatar/Avatar.web.tsx +2 -2
  14. package/src/Badge/Badge.native.tsx +2 -2
  15. package/src/Badge/Badge.styles.tsx +37 -16
  16. package/src/Badge/Badge.web.tsx +6 -6
  17. package/src/Breadcrumb/Breadcrumb.native.tsx +12 -5
  18. package/src/Breadcrumb/Breadcrumb.styles.tsx +59 -58
  19. package/src/Breadcrumb/Breadcrumb.web.tsx +13 -6
  20. package/src/Button/Button.native.tsx +39 -14
  21. package/src/Button/Button.styles.tsx +106 -208
  22. package/src/Button/Button.web.tsx +10 -8
  23. package/src/Card/Card.native.tsx +14 -6
  24. package/src/Card/Card.styles.tsx +64 -62
  25. package/src/Card/Card.web.tsx +5 -4
  26. package/src/Checkbox/Checkbox.native.tsx +7 -3
  27. package/src/Checkbox/Checkbox.styles.tsx +49 -25
  28. package/src/Checkbox/Checkbox.web.tsx +3 -3
  29. package/src/Chip/Chip.native.tsx +5 -5
  30. package/src/Chip/Chip.styles.tsx +71 -21
  31. package/src/Chip/Chip.web.tsx +5 -5
  32. package/src/Dialog/Dialog.native.tsx +10 -4
  33. package/src/Dialog/Dialog.styles.tsx +130 -90
  34. package/src/Dialog/Dialog.web.tsx +4 -4
  35. package/src/Divider/Divider.native.tsx +29 -42
  36. package/src/Divider/Divider.styles.tsx +138 -242
  37. package/src/Divider/Divider.web.tsx +17 -14
  38. package/src/Icon/Icon.native.tsx +11 -3
  39. package/src/Icon/Icon.styles.tsx +10 -4
  40. package/src/Image/Image.styles.tsx +53 -37
  41. package/src/Input/Input.native.tsx +6 -7
  42. package/src/Input/Input.styles.tsx +194 -174
  43. package/src/Input/Input.web.tsx +5 -8
  44. package/src/Link/Link.native.tsx +4 -1
  45. package/src/List/List.styles.tsx +79 -105
  46. package/src/List/ListItem.native.tsx +5 -3
  47. package/src/List/ListItem.web.tsx +4 -3
  48. package/src/Menu/Menu.native.tsx +1 -1
  49. package/src/Menu/Menu.styles.tsx +53 -37
  50. package/src/Menu/Menu.web.tsx +2 -2
  51. package/src/Menu/MenuItem.native.tsx +5 -3
  52. package/src/Menu/MenuItem.styles.tsx +68 -69
  53. package/src/Menu/MenuItem.web.tsx +16 -3
  54. package/src/Popover/Popover.native.tsx +1 -1
  55. package/src/Popover/Popover.styles.tsx +40 -29
  56. package/src/Popover/Popover.web.tsx +1 -1
  57. package/src/Pressable/Pressable.native.tsx +3 -1
  58. package/src/Pressable/Pressable.styles.tsx +20 -13
  59. package/src/Pressable/Pressable.web.tsx +1 -1
  60. package/src/Progress/Progress.native.tsx +15 -6
  61. package/src/Progress/Progress.styles.tsx +125 -85
  62. package/src/Progress/Progress.web.tsx +10 -9
  63. package/src/RadioButton/RadioButton.native.tsx +8 -3
  64. package/src/RadioButton/RadioButton.styles.tsx +44 -37
  65. package/src/RadioButton/RadioButton.web.tsx +3 -3
  66. package/src/SVGImage/SVGImage.styles.tsx +28 -16
  67. package/src/Screen/Screen.native.tsx +23 -13
  68. package/src/Screen/Screen.styles.tsx +57 -46
  69. package/src/Screen/Screen.web.tsx +1 -1
  70. package/src/Select/Select.native.tsx +11 -5
  71. package/src/Select/Select.styles.tsx +72 -52
  72. package/src/Select/Select.web.tsx +5 -5
  73. package/src/Skeleton/Skeleton.styles.tsx +26 -14
  74. package/src/Slider/Slider.native.tsx +9 -5
  75. package/src/Slider/Slider.styles.tsx +59 -48
  76. package/src/Slider/Slider.web.tsx +5 -5
  77. package/src/Switch/Switch.native.tsx +6 -2
  78. package/src/Switch/Switch.styles.tsx +46 -19
  79. package/src/Switch/Switch.web.tsx +4 -4
  80. package/src/TabBar/TabBar.native.tsx +23 -31
  81. package/src/TabBar/TabBar.styles.tsx +215 -371
  82. package/src/TabBar/TabBar.web.tsx +21 -33
  83. package/src/Table/Table.native.tsx +1 -1
  84. package/src/Table/Table.styles.tsx +11 -4
  85. package/src/Table/Table.web.tsx +1 -1
  86. package/src/Text/Text.native.tsx +3 -4
  87. package/src/Text/Text.styles.tsx +7 -1
  88. package/src/Text/Text.web.tsx +1 -1
  89. package/src/TextArea/TextArea.styles.tsx +90 -58
  90. package/src/Tooltip/Tooltip.native.tsx +2 -2
  91. package/src/Tooltip/Tooltip.styles.tsx +21 -12
  92. package/src/Tooltip/Tooltip.web.tsx +2 -2
  93. package/src/Video/Video.styles.tsx +39 -23
  94. package/src/View/View.native.tsx +4 -2
  95. package/src/View/View.styles.tsx +33 -22
  96. package/src/View/View.web.tsx +13 -2
  97. package/src/extensions/applyExtension.ts +210 -0
  98. package/src/extensions/extendComponent.ts +377 -0
  99. package/src/extensions/index.ts +102 -0
  100. package/src/extensions/types.ts +497 -0
  101. package/src/globals.ts +16 -0
  102. package/src/index.native.ts +4 -0
  103. package/src/index.ts +28 -0
  104. package/src/utils/deepMerge.ts +54 -2
@@ -9,7 +9,7 @@ import {
9
9
  } from './TabBar.styles';
10
10
  import type { TabBarProps, TabBarItem } from './types';
11
11
  import useMergeRefs from '../hooks/useMergeRefs';
12
- import { getWebAriaProps, generateAccessibilityId, TAB_KEYS } from '../utils/accessibility';
12
+ import { getWebAriaProps, generateAccessibilityId } from '../utils/accessibility';
13
13
 
14
14
  // Icon size mapping based on size variant
15
15
  const ICON_SIZES: Record<string, number> = {
@@ -66,23 +66,7 @@ const Tab: React.FC<TabProps> = ({
66
66
  }) => {
67
67
  const iconSize = ICON_SIZES[size || 'md'] || 18;
68
68
 
69
- // Apply tab and label types for this specific tab
70
- tabBarTabStyles.useVariants({
71
- size,
72
- type,
73
- active: isActive,
74
- disabled: Boolean(item.disabled),
75
- pillMode,
76
- iconPosition,
77
- justify,
78
- });
79
- tabBarLabelStyles.useVariants({
80
- size,
81
- type,
82
- pillMode,
83
- active: isActive,
84
- disabled: Boolean(item.disabled),
85
- });
69
+ // Apply icon variants (size, disabled, iconPosition)
86
70
  tabBarIconStyles.useVariants({
87
71
  size,
88
72
  active: isActive,
@@ -90,9 +74,13 @@ const Tab: React.FC<TabProps> = ({
90
74
  iconPosition,
91
75
  });
92
76
 
93
- const tabProps = getWebProps([tabBarTabStyles.tab]);
94
- const labelProps = getWebProps([tabBarLabelStyles.tabLabel]);
95
- const iconProps = getWebProps([tabBarIconStyles.tabIcon]);
77
+ // Compute dynamic styles for this tab
78
+ const tabStyle = (tabBarTabStyles.tab as any)({ type, size, active: isActive, pillMode, justify });
79
+ const labelStyle = (tabBarLabelStyles.tabLabel as any)({ type, active: isActive, pillMode });
80
+
81
+ const tabProps = getWebProps([tabStyle]);
82
+ const labelProps = getWebProps([labelStyle]);
83
+ const iconProps = getWebProps([tabBarIconStyles.tabIcon as any]);
96
84
 
97
85
  // Merge refs from getWebProps with our tracking ref
98
86
  const mergedRef = useMergeRefs<HTMLButtonElement>(
@@ -174,16 +162,16 @@ const TabBar: React.FC<TabBarProps> = ({
174
162
  const currentIndex = enabledItems.findIndex(item => item.value === itemValue);
175
163
  let nextIndex = -1;
176
164
 
177
- if (TAB_KEYS.next.includes(key)) {
165
+ if (key === 'ArrowRight') {
178
166
  e.preventDefault();
179
167
  nextIndex = currentIndex < enabledItems.length - 1 ? currentIndex + 1 : 0;
180
- } else if (TAB_KEYS.prev.includes(key)) {
168
+ } else if (key === 'ArrowLeft') {
181
169
  e.preventDefault();
182
170
  nextIndex = currentIndex > 0 ? currentIndex - 1 : enabledItems.length - 1;
183
- } else if (TAB_KEYS.first.includes(key)) {
171
+ } else if (key === 'Home') {
184
172
  e.preventDefault();
185
173
  nextIndex = 0;
186
- } else if (TAB_KEYS.last.includes(key)) {
174
+ } else if (key === 'End') {
187
175
  e.preventDefault();
188
176
  nextIndex = enabledItems.length - 1;
189
177
  }
@@ -255,11 +243,8 @@ const TabBar: React.FC<TabBarProps> = ({
255
243
  onChange?.(itemValue);
256
244
  };
257
245
 
258
- // Apply container and indicator types
259
- tabBarContainerStyles.useVariants({
260
- type,
261
- size,
262
- pillMode,
246
+ // Apply container variants (for spacing only)
247
+ (tabBarContainerStyles.useVariants as any)({
263
248
  justify,
264
249
  gap,
265
250
  padding,
@@ -269,10 +254,13 @@ const TabBar: React.FC<TabBarProps> = ({
269
254
  marginVertical,
270
255
  marginHorizontal,
271
256
  });
272
- const containerProps = getWebProps([tabBarContainerStyles.container, style as any]);
273
257
 
274
- tabBarIndicatorStyles.useVariants({ type, pillMode });
275
- const indicatorProps = getWebProps([tabBarIndicatorStyles.indicator]);
258
+ // Compute dynamic container and indicator styles
259
+ const containerStyle = (tabBarContainerStyles.container as any)({ type, pillMode });
260
+ const containerProps = getWebProps([containerStyle, style as any]);
261
+
262
+ const indicatorVisualStyle = (tabBarIndicatorStyles.indicator as any)({ type, pillMode });
263
+ const indicatorProps = getWebProps([indicatorVisualStyle]);
276
264
 
277
265
  // Merge container ref with getWebProps ref
278
266
  const mergedContainerRef = useMergeRefs<HTMLDivElement>(
@@ -67,7 +67,7 @@ function TableInner<T = any>({
67
67
  ref={ref}
68
68
  nativeID={id}
69
69
  horizontal
70
- style={[tableStyles.container, style]}
70
+ style={[(tableStyles.container as any)({}), style]}
71
71
  testID={testID}
72
72
  {...nativeA11yProps}
73
73
  >
@@ -10,6 +10,7 @@ import {
10
10
  buildMarginVerticalVariants,
11
11
  buildMarginHorizontalVariants,
12
12
  } from '../utils/buildViewStyleVariants';
13
+ import { applyExtensions } from '../extensions/applyExtension';
13
14
 
14
15
  type TableType = 'default' | 'bordered' | 'striped';
15
16
 
@@ -166,8 +167,8 @@ function createCellTypeVariants(theme: Theme) {
166
167
  } as const;
167
168
  }
168
169
 
169
- const createContainerStyles = (theme: Theme) => {
170
- return {
170
+ function createContainerStyles(theme: Theme) {
171
+ return () => ({
171
172
  width: '100%',
172
173
  _web: {
173
174
  overflow: 'auto',
@@ -183,7 +184,7 @@ const createContainerStyles = (theme: Theme) => {
183
184
  marginVertical: buildMarginVerticalVariants(theme),
184
185
  marginHorizontal: buildMarginHorizontalVariants(theme),
185
186
  },
186
- } as const;
187
+ });
187
188
  }
188
189
 
189
190
  const createTableStyles = (theme: Theme) => {
@@ -298,8 +299,14 @@ const createCellStyles = (theme: Theme) => {
298
299
  }
299
300
 
300
301
  export const tableStyles = StyleSheet.create((theme: Theme) => {
301
- return {
302
+ // Apply extensions to main visual elements
303
+ const extended = applyExtensions('Table', theme, {
302
304
  container: createContainerStyles(theme),
305
+ });
306
+
307
+ return {
308
+ ...extended,
309
+ // Minor utility styles (not extended)
303
310
  table: createTableStyles(theme),
304
311
  thead: createTheadStyles(theme),
305
312
  tbody: {},
@@ -50,7 +50,7 @@ function Table<T = any>({
50
50
  marginHorizontal,
51
51
  });
52
52
 
53
- const containerProps = getWebProps([tableStyles.container, style as any]);
53
+ const containerProps = getWebProps([(tableStyles.container as any)({}), style as any]);
54
54
  const tableProps = getWebProps([tableStyles.table]);
55
55
 
56
56
  // Helper to get cell value
@@ -28,14 +28,13 @@ const Text = forwardRef<RNText, TextProps>(({
28
28
  paddingHorizontal,
29
29
  });
30
30
 
31
+ const textStyle = (textStyles.text as any)({ color });
32
+
31
33
  return (
32
34
  <RNText
33
35
  ref={ref}
34
36
  nativeID={id}
35
- style={[
36
- textStyles.text({ color }),
37
- style,
38
- ]}
37
+ style={[textStyle, style]}
39
38
  testID={testID}
40
39
  >
41
40
  {children}
@@ -7,6 +7,7 @@ import {
7
7
  buildPaddingHorizontalVariants,
8
8
  } from '../utils/buildViewStyleVariants';
9
9
  import { TextAlignVariant, TextColorVariant, TextWeightVariant, TextTypographyVariant } from "./types";
10
+ import { applyExtensions } from '../extensions/applyExtension';
10
11
 
11
12
  export type TextVariants = {
12
13
  typography: TextTypographyVariant;
@@ -90,7 +91,12 @@ function createTextStyles(theme: Theme) {
90
91
  // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
91
92
  // transform on native cannot resolve function calls to extract variant structures.
92
93
  export const textStyles = StyleSheet.create((theme: Theme) => {
93
- return {
94
+ // Apply extensions to main visual elements
95
+ const extended = applyExtensions('Text', theme, {
94
96
  text: createTextStyles(theme),
97
+ });
98
+
99
+ return {
100
+ ...extended,
95
101
  };
96
102
  });
@@ -31,7 +31,7 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
31
31
 
32
32
  // Create the style array
33
33
  const textStyleArray = [
34
- textStyles.text({ color }),
34
+ (textStyles.text as any)({ color }),
35
35
  style,
36
36
  ];
37
37
 
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles, Intent, Size} from '@idealyst/theme';
2
+ import { Theme, StylesheetStyles, Intent, Size } from '@idealyst/theme';
3
3
  import { buildSizeVariants } from '../utils/buildSizeVariants';
4
4
  import {
5
5
  buildMarginVariants,
@@ -7,6 +7,7 @@ import {
7
7
  buildMarginHorizontalVariants,
8
8
  } from '../utils/buildViewStyleVariants';
9
9
  import { TextAreaIntentVariant } from './types';
10
+ import { applyExtensions } from '../extensions/applyExtension';
10
11
 
11
12
 
12
13
  /**
@@ -114,73 +115,104 @@ const createTextareaStyles = (theme: Theme) => {
114
115
  }
115
116
  }
116
117
 
117
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
118
- export const textAreaStyles = StyleSheet.create((theme: Theme) => {
119
- return {
120
- container: {
121
- display: 'flex',
122
- flexDirection: 'column',
123
- gap: 4,
124
- variants: {
125
- // Spacing variants from FormInputStyleProps
126
- margin: buildMarginVariants(theme),
127
- marginVertical: buildMarginVerticalVariants(theme),
128
- marginHorizontal: buildMarginHorizontalVariants(theme),
129
- },
118
+ // Helper functions to create static styles wrapped in dynamic functions
119
+ function createContainerStyles(theme: Theme) {
120
+ return () => ({
121
+ display: 'flex' as const,
122
+ flexDirection: 'column' as const,
123
+ gap: 4,
124
+ variants: {
125
+ // Spacing variants from FormInputStyleProps
126
+ margin: buildMarginVariants(theme),
127
+ marginVertical: buildMarginVerticalVariants(theme),
128
+ marginHorizontal: buildMarginHorizontalVariants(theme),
130
129
  },
131
- label: {
132
- fontSize: 14,
133
- fontWeight: '500',
134
- color: theme.colors.text.primary,
135
- variants: {
136
- disabled: {
137
- true: {
138
- opacity: 0.5,
139
- },
140
- false: {},
130
+ });
131
+ }
132
+
133
+ function createLabelStyles(theme: Theme) {
134
+ return () => ({
135
+ fontSize: 14,
136
+ fontWeight: '500' as const,
137
+ color: theme.colors.text.primary,
138
+ variants: {
139
+ disabled: {
140
+ true: {
141
+ opacity: 0.5,
141
142
  },
143
+ false: {},
142
144
  },
143
145
  },
144
- textareaContainer: {
145
- position: 'relative',
146
- },
147
- textarea: createTextareaStyles(theme),
148
- helperText: {
149
- fontSize: 12,
150
- color: theme.colors.text.secondary,
151
- variants: {
152
- hasError: {
153
- true: {
154
- color: theme.intents.error.primary,
155
- },
156
- false: {},
146
+ });
147
+ }
148
+
149
+ function createTextareaContainerStyles() {
150
+ return () => ({
151
+ position: 'relative' as const,
152
+ });
153
+ }
154
+
155
+ function createHelperTextStyles(theme: Theme) {
156
+ return () => ({
157
+ fontSize: 12,
158
+ color: theme.colors.text.secondary,
159
+ variants: {
160
+ hasError: {
161
+ true: {
162
+ color: theme.intents.error.primary,
157
163
  },
164
+ false: {},
158
165
  },
159
166
  },
160
- footer: {
161
- display: 'flex',
162
- flexDirection: 'row',
163
- justifyContent: 'space-between',
164
- alignItems: 'center',
165
- gap: 4,
166
- },
167
- characterCount: {
168
- fontSize: 12,
169
- color: theme.colors.text.secondary,
170
- variants: {
171
- isNearLimit: {
172
- true: {
173
- color: theme.intents.warning.primary,
174
- },
175
- false: {},
167
+ });
168
+ }
169
+
170
+ function createFooterStyles() {
171
+ return () => ({
172
+ display: 'flex' as const,
173
+ flexDirection: 'row' as const,
174
+ justifyContent: 'space-between' as const,
175
+ alignItems: 'center' as const,
176
+ gap: 4,
177
+ });
178
+ }
179
+
180
+ function createCharacterCountStyles(theme: Theme) {
181
+ return () => ({
182
+ fontSize: 12,
183
+ color: theme.colors.text.secondary,
184
+ variants: {
185
+ isNearLimit: {
186
+ true: {
187
+ color: theme.intents.warning.primary,
176
188
  },
177
- isAtLimit: {
178
- true: {
179
- color: theme.intents.error.primary,
180
- },
181
- false: {},
189
+ false: {},
190
+ },
191
+ isAtLimit: {
192
+ true: {
193
+ color: theme.intents.error.primary,
182
194
  },
195
+ false: {},
183
196
  },
184
197
  },
198
+ });
199
+ }
200
+
201
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
202
+ export const textAreaStyles = StyleSheet.create((theme: Theme) => {
203
+ // Apply extensions to main visual elements
204
+ const extended = applyExtensions('TextArea', theme, {
205
+ container: createContainerStyles(theme),
206
+ textarea: createTextareaStyles(theme),
207
+ });
208
+
209
+ return {
210
+ ...extended,
211
+ // Minor utility styles (not extended)
212
+ label: createLabelStyles(theme)(),
213
+ textareaContainer: createTextareaContainerStyles()(),
214
+ helperText: createHelperTextStyles(theme)(),
215
+ footer: createFooterStyles()(),
216
+ characterCount: createCharacterCountStyles(theme)(),
185
217
  };
186
218
  });
@@ -159,14 +159,14 @@ const Tooltip = forwardRef<View, TooltipProps>(({
159
159
  <Pressable style={{ flex: 1 }} onPress={() => setVisible(false)}>
160
160
  <View
161
161
  style={[
162
- tooltipStyles.tooltip,
162
+ (tooltipStyles.tooltip as any)({}),
163
163
  { position: 'absolute' },
164
164
  getPositionStyle(),
165
165
  ]}
166
166
  pointerEvents="none"
167
167
  >
168
168
  {typeof content === 'string' ? (
169
- <Text style={tooltipStyles.tooltip}>{content}</Text>
169
+ <Text style={(tooltipStyles.tooltip as any)({})}>{content}</Text>
170
170
  ) : (
171
171
  content
172
172
  )}
@@ -1,6 +1,7 @@
1
1
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles, Intent, Size} from '@idealyst/theme';
2
+ import { Theme, StylesheetStyles, Intent, Size } from '@idealyst/theme';
3
3
  import { buildSizeVariants } from '../utils/buildSizeVariants';
4
+ import { applyExtensions } from '../extensions/applyExtension';
4
5
 
5
6
  type TooltipSize = Size;
6
7
  type TooltipIntent = Intent;
@@ -38,19 +39,19 @@ function createTooltipIntentVariants(theme: Theme) {
38
39
  return intents;
39
40
  }
40
41
 
41
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
42
- // transform on native cannot resolve function calls to extract variant structures.
43
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
44
- export const tooltipStyles = StyleSheet.create((theme: Theme) => {
45
- return {
46
- container: {
47
- position: 'relative',
42
+ // Style creators for extension support
43
+ function createContainerStyles() {
44
+ return () => ({
45
+ position: 'relative' as const,
48
46
  _web: {
49
47
  display: 'inline-flex',
50
48
  width: 'fit-content',
51
49
  },
52
- } as const,
53
- tooltip: {
50
+ });
51
+ }
52
+
53
+ function createTooltipStyles(theme: Theme) {
54
+ return () => ({
54
55
  borderRadius: 8,
55
56
  maxWidth: 300,
56
57
  shadowColor: '#000',
@@ -68,6 +69,14 @@ export const tooltipStyles = StyleSheet.create((theme: Theme) => {
68
69
  width: 'max-content',
69
70
  wordWrap: 'break-word',
70
71
  },
71
- } as const,
72
- } as const;
72
+ });
73
+ }
74
+
75
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
76
+ // transform on native cannot resolve function calls to extract variant structures.
77
+ export const tooltipStyles = StyleSheet.create((theme: Theme) => {
78
+ return applyExtensions('Tooltip', theme, {
79
+ container: createContainerStyles(),
80
+ tooltip: createTooltipStyles(theme),
81
+ });
73
82
  });
@@ -47,8 +47,8 @@ const Tooltip: React.FC<TooltipProps> = ({
47
47
  intent,
48
48
  });
49
49
 
50
- const containerProps = getWebProps([tooltipStyles.container, style as any]);
51
- const tooltipContentProps = getWebProps(tooltipStyles.tooltip);
50
+ const containerProps = getWebProps([(tooltipStyles.container as any)({}), style as any]);
51
+ const tooltipContentProps = getWebProps([(tooltipStyles.tooltip as any)({})]);
52
52
 
53
53
  const handleMouseEnter = () => {
54
54
  if (timeoutRef.current) {
@@ -1,5 +1,6 @@
1
1
  import { StyleSheet } from 'react-native-unistyles';
2
2
  import { Theme, StylesheetStyles} from '@idealyst/theme';
3
+ import { applyExtensions } from '../extensions/applyExtension';
3
4
 
4
5
  export type ExpandedVideoStyles = StylesheetStyles<never>;
5
6
 
@@ -9,31 +10,46 @@ export type VideoStylesheet = {
9
10
  fallback: ExpandedVideoStyles;
10
11
  }
11
12
 
13
+ // Style creators for extension support
14
+ function createContainerStyles(theme: Theme) {
15
+ return () => ({
16
+ position: 'relative' as const,
17
+ overflow: 'hidden' as const,
18
+ backgroundColor: theme.colors['black'],
19
+ });
20
+ }
21
+
22
+ function createVideoStyles() {
23
+ return () => ({
24
+ width: '100%' as const,
25
+ height: '100%' as const,
26
+ });
27
+ }
28
+
12
29
  // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
13
30
  // transform on native cannot resolve function calls to extract variant structures.
14
31
  // @ts-ignore - TS language server needs restart to pick up theme structure changes
15
32
  export const videoStyles = StyleSheet.create((theme: Theme) => {
16
- return {
17
- container: {
18
- position: 'relative',
19
- overflow: 'hidden',
20
- backgroundColor: theme.colors['black'],
21
- },
22
- video: {
23
- width: '100%',
24
- height: '100%',
25
- },
26
- fallback: {
27
- position: 'absolute',
28
- top: 0,
29
- left: 0,
30
- right: 0,
31
- bottom: 0,
32
- display: 'flex',
33
- alignItems: 'center',
34
- justifyContent: 'center',
35
- backgroundColor: theme.colors['gray.300'],
36
- color: theme.colors['gray.600'],
37
- },
38
- };
33
+ // Apply extensions to main visual elements
34
+ const extended = applyExtensions('Video', theme, {
35
+ container: createContainerStyles(theme),
36
+ video: createVideoStyles(),
37
+ });
38
+
39
+ return {
40
+ ...extended,
41
+ // Minor utility styles (not extended)
42
+ fallback: {
43
+ position: 'absolute',
44
+ top: 0,
45
+ left: 0,
46
+ right: 0,
47
+ bottom: 0,
48
+ display: 'flex',
49
+ alignItems: 'center',
50
+ justifyContent: 'center',
51
+ backgroundColor: theme.colors['gray.300'],
52
+ color: theme.colors['gray.600'],
53
+ },
54
+ };
39
55
  });
@@ -50,12 +50,14 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
50
50
  return baseStyles;
51
51
  };
52
52
 
53
+ const viewStyle = (viewStyles.view as any)({});
54
+
53
55
  if (scrollable) {
54
56
  return (
55
57
  <RNScrollView
56
58
  ref={ref as any}
57
59
  style={[{ flex: 1 }, style]}
58
- contentContainerStyle={[viewStyles.view, getStyles()]}
60
+ contentContainerStyle={[viewStyle, getStyles()]}
59
61
  testID={testID}
60
62
  nativeID={id}
61
63
  >
@@ -65,7 +67,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
65
67
  }
66
68
 
67
69
  return (
68
- <RNView ref={ref as any} style={[viewStyles.view, getStyles(), style]} testID={testID} nativeID={id}>
70
+ <RNView ref={ref as any} style={[viewStyle, getStyles(), style]} testID={testID} nativeID={id}>
69
71
  {children}
70
72
  </RNView>
71
73
  );
@@ -11,6 +11,7 @@ import {
11
11
  } from '../utils/buildViewStyleVariants';
12
12
  import { ViewBackgroundVariant, ViewBorderVariant, ViewRadiusVariant } from './types';
13
13
  import { ViewStyleSize } from '../utils/viewStyleProps';
14
+ import { applyExtensions } from '../extensions/applyExtension';
14
15
 
15
16
  type ViewVariants = {
16
17
  background: ViewBackgroundVariant;
@@ -86,29 +87,39 @@ function createBorderVariants(theme: Theme) {
86
87
  } as const;
87
88
  }
88
89
 
90
+ // Style creators for extension support
91
+ function createViewStyles(theme: Theme) {
92
+ return () => ({
93
+ display: 'flex' as const,
94
+ variants: {
95
+ background: createBackgroundVariants(theme),
96
+ radius: createRadiusVariants(),
97
+ border: createBorderVariants(theme),
98
+ gap: buildGapVariants(theme),
99
+ padding: buildPaddingVariants(theme),
100
+ paddingVertical: buildPaddingVerticalVariants(theme),
101
+ paddingHorizontal: buildPaddingHorizontalVariants(theme),
102
+ margin: buildMarginVariants(theme),
103
+ marginVertical: buildMarginVerticalVariants(theme),
104
+ marginHorizontal: buildMarginHorizontalVariants(theme),
105
+ },
106
+ _web: {
107
+ display: 'flex',
108
+ flexDirection: 'column',
109
+ boxSizing: 'border-box',
110
+ },
111
+ });
112
+ }
113
+
89
114
  // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
90
115
  // transform on native cannot resolve function calls to extract variant structures.
91
116
  export const viewStyles = StyleSheet.create((theme: Theme) => {
92
- return {
93
- view: {
94
- display: 'flex',
95
- variants: {
96
- background: createBackgroundVariants(theme),
97
- radius: createRadiusVariants(),
98
- border: createBorderVariants(theme),
99
- gap: buildGapVariants(theme),
100
- padding: buildPaddingVariants(theme),
101
- paddingVertical: buildPaddingVerticalVariants(theme),
102
- paddingHorizontal: buildPaddingHorizontalVariants(theme),
103
- margin: buildMarginVariants(theme),
104
- marginVertical: buildMarginVerticalVariants(theme),
105
- marginHorizontal: buildMarginHorizontalVariants(theme),
106
- },
107
- _web: {
108
- display: 'flex',
109
- flexDirection: 'column',
110
- boxSizing: 'border-box',
111
- },
112
- },
113
- };
117
+ // Apply extensions to main visual elements
118
+ const extended = applyExtensions('View', theme, {
119
+ view: createViewStyles(theme),
120
+ });
121
+
122
+ return {
123
+ ...extended,
124
+ };
114
125
  });