@expokit/cli 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +46 -2
- package/bin/expo-kit.js +1266 -0
- package/bin/lib.mjs +343 -0
- package/bin/mcp.mjs +345 -0
- package/package.json +49 -4
- package/registry/_docs/accordion.json +115 -0
- package/registry/_docs/action-sheet.json +138 -0
- package/registry/_docs/alert.json +155 -0
- package/registry/_docs/avatar.json +227 -0
- package/registry/_docs/badge.json +148 -0
- package/registry/_docs/bottom-nav.json +143 -0
- package/registry/_docs/bottom-sheet.json +186 -0
- package/registry/_docs/bullet.json +27 -0
- package/registry/_docs/button-3d.json +138 -0
- package/registry/_docs/button.json +131 -0
- package/registry/_docs/calendar.json +198 -0
- package/registry/_docs/card-stack.json +124 -0
- package/registry/_docs/card.json +131 -0
- package/registry/_docs/carousel.json +122 -0
- package/registry/_docs/chat.json +184 -0
- package/registry/_docs/checkbox.json +109 -0
- package/registry/_docs/checkout.json +105 -0
- package/registry/_docs/chip-group.json +132 -0
- package/registry/_docs/color-swatch.json +82 -0
- package/registry/_docs/confetti.json +102 -0
- package/registry/_docs/coupon.json +192 -0
- package/registry/_docs/cube-pager.json +100 -0
- package/registry/_docs/dashboard.json +123 -0
- package/registry/_docs/date-picker.json +269 -0
- package/registry/_docs/dialog.json +186 -0
- package/registry/_docs/drawer.json +199 -0
- package/registry/_docs/fab.json +144 -0
- package/registry/_docs/flip-card.json +127 -0
- package/registry/_docs/floating-input.json +211 -0
- package/registry/_docs/gift-card.json +124 -0
- package/registry/_docs/glass-button.json +142 -0
- package/registry/_docs/glass-nav-bar.json +102 -0
- package/registry/_docs/glass-search-bar.json +114 -0
- package/registry/_docs/glass-segmented.json +94 -0
- package/registry/_docs/glass-sheet.json +136 -0
- package/registry/_docs/glass-tab-bar.json +100 -0
- package/registry/_docs/glass.json +94 -0
- package/registry/_docs/inbox.json +75 -0
- package/registry/_docs/isometric-bar.json +75 -0
- package/registry/_docs/kit.json +14 -0
- package/registry/_docs/kpi-card.json +14 -0
- package/registry/_docs/like-button.json +92 -0
- package/registry/_docs/liquidglass-tab.json +30 -0
- package/registry/_docs/list-item.json +216 -0
- package/registry/_docs/loyalty-card.json +124 -0
- package/registry/_docs/morph-button.json +128 -0
- package/registry/_docs/number-ticker.json +112 -0
- package/registry/_docs/offers.json +81 -0
- package/registry/_docs/onboarding.json +69 -0
- package/registry/_docs/otp-input.json +158 -0
- package/registry/_docs/pagination-dots.json +108 -0
- package/registry/_docs/parallax-layers.json +104 -0
- package/registry/_docs/parallax-scroll.json +210 -0
- package/registry/_docs/password-input.json +112 -0
- package/registry/_docs/payment-card.json +169 -0
- package/registry/_docs/pixel-bar.json +69 -0
- package/registry/_docs/polar-area.json +81 -0
- package/registry/_docs/profile.json +87 -0
- package/registry/_docs/progress-steps.json +116 -0
- package/registry/_docs/progress.json +152 -0
- package/registry/_docs/radio-group.json +112 -0
- package/registry/_docs/rating.json +114 -0
- package/registry/_docs/ring-carousel.json +122 -0
- package/registry/_docs/scratch-card.json +110 -0
- package/registry/_docs/search-bar.json +160 -0
- package/registry/_docs/search-results.json +123 -0
- package/registry/_docs/segmented-control.json +123 -0
- package/registry/_docs/select.json +277 -0
- package/registry/_docs/settings.json +75 -0
- package/registry/_docs/shimmer-button.json +98 -0
- package/registry/_docs/sign-in.json +201 -0
- package/registry/_docs/skeleton.json +162 -0
- package/registry/_docs/slide-to-confirm.json +108 -0
- package/registry/_docs/slider.json +177 -0
- package/registry/_docs/spin-wheel.json +138 -0
- package/registry/_docs/spinner.json +121 -0
- package/registry/_docs/stateful-button.json +184 -0
- package/registry/_docs/stepper.json +184 -0
- package/registry/_docs/swipe-deck.json +118 -0
- package/registry/_docs/swipeable-row.json +95 -0
- package/registry/_docs/switch.json +124 -0
- package/registry/_docs/tabs.json +129 -0
- package/registry/_docs/tag-input.json +148 -0
- package/registry/_docs/text-animation.json +141 -0
- package/registry/_docs/textarea.json +191 -0
- package/registry/_docs/ticket-card.json +194 -0
- package/registry/_docs/ticket-shape.json +14 -0
- package/registry/_docs/tilt-card.json +157 -0
- package/registry/_docs/time-picker.json +269 -0
- package/registry/_docs/timeline-chart.json +33 -0
- package/registry/_docs/timeline.json +172 -0
- package/registry/_docs/toast.json +185 -0
- package/registry/_docs/treemap.json +33 -0
- package/registry/_docs/waterfall.json +39 -0
- package/registry/_docs/wheel-list.json +122 -0
- package/registry/accordion/files/src/components/ui/accordion.tsx +233 -0
- package/registry/accordion/files/src/lib/kit.tsx +219 -0
- package/registry/accordion.json +17 -0
- package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +580 -0
- package/registry/action-sheet/files/src/lib/kit.tsx +219 -0
- package/registry/action-sheet.json +18 -0
- package/registry/alert/files/src/components/ui/alert.tsx +654 -0
- package/registry/alert/files/src/components/ui/button.tsx +274 -0
- package/registry/alert/files/src/lib/kit.tsx +219 -0
- package/registry/alert.json +20 -0
- package/registry/avatar/files/src/components/ui/avatar.tsx +790 -0
- package/registry/avatar/files/src/lib/kit.tsx +219 -0
- package/registry/avatar.json +18 -0
- package/registry/badge/files/src/components/ui/badge.tsx +626 -0
- package/registry/badge/files/src/lib/kit.tsx +219 -0
- package/registry/badge.json +17 -0
- package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +1050 -0
- package/registry/bottom-nav/files/src/lib/kit.tsx +219 -0
- package/registry/bottom-nav.json +18 -0
- package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +585 -0
- package/registry/bottom-sheet/files/src/lib/kit.tsx +219 -0
- package/registry/bottom-sheet.json +17 -0
- package/registry/bullet.json +14 -0
- package/registry/button/files/src/components/ui/button.tsx +274 -0
- package/registry/button/files/src/lib/kit.tsx +219 -0
- package/registry/button-3d/files/src/components/ui/button-3d.tsx +212 -0
- package/registry/button-3d/files/src/lib/kit.tsx +219 -0
- package/registry/button-3d.json +18 -0
- package/registry/button.json +18 -0
- package/registry/calendar/files/src/components/ui/calendar.tsx +822 -0
- package/registry/calendar/files/src/lib/kit.tsx +219 -0
- package/registry/calendar.json +17 -0
- package/registry/card/files/src/components/ui/card.tsx +300 -0
- package/registry/card/files/src/lib/kit.tsx +219 -0
- package/registry/card-stack.json +15 -0
- package/registry/card.json +17 -0
- package/registry/carousel.json +15 -0
- package/registry/chat.json +18 -0
- package/registry/checkbox/files/src/components/ui/checkbox.tsx +150 -0
- package/registry/checkbox/files/src/lib/kit.tsx +219 -0
- package/registry/checkbox.json +17 -0
- package/registry/checkout.json +26 -0
- package/registry/chip-group/files/src/components/ui/chip-group.tsx +269 -0
- package/registry/chip-group/files/src/lib/kit.tsx +219 -0
- package/registry/chip-group.json +17 -0
- package/registry/color-swatch.json +17 -0
- package/registry/confetti/files/src/components/ui/confetti.tsx +222 -0
- package/registry/confetti/files/src/lib/kit.tsx +219 -0
- package/registry/confetti.json +15 -0
- package/registry/coupon/files/src/components/ui/coupon.tsx +698 -0
- package/registry/coupon/files/src/components/ui/flip-card.tsx +205 -0
- package/registry/coupon/files/src/components/ui/tilt-card.tsx +635 -0
- package/registry/coupon/files/src/lib/kit.tsx +219 -0
- package/registry/coupon/files/src/lib/ticket-shape.tsx +543 -0
- package/registry/coupon.json +23 -0
- package/registry/cube-pager.json +15 -0
- package/registry/dashboard.json +32 -0
- package/registry/date-picker/files/src/components/ui/calendar.tsx +822 -0
- package/registry/date-picker/files/src/components/ui/date-picker.tsx +796 -0
- package/registry/date-picker/files/src/lib/kit.tsx +219 -0
- package/registry/date-picker.json +19 -0
- package/registry/dialog/files/src/components/ui/dialog.tsx +759 -0
- package/registry/dialog/files/src/lib/kit.tsx +219 -0
- package/registry/dialog.json +18 -0
- package/registry/drawer/files/src/components/ui/drawer.tsx +1135 -0
- package/registry/drawer/files/src/lib/kit.tsx +219 -0
- package/registry/drawer.json +18 -0
- package/registry/fab.json +18 -0
- package/registry/flip-card/files/src/components/ui/flip-card.tsx +205 -0
- package/registry/flip-card/files/src/lib/kit.tsx +219 -0
- package/registry/flip-card.json +15 -0
- package/registry/floating-input/files/src/components/ui/floating-input.tsx +528 -0
- package/registry/floating-input/files/src/lib/kit.tsx +219 -0
- package/registry/floating-input.json +17 -0
- package/registry/gift-card.json +21 -0
- package/registry/glass-button.json +22 -0
- package/registry/glass-nav-bar.json +21 -0
- package/registry/glass-search-bar.json +21 -0
- package/registry/glass-segmented.json +22 -0
- package/registry/glass-sheet.json +22 -0
- package/registry/glass-tab-bar.json +22 -0
- package/registry/glass.json +19 -0
- package/registry/inbox.json +30 -0
- package/registry/isometric-bar.json +14 -0
- package/registry/kit/files/src/lib/kit.tsx +219 -0
- package/registry/kit.json +11 -0
- package/registry/kpi-card/files/src/components/charts/kpi-card.tsx +45 -0
- package/registry/kpi-card.json +14 -0
- package/registry/like-button.json +18 -0
- package/registry/liquidglass-tab/files/src/app/(tabs)/_layout.tsx +97 -0
- package/registry/liquidglass-tab/files/src/app/(tabs)/alerts.tsx +5 -0
- package/registry/liquidglass-tab/files/src/app/(tabs)/explore.tsx +5 -0
- package/registry/liquidglass-tab/files/src/app/(tabs)/index.tsx +5 -0
- package/registry/liquidglass-tab/files/src/app/(tabs)/profile.tsx +5 -0
- package/registry/liquidglass-tab/files/src/app/_layout.tsx +33 -0
- package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +259 -0
- package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +122 -0
- package/registry/liquidglass-tab/files/src/lib/tab-bar.ts +61 -0
- package/registry/liquidglass-tab/files/src/lib/tab-icons.ts +130 -0
- package/registry/liquidglass-tab/files/src/lib/tabs.ts +108 -0
- package/registry/liquidglass-tab.json +23 -0
- package/registry/list-item/files/src/components/ui/list-item.tsx +508 -0
- package/registry/list-item/files/src/lib/kit.tsx +219 -0
- package/registry/list-item.json +17 -0
- package/registry/loyalty-card.json +23 -0
- package/registry/morph-button.json +18 -0
- package/registry/number-ticker.json +15 -0
- package/registry/offers.json +24 -0
- package/registry/onboarding.json +17 -0
- package/registry/otp-input/files/src/components/ui/otp-input.tsx +380 -0
- package/registry/otp-input/files/src/lib/kit.tsx +219 -0
- package/registry/otp-input.json +17 -0
- package/registry/pagination-dots/files/src/components/ui/pagination-dots.tsx +262 -0
- package/registry/pagination-dots/files/src/lib/kit.tsx +219 -0
- package/registry/pagination-dots.json +15 -0
- package/registry/parallax-layers.json +15 -0
- package/registry/parallax-scroll.json +17 -0
- package/registry/password-input/files/src/components/ui/floating-input.tsx +528 -0
- package/registry/password-input/files/src/components/ui/password-input.tsx +271 -0
- package/registry/password-input/files/src/lib/kit.tsx +219 -0
- package/registry/password-input.json +19 -0
- package/registry/payment-card/files/src/components/ui/flip-card.tsx +205 -0
- package/registry/payment-card/files/src/components/ui/payment-card.tsx +385 -0
- package/registry/payment-card/files/src/components/ui/tilt-card.tsx +635 -0
- package/registry/payment-card/files/src/lib/kit.tsx +219 -0
- package/registry/payment-card.json +21 -0
- package/registry/pixel-bar.json +14 -0
- package/registry/polar-area.json +14 -0
- package/registry/profile.json +17 -0
- package/registry/progress/files/src/components/ui/progress.tsx +883 -0
- package/registry/progress/files/src/lib/kit.tsx +219 -0
- package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +559 -0
- package/registry/progress-steps/files/src/lib/kit.tsx +219 -0
- package/registry/progress-steps.json +18 -0
- package/registry/progress.json +17 -0
- package/registry/radio-group/files/src/components/ui/radio-group.tsx +327 -0
- package/registry/radio-group/files/src/lib/kit.tsx +219 -0
- package/registry/radio-group.json +18 -0
- package/registry/rating.json +18 -0
- package/registry/ring-carousel.json +15 -0
- package/registry/scratch-card.json +18 -0
- package/registry/search-bar/files/src/components/ui/search-bar.tsx +530 -0
- package/registry/search-bar/files/src/lib/kit.tsx +219 -0
- package/registry/search-bar.json +17 -0
- package/registry/search-results.json +30 -0
- package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +341 -0
- package/registry/segmented-control/files/src/lib/kit.tsx +219 -0
- package/registry/segmented-control.json +18 -0
- package/registry/select/files/src/components/ui/select.tsx +1398 -0
- package/registry/select/files/src/lib/kit.tsx +219 -0
- package/registry/select.json +17 -0
- package/registry/settings.json +26 -0
- package/registry/shimmer-button.json +17 -0
- package/registry/sign-in.json +26 -0
- package/registry/skeleton/files/src/components/ui/skeleton.tsx +799 -0
- package/registry/skeleton/files/src/lib/kit.tsx +219 -0
- package/registry/skeleton.json +17 -0
- package/registry/slide-to-confirm.json +18 -0
- package/registry/slider/files/src/components/ui/slider.tsx +716 -0
- package/registry/slider/files/src/lib/kit.tsx +219 -0
- package/registry/slider.json +17 -0
- package/registry/spin-wheel.json +18 -0
- package/registry/spinner/files/src/components/ui/spinner.tsx +748 -0
- package/registry/spinner/files/src/lib/kit.tsx +219 -0
- package/registry/spinner.json +17 -0
- package/registry/stateful-button/files/src/components/ui/stateful-button.tsx +532 -0
- package/registry/stateful-button/files/src/lib/kit.tsx +219 -0
- package/registry/stateful-button.json +18 -0
- package/registry/stepper/files/src/components/ui/stepper.tsx +646 -0
- package/registry/stepper/files/src/lib/kit.tsx +219 -0
- package/registry/stepper.json +17 -0
- package/registry/swipe-deck.json +15 -0
- package/registry/swipeable-row.json +15 -0
- package/registry/switch/files/src/components/ui/switch.tsx +344 -0
- package/registry/switch/files/src/lib/kit.tsx +219 -0
- package/registry/switch.json +18 -0
- package/registry/tabs/files/src/components/ui/tabs.tsx +539 -0
- package/registry/tabs/files/src/lib/kit.tsx +219 -0
- package/registry/tabs.json +17 -0
- package/registry/tag-input/files/src/components/ui/tag-input.tsx +720 -0
- package/registry/tag-input/files/src/lib/kit.tsx +219 -0
- package/registry/tag-input.json +17 -0
- package/registry/text-animation/files/src/components/ui/text-animation.tsx +650 -0
- package/registry/text-animation/files/src/lib/kit.tsx +219 -0
- package/registry/text-animation.json +15 -0
- package/registry/textarea/files/src/components/ui/textarea.tsx +553 -0
- package/registry/textarea/files/src/lib/kit.tsx +219 -0
- package/registry/textarea.json +17 -0
- package/registry/ticket-card.json +24 -0
- package/registry/ticket-shape/files/src/lib/kit.tsx +219 -0
- package/registry/ticket-shape/files/src/lib/ticket-shape.tsx +543 -0
- package/registry/ticket-shape.json +17 -0
- package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +635 -0
- package/registry/tilt-card/files/src/lib/kit.tsx +219 -0
- package/registry/tilt-card.json +17 -0
- package/registry/time-picker/files/src/components/ui/time-picker.tsx +1159 -0
- package/registry/time-picker/files/src/lib/kit.tsx +219 -0
- package/registry/time-picker.json +17 -0
- package/registry/timeline/files/src/components/ui/avatar.tsx +790 -0
- package/registry/timeline/files/src/components/ui/timeline.tsx +1059 -0
- package/registry/timeline/files/src/lib/kit.tsx +219 -0
- package/registry/timeline-chart.json +14 -0
- package/registry/timeline.json +20 -0
- package/registry/toast/files/src/components/ui/button.tsx +274 -0
- package/registry/toast/files/src/components/ui/toast.tsx +1284 -0
- package/registry/toast/files/src/lib/kit.tsx +219 -0
- package/registry/toast.json +20 -0
- package/registry/treemap.json +14 -0
- package/registry/waterfall.json +14 -0
- package/registry/wheel-list.json +17 -0
- package/schema/components.schema.json +13 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bottom-sheet",
|
|
3
|
+
"category": "Overlays",
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"exportName": "BottomSheet",
|
|
6
|
+
"files": [
|
|
7
|
+
"src/components/ui/bottom-sheet.tsx"
|
|
8
|
+
],
|
|
9
|
+
"summary": "A draggable sheet with snap points whose grabber stretches as you pull it.",
|
|
10
|
+
"props": [
|
|
11
|
+
[
|
|
12
|
+
"open",
|
|
13
|
+
"boolean",
|
|
14
|
+
"—",
|
|
15
|
+
"Show the sheet."
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"onClose",
|
|
19
|
+
"() => void",
|
|
20
|
+
"—",
|
|
21
|
+
"Called after it is dragged, flung, tapped or back-buttoned closed."
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
"snapPoints",
|
|
25
|
+
"(number | \"NN%\")[]",
|
|
26
|
+
"content height",
|
|
27
|
+
"Resting heights, in points or % of the screen. Omit to size the sheet to its content (taller content scrolls)."
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"initialSnap",
|
|
31
|
+
"number",
|
|
32
|
+
"0",
|
|
33
|
+
"Snap index it opens at."
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"snapIndex",
|
|
37
|
+
"number",
|
|
38
|
+
"—",
|
|
39
|
+
"Controlled snap index — change it while open to move the sheet."
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"onSnapChange",
|
|
43
|
+
"(index: number) => void",
|
|
44
|
+
"—",
|
|
45
|
+
"Fires when it settles on another snap."
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
"dismissible",
|
|
49
|
+
"boolean",
|
|
50
|
+
"true",
|
|
51
|
+
"Allow drag-down / scrim / back to close; otherwise it rubber-bands at the lowest snap."
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"title / subtitle",
|
|
55
|
+
"string",
|
|
56
|
+
"—",
|
|
57
|
+
"Left-aligned heading and muted line under the grabber."
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"headerRight",
|
|
61
|
+
"ReactNode",
|
|
62
|
+
"—",
|
|
63
|
+
"Trailing node in the title row, e.g. a Reset link."
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
"showClose",
|
|
67
|
+
"boolean",
|
|
68
|
+
"with a title",
|
|
69
|
+
"Round ✕ in the header (shown when dismissible, there's a title and no headerRight)."
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"handle",
|
|
73
|
+
"boolean",
|
|
74
|
+
"true",
|
|
75
|
+
"Grabber pill (also an accessibility adjustable)."
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
"scrollable",
|
|
79
|
+
"boolean",
|
|
80
|
+
"false",
|
|
81
|
+
"Body is a ScrollView: below the top snap a drag resizes the sheet, at the top snap it scrolls, and pulling down from the top collapses it."
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
"dragFromContent",
|
|
85
|
+
"boolean",
|
|
86
|
+
"= scrollable",
|
|
87
|
+
"Let vertical drags on the body move the sheet. Leave false if children contain their own ScrollView."
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"footer",
|
|
91
|
+
"ReactNode",
|
|
92
|
+
"—",
|
|
93
|
+
"Pinned to the bottom of the visible sheet at every snap point."
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"avoidKeyboard",
|
|
97
|
+
"boolean",
|
|
98
|
+
"true",
|
|
99
|
+
"Lift the sheet above the keyboard (capped below the status bar; the rest becomes scroll padding)."
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"haptics",
|
|
103
|
+
"boolean",
|
|
104
|
+
"true",
|
|
105
|
+
"Light impact on open, selection tick on each snap."
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"backdropOpacity",
|
|
109
|
+
"number",
|
|
110
|
+
"1",
|
|
111
|
+
"Scrim dim at the top snap, 0–1."
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
"bottomInset",
|
|
115
|
+
"number",
|
|
116
|
+
"platform safe inset",
|
|
117
|
+
"Extra padding above the home indicator; pass useSafeAreaInsets().bottom for the device."
|
|
118
|
+
],
|
|
119
|
+
[
|
|
120
|
+
"accessibilityLabel",
|
|
121
|
+
"string",
|
|
122
|
+
"title",
|
|
123
|
+
"Label for the modal sheet."
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"style / contentStyle",
|
|
127
|
+
"StyleProp<ViewStyle>",
|
|
128
|
+
"—",
|
|
129
|
+
"Sheet and content styles."
|
|
130
|
+
]
|
|
131
|
+
],
|
|
132
|
+
"behavior": [
|
|
133
|
+
[
|
|
134
|
+
"Touch",
|
|
135
|
+
"Drag the grabber or header between snap points; release velocity picks the detent and dragging past the limits rubber-bands. Tap the scrim or drag down to close."
|
|
136
|
+
],
|
|
137
|
+
[
|
|
138
|
+
"Motion",
|
|
139
|
+
"Glides between detents on a firm spring while the scrim dims with its height. The keyboard lifts the sheet when avoidKeyboard is on."
|
|
140
|
+
],
|
|
141
|
+
[
|
|
142
|
+
"Reduced motion",
|
|
143
|
+
"Snapping uses a short timing instead of a spring."
|
|
144
|
+
],
|
|
145
|
+
[
|
|
146
|
+
"Haptics",
|
|
147
|
+
"A light impact on open and a selection tick on each snap. Turn off with haptics={false}."
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"Screen readers",
|
|
151
|
+
"The sheet is a modal view. The grabber is adjustable with increment and decrement actions to change snap point, and the title is a header."
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
"Keyboard",
|
|
155
|
+
"Escape closes it on web when dismissible; the Android back button closes it too."
|
|
156
|
+
]
|
|
157
|
+
],
|
|
158
|
+
"usage": "import { useState } from 'react';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\n\nconst [open, setOpen] = useState(false);\n<BottomSheet\n open={open}\n onClose={() => setOpen(false)}\n snapPoints={['40%', '85%']}\n title=\"Share album\"\n/>",
|
|
159
|
+
"examples": [
|
|
160
|
+
{
|
|
161
|
+
"name": "Basic",
|
|
162
|
+
"title": "Basic",
|
|
163
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { Avatar } from '@/components/ui/avatar';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\nimport { Button } from '@/components/ui/button';\nimport { ListIcon, ListItem, ListSection } from '@/components/ui/list-item';\nimport { alpha, readableOn, useKit } from '@/lib/kit';\n\nexport default function Basic() {\n const { colors, radius } = useKit();\n const [open, setOpen] = useState(false);\n const apps: [string, 'mail' | 'phone' | 'globe' | 'heart', string][] = [\n ['Mail', 'mail', colors.accent],\n ['Messages', 'phone', colors.success],\n ['Browser', 'globe', colors.warning],\n ['Favorites', 'heart', colors.danger],\n ];\n return (\n <View style={{ alignItems: 'center' }}>\n <Button variant=\"accent\" onPress={() => setOpen(true)}>\n Share album\n </Button>\n <BottomSheet\n open={open}\n onClose={() => setOpen(false)}\n title=\"Share “Lisbon, May 12–16”\"\n subtitle=\"24 photos · 3 videos\"\n contentStyle={{ paddingHorizontal: 0 }}\n >\n <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ gap: 18, paddingHorizontal: 20, paddingVertical: 8 }}>\n {['Ana Costa', 'Luis Moreno', 'Priya Shah', 'Tom Becker', 'Mei Lin'].map((name) => (\n <Pressable key={name} accessibilityRole=\"button\" accessibilityLabel={`Send to ${name}`} style={{ alignItems: 'center', gap: 6, width: 58 }}>\n <Avatar name={name} size={54} />\n <Text numberOfLines={1} style={{ fontSize: 12, color: colors.foreground }}>\n {name.split(' ')[0]}\n </Text>\n </Pressable>\n ))}\n </ScrollView>\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 20, paddingVertical: 14 }}>\n {apps.map(([label, icon, color]) => (\n <Pressable key={label} accessibilityRole=\"button\" accessibilityLabel={label} style={{ alignItems: 'center', gap: 6, flex: 1 }}>\n <View\n style={{\n width: 54,\n height: 54,\n borderRadius: radius.scale(16),\n backgroundColor: color,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <ListIcon name={icon} color={readableOn(color)} size={24} />\n </View>\n <Text style={{ fontSize: 12, color: colors.mutedForeground }}>{label}</Text>\n </Pressable>\n ))}\n </View>\n <ListSection>\n <ListItem title=\"Copy link\" icon=\"globe\" iconVariant=\"tinted\" chevron={false} size=\"sm\" onPress={() => setOpen(false)} />\n <ListItem title=\"Add to shared album\" icon=\"user\" iconVariant=\"tinted\" chevron={false} size=\"sm\" onPress={() => setOpen(false)} />\n <ListItem title=\"Mark as favorite\" icon=\"star\" iconVariant=\"tinted\" chevron={false} size=\"sm\" onPress={() => setOpen(false)} />\n </ListSection>\n </BottomSheet>\n </View>\n );\n}\n"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "SnapPoints",
|
|
167
|
+
"title": "Snap Points",
|
|
168
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { Avatar } from '@/components/ui/avatar';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\nimport { Button } from '@/components/ui/button';\nimport { ListIcon, ListItem, ListSection } from '@/components/ui/list-item';\nimport { alpha, readableOn, useKit } from '@/lib/kit';\n\nfunction useMuted() {\n const { colors } = useKit();\n return { fontSize: 14, lineHeight: 20, color: colors.mutedForeground };\n}\n\nexport default function SnapPoints() {\n const { colors, radius } = useKit();\n const muted = useMuted();\n const [open, setOpen] = useState(false);\n const [snap, setSnap] = useState(0);\n return (\n <View style={{ alignItems: 'center' }}>\n <Button variant=\"accent\" onPress={() => setOpen(true)}>\n Track your ride\n </Button>\n <BottomSheet\n open={open}\n onClose={() => {\n setOpen(false);\n setSnap(0);\n }}\n snapPoints={['40%', '90%']}\n snapIndex={snap}\n onSnapChange={setSnap}\n scrollable\n accessibilityLabel=\"Ride details\"\n >\n <View style={{ flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between' }}>\n <View>\n <Text style={{ fontSize: 24, letterSpacing: -0.5, color: colors.foreground }}>Arriving in 4 min</Text>\n <Text style={[muted, { marginTop: 2 }]}>Silver Toyota Prius · 7KJ 482</Text>\n </View>\n <View\n style={{\n paddingHorizontal: 10,\n height: 28,\n justifyContent: 'center',\n borderRadius: radius.capsule(28),\n backgroundColor: alpha(colors.success, 0.14),\n }}\n >\n <Text style={{ fontSize: 13, color: colors.success }}>On time</Text>\n </View>\n </View>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12, marginTop: 18 }}>\n <Avatar name=\"Daniel Ortiz\" size={48} />\n <View style={{ flex: 1 }}>\n <Text style={{ fontSize: 16, color: colors.foreground }}>Daniel Ortiz</Text>\n <Text style={muted}>★ 4.92 · 2,184 trips</Text>\n </View>\n </View>\n <View style={{ flexDirection: 'row', gap: 10, marginTop: 18 }}>\n <Button variant=\"secondary\" style={{ flex: 1 }}>\n Message\n </Button>\n <Button variant=\"secondary\" style={{ flex: 1 }}>\n Call\n </Button>\n <Button variant=\"secondary\" style={{ flex: 1 }} onPress={() => setSnap(1)}>\n {snap === 0 ? 'Details' : 'Share'}\n </Button>\n </View>\n\n <Text style={[muted, { marginTop: 28, marginBottom: 6, fontSize: 12, letterSpacing: 0.8 }]}>TRIP</Text>\n {[\n ['Pickup', 'Rua Augusta 24, Baixa', colors.accent],\n ['Drop-off', 'Lisbon Airport, Terminal 1', colors.foreground],\n ].map(([label, place, color]) => (\n <View key={label} style={{ flexDirection: 'row', gap: 12, paddingVertical: 10 }}>\n <View style={{ width: 10, height: 10, marginTop: 5, borderRadius: radius.capsule(10), backgroundColor: color }} />\n <View>\n <Text style={muted}>{label}</Text>\n <Text style={{ fontSize: 15, color: colors.foreground }}>{place}</Text>\n </View>\n </View>\n ))}\n <Text style={[muted, { marginTop: 22, marginBottom: 6, fontSize: 12, letterSpacing: 0.8 }]}>FARE</Text>\n {[\n ['Comfort · 14.2 km', '₹333'],\n ['Airport fee', '₹50'],\n ['Promo SPRING10', '−₹35'],\n ['Total · Visa ••42', '₹348'],\n ].map(([item, price], i, all) => (\n <View key={item} style={{ flexDirection: 'row', justifyContent: 'space-between', paddingVertical: 10 }}>\n <Text style={[muted, i === all.length - 1 && { color: colors.foreground }]}>{item}</Text>\n <Text style={{ fontSize: 14, color: colors.foreground }}>{price}</Text>\n </View>\n ))}\n <Text style={[muted, { marginTop: 22, marginBottom: 6, fontSize: 12, letterSpacing: 0.8 }]}>SAFETY</Text>\n <ListSection>\n <ListItem title=\"Share trip status\" icon=\"user\" iconVariant=\"tinted\" size=\"sm\" onPress={() => {}} />\n <ListItem title=\"Emergency assistance\" icon=\"shield\" iconVariant=\"tinted\" size=\"sm\" onPress={() => {}} />\n <ListItem title=\"Cancel ride\" icon=\"trash\" destructive size=\"sm\" chevron={false} onPress={() => setOpen(false)} />\n </ListSection>\n </BottomSheet>\n </View>\n );\n}\n"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "Filters",
|
|
172
|
+
"title": "Filters",
|
|
173
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\nimport { Button } from '@/components/ui/button';\nimport { ChipGroup } from '@/components/ui/chip-group';\nimport { Switch } from '@/components/ui/switch';\nimport { alpha, readableOn, useKit } from '@/lib/kit';\n\nexport default function Filters() {\n const { colors } = useKit();\n const [open, setOpen] = useState(false);\n const [type, setType] = useState<string[]>(['Entire home']);\n const [price, setPrice] = useState<string[]>(['₹5,000 – ₹10,000']);\n const [rooms, setRooms] = useState<string[]>(['2']);\n const [amenities, setAmenities] = useState<string[]>(['Wi-Fi', 'Kitchen']);\n const [instant, setInstant] = useState(true);\n const [flexible, setFlexible] = useState(false);\n const count = 214 - amenities.length * 23 - (instant ? 31 : 0) - (flexible ? 18 : 0);\n const reset = () => {\n setType([]);\n setPrice([]);\n setRooms([]);\n setAmenities([]);\n setInstant(false);\n setFlexible(false);\n };\n const heading = (t: string) => <Text style={{ fontSize: 16, color: colors.foreground, marginTop: 20, marginBottom: 10 }}>{t}</Text>;\n return (\n <View style={{ alignItems: 'center' }}>\n <Button variant=\"outline\" onPress={() => setOpen(true)}>\n Filters · Porto\n </Button>\n <BottomSheet\n open={open}\n onClose={() => setOpen(false)}\n snapPoints={['62%', '92%']}\n scrollable\n title=\"Filters\"\n headerRight={\n <Pressable onPress={reset} accessibilityRole=\"button\" hitSlop={12}>\n <Text style={{ fontSize: 15, color: colors.accent }}>Reset</Text>\n </Pressable>\n }\n footer={\n <Button variant=\"accent\" block onPress={() => setOpen(false)}>\n {`Show ${count} homes`}\n </Button>\n }\n >\n {heading('Type of place')}\n <ChipGroup options={['Entire home', 'Private room', 'Shared room']} value={type} onValueChange={setType} />\n {heading('Price per night')}\n <ChipGroup options={['Under ₹5,000', '₹5,000 – ₹10,000', '₹10,000+']} value={price} onValueChange={setPrice} />\n {heading('Bedrooms')}\n <ChipGroup options={['Any', '1', '2', '3', '4+']} value={rooms} onValueChange={setRooms} />\n {heading('Amenities')}\n <ChipGroup\n multiple\n options={['Wi-Fi', 'Kitchen', 'Washer', 'Air conditioning', 'Free parking', 'Workspace', 'Pool']}\n value={amenities}\n onValueChange={setAmenities}\n />\n {heading('Booking options')}\n <View style={{ gap: 14 }}>\n <Switch label=\"Instant book\" description=\"Book without waiting for host approval\" value={instant} onValueChange={setInstant} />\n <Switch label=\"Free cancellation\" description=\"Cancel up to 48 h before check-in\" value={flexible} onValueChange={setFlexible} />\n </View>\n </BottomSheet>\n </View>\n );\n}\n"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "KeyboardAware",
|
|
177
|
+
"title": "Keyboard Aware",
|
|
178
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\nimport { Button } from '@/components/ui/button';\nimport { alpha, readableOn, useKit } from '@/lib/kit';\n\nexport default function KeyboardAware() {\n const { colors, radius } = useKit();\n const [open, setOpen] = useState(false);\n const [text, setText] = useState('');\n return (\n <View style={{ alignItems: 'center' }}>\n <Button variant=\"secondary\" onPress={() => setOpen(true)}>\n Reply to Lena\n </Button>\n <BottomSheet\n open={open}\n onClose={() => setOpen(false)}\n snapPoints={[300]}\n title=\"Reply to Lena Fischer\"\n subtitle=\"Re: Offsite agenda\"\n >\n <TextInput\n value={text}\n onChangeText={setText}\n placeholder=\"Thursday works for me — I’ll bring the prototypes.\"\n placeholderTextColor={colors.mutedForeground}\n multiline\n accessibilityLabel=\"Reply\"\n style={{\n minHeight: 110,\n padding: 14,\n fontSize: 15,\n textAlignVertical: 'top',\n color: colors.foreground,\n borderRadius: radius.lg,\n borderWidth: 1,\n borderColor: alpha(colors.foreground, 0.08),\n backgroundColor: colors.muted,\n }}\n />\n <View style={{ flexDirection: 'row', justifyContent: 'flex-end', gap: 10, marginTop: 12 }}>\n <Button variant=\"ghost\" onPress={() => setOpen(false)}>\n Discard\n </Button>\n <Button\n variant=\"accent\"\n disabled={!text.trim()}\n onPress={() => {\n setText('');\n setOpen(false);\n }}\n >\n Send\n </Button>\n </View>\n </BottomSheet>\n </View>\n );\n}\n"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "NonDismissible",
|
|
182
|
+
"title": "Non Dismissible",
|
|
183
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { BottomSheet } from '@/components/ui/bottom-sheet';\nimport { Button } from '@/components/ui/button';\nimport { alpha, readableOn, useKit } from '@/lib/kit';\n\nfunction useMuted() {\n const { colors } = useKit();\n return { fontSize: 14, lineHeight: 20, color: colors.mutedForeground };\n}\n\nexport default function NonDismissible() {\n const muted = useMuted();\n const [open, setOpen] = useState(false);\n return (\n <View style={{ alignItems: 'center' }}>\n <Button variant=\"secondary\" onPress={() => setOpen(true)}>\n Review terms\n </Button>\n <BottomSheet\n open={open}\n onClose={() => setOpen(false)}\n snapPoints={['40%', '70%']}\n dismissible={false}\n title=\"We updated our terms\"\n subtitle=\"Effective November 1, 2026\"\n >\n <Text style={muted}>\n Your files stay encrypted at rest, and we never sell personal information. We now keep deleted items for 30 days so you\n can restore them. Please review and accept to keep using your account.\n </Text>\n <View style={{ flexDirection: 'row', gap: 10, marginTop: 20 }}>\n <Button variant=\"outline\" style={{ flex: 1 }} block onPress={() => setOpen(false)}>\n Later\n </Button>\n <Button variant=\"accent\" style={{ flex: 1 }} block onPress={() => setOpen(false)}>\n Accept\n </Button>\n </View>\n </BottomSheet>\n </View>\n );\n}\n"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bullet",
|
|
3
|
+
"category": "Charts",
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"exportName": "BulletChart",
|
|
6
|
+
"files": [
|
|
7
|
+
"src/components/charts/bullet.tsx"
|
|
8
|
+
],
|
|
9
|
+
"summary": null,
|
|
10
|
+
"props": [
|
|
11
|
+
[
|
|
12
|
+
"data",
|
|
13
|
+
"{ label, value, target?, ranges? }[]",
|
|
14
|
+
"—",
|
|
15
|
+
"KPI rows."
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"rowHeight / barHeight",
|
|
19
|
+
"number",
|
|
20
|
+
"52 / 14",
|
|
21
|
+
"Sizing."
|
|
22
|
+
]
|
|
23
|
+
],
|
|
24
|
+
"behavior": [],
|
|
25
|
+
"usage": null,
|
|
26
|
+
"examples": []
|
|
27
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "button-3d",
|
|
3
|
+
"category": "3D",
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"exportName": "Button3D",
|
|
6
|
+
"files": [
|
|
7
|
+
"src/components/ui/button-3d.tsx"
|
|
8
|
+
],
|
|
9
|
+
"summary": "A keycap-style button whose lit face sinks into its edge when pressed.",
|
|
10
|
+
"props": [
|
|
11
|
+
[
|
|
12
|
+
"children",
|
|
13
|
+
"ReactNode",
|
|
14
|
+
"—",
|
|
15
|
+
"Label, a single glyph (circle buttons) or custom content."
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"onPress",
|
|
19
|
+
"() => void",
|
|
20
|
+
"—",
|
|
21
|
+
"Fires on tap."
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
"appearance",
|
|
25
|
+
"\"auto\" | \"light\" | \"dark\" | \"glass\"",
|
|
26
|
+
"\"auto\"",
|
|
27
|
+
"Keycap material; auto is light on dark screens and dark on light ones. Glass is for buttons on photos."
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"color",
|
|
31
|
+
"string",
|
|
32
|
+
"—",
|
|
33
|
+
"A custom face colour instead of a material, e.g. your brand colour."
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"size",
|
|
37
|
+
"\"sm\" | \"md\" | \"lg\"",
|
|
38
|
+
"\"md\"",
|
|
39
|
+
"Height and text size (36 / 46 / 56)."
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"shape",
|
|
43
|
+
"\"rounded\" | \"pill\" | \"circle\"",
|
|
44
|
+
"\"rounded\"",
|
|
45
|
+
"Keycap, pill or round icon button."
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
"depth",
|
|
49
|
+
"number",
|
|
50
|
+
"4 / 5 / 6 by size",
|
|
51
|
+
"Edge height in points."
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"icon",
|
|
55
|
+
"ReactNode",
|
|
56
|
+
"—",
|
|
57
|
+
"Shown before the label."
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"block",
|
|
61
|
+
"boolean",
|
|
62
|
+
"false",
|
|
63
|
+
"Stretch to the parent's width."
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
"loading",
|
|
67
|
+
"boolean",
|
|
68
|
+
"false",
|
|
69
|
+
"Show a spinner and ignore taps."
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"disabled",
|
|
73
|
+
"boolean",
|
|
74
|
+
"false",
|
|
75
|
+
"Dim the button and ignore taps."
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
"haptics",
|
|
79
|
+
"boolean",
|
|
80
|
+
"true",
|
|
81
|
+
"Light haptic tap on press (iOS / Android)."
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
"accessibilityLabel",
|
|
85
|
+
"string",
|
|
86
|
+
"—",
|
|
87
|
+
"Label for screen readers (needed for icon-only buttons)."
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"style",
|
|
91
|
+
"StyleProp<ViewStyle>",
|
|
92
|
+
"—",
|
|
93
|
+
"Style for the root (width, margins)."
|
|
94
|
+
]
|
|
95
|
+
],
|
|
96
|
+
"behavior": [
|
|
97
|
+
[
|
|
98
|
+
"Touch",
|
|
99
|
+
"The face sinks into its edge on press-in and springs back on release. Small sizes pad their hit area to 44pt."
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"Haptics",
|
|
103
|
+
"A light impact on press-in on iOS and on press on Android, so scrolling past it doesn't buzz. Turn off with haptics={false}."
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
"Screen readers",
|
|
107
|
+
"A button with disabled and busy state. Pass accessibilityLabel for circle keys that show only a glyph."
|
|
108
|
+
]
|
|
109
|
+
],
|
|
110
|
+
"usage": "import { Button3D } from '@/components/ui/button-3d';\n\n<Button3D size=\"lg\" shape=\"pill\" onPress={startTrip}>\n Start the trip\n</Button3D>",
|
|
111
|
+
"examples": [
|
|
112
|
+
{
|
|
113
|
+
"name": "OnPhoto",
|
|
114
|
+
"title": "On Photo",
|
|
115
|
+
"code": "import React, { useState } from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { Button3D } from '@/components/ui/button-3d';\nimport { useKit } from '@/lib/kit';\n\n/** Any photo works (`require()` or a URL). `blur` gives soft, abstract art. */\nconst photo = (id: number, w: number, h: number, blur = false) => ({ uri: `https://picsum.photos/id/${id}/${w}/${h}${blur ? '?blur=10' : ''}` });\n\n/** A screen title, as it sits above the content in your app. */\nfunction Header({ title, sub, right }: { title: string; sub?: string; right?: React.ReactNode }) {\n const { colors } = useKit();\n return (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>\n <View style={{ flex: 1 }}>\n <Text style={{ color: colors.foreground, fontSize: 22, fontWeight: '700', letterSpacing: -0.4 }}>{title}</Text>\n {sub ? <Text style={{ color: colors.mutedForeground, fontSize: 13, marginTop: 2 }}>{sub}</Text> : null}\n </View>\n {right}\n </View>\n );\n}\n\nexport default function OnPhoto() {\n const { colors } = useKit();\n return (\n <View style={{ gap: 18 }}>\n <Header\n title=\"Good morning, Maya\"\n sub=\"Your trip starts in 3 days\"\n right={\n <View style={{ width: 40, height: 40, borderRadius: 20, backgroundColor: colors.muted, alignItems: 'center', justifyContent: 'center' }}>\n <Text style={{ color: colors.foreground, fontSize: 14, fontWeight: '700' }}>MP</Text>\n </View>\n }\n />\n <View style={{ height: 440, borderRadius: 28, overflow: 'hidden', backgroundColor: '#1a2a22' }}>\n <Image alt=\"\" source={photo(1039, 700, 880)} style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }} />\n <View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.28)' }} />\n <View style={{ flex: 1, justifyContent: 'flex-end', padding: 22, gap: 16 }}>\n <View>\n <Text style={{ color: 'rgba(255,255,255,0.85)', fontSize: 12, fontWeight: '700', letterSpacing: 1.2 }}>OREGON · 3 DAYS</Text>\n <Text style={{ color: '#fff', fontSize: 30, fontWeight: '800', letterSpacing: -0.8 }}>Multnomah Falls</Text>\n <Text style={{ color: 'rgba(255,255,255,0.8)', fontSize: 13, marginTop: 2 }}>Waterfalls, old-growth forest and a lodge by the river</Text>\n </View>\n <View style={{ flexDirection: 'row', gap: 10, alignItems: 'center' }}>\n <Button3D appearance=\"glass\" size=\"lg\" shape=\"pill\" style={{ flex: 1 }} block>\n Start the trip\n </Button3D>\n <Button3D appearance=\"glass\" size=\"lg\" shape=\"circle\" accessibilityLabel=\"Save\">\n ♡\n </Button3D>\n <Button3D appearance=\"glass\" size=\"lg\" shape=\"circle\" accessibilityLabel=\"Share\">\n ↗\n </Button3D>\n </View>\n </View>\n </View>\n </View>\n );\n}\n"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "Keypad",
|
|
119
|
+
"title": "Keypad",
|
|
120
|
+
"code": "import React, { useState } from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { Button3D } from '@/components/ui/button-3d';\nimport { useKit } from '@/lib/kit';\n\nexport default function Keypad() {\n const { colors } = useKit();\n const [pin, setPin] = useState('');\n const keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '', '0', '⌫'];\n return (\n <View style={{ gap: 26, alignItems: 'center' }}>\n <View style={{ alignItems: 'center', gap: 4 }}>\n <Text style={{ color: colors.foreground, fontSize: 22, fontWeight: '700', letterSpacing: -0.4 }}>Enter passcode</Text>\n <Text style={{ color: colors.mutedForeground, fontSize: 13 }}>to unlock Northwind</Text>\n </View>\n <View style={{ flexDirection: 'row', gap: 14 }}>\n {[0, 1, 2, 3].map((i) => (\n <View key={i} style={{ width: 12, height: 12, borderRadius: 6, backgroundColor: i < pin.length ? colors.foreground : colors.border }} />\n ))}\n </View>\n <View style={{ width: 252, flexDirection: 'row', flexWrap: 'wrap', gap: 12, justifyContent: 'center' }}>\n {keys.map((k, i) =>\n k ? (\n <Button3D\n key={k}\n appearance=\"light\"\n size=\"lg\"\n style={{ width: 76 }}\n accessibilityLabel={k === '⌫' ? 'Delete' : k}\n onPress={() => setPin((p) => (k === '⌫' ? p.slice(0, -1) : (p + k).slice(0, 4)))}\n >\n {k}\n </Button3D>\n ) : (\n <View key={`gap-${i}`} style={{ width: 76 }} />\n )\n )}\n </View>\n <Text style={{ color: colors.mutedForeground, fontSize: 13, fontWeight: '500' }}>Forgot passcode?</Text>\n </View>\n );\n}\n"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "Checkout",
|
|
124
|
+
"title": "Checkout",
|
|
125
|
+
"code": "import React, { useState } from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { Button3D } from '@/components/ui/button-3d';\nimport { useKit } from '@/lib/kit';\n\n/** Any photo works (`require()` or a URL). `blur` gives soft, abstract art. */\nconst photo = (id: number, w: number, h: number, blur = false) => ({ uri: `https://picsum.photos/id/${id}/${w}/${h}${blur ? '?blur=10' : ''}` });\n\n/** A screen title, as it sits above the content in your app. */\nfunction Header({ title, sub, right }: { title: string; sub?: string; right?: React.ReactNode }) {\n const { colors } = useKit();\n return (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>\n <View style={{ flex: 1 }}>\n <Text style={{ color: colors.foreground, fontSize: 22, fontWeight: '700', letterSpacing: -0.4 }}>{title}</Text>\n {sub ? <Text style={{ color: colors.mutedForeground, fontSize: 13, marginTop: 2 }}>{sub}</Text> : null}\n </View>\n {right}\n </View>\n );\n}\n\nexport default function Checkout() {\n const { colors } = useKit();\n const [busy, setBusy] = useState(false);\n const items = [\n { img: 766, name: 'House blend beans', detail: '250 g · ×2', price: '₹880' },\n { img: 1060, name: 'Pour-over filters', detail: 'Pack of 100', price: '₹120' },\n ];\n const line = (label: string, value: string, strong = false) => (\n <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>\n <Text style={{ color: strong ? colors.foreground : colors.mutedForeground, fontSize: strong ? 16 : 14, fontWeight: strong ? '700' : '400' }}>{label}</Text>\n <Text style={{ color: colors.foreground, fontSize: strong ? 16 : 14, fontWeight: strong ? '700' : '500' }}>{value}</Text>\n </View>\n );\n return (\n <View style={{ gap: 18 }}>\n <Header title=\"Checkout\" sub=\"2 items · arrives tomorrow\" />\n <View style={{ gap: 12 }}>\n {items.map((it) => (\n <View key={it.name} style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>\n <Image alt=\"\" source={photo(it.img, 120, 120)} style={{ width: 52, height: 52, borderRadius: 12, backgroundColor: colors.muted }} />\n <View style={{ flex: 1 }}>\n <Text style={{ color: colors.foreground, fontSize: 15, fontWeight: '600' }}>{it.name}</Text>\n <Text style={{ color: colors.mutedForeground, fontSize: 12 }}>{it.detail}</Text>\n </View>\n <Text style={{ color: colors.foreground, fontSize: 14, fontWeight: '600' }}>{it.price}</Text>\n </View>\n ))}\n </View>\n <View style={{ gap: 8, paddingTop: 14, borderTopWidth: 1, borderTopColor: colors.border }}>\n {line('Subtotal', '₹1,000')}\n {line('Express delivery', '₹240')}\n {line('Total', '₹1,240', true)}\n </View>\n <View style={{ gap: 12 }}>\n <Button3D\n block\n size=\"lg\"\n loading={busy}\n onPress={() => {\n setBusy(true);\n setTimeout(() => setBusy(false), 1500);\n }}\n >\n Pay ₹1,240\n </Button3D>\n <Button3D block size=\"md\" color={colors.muted}>\n Add a promo code\n </Button3D>\n </View>\n </View>\n );\n}\n"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "Keycaps",
|
|
129
|
+
"title": "Keycaps",
|
|
130
|
+
"code": "import React, { useState } from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { Button3D } from '@/components/ui/button-3d';\nimport { useKit } from '@/lib/kit';\n\n/** A screen title, as it sits above the content in your app. */\nfunction Header({ title, sub, right }: { title: string; sub?: string; right?: React.ReactNode }) {\n const { colors } = useKit();\n return (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>\n <View style={{ flex: 1 }}>\n <Text style={{ color: colors.foreground, fontSize: 22, fontWeight: '700', letterSpacing: -0.4 }}>{title}</Text>\n {sub ? <Text style={{ color: colors.mutedForeground, fontSize: 13, marginTop: 2 }}>{sub}</Text> : null}\n </View>\n {right}\n </View>\n );\n}\n\nexport default function Keycaps() {\n const row = (keys: [string, number?][], appearance: 'light' | 'dark') => (\n <View style={{ flexDirection: 'row', gap: 8, justifyContent: 'center' }}>\n {keys.map(([k, w]) => (\n <Button3D key={k} appearance={appearance} size=\"lg\" style={{ width: w ?? 56 }} accessibilityLabel={k}>\n {k}\n </Button3D>\n ))}\n </View>\n );\n return (\n <View style={{ gap: 22 }}>\n <Header title=\"Keycaps\" sub=\"Press and hold a key to feel it sink\" />\n <View style={{ gap: 12 }}>\n {row([['esc', 64], ['Q'], ['W'], ['E'], ['R']], 'light')}\n {row([['⌘', 64], ['A'], ['S'], ['D'], ['F']], 'dark')}\n {row([['space', 196], ['↵', 92]], 'light')}\n </View>\n </View>\n );\n}\n"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "Materials",
|
|
134
|
+
"title": "Materials",
|
|
135
|
+
"code": "import React, { useState } from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { Button3D } from '@/components/ui/button-3d';\nimport { useKit } from '@/lib/kit';\n\n/** Any photo works (`require()` or a URL). `blur` gives soft, abstract art. */\nconst photo = (id: number, w: number, h: number, blur = false) => ({ uri: `https://picsum.photos/id/${id}/${w}/${h}${blur ? '?blur=10' : ''}` });\n\n/** A screen title, as it sits above the content in your app. */\nfunction Header({ title, sub, right }: { title: string; sub?: string; right?: React.ReactNode }) {\n const { colors } = useKit();\n return (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>\n <View style={{ flex: 1 }}>\n <Text style={{ color: colors.foreground, fontSize: 22, fontWeight: '700', letterSpacing: -0.4 }}>{title}</Text>\n {sub ? <Text style={{ color: colors.mutedForeground, fontSize: 13, marginTop: 2 }}>{sub}</Text> : null}\n </View>\n {right}\n </View>\n );\n}\n\nexport default function Materials() {\n return (\n <View style={{ gap: 18 }}>\n <Header title=\"Materials\" sub=\"Light, dark, frosted glass — or any colour\" />\n <View style={{ flexDirection: 'row', gap: 10, justifyContent: 'center' }}>\n <Button3D appearance=\"light\">Light</Button3D>\n <Button3D appearance=\"dark\">Dark</Button3D>\n <Button3D color=\"#ff5a5f\">Custom</Button3D>\n </View>\n <View style={{ borderRadius: 22, overflow: 'hidden', padding: 18, alignItems: 'center', backgroundColor: '#3a2b55' }}>\n <Image alt=\"\" source={photo(888, 300, 160, true)} style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }} />\n <View style={{ flexDirection: 'row', gap: 10 }}>\n <Button3D appearance=\"glass\">Glass</Button3D>\n <Button3D appearance=\"glass\" shape=\"pill\">\n On any photo\n </Button3D>\n </View>\n </View>\n </View>\n );\n}\n"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "button",
|
|
3
|
+
"category": "Buttons",
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"exportName": "Button",
|
|
6
|
+
"files": [
|
|
7
|
+
"src/components/ui/button.tsx"
|
|
8
|
+
],
|
|
9
|
+
"summary": "A button that springs down on press, in eleven variants including gradient and glow.",
|
|
10
|
+
"props": [
|
|
11
|
+
[
|
|
12
|
+
"variant",
|
|
13
|
+
"\"primary\" | \"accent\" | \"secondary\" | \"outline\" | \"ghost\" | \"soft\" | \"destructive\" | \"link\" | \"gradient\" | \"glow\" | \"elevated\"",
|
|
14
|
+
"\"primary\"",
|
|
15
|
+
"Solid primary / accent / secondary / danger fill, bordered outline, transparent ghost, tinted soft, underlined link, two-tone gradient, accent with a coloured glow, or a raised elevated surface."
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"size",
|
|
19
|
+
"\"sm\" | \"md\" | \"lg\" | \"icon\"",
|
|
20
|
+
"\"md\"",
|
|
21
|
+
"36 / 46 / 54pt, or a round icon button."
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
"loading",
|
|
25
|
+
"boolean",
|
|
26
|
+
"false",
|
|
27
|
+
"Spinner + blocks presses."
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"left / right",
|
|
31
|
+
"ReactNode",
|
|
32
|
+
"—",
|
|
33
|
+
"Icons beside the label."
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"block",
|
|
37
|
+
"boolean",
|
|
38
|
+
"false",
|
|
39
|
+
"Stretches to the parent's width (alignSelf: stretch)."
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"pill",
|
|
43
|
+
"boolean",
|
|
44
|
+
"false",
|
|
45
|
+
"Fully rounded."
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
"color",
|
|
49
|
+
"string",
|
|
50
|
+
"theme accent",
|
|
51
|
+
"Any colour; recolours every tinted variant and picks readable text automatically."
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"gradientTo",
|
|
55
|
+
"string",
|
|
56
|
+
"color shifted 38° on the hue wheel",
|
|
57
|
+
"Second stop for variant=\"gradient\"."
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"haptics",
|
|
61
|
+
"boolean",
|
|
62
|
+
"false",
|
|
63
|
+
"Light tap on press."
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
"textStyle",
|
|
67
|
+
"StyleProp<TextStyle>",
|
|
68
|
+
"—",
|
|
69
|
+
"Style for the label text (merged over size and variant typography)."
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"style",
|
|
73
|
+
"StyleProp<ViewStyle>",
|
|
74
|
+
"—",
|
|
75
|
+
"Style for the outer animated wrapper (margins, alignment); the pressable surface keeps its own."
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
"…PressableProps",
|
|
79
|
+
"",
|
|
80
|
+
"",
|
|
81
|
+
"onPress, disabled, …"
|
|
82
|
+
]
|
|
83
|
+
],
|
|
84
|
+
"behavior": [
|
|
85
|
+
[
|
|
86
|
+
"Touch",
|
|
87
|
+
"Scales down with a spring on press-in and bounces back on release. loading swaps the label for a spinner and blocks presses."
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"Haptics",
|
|
91
|
+
"Opt-in light impact on press with haptics; off by default."
|
|
92
|
+
],
|
|
93
|
+
[
|
|
94
|
+
"Screen readers",
|
|
95
|
+
"A button with disabled and busy state."
|
|
96
|
+
]
|
|
97
|
+
],
|
|
98
|
+
"usage": "import { Button } from '@/components/ui/button';\n\n<Button variant=\"accent\" size=\"lg\" block onPress={checkout}>\n Continue to payment\n</Button>",
|
|
99
|
+
"examples": [
|
|
100
|
+
{
|
|
101
|
+
"name": "Variants",
|
|
102
|
+
"title": "Variants",
|
|
103
|
+
"code": "import { Pressable, Text, View } from 'react-native';\nimport { Button } from '@/components/ui/button';\n\nexport default function Variants() {\n return (\n <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 10 }}>\n <Button>Primary</Button>\n <Button variant=\"accent\">Accent</Button>\n <Button variant=\"secondary\">Secondary</Button>\n <Button variant=\"outline\">Outline</Button>\n <Button variant=\"soft\">Soft</Button>\n <Button variant=\"ghost\">Ghost</Button>\n <Button variant=\"elevated\">Elevated</Button>\n <Button variant=\"destructive\">Delete</Button>\n <Button variant=\"link\">Link</Button>\n </View>\n );\n}\n"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "GradientAndGlow",
|
|
107
|
+
"title": "Gradient And Glow",
|
|
108
|
+
"code": "import { Pressable, Text, View } from 'react-native';\nimport { Button } from '@/components/ui/button';\nimport { readableOn, useKit } from '@/lib/kit';\n\nexport default function GradientAndGlow() {\n const { colors } = useKit();\n return (\n <View style={{ gap: 12 }}>\n <Button\n variant=\"gradient\"\n size=\"lg\"\n block\n pill\n right={<Text style={{ color: readableOn(colors.accent), fontSize: 18 }}>→</Text>}\n >\n Get started\n </Button>\n <View style={{ flexDirection: 'row', gap: 10 }}>\n <Button variant=\"glow\" pill style={{ flex: 1 }}>\n Go live\n </Button>\n <Button variant=\"gradient\" pill style={{ flex: 1 }}>\n Boost\n </Button>\n </View>\n </View>\n );\n}\n"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "DynamicColor",
|
|
112
|
+
"title": "Dynamic Color",
|
|
113
|
+
"code": "import React, { useState } from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { Button } from '@/components/ui/button';\nimport { readableOn, useKit } from '@/lib/kit';\n\nconst PALETTE = ['#6366f1', '#10b981', '#f59e0b', '#ef4444', '#0ea5e9', '#ec4899'];\n\nexport default function DynamicColor() {\n const { colors, radius } = useKit();\n const [color, setColor] = useState(PALETTE[0]);\n return (\n <View style={{ gap: 14 }}>\n <View style={{ flexDirection: 'row', gap: 10 }}>\n {PALETTE.map((c) => (\n <Pressable\n key={c}\n onPress={() => setColor(c)}\n accessibilityRole=\"button\"\n accessibilityLabel={`Use ${c}`}\n style={{\n width: 28,\n height: 28,\n borderRadius: radius.full,\n backgroundColor: c,\n borderWidth: 3,\n borderColor: c === color ? colors.foreground : 'transparent',\n }}\n />\n ))}\n </View>\n <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 10 }}>\n <Button variant=\"accent\" color={color}>Accent</Button>\n <Button variant=\"gradient\" color={color}>Gradient</Button>\n <Button variant=\"glow\" color={color}>Glow</Button>\n <Button variant=\"soft\" color={color}>Soft</Button>\n <Button variant=\"outline\" color={color}>Outline</Button>\n <Button variant=\"elevated\" color={color}>Elevated</Button>\n </View>\n </View>\n );\n}\n"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "Sizes",
|
|
117
|
+
"title": "Sizes",
|
|
118
|
+
"code": "import { Pressable, Text, View } from 'react-native';\nimport { Button } from '@/components/ui/button';\n\nexport default function Sizes() {\n return (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>\n <Button size=\"sm\">Small</Button>\n <Button size=\"md\">Medium</Button>\n <Button size=\"lg\">Large</Button>\n <Button size=\"icon\" variant=\"outline\">\n <Text style={{ fontSize: 18 }}>♥</Text>\n </Button>\n </View>\n );\n}\n"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "Loading",
|
|
122
|
+
"title": "Loading",
|
|
123
|
+
"code": "import React, { useState } from 'react';\nimport { Button } from '@/components/ui/button';\n\nexport default function Loading() {\n const [busy, setBusy] = useState(false);\n return (\n <Button\n variant=\"accent\"\n pill\n block\n size=\"lg\"\n loading={busy}\n onPress={() => {\n setBusy(true);\n setTimeout(() => setBusy(false), 1600);\n }}\n >\n {busy ? 'Saving' : 'Save changes'}\n </Button>\n );\n}\n"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "Colors",
|
|
127
|
+
"title": "Colors",
|
|
128
|
+
"code": "import { Pressable, Text, View } from 'react-native';\nimport { Button } from '@/components/ui/button';\n\nexport default function Colors() {\n return (\n <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 10 }}>\n <Button variant=\"soft\" color=\"#10b981\">Approve</Button>\n <Button variant=\"soft\" color=\"#f59e0b\">Pending</Button>\n <Button variant=\"soft\" color=\"#ef4444\">Reject</Button>\n <Button variant=\"accent\" color=\"#ec4899\" pill>Follow</Button>\n </View>\n );\n}\n"
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|