@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,15 +1,31 @@
1
+ /**
2
+ * Chip styles using defineStyle with dynamic size/intent/type/selected handling.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, Intent} from '@idealyst/theme';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
7
+
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
10
+
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
3
13
 
4
- type ChipSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
5
14
  type ChipType = 'filled' | 'outlined' | 'soft';
6
- type ChipIntent = Intent;
7
15
 
8
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
9
- // transform on native cannot resolve function calls to extract variant structures.
10
- export const chipStyles = StyleSheet.create((theme: Theme) => {
11
- return {
12
- container: (size: ChipSize, intent: ChipIntent, type: ChipType, selected: boolean, disabled: boolean) => {
16
+ export type ChipDynamicProps = {
17
+ size?: Size;
18
+ intent?: Intent;
19
+ type?: ChipType;
20
+ selected?: boolean;
21
+ disabled?: boolean;
22
+ };
23
+
24
+ /**
25
+ * Chip styles with size/intent/type/selected handling.
26
+ */
27
+ export const chipStyles = defineStyle('Chip', (theme: Theme) => ({
28
+ container: ({ size = 'md', intent = 'primary', type = 'filled', selected = false, disabled = false }: ChipDynamicProps) => {
13
29
  const intentValue = theme.intents[intent];
14
30
  const sizeValue = theme.sizes.chip[size];
15
31
 
@@ -50,13 +66,12 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
50
66
  } as const;
51
67
  },
52
68
 
53
- label: (size: ChipSize, intent: ChipIntent, type: ChipType, selected: boolean) => {
69
+ label: ({ size = 'md', intent = 'primary', type = 'filled', selected = false }: ChipDynamicProps) => {
54
70
  const intentValue = theme.intents[intent];
55
71
  const sizeValue = theme.sizes.chip[size];
56
72
 
57
73
  // Compute color based on type and selected state
58
74
  let color: string;
59
-
60
75
  if (type === 'filled') {
61
76
  color = selected ? intentValue.primary : intentValue.contrast;
62
77
  } else if (type === 'outlined') {
@@ -66,7 +81,7 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
66
81
  }
67
82
 
68
83
  return {
69
- fontFamily: 'inherit',
84
+ fontFamily: 'inherit' as const,
70
85
  fontWeight: '500' as const,
71
86
  fontSize: sizeValue.fontSize as number,
72
87
  lineHeight: sizeValue.lineHeight as number,
@@ -74,18 +89,17 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
74
89
  } as const;
75
90
  },
76
91
 
77
- icon: (size: ChipSize, intent: ChipIntent, type: ChipType, selected: boolean) => {
92
+ icon: ({ size = 'md', intent = 'primary', type = 'filled', selected = false }: ChipDynamicProps) => {
78
93
  const intentValue = theme.intents[intent];
79
94
  const sizeValue = theme.sizes.chip[size];
80
95
 
81
- // Compute color based on type and selected state (same logic as label)
96
+ // Same color logic as label
82
97
  let color: string;
83
-
84
98
  if (type === 'filled') {
85
99
  color = selected ? intentValue.primary : intentValue.contrast;
86
100
  } else if (type === 'outlined') {
87
101
  color = selected ? theme.colors.text.inverse : intentValue.primary;
88
- } else { // soft
102
+ } else {
89
103
  color = selected ? theme.colors.text.inverse : intentValue.dark;
90
104
  }
91
105
 
@@ -99,7 +113,7 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
99
113
  } as const;
100
114
  },
101
115
 
102
- deleteButton: (size: ChipSize) => {
116
+ deleteButton: ({ size = 'md' }: ChipDynamicProps) => {
103
117
  const sizeValue = theme.sizes.chip[size];
104
118
 
105
119
  return {
@@ -114,18 +128,17 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
114
128
  } as const;
115
129
  },
116
130
 
117
- deleteIcon: (size: ChipSize, intent: ChipIntent, type: ChipType, selected: boolean) => {
131
+ deleteIcon: ({ size = 'md', intent = 'primary', type = 'filled', selected = false }: ChipDynamicProps) => {
118
132
  const intentValue = theme.intents[intent];
119
133
  const sizeValue = theme.sizes.chip[size];
120
134
 
121
- // Compute color based on type and selected state (same logic as label/icon)
135
+ // Same color logic as label/icon
122
136
  let color: string;
123
-
124
137
  if (type === 'filled') {
125
138
  color = selected ? intentValue.primary : intentValue.contrast;
126
139
  } else if (type === 'outlined') {
127
140
  color = selected ? theme.colors.text.inverse : intentValue.primary;
128
- } else { // soft
141
+ } else {
129
142
  color = selected ? theme.colors.text.inverse : intentValue.dark;
130
143
  }
131
144
 
@@ -134,5 +147,4 @@ export const chipStyles = StyleSheet.create((theme: Theme) => {
134
147
  color,
135
148
  } as const;
136
149
  },
137
- } as const;
138
- });
150
+ }));
@@ -30,11 +30,11 @@ const Chip = forwardRef<HTMLDivElement, ChipProps>(({
30
30
  const isSelected = selectable ? selected : false;
31
31
 
32
32
  // Compute dynamic styles
33
- const containerProps = getWebProps([chipStyles.container(size, intent, type, isSelected, disabled), style as any]);
34
- const labelProps = getWebProps([chipStyles.label(size, intent, type, isSelected)]);
35
- const iconProps = getWebProps([chipStyles.icon(size, intent, type, isSelected)]);
36
- const deleteButtonProps = getWebProps([chipStyles.deleteButton(size)]);
37
- const deleteIconProps = getWebProps([chipStyles.deleteIcon(size, intent, type, isSelected)]);
33
+ const containerProps = getWebProps([(chipStyles.container as any)({ size, intent, type, selected: isSelected, disabled }), style as any]);
34
+ const labelProps = getWebProps([(chipStyles.label as any)({ size, intent, type, selected: isSelected })]);
35
+ const iconProps = getWebProps([(chipStyles.icon as any)({ size, intent, type, selected: isSelected })]);
36
+ const deleteButtonProps = getWebProps([(chipStyles.deleteButton as any)({ size })]);
37
+ const deleteIconProps = getWebProps([(chipStyles.deleteIcon as any)({ size, intent, type, selected: isSelected })]);
38
38
 
39
39
  const handleClick = () => {
40
40
  if (disabled) return;
@@ -115,6 +115,15 @@ const Dialog = forwardRef<View, DialogProps>(({
115
115
  };
116
116
  });
117
117
 
118
+ // Get dynamic styles - call as functions for theme reactivity
119
+ const backdropStyle = (dialogStyles.backdrop as any)({});
120
+ const containerStyle = (dialogStyles.container as any)({});
121
+ const headerStyle = (dialogStyles.header as any)({});
122
+ const titleStyle = (dialogStyles.title as any)({});
123
+ const closeButtonStyle = (dialogStyles.closeButton as any)({});
124
+ const closeButtonTextStyle = (dialogStyles.closeButtonText as any)({});
125
+ const contentStyle = (dialogStyles.content as any)({});
126
+
118
127
  return (
119
128
  <Modal
120
129
  visible={open}
@@ -125,29 +134,29 @@ const Dialog = forwardRef<View, DialogProps>(({
125
134
  testID={testID}
126
135
  >
127
136
  <TouchableWithoutFeedback onPress={handleBackdropPress}>
128
- <Animated.View style={[dialogStyles.backdrop, backdropAnimatedStyle]}>
137
+ <Animated.View style={[backdropStyle, backdropAnimatedStyle]}>
129
138
  <TouchableWithoutFeedback onPress={(e) => e.stopPropagation()}>
130
- <Animated.View ref={ref as any} style={[dialogStyles.container, style, containerAnimatedStyle]} nativeID={id} {...nativeA11yProps}>
139
+ <Animated.View ref={ref as any} style={[containerStyle, style, containerAnimatedStyle]} nativeID={id} {...nativeA11yProps}>
131
140
  {(title || showCloseButton) && (
132
- <View style={dialogStyles.header}>
141
+ <View style={headerStyle}>
133
142
  {title && (
134
- <Text style={dialogStyles.title}>
143
+ <Text style={titleStyle}>
135
144
  {title}
136
145
  </Text>
137
146
  )}
138
147
  {showCloseButton && (
139
148
  <TouchableOpacity
140
- style={dialogStyles.closeButton}
149
+ style={closeButtonStyle}
141
150
  onPress={handleClosePress}
142
151
  accessibilityLabel="Close dialog"
143
152
  accessibilityRole="button"
144
153
  >
145
- <Text style={dialogStyles.closeButtonText}>×</Text>
154
+ <Text style={closeButtonTextStyle}>×</Text>
146
155
  </TouchableOpacity>
147
156
  )}
148
157
  </View>
149
158
  )}
150
- <View style={dialogStyles.content}>
159
+ <View style={contentStyle}>
151
160
  {children}
152
161
  </View>
153
162
  </Animated.View>
@@ -0,0 +1,202 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, StylesheetStyles } from '@idealyst/theme';
3
+ import { applyExtensions } from '../extensions/applyExtension';
4
+ type DialogSize = 'sm' | 'md' | 'lg' | 'fullscreen';
5
+ type DialogType = 'default' | 'alert' | 'confirmation';
6
+
7
+ type DialogVariants = {
8
+ size: DialogSize;
9
+ type: DialogType;
10
+ }
11
+
12
+ export type ExpandedDialogStyles = StylesheetStyles<keyof DialogVariants>;
13
+
14
+ export type DialogStylesheet = {
15
+ backdrop: ExpandedDialogStyles;
16
+ container: ExpandedDialogStyles;
17
+ header: ExpandedDialogStyles;
18
+ title: ExpandedDialogStyles;
19
+ closeButton: ExpandedDialogStyles;
20
+ closeButtonText: ExpandedDialogStyles;
21
+ content: ExpandedDialogStyles;
22
+ modal: ExpandedDialogStyles;
23
+ }
24
+
25
+ /**
26
+ * Create size variants for container
27
+ */
28
+ function createContainerSizeVariants() {
29
+ return {
30
+ sm: {
31
+ width: '90%',
32
+ maxWidth: 400,
33
+ },
34
+ md: {
35
+ width: '90%',
36
+ maxWidth: 600,
37
+ },
38
+ lg: {
39
+ width: '90%',
40
+ maxWidth: 800,
41
+ },
42
+ fullscreen: {
43
+ width: '100%',
44
+ height: '100%',
45
+ borderRadius: 0,
46
+ maxHeight: '100%',
47
+ },
48
+ } as const;
49
+ }
50
+
51
+ /**
52
+ * Create type variants for container
53
+ */
54
+ function createContainerTypeVariants(theme: Theme) {
55
+ return {
56
+ standard: {},
57
+ alert: {
58
+ borderTopWidth: 4,
59
+ borderTopColor: theme.colors.border.primary,
60
+ },
61
+ confirmation: {
62
+ borderTopWidth: 4,
63
+ borderTopColor: theme.colors.border.primary,
64
+ },
65
+ } as const;
66
+ }
67
+
68
+ // Helper functions to create static styles wrapped in dynamic functions
69
+ function createBackdropStyles() {
70
+ return () => ({
71
+ position: 'absolute' as const,
72
+ top: 0,
73
+ left: 0,
74
+ right: 0,
75
+ bottom: 0,
76
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
77
+ display: 'flex' as const,
78
+ alignItems: 'center' as const,
79
+ justifyContent: 'center' as const,
80
+ zIndex: 1000,
81
+ _web: {
82
+ position: 'fixed',
83
+ transition: 'opacity 150ms ease-out',
84
+ },
85
+ });
86
+ }
87
+
88
+ function createDialogContainerStyles(theme: Theme) {
89
+ return () => ({
90
+ backgroundColor: theme.colors.surface.primary,
91
+ borderRadius: 12,
92
+ shadowColor: '#000',
93
+ shadowOffset: { width: 0, height: 10 },
94
+ shadowOpacity: 0.25,
95
+ shadowRadius: 20,
96
+ elevation: 10,
97
+ maxHeight: '90%',
98
+ variants: {
99
+ size: createContainerSizeVariants(),
100
+ type: createContainerTypeVariants(theme),
101
+ },
102
+ _web: {
103
+ position: 'relative',
104
+ display: 'flex',
105
+ flexDirection: 'column',
106
+ overflow: 'auto',
107
+ boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
108
+ transition: 'opacity 150ms ease-out, transform 150ms ease-out',
109
+ transformOrigin: 'center center',
110
+ },
111
+ });
112
+ }
113
+
114
+ function createHeaderStyles(theme: Theme) {
115
+ return () => ({
116
+ borderBottomWidth: 1,
117
+ borderBottomColor: theme.colors.border.primary,
118
+ display: 'flex' as const,
119
+ flexDirection: 'row' as const,
120
+ alignItems: 'center' as const,
121
+ justifyContent: 'space-between' as const,
122
+ _web: {
123
+ borderBottomStyle: 'solid',
124
+ },
125
+ });
126
+ }
127
+
128
+ function createTitleStyles(theme: Theme) {
129
+ return () => ({
130
+ marginLeft: 24,
131
+ fontSize: 18,
132
+ paddingVertical: 16,
133
+ fontWeight: '600' as const,
134
+ color: theme.colors.text.primary,
135
+ flex: 1,
136
+ _web: {
137
+ paddingVertical: 4,
138
+ },
139
+ });
140
+ }
141
+
142
+ function createCloseButtonStyles(theme: Theme) {
143
+ return () => ({
144
+ width: 32,
145
+ height: 32,
146
+ marginRight: 16,
147
+ borderRadius: 16,
148
+ backgroundColor: 'transparent' as const,
149
+ display: 'flex' as const,
150
+ alignItems: 'center' as const,
151
+ justifyContent: 'center' as const,
152
+ _web: {
153
+ border: 'none',
154
+ cursor: 'pointer',
155
+ _hover: {
156
+ backgroundColor: theme.colors.surface.secondary,
157
+ },
158
+ },
159
+ });
160
+ }
161
+
162
+ function createCloseButtonTextStyles(theme: Theme) {
163
+ return () => ({
164
+ fontSize: 18,
165
+ color: theme.colors.text.secondary,
166
+ fontWeight: '500' as const,
167
+ });
168
+ }
169
+
170
+ function createContentStyles() {
171
+ return () => ({
172
+ padding: 24,
173
+ _web: {
174
+ overflow: 'visible',
175
+ maxHeight: 'none',
176
+ },
177
+ });
178
+ }
179
+
180
+ function createModalStyles() {
181
+ return () => ({
182
+ margin: 0,
183
+ justifyContent: 'center' as const,
184
+ alignItems: 'center' as const,
185
+ });
186
+ }
187
+
188
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
189
+ export const dialogStyles = StyleSheet.create((theme: Theme) => {
190
+ // Apply extensions to main visual elements
191
+
192
+ return applyExtensions('Dialog', theme, {backdrop: createBackdropStyles(),
193
+ container: createDialogContainerStyles(theme),
194
+ header: createHeaderStyles(theme),
195
+ content: createContentStyles(),
196
+ // Additional styles (merged from return)
197
+ // Minor utility styles (not extended)
198
+ title: createTitleStyles(theme)(),
199
+ closeButton: createCloseButtonStyles(theme)(),
200
+ closeButtonText: createCloseButtonTextStyles(theme)(),
201
+ modal: createModalStyles()()});
202
+ });
@@ -1,89 +1,61 @@
1
+ /**
2
+ * Dialog styles using defineStyle with dynamic props.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles} from '@idealyst/theme';
3
- type DialogSize = 'sm' | 'md' | 'lg' | 'fullscreen';
4
- type DialogType = 'default' | 'alert' | 'confirmation';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme } from '@idealyst/theme';
5
7
 
6
- type DialogVariants = {
7
- size: DialogSize;
8
- type: DialogType;
9
- }
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
10
10
 
11
- export type ExpandedDialogStyles = StylesheetStyles<keyof DialogVariants>;
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
12
13
 
13
- export type DialogStylesheet = {
14
- backdrop: ExpandedDialogStyles;
15
- container: ExpandedDialogStyles;
16
- header: ExpandedDialogStyles;
17
- title: ExpandedDialogStyles;
18
- closeButton: ExpandedDialogStyles;
19
- closeButtonText: ExpandedDialogStyles;
20
- content: ExpandedDialogStyles;
21
- modal: ExpandedDialogStyles;
22
- }
14
+ type DialogSize = 'sm' | 'md' | 'lg' | 'fullscreen';
15
+ type DialogType = 'default' | 'alert' | 'confirmation';
23
16
 
24
- /**
25
- * Create size variants for container
26
- */
27
- function createContainerSizeVariants() {
28
- return {
29
- sm: {
30
- width: '90%',
31
- maxWidth: 400,
32
- },
33
- md: {
34
- width: '90%',
35
- maxWidth: 600,
36
- },
37
- lg: {
38
- width: '90%',
39
- maxWidth: 800,
40
- },
41
- fullscreen: {
42
- width: '100%',
43
- height: '100%',
44
- borderRadius: 0,
45
- maxHeight: '100%',
46
- },
47
- } as const;
48
- }
17
+ export type DialogDynamicProps = {
18
+ size?: DialogSize;
19
+ type?: DialogType;
20
+ };
49
21
 
50
22
  /**
51
- * Create type variants for container
23
+ * Dialog styles with size/type handling.
52
24
  */
53
- function createContainerTypeVariants(theme: Theme) {
54
- return {
55
- standard: {},
56
- alert: {
57
- borderTopWidth: 4,
58
- borderTopColor: theme.colors.border.primary,
25
+ export const dialogStyles = defineStyle('Dialog', (theme: Theme) => ({
26
+ backdrop: (_props: DialogDynamicProps) => ({
27
+ position: 'absolute' as const,
28
+ top: 0,
29
+ left: 0,
30
+ right: 0,
31
+ bottom: 0,
32
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
33
+ display: 'flex' as const,
34
+ alignItems: 'center' as const,
35
+ justifyContent: 'center' as const,
36
+ zIndex: 1000,
37
+ _web: {
38
+ position: 'fixed',
39
+ transition: 'opacity 150ms ease-out',
59
40
  },
60
- confirmation: {
41
+ }),
42
+
43
+ container: ({ size = 'md', type = 'default' }: DialogDynamicProps) => {
44
+ // Size dimensions
45
+ const sizeStyles = {
46
+ sm: { width: '90%', maxWidth: 400 },
47
+ md: { width: '90%', maxWidth: 600 },
48
+ lg: { width: '90%', maxWidth: 800 },
49
+ fullscreen: { width: '100%', height: '100%', borderRadius: 0, maxHeight: '100%' },
50
+ }[size];
51
+
52
+ // Type-specific styles
53
+ const typeStyles = type !== 'default' ? {
61
54
  borderTopWidth: 4,
62
55
  borderTopColor: theme.colors.border.primary,
63
- },
64
- } as const;
65
- }
56
+ } : {};
66
57
 
67
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
68
- export const dialogStyles = StyleSheet.create((theme: Theme) => {
69
- return {
70
- backdrop: {
71
- position: 'absolute',
72
- top: 0,
73
- left: 0,
74
- right: 0,
75
- bottom: 0,
76
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
77
- display: 'flex',
78
- alignItems: 'center',
79
- justifyContent: 'center',
80
- zIndex: 1000,
81
- _web: {
82
- position: 'fixed',
83
- transition: 'opacity 150ms ease-out',
84
- },
85
- },
86
- container: {
58
+ return {
87
59
  backgroundColor: theme.colors.surface.primary,
88
60
  borderRadius: 12,
89
61
  shadowColor: '#000',
@@ -92,10 +64,8 @@ export const dialogStyles = StyleSheet.create((theme: Theme) => {
92
64
  shadowRadius: 20,
93
65
  elevation: 10,
94
66
  maxHeight: '90%',
95
- variants: {
96
- size: createContainerSizeVariants(),
97
- type: createContainerTypeVariants(theme),
98
- },
67
+ ...sizeStyles,
68
+ ...typeStyles,
99
69
  _web: {
100
70
  position: 'relative',
101
71
  display: 'flex',
@@ -105,62 +75,68 @@ export const dialogStyles = StyleSheet.create((theme: Theme) => {
105
75
  transition: 'opacity 150ms ease-out, transform 150ms ease-out',
106
76
  transformOrigin: 'center center',
107
77
  },
78
+ } as const;
79
+ },
80
+
81
+ header: (_props: DialogDynamicProps) => ({
82
+ borderBottomWidth: 1,
83
+ borderBottomColor: theme.colors.border.primary,
84
+ display: 'flex' as const,
85
+ flexDirection: 'row' as const,
86
+ alignItems: 'center' as const,
87
+ justifyContent: 'space-between' as const,
88
+ _web: {
89
+ borderBottomStyle: 'solid',
108
90
  },
109
- header: {
110
- borderBottomWidth: 1,
111
- borderBottomColor: theme.colors.border.primary,
112
- display: 'flex',
113
- flexDirection: 'row',
114
- alignItems: 'center',
115
- justifyContent: 'space-between',
116
- _web: {
117
- borderBottomStyle: 'solid',
118
- },
119
- },
120
- title: {
121
- marginLeft: 24,
122
- fontSize: 18,
123
- paddingVertical: 16,
124
- fontWeight: '600',
125
- color: theme.colors.text.primary,
126
- flex: 1,
127
- _web: {
128
- paddingVertical: 4,
129
- },
130
- },
131
- closeButton: {
132
- width: 32,
133
- height: 32,
134
- marginRight: 16,
135
- borderRadius: 16,
136
- backgroundColor: 'transparent',
137
- display: 'flex',
138
- alignItems: 'center',
139
- justifyContent: 'center',
140
- _web: {
141
- border: 'none',
142
- cursor: 'pointer',
143
- _hover: {
144
- backgroundColor: theme.colors.surface.secondary,
145
- },
146
- },
147
- },
148
- closeButtonText: {
149
- fontSize: 18,
150
- color: theme.colors.text.secondary,
151
- fontWeight: '500',
91
+ }),
92
+
93
+ title: (_props: DialogDynamicProps) => ({
94
+ marginLeft: 24,
95
+ fontSize: 18,
96
+ paddingVertical: 16,
97
+ fontWeight: '600' as const,
98
+ color: theme.colors.text.primary,
99
+ flex: 1,
100
+ _web: {
101
+ paddingVertical: 4,
152
102
  },
153
- content: {
154
- padding: 24,
155
- _web: {
156
- overflow: 'visible',
157
- maxHeight: 'none',
103
+ }),
104
+
105
+ closeButton: (_props: DialogDynamicProps) => ({
106
+ width: 32,
107
+ height: 32,
108
+ marginRight: 16,
109
+ borderRadius: 16,
110
+ backgroundColor: 'transparent' as const,
111
+ display: 'flex' as const,
112
+ alignItems: 'center' as const,
113
+ justifyContent: 'center' as const,
114
+ _web: {
115
+ border: 'none',
116
+ cursor: 'pointer',
117
+ _hover: {
118
+ backgroundColor: theme.colors.surface.secondary,
158
119
  },
159
120
  },
160
- modal: {
161
- margin: 0,
162
- justifyContent: 'center',
163
- alignItems: 'center',
121
+ }),
122
+
123
+ closeButtonText: (_props: DialogDynamicProps) => ({
124
+ fontSize: 18,
125
+ color: theme.colors.text.secondary,
126
+ fontWeight: '500' as const,
127
+ }),
128
+
129
+ content: (_props: DialogDynamicProps) => ({
130
+ padding: 24,
131
+ _web: {
132
+ overflow: 'visible',
133
+ maxHeight: 'none',
164
134
  },
165
- };
166
- });
135
+ }),
136
+
137
+ modal: (_props: DialogDynamicProps) => ({
138
+ margin: 0,
139
+ justifyContent: 'center' as const,
140
+ alignItems: 'center' as const,
141
+ }),
142
+ }));