@delacour/react-native-ui 0.1.0-alpha.20260925053522
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/package.json +125 -0
- package/src/components/accordion/AGENTS.md +193 -0
- package/src/components/accordion/accordion-content.tsx +125 -0
- package/src/components/accordion/accordion-description.tsx +17 -0
- package/src/components/accordion/accordion-indicator.tsx +104 -0
- package/src/components/accordion/accordion-item.tsx +78 -0
- package/src/components/accordion/accordion-title.tsx +18 -0
- package/src/components/accordion/accordion-trigger.tsx +148 -0
- package/src/components/accordion/accordion.context.tsx +153 -0
- package/src/components/accordion/accordion.tsx +253 -0
- package/src/components/accordion/accordion.types.ts +11 -0
- package/src/components/accordion/accordion.variants.test.ts +434 -0
- package/src/components/accordion/accordion.variants.ts +358 -0
- package/src/components/accordion/index.ts +45 -0
- package/src/components/badge/AGENTS.md +83 -0
- package/src/components/badge/badge-close-button.tsx +48 -0
- package/src/components/badge/badge-end-content.tsx +15 -0
- package/src/components/badge/badge-label.tsx +24 -0
- package/src/components/badge/badge-start-content.tsx +16 -0
- package/src/components/badge/badge.context.tsx +64 -0
- package/src/components/badge/badge.tsx +192 -0
- package/src/components/badge/badge.types.ts +10 -0
- package/src/components/badge/badge.variants.test.ts +269 -0
- package/src/components/badge/badge.variants.ts +238 -0
- package/src/components/badge/index.ts +17 -0
- package/src/components/bottom-sheet/AGENTS.md +242 -0
- package/src/components/bottom-sheet/bottom-sheet-background.tsx +35 -0
- package/src/components/bottom-sheet/bottom-sheet-close.tsx +60 -0
- package/src/components/bottom-sheet/bottom-sheet-container.tsx +246 -0
- package/src/components/bottom-sheet/bottom-sheet-content.tsx +66 -0
- package/src/components/bottom-sheet/bottom-sheet-description.tsx +29 -0
- package/src/components/bottom-sheet/bottom-sheet-footer.tsx +150 -0
- package/src/components/bottom-sheet/bottom-sheet-handle.tsx +47 -0
- package/src/components/bottom-sheet/bottom-sheet-overlay.tsx +180 -0
- package/src/components/bottom-sheet/bottom-sheet-portal.tsx +72 -0
- package/src/components/bottom-sheet/bottom-sheet-scroll-view.tsx +105 -0
- package/src/components/bottom-sheet/bottom-sheet-title.tsx +24 -0
- package/src/components/bottom-sheet/bottom-sheet-trigger.tsx +73 -0
- package/src/components/bottom-sheet/bottom-sheet.context.tsx +135 -0
- package/src/components/bottom-sheet/bottom-sheet.tsx +125 -0
- package/src/components/bottom-sheet/bottom-sheet.variants.test.ts +293 -0
- package/src/components/bottom-sheet/bottom-sheet.variants.ts +220 -0
- package/src/components/bottom-sheet/index.ts +40 -0
- package/src/components/bottom-sheet/use-bottom-sheet-input.ts +125 -0
- package/src/components/button/AGENTS.md +217 -0
- package/src/components/button/button-end-content.tsx +15 -0
- package/src/components/button/button-group-separator.tsx +37 -0
- package/src/components/button/button-group-text.tsx +101 -0
- package/src/components/button/button-group.tsx +158 -0
- package/src/components/button/button-label.tsx +24 -0
- package/src/components/button/button-start-content.tsx +15 -0
- package/src/components/button/button.context.tsx +187 -0
- package/src/components/button/button.tsx +273 -0
- package/src/components/button/button.types.ts +10 -0
- package/src/components/button/button.variants.test.ts +811 -0
- package/src/components/button/button.variants.ts +480 -0
- package/src/components/button/index.ts +50 -0
- package/src/components/chart/AGENTS.md +210 -0
- package/src/components/chart/chart-area.tsx +93 -0
- package/src/components/chart/chart-bar.tsx +103 -0
- package/src/components/chart/chart-bars.tsx +75 -0
- package/src/components/chart/chart-candlestick.tsx +60 -0
- package/src/components/chart/chart-grid.tsx +33 -0
- package/src/components/chart/chart-legend.tsx +41 -0
- package/src/components/chart/chart-line.tsx +50 -0
- package/src/components/chart/chart-scatter.tsx +35 -0
- package/src/components/chart/chart-tooltip-dot.tsx +70 -0
- package/src/components/chart/chart-tooltip-x.tsx +121 -0
- package/src/components/chart/chart-tooltip-y.tsx +55 -0
- package/src/components/chart/chart-tooltip.tsx +133 -0
- package/src/components/chart/chart-x-axis.tsx +27 -0
- package/src/components/chart/chart-y-axis.tsx +21 -0
- package/src/components/chart/chart.context.tsx +127 -0
- package/src/components/chart/chart.tsx +448 -0
- package/src/components/chart/chart.types.ts +108 -0
- package/src/components/chart/chart.variants.test.ts +893 -0
- package/src/components/chart/chart.variants.ts +726 -0
- package/src/components/chart/index.ts +103 -0
- package/src/components/chart/pie-chart-center.tsx +40 -0
- package/src/components/chart/pie-chart-label.tsx +56 -0
- package/src/components/chart/pie-chart-slice.tsx +45 -0
- package/src/components/chart/pie-chart-tooltip.tsx +85 -0
- package/src/components/chart/pie-chart.context.tsx +77 -0
- package/src/components/chart/pie-chart.tsx +247 -0
- package/src/components/chart/use-chart-font.ts +25 -0
- package/src/components/chart/use-chart-palette.ts +38 -0
- package/src/components/checkbox/AGENTS.md +185 -0
- package/src/components/checkbox/checkbox-box.tsx +152 -0
- package/src/components/checkbox/checkbox-group.tsx +107 -0
- package/src/components/checkbox/checkbox-label.tsx +34 -0
- package/src/components/checkbox/checkbox.context.tsx +136 -0
- package/src/components/checkbox/checkbox.tsx +258 -0
- package/src/components/checkbox/checkbox.types.ts +14 -0
- package/src/components/checkbox/checkbox.variants.test.ts +634 -0
- package/src/components/checkbox/checkbox.variants.ts +484 -0
- package/src/components/checkbox/index.ts +42 -0
- package/src/components/field/AGENTS.md +112 -0
- package/src/components/field/field-content.tsx +24 -0
- package/src/components/field/field-description.tsx +29 -0
- package/src/components/field/field-error.tsx +61 -0
- package/src/components/field/field-group.tsx +22 -0
- package/src/components/field/field-label.tsx +47 -0
- package/src/components/field/field-legend.tsx +34 -0
- package/src/components/field/field-separator.tsx +81 -0
- package/src/components/field/field-set.tsx +22 -0
- package/src/components/field/field.context.tsx +95 -0
- package/src/components/field/field.tsx +157 -0
- package/src/components/field/field.types.ts +15 -0
- package/src/components/field/field.variants.test.ts +240 -0
- package/src/components/field/field.variants.ts +156 -0
- package/src/components/field/index.ts +22 -0
- package/src/components/icon/AGENTS.md +104 -0
- package/src/components/icon/icon.context.tsx +29 -0
- package/src/components/icon/icon.tsx +92 -0
- package/src/components/icon/icon.variants.test.ts +111 -0
- package/src/components/icon/icon.variants.ts +79 -0
- package/src/components/icon/index.ts +11 -0
- package/src/components/input/AGENTS.md +126 -0
- package/src/components/input/index.ts +27 -0
- package/src/components/input/input-group-decorator.tsx +84 -0
- package/src/components/input/input-group-prefix.tsx +16 -0
- package/src/components/input/input-group-suffix.tsx +15 -0
- package/src/components/input/input-group.tsx +140 -0
- package/src/components/input/input.context.tsx +87 -0
- package/src/components/input/input.tsx +184 -0
- package/src/components/input/input.types.ts +10 -0
- package/src/components/input/input.variants.test.ts +369 -0
- package/src/components/input/input.variants.ts +329 -0
- package/src/components/list-group/AGENTS.md +67 -0
- package/src/components/list-group/index.ts +20 -0
- package/src/components/list-group/list-group-item-content.tsx +10 -0
- package/src/components/list-group/list-group-item-description.tsx +12 -0
- package/src/components/list-group/list-group-item-prefix.tsx +30 -0
- package/src/components/list-group/list-group-item-suffix.tsx +55 -0
- package/src/components/list-group/list-group-item-title.tsx +17 -0
- package/src/components/list-group/list-group-item.tsx +87 -0
- package/src/components/list-group/list-group.context.tsx +65 -0
- package/src/components/list-group/list-group.tsx +116 -0
- package/src/components/list-group/list-group.types.ts +14 -0
- package/src/components/list-group/list-group.variants.test.ts +223 -0
- package/src/components/list-group/list-group.variants.ts +107 -0
- package/src/components/pressable/AGENTS.md +74 -0
- package/src/components/pressable/index.ts +9 -0
- package/src/components/pressable/pressable.tsx +261 -0
- package/src/components/pressable/pressable.variants.test.ts +128 -0
- package/src/components/pressable/pressable.variants.ts +80 -0
- package/src/components/provider/AGENTS.md +90 -0
- package/src/components/provider/index.ts +1 -0
- package/src/components/provider/provider.tsx +105 -0
- package/src/components/radio/AGENTS.md +245 -0
- package/src/components/radio/index.ts +35 -0
- package/src/components/radio/radio-group.tsx +126 -0
- package/src/components/radio/radio-indicator.tsx +91 -0
- package/src/components/radio/radio-label.tsx +39 -0
- package/src/components/radio/radio.context.tsx +132 -0
- package/src/components/radio/radio.tsx +215 -0
- package/src/components/radio/radio.variants.test.ts +580 -0
- package/src/components/radio/radio.variants.ts +271 -0
- package/src/components/screen/AGENTS.md +287 -0
- package/src/components/screen/index.ts +85 -0
- package/src/components/screen/screen-chat-list.tsx +485 -0
- package/src/components/screen/screen-content.tsx +69 -0
- package/src/components/screen/screen-debug.ts +43 -0
- package/src/components/screen/screen-error.tsx +61 -0
- package/src/components/screen/screen-flat-list.tsx +88 -0
- package/src/components/screen/screen-footer-background.tsx +60 -0
- package/src/components/screen/screen-footer.tsx +170 -0
- package/src/components/screen/screen-header.tsx +36 -0
- package/src/components/screen/screen-legend-list.tsx +105 -0
- package/src/components/screen/screen-list-component.tsx +23 -0
- package/src/components/screen/screen-loading.tsx +50 -0
- package/src/components/screen/screen-navbar-back-button.tsx +79 -0
- package/src/components/screen/screen-navbar-background.tsx +45 -0
- package/src/components/screen/screen-navbar-subtitle.tsx +26 -0
- package/src/components/screen/screen-navbar-title.tsx +31 -0
- package/src/components/screen/screen-navbar.tsx +154 -0
- package/src/components/screen/screen-root.tsx +38 -0
- package/src/components/screen/screen-scroll-area.tsx +116 -0
- package/src/components/screen/screen-scroll-shadow.tsx +186 -0
- package/src/components/screen/screen-section-list.tsx +81 -0
- package/src/components/screen/screen-view.tsx +59 -0
- package/src/components/screen/screen.context.tsx +167 -0
- package/src/components/screen/screen.tsx +114 -0
- package/src/components/screen/screen.types.ts +66 -0
- package/src/components/screen/screen.variants.test.ts +602 -0
- package/src/components/screen/screen.variants.ts +475 -0
- package/src/components/screen/use-screen-scroll-insets.ts +218 -0
- package/src/components/separator/AGENTS.md +30 -0
- package/src/components/separator/index.ts +8 -0
- package/src/components/separator/separator.tsx +85 -0
- package/src/components/slider/AGENTS.md +274 -0
- package/src/components/slider/index.ts +50 -0
- package/src/components/slider/slider-fill.tsx +68 -0
- package/src/components/slider/slider-output.tsx +55 -0
- package/src/components/slider/slider-thumb.tsx +193 -0
- package/src/components/slider/slider-track.tsx +233 -0
- package/src/components/slider/slider.context.tsx +118 -0
- package/src/components/slider/slider.tsx +321 -0
- package/src/components/slider/slider.types.ts +26 -0
- package/src/components/slider/slider.variants.test.ts +856 -0
- package/src/components/slider/slider.variants.ts +661 -0
- package/src/components/spinner/AGENTS.md +73 -0
- package/src/components/spinner/index.ts +17 -0
- package/src/components/spinner/spinner-arc.tsx +90 -0
- package/src/components/spinner/spinner-content.tsx +63 -0
- package/src/components/spinner/spinner.context.tsx +52 -0
- package/src/components/spinner/spinner.tsx +128 -0
- package/src/components/spinner/spinner.variants.test.ts +273 -0
- package/src/components/spinner/spinner.variants.ts +187 -0
- package/src/components/switch/AGENTS.md +213 -0
- package/src/components/switch/index.ts +42 -0
- package/src/components/switch/switch-content.tsx +111 -0
- package/src/components/switch/switch-end-content.tsx +18 -0
- package/src/components/switch/switch-start-content.tsx +20 -0
- package/src/components/switch/switch-thumb.tsx +102 -0
- package/src/components/switch/switch.context.tsx +79 -0
- package/src/components/switch/switch.tsx +423 -0
- package/src/components/switch/switch.types.ts +14 -0
- package/src/components/switch/switch.variants.test.ts +570 -0
- package/src/components/switch/switch.variants.ts +511 -0
- package/src/components/tabs/AGENTS.md +287 -0
- package/src/components/tabs/index.ts +69 -0
- package/src/components/tabs/tabs-content.tsx +65 -0
- package/src/components/tabs/tabs-indicator.tsx +97 -0
- package/src/components/tabs/tabs-label.tsx +62 -0
- package/src/components/tabs/tabs-list.tsx +139 -0
- package/src/components/tabs/tabs-pager.tsx +59 -0
- package/src/components/tabs/tabs-scroll-view.tsx +171 -0
- package/src/components/tabs/tabs-separator.tsx +73 -0
- package/src/components/tabs/tabs-trigger.tsx +210 -0
- package/src/components/tabs/tabs.context.tsx +294 -0
- package/src/components/tabs/tabs.tsx +435 -0
- package/src/components/tabs/tabs.types.ts +13 -0
- package/src/components/tabs/tabs.variants.test.ts +1020 -0
- package/src/components/tabs/tabs.variants.ts +670 -0
- package/src/components/text/AGENTS.md +95 -0
- package/src/components/text/index.ts +25 -0
- package/src/components/text/text.context.tsx +60 -0
- package/src/components/text/text.tsx +251 -0
- package/src/components/text/text.variants.test.ts +422 -0
- package/src/components/text/text.variants.ts +282 -0
- package/src/display-name.test.ts +145 -0
- package/src/docs.test.ts +98 -0
- package/src/expo/navigation-theme.tsx +58 -0
- package/src/hooks/use-controllable-state.ts +45 -0
- package/src/hooks/use-keyboard-state-sync.tsx +147 -0
- package/src/hooks/use-navigation-theme.ts +78 -0
- package/src/hooks/use-theme-color.ts +44 -0
- package/src/icons/central.ts +1 -0
- package/src/lib/cn.test.ts +136 -0
- package/src/lib/cn.ts +29 -0
- package/src/lib/color.test.ts +80 -0
- package/src/lib/color.ts +79 -0
- package/src/lib/compose-refs.test.ts +64 -0
- package/src/lib/compose-refs.ts +37 -0
- package/src/lib/keyboard-animation.test.ts +33 -0
- package/src/lib/keyboard-animation.ts +28 -0
- package/src/lib/merge-props.test.ts +82 -0
- package/src/lib/merge-props.ts +47 -0
- package/src/lib/navigation-theme.test.ts +49 -0
- package/src/lib/navigation-theme.ts +53 -0
- package/src/lib/slot.tsx +45 -0
- package/src/lib/tv.ts +20 -0
- package/src/styles/base.css +2 -0
- package/src/styles/geometry.test.ts +117 -0
- package/src/styles/index.css +3 -0
- package/src/styles/theme-tokens.test.ts +252 -0
- package/src/styles/theme.css +447 -0
- package/src/styles/tokens.css +132 -0
- package/src/styles/tokens.test.ts +181 -0
- package/src/styles/tokens.ts +86 -0
- package/src/uniwind-env.d.ts +1 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { createContext, type ReactElement, type ReactNode, use } from "react";
|
|
2
|
+
import type { GestureType } from "react-native-gesture-handler";
|
|
3
|
+
import type { SharedValue } from "react-native-reanimated";
|
|
4
|
+
import type { TabMeasurement, TabsSize, TabsVariant, TabTracks } from "./tabs.variants";
|
|
5
|
+
|
|
6
|
+
export type TabsContextValue = {
|
|
7
|
+
/** The selected tab's value. `null` is "nothing selected", never `undefined`. */
|
|
8
|
+
value: string | null;
|
|
9
|
+
/** What a trigger calls on press. Stays quiet when the tab is already selected. */
|
|
10
|
+
select: (value: string) => void;
|
|
11
|
+
/** Every tab's value, in the order its panels are laid out. */
|
|
12
|
+
order: readonly string[];
|
|
13
|
+
/**
|
|
14
|
+
* Which tab is painted as current — the one the indicator mostly covers.
|
|
15
|
+
*
|
|
16
|
+
* Distinct from {@link TabsContextValue.value}, and both are needed. The value
|
|
17
|
+
* is what a screen reader announces, what a panel hides on and what
|
|
18
|
+
* `onValueChange` reported; this is only what things are painted from, and it
|
|
19
|
+
* swaps mid-drag so a filled capsule never carries an unselected label.
|
|
20
|
+
*/
|
|
21
|
+
visualIndex: number;
|
|
22
|
+
/** How the bar is painted. The root owns this axis outright. */
|
|
23
|
+
variant: TabsVariant;
|
|
24
|
+
/** The bar's size. The root owns this axis outright. */
|
|
25
|
+
size: TabsSize;
|
|
26
|
+
/** Whether a pan on the panels drags them. */
|
|
27
|
+
isSwipeable: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Raw rather than resolved, and deliberately so — `Radio.Group`'s note, and the
|
|
30
|
+
* same reason. The root paints nothing whose state it has to settle, so leaving
|
|
31
|
+
* `undefined` to mean "the bar said nothing" is what lets one trigger disable
|
|
32
|
+
* itself.
|
|
33
|
+
*/
|
|
34
|
+
isDisabled?: boolean;
|
|
35
|
+
/** Records a trigger's value, for a bar with no panels to take its order from. */
|
|
36
|
+
registerValue: (value: string) => () => void;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type TabsMotionValue = {
|
|
40
|
+
/**
|
|
41
|
+
* Where the pager sits, in tab-index space, on the **UI thread**.
|
|
42
|
+
*
|
|
43
|
+
* `1.4` is 40% of the way from the second tab to the third. Every animated
|
|
44
|
+
* style in the component reads this one value — the pager's translation, the
|
|
45
|
+
* indicator's frame, each separator's opacity — so none of them can drift out
|
|
46
|
+
* of step by a frame.
|
|
47
|
+
*/
|
|
48
|
+
position: SharedValue<number>;
|
|
49
|
+
/** The pager viewport's width in points, `0` before its first layout. */
|
|
50
|
+
pageWidth: SharedValue<number>;
|
|
51
|
+
/**
|
|
52
|
+
* The pager's own pan, published so a caller can relate their own to it.
|
|
53
|
+
*
|
|
54
|
+
* A horizontal scrollable *inside* a panel is a head-on conflict that only the
|
|
55
|
+
* caller can settle, because only they know which should win:
|
|
56
|
+
* `Gesture.Native().blocksExternalGesture(panGesture)` hands the touch to
|
|
57
|
+
* theirs. A hook rather than a prop, the trade `useScreenFooterKeyboardClearance`
|
|
58
|
+
* already makes.
|
|
59
|
+
*/
|
|
60
|
+
panGesture: GestureType;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type TabsListValue = {
|
|
64
|
+
/**
|
|
65
|
+
* The interpolation tracks, or `null` while any trigger is still unmeasured.
|
|
66
|
+
*
|
|
67
|
+
* One shared value holding three pre-built arrays rather than three shared
|
|
68
|
+
* values holding one each: `interpolate` throws when its input and output
|
|
69
|
+
* ranges differ in length, and three separate writes would be three separate
|
|
70
|
+
* chances for the UI thread to read a half-updated set.
|
|
71
|
+
*/
|
|
72
|
+
tracks: SharedValue<TabTracks | null>;
|
|
73
|
+
/** A trigger reports its frame here on layout. Stable for the bar's lifetime. */
|
|
74
|
+
measure: (value: string, measurement: TabMeasurement) => void;
|
|
75
|
+
/** A trigger withdraws its frame here on unmount. Stable for the bar's lifetime. */
|
|
76
|
+
unmeasure: (value: string) => void;
|
|
77
|
+
/** The bar's own scroll offset, and the two widths `resolveScrollOffset` needs. */
|
|
78
|
+
scrollX: SharedValue<number>;
|
|
79
|
+
viewportWidth: SharedValue<number>;
|
|
80
|
+
contentWidth: SharedValue<number>;
|
|
81
|
+
/**
|
|
82
|
+
* Whether the bar is being scrolled by hand.
|
|
83
|
+
*
|
|
84
|
+
* Auto-scrolling into a hand-scroll — or into the momentum left behind by one —
|
|
85
|
+
* is a tug-of-war the user feels as the bar snapping backwards mid-flick.
|
|
86
|
+
*/
|
|
87
|
+
isBarDragging: SharedValue<boolean>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type TabsTriggerContextValue = {
|
|
91
|
+
/** What this trigger is called, and the `Tabs.Content` it selects. */
|
|
92
|
+
value: string;
|
|
93
|
+
/** This trigger's place in the order, or `-1` when no panel claims its value. */
|
|
94
|
+
index: number;
|
|
95
|
+
/** Whether this trigger is the settled selection — what accessibility reads. */
|
|
96
|
+
isSelected: boolean;
|
|
97
|
+
/** Whether this trigger is the one currently painted as selected. */
|
|
98
|
+
isVisuallySelected: boolean;
|
|
99
|
+
/** Whether this trigger is unavailable, already settled from the bar and its own prop. */
|
|
100
|
+
isDisabled: boolean;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const TabsContext = createContext<TabsContextValue | null>(null);
|
|
104
|
+
const TabsMotionContext = createContext<TabsMotionValue | null>(null);
|
|
105
|
+
const TabsListContext = createContext<TabsListValue | null>(null);
|
|
106
|
+
const TabsTriggerContext = createContext<TabsTriggerContextValue | null>(null);
|
|
107
|
+
const TabsScrollableContext = createContext(false);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Supplies the bar's selection and axes to everything inside it.
|
|
111
|
+
*
|
|
112
|
+
* Lives in its own module, importing nothing but React and types, so a part can
|
|
113
|
+
* read it without importing `./tabs`. That import would close a cycle, and Metro
|
|
114
|
+
* serves a partially initialised module for a cycle — leaving the context
|
|
115
|
+
* `undefined` at import time and red-boxing the app on a cold start.
|
|
116
|
+
*/
|
|
117
|
+
export function TabsProvider({ value, children }: { value: TabsContextValue; children: ReactNode }): ReactElement {
|
|
118
|
+
return <TabsContext value={value}>{children}</TabsContext>;
|
|
119
|
+
}
|
|
120
|
+
TabsProvider.displayName = "DelacourUI.Tabs.Provider";
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Supplies the Reanimated layer.
|
|
124
|
+
*
|
|
125
|
+
* Split from {@link TabsProvider} because that one changes identity on every
|
|
126
|
+
* selection, and `Tabs.Indicator` — whose whole job is to read the UI thread —
|
|
127
|
+
* must never re-render for one. Every field here is a shared value or a gesture
|
|
128
|
+
* built once, so this bundle is memoised once and never invalidated.
|
|
129
|
+
*/
|
|
130
|
+
export function TabsMotionProvider({ value, children }: { value: TabsMotionValue; children: ReactNode }): ReactElement {
|
|
131
|
+
return <TabsMotionContext value={value}>{children}</TabsMotionContext>;
|
|
132
|
+
}
|
|
133
|
+
TabsMotionProvider.displayName = "DelacourUI.Tabs.MotionProvider";
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Supplies the trigger measurements a `Tabs.List` collects.
|
|
137
|
+
*
|
|
138
|
+
* Created by the list rather than by the root, so `Tabs.Indicator` and
|
|
139
|
+
* `Tabs.Trigger` throw by name when either is written outside one — which is the
|
|
140
|
+
* only way an indicator with nothing to measure could otherwise present itself.
|
|
141
|
+
*/
|
|
142
|
+
export function TabsListProvider({ value, children }: { value: TabsListValue; children: ReactNode }): ReactElement {
|
|
143
|
+
return <TabsListContext value={value}>{children}</TabsListContext>;
|
|
144
|
+
}
|
|
145
|
+
TabsListProvider.displayName = "DelacourUI.Tabs.List.Provider";
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Supplies one trigger's settled state to its own parts.
|
|
149
|
+
*
|
|
150
|
+
* What the parts read is always the *resolved* state, so `Tabs.Label` never has
|
|
151
|
+
* to know whether the bar is disabled, never runs the ladder, and never imports
|
|
152
|
+
* the root.
|
|
153
|
+
*/
|
|
154
|
+
export function TabsTriggerProvider({
|
|
155
|
+
value,
|
|
156
|
+
children,
|
|
157
|
+
}: {
|
|
158
|
+
value: TabsTriggerContextValue;
|
|
159
|
+
children: ReactNode;
|
|
160
|
+
}): ReactElement {
|
|
161
|
+
return <TabsTriggerContext value={value}>{children}</TabsTriggerContext>;
|
|
162
|
+
}
|
|
163
|
+
TabsTriggerProvider.displayName = "DelacourUI.Tabs.Trigger.Provider";
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Tells the triggers inside it that their row scrolls.
|
|
167
|
+
*
|
|
168
|
+
* A bare boolean rather than an object, so React compares it by value and an
|
|
169
|
+
* unchanged one re-renders nothing — `TextClassProvider`'s argument. It answers
|
|
170
|
+
* exactly one question: does a trigger fill the bar, or size to its own content.
|
|
171
|
+
*/
|
|
172
|
+
export function TabsScrollableProvider({ value, children }: { value: boolean; children: ReactNode }): ReactElement {
|
|
173
|
+
return <TabsScrollableContext value={value}>{children}</TabsScrollableContext>;
|
|
174
|
+
}
|
|
175
|
+
TabsScrollableProvider.displayName = "DelacourUI.Tabs.ScrollView.Provider";
|
|
176
|
+
|
|
177
|
+
/** The enclosing bar's selection and axes, or null outside a `<Tabs>`. */
|
|
178
|
+
export function useTabsContext(): TabsContextValue | null {
|
|
179
|
+
return use(TabsContext);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Reads the enclosing bar's selection and axes.
|
|
184
|
+
*
|
|
185
|
+
* For a custom control that has to match the bar it sits in — a header showing
|
|
186
|
+
* the active tab's title, a footer that changes with it. Throws outside a
|
|
187
|
+
* `<Tabs>`; use {@link useTabsContext} where the bar is optional.
|
|
188
|
+
*/
|
|
189
|
+
export function useTabs(): TabsContextValue {
|
|
190
|
+
const context = useTabsContext();
|
|
191
|
+
if (!context) {
|
|
192
|
+
throw new Error("useTabs must be called inside a <Tabs>.");
|
|
193
|
+
}
|
|
194
|
+
return context;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** The enclosing bar's Reanimated layer, or null outside a `<Tabs>`. */
|
|
198
|
+
export function useTabsMotionContext(): TabsMotionValue | null {
|
|
199
|
+
return use(TabsMotionContext);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Reads the shared values the bar animates from, and its pan.
|
|
204
|
+
*
|
|
205
|
+
* For a custom part that has to move with the pager, and for relating a
|
|
206
|
+
* horizontal gesture of your own to the pager's. Throws outside a `<Tabs>`.
|
|
207
|
+
*/
|
|
208
|
+
export function useTabsMotion(): TabsMotionValue {
|
|
209
|
+
const context = useTabsMotionContext();
|
|
210
|
+
if (!context) {
|
|
211
|
+
throw new Error("useTabsMotion must be called inside a <Tabs>.");
|
|
212
|
+
}
|
|
213
|
+
return context;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** The enclosing list's measurements, or null outside a `<Tabs.List>`. */
|
|
217
|
+
export function useTabsListContext(): TabsListValue | null {
|
|
218
|
+
return use(TabsListContext);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Reads the enclosing list's trigger measurements. Throws outside a `<Tabs.List>`. */
|
|
222
|
+
export function useTabsList(): TabsListValue {
|
|
223
|
+
const context = useTabsListContext();
|
|
224
|
+
if (!context) {
|
|
225
|
+
throw new Error("useTabsList must be called inside a <Tabs.List>.");
|
|
226
|
+
}
|
|
227
|
+
return context;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** The enclosing trigger's settled state, or null outside a `<Tabs.Trigger>`. */
|
|
231
|
+
export function useTabsTriggerContext(): TabsTriggerContextValue | null {
|
|
232
|
+
return use(TabsTriggerContext);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Reads the enclosing trigger's settled state.
|
|
237
|
+
*
|
|
238
|
+
* Lets a custom child style itself to match without the trigger having to pass
|
|
239
|
+
* props down through every slot. Throws outside a `<Tabs.Trigger>`.
|
|
240
|
+
*/
|
|
241
|
+
export function useTabsTrigger(): TabsTriggerContextValue {
|
|
242
|
+
const context = useTabsTriggerContext();
|
|
243
|
+
if (!context) {
|
|
244
|
+
throw new Error("useTabsTrigger must be called inside a <Tabs.Trigger>.");
|
|
245
|
+
}
|
|
246
|
+
return context;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Whether the enclosing trigger row scrolls. `false` outside a `<Tabs.ScrollView>`. */
|
|
250
|
+
export function useTabsIsScrollable(): boolean {
|
|
251
|
+
return use(TabsScrollableContext);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* The enclosing bar's state, for a compound part that cannot work without one.
|
|
256
|
+
*
|
|
257
|
+
* Internal: deliberately not re-exported from `index.ts`. A caller outside the
|
|
258
|
+
* library wants {@link useTabs}, whose error message names the hook rather than a
|
|
259
|
+
* part.
|
|
260
|
+
*/
|
|
261
|
+
export function useTabsPart(component: string): TabsContextValue {
|
|
262
|
+
const context = useTabsContext();
|
|
263
|
+
if (!context) {
|
|
264
|
+
throw new Error(`${component} must be rendered inside a <Tabs>.`);
|
|
265
|
+
}
|
|
266
|
+
return context;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** The enclosing bar's Reanimated layer, for a part that cannot work without one. Internal. */
|
|
270
|
+
export function useTabsMotionPart(component: string): TabsMotionValue {
|
|
271
|
+
const context = useTabsMotionContext();
|
|
272
|
+
if (!context) {
|
|
273
|
+
throw new Error(`${component} must be rendered inside a <Tabs>.`);
|
|
274
|
+
}
|
|
275
|
+
return context;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** The enclosing list's measurements, for a part that cannot work without one. Internal. */
|
|
279
|
+
export function useTabsListPart(component: string): TabsListValue {
|
|
280
|
+
const context = useTabsListContext();
|
|
281
|
+
if (!context) {
|
|
282
|
+
throw new Error(`${component} must be rendered inside a <Tabs.List>.`);
|
|
283
|
+
}
|
|
284
|
+
return context;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** The enclosing trigger's state, for a part that cannot work without one. Internal. */
|
|
288
|
+
export function useTabsTriggerPart(component: string): TabsTriggerContextValue {
|
|
289
|
+
const context = useTabsTriggerContext();
|
|
290
|
+
if (!context) {
|
|
291
|
+
throw new Error(`${component} must be rendered inside a <Tabs.Trigger>.`);
|
|
292
|
+
}
|
|
293
|
+
return context;
|
|
294
|
+
}
|