@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
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tag-input",
|
|
3
|
-
"category": "Inputs",
|
|
4
|
-
"aliases": [],
|
|
5
|
-
"exportName": "TagInput",
|
|
6
|
-
"files": [
|
|
7
|
-
"src/components/ui/tag-input.tsx"
|
|
8
|
-
],
|
|
9
|
-
"props": [
|
|
10
|
-
[
|
|
11
|
-
"value / defaultValue",
|
|
12
|
-
"string[]",
|
|
13
|
-
"[]",
|
|
14
|
-
"Controlled or uncontrolled tags."
|
|
15
|
-
],
|
|
16
|
-
[
|
|
17
|
-
"onChange",
|
|
18
|
-
"(tags) => void",
|
|
19
|
-
"—",
|
|
20
|
-
"Called when a tag is added or removed (the removed chip then shrinks out)."
|
|
21
|
-
],
|
|
22
|
-
[
|
|
23
|
-
"variant",
|
|
24
|
-
"\"outlined\" | \"filled\"",
|
|
25
|
-
"\"outlined\"",
|
|
26
|
-
"Field style."
|
|
27
|
-
],
|
|
28
|
-
[
|
|
29
|
-
"chipVariant",
|
|
30
|
-
"\"soft\" | \"solid\" | \"outline\"",
|
|
31
|
-
"\"soft\"",
|
|
32
|
-
"Tinted accent chips, filled accent chips, or bordered chips with an accent dot."
|
|
33
|
-
],
|
|
34
|
-
[
|
|
35
|
-
"colorize",
|
|
36
|
-
"boolean",
|
|
37
|
-
"false",
|
|
38
|
-
"Tint each chip from a hash of its label."
|
|
39
|
-
],
|
|
40
|
-
[
|
|
41
|
-
"prefix",
|
|
42
|
-
"string",
|
|
43
|
-
"—",
|
|
44
|
-
"Shown before every chip label (e.g. \"#\"); typed copies are stripped."
|
|
45
|
-
],
|
|
46
|
-
[
|
|
47
|
-
"transform",
|
|
48
|
-
"(tag) => string",
|
|
49
|
-
"—",
|
|
50
|
-
"Normalise a tag before validation (lowercase, strip spaces…)."
|
|
51
|
-
],
|
|
52
|
-
[
|
|
53
|
-
"maxTags",
|
|
54
|
-
"number",
|
|
55
|
-
"—",
|
|
56
|
-
"Limit; shows a filling ring and \"3/5\" counter, and locks the input when reached."
|
|
57
|
-
],
|
|
58
|
-
[
|
|
59
|
-
"suggestions",
|
|
60
|
-
"string[]",
|
|
61
|
-
"—",
|
|
62
|
-
"Pills under the empty field; while typing, a list with the match highlighted and an \"Add …\" row."
|
|
63
|
-
],
|
|
64
|
-
[
|
|
65
|
-
"separators",
|
|
66
|
-
"string[]",
|
|
67
|
-
"[\",\"]",
|
|
68
|
-
"Characters that commit a tag (Enter always does)."
|
|
69
|
-
],
|
|
70
|
-
[
|
|
71
|
-
"validate",
|
|
72
|
-
"(tag, tags) => boolean | string",
|
|
73
|
-
"—",
|
|
74
|
-
"Reject a tag (the field shakes); return a string to show it as the error."
|
|
75
|
-
],
|
|
76
|
-
[
|
|
77
|
-
"error / helper",
|
|
78
|
-
"string",
|
|
79
|
-
"—",
|
|
80
|
-
"Message under the field; errors shake once."
|
|
81
|
-
],
|
|
82
|
-
[
|
|
83
|
-
"accent",
|
|
84
|
-
"string",
|
|
85
|
-
"theme accent",
|
|
86
|
-
"Focus and chip colour."
|
|
87
|
-
],
|
|
88
|
-
[
|
|
89
|
-
"style",
|
|
90
|
-
"StyleProp<ViewStyle>",
|
|
91
|
-
"—",
|
|
92
|
-
"Style for the outer wrapper around the field, suggestions and message (the one that shakes)."
|
|
93
|
-
],
|
|
94
|
-
[
|
|
95
|
-
"…TextInputProps",
|
|
96
|
-
"",
|
|
97
|
-
"",
|
|
98
|
-
"placeholder, keyboardType, …"
|
|
99
|
-
]
|
|
100
|
-
],
|
|
101
|
-
"examples": [
|
|
102
|
-
{
|
|
103
|
-
"name": "Skills",
|
|
104
|
-
"title": "Skills",
|
|
105
|
-
"code": "import React, { useState } from 'react';\nimport { StyleSheet, Text, View, type TextProps, type ViewProps } from 'react-native';\nimport { TagInput } from '@/components/ui/tag-input';\nimport { useKit } from '@/lib/kit';\n\n/** Demo card that follows the kit theme, so the docs radius / accent picker reshapes it too. */\nfunction Card({ style, ...rest }: ViewProps) {\n const { colors, radius } = useKit();\n return (\n <View\n style={[\n s.card,\n { borderRadius: radius.xl, borderColor: colors.border, backgroundColor: colors.card },\n style,\n ]}\n {...rest}\n />\n );\n}\n\n/** Text in the kit's ink: `tone=\"muted\"` for secondary copy. */\nfunction Ink({ tone, style, ...rest }: TextProps & { tone?: 'muted' }) {\n const { colors } = useKit();\n return <Text style={[{ color: tone === 'muted' ? colors.mutedForeground : colors.foreground }, style]} {...rest} />;\n}\n\nconst s = StyleSheet.create({\n card: { padding: 16, borderWidth: StyleSheet.hairlineWidth, gap: 12 },\n title: { fontSize: 15, fontWeight: '400' },\n label: { fontSize: 12, fontWeight: '400', letterSpacing: 0.4, textTransform: 'uppercase', marginBottom: -6 },\n});\n\nexport default function Skills() {\n return (\n <Card>\n <Ink style={s.title}>Your skills</Ink>\n <TagInput\n placeholder=\"Add a skill…\"\n defaultValue={['TypeScript', 'React Native']}\n suggestions={['React', 'Swift', 'SwiftUI', 'Kotlin', 'GraphQL', 'Figma', 'Node.js', 'Rust', 'PostgreSQL']}\n helper=\"Type to search, or tap a suggestion.\"\n />\n </Card>\n );\n}\n"
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"name": "InviteByEmail",
|
|
109
|
-
"title": "Invite By Email",
|
|
110
|
-
"code": "import React, { useState } from 'react';\nimport { StyleSheet, Text, View, type TextProps, type ViewProps } from 'react-native';\nimport { TagInput } from '@/components/ui/tag-input';\nimport { useKit } from '@/lib/kit';\n\n/** Demo card that follows the kit theme, so the docs radius / accent picker reshapes it too. */\nfunction Card({ style, ...rest }: ViewProps) {\n const { colors, radius } = useKit();\n return (\n <View\n style={[\n s.card,\n { borderRadius: radius.xl, borderColor: colors.border, backgroundColor: colors.card },\n style,\n ]}\n {...rest}\n />\n );\n}\n\n/** Text in the kit's ink: `tone=\"muted\"` for secondary copy. */\nfunction Ink({ tone, style, ...rest }: TextProps & { tone?: 'muted' }) {\n const { colors } = useKit();\n return <Text style={[{ color: tone === 'muted' ? colors.mutedForeground : colors.foreground }, style]} {...rest} />;\n}\n\nconst s = StyleSheet.create({\n card: { padding: 16, borderWidth: StyleSheet.hairlineWidth, gap: 12 },\n title: { fontSize: 15, fontWeight: '400' },\n label: { fontSize: 12, fontWeight: '400', letterSpacing: 0.4, textTransform: 'uppercase', marginBottom: -6 },\n});\n\nexport default function InviteByEmail() {\n const [emails, setEmails] = useState(['maya@studio.co', 'leo@studio.co']);\n return (\n <Card>\n <Ink style={s.title}>Invite teammates</Ink>\n <TagInput\n value={emails}\n onChange={setEmails}\n validate={(tag) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/.test(tag) || `“${tag}” isn't a valid email address`}\n transform={(tag) => tag.toLowerCase()}\n chipVariant=\"outline\"\n keyboardType=\"email-address\"\n placeholder=\"name@company.com\"\n helper=\"Separate addresses with a comma or space.\"\n separators={[',', ' ']}\n />\n </Card>\n );\n}\n"
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
"name": "Topics",
|
|
114
|
-
"title": "Topics",
|
|
115
|
-
"code": "import { StyleSheet, Text, View, type TextProps, type ViewProps } from 'react-native';\nimport { TagInput } from '@/components/ui/tag-input';\nimport { useKit } from '@/lib/kit';\n\n/** Demo card that follows the kit theme, so the docs radius / accent picker reshapes it too. */\nfunction Card({ style, ...rest }: ViewProps) {\n const { colors, radius } = useKit();\n return (\n <View\n style={[\n s.card,\n { borderRadius: radius.xl, borderColor: colors.border, backgroundColor: colors.card },\n style,\n ]}\n {...rest}\n />\n );\n}\n\n/** Text in the kit's ink: `tone=\"muted\"` for secondary copy. */\nfunction Ink({ tone, style, ...rest }: TextProps & { tone?: 'muted' }) {\n const { colors } = useKit();\n return <Text style={[{ color: tone === 'muted' ? colors.mutedForeground : colors.foreground }, style]} {...rest} />;\n}\n\nconst s = StyleSheet.create({\n card: { padding: 16, borderWidth: StyleSheet.hairlineWidth, gap: 12 },\n title: { fontSize: 15, fontWeight: '400' },\n label: { fontSize: 12, fontWeight: '400', letterSpacing: 0.4, textTransform: 'uppercase', marginBottom: -6 },\n});\n\nexport default function Topics() {\n return (\n <Card>\n <Ink style={s.title}>Follow topics</Ink>\n <TagInput\n colorize\n maxTags={5}\n defaultValue={['Design', 'Climate', 'Startups']}\n suggestions={['Space', 'AI', 'Music', 'Cooking', 'Photography', 'Travel']}\n placeholder=\"Add a topic…\"\n helper=\"Pick up to five for your feed.\"\n />\n </Card>\n );\n}\n"
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"name": "Hashtags",
|
|
119
|
-
"title": "Hashtags",
|
|
120
|
-
"code": "import { StyleSheet, Text, View, type TextProps, type ViewProps } from 'react-native';\nimport { TagInput } from '@/components/ui/tag-input';\nimport { useKit } from '@/lib/kit';\n\n/** Demo card that follows the kit theme, so the docs radius / accent picker reshapes it too. */\nfunction Card({ style, ...rest }: ViewProps) {\n const { colors, radius } = useKit();\n return (\n <View\n style={[\n s.card,\n { borderRadius: radius.xl, borderColor: colors.border, backgroundColor: colors.card },\n style,\n ]}\n {...rest}\n />\n );\n}\n\n/** Text in the kit's ink: `tone=\"muted\"` for secondary copy. */\nfunction Ink({ tone, style, ...rest }: TextProps & { tone?: 'muted' }) {\n const { colors } = useKit();\n return <Text style={[{ color: tone === 'muted' ? colors.mutedForeground : colors.foreground }, style]} {...rest} />;\n}\n\nconst s = StyleSheet.create({\n card: { padding: 16, borderWidth: StyleSheet.hairlineWidth, gap: 12 },\n title: { fontSize: 15, fontWeight: '400' },\n label: { fontSize: 12, fontWeight: '400', letterSpacing: 0.4, textTransform: 'uppercase', marginBottom: -6 },\n});\n\nexport default function Hashtags() {\n return (\n <Card>\n <Ink style={s.title}>New post</Ink>\n <TagInput\n variant=\"filled\"\n chipVariant=\"solid\"\n prefix=\"#\"\n transform={(tag) => tag.replace(/\\s+/g, '').toLowerCase()}\n separators={[',', ' ']}\n defaultValue={['sunset', 'lisbon']}\n suggestions={['travel', 'goldenhour', 'streetphotography', 'portugal']}\n placeholder=\"#hashtag\"\n helper=\"Backspace once to highlight the last tag, twice to remove it.\"\n />\n </Card>\n );\n}\n"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"name": "ChipStyles",
|
|
124
|
-
"title": "Chip Styles",
|
|
125
|
-
"code": "import { StyleSheet, Text, View, type TextProps, type ViewProps } from 'react-native';\nimport { TagInput } from '@/components/ui/tag-input';\nimport { useKit } from '@/lib/kit';\n\n/** Demo card that follows the kit theme, so the docs radius / accent picker reshapes it too. */\nfunction Card({ style, ...rest }: ViewProps) {\n const { colors, radius } = useKit();\n return (\n <View\n style={[\n s.card,\n { borderRadius: radius.xl, borderColor: colors.border, backgroundColor: colors.card },\n style,\n ]}\n {...rest}\n />\n );\n}\n\n/** Text in the kit's ink: `tone=\"muted\"` for secondary copy. */\nfunction Ink({ tone, style, ...rest }: TextProps & { tone?: 'muted' }) {\n const { colors } = useKit();\n return <Text style={[{ color: tone === 'muted' ? colors.mutedForeground : colors.foreground }, style]} {...rest} />;\n}\n\nconst s = StyleSheet.create({\n card: { padding: 16, borderWidth: StyleSheet.hairlineWidth, gap: 12 },\n title: { fontSize: 15, fontWeight: '400' },\n label: { fontSize: 12, fontWeight: '400', letterSpacing: 0.4, textTransform: 'uppercase', marginBottom: -6 },\n});\n\nexport default function ChipStyles() {\n return (\n <Card>\n <Ink tone=\"muted\" style={s.label}>Soft</Ink>\n <TagInput defaultValue={['Vegan', 'Gluten-free']} placeholder=\"Dietary needs\" />\n <Ink tone=\"muted\" style={s.label}>Solid</Ink>\n <TagInput chipVariant=\"solid\" defaultValue={['Urgent', 'Bug']} placeholder=\"Labels\" />\n <Ink tone=\"muted\" style={s.label}>Outline</Ink>\n <TagInput chipVariant=\"outline\" defaultValue={['Remote', 'Full-time']} placeholder=\"Job filters\" />\n <Ink tone=\"muted\" style={s.label}>Disabled</Ink>\n <TagInput editable={false} defaultValue={['Read-only']} />\n </Card>\n );\n}\n"
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "color-swatch",
|
|
3
|
-
"type": "component",
|
|
4
|
-
"title": "Color Swatch",
|
|
5
|
-
"description": "A colour picker row or grid. The chosen swatch settles inward while a ring springs out around it and a check pops in, in whichever colour reads best on top.",
|
|
6
|
-
"tier": "pro",
|
|
7
|
-
"dependencies": [
|
|
8
|
-
"react-native-svg"
|
|
9
|
-
],
|
|
10
|
-
"registryDependencies": [
|
|
11
|
-
"kit"
|
|
12
|
-
],
|
|
13
|
-
"sharedFiles": [
|
|
14
|
-
"lib/kit.tsx"
|
|
15
|
-
],
|
|
16
|
-
"filesDir": null
|
|
17
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { StyleSheet, Text, View, type StyleProp, type ViewStyle } from "react-native";
|
|
2
|
-
import { Sparkline, useChartTheme } from "expo-charts";
|
|
3
|
-
|
|
4
|
-
export interface KpiCardProps {
|
|
5
|
-
label: string;
|
|
6
|
-
value: string;
|
|
7
|
-
/** Percentage change, e.g. 12.4 or -3.1. */
|
|
8
|
-
delta?: number;
|
|
9
|
-
/** Recent values for the sparkline (oldest first). */
|
|
10
|
-
trend?: number[];
|
|
11
|
-
style?: StyleProp<ViewStyle>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Big number + trend badge + sparkline. Colours follow <ChartProvider>. */
|
|
15
|
-
export function KpiCard({ label, value, delta, trend, style }: KpiCardProps) {
|
|
16
|
-
const theme = useChartTheme();
|
|
17
|
-
const up = (delta ?? 0) >= 0;
|
|
18
|
-
const tone = up ? theme.positive : theme.negative;
|
|
19
|
-
return (
|
|
20
|
-
<View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }, style]}>
|
|
21
|
-
<View style={styles.row}>
|
|
22
|
-
<Text style={[styles.label, { color: theme.mutedForeground }]}>{label}</Text>
|
|
23
|
-
{delta !== undefined ? (
|
|
24
|
-
<View style={[styles.badge, { borderColor: tone }]}>
|
|
25
|
-
<Text style={[styles.badgeText, { color: tone }]}>
|
|
26
|
-
{up ? "+" : ""}
|
|
27
|
-
{delta.toFixed(1)}%
|
|
28
|
-
</Text>
|
|
29
|
-
</View>
|
|
30
|
-
) : null}
|
|
31
|
-
</View>
|
|
32
|
-
<Text style={[styles.value, { color: theme.foreground }]}>{value}</Text>
|
|
33
|
-
{trend && trend.length > 1 ? <Sparkline data={trend} height={40} color={tone} /> : null}
|
|
34
|
-
</View>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const styles = StyleSheet.create({
|
|
39
|
-
card: { borderRadius: 16, borderWidth: StyleSheet.hairlineWidth, padding: 16, gap: 6 },
|
|
40
|
-
row: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" },
|
|
41
|
-
label: { fontSize: 13, fontWeight: "400" },
|
|
42
|
-
badge: { borderWidth: StyleSheet.hairlineWidth, borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },
|
|
43
|
-
badgeText: { fontSize: 11, fontWeight: "400", fontVariant: ["tabular-nums"] },
|
|
44
|
-
value: { fontSize: 28, fontWeight: "400", letterSpacing: -0.5, fontVariant: ["tabular-nums"] },
|
|
45
|
-
});
|
package/registry/kpi-card.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "kpi-card",
|
|
3
|
-
"type": "chart",
|
|
4
|
-
"title": "KPI card",
|
|
5
|
-
"description": "Big number, trend badge and an animated sparkline. Built on expo-charts.",
|
|
6
|
-
"tier": "free",
|
|
7
|
-
"dependencies": [
|
|
8
|
-
"expo-charts",
|
|
9
|
-
"react-native-svg"
|
|
10
|
-
],
|
|
11
|
-
"registryDependencies": [],
|
|
12
|
-
"sharedFiles": [],
|
|
13
|
-
"filesDir": "kpi-card/files"
|
|
14
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "like-button",
|
|
3
|
-
"type": "component",
|
|
4
|
-
"title": "Like Button",
|
|
5
|
-
"description": "Heart, star or bookmark that pops, throws a ring and a burst of coloured particles when liked, with an optional counter that rolls to the new number.",
|
|
6
|
-
"tier": "pro",
|
|
7
|
-
"dependencies": [
|
|
8
|
-
"react-native-svg",
|
|
9
|
-
"expo-haptics"
|
|
10
|
-
],
|
|
11
|
-
"registryDependencies": [
|
|
12
|
-
"kit"
|
|
13
|
-
],
|
|
14
|
-
"sharedFiles": [
|
|
15
|
-
"lib/kit.tsx"
|
|
16
|
-
],
|
|
17
|
-
"filesDir": null
|
|
18
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "morph-button",
|
|
3
|
-
"type": "component",
|
|
4
|
-
"title": "Morph Button",
|
|
5
|
-
"description": "Async button that shrinks into a circle with a spinner while your promise runs, then draws a success tick or shakes with an error cross before springing back to its label.",
|
|
6
|
-
"tier": "pro",
|
|
7
|
-
"dependencies": [
|
|
8
|
-
"react-native-svg",
|
|
9
|
-
"expo-haptics"
|
|
10
|
-
],
|
|
11
|
-
"registryDependencies": [
|
|
12
|
-
"kit"
|
|
13
|
-
],
|
|
14
|
-
"sharedFiles": [
|
|
15
|
-
"lib/kit.tsx"
|
|
16
|
-
],
|
|
17
|
-
"filesDir": null
|
|
18
|
-
}
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Animated,
|
|
4
|
-
Pressable,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
Text,
|
|
7
|
-
View,
|
|
8
|
-
type AccessibilityActionEvent,
|
|
9
|
-
type LayoutChangeEvent,
|
|
10
|
-
type StyleProp,
|
|
11
|
-
type ViewStyle,
|
|
12
|
-
} from 'react-native';
|
|
13
|
-
|
|
14
|
-
import { alpha, motion, useKit } from '@/lib/kit';
|
|
15
|
-
|
|
16
|
-
export type PaginationDotsVariant = 'dots' | 'scale' | 'line' | 'numbers';
|
|
17
|
-
export type PaginationDotsSize = 'sm' | 'md' | 'lg';
|
|
18
|
-
|
|
19
|
-
/** A page position: 0 = first page, 1.5 = halfway between the second and third. */
|
|
20
|
-
export type PaginationProgress = Animated.Value | Animated.AnimatedInterpolation<number> | number;
|
|
21
|
-
|
|
22
|
-
export interface PaginationDotsProps {
|
|
23
|
-
/** Number of pages. */
|
|
24
|
-
count: number;
|
|
25
|
-
/** Active page. Changes spring the indicator across. Ignored when `progress` is an Animated value. */
|
|
26
|
-
index?: number;
|
|
27
|
-
/**
|
|
28
|
-
* Live page position, e.g. `Animated.divide(scrollX, pageWidth)`, so the indicator follows the
|
|
29
|
-
* finger while swiping. Drive it with `useNativeDriver: false` for the 'dots' variant (it
|
|
30
|
-
* animates widths); 'scale', 'line' and 'numbers' work with either driver.
|
|
31
|
-
*/
|
|
32
|
-
progress?: PaginationProgress;
|
|
33
|
-
/** 'dots' active dot stretches into a pill · 'scale' active dot grows · 'line' progress segments · 'numbers' "2 / 5". */
|
|
34
|
-
variant?: PaginationDotsVariant;
|
|
35
|
-
size?: PaginationDotsSize;
|
|
36
|
-
/** Makes each dot a button (with a 44pt hit area) that reports its page. */
|
|
37
|
-
onPress?: (index: number) => void;
|
|
38
|
-
/** Active colour (default: theme accent). */
|
|
39
|
-
accent?: string;
|
|
40
|
-
/** Inactive dot colour (default: a soft tint of the foreground). */
|
|
41
|
-
inactiveColor?: string;
|
|
42
|
-
accessibilityLabel?: string;
|
|
43
|
-
style?: StyleProp<ViewStyle>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const SIZES: Record<PaginationDotsSize, { dot: number; gap: number; pill: number; line: number; font: number }> = {
|
|
47
|
-
sm: { dot: 6, gap: 6, pill: 18, line: 3, font: 12 },
|
|
48
|
-
md: { dot: 8, gap: 8, pill: 24, line: 4, font: 13 },
|
|
49
|
-
lg: { dot: 10, gap: 10, pill: 32, line: 5, font: 15 },
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Page indicator for carousels and onboarding. Feed it a live `progress` value and it tracks the
|
|
54
|
-
* swipe continuously: the active dot stretches into a pill that hands its width to the next dot,
|
|
55
|
-
* scales up, fills a segmented line or rolls the page number.
|
|
56
|
-
*/
|
|
57
|
-
export function PaginationDots({
|
|
58
|
-
count,
|
|
59
|
-
index = 0,
|
|
60
|
-
progress,
|
|
61
|
-
variant = 'dots',
|
|
62
|
-
size = 'md',
|
|
63
|
-
onPress,
|
|
64
|
-
accent,
|
|
65
|
-
inactiveColor,
|
|
66
|
-
accessibilityLabel = 'Page',
|
|
67
|
-
style,
|
|
68
|
-
}: PaginationDotsProps) {
|
|
69
|
-
const { colors, radius } = useKit();
|
|
70
|
-
const tint = accent ?? colors.accent;
|
|
71
|
-
const idle = inactiveColor ?? alpha(colors.foreground, 0.18);
|
|
72
|
-
const s = SIZES[size];
|
|
73
|
-
const n = Math.max(1, count);
|
|
74
|
-
|
|
75
|
-
// A spring-driven position when we aren't handed an Animated value.
|
|
76
|
-
const external = typeof progress === 'object' ? progress : null;
|
|
77
|
-
const target = typeof progress === 'number' ? progress : index;
|
|
78
|
-
const internal = useRef(new Animated.Value(target)).current;
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
if (external) return;
|
|
81
|
-
if (typeof progress === 'number') internal.setValue(target);
|
|
82
|
-
else Animated.spring(internal, { toValue: target, useNativeDriver: false, ...motion.snappy }).start();
|
|
83
|
-
}, [external, progress, target, internal]);
|
|
84
|
-
const pos = external ?? internal;
|
|
85
|
-
|
|
86
|
-
// Rounded page for the 'numbers' label and accessibility.
|
|
87
|
-
const [page, setPage] = useState(Math.round(target));
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
if (!external) {
|
|
90
|
-
setPage(Math.round(target));
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const id = external.addListener(({ value }: { value: number }) => setPage(Math.min(n - 1, Math.max(0, Math.round(value)))));
|
|
94
|
-
return () => external.removeListener(id);
|
|
95
|
-
}, [external, target, n]);
|
|
96
|
-
|
|
97
|
-
const pages = useMemo(() => Array.from({ length: n }, (_, i) => i), [n]);
|
|
98
|
-
const around = (i: number, outside: number, inside: number) =>
|
|
99
|
-
pos.interpolate({ inputRange: [i - 1, i, i + 1], outputRange: [outside, inside, outside], extrapolate: 'clamp' });
|
|
100
|
-
|
|
101
|
-
const onAction = (e: AccessibilityActionEvent) => {
|
|
102
|
-
if (!onPress) return;
|
|
103
|
-
if (e.nativeEvent.actionName === 'increment' && page < n - 1) onPress(page + 1);
|
|
104
|
-
if (e.nativeEvent.actionName === 'decrement' && page > 0) onPress(page - 1);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const a11y = {
|
|
108
|
-
accessible: true,
|
|
109
|
-
accessibilityRole: onPress ? ('adjustable' as const) : ('text' as const),
|
|
110
|
-
accessibilityLabel,
|
|
111
|
-
accessibilityValue: { min: 1, max: n, now: page + 1, text: `${page + 1} of ${n}` },
|
|
112
|
-
accessibilityActions: onPress ? [{ name: 'increment' as const }, { name: 'decrement' as const }] : undefined,
|
|
113
|
-
onAccessibilityAction: onAction,
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const hit = (i: number, child: React.ReactNode, extra?: ViewStyle) =>
|
|
117
|
-
onPress ? (
|
|
118
|
-
<Pressable
|
|
119
|
-
key={i}
|
|
120
|
-
onPress={() => onPress(i)}
|
|
121
|
-
hitSlop={{ top: 18, bottom: 18, left: s.gap / 2, right: s.gap / 2 }}
|
|
122
|
-
accessibilityLabel={`Go to page ${i + 1}`}
|
|
123
|
-
style={extra}
|
|
124
|
-
>
|
|
125
|
-
{child}
|
|
126
|
-
</Pressable>
|
|
127
|
-
) : (
|
|
128
|
-
<View key={i} style={extra}>
|
|
129
|
-
{child}
|
|
130
|
-
</View>
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
if (variant === 'numbers') {
|
|
134
|
-
return (
|
|
135
|
-
<View {...a11y} style={[styles.numbers, { borderRadius: radius.capsule(Math.ceil(s.font * 1.4) + 10), backgroundColor: alpha(colors.foreground, 0.06) }, style]}>
|
|
136
|
-
<RollingNumber value={page + 1} color={tint} size={s.font} />
|
|
137
|
-
<Text style={[styles.numText, { fontSize: s.font, color: colors.mutedForeground }]}> / {n}</Text>
|
|
138
|
-
</View>
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (variant === 'line') return <LineSegments {...{ pages, pos, s, tint, idle, a11y, hit, style }} />;
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<View {...a11y} style={[styles.row, { gap: s.gap, height: s.dot * (variant === 'scale' ? 1.8 : 1) }, style]}>
|
|
146
|
-
{pages.map((i) =>
|
|
147
|
-
variant === 'scale'
|
|
148
|
-
? hit(
|
|
149
|
-
i,
|
|
150
|
-
<Animated.View
|
|
151
|
-
style={{
|
|
152
|
-
width: s.dot,
|
|
153
|
-
height: s.dot,
|
|
154
|
-
borderRadius: s.dot,
|
|
155
|
-
backgroundColor: tint,
|
|
156
|
-
opacity: around(i, 0.28, 1),
|
|
157
|
-
transform: [{ scale: around(i, 1, 1.55) }],
|
|
158
|
-
}}
|
|
159
|
-
/>
|
|
160
|
-
)
|
|
161
|
-
: hit(
|
|
162
|
-
i,
|
|
163
|
-
// Width (JS driver) on the outer view, the accent fill fades on an inner view.
|
|
164
|
-
<Animated.View
|
|
165
|
-
style={{ width: around(i, s.dot, s.pill), height: s.dot, borderRadius: s.dot, backgroundColor: idle, overflow: 'hidden' }}
|
|
166
|
-
>
|
|
167
|
-
<Animated.View style={[StyleSheet.absoluteFill, { backgroundColor: tint, opacity: around(i, 0, 1) }]} />
|
|
168
|
-
</Animated.View>
|
|
169
|
-
)
|
|
170
|
-
)}
|
|
171
|
-
</View>
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
interface LineProps {
|
|
176
|
-
pages: number[];
|
|
177
|
-
pos: Animated.Value | Animated.AnimatedInterpolation<number>;
|
|
178
|
-
s: (typeof SIZES)[PaginationDotsSize];
|
|
179
|
-
tint: string;
|
|
180
|
-
idle: string;
|
|
181
|
-
a11y: object;
|
|
182
|
-
hit: (i: number, child: React.ReactNode, extra?: ViewStyle) => React.ReactNode;
|
|
183
|
-
style?: StyleProp<ViewStyle>;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/** Segments fill left-to-right as the position moves into each page. */
|
|
187
|
-
function LineSegments({ pages, pos, s, tint, idle, a11y, hit, style }: LineProps) {
|
|
188
|
-
const [w, setW] = useState(0);
|
|
189
|
-
const n = pages.length;
|
|
190
|
-
const segW = w ? (w - s.gap * (n - 1)) / n : 0;
|
|
191
|
-
const onLayout = (e: LayoutChangeEvent) => setW(e.nativeEvent.layout.width);
|
|
192
|
-
return (
|
|
193
|
-
<View {...a11y} onLayout={onLayout} style={[styles.line, { gap: s.gap }, style]}>
|
|
194
|
-
{pages.map((i) =>
|
|
195
|
-
hit(
|
|
196
|
-
i,
|
|
197
|
-
<View style={{ height: s.line, borderRadius: s.line, backgroundColor: idle, overflow: 'hidden' }}>
|
|
198
|
-
{segW ? (
|
|
199
|
-
<Animated.View
|
|
200
|
-
style={{
|
|
201
|
-
width: segW,
|
|
202
|
-
height: s.line,
|
|
203
|
-
borderRadius: s.line,
|
|
204
|
-
backgroundColor: tint,
|
|
205
|
-
transform: [
|
|
206
|
-
{
|
|
207
|
-
translateX: pos.interpolate({ inputRange: [i - 1, i], outputRange: [-segW, 0], extrapolate: 'clamp' }),
|
|
208
|
-
},
|
|
209
|
-
],
|
|
210
|
-
}}
|
|
211
|
-
/>
|
|
212
|
-
) : null}
|
|
213
|
-
</View>,
|
|
214
|
-
styles.segment
|
|
215
|
-
)
|
|
216
|
-
)}
|
|
217
|
-
</View>
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function RollingNumber({ value, color, size }: { value: number; color: string; size: number }) {
|
|
222
|
-
const v = useRef(new Animated.Value(1)).current;
|
|
223
|
-
const last = useRef(value);
|
|
224
|
-
const dir = value >= last.current ? 1 : -1;
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
if (value === last.current) return;
|
|
227
|
-
last.current = value;
|
|
228
|
-
v.setValue(0);
|
|
229
|
-
Animated.spring(v, { toValue: 1, useNativeDriver: true, ...motion.snappy }).start();
|
|
230
|
-
}, [value, v]);
|
|
231
|
-
return (
|
|
232
|
-
<Animated.Text
|
|
233
|
-
style={[
|
|
234
|
-
styles.numText,
|
|
235
|
-
{
|
|
236
|
-
fontSize: size,
|
|
237
|
-
color,
|
|
238
|
-
fontWeight: '400',
|
|
239
|
-
opacity: v,
|
|
240
|
-
transform: [{ translateY: v.interpolate({ inputRange: [0, 1], outputRange: [dir * size * 0.7, 0] }) }],
|
|
241
|
-
},
|
|
242
|
-
]}
|
|
243
|
-
>
|
|
244
|
-
{value}
|
|
245
|
-
</Animated.Text>
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const styles = StyleSheet.create({
|
|
250
|
-
row: { flexDirection: 'row', alignItems: 'center', alignSelf: 'center' },
|
|
251
|
-
line: { flexDirection: 'row', alignItems: 'center', alignSelf: 'stretch' },
|
|
252
|
-
segment: { flex: 1, justifyContent: 'center' },
|
|
253
|
-
numbers: {
|
|
254
|
-
flexDirection: 'row',
|
|
255
|
-
alignItems: 'center',
|
|
256
|
-
alignSelf: 'center',
|
|
257
|
-
paddingHorizontal: 12,
|
|
258
|
-
paddingVertical: 5,
|
|
259
|
-
overflow: 'hidden',
|
|
260
|
-
},
|
|
261
|
-
numText: { fontVariant: ['tabular-nums'], fontWeight: '400' },
|
|
262
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pagination-dots",
|
|
3
|
-
"type": "component",
|
|
4
|
-
"title": "Pagination Dots",
|
|
5
|
-
"description": "Page indicator for carousels and onboarding that follows your finger: hand it a live scroll position and the active dot stretches into a pill that pours into the next one, dots scale, segments fill, or the page number rolls. Tap a dot to jump; VoiceOver can swipe through pages.",
|
|
6
|
-
"tier": "free",
|
|
7
|
-
"dependencies": [],
|
|
8
|
-
"registryDependencies": [
|
|
9
|
-
"kit"
|
|
10
|
-
],
|
|
11
|
-
"sharedFiles": [
|
|
12
|
-
"lib/kit.tsx"
|
|
13
|
-
],
|
|
14
|
-
"filesDir": "pagination-dots/files"
|
|
15
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "shimmer-button",
|
|
3
|
-
"type": "component",
|
|
4
|
-
"title": "Shimmer Button",
|
|
5
|
-
"description": "Premium call-to-action with a looping light sweep, a breathing glow halo or a beam of light orbiting the border — all native-driven, with spring press feedback and reduce-motion support.",
|
|
6
|
-
"tier": "pro",
|
|
7
|
-
"dependencies": [
|
|
8
|
-
"react-native-svg"
|
|
9
|
-
],
|
|
10
|
-
"registryDependencies": [
|
|
11
|
-
"kit"
|
|
12
|
-
],
|
|
13
|
-
"sharedFiles": [
|
|
14
|
-
"lib/kit.tsx"
|
|
15
|
-
],
|
|
16
|
-
"filesDir": null
|
|
17
|
-
}
|