@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,119 +1,86 @@
1
+ /**
2
+ * MenuItem styles using defineStyle with dynamic props.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme } from '@idealyst/theme';
3
- import { buildSizeVariants } from '../utils/buildSizeVariants';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
4
7
 
5
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
6
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
7
- export const menuItemStyles = StyleSheet.create((theme: Theme) => {
8
- return {
9
- item: {
10
- flexDirection: 'row',
11
- alignItems: 'center',
12
- backgroundColor: 'transparent',
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>;
13
+
14
+ export type MenuItemDynamicProps = {
15
+ size?: Size;
16
+ intent?: Intent;
17
+ disabled?: boolean;
18
+ };
19
+
20
+ /**
21
+ * MenuItem styles with intent/disabled handling.
22
+ */
23
+ export const menuItemStyles = defineStyle('MenuItem', (theme: Theme) => ({
24
+ item: ({ intent = 'neutral', disabled = false }: MenuItemDynamicProps) => {
25
+ const intentValue = theme.intents[intent];
26
+ const hoverStyles = intent !== 'neutral' ? {
27
+ backgroundColor: intentValue.light,
28
+ color: intentValue.primary,
29
+ } : {
30
+ backgroundColor: theme.colors.surface.secondary,
31
+ };
32
+
33
+ return {
34
+ flexDirection: 'row' as const,
35
+ alignItems: 'center' as const,
36
+ backgroundColor: 'transparent' as const,
13
37
  borderRadius: 4,
14
38
  minHeight: 44,
39
+ opacity: disabled ? 0.5 : 1,
40
+ variants: {
41
+ size: {
42
+ paddingVertical: theme.sizes.$menu.paddingVertical,
43
+ paddingHorizontal: theme.sizes.$menu.paddingHorizontal,
44
+ },
45
+ },
15
46
  _web: {
16
- cursor: 'pointer',
47
+ display: 'flex',
48
+ width: '100%',
49
+ cursor: disabled ? 'not-allowed' : 'pointer',
17
50
  border: 'none',
51
+ borderWidth: 0,
18
52
  outline: 'none',
19
53
  transition: 'background-color 0.2s ease',
20
54
  textAlign: 'left',
21
- _hover: {
22
- backgroundColor: theme.colors.surface.secondary,
23
- },
55
+ _hover: disabled ? { backgroundColor: 'transparent' } : hoverStyles,
24
56
  },
25
- variants: {
26
- size: buildSizeVariants(theme, 'menu', (size) => ({
27
- paddingVertical: size.paddingVertical,
28
- paddingHorizontal: size.paddingHorizontal,
29
- })),
30
- disabled: {
31
- true: {
32
- opacity: 0.5,
33
- _web: {
34
- cursor: 'not-allowed',
35
- },
36
- },
37
- false: {},
38
- },
39
- intent: {
40
- primary: {
41
- _web: {
42
- _hover: {
43
- backgroundColor: theme.intents.primary.light,
44
- color: theme.intents.primary.primary,
45
- },
46
- },
47
- },
48
- neutral: {},
49
- success: {
50
- _web: {
51
- _hover: {
52
- backgroundColor: theme.intents.success.light,
53
- color: theme.intents.success.primary,
54
- },
55
- },
56
- },
57
- error: {
58
- _web: {
59
- _hover: {
60
- backgroundColor: theme.intents.error.light,
61
- color: theme.intents.error.primary,
62
- },
63
- },
64
- },
65
- warning: {
66
- _web: {
67
- _hover: {
68
- backgroundColor: theme.intents.warning.light,
69
- color: theme.intents.warning.primary,
70
- },
71
- },
72
- },
73
- info: {
74
- _web: {
75
- _hover: {
76
- backgroundColor: theme.intents.info.light,
77
- color: theme.intents.info.primary,
78
- },
79
- },
80
- },
81
- },
57
+ } as const;
58
+ },
59
+
60
+ icon: (_props: MenuItemDynamicProps) => ({
61
+ alignItems: 'center' as const,
62
+ justifyContent: 'center' as const,
63
+ flexShrink: 0,
64
+ marginRight: 12,
65
+ variants: {
66
+ size: {
67
+ width: theme.sizes.$menu.iconSize,
68
+ height: theme.sizes.$menu.iconSize,
69
+ fontSize: theme.sizes.$menu.iconSize,
82
70
  },
83
- compoundVariants: [
84
- {
85
- disabled: true,
86
- styles: {
87
- _web: {
88
- _hover: {
89
- backgroundColor: 'transparent',
90
- },
91
- },
92
- },
93
- },
94
- ],
95
71
  },
96
- icon: {
97
- alignItems: 'center',
98
- justifyContent: 'center',
99
- flexShrink: 0,
100
- marginRight: 12,
101
- variants: {
102
- size: buildSizeVariants(theme, 'menu', (size) => ({
103
- width: size.iconSize,
104
- height: size.iconSize,
105
- fontSize: size.iconSize,
106
- }))
107
- },
72
+ _web: {
73
+ display: 'flex',
108
74
  },
109
- label: {
110
- flex: 1,
111
- color: theme.colors.text.primary,
112
- variants: {
113
- size: buildSizeVariants(theme, 'menu', (size) => ({
114
- fontSize: size.labelFontSize,
115
- })),
75
+ }),
76
+
77
+ label: (_props: MenuItemDynamicProps) => ({
78
+ flex: 1,
79
+ color: theme.colors.text.primary,
80
+ variants: {
81
+ size: {
82
+ fontSize: theme.sizes.$menu.labelFontSize,
116
83
  },
117
84
  },
118
- };
119
- });
85
+ }),
86
+ }));
@@ -14,16 +14,20 @@ interface MenuItemProps {
14
14
  }
15
15
 
16
16
  const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(({ item, onPress, size = 'md', testID }, ref) => {
17
- // Initialize styles with useVariants
17
+ // Initialize styles with useVariants (for size and disabled)
18
18
  menuItemStyles.useVariants({
19
19
  size,
20
20
  disabled: Boolean(item.disabled),
21
- intent: item.intent || 'neutral',
22
21
  });
23
22
 
24
- const itemProps = getWebProps([menuItemStyles.item]);
25
- const iconProps = getWebProps([menuItemStyles.icon]);
26
- const labelProps = getWebProps([menuItemStyles.label]);
23
+ // Compute dynamic styles - call as functions for theme reactivity
24
+ const itemStyle = (menuItemStyles.item as any)({ intent: item.intent || 'neutral' });
25
+ const iconStyle = (menuItemStyles.icon as any)({});
26
+ const labelStyle = (menuItemStyles.label as any)({});
27
+
28
+ const itemProps = getWebProps([itemStyle]);
29
+ const iconProps = getWebProps([iconStyle]);
30
+ const labelProps = getWebProps([labelStyle]);
27
31
 
28
32
  const renderIcon = () => {
29
33
  if (!item.icon) return null;
@@ -31,9 +35,11 @@ const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(({ item, onPress,
31
35
  if (isIconName(item.icon)) {
32
36
  // Resolve icon name to path and render with IconSvg
33
37
  const iconPath = resolveIconPath(item.icon);
38
+ // IconSvg uses size="1em" by default, sized by container's fontSize from styles
34
39
  return (
35
40
  <IconSvg
36
41
  path={iconPath}
42
+ color="currentColor"
37
43
  aria-label={item.icon}
38
44
  />
39
45
  );
@@ -48,10 +54,22 @@ const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(({ item, onPress,
48
54
  // Merge refs
49
55
  const mergedRef = useMergeRefs(ref, itemProps.ref);
50
56
 
57
+ // Button reset styles that must be applied directly
58
+ const buttonResetStyles: React.CSSProperties = {
59
+ display: 'flex',
60
+ width: '100%',
61
+ border: 'none',
62
+ outline: 'none',
63
+ cursor: item.disabled ? 'not-allowed' : 'pointer',
64
+ background: 'transparent',
65
+ textAlign: 'left',
66
+ };
67
+
51
68
  return (
52
69
  <button
53
70
  {...itemProps}
54
71
  ref={mergedRef}
72
+ style={{ ...buttonResetStyles, ...itemProps.style }}
55
73
  onClick={() => onPress(item)}
56
74
  disabled={item.disabled}
57
75
  role="menuitem"
@@ -43,6 +43,12 @@ const Popover = forwardRef<View, PopoverProps>(({
43
43
  // Apply variants
44
44
  popoverStyles.useVariants({});
45
45
 
46
+ // Get dynamic styles - call as functions for theme reactivity
47
+ const backdropStyle = (popoverStyles.backdrop as any)({});
48
+ const containerStyle = (popoverStyles.container as any)({});
49
+ const arrowStyle = (popoverStyles.arrow as any)({});
50
+ const contentStyle = (popoverStyles.content as any)({});
51
+
46
52
  // Determine if anchor is a ref object
47
53
  const anchorRefToUse = React.useMemo(() => {
48
54
  if (!anchor || typeof anchor !== 'object') return null;
@@ -147,19 +153,19 @@ const Popover = forwardRef<View, PopoverProps>(({
147
153
  nativeID={id}
148
154
  >
149
155
  <TouchableWithoutFeedback onPress={handleBackdropPress}>
150
- <View style={popoverStyles.backdrop}>
156
+ <View style={backdropStyle}>
151
157
  <TouchableWithoutFeedback>
152
158
  <BoundedModalContent
153
159
  top={popoverPosition.top}
154
160
  left={popoverPosition.left}
155
161
  width={Math.min(popoverPosition.width || 200, maxPopoverWidth)}
156
162
  maxHeight={500}
157
- style={[popoverStyles.container, style]}
163
+ style={[containerStyle, style]}
158
164
  onLayout={handlePopoverLayout}
159
165
  {...nativeA11yProps}
160
166
  >
161
- {showArrow && <View style={popoverStyles.arrow} />}
162
- <View style={popoverStyles.content}>
167
+ {showArrow && <View style={arrowStyle} />}
168
+ <View style={contentStyle}>
163
169
  {children}
164
170
  </View>
165
171
  </BoundedModalContent>
@@ -0,0 +1,135 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, StylesheetStyles } from '@idealyst/theme';
3
+ import { applyExtensions } from '../extensions/applyExtension';
4
+
5
+ type PopoverPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
6
+
7
+ type PopoverVariants = {
8
+ placement: PopoverPlacement;
9
+ }
10
+
11
+ export type ExpandedPopoverStyles = StylesheetStyles<keyof PopoverVariants>;
12
+
13
+ export type PopoverStylesheet = {
14
+ container: ExpandedPopoverStyles;
15
+ content: ExpandedPopoverStyles;
16
+ arrow: ExpandedPopoverStyles;
17
+ backdrop: ExpandedPopoverStyles;
18
+ }
19
+
20
+ function createArrowPlacementVariants(theme: Theme) {
21
+ return {
22
+ top: {
23
+ bottom: -6,
24
+ _web: {
25
+ left: '50%',
26
+ marginLeft: -6,
27
+ },
28
+ },
29
+ 'top-start': {
30
+ bottom: -6,
31
+ left: 16,
32
+ },
33
+ 'top-end': {
34
+ bottom: -6,
35
+ right: 16,
36
+ },
37
+ bottom: {
38
+ top: -6,
39
+ _web: {
40
+ left: '50%',
41
+ marginLeft: -6,
42
+ },
43
+ },
44
+ 'bottom-start': {
45
+ top: -6,
46
+ left: 16,
47
+ },
48
+ 'bottom-end': {
49
+ top: -6,
50
+ right: 16,
51
+ },
52
+ left: {
53
+ right: -6,
54
+ _web: {
55
+ top: '50%',
56
+ marginTop: -6,
57
+ },
58
+ },
59
+ 'left-start': {
60
+ right: -6,
61
+ top: 16,
62
+ },
63
+ 'left-end': {
64
+ right: -6,
65
+ bottom: 16,
66
+ },
67
+ right: {
68
+ left: -6,
69
+ _web: {
70
+ top: '50%',
71
+ marginTop: -6,
72
+ },
73
+ },
74
+ 'right-start': {
75
+ left: -6,
76
+ top: 16,
77
+ },
78
+ 'right-end': {
79
+ left: -6,
80
+ bottom: 16,
81
+ },
82
+ };
83
+ }
84
+
85
+ // Style creators for extension support
86
+ function createContainerStyles(theme: Theme) {
87
+ return () => ({
88
+ backgroundColor: theme.colors.surface.primary,
89
+ borderRadius: 8,
90
+ borderWidth: 1,
91
+ borderColor: theme.colors.border.primary,
92
+ borderStyle: 'solid' as const,
93
+ shadowColor: '#000',
94
+ shadowOffset: { width: 0, height: 4 },
95
+ shadowOpacity: 0.1,
96
+ shadowRadius: 12,
97
+ elevation: 8,
98
+ _web: {
99
+ border: `1px solid ${theme.colors.border.primary}`,
100
+ boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
101
+ transition: 'opacity 150ms ease-out, transform 150ms ease-out',
102
+ transformOrigin: 'center center',
103
+ },
104
+ });
105
+ }
106
+
107
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
108
+ // transform on native cannot resolve function calls to extract variant structures.
109
+ export const popoverStyles = StyleSheet.create((theme: Theme) => {
110
+ // Apply extensions to main visual elements
111
+
112
+ return applyExtensions('Popover', theme, {container: createContainerStyles(theme),
113
+ // Additional styles (merged from return)
114
+ // Minor utility styles (not extended)
115
+ content: {
116
+ padding: 16,
117
+ },
118
+ arrow: {
119
+ position: 'absolute',
120
+ width: 12,
121
+ height: 12,
122
+ backgroundColor: theme.colors.surface.primary,
123
+ variants: {
124
+ placement: createArrowPlacementVariants(theme),
125
+ },
126
+ _web: {
127
+ transform: 'rotate(45deg)',
128
+ boxShadow: '-2px 2px 4px rgba(0, 0, 0, 0.1)',
129
+ },
130
+ },
131
+ backdrop: {
132
+ flex: 1,
133
+ backgroundColor: 'transparent',
134
+ }});
135
+ });
@@ -1,97 +1,32 @@
1
+ /**
2
+ * Popover styles using defineStyle.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles} from '@idealyst/theme';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme } from '@idealyst/theme';
3
7
 
4
- type PopoverPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
5
10
 
6
- type PopoverVariants = {
7
- placement: PopoverPlacement;
8
- }
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
9
13
 
10
- export type ExpandedPopoverStyles = StylesheetStyles<keyof PopoverVariants>;
14
+ type PopoverPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
11
15
 
12
- export type PopoverStylesheet = {
13
- container: ExpandedPopoverStyles;
14
- content: ExpandedPopoverStyles;
15
- arrow: ExpandedPopoverStyles;
16
- backdrop: ExpandedPopoverStyles;
17
- }
16
+ export type PopoverDynamicProps = {
17
+ placement?: PopoverPlacement;
18
+ };
18
19
 
19
- function createArrowPlacementVariants(theme: Theme) {
20
- return {
21
- top: {
22
- bottom: -6,
23
- _web: {
24
- left: '50%',
25
- marginLeft: -6,
26
- },
27
- },
28
- 'top-start': {
29
- bottom: -6,
30
- left: 16,
31
- },
32
- 'top-end': {
33
- bottom: -6,
34
- right: 16,
35
- },
36
- bottom: {
37
- top: -6,
38
- _web: {
39
- left: '50%',
40
- marginLeft: -6,
41
- },
42
- },
43
- 'bottom-start': {
44
- top: -6,
45
- left: 16,
46
- },
47
- 'bottom-end': {
48
- top: -6,
49
- right: 16,
50
- },
51
- left: {
52
- right: -6,
53
- _web: {
54
- top: '50%',
55
- marginTop: -6,
56
- },
57
- },
58
- 'left-start': {
59
- right: -6,
60
- top: 16,
61
- },
62
- 'left-end': {
63
- right: -6,
64
- bottom: 16,
65
- },
66
- right: {
67
- left: -6,
68
- _web: {
69
- top: '50%',
70
- marginTop: -6,
71
- },
72
- },
73
- 'right-start': {
74
- left: -6,
75
- top: 16,
76
- },
77
- 'right-end': {
78
- left: -6,
79
- bottom: 16,
80
- },
81
- };
82
- }
83
-
84
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
85
- // transform on native cannot resolve function calls to extract variant structures.
86
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
87
- export const popoverStyles = StyleSheet.create((theme: Theme) => {
88
- return {
89
- container: {
20
+ /**
21
+ * Popover styles with placement variants.
22
+ */
23
+ export const popoverStyles = defineStyle('Popover', (theme: Theme) => ({
24
+ container: (_props: PopoverDynamicProps) => ({
90
25
  backgroundColor: theme.colors.surface.primary,
91
26
  borderRadius: 8,
92
27
  borderWidth: 1,
93
28
  borderColor: theme.colors.border.primary,
94
- borderStyle: 'solid',
29
+ borderStyle: 'solid' as const,
95
30
  shadowColor: '#000',
96
31
  shadowOffset: { width: 0, height: 4 },
97
32
  shadowOpacity: 0.1,
@@ -103,26 +38,41 @@ export const popoverStyles = StyleSheet.create((theme: Theme) => {
103
38
  transition: 'opacity 150ms ease-out, transform 150ms ease-out',
104
39
  transformOrigin: 'center center',
105
40
  },
106
- },
107
- content: {
41
+ }),
42
+
43
+ content: (_props: PopoverDynamicProps) => ({
108
44
  padding: 16,
109
- },
110
- arrow: {
111
- position: 'absolute',
45
+ }),
46
+
47
+ arrow: (_props: PopoverDynamicProps) => ({
48
+ position: 'absolute' as const,
112
49
  width: 12,
113
50
  height: 12,
114
51
  backgroundColor: theme.colors.surface.primary,
115
52
  variants: {
116
- placement: createArrowPlacementVariants(theme),
53
+ placement: {
54
+ top: { bottom: -6, _web: { left: '50%', marginLeft: -6 } },
55
+ 'top-start': { bottom: -6, left: 16 },
56
+ 'top-end': { bottom: -6, right: 16 },
57
+ bottom: { top: -6, _web: { left: '50%', marginLeft: -6 } },
58
+ 'bottom-start': { top: -6, left: 16 },
59
+ 'bottom-end': { top: -6, right: 16 },
60
+ left: { right: -6, _web: { top: '50%', marginTop: -6 } },
61
+ 'left-start': { right: -6, top: 16 },
62
+ 'left-end': { right: -6, bottom: 16 },
63
+ right: { left: -6, _web: { top: '50%', marginTop: -6 } },
64
+ 'right-start': { left: -6, top: 16 },
65
+ 'right-end': { left: -6, bottom: 16 },
66
+ },
117
67
  },
118
68
  _web: {
119
69
  transform: 'rotate(45deg)',
120
70
  boxShadow: '-2px 2px 4px rgba(0, 0, 0, 0.1)',
121
71
  },
122
- },
123
- backdrop: {
72
+ }),
73
+
74
+ backdrop: (_props: PopoverDynamicProps) => ({
124
75
  flex: 1,
125
- backgroundColor: 'transparent',
126
- },
127
- };
128
- });
76
+ backgroundColor: 'transparent' as const,
77
+ }),
78
+ }));
@@ -44,7 +44,7 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(({
44
44
 
45
45
  popoverStyles.useVariants({});
46
46
 
47
- const containerProps = getWebProps([popoverStyles.container]);
47
+ const containerProps = getWebProps([(popoverStyles.container as any)({})]);
48
48
  const contentProps = getWebProps([popoverStyles.content]);
49
49
 
50
50
  const mergedPopoverRef = useMergeRefs(ref, popoverRef);
@@ -26,6 +26,8 @@ const Pressable = forwardRef<View, PressableProps>(({
26
26
  paddingHorizontal,
27
27
  });
28
28
 
29
+ const pressableStyle = (pressableStyles.pressable as any)({});
30
+
29
31
  return (
30
32
  <TouchableWithoutFeedback
31
33
  onPress={disabled ? undefined : onPress}
@@ -35,7 +37,7 @@ const Pressable = forwardRef<View, PressableProps>(({
35
37
  testID={testID}
36
38
  accessibilityLabel={accessibilityLabel}
37
39
  >
38
- <View ref={ref} nativeID={id} style={[pressableStyles.pressable, style]}>
40
+ <View ref={ref} nativeID={id} style={[pressableStyle, style]}>
39
41
  {children}
40
42
  </View>
41
43
  </TouchableWithoutFeedback>
@@ -0,0 +1,27 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme } from '@idealyst/theme';
3
+ import {
4
+ buildPaddingVariants,
5
+ buildPaddingVerticalVariants,
6
+ buildPaddingHorizontalVariants,
7
+ } from '../utils/buildViewStyleVariants';
8
+ import { applyExtensions } from '../extensions/applyExtension';
9
+
10
+ // Style creators for extension support
11
+ function createPressableStyles(theme: Theme) {
12
+ return () => ({
13
+ variants: {
14
+ // Spacing variants from PressableSpacingStyleProps
15
+ padding: buildPaddingVariants(theme),
16
+ paddingVertical: buildPaddingVerticalVariants(theme),
17
+ paddingHorizontal: buildPaddingHorizontalVariants(theme),
18
+ },
19
+ });
20
+ }
21
+
22
+ export const pressableStyles = StyleSheet.create((theme: Theme) => {
23
+ // Apply extensions to main visual elements
24
+ return applyExtensions('Pressable', theme, {
25
+ pressable: createPressableStyles(theme),
26
+ });
27
+ });