panelui-native 0.1.0 → 0.4.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/README.md +251 -0
- package/lib/module/components/alert/index.js +107 -24
- package/lib/module/components/alert/index.js.map +1 -1
- package/lib/module/components/avatar/index.js +1 -1
- package/lib/module/components/avatar/index.js.map +1 -1
- package/lib/module/components/badge/index.js +3 -3
- package/lib/module/components/badge/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +35 -31
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/button/index.js +44 -15
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/card/index.js +5 -5
- package/lib/module/components/card/index.js.map +1 -1
- package/lib/module/components/checkbox/index.js +21 -8
- package/lib/module/components/checkbox/index.js.map +1 -1
- package/lib/module/components/dialog/index.js +21 -17
- package/lib/module/components/dialog/index.js.map +1 -1
- package/lib/module/components/empty-state/index.js +178 -0
- package/lib/module/components/empty-state/index.js.map +1 -0
- package/lib/module/components/frame/index.js +100 -0
- package/lib/module/components/frame/index.js.map +1 -0
- package/lib/module/components/inline-select/index.js +159 -0
- package/lib/module/components/inline-select/index.js.map +1 -0
- package/lib/module/components/input/index.js +1 -1
- package/lib/module/components/input/index.js.map +1 -1
- package/lib/module/components/input-group/index.js +132 -0
- package/lib/module/components/input-group/index.js.map +1 -0
- package/lib/module/components/label/index.js +117 -0
- package/lib/module/components/label/index.js.map +1 -0
- package/lib/module/components/progress/index.js +138 -0
- package/lib/module/components/progress/index.js.map +1 -0
- package/lib/module/components/select/index.js +35 -28
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/skeleton/index.js +1 -1
- package/lib/module/components/skeleton/index.js.map +1 -1
- package/lib/module/components/spinner/index.js +1 -1
- package/lib/module/components/spinner/index.js.map +1 -1
- package/lib/module/components/steps/index.js +354 -0
- package/lib/module/components/steps/index.js.map +1 -0
- package/lib/module/components/tabs/index.js +9 -3
- package/lib/module/components/tabs/index.js.map +1 -1
- package/lib/module/components/toast/index.js +479 -0
- package/lib/module/components/toast/index.js.map +1 -0
- package/lib/module/components/toast/toast-store.js +81 -0
- package/lib/module/components/toast/toast-store.js.map +1 -0
- package/lib/module/components/typography/index.js +126 -0
- package/lib/module/components/typography/index.js.map +1 -0
- package/lib/module/icons/index.js +223 -2
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +11 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/providers/panel-ui-provider.js +20 -8
- package/lib/module/providers/panel-ui-provider.js.map +1 -1
- package/lib/module/theme/use-theme.js +90 -3
- package/lib/module/theme/use-theme.js.map +1 -1
- package/lib/typescript/src/components/alert/index.d.ts +41 -19
- package/lib/typescript/src/components/alert/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts +39 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/checkbox/index.d.ts +8 -0
- package/lib/typescript/src/components/checkbox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/dialog/index.d.ts.map +1 -1
- package/lib/typescript/src/components/empty-state/index.d.ts +73 -0
- package/lib/typescript/src/components/empty-state/index.d.ts.map +1 -0
- package/lib/typescript/src/components/frame/index.d.ts +21 -0
- package/lib/typescript/src/components/frame/index.d.ts.map +1 -0
- package/lib/typescript/src/components/inline-select/index.d.ts +25 -0
- package/lib/typescript/src/components/inline-select/index.d.ts.map +1 -0
- package/lib/typescript/src/components/input-group/index.d.ts +34 -0
- package/lib/typescript/src/components/input-group/index.d.ts.map +1 -0
- package/lib/typescript/src/components/label/index.d.ts +28 -0
- package/lib/typescript/src/components/label/index.d.ts.map +1 -0
- package/lib/typescript/src/components/progress/index.d.ts +132 -0
- package/lib/typescript/src/components/progress/index.d.ts.map +1 -0
- package/lib/typescript/src/components/select/index.d.ts.map +1 -1
- package/lib/typescript/src/components/spinner/index.d.ts +2 -2
- package/lib/typescript/src/components/spinner/index.d.ts.map +1 -1
- package/lib/typescript/src/components/steps/index.d.ts +62 -0
- package/lib/typescript/src/components/steps/index.d.ts.map +1 -0
- package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/index.d.ts +176 -0
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/toast-store.d.ts +65 -0
- package/lib/typescript/src/components/toast/toast-store.d.ts.map +1 -0
- package/lib/typescript/src/components/typography/index.d.ts +77 -0
- package/lib/typescript/src/components/typography/index.d.ts.map +1 -0
- package/lib/typescript/src/icons/index.d.ts +25 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +12 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/providers/panel-ui-provider.d.ts +20 -5
- package/lib/typescript/src/providers/panel-ui-provider.d.ts.map +1 -1
- package/lib/typescript/src/theme/use-theme.d.ts +64 -4
- package/lib/typescript/src/theme/use-theme.d.ts.map +1 -1
- package/package.json +28 -5
- package/src/components/alert/index.tsx +104 -28
- package/src/components/avatar/index.tsx +1 -1
- package/src/components/badge/index.tsx +3 -3
- package/src/components/bottom-sheet/index.tsx +8 -3
- package/src/components/button/index.tsx +47 -7
- package/src/components/card/index.tsx +5 -5
- package/src/components/checkbox/index.tsx +18 -4
- package/src/components/dialog/index.tsx +10 -5
- package/src/components/empty-state/index.tsx +136 -0
- package/src/components/frame/index.tsx +104 -0
- package/src/components/inline-select/index.tsx +185 -0
- package/src/components/input/index.tsx +1 -1
- package/src/components/input-group/index.tsx +164 -0
- package/src/components/label/index.tsx +128 -0
- package/src/components/progress/index.tsx +147 -0
- package/src/components/select/index.tsx +30 -23
- package/src/components/skeleton/index.tsx +1 -1
- package/src/components/spinner/index.tsx +1 -1
- package/src/components/steps/index.tsx +343 -0
- package/src/components/tabs/index.tsx +10 -2
- package/src/components/toast/index.tsx +447 -0
- package/src/components/toast/toast-store.ts +120 -0
- package/src/components/typography/index.tsx +121 -0
- package/src/icons/index.tsx +152 -1
- package/src/index.ts +82 -3
- package/src/providers/panel-ui-provider.tsx +35 -10
- package/src/theme/use-theme.ts +119 -4
- package/theme.css +446 -108
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,kCAA+B,CAAC;AAG3F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
export interface PanelUIProviderProps {
|
|
3
3
|
children: ReactNode;
|
|
4
|
+
/**
|
|
5
|
+
* Classes for the themed page surface. Defaults to `bg-background`, which
|
|
6
|
+
* follows the active theme. Pass your own to change the page colour.
|
|
7
|
+
*/
|
|
8
|
+
className?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Set to false to render without the themed page background — do this only
|
|
11
|
+
* if you paint the app background yourself.
|
|
12
|
+
*/
|
|
13
|
+
background?: boolean;
|
|
4
14
|
}
|
|
5
15
|
/**
|
|
6
|
-
* Root provider for PanelUI.
|
|
7
|
-
* the
|
|
16
|
+
* Root provider for PanelUI. Owns three things:
|
|
17
|
+
* the gesture handler root, the themed page background, and the portal host
|
|
18
|
+
* used by overlay components (Dialog, BottomSheet, Select).
|
|
8
19
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
20
|
+
* The background lives here because native wrappers like SafeAreaView do not
|
|
21
|
+
* accept `className` — putting `bg-background` on one silently does nothing,
|
|
22
|
+
* leaving the page unthemed while its children follow the theme.
|
|
23
|
+
*
|
|
24
|
+
* Theme switching is handled natively by Uniwind — use the `useTheme()` hook
|
|
25
|
+
* exported from panelui-native.
|
|
11
26
|
*/
|
|
12
|
-
export declare function PanelUIProvider({ children }: PanelUIProviderProps): import("react").JSX.Element;
|
|
27
|
+
export declare function PanelUIProvider({ children, className, background, }: PanelUIProviderProps): import("react").JSX.Element;
|
|
13
28
|
//# sourceMappingURL=panel-ui-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel-ui-provider.d.ts","sourceRoot":"","sources":["../../../../src/providers/panel-ui-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"panel-ui-provider.d.ts","sourceRoot":"","sources":["../../../../src/providers/panel-ui-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,UAAiB,GAClB,EAAE,oBAAoB,+BAatB"}
|
|
@@ -1,12 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
/** Themes shipped in `panelui-native/theme.css`. */
|
|
2
|
+
export type PanelTheme = 'light' | 'dark' | 'moon' | 'moon-dark' | 'grass' | 'grass-dark';
|
|
3
|
+
export type ThemeName = PanelTheme | 'system';
|
|
4
|
+
/** Light/dark mode within a theme family. */
|
|
5
|
+
export type ThemeMode = 'light' | 'dark';
|
|
6
|
+
/** A theme family — one look, in its light and dark form. */
|
|
7
|
+
export interface PanelThemeFamily {
|
|
8
|
+
/** Stable id, e.g. `'moon'`. */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Short display name, for a theme picker. */
|
|
11
|
+
name: string;
|
|
12
|
+
light: PanelTheme;
|
|
13
|
+
dark: PanelTheme;
|
|
14
|
+
/** Representative colour for a swatch, as `[light, dark]`. */
|
|
15
|
+
swatch: [string, string];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The theme families PanelUI ships. Each sets its own palette *and* its own
|
|
19
|
+
* radius scale, so switching family changes the shape of the UI as well as
|
|
20
|
+
* its colour — Panel is the Coss default, Moon is sharp and monochrome,
|
|
21
|
+
* Grass is soft and green.
|
|
22
|
+
*
|
|
23
|
+
* Everything beyond `panel` must be registered in your metro config, or
|
|
24
|
+
* `setTheme` throws "it was not registered":
|
|
25
|
+
*
|
|
26
|
+
* ```js
|
|
27
|
+
* withUniwindConfig(config, {
|
|
28
|
+
* cssEntryFile: './global.css',
|
|
29
|
+
* extraThemes: ['moon', 'moon-dark', 'grass', 'grass-dark'],
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const PANEL_THEMES: readonly PanelThemeFamily[];
|
|
34
|
+
/** Every concrete theme name, in registration order. */
|
|
35
|
+
export declare const PANEL_THEME_NAMES: readonly PanelTheme[];
|
|
36
|
+
/** The names to pass as `extraThemes` in your metro config. */
|
|
37
|
+
export declare const PANEL_EXTRA_THEMES: readonly string[];
|
|
2
38
|
/**
|
|
3
39
|
* Reactive access to the current Uniwind theme plus a setter.
|
|
4
40
|
* Theme changes are applied natively by Uniwind without re-rendering the tree.
|
|
5
41
|
*/
|
|
6
42
|
export declare function useTheme(): {
|
|
7
|
-
/**
|
|
8
|
-
theme:
|
|
9
|
-
/** Switch theme
|
|
43
|
+
/** The active theme name, e.g. `'dark'` or `'moon-dark'`. */
|
|
44
|
+
theme: PanelTheme;
|
|
45
|
+
/** Switch theme by name, or `'system'` to follow the device. */
|
|
10
46
|
setTheme: (name: ThemeName) => void;
|
|
11
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Theme family and light/dark mode as two separate axes — what a picker like
|
|
50
|
+
* "choose a brand, then toggle the sun" actually needs.
|
|
51
|
+
*
|
|
52
|
+
* Named themes are not adaptive in Uniwind, so each brand ships as a
|
|
53
|
+
* light/dark pair. Toggling the mode keeps the current family, so a user in
|
|
54
|
+
* Moon dark lands in Moon light rather than the default theme.
|
|
55
|
+
*
|
|
56
|
+
* ```tsx
|
|
57
|
+
* const { family, mode, setFamily, toggleMode } = useThemeMode();
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function useThemeMode(): {
|
|
61
|
+
/** The active theme family. */
|
|
62
|
+
family: PanelThemeFamily;
|
|
63
|
+
/** `'light'` or `'dark'` within that family. */
|
|
64
|
+
mode: ThemeMode;
|
|
65
|
+
/** Switch brand, staying in the current light/dark mode. */
|
|
66
|
+
setFamily: (id: string) => void;
|
|
67
|
+
/** Set the mode, staying in the current family. */
|
|
68
|
+
setMode: (next: ThemeMode) => void;
|
|
69
|
+
/** Flip light ↔ dark within the current family. */
|
|
70
|
+
toggleMode: () => void;
|
|
71
|
+
};
|
|
12
72
|
//# sourceMappingURL=use-theme.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-theme.d.ts","sourceRoot":"","sources":["../../../../src/theme/use-theme.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"use-theme.d.ts","sourceRoot":"","sources":["../../../../src/theme/use-theme.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,MAAM,GACN,MAAM,GACN,WAAW,GACX,OAAO,GACP,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE9C,6CAA6C;AAC7C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzC,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,8DAA8D;IAC9D,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,gBAAgB,EAsBnD,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAE,SAAS,UAAU,EAElD,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAE/C,CAAC;AASF;;;GAGG;AACH,wBAAgB,QAAQ;IAIpB,6DAA6D;WAC7C,UAAU;IAC1B,gEAAgE;qBAC/C,SAAS;EAE7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY;IAMxB,+BAA+B;;IAE/B,gDAAgD;;IAEhD,4DAA4D;oBAC5C,MAAM;IAItB,mDAAmD;oBACnC,SAAS;IACzB,mDAAmD;;EAGtD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "panelui-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "High-performance React Native UI components for Expo. Coss UI design language, powered by Uniwind (Tailwind v4) and Reanimated.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"src",
|
|
20
20
|
"lib",
|
|
21
21
|
"theme.css",
|
|
22
|
+
"README.md",
|
|
22
23
|
"!**/__tests__",
|
|
23
24
|
"!**/*.tsbuildinfo"
|
|
24
25
|
],
|
|
@@ -32,19 +33,36 @@
|
|
|
32
33
|
"react-native",
|
|
33
34
|
"expo",
|
|
34
35
|
"ui",
|
|
36
|
+
"ui-library",
|
|
37
|
+
"ui-components",
|
|
35
38
|
"components",
|
|
39
|
+
"component-library",
|
|
36
40
|
"tailwind",
|
|
41
|
+
"tailwindcss",
|
|
37
42
|
"uniwind",
|
|
43
|
+
"nativewind",
|
|
44
|
+
"reanimated",
|
|
38
45
|
"design-system",
|
|
39
|
-
"shadcn"
|
|
46
|
+
"shadcn",
|
|
47
|
+
"dark-mode",
|
|
48
|
+
"theming",
|
|
49
|
+
"accessibility",
|
|
50
|
+
"typescript",
|
|
51
|
+
"ios",
|
|
52
|
+
"android",
|
|
53
|
+
"mobile"
|
|
40
54
|
],
|
|
41
55
|
"repository": {
|
|
42
56
|
"type": "git",
|
|
43
|
-
"url": "git+https://github.com/
|
|
57
|
+
"url": "git+https://github.com/panel-ui/PanelUI.git",
|
|
58
|
+
"directory": "packages/panelui"
|
|
59
|
+
},
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/panel-ui/PanelUI/issues"
|
|
44
62
|
},
|
|
45
63
|
"author": "Khalid Abdi",
|
|
46
64
|
"license": "MIT",
|
|
47
|
-
"homepage": "https://github.com/
|
|
65
|
+
"homepage": "https://github.com/panel-ui/PanelUI#readme",
|
|
48
66
|
"peerDependencies": {
|
|
49
67
|
"react": "*",
|
|
50
68
|
"react-native": "*",
|
|
@@ -66,7 +84,12 @@
|
|
|
66
84
|
"source": "src",
|
|
67
85
|
"output": "lib",
|
|
68
86
|
"targets": [
|
|
69
|
-
[
|
|
87
|
+
[
|
|
88
|
+
"module",
|
|
89
|
+
{
|
|
90
|
+
"esm": true
|
|
91
|
+
}
|
|
92
|
+
],
|
|
70
93
|
"typescript"
|
|
71
94
|
]
|
|
72
95
|
}
|
|
@@ -1,41 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alert — a status message with an optional leading status icon.
|
|
3
|
+
*
|
|
4
|
+
* Adapted from: heroui-inc/heroui-native src/components/alert/alert.tsx
|
|
5
|
+
* (Indicator / Content / Title / Description anatomy, status-driven icon and
|
|
6
|
+
* title colour), restyled with Coss UI tokens.
|
|
7
|
+
*
|
|
8
|
+
* The `variant` prop name is kept from PanelUI v0.2 rather than renamed to
|
|
9
|
+
* HeroUI's `status`, so existing code keeps working.
|
|
10
|
+
*/
|
|
1
11
|
import { createContext, forwardRef, useContext, type ReactNode } from 'react';
|
|
2
|
-
import { View, type ViewProps } from 'react-native';
|
|
12
|
+
import { View, type Text as RNText, type ViewProps } from 'react-native';
|
|
3
13
|
import { tv, type VariantProps } from 'tailwind-variants';
|
|
14
|
+
import { useCSSVariable } from 'uniwind';
|
|
4
15
|
import { cn } from '../../utils/cn';
|
|
5
16
|
import { Text, type TextProps } from '../../primitives/text';
|
|
17
|
+
import { AlertTriangleIcon, CheckCircleIcon, InfoIcon } from '../../icons';
|
|
6
18
|
|
|
7
19
|
const alertVariants = tv({
|
|
8
20
|
slots: {
|
|
9
|
-
root: 'w-full gap-
|
|
10
|
-
|
|
11
|
-
|
|
21
|
+
root: 'w-full flex-row gap-3 rounded-xl border px-3.5 py-3',
|
|
22
|
+
indicator: 'pt-px',
|
|
23
|
+
content: 'flex-1 gap-0.5',
|
|
24
|
+
title: 'text-sm font-medium',
|
|
25
|
+
description: 'text-sm text-muted-foreground',
|
|
12
26
|
},
|
|
13
27
|
variants: {
|
|
14
28
|
variant: {
|
|
15
29
|
default: {
|
|
16
|
-
root: 'border-border bg-
|
|
17
|
-
title: 'text-foreground',
|
|
18
|
-
description: 'text-muted-foreground',
|
|
30
|
+
root: 'border-border bg-surface',
|
|
31
|
+
title: 'text-card-foreground',
|
|
19
32
|
},
|
|
20
33
|
info: {
|
|
21
|
-
root: 'border-info/32 bg-info
|
|
22
|
-
title: 'text-foreground',
|
|
23
|
-
description: 'text-muted-foreground',
|
|
34
|
+
root: 'border-info/32 bg-info-soft',
|
|
35
|
+
title: 'text-info-foreground',
|
|
24
36
|
},
|
|
25
37
|
success: {
|
|
26
|
-
root: 'border-success/32 bg-success
|
|
27
|
-
title: 'text-foreground',
|
|
28
|
-
description: 'text-muted-foreground',
|
|
38
|
+
root: 'border-success/32 bg-success-soft',
|
|
39
|
+
title: 'text-success-foreground',
|
|
29
40
|
},
|
|
30
41
|
warning: {
|
|
31
|
-
root: 'border-warning/32 bg-warning
|
|
32
|
-
title: 'text-foreground',
|
|
33
|
-
description: 'text-muted-foreground',
|
|
42
|
+
root: 'border-warning/32 bg-warning-soft',
|
|
43
|
+
title: 'text-warning-foreground',
|
|
34
44
|
},
|
|
35
45
|
destructive: {
|
|
36
|
-
root: 'border-destructive/32 bg-destructive
|
|
37
|
-
title: 'text-foreground',
|
|
38
|
-
description: 'text-muted-foreground',
|
|
46
|
+
root: 'border-destructive/32 bg-destructive-soft',
|
|
47
|
+
title: 'text-destructive-foreground',
|
|
39
48
|
},
|
|
40
49
|
},
|
|
41
50
|
},
|
|
@@ -44,20 +53,42 @@ const alertVariants = tv({
|
|
|
44
53
|
},
|
|
45
54
|
});
|
|
46
55
|
|
|
47
|
-
type AlertVariant = VariantProps<typeof alertVariants>['variant']
|
|
56
|
+
type AlertVariant = NonNullable<VariantProps<typeof alertVariants>['variant']>;
|
|
48
57
|
|
|
49
58
|
const AlertContext = createContext<AlertVariant>('default');
|
|
50
59
|
|
|
60
|
+
/** CSS variable each variant's indicator icon takes its colour from. */
|
|
61
|
+
const INDICATOR_COLOR_VAR: Record<AlertVariant, string> = {
|
|
62
|
+
default: '--color-muted-foreground',
|
|
63
|
+
info: '--color-info-foreground',
|
|
64
|
+
success: '--color-success-foreground',
|
|
65
|
+
warning: '--color-warning-foreground',
|
|
66
|
+
destructive: '--color-destructive-foreground',
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const INDICATOR_ICON: Record<AlertVariant, typeof InfoIcon> = {
|
|
70
|
+
default: InfoIcon,
|
|
71
|
+
info: InfoIcon,
|
|
72
|
+
success: CheckCircleIcon,
|
|
73
|
+
warning: AlertTriangleIcon,
|
|
74
|
+
destructive: AlertTriangleIcon,
|
|
75
|
+
};
|
|
76
|
+
|
|
51
77
|
export interface AlertProps extends ViewProps, VariantProps<typeof alertVariants> {
|
|
52
78
|
className?: string;
|
|
53
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* Leading element rendered before the content.
|
|
81
|
+
*
|
|
82
|
+
* @deprecated Prefer `<Alert.Indicator>`, which picks a status icon for you.
|
|
83
|
+
* Still honoured so v0.2 call sites keep rendering.
|
|
84
|
+
*/
|
|
54
85
|
icon?: ReactNode;
|
|
55
86
|
children?: ReactNode;
|
|
56
87
|
}
|
|
57
88
|
|
|
58
89
|
const AlertRoot = forwardRef<View, AlertProps>(
|
|
59
90
|
({ className, variant = 'default', icon, children, ...props }, ref) => {
|
|
60
|
-
const { root } = alertVariants({ variant });
|
|
91
|
+
const { root, indicator, content } = alertVariants({ variant });
|
|
61
92
|
|
|
62
93
|
return (
|
|
63
94
|
<AlertContext.Provider value={variant}>
|
|
@@ -68,10 +99,10 @@ const AlertRoot = forwardRef<View, AlertProps>(
|
|
|
68
99
|
{...props}
|
|
69
100
|
>
|
|
70
101
|
{icon ? (
|
|
71
|
-
|
|
72
|
-
<View className=
|
|
73
|
-
<View className=
|
|
74
|
-
|
|
102
|
+
<>
|
|
103
|
+
<View className={indicator()}>{icon}</View>
|
|
104
|
+
<View className={content()}>{children}</View>
|
|
105
|
+
</>
|
|
75
106
|
) : (
|
|
76
107
|
children
|
|
77
108
|
)}
|
|
@@ -82,7 +113,48 @@ const AlertRoot = forwardRef<View, AlertProps>(
|
|
|
82
113
|
);
|
|
83
114
|
AlertRoot.displayName = 'Alert';
|
|
84
115
|
|
|
85
|
-
|
|
116
|
+
export interface AlertIndicatorProps extends ViewProps {
|
|
117
|
+
className?: string;
|
|
118
|
+
/** Overrides the size/colour of the default status icon. */
|
|
119
|
+
iconProps?: { size?: number; color?: string };
|
|
120
|
+
/** Replaces the default status icon entirely. */
|
|
121
|
+
children?: ReactNode;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Leading status icon. Resolves both the icon and its colour from the parent
|
|
126
|
+
* Alert's variant, so it follows the active theme.
|
|
127
|
+
*/
|
|
128
|
+
const AlertIndicator = forwardRef<View, AlertIndicatorProps>(
|
|
129
|
+
({ className, iconProps, children, ...props }, ref) => {
|
|
130
|
+
const variant = useContext(AlertContext);
|
|
131
|
+
const { indicator } = alertVariants({ variant });
|
|
132
|
+
const themeColor = useCSSVariable(INDICATOR_COLOR_VAR[variant]);
|
|
133
|
+
const Icon = INDICATOR_ICON[variant];
|
|
134
|
+
|
|
135
|
+
const color =
|
|
136
|
+
iconProps?.color ?? (typeof themeColor === 'string' ? themeColor : undefined);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<View ref={ref} className={indicator({ className })} {...props}>
|
|
140
|
+
{children ?? <Icon size={iconProps?.size ?? 18} color={color} />}
|
|
141
|
+
</View>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
AlertIndicator.displayName = 'Alert.Indicator';
|
|
146
|
+
|
|
147
|
+
/** Flex-1 wrapper for Alert.Title and Alert.Description. */
|
|
148
|
+
const AlertContent = forwardRef<View, ViewProps & { className?: string }>(
|
|
149
|
+
({ className, ...props }, ref) => {
|
|
150
|
+
const variant = useContext(AlertContext);
|
|
151
|
+
const { content } = alertVariants({ variant });
|
|
152
|
+
return <View ref={ref} className={content({ className })} {...props} />;
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
AlertContent.displayName = 'Alert.Content';
|
|
156
|
+
|
|
157
|
+
const AlertTitle = forwardRef<RNText, TextProps>(
|
|
86
158
|
({ className, ...props }, ref) => {
|
|
87
159
|
const variant = useContext(AlertContext);
|
|
88
160
|
const { title } = alertVariants({ variant });
|
|
@@ -91,7 +163,7 @@ const AlertTitle = forwardRef<React.ElementRef<typeof Text>, TextProps>(
|
|
|
91
163
|
);
|
|
92
164
|
AlertTitle.displayName = 'Alert.Title';
|
|
93
165
|
|
|
94
|
-
const AlertDescription = forwardRef<
|
|
166
|
+
const AlertDescription = forwardRef<RNText, TextProps>(
|
|
95
167
|
({ className, ...props }, ref) => {
|
|
96
168
|
const variant = useContext(AlertContext);
|
|
97
169
|
const { description } = alertVariants({ variant });
|
|
@@ -101,6 +173,10 @@ const AlertDescription = forwardRef<React.ElementRef<typeof Text>, TextProps>(
|
|
|
101
173
|
AlertDescription.displayName = 'Alert.Description';
|
|
102
174
|
|
|
103
175
|
export const Alert = Object.assign(AlertRoot, {
|
|
176
|
+
/** @optional Status icon rendered as the leading visual element. */
|
|
177
|
+
Indicator: AlertIndicator,
|
|
178
|
+
/** @optional Wrapper for title and description. */
|
|
179
|
+
Content: AlertContent,
|
|
104
180
|
Title: AlertTitle,
|
|
105
181
|
Description: AlertDescription,
|
|
106
182
|
});
|
|
@@ -12,7 +12,7 @@ import { Text } from '../../primitives/text';
|
|
|
12
12
|
const avatarVariants = tv({
|
|
13
13
|
slots: {
|
|
14
14
|
root: 'items-center justify-center overflow-hidden rounded-full border border-border bg-muted',
|
|
15
|
-
image: 'h-full w-full',
|
|
15
|
+
image: 'absolute inset-0 h-full w-full',
|
|
16
16
|
fallback: 'font-medium text-muted-foreground',
|
|
17
17
|
},
|
|
18
18
|
variants: {
|
|
@@ -14,9 +14,9 @@ const badgeVariants = tv({
|
|
|
14
14
|
secondary: { root: 'bg-secondary', label: 'text-secondary-foreground' },
|
|
15
15
|
outline: { root: 'border-border bg-transparent', label: 'text-foreground' },
|
|
16
16
|
destructive: { root: 'bg-destructive', label: 'text-white' },
|
|
17
|
-
success: { root: 'bg-success
|
|
18
|
-
warning: { root: 'bg-warning
|
|
19
|
-
info: { root: 'bg-info
|
|
17
|
+
success: { root: 'bg-success-subtle', label: 'text-success-foreground' },
|
|
18
|
+
warning: { root: 'bg-warning-subtle', label: 'text-warning-foreground' },
|
|
19
|
+
info: { root: 'bg-info-subtle', label: 'text-info-foreground' },
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
defaultVariants: {
|
|
@@ -111,7 +111,8 @@ function BottomSheetContent({
|
|
|
111
111
|
children,
|
|
112
112
|
...props
|
|
113
113
|
}: BottomSheetContentProps) {
|
|
114
|
-
const
|
|
114
|
+
const context = useBottomSheet('BottomSheet.Content');
|
|
115
|
+
const { open, setOpen } = context;
|
|
115
116
|
const { height: screenHeight } = useWindowDimensions();
|
|
116
117
|
const insets = useSafeAreaInsets();
|
|
117
118
|
const translateY = useSharedValue(0);
|
|
@@ -145,7 +146,10 @@ function BottomSheetContent({
|
|
|
145
146
|
|
|
146
147
|
return (
|
|
147
148
|
<Portal>
|
|
148
|
-
|
|
149
|
+
{/* Portal content mounts under PortalHost, outside this provider's
|
|
150
|
+
subtree — re-provide the context so nested consumers keep working. */}
|
|
151
|
+
<BottomSheetContext.Provider value={context}>
|
|
152
|
+
<View className="absolute inset-0 justify-end">
|
|
149
153
|
<Animated.View
|
|
150
154
|
entering={FadeIn.duration(180)}
|
|
151
155
|
exiting={FadeOut.duration(180)}
|
|
@@ -175,7 +179,8 @@ function BottomSheetContent({
|
|
|
175
179
|
{children}
|
|
176
180
|
</Animated.View>
|
|
177
181
|
</GestureDetector>
|
|
178
|
-
|
|
182
|
+
</View>
|
|
183
|
+
</BottomSheetContext.Provider>
|
|
179
184
|
</Portal>
|
|
180
185
|
);
|
|
181
186
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef,
|
|
1
|
+
import { forwardRef, type ReactNode } from 'react';
|
|
2
2
|
import type { View } from 'react-native';
|
|
3
3
|
import { tv, type VariantProps } from 'tailwind-variants';
|
|
4
4
|
import {
|
|
@@ -6,33 +6,40 @@ import {
|
|
|
6
6
|
type AnimatedPressableProps,
|
|
7
7
|
} from '../../primitives/animated-pressable';
|
|
8
8
|
import { Text } from '../../primitives/text';
|
|
9
|
+
import { Spinner } from '../spinner';
|
|
9
10
|
|
|
10
11
|
const buttonVariants = tv({
|
|
11
12
|
slots: {
|
|
12
13
|
root: 'flex-row items-center justify-center gap-2 rounded-lg border border-transparent',
|
|
13
14
|
label: 'font-medium',
|
|
15
|
+
spinner: '',
|
|
14
16
|
},
|
|
15
17
|
variants: {
|
|
16
18
|
variant: {
|
|
17
19
|
primary: {
|
|
18
20
|
root: 'border-primary bg-primary shadow-sm',
|
|
19
21
|
label: 'text-primary-foreground',
|
|
22
|
+
spinner: 'border-primary-foreground/32 border-t-primary-foreground',
|
|
20
23
|
},
|
|
21
24
|
secondary: {
|
|
22
25
|
root: 'bg-secondary',
|
|
23
26
|
label: 'text-secondary-foreground',
|
|
27
|
+
spinner: 'border-secondary-foreground/24 border-t-secondary-foreground',
|
|
24
28
|
},
|
|
25
29
|
outline: {
|
|
26
30
|
root: 'border-input bg-popover shadow-sm',
|
|
27
31
|
label: 'text-foreground',
|
|
32
|
+
spinner: 'border-muted border-t-foreground',
|
|
28
33
|
},
|
|
29
34
|
ghost: {
|
|
30
35
|
root: 'bg-transparent',
|
|
31
36
|
label: 'text-foreground',
|
|
37
|
+
spinner: 'border-muted border-t-foreground',
|
|
32
38
|
},
|
|
33
39
|
destructive: {
|
|
34
40
|
root: 'border-destructive bg-destructive shadow-sm',
|
|
35
41
|
label: 'text-white',
|
|
42
|
+
spinner: 'border-white/32 border-t-white',
|
|
36
43
|
},
|
|
37
44
|
},
|
|
38
45
|
size: {
|
|
@@ -41,6 +48,9 @@ const buttonVariants = tv({
|
|
|
41
48
|
lg: { root: 'h-12 px-6', label: 'text-lg' },
|
|
42
49
|
icon: { root: 'h-11 w-11 px-0' },
|
|
43
50
|
},
|
|
51
|
+
fullWidth: {
|
|
52
|
+
true: { root: 'w-full' },
|
|
53
|
+
},
|
|
44
54
|
disabled: {
|
|
45
55
|
true: { root: 'opacity-[0.64]' },
|
|
46
56
|
},
|
|
@@ -53,38 +63,68 @@ const buttonVariants = tv({
|
|
|
53
63
|
|
|
54
64
|
type ButtonVariantProps = VariantProps<typeof buttonVariants>;
|
|
55
65
|
|
|
66
|
+
const SPINNER_SIZE = { sm: 'sm', md: 'sm', lg: 'md', icon: 'sm' } as const;
|
|
67
|
+
|
|
56
68
|
export interface ButtonProps
|
|
57
69
|
extends Omit<AnimatedPressableProps, 'children' | 'disabled'>,
|
|
58
70
|
Omit<ButtonVariantProps, 'disabled'> {
|
|
59
71
|
children?: ReactNode;
|
|
60
72
|
disabled?: boolean;
|
|
73
|
+
/** Show a spinner and block presses while an action is in flight. */
|
|
74
|
+
loading?: boolean;
|
|
75
|
+
/** Content rendered before the label (replaced by the spinner while loading). */
|
|
76
|
+
startContent?: ReactNode;
|
|
77
|
+
/** Content rendered after the label. */
|
|
78
|
+
endContent?: ReactNode;
|
|
61
79
|
/** Extra classes for the label when children is a string. */
|
|
62
80
|
labelClassName?: string;
|
|
63
81
|
}
|
|
64
82
|
|
|
65
83
|
export const Button = forwardRef<View, ButtonProps>(
|
|
66
84
|
(
|
|
67
|
-
{
|
|
85
|
+
{
|
|
86
|
+
children,
|
|
87
|
+
className,
|
|
88
|
+
labelClassName,
|
|
89
|
+
variant,
|
|
90
|
+
size,
|
|
91
|
+
fullWidth,
|
|
92
|
+
disabled,
|
|
93
|
+
loading = false,
|
|
94
|
+
startContent,
|
|
95
|
+
endContent,
|
|
96
|
+
...props
|
|
97
|
+
},
|
|
68
98
|
ref
|
|
69
99
|
) => {
|
|
70
|
-
const
|
|
100
|
+
const isDisabled = disabled || loading;
|
|
101
|
+
const { root, label, spinner } = buttonVariants({
|
|
102
|
+
variant,
|
|
103
|
+
size,
|
|
104
|
+
fullWidth,
|
|
105
|
+
disabled: isDisabled,
|
|
106
|
+
});
|
|
71
107
|
|
|
72
108
|
return (
|
|
73
109
|
<AnimatedPressable
|
|
74
110
|
ref={ref}
|
|
75
111
|
accessibilityRole="button"
|
|
76
|
-
accessibilityState={{ disabled:
|
|
77
|
-
disabled={
|
|
112
|
+
accessibilityState={{ disabled: isDisabled, busy: loading }}
|
|
113
|
+
disabled={isDisabled}
|
|
78
114
|
className={root({ className })}
|
|
79
115
|
{...props}
|
|
80
116
|
>
|
|
117
|
+
{loading ? (
|
|
118
|
+
<Spinner size={SPINNER_SIZE[size ?? 'md']} className={spinner()} />
|
|
119
|
+
) : (
|
|
120
|
+
startContent
|
|
121
|
+
)}
|
|
81
122
|
{typeof children === 'string' ? (
|
|
82
123
|
<Text className={label({ className: labelClassName })}>{children}</Text>
|
|
83
|
-
) : isValidElement(children) ? (
|
|
84
|
-
children
|
|
85
124
|
) : (
|
|
86
125
|
children
|
|
87
126
|
)}
|
|
127
|
+
{endContent}
|
|
88
128
|
</AnimatedPressable>
|
|
89
129
|
);
|
|
90
130
|
}
|
|
@@ -10,14 +10,14 @@ export interface CardProps extends ViewProps {
|
|
|
10
10
|
const CardRoot = forwardRef<View, CardProps>(({ className, ...props }, ref) => (
|
|
11
11
|
<View
|
|
12
12
|
ref={ref}
|
|
13
|
-
className={cn('rounded-
|
|
13
|
+
className={cn('rounded-2xl border border-border bg-card shadow-sm', className)}
|
|
14
14
|
{...props}
|
|
15
15
|
/>
|
|
16
16
|
));
|
|
17
17
|
CardRoot.displayName = 'Card';
|
|
18
18
|
|
|
19
19
|
const CardHeader = forwardRef<View, CardProps>(({ className, ...props }, ref) => (
|
|
20
|
-
<View ref={ref} className={cn('gap-1.5 p-
|
|
20
|
+
<View ref={ref} className={cn('gap-1.5 p-6', className)} {...props} />
|
|
21
21
|
));
|
|
22
22
|
CardHeader.displayName = 'Card.Header';
|
|
23
23
|
|
|
@@ -27,7 +27,7 @@ const CardTitle = forwardRef<React.ElementRef<typeof Text>, TextProps>(
|
|
|
27
27
|
ref={ref}
|
|
28
28
|
size="lg"
|
|
29
29
|
weight="semibold"
|
|
30
|
-
className={cn('text-card-foreground', className)}
|
|
30
|
+
className={cn('leading-none text-card-foreground', className)}
|
|
31
31
|
{...props}
|
|
32
32
|
/>
|
|
33
33
|
)
|
|
@@ -42,14 +42,14 @@ const CardDescription = forwardRef<React.ElementRef<typeof Text>, TextProps>(
|
|
|
42
42
|
CardDescription.displayName = 'Card.Description';
|
|
43
43
|
|
|
44
44
|
const CardContent = forwardRef<View, CardProps>(({ className, ...props }, ref) => (
|
|
45
|
-
<View ref={ref} className={cn('p-
|
|
45
|
+
<View ref={ref} className={cn('p-6 pt-0', className)} {...props} />
|
|
46
46
|
));
|
|
47
47
|
CardContent.displayName = 'Card.Content';
|
|
48
48
|
|
|
49
49
|
const CardFooter = forwardRef<View, CardProps>(({ className, ...props }, ref) => (
|
|
50
50
|
<View
|
|
51
51
|
ref={ref}
|
|
52
|
-
className={cn('flex-row items-center gap-2 p-
|
|
52
|
+
className={cn('flex-row items-center gap-2 p-6 pt-0', className)}
|
|
53
53
|
{...props}
|
|
54
54
|
/>
|
|
55
55
|
));
|