@idealyst/components 1.2.14 → 1.2.16
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.
- package/package.json +3 -3
- package/src/Accordion/Accordion.web.tsx +1 -1
- package/src/Alert/Alert.native.tsx +1 -1
- package/src/Alert/Alert.web.tsx +1 -1
- package/src/Badge/Badge.web.tsx +6 -2
- package/src/Badge/types.ts +5 -0
- package/src/Button/Button.native.tsx +3 -3
- package/src/Button/Button.web.tsx +5 -1
- package/src/Button/types.ts +5 -0
- package/src/Card/Card.web.tsx +4 -1
- package/src/Card/types.ts +5 -0
- package/src/Dialog/Dialog.native.tsx +1 -1
- package/src/Divider/Divider.web.tsx +2 -2
- package/src/Icon/Icon.web.tsx +2 -2
- package/src/Image/Image.styles.tsx +5 -5
- package/src/Image/Image.web.tsx +3 -3
- package/src/List/List.native.tsx +1 -2
- package/src/List/List.web.tsx +1 -2
- package/src/List/ListSection.web.tsx +3 -3
- package/src/Menu/Menu.web.tsx +8 -10
- package/src/Menu/MenuItem.web.tsx +1 -1
- package/src/Popover/Popover.web.tsx +1 -1
- package/src/Pressable/Pressable.web.tsx +1 -1
- package/src/Progress/Progress.styles.tsx +76 -30
- package/src/Progress/Progress.web.tsx +13 -15
- package/src/SVGImage/SVGImage.web.tsx +1 -1
- package/src/Select/Select.web.tsx +2 -2
- package/src/Slider/Slider.styles.tsx +131 -44
- package/src/Slider/Slider.web.tsx +22 -22
- package/src/Text/Text.web.tsx +29 -3
- package/src/Text/types.ts +14 -1
- package/src/TextArea/TextArea.styles.tsx +96 -57
- package/src/TextArea/TextArea.web.tsx +19 -28
- package/src/Tooltip/Tooltip.web.tsx +3 -3
- package/src/Video/Video.styles.tsx +3 -3
- package/src/Video/Video.web.tsx +1 -1
- package/src/View/View.styles.tsx +2 -2
- package/src/View/View.web.tsx +95 -9
- package/src/View/types.ts +5 -1
- package/src/examples/ViewExamples.tsx +34 -0
- package/src/extensions/index.ts +0 -7
- package/src/hooks/useMergeRefs.ts +12 -6
- package/src/utils/accessibility/keyboardPatterns.ts +4 -0
- package/src/utils/accessibility/types.ts +5 -1
- package/src/utils/accessibility/useAnnounce.ts +1 -1
- package/src/utils/accessibility/useKeyboardNavigation.ts +1 -1
- package/src/utils/index.ts +0 -3
- package/src/utils/viewStyleProps.ts +2 -0
- package/src/extensions/applyExtension.ts +0 -210
- package/src/utils/buildSizeVariants.ts +0 -16
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import { deepMerge } from '../utils/deepMerge';
|
|
2
|
-
import { Styles, ElementStyle, ComponentName } from './types';
|
|
3
|
-
import { getExtension, getReplacement } from './extendComponent';
|
|
4
|
-
import { Theme } from '@idealyst/theme';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Wrap a dynamic style function to merge with extension styles.
|
|
8
|
-
*
|
|
9
|
-
* All styles in Unistyles must be dynamic functions (not static objects)
|
|
10
|
-
* to avoid Babel transform issues. This utility wraps a style function
|
|
11
|
-
* to automatically merge extension styles when the function is called.
|
|
12
|
-
*
|
|
13
|
-
* @param styleFn - The original dynamic style function
|
|
14
|
-
* @param elementExtension - Extension styles for this element (can be undefined).
|
|
15
|
-
* Can be either a static styles object or a function (props) => styles
|
|
16
|
-
* for prop-aware extensions.
|
|
17
|
-
* @returns A new function that returns merged styles
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* import { withExtension } from '../extensions/applyExtension';
|
|
22
|
-
* import { getExtension } from '../extensions/extendComponent';
|
|
23
|
-
*
|
|
24
|
-
* export const buttonStyles = StyleSheet.create((theme: Theme) => {
|
|
25
|
-
* const ext = getExtension('Button', theme);
|
|
26
|
-
*
|
|
27
|
-
* return {
|
|
28
|
-
* button: withExtension(createButtonStyles(theme), ext?.button),
|
|
29
|
-
* text: withExtension(createTextStyles(theme), ext?.text),
|
|
30
|
-
* };
|
|
31
|
-
* });
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @remarks
|
|
35
|
-
* - If no extension is provided, returns the original function unchanged
|
|
36
|
-
* - Extension styles take priority over base styles (deep merged)
|
|
37
|
-
* - Works with any style function signature
|
|
38
|
-
* - If extension is a function, it receives the same props as the base style function
|
|
39
|
-
*/
|
|
40
|
-
export function withExtension<TProps, TResult extends Styles>(
|
|
41
|
-
styleFn: (props: TProps) => TResult,
|
|
42
|
-
elementExtension: Styles | ((props: TProps) => Styles) | undefined
|
|
43
|
-
): (props: TProps) => TResult {
|
|
44
|
-
// If no extension, return original function unchanged
|
|
45
|
-
if (!elementExtension) {
|
|
46
|
-
return styleFn;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Return wrapped function that merges extension
|
|
50
|
-
return (props: TProps): TResult => {
|
|
51
|
-
const baseStyles = styleFn(props);
|
|
52
|
-
// If extension is a function, call it with props; otherwise use as-is
|
|
53
|
-
const extStyles = typeof elementExtension === 'function'
|
|
54
|
-
? elementExtension(props)
|
|
55
|
-
: elementExtension;
|
|
56
|
-
return deepMerge(baseStyles, extStyles) as TResult;
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Wrap a parameterless style function with extension.
|
|
62
|
-
*
|
|
63
|
-
* Use this for style functions that don't take any parameters.
|
|
64
|
-
* This is common for simpler elements like iconContainer.
|
|
65
|
-
*
|
|
66
|
-
* @param styleFn - The original style function (no parameters)
|
|
67
|
-
* @param elementExtension - Extension styles for this element
|
|
68
|
-
* @returns A new function that returns merged styles
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```typescript
|
|
72
|
-
* const createIconContainerStyles = (theme: Theme) => {
|
|
73
|
-
* return () => ({
|
|
74
|
-
* display: 'flex',
|
|
75
|
-
* flexDirection: 'row',
|
|
76
|
-
* gap: 4,
|
|
77
|
-
* });
|
|
78
|
-
* };
|
|
79
|
-
*
|
|
80
|
-
* // In StyleSheet.create:
|
|
81
|
-
* iconContainer: withSimpleExtension(
|
|
82
|
-
* createIconContainerStyles(theme),
|
|
83
|
-
* ext?.iconContainer
|
|
84
|
-
* ),
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
export function withSimpleExtension<TResult extends Styles>(
|
|
88
|
-
styleFn: () => TResult,
|
|
89
|
-
elementExtension: Styles | undefined
|
|
90
|
-
): () => TResult {
|
|
91
|
-
if (!elementExtension) {
|
|
92
|
-
return styleFn;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return (): TResult => {
|
|
96
|
-
const baseStyles = styleFn();
|
|
97
|
-
return deepMerge(baseStyles, elementExtension) as TResult;
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Normalize a style value (from replacement) into a dynamic function.
|
|
103
|
-
*
|
|
104
|
-
* Replacements can be either:
|
|
105
|
-
* - A function (props) => styles - used directly
|
|
106
|
-
* - A static styles object - wrapped in a function
|
|
107
|
-
*
|
|
108
|
-
* @param value - The replacement value (function or static object)
|
|
109
|
-
* @param defaultFn - Default function to use if value is undefined
|
|
110
|
-
* @returns The default function (type-safe) - replacement handling is done at runtime
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```typescript
|
|
114
|
-
* const replacement = getReplacement('Button', theme);
|
|
115
|
-
*
|
|
116
|
-
* // If replacement.button is a function, use it directly
|
|
117
|
-
* // If replacement.button is an object, wrap it in () => replacement.button
|
|
118
|
-
* // If undefined, use createButtonStyles(theme)
|
|
119
|
-
* button: withExtension(
|
|
120
|
-
* normalizeStyleFn(replacement?.button, createButtonStyles(theme)),
|
|
121
|
-
* ext?.button
|
|
122
|
-
* ),
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
export function normalizeStyleFn<TProps, TResult>(
|
|
126
|
-
value: unknown,
|
|
127
|
-
defaultFn: (props: TProps) => TResult
|
|
128
|
-
): (props: TProps) => TResult {
|
|
129
|
-
if (value === undefined || value === null) {
|
|
130
|
-
return defaultFn;
|
|
131
|
-
}
|
|
132
|
-
if (typeof value === 'function') {
|
|
133
|
-
return value as (props: TProps) => TResult;
|
|
134
|
-
}
|
|
135
|
-
// Static object - wrap in a function that ignores props
|
|
136
|
-
return (() => value) as (props: TProps) => TResult;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Normalize a simple style value (no props) into a parameterless function.
|
|
141
|
-
*
|
|
142
|
-
* @param value - The replacement value (function or static object)
|
|
143
|
-
* @param defaultFn - Default function to use if value is undefined
|
|
144
|
-
* @returns A parameterless function that returns styles
|
|
145
|
-
*/
|
|
146
|
-
export function normalizeSimpleStyleFn<TResult>(
|
|
147
|
-
value: unknown,
|
|
148
|
-
defaultFn: () => TResult
|
|
149
|
-
): () => TResult {
|
|
150
|
-
if (value === undefined || value === null) {
|
|
151
|
-
return defaultFn;
|
|
152
|
-
}
|
|
153
|
-
if (typeof value === 'function') {
|
|
154
|
-
return value as () => TResult;
|
|
155
|
-
}
|
|
156
|
-
// Static object - wrap in a function
|
|
157
|
-
return (() => value) as () => TResult;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Apply extensions and replacements to a set of style creators.
|
|
162
|
-
*
|
|
163
|
-
* This is a simplified helper that handles the common pattern of:
|
|
164
|
-
* 1. Getting extensions and replacements for a component
|
|
165
|
-
* 2. Applying normalizeStyleFn for each element
|
|
166
|
-
* 3. Merging extensions on top
|
|
167
|
-
*
|
|
168
|
-
* @param component - The component name
|
|
169
|
-
* @param theme - The current theme
|
|
170
|
-
* @param styleCreators - Object mapping element names to their style creator functions
|
|
171
|
-
* @returns Object with the same keys, but with extensions/replacements applied
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* export const buttonStyles = StyleSheet.create((theme: Theme) => {
|
|
176
|
-
* return applyExtensions('Button', theme, {
|
|
177
|
-
* button: createButtonStyles(theme),
|
|
178
|
-
* text: createTextStyles(theme),
|
|
179
|
-
* icon: createIconStyles(theme),
|
|
180
|
-
* });
|
|
181
|
-
* });
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
export function applyExtensions<
|
|
185
|
-
K extends ComponentName,
|
|
186
|
-
T extends Record<string, ((...args: any[]) => any)>
|
|
187
|
-
>(
|
|
188
|
-
component: K,
|
|
189
|
-
theme: Theme,
|
|
190
|
-
styleCreators: T
|
|
191
|
-
): T {
|
|
192
|
-
const ext = getExtension(component, theme);
|
|
193
|
-
const replacement = getReplacement(component, theme);
|
|
194
|
-
|
|
195
|
-
const result = {} as T;
|
|
196
|
-
|
|
197
|
-
for (const key in styleCreators) {
|
|
198
|
-
const creator = styleCreators[key];
|
|
199
|
-
const elementExt = ext?.[key as string as keyof typeof ext] as ElementStyle | undefined;
|
|
200
|
-
const elementReplacement = replacement?.[key as string as keyof typeof replacement];
|
|
201
|
-
|
|
202
|
-
// Apply replacement (if any) then extension (if any)
|
|
203
|
-
result[key] = withExtension(
|
|
204
|
-
normalizeStyleFn(elementReplacement, creator),
|
|
205
|
-
elementExt
|
|
206
|
-
) as T[typeof key];
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return result;
|
|
210
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { AllComponentSizes, Size, Theme, Styles } from '@idealyst/theme';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Builds a generic size variant. Not really useful on its own tbh, just good to show how it can be used.
|
|
5
|
-
* Context really matters for sizes
|
|
6
|
-
* @param theme
|
|
7
|
-
* @param builder
|
|
8
|
-
* @returns
|
|
9
|
-
*/
|
|
10
|
-
export function buildSizeVariants<T extends keyof AllComponentSizes>(theme: Theme, component: T, builder: (value: AllComponentSizes[T][Size]) => Styles): Record<Size, Styles> {
|
|
11
|
-
const variants = {} as Record<Size, Styles>;
|
|
12
|
-
for (const size in theme.sizes[component]) {
|
|
13
|
-
variants[size as Size] = builder(theme.sizes[component][size as Size]);
|
|
14
|
-
}
|
|
15
|
-
return variants;
|
|
16
|
-
}
|