@idealyst/theme 1.2.29 → 1.2.31

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/theme",
3
- "version": "1.2.29",
3
+ "version": "1.2.31",
4
4
  "description": "Theming system for Idealyst Framework",
5
5
  "readme": "README.md",
6
6
  "main": "src/index.ts",
@@ -50,6 +50,12 @@
50
50
  "import": "./src/darkTheme.ts",
51
51
  "require": "./src/darkTheme.ts",
52
52
  "types": "./src/darkTheme.ts"
53
+ },
54
+ "./animation": {
55
+ "native": "./src/animation/index.native.ts",
56
+ "import": "./src/animation/index.ts",
57
+ "require": "./src/animation/index.ts",
58
+ "types": "./src/animation/index.ts"
53
59
  }
54
60
  },
55
61
  "scripts": {
@@ -57,7 +63,7 @@
57
63
  "publish:npm": "npm publish"
58
64
  },
59
65
  "dependencies": {
60
- "@idealyst/tooling": "^1.2.3"
66
+ "@idealyst/tooling": "^1.2.30"
61
67
  },
62
68
  "peerDependencies": {
63
69
  "react-native-unistyles": ">=3.0.0"
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Animation module for @idealyst/theme (Native)
3
+ *
4
+ * This module provides animation tokens and utilities for creating
5
+ * consistent animations across web and native platforms.
6
+ *
7
+ * Native-specific exports include Reanimated-compatible utilities.
8
+ *
9
+ * @example
10
+ * // Import tokens
11
+ * import { durations, easings, presets } from '@idealyst/theme/animation';
12
+ *
13
+ * // Import native utilities
14
+ * import { timingConfig, springConfig, animationConfig } from '@idealyst/theme/animation';
15
+ *
16
+ * // Use with Reanimated
17
+ * import { withTiming, withSpring, Easing } from 'react-native-reanimated';
18
+ *
19
+ * const config = timingConfig('normal', 'easeOut');
20
+ * value.value = withTiming(target, {
21
+ * duration: config.duration,
22
+ * easing: Easing.bezier(...config.easing),
23
+ * });
24
+ */
25
+
26
+ // Export tokens
27
+ export { durations, easings, presets } from './tokens';
28
+ export type { DurationKey, EasingKey, PresetKey } from './tokens';
29
+
30
+ // Export types
31
+ export type {
32
+ Duration,
33
+ Easing,
34
+ BezierEasing,
35
+ SpringConfig,
36
+ CSSEasing,
37
+ AnimationConfig,
38
+ TransitionConfig,
39
+ Keyframes,
40
+ KeyframeAnimationConfig,
41
+ AnimationIterations,
42
+ AnimationDirection,
43
+ AnimationFillMode,
44
+ SpringType,
45
+ TimingAnimationConfig,
46
+ PlatformAnimationOptions,
47
+ GradientAnimation,
48
+ GradientBorderConfig,
49
+ } from './types';
50
+
51
+ // Export native utilities
52
+ export {
53
+ resolveDuration,
54
+ resolveEasingBezier,
55
+ isSpringEasing,
56
+ timingConfig,
57
+ springConfig,
58
+ animationConfig,
59
+ presetConfig,
60
+ delayMs,
61
+ sequenceSteps,
62
+ } from './transitions.native';
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Animation module for @idealyst/theme
3
+ *
4
+ * This module provides animation tokens and utilities for creating
5
+ * consistent animations across web and native platforms.
6
+ *
7
+ * @example
8
+ * // Import tokens
9
+ * import { durations, easings, presets } from '@idealyst/theme/animation';
10
+ *
11
+ * // Import web utilities
12
+ * import { cssTransition, cssPreset, cssKeyframes } from '@idealyst/theme/animation';
13
+ *
14
+ * // Import native utilities (in .native.ts files)
15
+ * import { timingConfig, springConfig } from '@idealyst/theme/animation';
16
+ */
17
+
18
+ // Export tokens
19
+ export { durations, easings, presets } from './tokens';
20
+ export type { DurationKey, EasingKey, PresetKey } from './tokens';
21
+
22
+ // Export types
23
+ export type {
24
+ Duration,
25
+ Easing,
26
+ BezierEasing,
27
+ SpringConfig,
28
+ CSSEasing,
29
+ AnimationConfig,
30
+ TransitionConfig,
31
+ Keyframes,
32
+ KeyframeAnimationConfig,
33
+ AnimationIterations,
34
+ AnimationDirection,
35
+ AnimationFillMode,
36
+ SpringType,
37
+ TimingAnimationConfig,
38
+ PlatformAnimationOptions,
39
+ GradientAnimation,
40
+ GradientBorderConfig,
41
+ } from './types';
42
+
43
+ // Export web utilities
44
+ export {
45
+ resolveDuration,
46
+ resolveEasing,
47
+ cssTransition,
48
+ cssPreset,
49
+ cssKeyframes,
50
+ cssAnimation,
51
+ gradientPropertyCSS,
52
+ injectGradientCSS,
53
+ conicSpinnerStyle,
54
+ pulseGradientStyle,
55
+ } from './transitions';
56
+
57
+ // Export native utilities (these are also exported from index.native.ts)
58
+ // Including here allows type-checking in monorepo without platform resolution
59
+ export {
60
+ resolveEasingBezier,
61
+ isSpringEasing,
62
+ timingConfig,
63
+ springConfig,
64
+ animationConfig,
65
+ presetConfig,
66
+ delayMs,
67
+ sequenceSteps,
68
+ } from './transitions.native';
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Animation tokens for @idealyst/theme
3
+ *
4
+ * These tokens provide consistent animation timing across the framework.
5
+ * Use these instead of hardcoded values for consistency and maintainability.
6
+ */
7
+
8
+ /**
9
+ * Duration tokens in milliseconds
10
+ *
11
+ * @example
12
+ * import { durations } from '@idealyst/theme/animation';
13
+ *
14
+ * // Use in CSS transition
15
+ * transition: `opacity ${durations.normal}ms ease`
16
+ *
17
+ * // Use with Reanimated
18
+ * withTiming(value, { duration: durations.fast })
19
+ */
20
+ export const durations = {
21
+ /** 0ms - No animation, instant change */
22
+ instant: 0,
23
+ /** 100ms - Micro-interactions: hover, focus, press feedback */
24
+ fast: 100,
25
+ /** 200ms - Standard state transitions: toggle, selection changes */
26
+ normal: 200,
27
+ /** 300ms - Complex transitions: expand/collapse, progress bars */
28
+ slow: 300,
29
+ /** 500ms - Entrance animations: modals, toasts appearing */
30
+ slower: 500,
31
+ /** 750ms - Extended animations: skeleton pulse, loading states */
32
+ slowest: 750,
33
+ /** 1000ms - Loop animations: spinners, continuous indicators */
34
+ loop: 1000,
35
+ } as const;
36
+
37
+ /**
38
+ * Easing tokens with both CSS string and bezier values
39
+ *
40
+ * CSS easings include both a CSS string for web transitions
41
+ * and bezier curve values for Reanimated's Easing.bezier()
42
+ *
43
+ * Spring easings are native-only and include damping/stiffness/mass
44
+ *
45
+ * @example
46
+ * import { easings } from '@idealyst/theme/animation';
47
+ *
48
+ * // Web: use CSS string
49
+ * transition: `opacity 200ms ${easings.easeOut.css}`
50
+ *
51
+ * // Native: use bezier values
52
+ * Easing.bezier(...easings.easeOut.bezier)
53
+ *
54
+ * // Native spring
55
+ * withSpring(value, easings.spring)
56
+ */
57
+ export const easings = {
58
+ // Standard CSS easings
59
+ /** Linear - constant speed, no acceleration */
60
+ linear: { css: 'linear', bezier: [0, 0, 1, 1] as const },
61
+ /** Ease - slight acceleration at start, deceleration at end */
62
+ ease: { css: 'ease', bezier: [0.25, 0.1, 0.25, 1] as const },
63
+ /** Ease-in - starts slow, accelerates */
64
+ easeIn: { css: 'ease-in', bezier: [0.42, 0, 1, 1] as const },
65
+ /** Ease-out - starts fast, decelerates (most common for UI) */
66
+ easeOut: { css: 'ease-out', bezier: [0, 0, 0.58, 1] as const },
67
+ /** Ease-in-out - symmetric acceleration and deceleration */
68
+ easeInOut: { css: 'ease-in-out', bezier: [0.42, 0, 0.58, 1] as const },
69
+
70
+ // Material Design easings
71
+ /** Standard - Material Design standard easing, balanced feel */
72
+ standard: { css: 'cubic-bezier(0.4, 0, 0.2, 1)', bezier: [0.4, 0, 0.2, 1] as const },
73
+ /** Decelerate - Material Design deceleration, for entering elements */
74
+ decelerate: { css: 'cubic-bezier(0, 0, 0.2, 1)', bezier: [0, 0, 0.2, 1] as const },
75
+ /** Accelerate - Material Design acceleration, for exiting elements */
76
+ accelerate: { css: 'cubic-bezier(0.4, 0, 1, 1)', bezier: [0.4, 0, 1, 1] as const },
77
+
78
+ // Spring configurations (native only - used with withSpring)
79
+ /** Spring - balanced spring, good for toggles and state changes */
80
+ spring: { damping: 15, stiffness: 200, mass: 1 } as const,
81
+ /** Spring stiff - less bounce, snappier feel, good for switches */
82
+ springStiff: { damping: 40, stiffness: 200, mass: 1 } as const,
83
+ /** Spring bouncy - more bounce, playful feel, good for buttons */
84
+ springBouncy: { damping: 10, stiffness: 180, mass: 1 } as const,
85
+ } as const;
86
+
87
+ /**
88
+ * Animation presets for common use cases
89
+ *
90
+ * These combine duration and easing for specific interaction patterns.
91
+ *
92
+ * @example
93
+ * import { presets } from '@idealyst/theme/animation';
94
+ *
95
+ * // Use for hover effects
96
+ * _web: { transition: cssPreset(presets.hover) }
97
+ */
98
+ export const presets = {
99
+ // Micro-interactions
100
+ /** Hover effect - fast, subtle */
101
+ hover: { duration: 'fast' as const, easing: 'ease' as const },
102
+ /** Press/active feedback - fast, ease-out */
103
+ press: { duration: 'fast' as const, easing: 'easeOut' as const },
104
+ /** Focus ring - normal speed */
105
+ focus: { duration: 'normal' as const, easing: 'ease' as const },
106
+
107
+ // State changes
108
+ /** Toggle/switch - normal with spring on native */
109
+ toggle: { duration: 'normal' as const, easing: 'spring' as const },
110
+ /** Selection change - normal, standard easing */
111
+ select: { duration: 'normal' as const, easing: 'standard' as const },
112
+
113
+ // Expand/collapse
114
+ /** Expand content - slow, standard easing */
115
+ expand: { duration: 'slow' as const, easing: 'standard' as const },
116
+ /** Collapse content - slightly faster than expand */
117
+ collapse: { duration: 'normal' as const, easing: 'accelerate' as const },
118
+
119
+ // Entrance/exit
120
+ /** Fade in - normal, decelerate */
121
+ fadeIn: { duration: 'normal' as const, easing: 'decelerate' as const },
122
+ /** Fade out - fast, accelerate */
123
+ fadeOut: { duration: 'fast' as const, easing: 'accelerate' as const },
124
+ /** Scale in (modal, dialog) - slower, decelerate */
125
+ scaleIn: { duration: 'slower' as const, easing: 'decelerate' as const },
126
+ /** Scale out - normal, accelerate */
127
+ scaleOut: { duration: 'normal' as const, easing: 'accelerate' as const },
128
+ /** Slide in - slow, standard */
129
+ slideIn: { duration: 'slow' as const, easing: 'standard' as const },
130
+ /** Slide out - normal, accelerate */
131
+ slideOut: { duration: 'normal' as const, easing: 'accelerate' as const },
132
+
133
+ // Loading/continuous
134
+ /** Spinner rotation - 1s linear loop */
135
+ spin: { duration: 'loop' as const, easing: 'linear' as const, iterations: 'infinite' as const },
136
+ /** Pulse effect - slowest, ease-in-out loop */
137
+ pulse: { duration: 'slowest' as const, easing: 'easeInOut' as const, iterations: 'infinite' as const },
138
+ /** Skeleton wave - slower than pulse */
139
+ wave: { duration: 1500 as const, easing: 'easeInOut' as const, iterations: 'infinite' as const },
140
+ } as const;
141
+
142
+ // Type exports for convenience
143
+ export type DurationKey = keyof typeof durations;
144
+ export type EasingKey = keyof typeof easings;
145
+ export type PresetKey = keyof typeof presets;
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Native-specific animation utilities
3
+ *
4
+ * These utilities generate Reanimated-compatible configurations
5
+ * from animation tokens for use in React Native animations.
6
+ */
7
+
8
+ import { durations, easings } from './tokens';
9
+ import type { DurationKey, EasingKey, PresetKey } from './tokens';
10
+ import type { Duration, SpringType, BezierEasing } from './types';
11
+
12
+ /**
13
+ * Resolve a duration value to milliseconds
14
+ */
15
+ export function resolveDuration(duration: Duration): number {
16
+ if (typeof duration === 'number') {
17
+ return duration;
18
+ }
19
+ return durations[duration];
20
+ }
21
+
22
+ /**
23
+ * Resolve an easing key to bezier curve values
24
+ * Returns bezier array for use with Easing.bezier()
25
+ *
26
+ * Note: Spring easings return a fallback bezier curve.
27
+ * For actual spring behavior, use springConfig() instead.
28
+ */
29
+ export function resolveEasingBezier(easing: EasingKey): BezierEasing {
30
+ const easingConfig = easings[easing];
31
+ // Spring configs don't have bezier equivalent, fall back to ease-out
32
+ if ('damping' in easingConfig) {
33
+ return easings.easeOut.bezier;
34
+ }
35
+ return easingConfig.bezier;
36
+ }
37
+
38
+ /**
39
+ * Check if an easing is a spring configuration
40
+ */
41
+ export function isSpringEasing(easing: EasingKey): easing is SpringType {
42
+ return easing === 'spring' || easing === 'springStiff' || easing === 'springBouncy';
43
+ }
44
+
45
+ /**
46
+ * Get Reanimated withTiming configuration from tokens
47
+ *
48
+ * Use with Reanimated's withTiming() function.
49
+ * The returned config includes duration and a bezier easing function creator.
50
+ *
51
+ * @param duration - Duration token key or milliseconds
52
+ * @param easing - Easing token key (spring easings fall back to easeOut)
53
+ * @returns Configuration object with duration and easing bezier values
54
+ *
55
+ * @example
56
+ * import { timingConfig } from '@idealyst/theme/animation';
57
+ * import { withTiming, Easing } from 'react-native-reanimated';
58
+ *
59
+ * const config = timingConfig('normal', 'easeOut');
60
+ * // => { duration: 200, easing: [0, 0, 0.58, 1] }
61
+ *
62
+ * // Use with Reanimated
63
+ * animatedValue.value = withTiming(targetValue, {
64
+ * duration: config.duration,
65
+ * easing: Easing.bezier(...config.easing),
66
+ * });
67
+ */
68
+ export function timingConfig(
69
+ duration: Duration = 'normal',
70
+ easing: EasingKey = 'easeOut'
71
+ ): { duration: number; easing: BezierEasing } {
72
+ return {
73
+ duration: resolveDuration(duration),
74
+ easing: resolveEasingBezier(easing),
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Get Reanimated withSpring configuration from tokens
80
+ *
81
+ * Use with Reanimated's withSpring() function.
82
+ *
83
+ * @param type - Spring type: 'spring', 'springStiff', or 'springBouncy'
84
+ * @returns Spring configuration object
85
+ *
86
+ * @example
87
+ * import { springConfig } from '@idealyst/theme/animation';
88
+ * import { withSpring } from 'react-native-reanimated';
89
+ *
90
+ * const config = springConfig('springStiff');
91
+ * // => { damping: 40, stiffness: 200, mass: 1 }
92
+ *
93
+ * // Use with Reanimated
94
+ * animatedValue.value = withSpring(targetValue, config);
95
+ */
96
+ export function springConfig(
97
+ type: SpringType = 'spring'
98
+ ): { damping: number; stiffness: number; mass: number } {
99
+ const config = easings[type];
100
+ return {
101
+ damping: config.damping,
102
+ stiffness: config.stiffness,
103
+ mass: config.mass,
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Get animation configuration based on easing type
109
+ *
110
+ * Automatically returns spring config for spring easings,
111
+ * or timing config for bezier easings.
112
+ *
113
+ * @param duration - Duration token key or milliseconds
114
+ * @param easing - Easing token key
115
+ * @returns Either spring config or timing config
116
+ *
117
+ * @example
118
+ * import { animationConfig } from '@idealyst/theme/animation';
119
+ *
120
+ * // Returns spring config
121
+ * animationConfig('normal', 'spring')
122
+ * // => { type: 'spring', config: { damping: 15, stiffness: 200, mass: 1 } }
123
+ *
124
+ * // Returns timing config
125
+ * animationConfig('normal', 'easeOut')
126
+ * // => { type: 'timing', config: { duration: 200, easing: [0, 0, 0.58, 1] } }
127
+ */
128
+ export function animationConfig(
129
+ duration: Duration = 'normal',
130
+ easing: EasingKey = 'easeOut'
131
+ ):
132
+ | { type: 'spring'; config: ReturnType<typeof springConfig> }
133
+ | { type: 'timing'; config: ReturnType<typeof timingConfig> } {
134
+ if (isSpringEasing(easing)) {
135
+ return {
136
+ type: 'spring',
137
+ config: springConfig(easing),
138
+ };
139
+ }
140
+ return {
141
+ type: 'timing',
142
+ config: timingConfig(duration, easing),
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Get preset animation configuration for native
148
+ *
149
+ * @param presetName - Preset key
150
+ * @returns Animation configuration for the preset
151
+ */
152
+ export function presetConfig(presetName: keyof typeof import('./tokens').presets) {
153
+ const { presets } = require('./tokens');
154
+ const preset = presets[presetName];
155
+ return animationConfig(preset.duration, preset.easing);
156
+ }
157
+
158
+ /**
159
+ * Helper to create a delay configuration
160
+ *
161
+ * Use with Reanimated's withDelay() function.
162
+ *
163
+ * @param delay - Delay in milliseconds or duration token
164
+ * @returns Delay in milliseconds
165
+ *
166
+ * @example
167
+ * import { delayMs } from '@idealyst/theme/animation';
168
+ * import { withDelay, withTiming } from 'react-native-reanimated';
169
+ *
170
+ * // Using duration token
171
+ * animatedValue.value = withDelay(
172
+ * delayMs('normal'),
173
+ * withTiming(targetValue, timingConfig('fast', 'easeOut'))
174
+ * );
175
+ */
176
+ export function delayMs(delay: Duration): number {
177
+ return resolveDuration(delay);
178
+ }
179
+
180
+ /**
181
+ * Create a sequence of timing animations
182
+ *
183
+ * Helper for creating withSequence() compatible values.
184
+ *
185
+ * @param steps - Array of { value, duration?, easing? } objects
186
+ * @returns Array of animation configurations
187
+ *
188
+ * @example
189
+ * import { sequenceSteps } from '@idealyst/theme/animation';
190
+ *
191
+ * const steps = sequenceSteps([
192
+ * { value: 0 },
193
+ * { value: 1, duration: 'normal', easing: 'easeOut' },
194
+ * { value: 0.5, duration: 'fast' },
195
+ * ]);
196
+ *
197
+ * // Use with Reanimated
198
+ * animatedValue.value = withSequence(
199
+ * ...steps.map(s => withTiming(s.value, {
200
+ * duration: s.config.duration,
201
+ * easing: Easing.bezier(...s.config.easing)
202
+ * }))
203
+ * );
204
+ */
205
+ export function sequenceSteps(
206
+ steps: Array<{
207
+ value: number;
208
+ duration?: Duration;
209
+ easing?: EasingKey;
210
+ }>
211
+ ): Array<{
212
+ value: number;
213
+ config: ReturnType<typeof timingConfig>;
214
+ }> {
215
+ return steps.map((step) => ({
216
+ value: step.value,
217
+ config: timingConfig(step.duration ?? 'normal', step.easing ?? 'easeOut'),
218
+ }));
219
+ }