@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.
Files changed (50) hide show
  1. package/package.json +3 -3
  2. package/src/Accordion/Accordion.web.tsx +1 -1
  3. package/src/Alert/Alert.native.tsx +1 -1
  4. package/src/Alert/Alert.web.tsx +1 -1
  5. package/src/Badge/Badge.web.tsx +6 -2
  6. package/src/Badge/types.ts +5 -0
  7. package/src/Button/Button.native.tsx +3 -3
  8. package/src/Button/Button.web.tsx +5 -1
  9. package/src/Button/types.ts +5 -0
  10. package/src/Card/Card.web.tsx +4 -1
  11. package/src/Card/types.ts +5 -0
  12. package/src/Dialog/Dialog.native.tsx +1 -1
  13. package/src/Divider/Divider.web.tsx +2 -2
  14. package/src/Icon/Icon.web.tsx +2 -2
  15. package/src/Image/Image.styles.tsx +5 -5
  16. package/src/Image/Image.web.tsx +3 -3
  17. package/src/List/List.native.tsx +1 -2
  18. package/src/List/List.web.tsx +1 -2
  19. package/src/List/ListSection.web.tsx +3 -3
  20. package/src/Menu/Menu.web.tsx +8 -10
  21. package/src/Menu/MenuItem.web.tsx +1 -1
  22. package/src/Popover/Popover.web.tsx +1 -1
  23. package/src/Pressable/Pressable.web.tsx +1 -1
  24. package/src/Progress/Progress.styles.tsx +76 -30
  25. package/src/Progress/Progress.web.tsx +13 -15
  26. package/src/SVGImage/SVGImage.web.tsx +1 -1
  27. package/src/Select/Select.web.tsx +2 -2
  28. package/src/Slider/Slider.styles.tsx +131 -44
  29. package/src/Slider/Slider.web.tsx +22 -22
  30. package/src/Text/Text.web.tsx +29 -3
  31. package/src/Text/types.ts +14 -1
  32. package/src/TextArea/TextArea.styles.tsx +96 -57
  33. package/src/TextArea/TextArea.web.tsx +19 -28
  34. package/src/Tooltip/Tooltip.web.tsx +3 -3
  35. package/src/Video/Video.styles.tsx +3 -3
  36. package/src/Video/Video.web.tsx +1 -1
  37. package/src/View/View.styles.tsx +2 -2
  38. package/src/View/View.web.tsx +95 -9
  39. package/src/View/types.ts +5 -1
  40. package/src/examples/ViewExamples.tsx +34 -0
  41. package/src/extensions/index.ts +0 -7
  42. package/src/hooks/useMergeRefs.ts +12 -6
  43. package/src/utils/accessibility/keyboardPatterns.ts +4 -0
  44. package/src/utils/accessibility/types.ts +5 -1
  45. package/src/utils/accessibility/useAnnounce.ts +1 -1
  46. package/src/utils/accessibility/useKeyboardNavigation.ts +1 -1
  47. package/src/utils/index.ts +0 -3
  48. package/src/utils/viewStyleProps.ts +2 -0
  49. package/src/extensions/applyExtension.ts +0 -210
  50. 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
- }