@tamagui/demos 1.12.0 → 1.12.2

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.
@@ -1,19 +1,23 @@
1
- import { useRef, useState } from 'react'
1
+ import { useState } from 'react'
2
2
  import {
3
3
  AnimatePresence,
4
4
  Button,
5
5
  H5,
6
6
  SizableText,
7
7
  Stack,
8
- TabTriggerLayout,
8
+ TabLayout,
9
9
  Tabs,
10
- TabsTriggerProps,
10
+ TabsTabProps,
11
11
  XStack,
12
12
  YStack,
13
13
  styled,
14
14
  } from 'tamagui'
15
15
 
16
16
  const demos = ['background', 'underline'] as const
17
+ const demosTitle: Record<(typeof demos)[number], string> = {
18
+ background: 'Background Indicator',
19
+ underline: 'Underline Indicator',
20
+ }
17
21
 
18
22
  export const TabsAdvancedDemo = () => {
19
23
  const [demoIndex, setDemoIndex] = useState(0)
@@ -22,9 +26,9 @@ export const TabsAdvancedDemo = () => {
22
26
  <>
23
27
  {demo === 'underline' ? <TabsAdvancedUnderline /> : <TabsAdvancedBackground />}
24
28
 
25
- <XStack alignItems="center" space position="absolute" bottom="$3" left="$4" $xxs={{ display: 'none' }}>
29
+ <XStack ai="center" space pos="absolute" b="$3" l="$4" $xxs={{ dsp: 'none' }}>
26
30
  <Button size="$2" onPress={() => setDemoIndex((x) => (x + 1) % demos.length)}>
27
- {demo}
31
+ {demosTitle[demo]}
28
32
  </Button>
29
33
  </XStack>
30
34
  </>
@@ -35,17 +39,17 @@ const TabsAdvancedBackground = () => {
35
39
  const [tabState, setTabState] = useState<{
36
40
  currentTab: string
37
41
  /**
38
- * Layout of the trigger user might intend to select (hovering / focusing)
42
+ * Layout of the Tab user might intend to select (hovering / focusing)
39
43
  */
40
- intentAt: TabTriggerLayout | null
44
+ intentAt: TabLayout | null
41
45
  /**
42
- * Layout of the trigger user selected
46
+ * Layout of the Tab user selected
43
47
  */
44
- activeAt: TabTriggerLayout | null
48
+ activeAt: TabLayout | null
45
49
  /**
46
50
  * Used to get the direction of activation for animating the active indicator
47
51
  */
48
- prevActiveAt: TabTriggerLayout | null
52
+ prevActiveAt: TabLayout | null
49
53
  }>({
50
54
  activeAt: null,
51
55
  currentTab: 'tab1',
@@ -76,7 +80,7 @@ const TabsAdvancedBackground = () => {
76
80
  const exitVariant =
77
81
  direction === 1 ? 'isRight' : direction === -1 ? 'isLeft' : 'defaultFade'
78
82
 
79
- const handleOnInteraction: TabsTriggerProps['onInteraction'] = (type, layout) => {
83
+ const handleOnInteraction: TabsTabProps['onInteraction'] = (type, layout) => {
80
84
  if (type === 'select') {
81
85
  setActiveIndicator(layout)
82
86
  } else {
@@ -89,46 +93,58 @@ const TabsAdvancedBackground = () => {
89
93
  value={currentTab}
90
94
  onValueChange={setCurrentTab}
91
95
  orientation="horizontal"
92
- size="$3"
96
+ size="$4"
93
97
  padding="$2"
94
98
  height={150}
95
99
  flexDirection="column"
96
100
  activationMode="manual"
101
+ backgroundColor="$background"
102
+ borderRadius="$4"
103
+ position="relative"
97
104
  >
98
- <Tabs.List
99
- loop={false}
100
- aria-label="Manage your account"
101
- disablePassBorderRadius
102
- >
103
- {intentAt && (
104
- <TabsRovingIndicator
105
- width={intentAt.width}
106
- height={intentAt.height}
107
- x={intentAt.x}
108
- y={intentAt.y}
109
- />
110
- )}
111
-
112
- {activeAt && (
113
- <TabsRovingIndicator
114
- theme="active"
115
- width={activeAt.width}
116
- height={activeAt.height}
117
- x={activeAt.x}
118
- y={activeAt.y}
119
- />
120
- )}
105
+ <YStack>
106
+ <AnimatePresence>
107
+ {intentAt && (
108
+ <TabsRovingIndicator
109
+ borderRadius="$4"
110
+ width={intentAt.width}
111
+ height={intentAt.height}
112
+ x={intentAt.x}
113
+ y={intentAt.y}
114
+ />
115
+ )}
116
+ </AnimatePresence>
117
+ <AnimatePresence>
118
+ {activeAt && (
119
+ <TabsRovingIndicator
120
+ borderRadius="$4"
121
+ theme="active"
122
+ width={activeAt.width}
123
+ height={activeAt.height}
124
+ x={activeAt.x}
125
+ y={activeAt.y}
126
+ />
127
+ )}
128
+ </AnimatePresence>
121
129
 
122
- <Tabs.Trigger value="tab1" onInteraction={handleOnInteraction}>
123
- <SizableText>Profile</SizableText>
124
- </Tabs.Trigger>
125
- <Tabs.Trigger value="tab2" onInteraction={handleOnInteraction}>
126
- <SizableText>Connections</SizableText>
127
- </Tabs.Trigger>
128
- <Tabs.Trigger value="tab3" onInteraction={handleOnInteraction}>
129
- <SizableText>Notifications</SizableText>
130
- </Tabs.Trigger>
131
- </Tabs.List>
130
+ <Tabs.List
131
+ disablePassBorderRadius
132
+ loop={false}
133
+ aria-label="Manage your account"
134
+ space="$2"
135
+ backgroundColor="transparent"
136
+ >
137
+ <Tabs.Tab unstyled value="tab1" onInteraction={handleOnInteraction}>
138
+ <SizableText>Profile</SizableText>
139
+ </Tabs.Tab>
140
+ <Tabs.Tab unstyled value="tab2" onInteraction={handleOnInteraction}>
141
+ <SizableText>Connections</SizableText>
142
+ </Tabs.Tab>
143
+ <Tabs.Tab unstyled value="tab3" onInteraction={handleOnInteraction}>
144
+ <SizableText>Notifications</SizableText>
145
+ </Tabs.Tab>
146
+ </Tabs.List>
147
+ </YStack>
132
148
 
133
149
  <AnimatePresence
134
150
  exitBeforeEnter
@@ -149,17 +165,17 @@ const TabsAdvancedUnderline = () => {
149
165
  const [tabState, setTabState] = useState<{
150
166
  currentTab: string
151
167
  /**
152
- * Layout of the trigger user might intend to select (hovering / focusing)
168
+ * Layout of the Tab user might intend to select (hovering / focusing)
153
169
  */
154
- intentAt: TabTriggerLayout | null
170
+ intentAt: TabLayout | null
155
171
  /**
156
- * Layout of the trigger user selected
172
+ * Layout of the Tab user selected
157
173
  */
158
- activeAt: TabTriggerLayout | null
174
+ activeAt: TabLayout | null
159
175
  /**
160
176
  * Used to get the direction of activation for animating the active indicator
161
177
  */
162
- prevActiveAt: TabTriggerLayout | null
178
+ prevActiveAt: TabLayout | null
163
179
  }>({
164
180
  activeAt: null,
165
181
  currentTab: 'tab1',
@@ -190,7 +206,7 @@ const TabsAdvancedUnderline = () => {
190
206
  const exitVariant =
191
207
  direction === 1 ? 'isRight' : direction === -1 ? 'isLeft' : 'defaultFade'
192
208
 
193
- const handleOnInteraction: TabsTriggerProps['onInteraction'] = (type, layout) => {
209
+ const handleOnInteraction: TabsTabProps['onInteraction'] = (type, layout) => {
194
210
  if (type === 'select') {
195
211
  setActiveIndicator(layout)
196
212
  } else {
@@ -203,52 +219,71 @@ const TabsAdvancedUnderline = () => {
203
219
  value={currentTab}
204
220
  onValueChange={setCurrentTab}
205
221
  orientation="horizontal"
206
- size="$3"
207
- padding="$2"
222
+ size="$4"
208
223
  height={150}
209
224
  flexDirection="column"
210
225
  activationMode="manual"
226
+ backgroundColor="$background"
227
+ borderRadius="$4"
211
228
  >
212
- <YStack borderColor="$color3" borderBottomWidth="$0.5">
213
- <Tabs.List
214
- loop={false}
215
- aria-label="Manage your account"
216
- disablePassBorderRadius
217
- borderBottomLeftRadius={0}
218
- borderBottomRightRadius={0}
219
- paddingBottom="$1.5"
220
- >
229
+ <YStack>
230
+ <AnimatePresence>
221
231
  {intentAt && (
222
232
  <TabsRovingIndicator
223
233
  width={intentAt.width}
224
- height="$0.25"
234
+ height="$0.5"
225
235
  x={intentAt.x}
226
- borderRadius={0}
227
- bottom={-3}
236
+ bottom={0}
228
237
  />
229
238
  )}
230
-
239
+ </AnimatePresence>
240
+ <AnimatePresence>
231
241
  {activeAt && (
232
242
  <TabsRovingIndicator
233
243
  theme="active"
234
244
  active
235
245
  width={activeAt.width}
236
- height="$0.25"
246
+ height="$0.5"
237
247
  x={activeAt.x}
238
- borderRadius={0}
239
- bottom={-3}
248
+ bottom={0}
240
249
  />
241
250
  )}
242
-
243
- <Tabs.Trigger value="tab1" onInteraction={handleOnInteraction}>
251
+ </AnimatePresence>
252
+ <Tabs.List
253
+ disablePassBorderRadius
254
+ loop={false}
255
+ aria-label="Manage your account"
256
+ borderBottomLeftRadius={0}
257
+ borderBottomRightRadius={0}
258
+ paddingBottom="$1.5"
259
+ borderColor="$color3"
260
+ borderBottomWidth="$0.5"
261
+ backgroundColor="transparent"
262
+ >
263
+ <Tabs.Tab
264
+ unstyled
265
+ padding="$5"
266
+ value="tab1"
267
+ onInteraction={handleOnInteraction}
268
+ >
244
269
  <SizableText>Profile</SizableText>
245
- </Tabs.Trigger>
246
- <Tabs.Trigger value="tab2" onInteraction={handleOnInteraction}>
270
+ </Tabs.Tab>
271
+ <Tabs.Tab
272
+ unstyled
273
+ padding="$5"
274
+ value="tab2"
275
+ onInteraction={handleOnInteraction}
276
+ >
247
277
  <SizableText>Connections</SizableText>
248
- </Tabs.Trigger>
249
- <Tabs.Trigger value="tab3" onInteraction={handleOnInteraction}>
278
+ </Tabs.Tab>
279
+ <Tabs.Tab
280
+ unstyled
281
+ padding="$5"
282
+ value="tab3"
283
+ onInteraction={handleOnInteraction}
284
+ >
250
285
  <SizableText>Notifications</SizableText>
251
- </Tabs.Trigger>
286
+ </Tabs.Tab>
252
287
  </Tabs.List>
253
288
  </YStack>
254
289
 
@@ -270,14 +305,19 @@ const TabsAdvancedUnderline = () => {
270
305
  const TabsRovingIndicator = styled(Stack, {
271
306
  position: 'absolute',
272
307
  backgroundColor: '$color5',
273
- opacity: 1,
308
+ opacity: 0.7,
274
309
  animation: '100ms',
275
- borderRadius: '$4',
276
-
310
+ enterStyle: {
311
+ opacity: 0,
312
+ },
313
+ exitStyle: {
314
+ opacity: 0,
315
+ },
277
316
  variants: {
278
317
  active: {
279
318
  true: {
280
319
  backgroundColor: '$color8',
320
+ opacity: 0.6,
281
321
  },
282
322
  },
283
323
  },
package/src/TabsDemo.tsx CHANGED
@@ -1,7 +1,20 @@
1
1
  import { useState } from 'react'
2
- import { Button, H5, SizableText, Tabs, XStack, YStack } from 'tamagui'
2
+ import {
3
+ Button,
4
+ H5,
5
+ Separator,
6
+ SizableText,
7
+ Tabs,
8
+ TabsContentProps,
9
+ XStack,
10
+ YStack,
11
+ } from 'tamagui'
3
12
 
4
13
  const demos = ['horizontal', 'vertical'] as const
14
+ const demosTitle: Record<(typeof demos)[number], string> = {
15
+ horizontal: 'Horizontal',
16
+ vertical: 'Vertical',
17
+ }
5
18
 
6
19
  export function TabsDemo() {
7
20
  const [demoIndex, setDemoIndex] = useState(0)
@@ -21,7 +34,7 @@ export function TabsDemo() {
21
34
  $xxs={{ display: 'none' }}
22
35
  >
23
36
  <Button size="$2" onPress={() => setDemoIndex((x) => (x + 1) % demos.length)}>
24
- {demo}
37
+ {demosTitle[demo]}
25
38
  </Button>
26
39
  </XStack>
27
40
  </YStack>
@@ -37,51 +50,37 @@ const HorizontalTabs = () => {
37
50
  width={400}
38
51
  height={150}
39
52
  borderRadius="$4"
53
+ borderWidth="$0.25"
54
+ overflow="hidden"
55
+ borderColor="$borderColor"
40
56
  >
41
- <Tabs.List disablePassBorderRadius="bottom" aria-label="Manage your account">
42
- <Tabs.Trigger theme="Button" flex={1} value="tab1">
57
+ <Tabs.List
58
+ separator={<Separator vertical />}
59
+ disablePassBorderRadius="bottom"
60
+ aria-label="Manage your account"
61
+ >
62
+ <Tabs.Tab flex={1} value="tab1">
43
63
  <SizableText fontFamily="$body">Profile</SizableText>
44
- </Tabs.Trigger>
45
- <Tabs.Trigger theme="Button" flex={1} value="tab2">
64
+ </Tabs.Tab>
65
+ <Tabs.Tab flex={1} value="tab2">
46
66
  <SizableText fontFamily="$body">Connections</SizableText>
47
- </Tabs.Trigger>
48
- <Tabs.Trigger theme="Button" flex={1} value="tab3">
67
+ </Tabs.Tab>
68
+ <Tabs.Tab flex={1} value="tab3">
49
69
  <SizableText fontFamily="$body">Notifications</SizableText>
50
- </Tabs.Trigger>
70
+ </Tabs.Tab>
51
71
  </Tabs.List>
52
-
53
- <Tabs.Content
54
- value="tab1"
55
- key="tab1"
56
- padding="$5"
57
- alignItems="center"
58
- justifyContent="center"
59
- flex={1}
60
- >
72
+ <Separator />
73
+ <TabsContent value="tab1">
61
74
  <H5>Profile</H5>
62
- </Tabs.Content>
75
+ </TabsContent>
63
76
 
64
- <Tabs.Content
65
- value="tab2"
66
- key="tab2"
67
- padding="$5"
68
- alignItems="center"
69
- justifyContent="center"
70
- flex={1}
71
- >
77
+ <TabsContent value="tab2">
72
78
  <H5>Connections</H5>
73
- </Tabs.Content>
79
+ </TabsContent>
74
80
 
75
- <Tabs.Content
76
- value="tab3"
77
- key="tab3"
78
- padding="$5"
79
- alignItems="center"
80
- justifyContent="center"
81
- flex={1}
82
- >
81
+ <TabsContent value="tab3">
83
82
  <H5>Notifications</H5>
84
- </Tabs.Content>
83
+ </TabsContent>
85
84
  </Tabs>
86
85
  )
87
86
  }
@@ -94,48 +93,56 @@ const VerticalTabs = () => {
94
93
  orientation="vertical"
95
94
  width={400}
96
95
  borderRadius="$4"
96
+ borderWidth="$0.25"
97
+ overflow="hidden"
98
+ borderColor="$borderColor"
97
99
  >
98
- <Tabs.List disablePassBorderRadius="end" aria-label="Manage your account">
99
- <Tabs.Trigger theme="Button" value="tab1">
100
+ <Tabs.List
101
+ disablePassBorderRadius="end"
102
+ aria-label="Manage your account"
103
+ separator={<Separator />}
104
+ >
105
+ <Tabs.Tab value="tab1">
100
106
  <SizableText>Profile</SizableText>
101
- </Tabs.Trigger>
102
- <Tabs.Trigger theme="Button" value="tab2">
107
+ </Tabs.Tab>
108
+ <Tabs.Tab value="tab2">
103
109
  <SizableText>Connections</SizableText>
104
- </Tabs.Trigger>
105
- <Tabs.Trigger theme="Button" value="tab3">
110
+ </Tabs.Tab>
111
+ <Tabs.Tab value="tab3">
106
112
  <SizableText>Notifications</SizableText>
107
- </Tabs.Trigger>
113
+ </Tabs.Tab>
108
114
  </Tabs.List>
109
- <Tabs.Content
110
- value="tab1"
111
- key="tab1"
112
- padding="$2"
113
- alignItems="center"
114
- justifyContent="center"
115
- flex={1}
116
- >
115
+ <Separator vertical />
116
+ <TabsContent value="tab1">
117
117
  <H5 textAlign="center">Profile</H5>
118
- </Tabs.Content>
119
- <Tabs.Content
120
- value="tab2"
121
- key="tab2"
122
- padding="$2"
123
- alignItems="center"
124
- justifyContent="center"
125
- flex={1}
126
- >
118
+ </TabsContent>
119
+ <TabsContent value="tab2">
127
120
  <H5 textAlign="center">Connections</H5>
128
- </Tabs.Content>
129
- <Tabs.Content
130
- value="tab3"
131
- key="tab3"
132
- padding="$2"
133
- alignItems="center"
134
- justifyContent="center"
135
- flex={1}
136
- >
121
+ </TabsContent>
122
+ <TabsContent value="tab3">
137
123
  <H5 textAlign="center">Notifications</H5>
138
- </Tabs.Content>
124
+ </TabsContent>
139
125
  </Tabs>
140
126
  )
141
127
  }
128
+
129
+ const TabsContent = (props: TabsContentProps) => {
130
+ return (
131
+ <Tabs.Content
132
+ backgroundColor="$background"
133
+ key="tab3"
134
+ padding="$2"
135
+ alignItems="center"
136
+ justifyContent="center"
137
+ flex={1}
138
+ borderColor="$background"
139
+ borderRadius="$2"
140
+ borderTopLeftRadius={0}
141
+ borderTopRightRadius={0}
142
+ borderWidth="$2"
143
+ {...props}
144
+ >
145
+ {props.children}
146
+ </Tabs.Content>
147
+ )
148
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"TabsAdvancedDemo.d.ts","sourceRoot":"","sources":["../src/TabsAdvancedDemo.tsx"],"names":[],"mappings":";AAiBA,eAAO,MAAM,gBAAgB,mBAc5B,CAAA"}
1
+ {"version":3,"file":"TabsAdvancedDemo.d.ts","sourceRoot":"","sources":["../src/TabsAdvancedDemo.tsx"],"names":[],"mappings":";AAqBA,eAAO,MAAM,gBAAgB,mBAc5B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"TabsDemo.d.ts","sourceRoot":"","sources":["../src/TabsDemo.tsx"],"names":[],"mappings":";AAKA,wBAAgB,QAAQ,gBAuBvB"}
1
+ {"version":3,"file":"TabsDemo.d.ts","sourceRoot":"","sources":["../src/TabsDemo.tsx"],"names":[],"mappings":";AAkBA,wBAAgB,QAAQ,gBAuBvB"}