@spelyco/react-native 0.0.1-e4f7457e-alpha → 1.0.0-alpha.1
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 +103 -25
- package/dist/components/Button/Button.d.ts +59 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/configure.d.ts +2 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/index.d.ts +4 -11
- package/dist/index.d.ts.map +1 -0
- package/dist/themes/dark.d.ts +3 -0
- package/dist/themes/dark.d.ts.map +1 -0
- package/dist/themes/index.d.ts +12 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/light.d.ts +29 -0
- package/dist/themes/light.d.ts.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/unistyles.d.ts +8 -0
- package/dist/unistyles.d.ts.map +1 -0
- package/package.json +29 -12
- package/src/components/Button/Button.test.ts +45 -0
- package/src/components/Button/Button.tsx +89 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/index.ts +1 -0
- package/src/configure.ts +3 -0
- package/src/index.ts +13 -0
- package/src/themes/dark.ts +29 -0
- package/src/themes/index.ts +13 -0
- package/src/themes/light.ts +55 -0
- package/src/types.ts +9 -0
- package/src/unistyles.ts +27 -0
- package/dist/index.d.mts +0 -11
- package/dist/index.js +0 -28
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -26
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,13 +1,96 @@
|
|
|
1
1
|
# @spelyco/react-native
|
|
2
2
|
|
|
3
|
-
React Native UI components for Spelyco
|
|
3
|
+
React Native UI components for Spelyco, powered by [Unistyles 3](https://www.unistyl.es).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
bun add @spelyco/react-native
|
|
10
|
+
bun add @spelyco/react-native \
|
|
11
|
+
react-native-unistyles \
|
|
12
|
+
react-native-edge-to-edge \
|
|
13
|
+
react-native-nitro-modules \
|
|
14
|
+
react-native-reanimated
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This package is published as TypeScript source. Your bundler (Metro for React Native / Expo) transpiles it directly. Make sure your Babel config processes it (see [Setup](#setup) below).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
### 1. Babel plugin (required)
|
|
24
|
+
|
|
25
|
+
Unistyles 3 ships a Babel plugin that wires up the C++ shadow tree bindings. Because this package is shipped as source, you must include it in `autoProcessPaths` so the plugin processes our files inside `node_modules`.
|
|
26
|
+
|
|
27
|
+
`babel.config.js`:
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
module.exports = function (api) {
|
|
31
|
+
api.cache(true);
|
|
32
|
+
return {
|
|
33
|
+
presets: ["babel-preset-expo"],
|
|
34
|
+
plugins: [
|
|
35
|
+
[
|
|
36
|
+
"react-native-unistyles/plugin",
|
|
37
|
+
{
|
|
38
|
+
root: "src",
|
|
39
|
+
autoProcessPaths: ["@spelyco/react-native"],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. TypeScript theme augmentation (recommended)
|
|
48
|
+
|
|
49
|
+
Because TypeScript module augmentations don't auto-propagate from `node_modules` packages, add a one-time augmentation file in your app so Unistyles' `StyleSheet.create((theme) => ...)` knows the theme shape:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// unistyles.d.ts (anywhere TypeScript picks it up, e.g. project root)
|
|
53
|
+
import type { AppBreakpoints, AppTheme } from "@spelyco/react-native";
|
|
54
|
+
|
|
55
|
+
declare module "react-native-unistyles" {
|
|
56
|
+
export interface UnistylesThemes {
|
|
57
|
+
light: AppTheme;
|
|
58
|
+
dark: AppTheme;
|
|
59
|
+
}
|
|
60
|
+
export interface UnistylesBreakpoints extends AppBreakpoints {}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. Configure Unistyles at app startup
|
|
65
|
+
|
|
66
|
+
Add this **as the very first line** of your entry file (e.g. `app/_layout.tsx` for Expo Router):
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import "@spelyco/react-native/configure";
|
|
70
|
+
|
|
71
|
+
import { Stack } from "expo-router";
|
|
72
|
+
|
|
73
|
+
export default function RootLayout() {
|
|
74
|
+
return <Stack screenOptions={{ headerShown: false }} />;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`@spelyco/react-native/configure` is a side-effect import that runs `StyleSheet.configure` with the bundled themes before any component using `StyleSheet.create` is loaded. It enables `adaptiveThemes` (OS color scheme drives the active theme).
|
|
79
|
+
|
|
80
|
+
For full control (custom themes, pinned initial theme, etc.) skip the side-effect import and call `configureUnistyles` yourself **before** importing any component that uses styles:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import { configureUnistyles } from "@spelyco/react-native";
|
|
84
|
+
|
|
85
|
+
configureUnistyles({ adaptiveThemes: false, initialTheme: "dark" });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 4. New Architecture
|
|
89
|
+
|
|
90
|
+
Unistyles 3 requires React Native's New Architecture. Make sure your `app.json` (Expo) has:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{ "expo": { "newArchEnabled": true } }
|
|
11
94
|
```
|
|
12
95
|
|
|
13
96
|
---
|
|
@@ -16,47 +99,38 @@ bun add @spelyco/react-native @spelyco/react-lib react react-native
|
|
|
16
99
|
|
|
17
100
|
### `Button`
|
|
18
101
|
|
|
19
|
-
A basic button built on React Native's `Pressable`. Supports variants and sizes.
|
|
20
|
-
|
|
21
102
|
```tsx
|
|
22
103
|
import { Button } from "@spelyco/react-native";
|
|
23
104
|
|
|
24
|
-
// Default
|
|
25
105
|
<Button label="Tap me" />
|
|
26
|
-
|
|
27
|
-
// Variants
|
|
28
106
|
<Button label="Primary" variant="primary" />
|
|
29
107
|
<Button label="Secondary" variant="secondary" />
|
|
30
108
|
<Button label="Ghost" variant="ghost" />
|
|
31
|
-
|
|
32
|
-
// Sizes
|
|
33
109
|
<Button label="Small" size="sm" />
|
|
34
110
|
<Button label="Large" size="lg" />
|
|
35
|
-
|
|
36
|
-
// Disabled
|
|
37
111
|
<Button label="Disabled" disabled />
|
|
38
|
-
|
|
39
|
-
// With onPress
|
|
40
112
|
<Button label="Save" onPress={() => console.log("saved")} />
|
|
41
113
|
```
|
|
42
114
|
|
|
43
|
-
**Props:**
|
|
44
|
-
|
|
45
115
|
| Prop | Type | Default | Description |
|
|
46
116
|
| --- | --- | --- | --- |
|
|
47
|
-
| `label` | `string` | required |
|
|
117
|
+
| `label` | `string` | required | Button text |
|
|
48
118
|
| `variant` | `"primary" \| "secondary" \| "ghost"` | `"primary"` | Visual style |
|
|
49
|
-
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Padding size |
|
|
119
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Padding/font size |
|
|
50
120
|
| `disabled` | `boolean` | `false` | Disable the button |
|
|
51
|
-
| `...rest` | `PressableProps` | — | Any
|
|
121
|
+
| `...rest` | `PressableProps` | — | Any RN `Pressable` prop |
|
|
52
122
|
|
|
53
|
-
|
|
123
|
+
---
|
|
54
124
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
125
|
+
## Theme
|
|
126
|
+
|
|
127
|
+
Re-exports for the default themes:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { lightTheme, darkTheme, breakpoints, type AppTheme } from "@spelyco/react-native";
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
For now these are minimal placeholders (colors, spacing, radii). A proper design-system release will follow in a subsequent version.
|
|
60
134
|
|
|
61
135
|
---
|
|
62
136
|
|
|
@@ -65,7 +139,11 @@ import { Button } from "@spelyco/react-native";
|
|
|
65
139
|
| Package | Version |
|
|
66
140
|
| --- | --- |
|
|
67
141
|
| `react` | `>=18` |
|
|
68
|
-
| `react-native` | `>=0.
|
|
142
|
+
| `react-native` | `>=0.76` |
|
|
143
|
+
| `react-native-unistyles` | `^3.2.4` |
|
|
144
|
+
| `react-native-edge-to-edge` | `*` |
|
|
145
|
+
| `react-native-nitro-modules` | `*` |
|
|
146
|
+
| `react-native-reanimated` | `*` |
|
|
69
147
|
|
|
70
148
|
---
|
|
71
149
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { PressableProps } from "react-native";
|
|
2
|
+
import { type UnistylesVariants } from "react-native-unistyles";
|
|
3
|
+
type ButtonVariants = UnistylesVariants<typeof styles>;
|
|
4
|
+
export type ButtonProps = Omit<PressableProps, "children"> & ButtonVariants & {
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const Button: ({ label, variant, size, disabled, style, ...rest }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare const styles: {
|
|
9
|
+
root: {
|
|
10
|
+
opacity: number;
|
|
11
|
+
} & {
|
|
12
|
+
backgroundColor: string;
|
|
13
|
+
} & {
|
|
14
|
+
backgroundColor: string;
|
|
15
|
+
} & {
|
|
16
|
+
backgroundColor: string;
|
|
17
|
+
borderWidth: number;
|
|
18
|
+
borderColor: string;
|
|
19
|
+
} & {
|
|
20
|
+
paddingHorizontal: number;
|
|
21
|
+
paddingVertical: number;
|
|
22
|
+
} & {
|
|
23
|
+
paddingHorizontal: number;
|
|
24
|
+
paddingVertical: number;
|
|
25
|
+
} & {
|
|
26
|
+
paddingHorizontal: number;
|
|
27
|
+
paddingVertical: number;
|
|
28
|
+
} & {
|
|
29
|
+
borderRadius: number;
|
|
30
|
+
alignItems: "center";
|
|
31
|
+
justifyContent: "center";
|
|
32
|
+
};
|
|
33
|
+
label: {
|
|
34
|
+
color: string;
|
|
35
|
+
} & {
|
|
36
|
+
color: string;
|
|
37
|
+
} & {
|
|
38
|
+
color: string;
|
|
39
|
+
} & {
|
|
40
|
+
fontSize: number;
|
|
41
|
+
} & {
|
|
42
|
+
fontSize: number;
|
|
43
|
+
} & {
|
|
44
|
+
fontSize: number;
|
|
45
|
+
} & {
|
|
46
|
+
fontWeight: "600";
|
|
47
|
+
};
|
|
48
|
+
} & {
|
|
49
|
+
useVariants: (variants: {
|
|
50
|
+
variant?: "primary" | "secondary" | "ghost" | undefined;
|
|
51
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
52
|
+
disabled?: boolean | "true" | undefined;
|
|
53
|
+
} | {
|
|
54
|
+
variant?: "primary" | "secondary" | "ghost" | undefined;
|
|
55
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
56
|
+
}) => void;
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,KAAK,cAAc,GAAG,iBAAiB,CAAC,OAAO,MAAM,CAAC,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GACxD,cAAc,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEJ,eAAO,MAAM,MAAM,GAAI,oDAOpB,WAAW,4CAab,CAAC;AAEF,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Button/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
variant?: "primary" | "secondary" | "ghost";
|
|
6
|
-
size?: "sm" | "md" | "lg";
|
|
7
|
-
label: string;
|
|
8
|
-
}
|
|
9
|
-
declare function Button({ variant, size, label, style, ...props }: ButtonProps): react.JSX.Element;
|
|
10
|
-
|
|
11
|
-
export { Button };
|
|
1
|
+
export * from "./components";
|
|
2
|
+
export { type AppBreakpoints, type AppTheme, breakpoints, darkTheme, lightTheme, } from "./themes";
|
|
3
|
+
export { type ConfigureUnistylesOptions, configureUnistyles, type UnistylesInitialTheme, } from "./unistyles";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,WAAW,EACX,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,yBAAyB,EAC9B,kBAAkB,EAClB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dark.d.ts","sourceRoot":"","sources":["../../src/themes/dark.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,eAAO,MAAM,SAAS,EAAE,QA0BvB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { darkTheme } from "./dark";
|
|
2
|
+
export type { AppTheme } from "./light";
|
|
3
|
+
export { lightTheme } from "./light";
|
|
4
|
+
export declare const breakpoints: {
|
|
5
|
+
readonly xs: 0;
|
|
6
|
+
readonly sm: 360;
|
|
7
|
+
readonly md: 768;
|
|
8
|
+
readonly lg: 1024;
|
|
9
|
+
readonly xl: 1280;
|
|
10
|
+
};
|
|
11
|
+
export type AppBreakpoints = typeof breakpoints;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,WAAW;;;;;;CAMd,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,WAAW,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface AppTheme {
|
|
2
|
+
colors: {
|
|
3
|
+
primary: string;
|
|
4
|
+
onPrimary: string;
|
|
5
|
+
secondary: string;
|
|
6
|
+
onSecondary: string;
|
|
7
|
+
ghost: string;
|
|
8
|
+
onGhost: string;
|
|
9
|
+
background: string;
|
|
10
|
+
text: string;
|
|
11
|
+
border: string;
|
|
12
|
+
disabled: string;
|
|
13
|
+
};
|
|
14
|
+
spacing: {
|
|
15
|
+
xs: number;
|
|
16
|
+
sm: number;
|
|
17
|
+
md: number;
|
|
18
|
+
lg: number;
|
|
19
|
+
xl: number;
|
|
20
|
+
};
|
|
21
|
+
radii: {
|
|
22
|
+
sm: number;
|
|
23
|
+
md: number;
|
|
24
|
+
lg: number;
|
|
25
|
+
pill: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare const lightTheme: AppTheme;
|
|
29
|
+
//# sourceMappingURL=light.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"light.d.ts","sourceRoot":"","sources":["../../src/themes/light.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,eAAO,MAAM,UAAU,EAAE,QA0BxB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AppBreakpoints, AppTheme } from "./themes";
|
|
2
|
+
declare module "react-native-unistyles" {
|
|
3
|
+
interface UnistylesThemes {
|
|
4
|
+
light: AppTheme;
|
|
5
|
+
dark: AppTheme;
|
|
6
|
+
}
|
|
7
|
+
interface UnistylesBreakpoints extends AppBreakpoints {
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzD,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAiB,eAAe;QAC9B,KAAK,EAAE,QAAQ,CAAC;QAChB,IAAI,EAAE,QAAQ,CAAC;KAChB;IACD,UAAiB,oBAAqB,SAAQ,cAAc;KAAG;CAChE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./types";
|
|
2
|
+
export type UnistylesInitialTheme = "light" | "dark";
|
|
3
|
+
export interface ConfigureUnistylesOptions {
|
|
4
|
+
initialTheme?: UnistylesInitialTheme;
|
|
5
|
+
adaptiveThemes?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const configureUnistyles: ({ initialTheme, adaptiveThemes, }?: ConfigureUnistylesOptions) => void;
|
|
8
|
+
//# sourceMappingURL=unistyles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unistyles.d.ts","sourceRoot":"","sources":["../src/unistyles.ts"],"names":[],"mappings":"AAGA,OAAO,SAAS,CAAC;AAEjB,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD,eAAO,MAAM,kBAAkB,GAAI,oCAGhC,yBAA8B,SAMhC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spelyco/react-native",
|
|
3
|
-
"version": "0.0.1
|
|
4
|
-
"description": "React Native UI components for Spelyco",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "React Native UI components for Spelyco, powered by Unistyles 3",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
7
7
|
"ui",
|
|
8
8
|
"components",
|
|
9
|
-
"spelyco"
|
|
9
|
+
"spelyco",
|
|
10
|
+
"unistyles"
|
|
10
11
|
],
|
|
11
12
|
"license": "MIT",
|
|
12
|
-
"main": "./
|
|
13
|
-
"module": "./
|
|
13
|
+
"main": "./src/index.ts",
|
|
14
|
+
"module": "./src/index.ts",
|
|
15
|
+
"react-native": "./src/index.ts",
|
|
14
16
|
"types": "./dist/index.d.ts",
|
|
15
17
|
"exports": {
|
|
16
18
|
".": {
|
|
17
19
|
"types": "./dist/index.d.ts",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
+
"react-native": "./src/index.ts",
|
|
21
|
+
"import": "./src/index.ts",
|
|
22
|
+
"require": "./src/index.ts"
|
|
23
|
+
},
|
|
24
|
+
"./configure": {
|
|
25
|
+
"types": "./dist/configure.d.ts",
|
|
26
|
+
"react-native": "./src/configure.ts",
|
|
27
|
+
"import": "./src/configure.ts",
|
|
28
|
+
"require": "./src/configure.ts"
|
|
20
29
|
}
|
|
21
30
|
},
|
|
22
31
|
"files": [
|
|
32
|
+
"src",
|
|
23
33
|
"dist"
|
|
24
34
|
],
|
|
25
35
|
"scripts": {
|
|
26
|
-
"build": "
|
|
27
|
-
"dev": "
|
|
36
|
+
"build": "tsc -p tsconfig.build.json",
|
|
37
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
28
38
|
"lint": "biome check src/",
|
|
29
39
|
"lint:fix": "biome check --write src/",
|
|
30
40
|
"test": "vitest run --passWithNoTests",
|
|
@@ -33,7 +43,11 @@
|
|
|
33
43
|
},
|
|
34
44
|
"peerDependencies": {
|
|
35
45
|
"react": ">=18",
|
|
36
|
-
"react-native": ">=0.
|
|
46
|
+
"react-native": ">=0.76",
|
|
47
|
+
"react-native-edge-to-edge": "*",
|
|
48
|
+
"react-native-nitro-modules": "*",
|
|
49
|
+
"react-native-reanimated": "*",
|
|
50
|
+
"react-native-unistyles": "^3.2.4"
|
|
37
51
|
},
|
|
38
52
|
"dependencies": {
|
|
39
53
|
"@spelyco/react-lib": "1.2.0"
|
|
@@ -42,8 +56,11 @@
|
|
|
42
56
|
"@spelyco/tsconfig": "*",
|
|
43
57
|
"@types/react": "^19.2.14",
|
|
44
58
|
"react": "^19.2.4",
|
|
45
|
-
"react-native": "^0.
|
|
46
|
-
"
|
|
59
|
+
"react-native": "^0.83.6",
|
|
60
|
+
"react-native-edge-to-edge": "^1.8.1",
|
|
61
|
+
"react-native-nitro-modules": "^0.35.6",
|
|
62
|
+
"react-native-reanimated": "^4.2.1",
|
|
63
|
+
"react-native-unistyles": "^3.2.4",
|
|
47
64
|
"vitest": "^4.1.1"
|
|
48
65
|
}
|
|
49
66
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
vi.mock("react-native", () => ({
|
|
4
|
+
Pressable: "Pressable",
|
|
5
|
+
Text: "Text",
|
|
6
|
+
}));
|
|
7
|
+
|
|
8
|
+
vi.mock("react-native-unistyles", () => {
|
|
9
|
+
type StylesObject = Record<string, unknown>;
|
|
10
|
+
return {
|
|
11
|
+
StyleSheet: {
|
|
12
|
+
create: (stylesFn: ((theme: unknown) => StylesObject) | StylesObject) => {
|
|
13
|
+
const styles =
|
|
14
|
+
typeof stylesFn === "function"
|
|
15
|
+
? stylesFn({
|
|
16
|
+
colors: {
|
|
17
|
+
primary: "#000",
|
|
18
|
+
onPrimary: "#fff",
|
|
19
|
+
secondary: "#000",
|
|
20
|
+
onSecondary: "#fff",
|
|
21
|
+
ghost: "transparent",
|
|
22
|
+
onGhost: "#000",
|
|
23
|
+
border: "#000",
|
|
24
|
+
},
|
|
25
|
+
spacing: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24 },
|
|
26
|
+
radii: { sm: 4, md: 8, lg: 12, pill: 999 },
|
|
27
|
+
})
|
|
28
|
+
: stylesFn;
|
|
29
|
+
return Object.assign({}, styles, { useVariants: () => undefined });
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const { Button } = await import("./Button");
|
|
36
|
+
|
|
37
|
+
describe("Button", () => {
|
|
38
|
+
it("is exported as a function", () => {
|
|
39
|
+
expect(typeof Button).toBe("function");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("has a name of Button", () => {
|
|
43
|
+
expect(Button.name).toBe("Button");
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { PressableProps } from "react-native";
|
|
2
|
+
import { Pressable, Text } from "react-native";
|
|
3
|
+
import { StyleSheet, type UnistylesVariants } from "react-native-unistyles";
|
|
4
|
+
|
|
5
|
+
type ButtonVariants = UnistylesVariants<typeof styles>;
|
|
6
|
+
|
|
7
|
+
export type ButtonProps = Omit<PressableProps, "children"> &
|
|
8
|
+
ButtonVariants & {
|
|
9
|
+
label: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const Button = ({
|
|
13
|
+
label,
|
|
14
|
+
variant = "primary",
|
|
15
|
+
size = "md",
|
|
16
|
+
disabled,
|
|
17
|
+
style,
|
|
18
|
+
...rest
|
|
19
|
+
}: ButtonProps) => {
|
|
20
|
+
styles.useVariants({ variant, size, disabled: disabled ?? false });
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Pressable
|
|
24
|
+
accessibilityRole="button"
|
|
25
|
+
disabled={disabled}
|
|
26
|
+
style={(state) => [styles.root, typeof style === "function" ? style(state) : style]}
|
|
27
|
+
{...rest}
|
|
28
|
+
>
|
|
29
|
+
<Text style={styles.label}>{label}</Text>
|
|
30
|
+
</Pressable>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const styles = StyleSheet.create((theme) => ({
|
|
35
|
+
root: {
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
justifyContent: "center",
|
|
38
|
+
borderRadius: theme.radii.md,
|
|
39
|
+
variants: {
|
|
40
|
+
variant: {
|
|
41
|
+
primary: {
|
|
42
|
+
backgroundColor: theme.colors.primary,
|
|
43
|
+
},
|
|
44
|
+
secondary: {
|
|
45
|
+
backgroundColor: theme.colors.secondary,
|
|
46
|
+
},
|
|
47
|
+
ghost: {
|
|
48
|
+
backgroundColor: theme.colors.ghost,
|
|
49
|
+
borderWidth: 1,
|
|
50
|
+
borderColor: theme.colors.border,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
size: {
|
|
54
|
+
sm: {
|
|
55
|
+
paddingHorizontal: theme.spacing.md,
|
|
56
|
+
paddingVertical: theme.spacing.xs,
|
|
57
|
+
},
|
|
58
|
+
md: {
|
|
59
|
+
paddingHorizontal: theme.spacing.lg,
|
|
60
|
+
paddingVertical: theme.spacing.sm,
|
|
61
|
+
},
|
|
62
|
+
lg: {
|
|
63
|
+
paddingHorizontal: theme.spacing.xl,
|
|
64
|
+
paddingVertical: theme.spacing.md,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
disabled: {
|
|
68
|
+
true: {
|
|
69
|
+
opacity: 0.5,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
label: {
|
|
75
|
+
fontWeight: "600",
|
|
76
|
+
variants: {
|
|
77
|
+
variant: {
|
|
78
|
+
primary: { color: theme.colors.onPrimary },
|
|
79
|
+
secondary: { color: theme.colors.onSecondary },
|
|
80
|
+
ghost: { color: theme.colors.onGhost },
|
|
81
|
+
},
|
|
82
|
+
size: {
|
|
83
|
+
sm: { fontSize: 14 },
|
|
84
|
+
md: { fontSize: 16 },
|
|
85
|
+
lg: { fontSize: 18 },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Button } from "./Button";
|
package/src/configure.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./components";
|
|
2
|
+
export {
|
|
3
|
+
type AppBreakpoints,
|
|
4
|
+
type AppTheme,
|
|
5
|
+
breakpoints,
|
|
6
|
+
darkTheme,
|
|
7
|
+
lightTheme,
|
|
8
|
+
} from "./themes";
|
|
9
|
+
export {
|
|
10
|
+
type ConfigureUnistylesOptions,
|
|
11
|
+
configureUnistyles,
|
|
12
|
+
type UnistylesInitialTheme,
|
|
13
|
+
} from "./unistyles";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AppTheme } from "./light";
|
|
2
|
+
|
|
3
|
+
export const darkTheme: AppTheme = {
|
|
4
|
+
colors: {
|
|
5
|
+
primary: "#818cf8",
|
|
6
|
+
onPrimary: "#0b1020",
|
|
7
|
+
secondary: "#1f2937",
|
|
8
|
+
onSecondary: "#f9fafb",
|
|
9
|
+
ghost: "transparent",
|
|
10
|
+
onGhost: "#f9fafb",
|
|
11
|
+
background: "#0b1020",
|
|
12
|
+
text: "#f9fafb",
|
|
13
|
+
border: "#374151",
|
|
14
|
+
disabled: "#4b5563",
|
|
15
|
+
},
|
|
16
|
+
spacing: {
|
|
17
|
+
xs: 4,
|
|
18
|
+
sm: 8,
|
|
19
|
+
md: 12,
|
|
20
|
+
lg: 16,
|
|
21
|
+
xl: 24,
|
|
22
|
+
},
|
|
23
|
+
radii: {
|
|
24
|
+
sm: 4,
|
|
25
|
+
md: 8,
|
|
26
|
+
lg: 12,
|
|
27
|
+
pill: 999,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { darkTheme } from "./dark";
|
|
2
|
+
export type { AppTheme } from "./light";
|
|
3
|
+
export { lightTheme } from "./light";
|
|
4
|
+
|
|
5
|
+
export const breakpoints = {
|
|
6
|
+
xs: 0,
|
|
7
|
+
sm: 360,
|
|
8
|
+
md: 768,
|
|
9
|
+
lg: 1024,
|
|
10
|
+
xl: 1280,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export type AppBreakpoints = typeof breakpoints;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface AppTheme {
|
|
2
|
+
colors: {
|
|
3
|
+
primary: string;
|
|
4
|
+
onPrimary: string;
|
|
5
|
+
secondary: string;
|
|
6
|
+
onSecondary: string;
|
|
7
|
+
ghost: string;
|
|
8
|
+
onGhost: string;
|
|
9
|
+
background: string;
|
|
10
|
+
text: string;
|
|
11
|
+
border: string;
|
|
12
|
+
disabled: string;
|
|
13
|
+
};
|
|
14
|
+
spacing: {
|
|
15
|
+
xs: number;
|
|
16
|
+
sm: number;
|
|
17
|
+
md: number;
|
|
18
|
+
lg: number;
|
|
19
|
+
xl: number;
|
|
20
|
+
};
|
|
21
|
+
radii: {
|
|
22
|
+
sm: number;
|
|
23
|
+
md: number;
|
|
24
|
+
lg: number;
|
|
25
|
+
pill: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const lightTheme: AppTheme = {
|
|
30
|
+
colors: {
|
|
31
|
+
primary: "#6366f1",
|
|
32
|
+
onPrimary: "#ffffff",
|
|
33
|
+
secondary: "#e5e7eb",
|
|
34
|
+
onSecondary: "#111827",
|
|
35
|
+
ghost: "transparent",
|
|
36
|
+
onGhost: "#111827",
|
|
37
|
+
background: "#ffffff",
|
|
38
|
+
text: "#111827",
|
|
39
|
+
border: "#d1d5db",
|
|
40
|
+
disabled: "#9ca3af",
|
|
41
|
+
},
|
|
42
|
+
spacing: {
|
|
43
|
+
xs: 4,
|
|
44
|
+
sm: 8,
|
|
45
|
+
md: 12,
|
|
46
|
+
lg: 16,
|
|
47
|
+
xl: 24,
|
|
48
|
+
},
|
|
49
|
+
radii: {
|
|
50
|
+
sm: 4,
|
|
51
|
+
md: 8,
|
|
52
|
+
lg: 12,
|
|
53
|
+
pill: 999,
|
|
54
|
+
},
|
|
55
|
+
};
|
package/src/types.ts
ADDED
package/src/unistyles.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
2
|
+
import { breakpoints, darkTheme, lightTheme } from "./themes";
|
|
3
|
+
|
|
4
|
+
import "./types";
|
|
5
|
+
|
|
6
|
+
export type UnistylesInitialTheme = "light" | "dark";
|
|
7
|
+
|
|
8
|
+
export interface ConfigureUnistylesOptions {
|
|
9
|
+
initialTheme?: UnistylesInitialTheme;
|
|
10
|
+
adaptiveThemes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const themes = {
|
|
14
|
+
light: lightTheme,
|
|
15
|
+
dark: darkTheme,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const configureUnistyles = ({
|
|
19
|
+
initialTheme = "light",
|
|
20
|
+
adaptiveThemes = true,
|
|
21
|
+
}: ConfigureUnistylesOptions = {}) => {
|
|
22
|
+
StyleSheet.configure({
|
|
23
|
+
themes,
|
|
24
|
+
breakpoints,
|
|
25
|
+
settings: adaptiveThemes ? { adaptiveThemes: true } : { initialTheme },
|
|
26
|
+
});
|
|
27
|
+
};
|
package/dist/index.d.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { PressableProps } from 'react-native';
|
|
3
|
-
|
|
4
|
-
interface ButtonProps extends PressableProps {
|
|
5
|
-
variant?: "primary" | "secondary" | "ghost";
|
|
6
|
-
size?: "sm" | "md" | "lg";
|
|
7
|
-
label: string;
|
|
8
|
-
}
|
|
9
|
-
declare function Button({ variant, size, label, style, ...props }: ButtonProps): react.JSX.Element;
|
|
10
|
-
|
|
11
|
-
export { Button };
|
package/dist/index.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var reactNative = require('react-native');
|
|
4
|
-
|
|
5
|
-
// src/components/Button/Button.tsx
|
|
6
|
-
function Button({ variant = "primary", size = "md", label, style, ...props }) {
|
|
7
|
-
return /* @__PURE__ */ React.createElement(reactNative.Pressable, { style: [styles.base, styles[variant], styles[size], style], ...props }, /* @__PURE__ */ React.createElement(reactNative.Text, { style: styles.label }, label));
|
|
8
|
-
}
|
|
9
|
-
var styles = reactNative.StyleSheet.create({
|
|
10
|
-
base: {
|
|
11
|
-
alignItems: "center",
|
|
12
|
-
justifyContent: "center",
|
|
13
|
-
borderRadius: 8
|
|
14
|
-
},
|
|
15
|
-
label: {
|
|
16
|
-
fontWeight: "600"
|
|
17
|
-
},
|
|
18
|
-
primary: { backgroundColor: "#6366f1" },
|
|
19
|
-
secondary: { backgroundColor: "#e5e7eb" },
|
|
20
|
-
ghost: { backgroundColor: "transparent" },
|
|
21
|
-
sm: { paddingHorizontal: 12, paddingVertical: 6 },
|
|
22
|
-
md: { paddingHorizontal: 16, paddingVertical: 10 },
|
|
23
|
-
lg: { paddingHorizontal: 24, paddingVertical: 14 }
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
exports.Button = Button;
|
|
27
|
-
//# sourceMappingURL=index.js.map
|
|
28
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Button/Button.tsx"],"names":["Pressable","Text","StyleSheet"],"mappings":";;;;;AASO,SAAS,MAAA,CAAO,EAAE,OAAA,GAAU,SAAA,EAAW,IAAA,GAAO,MAAM,KAAA,EAAO,KAAA,EAAO,GAAG,KAAA,EAAM,EAAgB;AAChG,EAAA,uBACE,KAAA,CAAA,aAAA,CAACA,yBAAU,KAAA,EAAO,CAAC,OAAO,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,EAAG,MAAA,CAAO,IAAI,GAAG,KAAkB,CAAA,EAAI,GAAG,KAAA,EAAA,kBACtF,KAAA,CAAA,aAAA,CAACC,oBAAK,KAAA,EAAO,MAAA,CAAO,KAAA,EAAA,EAAQ,KAAM,CACpC,CAAA;AAEJ;AAEA,IAAM,MAAA,GAASC,uBAAW,MAAA,CAAO;AAAA,EAC/B,IAAA,EAAM;AAAA,IACJ,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,UAAA,EAAY;AAAA,GACd;AAAA,EACA,OAAA,EAAS,EAAE,eAAA,EAAiB,SAAA,EAAU;AAAA,EACtC,SAAA,EAAW,EAAE,eAAA,EAAiB,SAAA,EAAU;AAAA,EACxC,KAAA,EAAO,EAAE,eAAA,EAAiB,aAAA,EAAc;AAAA,EACxC,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,CAAA,EAAE;AAAA,EAChD,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,EAAA,EAAG;AAAA,EACjD,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,EAAA;AAChD,CAAC,CAAA","file":"index.js","sourcesContent":["import type { PressableProps, TextStyle, ViewStyle } from \"react-native\";\nimport { Pressable, StyleSheet, Text } from \"react-native\";\n\nexport interface ButtonProps extends PressableProps {\n variant?: \"primary\" | \"secondary\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n label: string;\n}\n\nexport function Button({ variant = \"primary\", size = \"md\", label, style, ...props }: ButtonProps) {\n return (\n <Pressable style={[styles.base, styles[variant], styles[size], style as ViewStyle]} {...props}>\n <Text style={styles.label}>{label}</Text>\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n base: {\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: 8,\n },\n label: {\n fontWeight: \"600\",\n } as TextStyle,\n primary: { backgroundColor: \"#6366f1\" } as ViewStyle,\n secondary: { backgroundColor: \"#e5e7eb\" } as ViewStyle,\n ghost: { backgroundColor: \"transparent\" } as ViewStyle,\n sm: { paddingHorizontal: 12, paddingVertical: 6 } as ViewStyle,\n md: { paddingHorizontal: 16, paddingVertical: 10 } as ViewStyle,\n lg: { paddingHorizontal: 24, paddingVertical: 14 } as ViewStyle,\n});\n"]}
|
package/dist/index.mjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { StyleSheet, Pressable, Text } from 'react-native';
|
|
2
|
-
|
|
3
|
-
// src/components/Button/Button.tsx
|
|
4
|
-
function Button({ variant = "primary", size = "md", label, style, ...props }) {
|
|
5
|
-
return /* @__PURE__ */ React.createElement(Pressable, { style: [styles.base, styles[variant], styles[size], style], ...props }, /* @__PURE__ */ React.createElement(Text, { style: styles.label }, label));
|
|
6
|
-
}
|
|
7
|
-
var styles = StyleSheet.create({
|
|
8
|
-
base: {
|
|
9
|
-
alignItems: "center",
|
|
10
|
-
justifyContent: "center",
|
|
11
|
-
borderRadius: 8
|
|
12
|
-
},
|
|
13
|
-
label: {
|
|
14
|
-
fontWeight: "600"
|
|
15
|
-
},
|
|
16
|
-
primary: { backgroundColor: "#6366f1" },
|
|
17
|
-
secondary: { backgroundColor: "#e5e7eb" },
|
|
18
|
-
ghost: { backgroundColor: "transparent" },
|
|
19
|
-
sm: { paddingHorizontal: 12, paddingVertical: 6 },
|
|
20
|
-
md: { paddingHorizontal: 16, paddingVertical: 10 },
|
|
21
|
-
lg: { paddingHorizontal: 24, paddingVertical: 14 }
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export { Button };
|
|
25
|
-
//# sourceMappingURL=index.mjs.map
|
|
26
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Button/Button.tsx"],"names":[],"mappings":";;;AASO,SAAS,MAAA,CAAO,EAAE,OAAA,GAAU,SAAA,EAAW,IAAA,GAAO,MAAM,KAAA,EAAO,KAAA,EAAO,GAAG,KAAA,EAAM,EAAgB;AAChG,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,aAAU,KAAA,EAAO,CAAC,OAAO,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,EAAG,MAAA,CAAO,IAAI,GAAG,KAAkB,CAAA,EAAI,GAAG,KAAA,EAAA,kBACtF,KAAA,CAAA,aAAA,CAAC,QAAK,KAAA,EAAO,MAAA,CAAO,KAAA,EAAA,EAAQ,KAAM,CACpC,CAAA;AAEJ;AAEA,IAAM,MAAA,GAAS,WAAW,MAAA,CAAO;AAAA,EAC/B,IAAA,EAAM;AAAA,IACJ,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,UAAA,EAAY;AAAA,GACd;AAAA,EACA,OAAA,EAAS,EAAE,eAAA,EAAiB,SAAA,EAAU;AAAA,EACtC,SAAA,EAAW,EAAE,eAAA,EAAiB,SAAA,EAAU;AAAA,EACxC,KAAA,EAAO,EAAE,eAAA,EAAiB,aAAA,EAAc;AAAA,EACxC,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,CAAA,EAAE;AAAA,EAChD,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,EAAA,EAAG;AAAA,EACjD,EAAA,EAAI,EAAE,iBAAA,EAAmB,EAAA,EAAI,iBAAiB,EAAA;AAChD,CAAC,CAAA","file":"index.mjs","sourcesContent":["import type { PressableProps, TextStyle, ViewStyle } from \"react-native\";\nimport { Pressable, StyleSheet, Text } from \"react-native\";\n\nexport interface ButtonProps extends PressableProps {\n variant?: \"primary\" | \"secondary\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n label: string;\n}\n\nexport function Button({ variant = \"primary\", size = \"md\", label, style, ...props }: ButtonProps) {\n return (\n <Pressable style={[styles.base, styles[variant], styles[size], style as ViewStyle]} {...props}>\n <Text style={styles.label}>{label}</Text>\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n base: {\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: 8,\n },\n label: {\n fontWeight: \"600\",\n } as TextStyle,\n primary: { backgroundColor: \"#6366f1\" } as ViewStyle,\n secondary: { backgroundColor: \"#e5e7eb\" } as ViewStyle,\n ghost: { backgroundColor: \"transparent\" } as ViewStyle,\n sm: { paddingHorizontal: 12, paddingVertical: 6 } as ViewStyle,\n md: { paddingHorizontal: 16, paddingVertical: 10 } as ViewStyle,\n lg: { paddingHorizontal: 24, paddingVertical: 14 } as ViewStyle,\n});\n"]}
|