Skip to content

Commit b0fdc57

Browse files
committed
wip: remove app.json and update dependencies in pnpm-lock.yaml; add Tabs component to sandbox and update documentation imports
1 parent 39562ff commit b0fdc57

File tree

18 files changed

+1643
-46
lines changed

18 files changed

+1643
-46
lines changed

app.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

apps/sandbox/app/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const primitives = [
1616
{ name: "Checkbox Group", path: "/preview/checkbox-group", description: "Manage multiple checkboxes with coordinated state" },
1717
{ name: "Radio", path: "/preview/radio", description: "Individual radio button with clickable labels" },
1818
{ name: "Radio Group", path: "/preview/radiogroup", description: "Manage multiple radios with coordinated state (single selection)" },
19+
{ name: "Tabs", path: "/preview/tabs", description: "Organize content into tabs: classic on web, liquid glass dropdown on mobile" },
1920
{ name: "Context Menu", path: "/preview/context-menu", description: "Cross-platform context menu: right-click on web, long press on native" },
2021
{ name: "Switch", path: "/preview/switch", description: "Switch between on/off states with customizable styling" },
2122
{ name: "Switch Group", path: "/preview/switch-group", description: "Manage multiple switches with coordinated state" },

apps/sandbox/app/preview/tabs.tsx

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import { Stack } from "expo-router";
2+
import { View, Text } from "@native-ui-org/primitives";
3+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@native-ui-org/primitives";
4+
import { StyleSheet, Platform, ScrollView } from "react-native";
5+
import React from "react";
6+
7+
export default function TabsPreview() {
8+
return (
9+
<ScrollView style={styles.container}>
10+
<Stack.Screen options={{ title: "Tabs" }} />
11+
12+
<View style={styles.content}>
13+
<View style={styles.section}>
14+
<Text as="h2" style={styles.sectionTitle}>Tabs Primitive</Text>
15+
<Text as="p" style={styles.description}>
16+
Organize content into tabbed sections. On web: classic tabs. On iOS/Android: native dropdown button.
17+
</Text>
18+
</View>
19+
20+
{/* Example 1: Normal tabs, no styling */}
21+
<View style={styles.section}>
22+
<Text as="h3" style={styles.subTitle}>Example 1: Normal Tabs</Text>
23+
<Text as="p" style={styles.description}>
24+
Basic tabs without any custom styling
25+
</Text>
26+
27+
<Tabs
28+
defaultValue="tab1"
29+
style={Platform.OS !== "web" ? styles.nativeTabsButton : undefined}
30+
backgroundColor={Platform.OS !== "web" ? "#F2F2F7" : undefined}
31+
borderColor={Platform.OS !== "web" ? "#E5E5EA" : undefined}
32+
cornerRadius={Platform.OS !== "web" ? 10 : undefined}
33+
>
34+
<TabsList>
35+
<TabsTrigger value="tab1" iosIcon="house.fill" androidIcon="home" icon="🏠">Home</TabsTrigger>
36+
<TabsTrigger value="tab2" iosIcon="person.fill" androidIcon="person" icon="👤">Profile</TabsTrigger>
37+
<TabsTrigger value="tab3" iosIcon="gear" androidIcon="settings" icon="⚙️">Settings</TabsTrigger>
38+
</TabsList>
39+
40+
<TabsContent value="tab1">
41+
<View style={styles.tabContent}>
42+
<Text style={styles.tabTitle}>Home Tab</Text>
43+
<Text style={styles.tabText}>
44+
This is the content for the Home tab. You can see that the content is properly displayed with full width.
45+
</Text>
46+
</View>
47+
</TabsContent>
48+
49+
<TabsContent value="tab2">
50+
<View style={styles.tabContent}>
51+
<Text style={styles.tabTitle}>Profile Tab</Text>
52+
<Text style={styles.tabText}>
53+
This is the content for the Profile tab. The content should take the full width available.
54+
</Text>
55+
</View>
56+
</TabsContent>
57+
58+
<TabsContent value="tab3">
59+
<View style={styles.tabContent}>
60+
<Text style={styles.tabTitle}>Settings Tab</Text>
61+
<Text style={styles.tabText}>
62+
This is the content for the Settings tab. All content should be properly sized and visible.
63+
</Text>
64+
</View>
65+
</TabsContent>
66+
</Tabs>
67+
</View>
68+
69+
{/* Example 2: Right aligned button */}
70+
{Platform.OS !== "web" && (
71+
<View style={styles.section}>
72+
<Text as="h3" style={styles.subTitle}>Example 2: Right Aligned Button</Text>
73+
<Text as="p" style={styles.description}>
74+
Button aligned to the right with auto width
75+
</Text>
76+
77+
<View style={styles.rightAlignedContainer}>
78+
<Tabs
79+
defaultValue="option1"
80+
alignment="right"
81+
style={styles.nativeTabsButtonAuto}
82+
backgroundColor="#F2F2F7"
83+
borderColor="#E5E5EA"
84+
cornerRadius={10}
85+
>
86+
<TabsList>
87+
<TabsTrigger value="option1" iosIcon="star.fill" androidIcon="star" icon="⭐">Option 1</TabsTrigger>
88+
<TabsTrigger value="option2" iosIcon="heart.fill" androidIcon="favorite" icon="❤️">Option 2</TabsTrigger>
89+
<TabsTrigger value="option3" iosIcon="bookmark.fill" androidIcon="bookmark" icon="🔖">Option 3</TabsTrigger>
90+
</TabsList>
91+
92+
<TabsContent value="option1">
93+
<View style={styles.tabContent}>
94+
<Text style={styles.tabTitle}>Option 1 Selected</Text>
95+
<Text style={styles.tabText}>
96+
The button is aligned to the right. The content below should take full width and be properly displayed.
97+
</Text>
98+
</View>
99+
</TabsContent>
100+
101+
<TabsContent value="option2">
102+
<View style={styles.tabContent}>
103+
<Text style={styles.tabTitle}>Option 2 Selected</Text>
104+
<Text style={styles.tabText}>
105+
The button is aligned to the right. The content below should take full width and be properly displayed.
106+
</Text>
107+
</View>
108+
</TabsContent>
109+
110+
<TabsContent value="option3">
111+
<View style={styles.tabContent}>
112+
<Text style={styles.tabTitle}>Option 3 Selected</Text>
113+
<Text style={styles.tabText}>
114+
The button is aligned to the right. The content below should take full width and be properly displayed.
115+
</Text>
116+
</View>
117+
</TabsContent>
118+
</Tabs>
119+
</View>
120+
</View>
121+
)}
122+
123+
{/* Example 3: Custom styling */}
124+
<View style={styles.section}>
125+
<Text as="h3" style={styles.subTitle}>Example 3: Custom Styled</Text>
126+
<Text as="p" style={styles.description}>
127+
Custom colors and styling with blue background
128+
</Text>
129+
130+
<Tabs
131+
defaultValue="home"
132+
backgroundColor={Platform.OS !== "web" ? "#007AFF" : undefined}
133+
textColor={Platform.OS !== "web" ? "#FFFFFF" : undefined}
134+
borderColor={Platform.OS !== "web" ? "#0051D5" : undefined}
135+
cornerRadius={Platform.OS !== "web" ? 20 : undefined}
136+
showChevron={Platform.OS !== "web" ? true : undefined}
137+
chevronIcon={Platform.OS !== "web" ? "arrow.down.circle.fill" : undefined}
138+
style={Platform.OS !== "web" ? styles.nativeTabsButton : undefined}
139+
>
140+
<TabsList>
141+
<TabsTrigger value="home" iosIcon="house.fill" androidIcon="home" icon="🏠">Home</TabsTrigger>
142+
<TabsTrigger value="search" iosIcon="magnifyingglass" androidIcon="search" icon="🔍">Search</TabsTrigger>
143+
<TabsTrigger value="profile" iosIcon="person.fill" androidIcon="person" icon="👤">Profile</TabsTrigger>
144+
</TabsList>
145+
146+
<TabsContent value="home">
147+
<View style={styles.tabContent}>
148+
<Text style={styles.tabTitle}>Home</Text>
149+
<Text style={styles.tabText}>
150+
Custom styled button with blue background. The content should be properly displayed with full width.
151+
</Text>
152+
</View>
153+
</TabsContent>
154+
155+
<TabsContent value="search">
156+
<View style={styles.tabContent}>
157+
<Text style={styles.tabTitle}>Search</Text>
158+
<Text style={styles.tabText}>
159+
Custom styled button with blue background. The content should be properly displayed with full width.
160+
</Text>
161+
</View>
162+
</TabsContent>
163+
164+
<TabsContent value="profile">
165+
<View style={styles.tabContent}>
166+
<Text style={styles.tabTitle}>Profile</Text>
167+
<Text style={styles.tabText}>
168+
Custom styled button with blue background. The content should be properly displayed with full width.
169+
</Text>
170+
</View>
171+
</TabsContent>
172+
</Tabs>
173+
</View>
174+
</View>
175+
</ScrollView>
176+
);
177+
}
178+
179+
const styles = StyleSheet.create({
180+
container: {
181+
flex: 1,
182+
backgroundColor: Platform.OS === "web" ? "#fff" : "#f2f2f7",
183+
},
184+
content: {
185+
...Platform.select({
186+
web: {
187+
maxWidth: 800,
188+
marginHorizontal: "auto",
189+
width: "100%",
190+
paddingHorizontal: 24,
191+
paddingVertical: 32,
192+
},
193+
default: {
194+
padding: 16,
195+
},
196+
}),
197+
},
198+
section: {
199+
marginBottom: 32,
200+
},
201+
sectionTitle: {
202+
fontSize: 24,
203+
fontWeight: "600",
204+
marginBottom: 8,
205+
color: "#000",
206+
},
207+
subTitle: {
208+
fontSize: 18,
209+
fontWeight: "600",
210+
marginBottom: 8,
211+
color: "#000",
212+
},
213+
description: {
214+
fontSize: 14,
215+
color: "#666",
216+
marginBottom: 16,
217+
lineHeight: 20,
218+
},
219+
tabContent: {
220+
padding: 16,
221+
backgroundColor: Platform.OS === "web" ? "#f9fafb" : "#fff",
222+
borderRadius: 8,
223+
marginTop: Platform.OS === "web" ? 16 : 0, // TabsContent already has marginTop on native
224+
},
225+
tabTitle: {
226+
fontSize: 18,
227+
fontWeight: "600",
228+
marginBottom: 8,
229+
color: "#000",
230+
},
231+
tabText: {
232+
fontSize: 14,
233+
color: "#666",
234+
lineHeight: 20,
235+
},
236+
nativeTabsButton: {
237+
height: 44,
238+
marginBottom: 16,
239+
width: "100%",
240+
},
241+
nativeTabsButtonAuto: {
242+
height: 44,
243+
marginBottom: 16,
244+
minWidth: 150,
245+
},
246+
rightAlignedContainer: {
247+
width: "100%",
248+
alignItems: "flex-end" as any,
249+
marginBottom: 16,
250+
alignSelf: "stretch" as any,
251+
},
252+
});

apps/website/.source/index.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
// @ts-nocheck -- skip type checking
2-
import * as docs_16 from "../docs/view.mdx?collection=docs"
3-
import * as docs_15 from "../docs/toggle.mdx?collection=docs"
4-
import * as docs_14 from "../docs/toggle-group.mdx?collection=docs"
5-
import * as docs_13 from "../docs/text.mdx?collection=docs"
6-
import * as docs_12 from "../docs/switch.mdx?collection=docs"
7-
import * as docs_11 from "../docs/switch-group.mdx?collection=docs"
8-
import * as docs_10 from "../docs/slot.mdx?collection=docs"
9-
import * as docs_9 from "../docs/portal.mdx?collection=docs"
10-
import * as docs_8 from "../docs/index.mdx?collection=docs"
11-
import * as docs_7 from "../docs/context-menu.mdx?collection=docs"
12-
import * as docs_6 from "../docs/collapsible.mdx?collection=docs"
13-
import * as docs_5 from "../docs/checkbox.mdx?collection=docs"
14-
import * as docs_4 from "../docs/checkbox-group.mdx?collection=docs"
15-
import * as docs_3 from "../docs/avatar.mdx?collection=docs"
16-
import * as docs_2 from "../docs/aspect-ratio.mdx?collection=docs"
17-
import * as docs_1 from "../docs/alert.mdx?collection=docs"
2+
import * as docs_20 from "../docs/view.mdx?collection=docs"
3+
import * as docs_19 from "../docs/toggle.mdx?collection=docs"
4+
import * as docs_18 from "../docs/toggle-group.mdx?collection=docs"
5+
import * as docs_17 from "../docs/text.mdx?collection=docs"
6+
import * as docs_16 from "../docs/switch.mdx?collection=docs"
7+
import * as docs_15 from "../docs/switch-group.mdx?collection=docs"
8+
import * as docs_14 from "../docs/slot.mdx?collection=docs"
9+
import * as docs_13 from "../docs/radiogroup.mdx?collection=docs"
10+
import * as docs_12 from "../docs/radio.mdx?collection=docs"
11+
import * as docs_11 from "../docs/portal.mdx?collection=docs"
12+
import * as docs_10 from "../docs/index.mdx?collection=docs"
13+
import * as docs_9 from "../docs/drawer.mdx?collection=docs"
14+
import * as docs_8 from "../docs/context-menu.mdx?collection=docs"
15+
import * as docs_7 from "../docs/collapsible.mdx?collection=docs"
16+
import * as docs_6 from "../docs/checkbox.mdx?collection=docs"
17+
import * as docs_5 from "../docs/checkbox-group.mdx?collection=docs"
18+
import * as docs_4 from "../docs/avatar.mdx?collection=docs"
19+
import * as docs_3 from "../docs/aspect-ratio.mdx?collection=docs"
20+
import * as docs_2 from "../docs/alert.mdx?collection=docs"
21+
import * as docs_1 from "../docs/activity-view.mdx?collection=docs"
1822
import * as docs_0 from "../docs/accordion.mdx?collection=docs"
1923
import { _runtime } from "fumadocs-mdx/runtime/next"
2024
import * as _source from "../source.config"
21-
export const docs = _runtime.docs<typeof _source.docs>([{ info: {"path":"accordion.mdx","fullPath":"docs/accordion.mdx"}, data: docs_0 }, { info: {"path":"alert.mdx","fullPath":"docs/alert.mdx"}, data: docs_1 }, { info: {"path":"aspect-ratio.mdx","fullPath":"docs/aspect-ratio.mdx"}, data: docs_2 }, { info: {"path":"avatar.mdx","fullPath":"docs/avatar.mdx"}, data: docs_3 }, { info: {"path":"checkbox-group.mdx","fullPath":"docs/checkbox-group.mdx"}, data: docs_4 }, { info: {"path":"checkbox.mdx","fullPath":"docs/checkbox.mdx"}, data: docs_5 }, { info: {"path":"collapsible.mdx","fullPath":"docs/collapsible.mdx"}, data: docs_6 }, { info: {"path":"context-menu.mdx","fullPath":"docs/context-menu.mdx"}, data: docs_7 }, { info: {"path":"index.mdx","fullPath":"docs/index.mdx"}, data: docs_8 }, { info: {"path":"portal.mdx","fullPath":"docs/portal.mdx"}, data: docs_9 }, { info: {"path":"slot.mdx","fullPath":"docs/slot.mdx"}, data: docs_10 }, { info: {"path":"switch-group.mdx","fullPath":"docs/switch-group.mdx"}, data: docs_11 }, { info: {"path":"switch.mdx","fullPath":"docs/switch.mdx"}, data: docs_12 }, { info: {"path":"text.mdx","fullPath":"docs/text.mdx"}, data: docs_13 }, { info: {"path":"toggle-group.mdx","fullPath":"docs/toggle-group.mdx"}, data: docs_14 }, { info: {"path":"toggle.mdx","fullPath":"docs/toggle.mdx"}, data: docs_15 }, { info: {"path":"view.mdx","fullPath":"docs/view.mdx"}, data: docs_16 }], [])
25+
export const docs = _runtime.docs<typeof _source.docs>([{ info: {"path":"accordion.mdx","fullPath":"docs/accordion.mdx"}, data: docs_0 }, { info: {"path":"activity-view.mdx","fullPath":"docs/activity-view.mdx"}, data: docs_1 }, { info: {"path":"alert.mdx","fullPath":"docs/alert.mdx"}, data: docs_2 }, { info: {"path":"aspect-ratio.mdx","fullPath":"docs/aspect-ratio.mdx"}, data: docs_3 }, { info: {"path":"avatar.mdx","fullPath":"docs/avatar.mdx"}, data: docs_4 }, { info: {"path":"checkbox-group.mdx","fullPath":"docs/checkbox-group.mdx"}, data: docs_5 }, { info: {"path":"checkbox.mdx","fullPath":"docs/checkbox.mdx"}, data: docs_6 }, { info: {"path":"collapsible.mdx","fullPath":"docs/collapsible.mdx"}, data: docs_7 }, { info: {"path":"context-menu.mdx","fullPath":"docs/context-menu.mdx"}, data: docs_8 }, { info: {"path":"drawer.mdx","fullPath":"docs/drawer.mdx"}, data: docs_9 }, { info: {"path":"index.mdx","fullPath":"docs/index.mdx"}, data: docs_10 }, { info: {"path":"portal.mdx","fullPath":"docs/portal.mdx"}, data: docs_11 }, { info: {"path":"radio.mdx","fullPath":"docs/radio.mdx"}, data: docs_12 }, { info: {"path":"radiogroup.mdx","fullPath":"docs/radiogroup.mdx"}, data: docs_13 }, { info: {"path":"slot.mdx","fullPath":"docs/slot.mdx"}, data: docs_14 }, { info: {"path":"switch-group.mdx","fullPath":"docs/switch-group.mdx"}, data: docs_15 }, { info: {"path":"switch.mdx","fullPath":"docs/switch.mdx"}, data: docs_16 }, { info: {"path":"text.mdx","fullPath":"docs/text.mdx"}, data: docs_17 }, { info: {"path":"toggle-group.mdx","fullPath":"docs/toggle-group.mdx"}, data: docs_18 }, { info: {"path":"toggle.mdx","fullPath":"docs/toggle.mdx"}, data: docs_19 }, { info: {"path":"view.mdx","fullPath":"docs/view.mdx"}, data: docs_20 }], [])
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package expo.modules.nativeuiorgnativemodules.tabs
2+
3+
import expo.modules.kotlin.modules.Module
4+
import expo.modules.kotlin.modules.ModuleDefinition
5+
6+
class NativeUiOrgTabsModule : Module() {
7+
override fun definition() = ModuleDefinition {
8+
Name("NativeUiOrgTabs")
9+
10+
// Define the native view component
11+
View(NativeUiOrgTabsView::class) {
12+
// Props
13+
Prop("tabs") { view: NativeUiOrgTabsView, items: List<Map<String, Any>> ->
14+
view.setTabs(items)
15+
}
16+
17+
Prop("selectedValue") { view: NativeUiOrgTabsView, value: String ->
18+
view.setSelectedValue(value)
19+
}
20+
21+
// Events
22+
Events("onValueChange")
23+
}
24+
}
25+
}
26+

0 commit comments

Comments
 (0)