@expokit/cli 0.2.0 → 0.4.0
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/README.md +20 -2
- package/bin/expo-kit.js +219 -44
- package/bin/lib.mjs +110 -1
- package/bin/mcp.mjs +48 -19
- package/package.json +9 -4
- package/registry/_docs/accordion.json +16 -0
- package/registry/_docs/action-sheet.json +28 -0
- package/registry/_docs/alert.json +28 -0
- package/registry/_docs/assistant-app.json +47 -0
- package/registry/_docs/avatar.json +25 -1
- package/registry/_docs/badge.json +36 -5
- package/registry/_docs/bottom-nav.json +30 -6
- package/registry/_docs/bottom-sheet.json +28 -0
- package/registry/_docs/bullet.json +3 -0
- package/registry/_docs/button-3d.json +18 -2
- package/registry/_docs/button.json +16 -0
- package/registry/_docs/calendar.json +21 -5
- package/registry/_docs/card-stack.json +16 -0
- package/registry/_docs/card.json +20 -0
- package/registry/_docs/carousel.json +20 -0
- package/registry/_docs/chat.json +184 -0
- package/registry/_docs/checkbox.json +16 -0
- package/registry/_docs/checkout.json +10 -1
- package/registry/_docs/chip-group.json +16 -0
- package/registry/_docs/confetti.json +23 -3
- package/registry/_docs/coupon.json +16 -0
- package/registry/_docs/cube-pager.json +16 -0
- package/registry/_docs/dashboard.json +3 -0
- package/registry/_docs/date-picker.json +24 -4
- package/registry/_docs/dialog.json +24 -0
- package/registry/_docs/donut-shop.json +88 -0
- package/registry/_docs/drawer.json +32 -4
- package/registry/_docs/fab.json +24 -0
- package/registry/_docs/fintech-app.json +49 -0
- package/registry/_docs/flip-card.json +16 -0
- package/registry/_docs/floating-input.json +25 -5
- package/registry/_docs/food-app.json +47 -0
- package/registry/_docs/gift-card.json +16 -0
- package/registry/_docs/glass-button.json +24 -0
- package/registry/_docs/glass-nav-bar.json +24 -0
- package/registry/_docs/glass-search-bar.json +24 -0
- package/registry/_docs/glass-segmented.json +28 -0
- package/registry/_docs/glass-sheet.json +28 -0
- package/registry/_docs/glass-tab-bar.json +24 -0
- package/registry/_docs/glass.json +17 -1
- package/registry/_docs/grain.json +80 -0
- package/registry/_docs/inbox.json +3 -0
- package/registry/_docs/isometric-bar.json +3 -0
- package/registry/_docs/kit.json +3 -0
- package/registry/_docs/liquidglass-tab.json +3 -0
- package/registry/_docs/list-item.json +16 -0
- package/registry/_docs/loyalty-card.json +16 -0
- package/registry/_docs/morphing-button-group.json +96 -0
- package/registry/_docs/number-ticker.json +16 -0
- package/registry/_docs/offers.json +3 -0
- package/registry/_docs/onboarding.json +3 -0
- package/registry/_docs/orb-reveal.json +132 -0
- package/registry/_docs/otp-input.json +28 -4
- package/registry/_docs/parallax-layers.json +20 -0
- package/registry/_docs/parallax-scroll.json +24 -0
- package/registry/_docs/password-input.json +23 -3
- package/registry/_docs/payment-card.json +16 -0
- package/registry/_docs/pixel-bar.json +3 -0
- package/registry/_docs/polar-area.json +3 -0
- package/registry/_docs/profile.json +3 -0
- package/registry/_docs/progress-steps.json +24 -0
- package/registry/_docs/progress.json +20 -0
- package/registry/_docs/qr-code-button.json +122 -0
- package/registry/_docs/radio-group.json +20 -0
- package/registry/_docs/rating.json +24 -0
- package/registry/_docs/ring-carousel.json +20 -0
- package/registry/_docs/scratch-card.json +20 -0
- package/registry/_docs/search-bar.json +23 -3
- package/registry/_docs/search-results.json +3 -0
- package/registry/_docs/segmented-control.json +20 -0
- package/registry/_docs/select.json +33 -8
- package/registry/_docs/settings.json +9 -0
- package/registry/_docs/sign-in.json +3 -0
- package/registry/_docs/skeleton.json +22 -2
- package/registry/_docs/slide-to-confirm.json +24 -0
- package/registry/_docs/slider.json +27 -7
- package/registry/_docs/spin-wheel.json +24 -0
- package/registry/_docs/spinner.json +41 -11
- package/registry/_docs/stateful-button.json +184 -0
- package/registry/_docs/stepper.json +23 -7
- package/registry/_docs/swipe-deck.json +16 -0
- package/registry/_docs/swipeable-row.json +24 -1
- package/registry/_docs/switch.json +20 -0
- package/registry/_docs/tabs.json +24 -0
- package/registry/_docs/text-animation.json +141 -0
- package/registry/_docs/textarea.json +18 -2
- package/registry/_docs/ticket-card.json +20 -0
- package/registry/_docs/ticket-shape.json +4 -1
- package/registry/_docs/tilt-card.json +20 -4
- package/registry/_docs/time-picker.json +22 -6
- package/registry/_docs/timeline-chart.json +3 -0
- package/registry/_docs/timeline.json +18 -2
- package/registry/_docs/toast.json +32 -8
- package/registry/_docs/treemap.json +3 -0
- package/registry/_docs/waterfall.json +3 -0
- package/registry/_docs/wheel-list.json +20 -0
- package/registry/accordion/files/src/components/ui/accordion.tsx +5 -4
- package/registry/accordion/files/src/lib/kit.tsx +8 -5
- package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +9 -8
- package/registry/action-sheet/files/src/lib/kit.tsx +8 -5
- package/registry/alert/files/src/components/ui/alert.tsx +7 -4
- package/registry/alert/files/src/components/ui/button.tsx +4 -3
- package/registry/alert/files/src/lib/kit.tsx +8 -5
- package/registry/assistant-app.json +49 -0
- package/registry/avatar/files/src/components/ui/avatar.tsx +7 -4
- package/registry/avatar/files/src/lib/kit.tsx +8 -5
- package/registry/badge/files/src/components/ui/badge.tsx +345 -21
- package/registry/badge/files/src/lib/kit.tsx +8 -5
- package/registry/badge.json +1 -1
- package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +14 -7
- package/registry/bottom-nav/files/src/lib/kit.tsx +8 -5
- package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +7 -6
- package/registry/bottom-sheet/files/src/lib/kit.tsx +8 -5
- package/registry/button/files/src/components/ui/button.tsx +4 -3
- package/registry/button/files/src/lib/kit.tsx +8 -5
- package/registry/button-3d/files/src/components/ui/button-3d.tsx +3 -2
- package/registry/button-3d/files/src/lib/kit.tsx +8 -5
- package/registry/calendar/files/src/components/ui/calendar.tsx +9 -5
- package/registry/calendar/files/src/lib/kit.tsx +8 -5
- package/registry/card/files/src/components/ui/card.tsx +8 -6
- package/registry/card/files/src/lib/kit.tsx +8 -5
- package/registry/chat.json +18 -0
- package/registry/checkbox/files/src/components/ui/checkbox.tsx +6 -5
- package/registry/checkbox/files/src/lib/kit.tsx +8 -5
- package/registry/chip-group/files/src/components/ui/chip-group.tsx +4 -2
- package/registry/chip-group/files/src/lib/kit.tsx +8 -5
- package/registry/confetti/files/src/lib/kit.tsx +8 -5
- package/registry/coupon/files/src/components/ui/coupon.tsx +23 -20
- package/registry/coupon/files/src/components/ui/flip-card.tsx +1 -1
- package/registry/coupon/files/src/components/ui/tilt-card.tsx +2 -2
- package/registry/coupon/files/src/lib/kit.tsx +8 -5
- package/registry/date-picker/files/src/components/ui/calendar.tsx +9 -5
- package/registry/date-picker/files/src/components/ui/date-picker.tsx +2 -2
- package/registry/date-picker/files/src/lib/kit.tsx +8 -5
- package/registry/dialog/files/src/components/ui/dialog.tsx +12 -6
- package/registry/dialog/files/src/lib/kit.tsx +8 -5
- package/registry/donut-shop.json +18 -0
- package/registry/drawer/files/src/components/ui/drawer.tsx +25 -19
- package/registry/drawer/files/src/lib/kit.tsx +8 -5
- package/registry/fintech-app.json +57 -0
- package/registry/flip-card/files/src/components/ui/flip-card.tsx +1 -1
- package/registry/flip-card/files/src/lib/kit.tsx +8 -5
- package/registry/floating-input/files/src/components/ui/floating-input.tsx +16 -6
- package/registry/floating-input/files/src/lib/kit.tsx +8 -5
- package/registry/food-app.json +55 -0
- package/registry/grain/files/src/components/ui/grain.tsx +113 -0
- package/registry/{tag-input → grain}/files/src/lib/kit.tsx +8 -5
- package/registry/grain.json +17 -0
- package/registry/kit/files/src/lib/kit.tsx +8 -5
- package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +1 -1
- package/registry/liquidglass-tab/files/src/lib/tab-bar.ts +1 -1
- package/registry/list-item/files/src/components/ui/list-item.tsx +20 -16
- package/registry/list-item/files/src/lib/kit.tsx +8 -5
- package/registry/morphing-button-group.json +18 -0
- package/registry/orb-reveal.json +20 -0
- package/registry/otp-input/files/src/components/ui/otp-input.tsx +8 -6
- package/registry/otp-input/files/src/lib/kit.tsx +8 -5
- package/registry/password-input/files/src/components/ui/floating-input.tsx +16 -6
- package/registry/password-input/files/src/components/ui/password-input.tsx +2 -2
- package/registry/password-input/files/src/lib/kit.tsx +8 -5
- package/registry/payment-card/files/src/components/ui/flip-card.tsx +1 -1
- package/registry/payment-card/files/src/components/ui/payment-card.tsx +27 -14
- package/registry/payment-card/files/src/components/ui/tilt-card.tsx +2 -2
- package/registry/payment-card/files/src/lib/kit.tsx +8 -5
- package/registry/progress/files/src/components/ui/progress.tsx +8 -5
- package/registry/progress/files/src/lib/kit.tsx +8 -5
- package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +15 -11
- package/registry/progress-steps/files/src/lib/kit.tsx +8 -5
- package/registry/qr-code-button.json +18 -0
- package/registry/radio-group/files/src/components/ui/radio-group.tsx +10 -9
- package/registry/radio-group/files/src/lib/kit.tsx +8 -5
- package/registry/search-bar/files/src/components/ui/search-bar.tsx +13 -11
- package/registry/search-bar/files/src/lib/kit.tsx +8 -5
- package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +4 -2
- package/registry/segmented-control/files/src/lib/kit.tsx +8 -5
- package/registry/select/files/src/components/ui/select.tsx +3 -3
- package/registry/select/files/src/lib/kit.tsx +8 -5
- package/registry/skeleton/files/src/components/ui/skeleton.tsx +4 -4
- package/registry/skeleton/files/src/lib/kit.tsx +8 -5
- package/registry/slider/files/src/components/ui/slider.tsx +5 -4
- package/registry/slider/files/src/lib/kit.tsx +8 -5
- package/registry/spinner/files/src/components/ui/spinner.tsx +452 -34
- package/registry/spinner/files/src/lib/kit.tsx +8 -5
- package/registry/spinner.json +1 -1
- package/registry/stateful-button/files/src/components/ui/stateful-button.tsx +532 -0
- package/registry/{pagination-dots → stateful-button}/files/src/lib/kit.tsx +8 -5
- package/registry/stateful-button.json +18 -0
- package/registry/stepper/files/src/components/ui/stepper.tsx +8 -4
- package/registry/stepper/files/src/lib/kit.tsx +8 -5
- package/registry/switch/files/src/components/ui/switch.tsx +4 -3
- package/registry/switch/files/src/lib/kit.tsx +8 -5
- package/registry/tabs/files/src/components/ui/tabs.tsx +10 -8
- package/registry/tabs/files/src/lib/kit.tsx +8 -5
- package/registry/text-animation/files/src/components/ui/text-animation.tsx +650 -0
- package/registry/text-animation/files/src/lib/kit.tsx +222 -0
- package/registry/text-animation.json +15 -0
- package/registry/textarea/files/src/components/ui/textarea.tsx +11 -9
- package/registry/textarea/files/src/lib/kit.tsx +8 -5
- package/registry/ticket-shape/files/src/lib/kit.tsx +8 -5
- package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +2 -2
- package/registry/tilt-card/files/src/lib/kit.tsx +8 -5
- package/registry/time-picker/files/src/components/ui/time-picker.tsx +2 -2
- package/registry/time-picker/files/src/lib/kit.tsx +8 -5
- package/registry/timeline/files/src/components/ui/avatar.tsx +7 -4
- package/registry/timeline/files/src/components/ui/timeline.tsx +12 -10
- package/registry/timeline/files/src/lib/kit.tsx +8 -5
- package/registry/toast/files/src/components/ui/button.tsx +4 -3
- package/registry/toast/files/src/components/ui/toast.tsx +13 -11
- package/registry/toast/files/src/lib/kit.tsx +8 -5
- package/schema/components.schema.json +1 -1
- package/registry/_docs/color-swatch.json +0 -66
- package/registry/_docs/kpi-card.json +0 -11
- package/registry/_docs/like-button.json +0 -72
- package/registry/_docs/morph-button.json +0 -108
- package/registry/_docs/pagination-dots.json +0 -88
- package/registry/_docs/shimmer-button.json +0 -78
- package/registry/_docs/tag-input.json +0 -128
- package/registry/color-swatch.json +0 -17
- package/registry/kpi-card/files/src/components/charts/kpi-card.tsx +0 -45
- package/registry/kpi-card.json +0 -14
- package/registry/like-button.json +0 -18
- package/registry/morph-button.json +0 -18
- package/registry/pagination-dots/files/src/components/ui/pagination-dots.tsx +0 -262
- package/registry/pagination-dots.json +0 -15
- package/registry/shimmer-button.json +0 -17
- package/registry/tag-input/files/src/components/ui/tag-input.tsx +0 -720
- package/registry/tag-input.json +0 -17
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
|
+
import { Platform, useColorScheme, type TextStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ExpoKit design tokens. Every component reads them through useKit(), so one
|
|
6
|
+
* <KitProvider> (optional) re-skins the whole kit: light / dark, accent colour, radius.
|
|
7
|
+
* Without a provider, components follow the system colour scheme.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Bumped whenever components start using a new kit API (2: radius.scale / radius.capsule).
|
|
12
|
+
* The CLI won't keep an edited kit.tsx older than the component being added needs.
|
|
13
|
+
*/
|
|
14
|
+
export const KIT_VERSION = 2;
|
|
15
|
+
|
|
16
|
+
export type ColorScheme = 'light' | 'dark';
|
|
17
|
+
|
|
18
|
+
export interface Colors {
|
|
19
|
+
background: string;
|
|
20
|
+
foreground: string;
|
|
21
|
+
/** Cards, sheets, inputs. */
|
|
22
|
+
card: string;
|
|
23
|
+
cardForeground: string;
|
|
24
|
+
/** Raised surfaces: popovers, toasts. */
|
|
25
|
+
popover: string;
|
|
26
|
+
muted: string;
|
|
27
|
+
mutedForeground: string;
|
|
28
|
+
border: string;
|
|
29
|
+
input: string;
|
|
30
|
+
primary: string;
|
|
31
|
+
primaryForeground: string;
|
|
32
|
+
secondary: string;
|
|
33
|
+
secondaryForeground: string;
|
|
34
|
+
accent: string;
|
|
35
|
+
accentForeground: string;
|
|
36
|
+
success: string;
|
|
37
|
+
warning: string;
|
|
38
|
+
danger: string;
|
|
39
|
+
dangerForeground: string;
|
|
40
|
+
ring: string;
|
|
41
|
+
overlay: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Theme {
|
|
45
|
+
dark: boolean;
|
|
46
|
+
colors: Colors;
|
|
47
|
+
/** Corner radius scale. `radius.full` makes pills. */
|
|
48
|
+
radius: {
|
|
49
|
+
sm: number;
|
|
50
|
+
md: number;
|
|
51
|
+
lg: number;
|
|
52
|
+
xl: number;
|
|
53
|
+
full: number;
|
|
54
|
+
/** A corner designed at the default radius (12), scaled to the current one: `radius.scale(16)` is 16 at 12, 0 at 0. */
|
|
55
|
+
scale: (n: number) => number;
|
|
56
|
+
/** Corner for a bar or chip of height `h`: a pill at radius ≥ 12, softer below, square at 0. */
|
|
57
|
+
capsule: (h: number) => number;
|
|
58
|
+
};
|
|
59
|
+
/** 4pt spacing scale: space(4) === 16. */
|
|
60
|
+
space: (n: number) => number;
|
|
61
|
+
font: { family?: string; mono: string };
|
|
62
|
+
text: Record<'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl', TextStyle>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const light: Colors = {
|
|
66
|
+
background: '#ffffff',
|
|
67
|
+
foreground: '#09090b',
|
|
68
|
+
card: '#ffffff',
|
|
69
|
+
cardForeground: '#09090b',
|
|
70
|
+
popover: '#ffffff',
|
|
71
|
+
muted: '#f4f4f5',
|
|
72
|
+
mutedForeground: '#71717a',
|
|
73
|
+
border: '#e4e4e7',
|
|
74
|
+
input: '#d4d4d8',
|
|
75
|
+
primary: '#18181b',
|
|
76
|
+
primaryForeground: '#fafafa',
|
|
77
|
+
secondary: '#f4f4f5',
|
|
78
|
+
secondaryForeground: '#18181b',
|
|
79
|
+
accent: '#18181b',
|
|
80
|
+
accentForeground: '#ffffff',
|
|
81
|
+
success: '#16a34a',
|
|
82
|
+
warning: '#f59e0b',
|
|
83
|
+
danger: '#e5484d',
|
|
84
|
+
dangerForeground: '#ffffff',
|
|
85
|
+
ring: '#18181b',
|
|
86
|
+
overlay: 'rgba(0,0,0,0.4)',
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const dark: Colors = {
|
|
90
|
+
background: '#09090b',
|
|
91
|
+
foreground: '#fafafa',
|
|
92
|
+
card: '#111113',
|
|
93
|
+
cardForeground: '#fafafa',
|
|
94
|
+
popover: '#18181b',
|
|
95
|
+
muted: '#1c1c20',
|
|
96
|
+
mutedForeground: '#a1a1aa',
|
|
97
|
+
border: '#27272a',
|
|
98
|
+
input: '#34343a',
|
|
99
|
+
primary: '#fafafa',
|
|
100
|
+
primaryForeground: '#18181b',
|
|
101
|
+
secondary: '#1f1f23',
|
|
102
|
+
secondaryForeground: '#fafafa',
|
|
103
|
+
accent: '#fafafa',
|
|
104
|
+
accentForeground: '#09090b',
|
|
105
|
+
success: '#3dd68c',
|
|
106
|
+
warning: '#ffb224',
|
|
107
|
+
danger: '#ff6369',
|
|
108
|
+
dangerForeground: '#ffffff',
|
|
109
|
+
ring: '#d4d4d8',
|
|
110
|
+
overlay: 'rgba(0,0,0,0.6)',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const palettes = { light, dark };
|
|
114
|
+
|
|
115
|
+
function build(scheme: ColorScheme, overrides?: ThemeOverrides): Theme {
|
|
116
|
+
const base = scheme === 'dark' ? dark : light;
|
|
117
|
+
const accent = overrides?.accent;
|
|
118
|
+
const colors: Colors = {
|
|
119
|
+
...base,
|
|
120
|
+
...(accent ? { accent, ring: accent, accentForeground: readableOn(accent) } : null),
|
|
121
|
+
...overrides?.colors?.[scheme],
|
|
122
|
+
};
|
|
123
|
+
const r = overrides?.radius ?? 12;
|
|
124
|
+
return {
|
|
125
|
+
dark: scheme === 'dark',
|
|
126
|
+
colors,
|
|
127
|
+
radius: {
|
|
128
|
+
sm: Math.round(r * 0.5),
|
|
129
|
+
md: r,
|
|
130
|
+
lg: Math.round(r * 1.35),
|
|
131
|
+
xl: Math.round(r * 1.8),
|
|
132
|
+
full: 999,
|
|
133
|
+
scale: (n) => Math.round((n * r) / 12),
|
|
134
|
+
capsule: (h) => Math.round((h / 2) * Math.min(1, r / 12)),
|
|
135
|
+
},
|
|
136
|
+
space: (n) => n * 4,
|
|
137
|
+
font: {
|
|
138
|
+
family: overrides?.fontFamily,
|
|
139
|
+
mono: Platform.select({ ios: 'Menlo', android: 'monospace', default: 'ui-monospace, SFMono-Regular, Menlo, monospace' })!,
|
|
140
|
+
},
|
|
141
|
+
text: {
|
|
142
|
+
xs: { fontSize: 12, lineHeight: 16 },
|
|
143
|
+
sm: { fontSize: 14, lineHeight: 20 },
|
|
144
|
+
md: { fontSize: 16, lineHeight: 22 },
|
|
145
|
+
lg: { fontSize: 18, lineHeight: 24, fontWeight: '400' },
|
|
146
|
+
xl: { fontSize: 22, lineHeight: 28, fontWeight: '400', letterSpacing: -0.3 },
|
|
147
|
+
xxl: { fontSize: 30, lineHeight: 36, fontWeight: '400', letterSpacing: -0.8 },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface ThemeOverrides {
|
|
153
|
+
/** Brand colour used for focus rings, selected states and accent buttons. */
|
|
154
|
+
accent?: string;
|
|
155
|
+
/** Base corner radius in points (default 12). */
|
|
156
|
+
radius?: number;
|
|
157
|
+
fontFamily?: string;
|
|
158
|
+
/** Override any token per scheme. */
|
|
159
|
+
colors?: Partial<Record<ColorScheme, Partial<Colors>>>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const KitContext = createContext<{ scheme?: ColorScheme; overrides?: ThemeOverrides } | null>(null);
|
|
163
|
+
|
|
164
|
+
export function KitProvider({
|
|
165
|
+
scheme,
|
|
166
|
+
children,
|
|
167
|
+
...overrides
|
|
168
|
+
}: ThemeOverrides & { scheme?: ColorScheme | 'system'; children: React.ReactNode }) {
|
|
169
|
+
const value = useMemo(
|
|
170
|
+
() => ({ scheme: scheme === 'system' ? undefined : scheme, overrides }),
|
|
171
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
172
|
+
[scheme, overrides.accent, overrides.radius, overrides.fontFamily, overrides.colors]
|
|
173
|
+
);
|
|
174
|
+
return <KitContext.Provider value={value}>{children}</KitContext.Provider>;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function useKit(): Theme {
|
|
178
|
+
const ctx = useContext(KitContext);
|
|
179
|
+
const system = useColorScheme();
|
|
180
|
+
const scheme: ColorScheme = ctx?.scheme ?? (system === 'dark' ? 'dark' : 'light');
|
|
181
|
+
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
188
|
+
export const motion = {
|
|
189
|
+
/** Toggles, selection indicators. */
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
193
|
+
/** Sheets, layout changes. */
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
195
|
+
fast: 160,
|
|
196
|
+
normal: 240,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/** Adds alpha to a #rrggbb colour: alpha('#6366f1', 0.2). */
|
|
200
|
+
export function alpha(hex: string, a: number) {
|
|
201
|
+
if (!hex.startsWith('#') || (hex.length !== 7 && hex.length !== 4)) return hex;
|
|
202
|
+
const full = hex.length === 4 ? '#' + [...hex.slice(1)].map((c) => c + c).join('') : hex;
|
|
203
|
+
return full + Math.round(Math.max(0, Math.min(1, a)) * 255).toString(16).padStart(2, '0');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Black or white, whichever reads better on `hex`. */
|
|
207
|
+
export function readableOn(hex: string) {
|
|
208
|
+
const full = hex.length === 4 ? '#' + [...hex.slice(1)].map((c) => c + c).join('') : hex;
|
|
209
|
+
const n = parseInt(full.slice(1, 7), 16);
|
|
210
|
+
if (Number.isNaN(n)) return '#ffffff';
|
|
211
|
+
const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|
212
|
+
return (r * 299 + g * 587 + b * 114) / 1000 > 150 ? '#09090b' : '#ffffff';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* True for children that must be wrapped in <Text>: strings, numbers and arrays of them —
|
|
217
|
+
* `{count} new` is the array [3, ' new'], and raw text outside <Text> crashes on native.
|
|
218
|
+
*/
|
|
219
|
+
export function isTextNode(node: React.ReactNode): node is string | number | (string | number)[] {
|
|
220
|
+
if (typeof node === 'string' || typeof node === 'number') return true;
|
|
221
|
+
return Array.isArray(node) && node.length > 0 && node.every((n) => typeof n === 'string' || typeof n === 'number');
|
|
222
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "text-animation",
|
|
3
|
+
"type": "component",
|
|
4
|
+
"title": "Text Animation",
|
|
5
|
+
"description": "Five text effects in one component: words rising on a soft spring, a looping shimmer for \"Thinking…\" states, letters rolling between values, a glyph scramble and a typewriter with a caret. Everything staggers letter by letter on the native driver, and screen readers still hear one clean string.",
|
|
6
|
+
"tier": "free",
|
|
7
|
+
"dependencies": [],
|
|
8
|
+
"registryDependencies": [
|
|
9
|
+
"kit"
|
|
10
|
+
],
|
|
11
|
+
"sharedFiles": [
|
|
12
|
+
"lib/kit.tsx"
|
|
13
|
+
],
|
|
14
|
+
"filesDir": "text-animation/files"
|
|
15
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
1
|
+
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState, type ComponentRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Easing,
|
|
@@ -97,7 +97,7 @@ const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
|
97
97
|
* optional floating label, a focus halo, a counter that morphs into a progress ring near
|
|
98
98
|
* `maxLength`, and a `toolbar` slot for chat composers.
|
|
99
99
|
*/
|
|
100
|
-
export const Textarea = forwardRef<TextInput
|
|
100
|
+
export const Textarea = forwardRef<ComponentRef<typeof TextInput>, TextareaProps>(function Textarea(
|
|
101
101
|
{
|
|
102
102
|
label,
|
|
103
103
|
floatingLabel = true,
|
|
@@ -143,16 +143,18 @@ export const Textarea = forwardRef<TextInput, TextareaProps>(function Textarea(
|
|
|
143
143
|
const LINE = typeof userInput.lineHeight === 'number' ? userInput.lineHeight : Math.round((FONT * S.line) / S.font);
|
|
144
144
|
const corner = typeof userField.borderRadius === 'number' ? userField.borderRadius : radius.md;
|
|
145
145
|
// The hidden mirror must measure text exactly like the input does.
|
|
146
|
-
const metrics: TextStyle = {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
const metrics: TextStyle = {
|
|
147
|
+
...ff,
|
|
148
|
+
...(userInput.fontFamily !== undefined ? { fontFamily: userInput.fontFamily } : null),
|
|
149
|
+
...(userInput.fontWeight !== undefined ? { fontWeight: userInput.fontWeight } : null),
|
|
150
|
+
...(userInput.fontStyle !== undefined ? { fontStyle: userInput.fontStyle } : null),
|
|
151
|
+
...(userInput.letterSpacing !== undefined ? { letterSpacing: userInput.letterSpacing } : null),
|
|
152
|
+
};
|
|
151
153
|
const tint = accent ?? colors.accent;
|
|
152
154
|
const bg = surface ?? colors.background;
|
|
153
155
|
const filled = variant === 'filled';
|
|
154
|
-
const inputRef = useRef<TextInput
|
|
155
|
-
useImperativeHandle(ref, () => inputRef.current as TextInput);
|
|
156
|
+
const inputRef = useRef<ComponentRef<typeof TextInput>>(null);
|
|
157
|
+
useImperativeHandle(ref, () => inputRef.current as ComponentRef<typeof TextInput>);
|
|
156
158
|
|
|
157
159
|
const [focused, setFocused] = useState(false);
|
|
158
160
|
const [inner, setInner] = useState(defaultValue ?? '');
|
|
@@ -181,14 +181,17 @@ export function useKit(): Theme {
|
|
|
181
181
|
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
185
188
|
export const motion = {
|
|
186
189
|
/** Toggles, selection indicators. */
|
|
187
|
-
snappy: { damping:
|
|
188
|
-
/** Press feedback, pops. */
|
|
189
|
-
bouncy: { damping:
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
190
193
|
/** Sheets, layout changes. */
|
|
191
|
-
gentle: { damping:
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
192
195
|
fast: 160,
|
|
193
196
|
normal: 240,
|
|
194
197
|
};
|
|
@@ -181,14 +181,17 @@ export function useKit(): Theme {
|
|
|
181
181
|
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
185
188
|
export const motion = {
|
|
186
189
|
/** Toggles, selection indicators. */
|
|
187
|
-
snappy: { damping:
|
|
188
|
-
/** Press feedback, pops. */
|
|
189
|
-
bouncy: { damping:
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
190
193
|
/** Sheets, layout changes. */
|
|
191
|
-
gentle: { damping:
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
192
195
|
fast: 160,
|
|
193
196
|
normal: 240,
|
|
194
197
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import React, { createContext, useContext, useEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Easing,
|
|
@@ -267,7 +267,7 @@ export function TiltCard({
|
|
|
267
267
|
const touching = useRef(false);
|
|
268
268
|
const origin = useRef({ x: 0, y: 0 });
|
|
269
269
|
const moved = useRef(false);
|
|
270
|
-
const viewRef = useRef<View
|
|
270
|
+
const viewRef = useRef<ComponentRef<typeof View>>(null);
|
|
271
271
|
const disabledRef = useRef(disabled);
|
|
272
272
|
disabledRef.current = disabled;
|
|
273
273
|
|
|
@@ -181,14 +181,17 @@ export function useKit(): Theme {
|
|
|
181
181
|
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
185
188
|
export const motion = {
|
|
186
189
|
/** Toggles, selection indicators. */
|
|
187
|
-
snappy: { damping:
|
|
188
|
-
/** Press feedback, pops. */
|
|
189
|
-
bouncy: { damping:
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
190
193
|
/** Sheets, layout changes. */
|
|
191
|
-
gentle: { damping:
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
192
195
|
fast: 160,
|
|
193
196
|
normal: 240,
|
|
194
197
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import React, { memo, useEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Easing,
|
|
@@ -255,7 +255,7 @@ const WheelColumn = memo(function WheelColumn({ items, index, onIndexChange, lab
|
|
|
255
255
|
const { colors, font } = useKit();
|
|
256
256
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
257
257
|
const scrollY = useRef(new Animated.Value(index * ITEM)).current; // native, driven by the scroll view
|
|
258
|
-
const ref = useRef<ScrollView
|
|
258
|
+
const ref = useRef<ComponentRef<typeof ScrollView>>(null);
|
|
259
259
|
const settled = useRef(index);
|
|
260
260
|
const dragging = useRef(false);
|
|
261
261
|
const lastY = useRef(index * ITEM);
|
|
@@ -181,14 +181,17 @@ export function useKit(): Theme {
|
|
|
181
181
|
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
185
188
|
export const motion = {
|
|
186
189
|
/** Toggles, selection indicators. */
|
|
187
|
-
snappy: { damping:
|
|
188
|
-
/** Press feedback, pops. */
|
|
189
|
-
bouncy: { damping:
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
190
193
|
/** Sheets, layout changes. */
|
|
191
|
-
gentle: { damping:
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
192
195
|
fast: 160,
|
|
193
196
|
normal: 240,
|
|
194
197
|
};
|
|
@@ -131,7 +131,8 @@ export function Avatar({
|
|
|
131
131
|
haptics = true,
|
|
132
132
|
style,
|
|
133
133
|
}: AvatarProps) {
|
|
134
|
-
const { colors, radius, dark } = useKit();
|
|
134
|
+
const { colors, radius, dark, font } = useKit();
|
|
135
|
+
const ff = font.family ? { fontFamily: font.family } : null;
|
|
135
136
|
const reduceMotion = useReduceMotion();
|
|
136
137
|
const uid = useId().replace(/[^a-zA-Z0-9]/g, '');
|
|
137
138
|
const px = resolveSize(size);
|
|
@@ -280,6 +281,7 @@ export function Avatar({
|
|
|
280
281
|
numberOfLines={1}
|
|
281
282
|
style={[
|
|
282
283
|
styles.initials,
|
|
284
|
+
ff,
|
|
283
285
|
{
|
|
284
286
|
color: ink,
|
|
285
287
|
fontSize: Math.max(9, px * (initials.length > 1 ? 0.37 : 0.42)),
|
|
@@ -448,7 +450,7 @@ export function Avatar({
|
|
|
448
450
|
{badgeText ? (
|
|
449
451
|
<Text
|
|
450
452
|
allowFontScaling={false}
|
|
451
|
-
style={[styles.badgeText, { color: colors.dangerForeground, fontSize: Math.max(9, badgeH * 0.6) }]}
|
|
453
|
+
style={[styles.badgeText, ff, { color: colors.dangerForeground, fontSize: Math.max(9, badgeH * 0.6) }]}
|
|
452
454
|
>
|
|
453
455
|
{badgeText}
|
|
454
456
|
</Text>
|
|
@@ -623,7 +625,8 @@ export function AvatarGroup({
|
|
|
623
625
|
onPressMore,
|
|
624
626
|
style,
|
|
625
627
|
}: AvatarGroupProps) {
|
|
626
|
-
const { colors, radius, dark } = useKit();
|
|
628
|
+
const { colors, radius, dark, font } = useKit();
|
|
629
|
+
const ff = font.family ? { fontFamily: font.family } : null;
|
|
627
630
|
const reduceMotion = useReduceMotion();
|
|
628
631
|
const px = resolveSize(size);
|
|
629
632
|
const bg = surface ?? colors.background;
|
|
@@ -699,7 +702,7 @@ export function AvatarGroup({
|
|
|
699
702
|
<Text
|
|
700
703
|
allowFontScaling={false}
|
|
701
704
|
numberOfLines={1}
|
|
702
|
-
style={[styles.moreText, { color: colors.foreground, fontSize: Math.max(8, px * (extraText.length <= 2 ? 0.34 : extraText.length === 3 ? 0.29 : 0.24)) }]}
|
|
705
|
+
style={[styles.moreText, ff, { color: colors.foreground, fontSize: Math.max(8, px * (extraText.length <= 2 ? 0.34 : extraText.length === 3 ? 0.29 : 0.24)) }]}
|
|
703
706
|
>
|
|
704
707
|
+{extraText}
|
|
705
708
|
</Text>
|
|
@@ -244,7 +244,7 @@ function ScrollTimeline({
|
|
|
244
244
|
const dottedFrom = Math.max(0, reach);
|
|
245
245
|
const dottedH = measured && reach < n - 1 ? nodes[n - 1] - nodes[dottedFrom] : 0;
|
|
246
246
|
|
|
247
|
-
let fillStyle: Animated.
|
|
247
|
+
let fillStyle: Animated.WithAnimatedValue<ViewStyle> | null = null;
|
|
248
248
|
if (fillH > 0) {
|
|
249
249
|
if (frozen) {
|
|
250
250
|
fillStyle = {};
|
|
@@ -379,7 +379,8 @@ function Row({
|
|
|
379
379
|
lit,
|
|
380
380
|
onNode,
|
|
381
381
|
}: RowProps) {
|
|
382
|
-
const { colors, radius, dark } = useKit();
|
|
382
|
+
const { colors, radius, dark, font } = useKit();
|
|
383
|
+
const ff = font.family ? { fontFamily: font.family } : null;
|
|
383
384
|
const compact = variant === 'compact';
|
|
384
385
|
const card = variant === 'card';
|
|
385
386
|
const scroll = variant === 'scroll';
|
|
@@ -454,21 +455,21 @@ function Row({
|
|
|
454
455
|
<View style={[styles.titleRow, compact && styles.compactRow]}>
|
|
455
456
|
<Text
|
|
456
457
|
numberOfLines={compact ? 1 : 2}
|
|
457
|
-
style={[styles.title, { fontSize: titleSize, lineHeight: titleLine, color: titleColor }]}
|
|
458
|
+
style={[styles.title, ff, { fontSize: titleSize, lineHeight: titleLine, color: titleColor }]}
|
|
458
459
|
>
|
|
459
460
|
{item.title}
|
|
460
461
|
</Text>
|
|
461
462
|
{item.time ? (
|
|
462
463
|
<Text
|
|
463
464
|
numberOfLines={1}
|
|
464
|
-
style={[styles.time, { lineHeight: titleLine, color: current ? tint : colors.mutedForeground }]}
|
|
465
|
+
style={[styles.time, ff, { lineHeight: titleLine, color: current ? tint : colors.mutedForeground }]}
|
|
465
466
|
>
|
|
466
467
|
{item.time}
|
|
467
468
|
</Text>
|
|
468
469
|
) : null}
|
|
469
470
|
</View>
|
|
470
471
|
{item.description && !compact ? (
|
|
471
|
-
<Text style={[styles.desc, { color: colors.mutedForeground }]}>{item.description}</Text>
|
|
472
|
+
<Text style={[styles.desc, ff, { color: colors.mutedForeground }]}>{item.description}</Text>
|
|
472
473
|
) : null}
|
|
473
474
|
{photos.length ? <TimelineGallery images={photos} dim={muted} /> : null}
|
|
474
475
|
{item.tags?.length || hasLinks ? (
|
|
@@ -478,7 +479,7 @@ function Row({
|
|
|
478
479
|
key={`t-${t}`}
|
|
479
480
|
style={[styles.tag, { borderRadius: radius.capsule(22), backgroundColor: alpha(tint, dark ? 0.2 : 0.1) }]}
|
|
480
481
|
>
|
|
481
|
-
<Text style={[styles.tagText, { color: tint }]}>{t}</Text>
|
|
482
|
+
<Text style={[styles.tagText, ff, { color: tint }]}>{t}</Text>
|
|
482
483
|
</View>
|
|
483
484
|
))}
|
|
484
485
|
{item.links?.map((l) => (
|
|
@@ -490,14 +491,14 @@ function Row({
|
|
|
490
491
|
hitSlop={12}
|
|
491
492
|
style={({ pressed }) => [styles.link, { opacity: pressed ? 0.55 : 1 }]}
|
|
492
493
|
>
|
|
493
|
-
<Text style={[styles.linkText, { color: tint }]}>{l.label} →</Text>
|
|
494
|
+
<Text style={[styles.linkText, ff, { color: tint }]}>{l.label} →</Text>
|
|
494
495
|
</Pressable>
|
|
495
496
|
))}
|
|
496
497
|
</View>
|
|
497
498
|
) : null}
|
|
498
499
|
{item.content ? (
|
|
499
500
|
<View style={styles.content}>
|
|
500
|
-
{isTextNode(item.content) ? <Text style={{ color: colors.foreground }}>{item.content}</Text> : item.content}
|
|
501
|
+
{isTextNode(item.content) ? <Text style={[ff, { color: colors.foreground }]}>{item.content}</Text> : item.content}
|
|
501
502
|
</View>
|
|
502
503
|
) : null}
|
|
503
504
|
</>
|
|
@@ -927,7 +928,8 @@ function TimelineGallery({ images, dim }: { images: TimelineImageSource[]; dim:
|
|
|
927
928
|
}
|
|
928
929
|
|
|
929
930
|
function Photo({ uri, delay, style, more }: { uri: string; delay: number; style: StyleProp<ViewStyle>; more: number }) {
|
|
930
|
-
const { colors } = useKit();
|
|
931
|
+
const { colors, font } = useKit();
|
|
932
|
+
const ff = font.family ? { fontFamily: font.family } : null;
|
|
931
933
|
const shown = useRef(new Animated.Value(0)).current;
|
|
932
934
|
return (
|
|
933
935
|
<View style={[styles.photo, { backgroundColor: colors.muted }, style]}>
|
|
@@ -939,7 +941,7 @@ function Photo({ uri, delay, style, more }: { uri: string; delay: number; style:
|
|
|
939
941
|
/>
|
|
940
942
|
{more > 0 ? (
|
|
941
943
|
<View style={[StyleSheet.absoluteFill, styles.more]}>
|
|
942
|
-
<Text style={styles.moreText}>+{more}</Text>
|
|
944
|
+
<Text style={[styles.moreText, ff]}>+{more}</Text>
|
|
943
945
|
</View>
|
|
944
946
|
) : null}
|
|
945
947
|
</View>
|
|
@@ -181,14 +181,17 @@ export function useKit(): Theme {
|
|
|
181
181
|
return useMemo(() => build(scheme, ctx?.overrides), [scheme, ctx?.overrides]);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Shared motion presets so the whole kit moves the same way. Every spring is critically damped
|
|
186
|
+
* (damping ≥ 2·√(stiffness·mass)): it settles smoothly with no overshoot or wobble.
|
|
187
|
+
*/
|
|
185
188
|
export const motion = {
|
|
186
189
|
/** Toggles, selection indicators. */
|
|
187
|
-
snappy: { damping:
|
|
188
|
-
/** Press feedback, pops. */
|
|
189
|
-
bouncy: { damping:
|
|
190
|
+
snappy: { damping: 30, stiffness: 260, mass: 0.8 },
|
|
191
|
+
/** Press feedback, pops. (Kept under its old name; it no longer bounces.) */
|
|
192
|
+
bouncy: { damping: 26, stiffness: 220, mass: 0.7 },
|
|
190
193
|
/** Sheets, layout changes. */
|
|
191
|
-
gentle: { damping:
|
|
194
|
+
gentle: { damping: 27, stiffness: 160, mass: 1 },
|
|
192
195
|
fast: 160,
|
|
193
196
|
normal: 240,
|
|
194
197
|
};
|
|
@@ -116,7 +116,8 @@ export function Button({
|
|
|
116
116
|
onPressOut,
|
|
117
117
|
...props
|
|
118
118
|
}: ButtonProps) {
|
|
119
|
-
const { colors, radius, dark } = useKit();
|
|
119
|
+
const { colors, radius, dark, font } = useKit();
|
|
120
|
+
const ff = font.family ? { fontFamily: font.family } : null;
|
|
120
121
|
const gid = 'btn' + useId().replace(/[^a-zA-Z0-9]/g, '');
|
|
121
122
|
const scale = useRef(new Animated.Value(1)).current;
|
|
122
123
|
const isDisabled = disabled || loading;
|
|
@@ -149,7 +150,7 @@ export function Button({
|
|
|
149
150
|
const label = isTextNode(children) ? (
|
|
150
151
|
<Text
|
|
151
152
|
numberOfLines={1}
|
|
152
|
-
style={[styles.label, { color: fg, fontSize: s.font }, variant === 'link' && styles.link, textStyle]}
|
|
153
|
+
style={[styles.label, ff, { color: fg, fontSize: s.font }, variant === 'link' && styles.link, textStyle]}
|
|
153
154
|
>
|
|
154
155
|
{children}
|
|
155
156
|
</Text>
|
|
@@ -235,7 +236,7 @@ export function Button({
|
|
|
235
236
|
<View style={styles.row}>
|
|
236
237
|
<ActivityIndicator size="small" color={fg} />
|
|
237
238
|
{size !== 'icon' && isTextNode(children) ? (
|
|
238
|
-
<Text style={[styles.label, { color: fg, fontSize: s.font, opacity: 0.85 }]}>{children}</Text>
|
|
239
|
+
<Text style={[styles.label, ff, { color: fg, fontSize: s.font, opacity: 0.85 }]}>{children}</Text>
|
|
239
240
|
) : null}
|
|
240
241
|
</View>
|
|
241
242
|
) : (
|