@startupjs-ui/tabs 0.1.3

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/Bar/index.tsx ADDED
@@ -0,0 +1,43 @@
1
+ import { type ReactNode } from 'react'
2
+ import { TabBar } from 'react-native-tab-view'
3
+ import { pug, observer } from 'startupjs'
4
+
5
+ export const TAB_BAR_PROP_NAMES = [
6
+ 'getLabelText',
7
+ 'getAccessible',
8
+ 'getAccessibilityLabel',
9
+ 'getTestID',
10
+ 'renderIcon',
11
+ 'renderTabBarItem',
12
+ 'renderLabel',
13
+ 'renderIndicator',
14
+ 'renderBadge',
15
+ 'onTabPress',
16
+ 'onTabLongPress',
17
+ 'activeColor',
18
+ 'inactiveColor',
19
+ 'pressColor',
20
+ 'pressOpacity',
21
+ 'scrollEnabled',
22
+ 'bounces',
23
+ 'tabStyle',
24
+ 'indicatorStyle',
25
+ 'indicatorContainerStyle',
26
+ 'labelStyle',
27
+ 'contentContainerStyle',
28
+ 'style'
29
+ ] as const
30
+
31
+ export type BarProps = Record<string, any>
32
+
33
+ function Bar ({
34
+ ...props
35
+ }: BarProps): ReactNode {
36
+ return pug`
37
+ TabBar(...props)
38
+ `
39
+ }
40
+
41
+ const ObservedBar: any = observer(Bar)
42
+
43
+ export default ObservedBar
package/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.1.3](https://github.com/startupjs/startupjs-ui/compare/v0.1.2...v0.1.3) (2025-12-29)
7
+
8
+ **Note:** Version bump only for package @startupjs-ui/tabs
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.1.2](https://github.com/startupjs/startupjs-ui/compare/v0.1.1...v0.1.2) (2025-12-29)
15
+
16
+
17
+ ### Features
18
+
19
+ * add mdx and docs packages. Refactor docs to get rid of any @startupjs/ui usage and use startupjs-ui instead ([703c926](https://github.com/startupjs/startupjs-ui/commit/703c92636efb0421ffd11783f692fc892b74018f))
20
+ * **tabs:** refactor Tabs component ([a3198d0](https://github.com/startupjs/startupjs-ui/commit/a3198d079d93a3206942ae20972f3998ed77b25c))
package/README.mdx ADDED
@@ -0,0 +1,95 @@
1
+ import { useState } from 'react'
2
+ import Div from '@startupjs-ui/div'
3
+ import Tabs, { _PropsJsonSchema as TabsPropsJsonSchema } from './index'
4
+ import { Sandbox } from '@startupjs-ui/docs'
5
+
6
+ # Tabs
7
+
8
+ Inherits [react-native-tab-view](https://github.com/satya164/react-native-tab-view) with some changes:
9
+
10
+ - `navigationState` property is replaced to properties `routes` and `$value`, where:
11
+ - `routes` is have the same structure as `navigationState.routes`
12
+ - `$value` is the scoped model, to make tabs controlled (by omitting this property the tabs will be uncontrolled)
13
+ - added property `initialKey` to set default tab
14
+ - added property `onChange` that responds to tab change instead of `onIndexChange`
15
+ - all props for [TabBar](https://github.com/satya164/react-native-tab-view#tabbar) can be assigned to `Tabs` component
16
+
17
+ Tabs allow you to switch between different views.
18
+
19
+ ```jsx
20
+ import { Tabs } from 'startupjs-ui'
21
+ ```
22
+
23
+ ## Tabs.Bar
24
+ Use component `Tabs.Bar` in the `renderTabBar` function if you want to make a custom `TabBar`
25
+
26
+ ## Simple example
27
+
28
+ ```jsx example noscroll
29
+ const [routes] = useState([
30
+ { key: 'first', title: 'First' },
31
+ { key: 'second', title: 'Second' },
32
+ ])
33
+
34
+ const FirstRoute = () => (
35
+ <Div style={{ height: 250, backgroundColor: '#ff4081' }} />
36
+ )
37
+
38
+ const SecondRoute = () => (
39
+ <Div style={{ height: 250, backgroundColor: '#673ab7' }} />
40
+ )
41
+
42
+ function renderScene ({ route }) {
43
+ switch (route.key) {
44
+ case 'first':
45
+ return <FirstRoute />;
46
+ case 'second':
47
+ return <SecondRoute />;
48
+ }
49
+ }
50
+
51
+ return (
52
+ <Tabs
53
+ routes={routes}
54
+ renderScene={renderScene}
55
+ />
56
+ )
57
+ ```
58
+
59
+ ## Sandbox
60
+
61
+ <Sandbox
62
+ Component={Tabs}
63
+ propsJsonSchema={TabsPropsJsonSchema}
64
+ props={(() => {
65
+ const routes = [
66
+ { key: 'first', title: 'First' },
67
+ { key: 'second', title: 'Second' }
68
+ ]
69
+
70
+ const FirstRoute = () => (
71
+ <Div style={{ height: 100, backgroundColor: '#ff4081' }} />
72
+ )
73
+
74
+ const SecondRoute = () => (
75
+ <Div style={{ height: 100, backgroundColor: '#673ab7' }} />
76
+ )
77
+
78
+ function renderScene ({ route }) {
79
+ switch (route.key) {
80
+ case 'first':
81
+ return <FirstRoute />
82
+ case 'second':
83
+ return <SecondRoute />
84
+ default:
85
+ return null
86
+ }
87
+ }
88
+
89
+ return {
90
+ routes,
91
+ renderScene
92
+ }
93
+ })()}
94
+ noScroll
95
+ />
package/index.d.ts ADDED
@@ -0,0 +1,100 @@
1
+ /* eslint-disable */
2
+ // DO NOT MODIFY THIS FILE - IT IS AUTOMATICALLY GENERATED ON COMMITS.
3
+
4
+ import { type ReactNode } from 'react';
5
+ import { type StyleProp, type ViewStyle } from 'react-native';
6
+ export declare const _PropsJsonSchema: {};
7
+ export interface TabsProps {
8
+ /** Tabs configuration containing keys and titles */
9
+ routes: TabsRoute[];
10
+ /** Key of the initially active tab when uncontrolled */
11
+ initialKey?: string;
12
+ /** Scoped model controlling the active tab key */
13
+ $value?: any;
14
+ /** Handler called when active tab changes with the new key */
15
+ onChange?: (key: string) => void;
16
+ /** Handler called when the tab index changes @deprecated use onChange instead */
17
+ onIndexChange?: (index: number) => void;
18
+ /** Custom TabBar renderer */
19
+ renderTabBar?: (props: any) => ReactNode;
20
+ /** Custom navigation state passed directly to TabView */
21
+ navigationState?: any;
22
+ /** Scene renderer returning content for each route */
23
+ renderScene?: (props: any) => ReactNode;
24
+ /** Initial layout configuration passed to TabView */
25
+ initialLayout?: any;
26
+ /** Controls keyboard dismiss mode for TabView */
27
+ keyboardDismissMode?: string;
28
+ /** Enable lazy rendering for scenes */
29
+ lazy?: boolean;
30
+ /** Distance of routes to preload while lazy loading */
31
+ lazyPreloadDistance?: number;
32
+ /** Called when swipe gesture starts */
33
+ onSwipeStart?: () => void;
34
+ /** Called when swipe gesture ends */
35
+ onSwipeEnd?: () => void;
36
+ /** Placeholder renderer while lazy loading scenes */
37
+ renderLazyPlaceholder?: (props: any) => ReactNode;
38
+ /** Style applied to scene container */
39
+ sceneContainerStyle?: StyleProp<ViewStyle>;
40
+ /** Custom styles applied to the root TabView */
41
+ style?: StyleProp<ViewStyle>;
42
+ /** Deprecated alias for style applied to TabView root */
43
+ tabsStyle?: StyleProp<ViewStyle>;
44
+ /** Allow switching tabs with swipe gestures */
45
+ swipeEnabled?: boolean;
46
+ /** Position of the tab bar */
47
+ tabBarPosition?: 'top' | 'bottom';
48
+ /** Function returning label text for a route */
49
+ getLabelText?: (scene: any) => any;
50
+ /** Function returning accessibility flag for a route */
51
+ getAccessible?: (scene: any) => any;
52
+ /** Function returning accessibility label for a route */
53
+ getAccessibilityLabel?: (scene: any) => any;
54
+ /** Function returning testID for a route */
55
+ getTestID?: (scene: any) => any;
56
+ /** Custom icon renderer for the tab bar */
57
+ renderIcon?: (props: any) => ReactNode;
58
+ /** Custom renderer for tab bar items */
59
+ renderTabBarItem?: (props: any) => ReactNode;
60
+ /** DEPRECATED and won't work! Use renderTabBarItem instead @deprecated */
61
+ renderLabel?: (props: any) => ReactNode;
62
+ /** Custom indicator renderer */
63
+ renderIndicator?: (props: any) => ReactNode;
64
+ /** Custom badge renderer */
65
+ renderBadge?: (props: any) => ReactNode;
66
+ /** Tab press handler */
67
+ onTabPress?: (props: any) => void;
68
+ /** Tab long-press handler */
69
+ onTabLongPress?: (props: any) => void;
70
+ /** Active label color @default 'primary' */
71
+ activeColor?: string;
72
+ /** Inactive label color @default 'text-description' */
73
+ inactiveColor?: string;
74
+ /** Ripple color for pressed tab */
75
+ pressColor?: string;
76
+ /** Ripple opacity for pressed tab */
77
+ pressOpacity?: number;
78
+ /** Allow scrolling tabs when they overflow */
79
+ scrollEnabled?: boolean;
80
+ /** Enable bounce effect for scrollable tabs */
81
+ bounces?: boolean;
82
+ /** Style applied to individual tabs */
83
+ tabStyle?: StyleProp<ViewStyle>;
84
+ /** Style applied to the indicator */
85
+ indicatorStyle?: StyleProp<ViewStyle>;
86
+ /** Style applied to indicator container */
87
+ indicatorContainerStyle?: StyleProp<ViewStyle>;
88
+ /** Style applied to tab labels */
89
+ labelStyle?: StyleProp<ViewStyle>;
90
+ /** Style applied to tab bar content container */
91
+ contentContainerStyle?: StyleProp<ViewStyle>;
92
+ }
93
+ export interface TabsRoute {
94
+ /** Route key used to identify the tab */
95
+ key: string;
96
+ /** Visible title displayed in the tab bar */
97
+ title: string;
98
+ }
99
+ declare const ObservedTabs: any;
100
+ export default ObservedTabs;
package/index.tsx ADDED
@@ -0,0 +1,191 @@
1
+ import { type ReactNode } from 'react'
2
+ import { type StyleProp, type ViewStyle } from 'react-native'
3
+ import { TabView } from 'react-native-tab-view'
4
+ import { pug, styl, observer, $ } from 'startupjs'
5
+ import { themed, useColors } from '@startupjs-ui/core'
6
+ import findIndex from 'lodash/findIndex'
7
+ import pick from 'lodash/pick'
8
+ import Bar, { TAB_BAR_PROP_NAMES } from './Bar'
9
+
10
+ export const _PropsJsonSchema = {/* TabsProps */} // used in docs generation
11
+
12
+ const TAB_VIEW_PROP_NAMES = [
13
+ 'navigationState',
14
+ 'renderScene',
15
+ 'initialLayout',
16
+ 'keyboardDismissMode',
17
+ 'lazy',
18
+ 'lazyPreloadDistance',
19
+ 'onSwipeStart',
20
+ 'onSwipeEnd',
21
+ 'renderLazyPlaceholder',
22
+ 'sceneContainerStyle',
23
+ 'style',
24
+ 'swipeEnabled',
25
+ 'tabBarPosition'
26
+ ]
27
+
28
+ export interface TabsProps {
29
+ /** Tabs configuration containing keys and titles */
30
+ routes: TabsRoute[]
31
+ /** Key of the initially active tab when uncontrolled */
32
+ initialKey?: string
33
+ /** Scoped model controlling the active tab key */
34
+ $value?: any
35
+ /** Handler called when active tab changes with the new key */
36
+ onChange?: (key: string) => void
37
+ /** Handler called when the tab index changes @deprecated use onChange instead */
38
+ onIndexChange?: (index: number) => void
39
+ /** Custom TabBar renderer */
40
+ renderTabBar?: (props: any) => ReactNode
41
+ /** Custom navigation state passed directly to TabView */
42
+ navigationState?: any
43
+ /** Scene renderer returning content for each route */
44
+ renderScene?: (props: any) => ReactNode
45
+ /** Initial layout configuration passed to TabView */
46
+ initialLayout?: any
47
+ /** Controls keyboard dismiss mode for TabView */
48
+ keyboardDismissMode?: string
49
+ /** Enable lazy rendering for scenes */
50
+ lazy?: boolean
51
+ /** Distance of routes to preload while lazy loading */
52
+ lazyPreloadDistance?: number
53
+ /** Called when swipe gesture starts */
54
+ onSwipeStart?: () => void
55
+ /** Called when swipe gesture ends */
56
+ onSwipeEnd?: () => void
57
+ /** Placeholder renderer while lazy loading scenes */
58
+ renderLazyPlaceholder?: (props: any) => ReactNode
59
+ /** Style applied to scene container */
60
+ sceneContainerStyle?: StyleProp<ViewStyle>
61
+ /** Custom styles applied to the root TabView */
62
+ style?: StyleProp<ViewStyle>
63
+ /** Deprecated alias for style applied to TabView root */
64
+ tabsStyle?: StyleProp<ViewStyle>
65
+ /** Allow switching tabs with swipe gestures */
66
+ swipeEnabled?: boolean
67
+ /** Position of the tab bar */
68
+ tabBarPosition?: 'top' | 'bottom'
69
+ /** Function returning label text for a route */
70
+ getLabelText?: (scene: any) => any
71
+ /** Function returning accessibility flag for a route */
72
+ getAccessible?: (scene: any) => any
73
+ /** Function returning accessibility label for a route */
74
+ getAccessibilityLabel?: (scene: any) => any
75
+ /** Function returning testID for a route */
76
+ getTestID?: (scene: any) => any
77
+ /** Custom icon renderer for the tab bar */
78
+ renderIcon?: (props: any) => ReactNode
79
+ /** Custom renderer for tab bar items */
80
+ renderTabBarItem?: (props: any) => ReactNode
81
+ /** DEPRECATED and won't work! Use renderTabBarItem instead @deprecated */
82
+ renderLabel?: (props: any) => ReactNode
83
+ /** Custom indicator renderer */
84
+ renderIndicator?: (props: any) => ReactNode
85
+ /** Custom badge renderer */
86
+ renderBadge?: (props: any) => ReactNode
87
+ /** Tab press handler */
88
+ onTabPress?: (props: any) => void
89
+ /** Tab long-press handler */
90
+ onTabLongPress?: (props: any) => void
91
+ /** Active label color @default 'primary' */
92
+ activeColor?: string
93
+ /** Inactive label color @default 'text-description' */
94
+ inactiveColor?: string
95
+ /** Ripple color for pressed tab */
96
+ pressColor?: string
97
+ /** Ripple opacity for pressed tab */
98
+ pressOpacity?: number
99
+ /** Allow scrolling tabs when they overflow */
100
+ scrollEnabled?: boolean
101
+ /** Enable bounce effect for scrollable tabs */
102
+ bounces?: boolean
103
+ /** Style applied to individual tabs */
104
+ tabStyle?: StyleProp<ViewStyle>
105
+ /** Style applied to the indicator */
106
+ indicatorStyle?: StyleProp<ViewStyle>
107
+ /** Style applied to indicator container */
108
+ indicatorContainerStyle?: StyleProp<ViewStyle>
109
+ /** Style applied to tab labels */
110
+ labelStyle?: StyleProp<ViewStyle>
111
+ /** Style applied to tab bar content container */
112
+ contentContainerStyle?: StyleProp<ViewStyle>
113
+ }
114
+
115
+ export interface TabsRoute {
116
+ /** Route key used to identify the tab */
117
+ key: string
118
+ /** Visible title displayed in the tab bar */
119
+ title: string
120
+ }
121
+
122
+ function Tabs ({
123
+ tabsStyle,
124
+ routes,
125
+ initialKey,
126
+ $value,
127
+ renderTabBar,
128
+ renderLabel, // deprecated and won't work. Throw an error to inform the user
129
+ activeColor = 'primary',
130
+ inactiveColor = 'text-description',
131
+ onChange,
132
+ onIndexChange, // skip property
133
+ ...props
134
+ }: TabsProps): ReactNode {
135
+ if (renderLabel) throw Error('[@startupjs/ui -> Tabs] `renderLabel` prop is deprecated and no longer supported. Use `renderTabBarItem` instead.')
136
+ if (tabsStyle) console.warn('[@startupjs/ui -> Tabs] `tabsStyle` prop is deprecated. Use `style` instead.')
137
+
138
+ const getColor = useColors()
139
+ const $localValue = $value ?? $(initialKey ?? routes[0]?.key)
140
+ const tabBarProps = pick(props, TAB_BAR_PROP_NAMES)
141
+ const tabViewProps = pick(props, TAB_VIEW_PROP_NAMES)
142
+
143
+ const tabIndex = findIndex(routes, { key: $localValue.get() })
144
+
145
+ function _renderTabBar (tabBarViewProps: any): ReactNode {
146
+ if (renderTabBar) return renderTabBar(tabBarViewProps)
147
+
148
+ return pug`
149
+ Bar.bar(
150
+ activeColor=getColor(activeColor) ?? activeColor
151
+ inactiveColor=getColor(inactiveColor) ?? inactiveColor
152
+ ...tabBarProps
153
+ ...tabBarViewProps
154
+ )
155
+ `
156
+ }
157
+
158
+ function _onIndexChange (index: number) {
159
+ const key = routes[index].key
160
+ onChange
161
+ ? onChange(key)
162
+ : $localValue.set(key)
163
+ }
164
+
165
+ return pug`
166
+ TabView(
167
+ part='root'
168
+ style=tabsStyle
169
+ navigationState={ index: tabIndex, routes }
170
+ renderTabBar=_renderTabBar
171
+ onIndexChange=_onIndexChange
172
+ ...tabViewProps
173
+ )
174
+ `
175
+ styl`
176
+ .bar
177
+ background-color transparent
178
+ &:part(indicator)
179
+ background-color var(--color-bg-primary)
180
+
181
+ .label
182
+ &.focused
183
+ color var(--color-primary)
184
+ `
185
+ }
186
+
187
+ const ObservedTabs: any = observer(themed('Tabs', Tabs))
188
+
189
+ ObservedTabs.Bar = Bar
190
+
191
+ export default ObservedTabs
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@startupjs-ui/tabs",
3
+ "version": "0.1.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "index.tsx",
8
+ "types": "index.d.ts",
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@startupjs-ui/core": "^0.1.3",
12
+ "react-native-tab-view": "^4.1.2"
13
+ },
14
+ "peerDependencies": {
15
+ "react": "*",
16
+ "react-native": "*",
17
+ "react-native-pager-view": "*",
18
+ "startupjs": "*"
19
+ },
20
+ "gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
21
+ }