@mrmeg/expo-ui 0.14.0 → 0.16.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/CHANGELOG.md +81 -0
- package/README.md +50 -6
- package/dist/components/Accordion.d.ts +1 -1
- package/dist/components/Accordion.js +25 -19
- package/dist/components/Badge.js +10 -7
- package/dist/components/BottomSheet.js +21 -19
- package/dist/components/Button.d.ts +2 -1
- package/dist/components/Button.js +22 -6
- package/dist/components/Card.js +5 -3
- package/dist/components/Checkbox.js +49 -19
- package/dist/components/Collapsible.d.ts +1 -1
- package/dist/components/Collapsible.js +22 -16
- package/dist/components/Drawer.js +8 -7
- package/dist/components/DropdownMenu.d.ts +1 -1
- package/dist/components/DropdownMenu.js +80 -59
- package/dist/components/EmptyState.d.ts +7 -1
- package/dist/components/EmptyState.js +26 -9
- package/dist/components/InputOTP.js +10 -4
- package/dist/components/Item.d.ts +93 -0
- package/dist/components/Item.js +125 -0
- package/dist/components/Label.js +10 -4
- package/dist/components/Notification.js +14 -24
- package/dist/components/Popover.d.ts +3 -18
- package/dist/components/Popover.js +10 -6
- package/dist/components/RadioGroup.js +49 -22
- package/dist/components/SectionHeader.d.ts +42 -0
- package/dist/components/SectionHeader.js +41 -0
- package/dist/components/Select.js +73 -41
- package/dist/components/Skeleton.js +5 -3
- package/dist/components/StatCard.d.ts +45 -0
- package/dist/components/StatCard.js +41 -0
- package/dist/components/StyledText.d.ts +20 -10
- package/dist/components/StyledText.js +85 -29
- package/dist/components/Switch.js +84 -57
- package/dist/components/Tabs.js +43 -12
- package/dist/components/TextInput.js +17 -11
- package/dist/components/Toggle.js +69 -42
- package/dist/components/ToggleGroup.js +82 -55
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/constants/fonts.d.ts +44 -5
- package/dist/constants/fonts.js +42 -12
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/constants/motion.d.ts +24 -0
- package/dist/constants/motion.js +24 -0
- package/dist/constants/spacing.d.ts +7 -7
- package/dist/constants/spacing.js +7 -7
- package/dist/hooks/useResources.d.ts +4 -2
- package/dist/hooks/useResources.js +30 -8
- package/dist/hooks/useStaggeredEntrance.d.ts +1 -1
- package/dist/hooks/useStaggeredEntrance.js +2 -1
- package/dist/hooks/useTheme.d.ts +1 -1
- package/dist/hooks/useTheme.js +53 -16
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/themedStyles.d.ts +21 -0
- package/dist/lib/themedStyles.js +33 -0
- package/dist/state/themeStore.d.ts +17 -0
- package/dist/state/themeStore.js +6 -0
- package/package.json +20 -19
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import * as Font from "expo-font";
|
|
3
3
|
import Feather from "@expo/vector-icons/Feather";
|
|
4
|
+
import { Inter_400Regular, Inter_500Medium, Inter_600SemiBold, Inter_700Bold, } from "@expo-google-fonts/inter";
|
|
4
5
|
import { Platform } from "react-native";
|
|
5
6
|
// Eager, module-scope load so expo-font registers Feather in its SSR
|
|
6
7
|
// serverContext. When the server renders the HTML document, expo-font emits
|
|
@@ -11,30 +12,50 @@ import { Platform } from "react-native";
|
|
|
11
12
|
// the effect; the effect's loadAsync becomes a no-op for the already-loaded
|
|
12
13
|
// font.
|
|
13
14
|
void Font.loadAsync(Feather.font);
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
// The four static Inter weights StyledText's native family keys point at
|
|
16
|
+
// (see constants/fonts.ts). Native-only: web never renders these family names
|
|
17
|
+
// ("Inter_400Regular" etc.) — fontFamilies.sansSerif resolves every weight to
|
|
18
|
+
// the single "Inter" CSS family on web (loaded via ensureWebFontStylesheet
|
|
19
|
+
// below), so fetching these .ttf assets there would just be ~1.3MB of dead
|
|
20
|
+
// weight with nothing pointing at them.
|
|
21
|
+
const interFontMap = {
|
|
22
|
+
Inter_400Regular,
|
|
23
|
+
Inter_500Medium,
|
|
24
|
+
Inter_600SemiBold,
|
|
25
|
+
Inter_700Bold,
|
|
26
|
+
};
|
|
27
|
+
function loadNativeInterFonts() {
|
|
28
|
+
if (Platform.OS === "web") {
|
|
29
|
+
return Promise.resolve();
|
|
30
|
+
}
|
|
31
|
+
return Font.loadAsync(interFontMap);
|
|
32
|
+
}
|
|
33
|
+
const INTER_STYLESHEET_ID = "mrmeg-expo-ui-inter";
|
|
34
|
+
const INTER_STYLESHEET_URL = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
|
|
16
35
|
function ensureWebFontStylesheet() {
|
|
17
36
|
if (Platform.OS !== "web" || typeof document === "undefined") {
|
|
18
37
|
return Promise.resolve();
|
|
19
38
|
}
|
|
20
|
-
if (document.getElementById(
|
|
39
|
+
if (document.getElementById(INTER_STYLESHEET_ID)) {
|
|
21
40
|
return Promise.resolve();
|
|
22
41
|
}
|
|
23
42
|
return new Promise((resolve, reject) => {
|
|
24
43
|
const link = document.createElement("link");
|
|
25
|
-
link.id =
|
|
44
|
+
link.id = INTER_STYLESHEET_ID;
|
|
26
45
|
link.rel = "stylesheet";
|
|
27
|
-
link.href =
|
|
46
|
+
link.href = INTER_STYLESHEET_URL;
|
|
28
47
|
link.onload = () => resolve();
|
|
29
|
-
link.onerror = () => reject(new Error("
|
|
48
|
+
link.onerror = () => reject(new Error("Inter stylesheet failed to load"));
|
|
30
49
|
document.head.appendChild(link);
|
|
31
50
|
});
|
|
32
51
|
}
|
|
33
52
|
/**
|
|
34
53
|
* Loads essential app resources on startup.
|
|
35
54
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
55
|
+
* Native platforms load four static Inter weights (via
|
|
56
|
+
* @expo-google-fonts/inter) so StyledText's weight range resolves to real
|
|
57
|
+
* font files. Web loads Inter from Google Fonts as a single CSS family;
|
|
58
|
+
* weight differentiation there comes from a numeric fontWeight instead.
|
|
38
59
|
*/
|
|
39
60
|
export const useResources = () => {
|
|
40
61
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -45,6 +66,7 @@ export const useResources = () => {
|
|
|
45
66
|
try {
|
|
46
67
|
const fontPromise = Promise.all([
|
|
47
68
|
Font.loadAsync(Feather.font),
|
|
69
|
+
loadNativeInterFonts(),
|
|
48
70
|
ensureWebFontStylesheet(),
|
|
49
71
|
]);
|
|
50
72
|
// Timeout after 5 seconds — proceed with system fallback fonts
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef } from "react";
|
|
2
2
|
import { Animated, Easing } from "react-native";
|
|
3
3
|
import { useReducedMotion } from "./useReduceMotion.js";
|
|
4
|
+
import { durations } from "../constants/motion.js";
|
|
4
5
|
/**
|
|
5
6
|
* Hook for entrance animations with stagger support using React Native Animated.
|
|
6
7
|
*
|
|
@@ -21,7 +22,7 @@ import { useReducedMotion } from "./useReduceMotion.js";
|
|
|
21
22
|
* ```
|
|
22
23
|
*/
|
|
23
24
|
export function useStaggeredEntrance(options = {}) {
|
|
24
|
-
const { type = "fadeSlideUp", delay = 0, duration =
|
|
25
|
+
const { type = "fadeSlideUp", delay = 0, duration = durations.normal, slideDistance = 8, initialScale = 0.95, } = options;
|
|
25
26
|
const reduceMotion = useReducedMotion();
|
|
26
27
|
const opacity = useRef(new Animated.Value(reduceMotion ? 1 : 0)).current;
|
|
27
28
|
const translateY = useRef(new Animated.Value(reduceMotion
|
package/dist/hooks/useTheme.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ interface ExtendedColorScheme {
|
|
|
32
32
|
* - getTextColorForBackground("#000") → "light"
|
|
33
33
|
* - getContrastingColor("#f4f4f4", "#222", "#fff") → "#222"
|
|
34
34
|
* - withAlpha("#336699", 0.6) → "rgba(51,102,153,0.6)"
|
|
35
|
-
* - getShadowStyle('base') → { boxShadow: "0px
|
|
35
|
+
* - getShadowStyle('base') → { boxShadow: "0px 2px 6px rgba(0, 0, 0, 0.05), 0px 4px 12px rgba(0, 0, 0, 0.03)" }
|
|
36
36
|
*/
|
|
37
37
|
export declare function useTheme(): ExtendedColorScheme & {
|
|
38
38
|
toggleTheme: () => void;
|
package/dist/hooks/useTheme.js
CHANGED
|
@@ -42,7 +42,7 @@ function getCachedOrCompute(key, compute) {
|
|
|
42
42
|
* - getTextColorForBackground("#000") → "light"
|
|
43
43
|
* - getContrastingColor("#f4f4f4", "#222", "#fff") → "#222"
|
|
44
44
|
* - withAlpha("#336699", 0.6) → "rgba(51,102,153,0.6)"
|
|
45
|
-
* - getShadowStyle('base') → { boxShadow: "0px
|
|
45
|
+
* - getShadowStyle('base') → { boxShadow: "0px 2px 6px rgba(0, 0, 0, 0.05), 0px 4px 12px rgba(0, 0, 0, 0.03)" }
|
|
46
46
|
*/
|
|
47
47
|
export function useTheme() {
|
|
48
48
|
const userTheme = useThemeStore((s) => s.userTheme);
|
|
@@ -100,29 +100,66 @@ export function useTheme() {
|
|
|
100
100
|
* `boxShadow` has no separate opacity field, each preset's opacity is folded
|
|
101
101
|
* into the color's alpha via `withAlpha`. `elevation` is dropped — `boxShadow`
|
|
102
102
|
* renders shadows on Android in 0.85+.
|
|
103
|
+
*
|
|
104
|
+
* Every preset (except `sharp` and `glow`, which are deliberately
|
|
105
|
+
* single-layer) is a dual-layer shadow: a tight "contact" layer plus a
|
|
106
|
+
* wider, softer "ambient" layer, pitsi-ui-style. Layers are comma-joined
|
|
107
|
+
* into one `boxShadow` value.
|
|
103
108
|
*/
|
|
104
109
|
const getShadowStyle = useCallback((type) => {
|
|
105
|
-
// Each preset
|
|
110
|
+
// Each preset is one or more layers of [offsetX, offsetY, blurRadius, color, opacity].
|
|
106
111
|
// Darker themes get a stronger alpha so shadows stay visible.
|
|
107
112
|
const boost = theme.dark ? 3 : 1;
|
|
108
113
|
const overlay = theme.colors.overlay;
|
|
109
114
|
const shadowConfigs = {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
subtle: [
|
|
116
|
+
{ x: 0, y: 1, blur: 3, color: overlay, opacity: 0.04 },
|
|
117
|
+
{ x: 0, y: 2, blur: 8, color: overlay, opacity: 0.03 },
|
|
118
|
+
],
|
|
119
|
+
base: [
|
|
120
|
+
{ x: 0, y: 2, blur: 6, color: overlay, opacity: 0.05 },
|
|
121
|
+
{ x: 0, y: 4, blur: 12, color: overlay, opacity: 0.03 },
|
|
122
|
+
],
|
|
123
|
+
soft: [
|
|
124
|
+
{ x: 0, y: 4, blur: 10, color: overlay, opacity: 0.05 },
|
|
125
|
+
{ x: 0, y: 8, blur: 20, color: overlay, opacity: 0.03 },
|
|
126
|
+
],
|
|
127
|
+
card: [
|
|
128
|
+
{ x: 0, y: 4, blur: 12, color: overlay, opacity: 0.05 },
|
|
129
|
+
{ x: 0, y: 8, blur: 24, color: overlay, opacity: 0.03 },
|
|
130
|
+
],
|
|
131
|
+
cardSubtle: [
|
|
132
|
+
{ x: 0, y: 1, blur: 3, color: overlay, opacity: 0.05 },
|
|
133
|
+
{ x: 0, y: 3, blur: 9, color: overlay, opacity: 0.03 },
|
|
134
|
+
],
|
|
135
|
+
cardHover: [
|
|
136
|
+
{ x: 0, y: 8, blur: 24, color: overlay, opacity: 0.06 },
|
|
137
|
+
{ x: 0, y: 16, blur: 48, color: overlay, opacity: 0.04 },
|
|
138
|
+
],
|
|
139
|
+
elevated: [
|
|
140
|
+
{ x: 0, y: 16, blur: 48, color: overlay, opacity: 0.08 },
|
|
141
|
+
{ x: 0, y: 32, blur: 96, color: overlay, opacity: 0.05 },
|
|
142
|
+
],
|
|
143
|
+
glass: [
|
|
144
|
+
{ x: 0, y: 4, blur: 30, color: overlay, opacity: 0.05 },
|
|
145
|
+
{ x: 0, y: 8, blur: 60, color: overlay, opacity: 0.03 },
|
|
146
|
+
],
|
|
147
|
+
// Single layer — intentional crispness, not a soft dual-layer shadow.
|
|
148
|
+
sharp: [
|
|
149
|
+
{ x: 0, y: 1, blur: 1, color: overlay, opacity: 0.15 },
|
|
150
|
+
],
|
|
151
|
+
// Single layer — already a deliberate, vivid accent glow.
|
|
152
|
+
glow: [
|
|
153
|
+
{ x: 0, y: 4, blur: 20, color: theme.colors.primary, opacity: 0.4 },
|
|
154
|
+
],
|
|
120
155
|
};
|
|
121
|
-
const { x, y, blur, color, opacity }
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
const layers = shadowConfigs[type].map(({ x, y, blur, color, opacity }) => {
|
|
157
|
+
// Don't boost the glow accent — it's already a deliberate, vivid alpha.
|
|
158
|
+
const alpha = color === theme.colors.primary ? opacity : Math.min(opacity * boost, 1);
|
|
159
|
+
return `${x}px ${y}px ${blur}px ${withAlpha(color, alpha)}`;
|
|
160
|
+
});
|
|
124
161
|
return {
|
|
125
|
-
boxShadow:
|
|
162
|
+
boxShadow: layers.join(", "),
|
|
126
163
|
};
|
|
127
164
|
}, [theme]);
|
|
128
165
|
const getFocusRingStyle = useCallback((offset = 2) => {
|
package/dist/lib/index.d.ts
CHANGED
package/dist/lib/index.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Theme } from "../constants/colors";
|
|
2
|
+
/**
|
|
3
|
+
* Registers theme-dependent styles at module scope so react-native-web
|
|
4
|
+
* inserts their CSS rules into the server-side sheet before the document
|
|
5
|
+
* <head> is serialized.
|
|
6
|
+
*
|
|
7
|
+
* Styles created lazily during render — the
|
|
8
|
+
* `useMemo(() => createStyles(theme), [theme])` idiom — are inserted into
|
|
9
|
+
* RNW's sheet *after* expo-router has already captured the
|
|
10
|
+
* `<style id="react-native-stylesheet">` snapshot for the head. The SSR
|
|
11
|
+
* HTML then references class names that have no rules, which paints
|
|
12
|
+
* completely unstyled until hydration re-inserts them client-side (worst
|
|
13
|
+
* on the first request after a server cold start, and on every dev
|
|
14
|
+
* rebundle). See docs/ssr-hydration.md.
|
|
15
|
+
*
|
|
16
|
+
* Both base themes are computed eagerly at module load. Themes carrying
|
|
17
|
+
* color overrides (global brand or scoped) are computed once per theme
|
|
18
|
+
* object identity — `useTheme` keeps that identity stable, so the WeakMap
|
|
19
|
+
* behaves like the old `useMemo` without the render-time registration.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createThemedStyles<T extends object>(factory: (theme: Theme) => T): (theme: Theme) => T;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { colors } from "../constants/colors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registers theme-dependent styles at module scope so react-native-web
|
|
4
|
+
* inserts their CSS rules into the server-side sheet before the document
|
|
5
|
+
* <head> is serialized.
|
|
6
|
+
*
|
|
7
|
+
* Styles created lazily during render — the
|
|
8
|
+
* `useMemo(() => createStyles(theme), [theme])` idiom — are inserted into
|
|
9
|
+
* RNW's sheet *after* expo-router has already captured the
|
|
10
|
+
* `<style id="react-native-stylesheet">` snapshot for the head. The SSR
|
|
11
|
+
* HTML then references class names that have no rules, which paints
|
|
12
|
+
* completely unstyled until hydration re-inserts them client-side (worst
|
|
13
|
+
* on the first request after a server cold start, and on every dev
|
|
14
|
+
* rebundle). See docs/ssr-hydration.md.
|
|
15
|
+
*
|
|
16
|
+
* Both base themes are computed eagerly at module load. Themes carrying
|
|
17
|
+
* color overrides (global brand or scoped) are computed once per theme
|
|
18
|
+
* object identity — `useTheme` keeps that identity stable, so the WeakMap
|
|
19
|
+
* behaves like the old `useMemo` without the render-time registration.
|
|
20
|
+
*/
|
|
21
|
+
export function createThemedStyles(factory) {
|
|
22
|
+
const cache = new WeakMap();
|
|
23
|
+
cache.set(colors.light, factory(colors.light));
|
|
24
|
+
cache.set(colors.dark, factory(colors.dark));
|
|
25
|
+
return (theme) => {
|
|
26
|
+
const cached = cache.get(theme);
|
|
27
|
+
if (cached)
|
|
28
|
+
return cached;
|
|
29
|
+
const created = factory(theme);
|
|
30
|
+
cache.set(theme, created);
|
|
31
|
+
return created;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ThemeColors } from "../constants/colors";
|
|
2
|
+
import type { FontOverrides } from "../constants/fonts";
|
|
2
3
|
export type ThemePreference = "system" | "light" | "dark";
|
|
3
4
|
export type ResolvedTheme = "light" | "dark";
|
|
4
5
|
/**
|
|
@@ -28,6 +29,12 @@ export type ThemeStore = {
|
|
|
28
29
|
* behaves exactly as before this field existed (fully backward compatible).
|
|
29
30
|
*/
|
|
30
31
|
colorOverrides: ColorOverrides;
|
|
32
|
+
/**
|
|
33
|
+
* App-injected font overrides, applied by `StyledText` on top of the package
|
|
34
|
+
* defaults. Empty by default — zero override means the package behaves
|
|
35
|
+
* exactly as before this field existed (fully backward compatible).
|
|
36
|
+
*/
|
|
37
|
+
fontOverrides: FontOverrides;
|
|
31
38
|
setTheme: (theme: ThemePreference) => void;
|
|
32
39
|
setSystemTheme: (theme: ResolvedTheme) => void;
|
|
33
40
|
/**
|
|
@@ -35,6 +42,16 @@ export type ThemeStore = {
|
|
|
35
42
|
* clear overrides and fall back to the package defaults.
|
|
36
43
|
*/
|
|
37
44
|
setColors: (overrides: ColorOverrides) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Replace the active font overrides. Pass `{}` to clear them and fall back
|
|
47
|
+
* to the package's bundled faces.
|
|
48
|
+
*
|
|
49
|
+
* Call this once at startup, after the app's fonts have been registered
|
|
50
|
+
* (e.g. alongside `setColors` in a theme-sync component). Apps loading
|
|
51
|
+
* per-weight faces via `expo-font` should also pass
|
|
52
|
+
* `webWeightStrategy: "family"` — see `FontWeightStrategy`.
|
|
53
|
+
*/
|
|
54
|
+
setFonts: (overrides: FontOverrides) => void;
|
|
38
55
|
loadTheme: () => void;
|
|
39
56
|
};
|
|
40
57
|
export declare function resolveThemePreference(userTheme: ThemePreference, systemTheme: ResolvedTheme): ResolvedTheme;
|
package/dist/state/themeStore.js
CHANGED
|
@@ -19,9 +19,15 @@ export const useThemeStore = create((set) => ({
|
|
|
19
19
|
// No overrides by default: the package renders with its built-in palette
|
|
20
20
|
// until a host app calls `setColors`.
|
|
21
21
|
colorOverrides: {},
|
|
22
|
+
// Same contract as `colorOverrides`: the package renders with its bundled
|
|
23
|
+
// faces until a host app calls `setFonts`.
|
|
24
|
+
fontOverrides: {},
|
|
22
25
|
setColors: (overrides) => {
|
|
23
26
|
set({ colorOverrides: overrides ?? {} });
|
|
24
27
|
},
|
|
28
|
+
setFonts: (overrides) => {
|
|
29
|
+
set({ fontOverrides: overrides ?? {} });
|
|
30
|
+
},
|
|
25
31
|
setTheme: (theme) => {
|
|
26
32
|
set({
|
|
27
33
|
userTheme: theme,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrmeg/expo-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reusable Expo and React Native UI primitives for MrMeg projects.",
|
|
6
6
|
"keywords": [
|
|
@@ -88,25 +88,26 @@
|
|
|
88
88
|
"publish:dry-run": "bun pm pack --dry-run"
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
|
+
"@expo-google-fonts/inter": "^0.4.2",
|
|
91
92
|
"@expo/vector-icons": ">=15.0.0 <16.0.0",
|
|
92
|
-
"@rn-primitives/accordion": "~1.
|
|
93
|
-
"@rn-primitives/alert-dialog": "~1.
|
|
94
|
-
"@rn-primitives/checkbox": "~1.
|
|
95
|
-
"@rn-primitives/collapsible": "~1.
|
|
96
|
-
"@rn-primitives/dialog": "~1.
|
|
97
|
-
"@rn-primitives/dropdown-menu": "~1.
|
|
98
|
-
"@rn-primitives/label": "~1.
|
|
99
|
-
"@rn-primitives/popover": "~1.
|
|
100
|
-
"@rn-primitives/portal": "~1.
|
|
101
|
-
"@rn-primitives/radio-group": "~1.
|
|
102
|
-
"@rn-primitives/select": "~1.
|
|
103
|
-
"@rn-primitives/separator": "~1.
|
|
104
|
-
"@rn-primitives/slot": "~1.
|
|
105
|
-
"@rn-primitives/switch": "~1.
|
|
106
|
-
"@rn-primitives/tabs": "~1.
|
|
107
|
-
"@rn-primitives/toggle": "~1.
|
|
108
|
-
"@rn-primitives/toggle-group": "~1.
|
|
109
|
-
"@rn-primitives/tooltip": "~1.
|
|
93
|
+
"@rn-primitives/accordion": "~1.5.2",
|
|
94
|
+
"@rn-primitives/alert-dialog": "~1.5.2",
|
|
95
|
+
"@rn-primitives/checkbox": "~1.5.2",
|
|
96
|
+
"@rn-primitives/collapsible": "~1.5.2",
|
|
97
|
+
"@rn-primitives/dialog": "~1.5.2",
|
|
98
|
+
"@rn-primitives/dropdown-menu": "~1.5.2",
|
|
99
|
+
"@rn-primitives/label": "~1.5.2",
|
|
100
|
+
"@rn-primitives/popover": "~1.5.2",
|
|
101
|
+
"@rn-primitives/portal": "~1.5.2",
|
|
102
|
+
"@rn-primitives/radio-group": "~1.5.2",
|
|
103
|
+
"@rn-primitives/select": "~1.5.2",
|
|
104
|
+
"@rn-primitives/separator": "~1.5.2",
|
|
105
|
+
"@rn-primitives/slot": "~1.5.2",
|
|
106
|
+
"@rn-primitives/switch": "~1.5.2",
|
|
107
|
+
"@rn-primitives/tabs": "~1.5.2",
|
|
108
|
+
"@rn-primitives/toggle": "~1.5.2",
|
|
109
|
+
"@rn-primitives/toggle-group": "~1.5.2",
|
|
110
|
+
"@rn-primitives/tooltip": "~1.5.2"
|
|
110
111
|
},
|
|
111
112
|
"peerDependencies": {
|
|
112
113
|
"@expo/ui": ">=56.0.0 <58.0.0",
|