@korsolutions/ui 0.0.16 → 0.0.18

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.
@@ -1,4 +1,4 @@
1
- import { B as FieldStyles, C as SelectStyles, F as InputPrimitiveBaseProps, L as InputStyles, M as ButtonStyles, c as EmptyStyles, m as CardStyles, r as AvatarStyles, x as SelectRootBaseProps } from "../index-Dyo-iQyH.mjs";
1
+ import { B as InputPrimitiveBaseProps, E as SelectRootBaseProps, G as FieldStyles, H as InputStyles, L as ButtonStyles, O as SelectStyles, c as AvatarStyles, p as EmptyStyles, r as ToastStyles, y as CardStyles } from "../index-Bfae0NgJ.mjs";
2
2
  import React from "react";
3
3
  import { ImageSource, TextProps, TextStyle } from "react-native";
4
4
 
@@ -166,4 +166,34 @@ interface AvatarProps {
166
166
  }
167
167
  declare function Avatar(props: AvatarProps): React.JSX.Element;
168
168
  //#endregion
169
- export { Avatar, AvatarProps, Button, Card, Empty, EmptyProps, Field, FieldProps, Input, Link, LinkProps, Select, SelectOption, SelectProps, Typography, TypographyProps };
169
+ //#region src/components/toast/variants/index.d.ts
170
+ declare const ToastVariants: {
171
+ default: () => ToastStyles;
172
+ success: () => ToastStyles;
173
+ danger: () => ToastStyles;
174
+ };
175
+ //#endregion
176
+ //#region src/components/toast/toast-manager.d.ts
177
+ interface ToastConfig {
178
+ id: string;
179
+ title: string;
180
+ description?: string;
181
+ variant?: keyof typeof ToastVariants;
182
+ duration?: number;
183
+ }
184
+ //#endregion
185
+ //#region src/components/toast/toast.d.ts
186
+ interface ToastProps {
187
+ title: string;
188
+ description?: string;
189
+ variant?: keyof typeof ToastVariants;
190
+ }
191
+ declare function ToastComponent(props: ToastProps): React.JSX.Element;
192
+ //#endregion
193
+ //#region src/components/toast/index.d.ts
194
+ declare const Toast: typeof ToastComponent & {
195
+ show: (config: ToastConfig) => string;
196
+ dismiss: (id: string) => void;
197
+ };
198
+ //#endregion
199
+ export { Avatar, AvatarProps, Button, Card, Empty, EmptyProps, Field, FieldProps, Input, Link, LinkProps, Select, SelectOption, SelectProps, Toast, Typography, TypographyProps };
@@ -1,6 +1,5 @@
1
- import { n as useTheme } from "../themes-pgmHo7MU.mjs";
2
- import "../portal-jF1KeGnu.mjs";
3
- import { a as ButtonPrimitive, i as SelectPrimitive, n as EmptyPrimitive, o as InputPrimitive, r as CardPrimitive, s as FieldPrimitive, t as AvatarPrimitive } from "../primitives-BKUnaQrI.mjs";
1
+ import { i as useThemedStyles, r as ToastComponent, t as ToastAPI } from "../toast-manager-Vq38WK76.mjs";
2
+ import { a as SelectPrimitive, c as FieldPrimitive, i as CardPrimitive, n as AvatarPrimitive, o as ButtonPrimitive, r as EmptyPrimitive, s as InputPrimitive } from "../primitives-B4L9y32H.mjs";
4
3
  import React, { useState } from "react";
5
4
  import { Linking, Text } from "react-native";
6
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -23,19 +22,6 @@ const hslaSetRelativeLightness = (hsla, delta) => {
23
22
  return hslaSetLightness(hsla, newLightness);
24
23
  };
25
24
 
26
- //#endregion
27
- //#region src/utils/use-themed-styles.ts
28
- const useThemedStyles = (callback) => {
29
- const theme = useTheme();
30
- return callback({
31
- colors: theme.colors,
32
- radius: theme.radius,
33
- fontFamily: theme.fontFamily,
34
- letterSpacing: theme.letterSpacing,
35
- fontSize: theme.fontSize
36
- });
37
- };
38
-
39
25
  //#endregion
40
26
  //#region src/components/button/variants/default.tsx
41
27
  const useButtonVariantDefault = () => {
@@ -581,4 +567,11 @@ function Avatar(props) {
581
567
  }
582
568
 
583
569
  //#endregion
584
- export { Avatar, Button, Card, Empty, Field, Input, Link, Select, Typography };
570
+ //#region src/components/toast/index.ts
571
+ const Toast = Object.assign(ToastComponent, {
572
+ show: ToastAPI.show,
573
+ dismiss: ToastAPI.dismiss
574
+ });
575
+
576
+ //#endregion
577
+ export { Avatar, Button, Card, Empty, Field, Input, Link, Select, Toast, Typography };
@@ -351,4 +351,43 @@ declare const AvatarPrimitive: {
351
351
  Fallback: typeof AvatarFallback;
352
352
  };
353
353
  //#endregion
354
- export { ButtonPrimitiveRootProps as A, FieldStyles as B, SelectStyles as C, SelectValueProps as D, SelectOverlayProps as E, InputPrimitiveBaseProps as F, FieldDescriptionProps as H, InputPrimitiveProps as I, InputStyles as L, ButtonStyles as M, ButtonPrimitiveLabelProps as N, SelectTriggerProps as O, InputPrimitive as P, FieldPrimitive as R, SelectRootProps as S, SelectContentProps as T, FieldLabelProps as U, FieldErrorProps as V, CardTitleProps as _, AvatarFallbackProps as a, SelectPortalProps as b, EmptyStyles as c, EmptyDescriptionProps as d, CardPrimitive as f, CardBodyProps as g, CardFooterProps as h, AvatarImageProps as i, ButtonState as j, ButtonPrimitive as k, EmptyTitleProps as l, CardStyles as m, AvatarRootProps as n, EmptyPrimitive as o, CardRootProps as p, AvatarStyles as r, EmptyRootProps as s, AvatarPrimitive as t, EmptyMediaProps as u, CardHeaderProps as v, SelectOptionProps as w, SelectRootBaseProps as x, SelectPrimitive as y, FieldPrimitiveRootProps as z };
354
+ //#region src/primitives/toast/toast-title.d.ts
355
+ interface ToastTitleProps {
356
+ children?: string;
357
+ render?: (props: ToastTitleProps) => React$1.ReactNode;
358
+ style?: StyleProp<TextStyle>;
359
+ }
360
+ declare function ToastTitle(props: ToastTitleProps): React$1.JSX.Element;
361
+ //#endregion
362
+ //#region src/primitives/toast/toast-description.d.ts
363
+ interface ToastDescriptionProps {
364
+ children?: string;
365
+ render?: (props: ToastDescriptionProps) => React$1.ReactNode;
366
+ style?: StyleProp<TextStyle>;
367
+ }
368
+ declare function ToastDescription(props: ToastDescriptionProps): React$1.JSX.Element;
369
+ //#endregion
370
+ //#region src/primitives/toast/types.d.ts
371
+ interface ToastStyles {
372
+ root?: ToastRootProps["style"];
373
+ title?: ToastTitleProps["style"];
374
+ description?: ToastDescriptionProps["style"];
375
+ }
376
+ //#endregion
377
+ //#region src/primitives/toast/toast-root.d.ts
378
+ interface ToastRootProps {
379
+ children?: React$1.ReactNode;
380
+ render?: (props: ToastRootProps) => React$1.ReactNode;
381
+ style?: StyleProp<ViewStyle>;
382
+ styles?: ToastStyles;
383
+ }
384
+ declare function ToastRoot(props: ToastRootProps): React$1.JSX.Element;
385
+ //#endregion
386
+ //#region src/primitives/toast/index.d.ts
387
+ declare const ToastPrimitive: {
388
+ Root: typeof ToastRoot;
389
+ Title: typeof ToastTitle;
390
+ Description: typeof ToastDescription;
391
+ };
392
+ //#endregion
393
+ export { SelectContentProps as A, InputPrimitiveBaseProps as B, CardHeaderProps as C, SelectRootProps as D, SelectRootBaseProps as E, ButtonPrimitiveRootProps as F, FieldStyles as G, InputStyles as H, ButtonState as I, FieldLabelProps as J, FieldErrorProps as K, ButtonStyles as L, SelectValueProps as M, SelectTriggerProps as N, SelectStyles as O, ButtonPrimitive as P, ButtonPrimitiveLabelProps as R, CardTitleProps as S, SelectPortalProps as T, FieldPrimitive as U, InputPrimitiveProps as V, FieldPrimitiveRootProps as W, CardPrimitive as _, ToastTitleProps as a, CardFooterProps as b, AvatarStyles as c, EmptyPrimitive as d, EmptyRootProps as f, EmptyDescriptionProps as g, EmptyMediaProps as h, ToastDescriptionProps as i, SelectOverlayProps as j, SelectOptionProps as k, AvatarImageProps as l, EmptyTitleProps as m, ToastRootProps as n, AvatarPrimitive as o, EmptyStyles as p, FieldDescriptionProps as q, ToastStyles as r, AvatarRootProps as s, ToastPrimitive as t, AvatarFallbackProps as u, CardRootProps as v, SelectPrimitive as w, CardBodyProps as x, CardStyles as y, InputPrimitive as z };
package/dist/index.mjs CHANGED
@@ -1,10 +1,14 @@
1
- import { n as useTheme, t as ThemeProvider } from "./themes-pgmHo7MU.mjs";
2
- import { n as PortalHost } from "./portal-jF1KeGnu.mjs";
1
+ import { a as ThemeProvider, n as ToastContainer, o as useTheme } from "./toast-manager-Vq38WK76.mjs";
2
+ import { l as PortalHost } from "./primitives-B4L9y32H.mjs";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
 
5
5
  //#region src/index.tsx
6
6
  const UniversalUIProvider = ({ children }) => {
7
- return /* @__PURE__ */ jsxs(ThemeProvider, { children: [children, /* @__PURE__ */ jsx(PortalHost, {})] });
7
+ return /* @__PURE__ */ jsxs(ThemeProvider, { children: [
8
+ children,
9
+ /* @__PURE__ */ jsx(PortalHost, {}),
10
+ /* @__PURE__ */ jsx(ToastContainer, {})
11
+ ] });
8
12
  };
9
13
 
10
14
  //#endregion
@@ -1,2 +1,2 @@
1
- import { A as ButtonPrimitiveRootProps, B as FieldStyles, C as SelectStyles, D as SelectValueProps, E as SelectOverlayProps, F as InputPrimitiveBaseProps, H as FieldDescriptionProps, I as InputPrimitiveProps, L as InputStyles, M as ButtonStyles, N as ButtonPrimitiveLabelProps, O as SelectTriggerProps, P as InputPrimitive, R as FieldPrimitive, S as SelectRootProps, T as SelectContentProps, U as FieldLabelProps, V as FieldErrorProps, _ as CardTitleProps, a as AvatarFallbackProps, b as SelectPortalProps, c as EmptyStyles, d as EmptyDescriptionProps, f as CardPrimitive, g as CardBodyProps, h as CardFooterProps, i as AvatarImageProps, j as ButtonState, k as ButtonPrimitive, l as EmptyTitleProps, m as CardStyles, n as AvatarRootProps, o as EmptyPrimitive, p as CardRootProps, r as AvatarStyles, s as EmptyRootProps, t as AvatarPrimitive, u as EmptyMediaProps, v as CardHeaderProps, w as SelectOptionProps, x as SelectRootBaseProps, y as SelectPrimitive, z as FieldPrimitiveRootProps } from "../index-Dyo-iQyH.mjs";
2
- export { AvatarFallbackProps, AvatarImageProps, AvatarPrimitive, AvatarRootProps, AvatarStyles, ButtonPrimitive, ButtonPrimitiveLabelProps, ButtonPrimitiveRootProps, ButtonState, ButtonStyles, CardBodyProps, CardFooterProps, CardHeaderProps, CardPrimitive, CardRootProps, CardStyles, CardTitleProps, EmptyDescriptionProps, EmptyMediaProps, EmptyPrimitive, EmptyRootProps, EmptyStyles, EmptyTitleProps, FieldDescriptionProps, FieldErrorProps, FieldLabelProps, FieldPrimitive, FieldPrimitiveRootProps, FieldStyles, InputPrimitive, InputPrimitiveBaseProps, InputPrimitiveProps, InputStyles, SelectContentProps, SelectOptionProps, SelectOverlayProps, SelectPortalProps, SelectPrimitive, SelectRootBaseProps, SelectRootProps, SelectStyles, SelectTriggerProps, SelectValueProps };
1
+ import { A as SelectContentProps, B as InputPrimitiveBaseProps, C as CardHeaderProps, D as SelectRootProps, E as SelectRootBaseProps, F as ButtonPrimitiveRootProps, G as FieldStyles, H as InputStyles, I as ButtonState, J as FieldLabelProps, K as FieldErrorProps, L as ButtonStyles, M as SelectValueProps, N as SelectTriggerProps, O as SelectStyles, P as ButtonPrimitive, R as ButtonPrimitiveLabelProps, S as CardTitleProps, T as SelectPortalProps, U as FieldPrimitive, V as InputPrimitiveProps, W as FieldPrimitiveRootProps, _ as CardPrimitive, a as ToastTitleProps, b as CardFooterProps, c as AvatarStyles, d as EmptyPrimitive, f as EmptyRootProps, g as EmptyDescriptionProps, h as EmptyMediaProps, i as ToastDescriptionProps, j as SelectOverlayProps, k as SelectOptionProps, l as AvatarImageProps, m as EmptyTitleProps, n as ToastRootProps, o as AvatarPrimitive, p as EmptyStyles, q as FieldDescriptionProps, r as ToastStyles, s as AvatarRootProps, t as ToastPrimitive, u as AvatarFallbackProps, v as CardRootProps, w as SelectPrimitive, x as CardBodyProps, y as CardStyles, z as InputPrimitive } from "../index-Bfae0NgJ.mjs";
2
+ export { AvatarFallbackProps, AvatarImageProps, AvatarPrimitive, AvatarRootProps, AvatarStyles, ButtonPrimitive, ButtonPrimitiveLabelProps, ButtonPrimitiveRootProps, ButtonState, ButtonStyles, CardBodyProps, CardFooterProps, CardHeaderProps, CardPrimitive, CardRootProps, CardStyles, CardTitleProps, EmptyDescriptionProps, EmptyMediaProps, EmptyPrimitive, EmptyRootProps, EmptyStyles, EmptyTitleProps, FieldDescriptionProps, FieldErrorProps, FieldLabelProps, FieldPrimitive, FieldPrimitiveRootProps, FieldStyles, InputPrimitive, InputPrimitiveBaseProps, InputPrimitiveProps, InputStyles, SelectContentProps, SelectOptionProps, SelectOverlayProps, SelectPortalProps, SelectPrimitive, SelectRootBaseProps, SelectRootProps, SelectStyles, SelectTriggerProps, SelectValueProps, ToastDescriptionProps, ToastPrimitive, ToastRootProps, ToastStyles, ToastTitleProps };
@@ -1,4 +1,3 @@
1
- import "../portal-jF1KeGnu.mjs";
2
- import { a as ButtonPrimitive, i as SelectPrimitive, n as EmptyPrimitive, o as InputPrimitive, r as CardPrimitive, s as FieldPrimitive, t as AvatarPrimitive } from "../primitives-BKUnaQrI.mjs";
1
+ import { a as SelectPrimitive, c as FieldPrimitive, i as CardPrimitive, n as AvatarPrimitive, o as ButtonPrimitive, r as EmptyPrimitive, s as InputPrimitive, t as ToastPrimitive } from "../primitives-B4L9y32H.mjs";
3
2
 
4
- export { AvatarPrimitive, ButtonPrimitive, CardPrimitive, EmptyPrimitive, FieldPrimitive, InputPrimitive, SelectPrimitive };
3
+ export { AvatarPrimitive, ButtonPrimitive, CardPrimitive, EmptyPrimitive, FieldPrimitive, InputPrimitive, SelectPrimitive, ToastPrimitive };
@@ -1,8 +1,63 @@
1
- import { t as Portal } from "./portal-jF1KeGnu.mjs";
2
- import React, { createContext, useContext, useEffect, useState } from "react";
1
+ import React, { createContext, useContext, useEffect, useState, useSyncExternalStore } from "react";
3
2
  import { ActivityIndicator, Image, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
4
- import { jsx } from "react/jsx-runtime";
3
+ import { Fragment, jsx } from "react/jsx-runtime";
5
4
 
5
+ //#region src/primitives/portal/portal.tsx
6
+ const DEFAULT_PORTAL_HOST = "KOR_NATIVE_DEFAULT_HOST_NAME";
7
+ const store = {
8
+ map: (/* @__PURE__ */ new Map()).set(DEFAULT_PORTAL_HOST, /* @__PURE__ */ new Map()),
9
+ listeners: /* @__PURE__ */ new Set()
10
+ };
11
+ function emit() {
12
+ for (const cb of store.listeners) cb();
13
+ }
14
+ function getSnapshot() {
15
+ return store.map;
16
+ }
17
+ function subscribe(cb) {
18
+ store.listeners.add(cb);
19
+ return () => {
20
+ store.listeners.delete(cb);
21
+ };
22
+ }
23
+ function updatePortal(hostName, name, children) {
24
+ const next = new Map(store.map);
25
+ const portal = next.get(hostName) ?? /* @__PURE__ */ new Map();
26
+ portal.set(name, children);
27
+ next.set(hostName, portal);
28
+ store.map = next;
29
+ emit();
30
+ }
31
+ function removePortal(hostName, name) {
32
+ const next = new Map(store.map);
33
+ const portal = next.get(hostName) ?? /* @__PURE__ */ new Map();
34
+ portal.delete(name);
35
+ next.set(hostName, portal);
36
+ store.map = next;
37
+ emit();
38
+ }
39
+ function PortalHost({ name = DEFAULT_PORTAL_HOST }) {
40
+ const portalMap = useSyncExternalStore(subscribe, getSnapshot, getSnapshot).get(name) ?? /* @__PURE__ */ new Map();
41
+ if (portalMap.size === 0) return null;
42
+ return /* @__PURE__ */ jsx(Fragment, { children: Array.from(portalMap.values()) });
43
+ }
44
+ function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }) {
45
+ useEffect(() => {
46
+ updatePortal(hostName, name, children);
47
+ }, [
48
+ hostName,
49
+ name,
50
+ children
51
+ ]);
52
+ useEffect(() => {
53
+ return () => {
54
+ removePortal(hostName, name);
55
+ };
56
+ }, [hostName, name]);
57
+ return null;
58
+ }
59
+
60
+ //#endregion
6
61
  //#region src/primitives/field/context.ts
7
62
  const FieldContext = createContext(void 0);
8
63
  const useField = () => {
@@ -555,4 +610,55 @@ const AvatarPrimitive = {
555
610
  };
556
611
 
557
612
  //#endregion
558
- export { ButtonPrimitive as a, SelectPrimitive as i, EmptyPrimitive as n, InputPrimitive as o, CardPrimitive as r, FieldPrimitive as s, AvatarPrimitive as t };
613
+ //#region src/primitives/toast/context.ts
614
+ const ToastContext = createContext(void 0);
615
+ const useToast = () => {
616
+ const context = useContext(ToastContext);
617
+ if (!context) throw new Error("useToast must be used within a ToastProvider");
618
+ return context;
619
+ };
620
+
621
+ //#endregion
622
+ //#region src/primitives/toast/toast-root.tsx
623
+ function ToastRoot(props) {
624
+ const composedStyle = [props.styles?.root, props.style];
625
+ const Component = props.render ?? View;
626
+ return /* @__PURE__ */ jsx(ToastContext.Provider, {
627
+ value: { styles: props.styles },
628
+ children: /* @__PURE__ */ jsx(Component, {
629
+ ...props,
630
+ style: composedStyle
631
+ })
632
+ });
633
+ }
634
+
635
+ //#endregion
636
+ //#region src/primitives/toast/toast-title.tsx
637
+ function ToastTitle(props) {
638
+ const composedStyle = [useToast().styles?.title, props.style];
639
+ return /* @__PURE__ */ jsx(props.render ?? Text, {
640
+ ...props,
641
+ style: composedStyle
642
+ });
643
+ }
644
+
645
+ //#endregion
646
+ //#region src/primitives/toast/toast-description.tsx
647
+ function ToastDescription(props) {
648
+ const composedStyle = [useToast().styles?.description, props.style];
649
+ return /* @__PURE__ */ jsx(props.render ?? Text, {
650
+ ...props,
651
+ style: composedStyle
652
+ });
653
+ }
654
+
655
+ //#endregion
656
+ //#region src/primitives/toast/index.ts
657
+ const ToastPrimitive = {
658
+ Root: ToastRoot,
659
+ Title: ToastTitle,
660
+ Description: ToastDescription
661
+ };
662
+
663
+ //#endregion
664
+ export { SelectPrimitive as a, FieldPrimitive as c, CardPrimitive as i, PortalHost as l, AvatarPrimitive as n, ButtonPrimitive as o, EmptyPrimitive as r, InputPrimitive as s, ToastPrimitive as t };
@@ -0,0 +1,281 @@
1
+ import { t as ToastPrimitive } from "./primitives-B4L9y32H.mjs";
2
+ import React, { createContext, useContext, useEffect, useState, useSyncExternalStore } from "react";
3
+ import { StyleSheet, View, useColorScheme } from "react-native";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+
6
+ //#region src/themes/default/colors.ts
7
+ const lightColors = {
8
+ background: "hsla(223.81, 100%, 100%, 1)",
9
+ foreground: "hsla(223.81, 0%, 3.94%, 1)",
10
+ primary: "hsla(223.81, 0%, 9.05%, 1)",
11
+ primaryForeground: "hsla(223.81, 0%, 98.03%, 1)",
12
+ secondary: "hsla(223.81, 0%, 96.06%, 1)",
13
+ secondaryForeground: "hsla(223.81, 0%, 9.05%, 1)",
14
+ muted: "hsla(223.81, 0%, 96.06%, 1)",
15
+ mutedForeground: "hsla(223.81, 0%, 45.15%, 1)",
16
+ border: "hsla(223.81, 0%, 89.82%, 1)",
17
+ surface: "hsla(223.81, 100%, 100%, 1)",
18
+ danger: "hsla(0, 84.2%, 60.2%, 1)",
19
+ success: "hsla(173, 58%, 39%, 1)",
20
+ warning: "hsla(43, 74%, 66%, 1)",
21
+ info: "hsla(197, 37%, 24%, 1)"
22
+ };
23
+ const darkColors = {
24
+ background: "hsla(223.81, 0%, 3.94%, 1)",
25
+ foreground: "hsla(223.81, 0%, 98.03%, 1)",
26
+ primary: "hsla(223.81, 0%, 89.82%, 1)",
27
+ primaryForeground: "hsla(223.81, 0%, 9.05%, 1)",
28
+ secondary: "hsla(223.81, 0%, 14.94%, 1)",
29
+ secondaryForeground: "hsla(223.81, 0%, 98.03%, 1)",
30
+ muted: "hsla(223.81, 0%, 14.94%, 1)",
31
+ mutedForeground: "hsla(223.81, 0%, 63.02%, 1)",
32
+ border: "hsla(223.81, 0%, 15.51%, 1)",
33
+ surface: "hsla(223.81, 0%, 9.05%, 1)",
34
+ danger: "hsla(0, 62.8%, 30.6%, 1)",
35
+ success: "hsla(160, 60%, 45%, 1)",
36
+ warning: "hsla(30, 80%, 55%, 1)",
37
+ info: "hsla(220, 70%, 50%, 1)"
38
+ };
39
+
40
+ //#endregion
41
+ //#region src/themes/default/index.ts
42
+ const defaultThemeAssets = {
43
+ colors: {
44
+ light: lightColors,
45
+ dark: darkColors
46
+ },
47
+ radius: 10,
48
+ fontFamily: "System",
49
+ letterSpacing: 0,
50
+ fontSize: 16
51
+ };
52
+
53
+ //#endregion
54
+ //#region src/themes/themes.ts
55
+ const themes = { default: defaultThemeAssets };
56
+
57
+ //#endregion
58
+ //#region src/themes/provider.tsx
59
+ const ThemeContext = createContext(null);
60
+ const ThemeProvider = (props) => {
61
+ const [themeName, setTheme] = useState("default");
62
+ const systemColorScheme = useColorScheme();
63
+ const [colorScheme, setColorScheme] = useState(systemColorScheme ?? "light");
64
+ const themesAssets = themes[themeName];
65
+ const colors = themesAssets.colors[colorScheme];
66
+ useEffect(() => {
67
+ if (systemColorScheme) setColorScheme(systemColorScheme);
68
+ }, [systemColorScheme]);
69
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, {
70
+ value: {
71
+ themeName,
72
+ setTheme,
73
+ colorScheme,
74
+ setColorScheme,
75
+ colors,
76
+ radius: themesAssets.radius,
77
+ fontFamily: themesAssets.fontFamily,
78
+ letterSpacing: themesAssets.letterSpacing,
79
+ fontSize: themesAssets.fontSize
80
+ },
81
+ children: props.children
82
+ });
83
+ };
84
+ const useTheme = () => {
85
+ const context = useContext(ThemeContext);
86
+ if (!context) throw new Error("useTheme must be used within a ThemeProvider");
87
+ return context;
88
+ };
89
+
90
+ //#endregion
91
+ //#region src/utils/use-themed-styles.ts
92
+ const useThemedStyles = (callback) => {
93
+ const theme = useTheme();
94
+ return callback({
95
+ colors: theme.colors,
96
+ radius: theme.radius,
97
+ fontFamily: theme.fontFamily,
98
+ letterSpacing: theme.letterSpacing,
99
+ fontSize: theme.fontSize
100
+ });
101
+ };
102
+
103
+ //#endregion
104
+ //#region src/components/toast/variants/default.tsx
105
+ const useToastVariantDefault = () => {
106
+ return useThemedStyles(({ colors, radius, fontFamily, fontSize }) => ({
107
+ root: {
108
+ backgroundColor: colors.surface,
109
+ borderWidth: 1,
110
+ borderColor: colors.border,
111
+ borderRadius: radius,
112
+ padding: 16,
113
+ gap: 4,
114
+ minWidth: 300,
115
+ maxWidth: 400
116
+ },
117
+ title: {
118
+ color: colors.foreground,
119
+ fontSize,
120
+ fontWeight: "600",
121
+ fontFamily
122
+ },
123
+ description: {
124
+ color: colors.mutedForeground,
125
+ fontSize: fontSize * .875,
126
+ fontFamily
127
+ }
128
+ }));
129
+ };
130
+
131
+ //#endregion
132
+ //#region src/components/toast/variants/success.tsx
133
+ const useToastVariantSuccess = () => {
134
+ return useThemedStyles(({ colors, radius, fontFamily, fontSize }) => ({
135
+ root: {
136
+ backgroundColor: colors.success,
137
+ borderWidth: 1,
138
+ borderColor: colors.success,
139
+ borderRadius: radius,
140
+ padding: 16,
141
+ gap: 4,
142
+ minWidth: 300,
143
+ maxWidth: 400
144
+ },
145
+ title: {
146
+ color: colors.foreground,
147
+ fontSize,
148
+ fontWeight: "600",
149
+ fontFamily
150
+ },
151
+ description: {
152
+ color: colors.foreground,
153
+ fontSize: fontSize * .875,
154
+ fontFamily,
155
+ opacity: .9
156
+ }
157
+ }));
158
+ };
159
+
160
+ //#endregion
161
+ //#region src/components/toast/variants/danger.tsx
162
+ const useToastVariantDanger = () => {
163
+ return useThemedStyles(({ colors, radius, fontFamily, fontSize }) => ({
164
+ root: {
165
+ backgroundColor: colors.danger,
166
+ borderWidth: 1,
167
+ borderColor: colors.danger,
168
+ borderRadius: radius,
169
+ padding: 16,
170
+ gap: 4,
171
+ minWidth: 300,
172
+ maxWidth: 400
173
+ },
174
+ title: {
175
+ color: colors.foreground,
176
+ fontSize,
177
+ fontWeight: "600",
178
+ fontFamily
179
+ },
180
+ description: {
181
+ color: colors.foreground,
182
+ fontSize: fontSize * .875,
183
+ fontFamily,
184
+ opacity: .9
185
+ }
186
+ }));
187
+ };
188
+
189
+ //#endregion
190
+ //#region src/components/toast/variants/index.ts
191
+ const ToastVariants = {
192
+ default: useToastVariantDefault,
193
+ success: useToastVariantSuccess,
194
+ danger: useToastVariantDanger
195
+ };
196
+
197
+ //#endregion
198
+ //#region src/components/toast/toast.tsx
199
+ function ToastComponent(props) {
200
+ const useVariantStyles = ToastVariants[props.variant || "default"];
201
+ const styles$1 = useVariantStyles();
202
+ return /* @__PURE__ */ jsxs(ToastPrimitive.Root, {
203
+ styles: styles$1,
204
+ children: [/* @__PURE__ */ jsx(ToastPrimitive.Title, { children: props.title }), !!props.description && /* @__PURE__ */ jsx(ToastPrimitive.Description, { children: props.description })]
205
+ });
206
+ }
207
+
208
+ //#endregion
209
+ //#region src/components/toast/toast-manager.tsx
210
+ const store = {
211
+ toasts: [],
212
+ listeners: /* @__PURE__ */ new Set()
213
+ };
214
+ function emit() {
215
+ for (const cb of store.listeners) cb();
216
+ }
217
+ function getSnapshot() {
218
+ return store.toasts;
219
+ }
220
+ function subscribe(cb) {
221
+ store.listeners.add(cb);
222
+ return () => {
223
+ store.listeners.delete(cb);
224
+ };
225
+ }
226
+ function addToast(config) {
227
+ const existingToast = store.toasts.find((t) => t.id === config.id);
228
+ if (existingToast) return existingToast.id;
229
+ const toast = {
230
+ duration: 3e3,
231
+ ...config
232
+ };
233
+ store.toasts = [...store.toasts, toast];
234
+ emit();
235
+ if (toast.duration) setTimeout(() => {
236
+ removeToast(toast.id);
237
+ }, toast.duration);
238
+ return toast.id;
239
+ }
240
+ function removeToast(id) {
241
+ store.toasts = store.toasts.filter((t) => t.id !== id);
242
+ emit();
243
+ }
244
+ const ToastAPI = {
245
+ show: addToast,
246
+ dismiss: removeToast
247
+ };
248
+ function ToastContainer() {
249
+ const toasts = useSyncExternalStore(subscribe, getSnapshot);
250
+ if (!toasts.length) return null;
251
+ return /* @__PURE__ */ jsx(View, {
252
+ style: styles.container,
253
+ pointerEvents: "box-none",
254
+ children: toasts.map((toast) => /* @__PURE__ */ jsx(View, {
255
+ style: styles.toastWrapper,
256
+ children: /* @__PURE__ */ jsx(ToastComponent, {
257
+ title: toast.title,
258
+ description: toast.description,
259
+ variant: toast.variant
260
+ })
261
+ }, toast.id))
262
+ });
263
+ }
264
+ const styles = StyleSheet.create({
265
+ container: {
266
+ position: "absolute",
267
+ top: 50,
268
+ left: 0,
269
+ right: 0,
270
+ alignItems: "center",
271
+ gap: 12,
272
+ zIndex: 9999
273
+ },
274
+ toastWrapper: {
275
+ width: "100%",
276
+ alignItems: "center"
277
+ }
278
+ });
279
+
280
+ //#endregion
281
+ export { ThemeProvider as a, useThemedStyles as i, ToastContainer as n, useTheme as o, ToastComponent as r, ToastAPI as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korsolutions/ui",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.mjs",
6
6
  "module": "dist/index.mjs",
@@ -7,3 +7,4 @@ export * from "./typography/typography";
7
7
  export * from "./link/link";
8
8
  export * from "./empty/empty";
9
9
  export * from "./avatar/avatar";
10
+ export * from "./toast/index";
@@ -0,0 +1,7 @@
1
+ import { ToastComponent } from "./toast";
2
+ import { ToastAPI } from "./toast-manager";
3
+
4
+ export const Toast = Object.assign(ToastComponent, {
5
+ show: ToastAPI.show,
6
+ dismiss: ToastAPI.dismiss,
7
+ });
@@ -0,0 +1,104 @@
1
+ import React, { useSyncExternalStore } from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { ToastComponent } from "./toast";
4
+ import { ToastVariants } from "./variants";
5
+
6
+ export interface ToastConfig {
7
+ id: string;
8
+ title: string;
9
+ description?: string;
10
+ variant?: keyof typeof ToastVariants;
11
+ duration?: number;
12
+ }
13
+
14
+ type ToastStore = {
15
+ toasts: ToastConfig[];
16
+ listeners: Set<() => void>;
17
+ };
18
+
19
+ const store: ToastStore = {
20
+ toasts: [],
21
+ listeners: new Set(),
22
+ };
23
+
24
+ function emit() {
25
+ for (const cb of store.listeners) cb();
26
+ }
27
+
28
+ function getSnapshot() {
29
+ return store.toasts;
30
+ }
31
+
32
+ function subscribe(cb: () => void) {
33
+ store.listeners.add(cb);
34
+ return () => {
35
+ store.listeners.delete(cb);
36
+ };
37
+ }
38
+
39
+ function addToast(config: ToastConfig): string {
40
+ // Check if toast with this ID already exists
41
+ const existingToast = store.toasts.find((t) => t.id === config.id);
42
+ if (existingToast) {
43
+ return existingToast.id;
44
+ }
45
+
46
+ const toast: ToastConfig = {
47
+ duration: 3000,
48
+ ...config,
49
+ };
50
+
51
+ store.toasts = [...store.toasts, toast];
52
+ emit();
53
+
54
+ // Auto-dismiss after duration
55
+ if (toast.duration) {
56
+ setTimeout(() => {
57
+ removeToast(toast.id);
58
+ }, toast.duration);
59
+ }
60
+
61
+ return toast.id;
62
+ }
63
+
64
+ function removeToast(id: string): void {
65
+ store.toasts = store.toasts.filter((t) => t.id !== id);
66
+ emit();
67
+ }
68
+
69
+ export const ToastAPI = {
70
+ show: addToast,
71
+ dismiss: removeToast,
72
+ };
73
+
74
+ export function ToastContainer() {
75
+ const toasts = useSyncExternalStore(subscribe, getSnapshot);
76
+
77
+ if (!toasts.length) return null;
78
+
79
+ return (
80
+ <View style={styles.container} pointerEvents="box-none">
81
+ {toasts.map((toast) => (
82
+ <View key={toast.id} style={styles.toastWrapper}>
83
+ <ToastComponent title={toast.title} description={toast.description} variant={toast.variant} />
84
+ </View>
85
+ ))}
86
+ </View>
87
+ );
88
+ }
89
+
90
+ const styles = StyleSheet.create({
91
+ container: {
92
+ position: "absolute",
93
+ top: 50,
94
+ left: 0,
95
+ right: 0,
96
+ alignItems: "center",
97
+ gap: 12,
98
+ zIndex: 9999,
99
+ },
100
+ toastWrapper: {
101
+ width: "100%",
102
+ alignItems: "center",
103
+ },
104
+ });
@@ -0,0 +1,22 @@
1
+ import { ToastPrimitive } from "@/primitives";
2
+ import React from "react";
3
+ import { ToastVariants } from "./variants";
4
+
5
+ interface ToastProps {
6
+ title: string;
7
+ description?: string;
8
+
9
+ variant?: keyof typeof ToastVariants;
10
+ }
11
+
12
+ export function ToastComponent(props: ToastProps) {
13
+ const useVariantStyles = ToastVariants[props.variant || "default"];
14
+ const styles = useVariantStyles();
15
+
16
+ return (
17
+ <ToastPrimitive.Root styles={styles}>
18
+ <ToastPrimitive.Title>{props.title}</ToastPrimitive.Title>
19
+ {!!props.description && <ToastPrimitive.Description>{props.description}</ToastPrimitive.Description>}
20
+ </ToastPrimitive.Root>
21
+ );
22
+ }
@@ -0,0 +1,31 @@
1
+ import { ToastStyles } from "@/primitives";
2
+ import { useThemedStyles } from "@/utils/use-themed-styles";
3
+
4
+ export const useToastVariantDanger = (): ToastStyles => {
5
+ return useThemedStyles(
6
+ ({ colors, radius, fontFamily, fontSize }): ToastStyles => ({
7
+ root: {
8
+ backgroundColor: colors.danger,
9
+ borderWidth: 1,
10
+ borderColor: colors.danger,
11
+ borderRadius: radius,
12
+ padding: 16,
13
+ gap: 4,
14
+ minWidth: 300,
15
+ maxWidth: 400,
16
+ },
17
+ title: {
18
+ color: colors.foreground,
19
+ fontSize: fontSize,
20
+ fontWeight: "600",
21
+ fontFamily,
22
+ },
23
+ description: {
24
+ color: colors.foreground,
25
+ fontSize: fontSize * 0.875,
26
+ fontFamily,
27
+ opacity: 0.9,
28
+ },
29
+ })
30
+ );
31
+ };
@@ -0,0 +1,30 @@
1
+ import { ToastStyles } from "@/primitives";
2
+ import { useThemedStyles } from "@/utils/use-themed-styles";
3
+
4
+ export const useToastVariantDefault = (): ToastStyles => {
5
+ return useThemedStyles(
6
+ ({ colors, radius, fontFamily, fontSize }): ToastStyles => ({
7
+ root: {
8
+ backgroundColor: colors.surface,
9
+ borderWidth: 1,
10
+ borderColor: colors.border,
11
+ borderRadius: radius,
12
+ padding: 16,
13
+ gap: 4,
14
+ minWidth: 300,
15
+ maxWidth: 400,
16
+ },
17
+ title: {
18
+ color: colors.foreground,
19
+ fontSize: fontSize,
20
+ fontWeight: "600",
21
+ fontFamily,
22
+ },
23
+ description: {
24
+ color: colors.mutedForeground,
25
+ fontSize: fontSize * 0.875,
26
+ fontFamily,
27
+ },
28
+ })
29
+ );
30
+ };
@@ -0,0 +1,9 @@
1
+ import { useToastVariantDefault } from "./default";
2
+ import { useToastVariantSuccess } from "./success";
3
+ import { useToastVariantDanger } from "./danger";
4
+
5
+ export const ToastVariants = {
6
+ default: useToastVariantDefault,
7
+ success: useToastVariantSuccess,
8
+ danger: useToastVariantDanger,
9
+ };
@@ -0,0 +1,31 @@
1
+ import { ToastStyles } from "@/primitives";
2
+ import { useThemedStyles } from "@/utils/use-themed-styles";
3
+
4
+ export const useToastVariantSuccess = (): ToastStyles => {
5
+ return useThemedStyles(
6
+ ({ colors, radius, fontFamily, fontSize }): ToastStyles => ({
7
+ root: {
8
+ backgroundColor: colors.success,
9
+ borderWidth: 1,
10
+ borderColor: colors.success,
11
+ borderRadius: radius,
12
+ padding: 16,
13
+ gap: 4,
14
+ minWidth: 300,
15
+ maxWidth: 400,
16
+ },
17
+ title: {
18
+ color: colors.foreground,
19
+ fontSize: fontSize,
20
+ fontWeight: "600",
21
+ fontFamily,
22
+ },
23
+ description: {
24
+ color: colors.foreground,
25
+ fontSize: fontSize * 0.875,
26
+ fontFamily,
27
+ opacity: 0.9,
28
+ },
29
+ })
30
+ );
31
+ };
package/src/index.tsx CHANGED
@@ -1,11 +1,13 @@
1
1
  import { ThemeProvider } from "@/themes";
2
2
  import { PortalHost } from "./primitives/portal";
3
+ import { ToastContainer } from "./components/toast/toast-manager";
3
4
 
4
5
  export const UniversalUIProvider = ({ children }: { children: React.ReactNode }) => {
5
6
  return (
6
7
  <ThemeProvider>
7
8
  {children}
8
9
  <PortalHost />
10
+ <ToastContainer />
9
11
  </ThemeProvider>
10
12
  );
11
13
  };
@@ -5,3 +5,4 @@ export * from "./select";
5
5
  export * from "./card";
6
6
  export * from "./empty";
7
7
  export * from "./avatar";
8
+ export * from "./toast";
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext } from "react";
2
+ import { ToastStyles } from "./types";
3
+
4
+ export interface ToastContext {
5
+ styles?: ToastStyles;
6
+ }
7
+
8
+ export const ToastContext = createContext<ToastContext | undefined>(undefined);
9
+
10
+ export const useToast = () => {
11
+ const context = useContext(ToastContext);
12
+ if (!context) {
13
+ throw new Error("useToast must be used within a ToastProvider");
14
+ }
15
+ return context;
16
+ };
@@ -0,0 +1,14 @@
1
+ import { ToastRoot } from "./toast-root";
2
+ import { ToastTitle } from "./toast-title";
3
+ import { ToastDescription } from "./toast-description";
4
+
5
+ export const ToastPrimitive = {
6
+ Root: ToastRoot,
7
+ Title: ToastTitle,
8
+ Description: ToastDescription,
9
+ };
10
+
11
+ export type { ToastRootProps } from "./toast-root";
12
+ export type { ToastTitleProps } from "./toast-title";
13
+ export type { ToastDescriptionProps } from "./toast-description";
14
+ export type { ToastStyles } from "./types";
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { StyleProp, Text, TextStyle } from "react-native";
3
+ import { useToast } from "./context";
4
+
5
+ export interface ToastDescriptionProps {
6
+ children?: string;
7
+
8
+ render?: (props: ToastDescriptionProps) => React.ReactNode;
9
+
10
+ style?: StyleProp<TextStyle>;
11
+ }
12
+
13
+ export function ToastDescription(props: ToastDescriptionProps) {
14
+ const toast = useToast();
15
+
16
+ const composedStyle = [toast.styles?.description, props.style];
17
+
18
+ const Component = props.render ?? Text;
19
+ return <Component {...props} style={composedStyle} />;
20
+ }
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { StyleProp, View, ViewStyle } from "react-native";
3
+ import { ToastStyles } from "./types";
4
+ import { ToastContext } from "./context";
5
+
6
+ export interface ToastRootProps {
7
+ children?: React.ReactNode;
8
+
9
+ render?: (props: ToastRootProps) => React.ReactNode;
10
+
11
+ style?: StyleProp<ViewStyle>;
12
+ styles?: ToastStyles;
13
+ }
14
+
15
+ export function ToastRoot(props: ToastRootProps) {
16
+ const composedStyle = [props.styles?.root, props.style];
17
+
18
+ const Component = props.render ?? View;
19
+ return (
20
+ <ToastContext.Provider
21
+ value={{
22
+ styles: props.styles,
23
+ }}
24
+ >
25
+ <Component {...props} style={composedStyle} />
26
+ </ToastContext.Provider>
27
+ );
28
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { StyleProp, Text, TextStyle } from "react-native";
3
+ import { useToast } from "./context";
4
+
5
+ export interface ToastTitleProps {
6
+ children?: string;
7
+
8
+ render?: (props: ToastTitleProps) => React.ReactNode;
9
+
10
+ style?: StyleProp<TextStyle>;
11
+ }
12
+
13
+ export function ToastTitle(props: ToastTitleProps) {
14
+ const toast = useToast();
15
+
16
+ const composedStyle = [toast.styles?.title, props.style];
17
+
18
+ const Component = props.render ?? Text;
19
+ return <Component {...props} style={composedStyle} />;
20
+ }
@@ -0,0 +1,9 @@
1
+ import { ToastRootProps } from "./toast-root";
2
+ import { ToastTitleProps } from "./toast-title";
3
+ import { ToastDescriptionProps } from "./toast-description";
4
+
5
+ export interface ToastStyles {
6
+ root?: ToastRootProps["style"];
7
+ title?: ToastTitleProps["style"];
8
+ description?: ToastDescriptionProps["style"];
9
+ }
@@ -1,61 +0,0 @@
1
- import { useEffect, useState, useSyncExternalStore } from "react";
2
- import "react-native";
3
- import { Fragment, jsx } from "react/jsx-runtime";
4
-
5
- //#region src/primitives/portal/portal.tsx
6
- const DEFAULT_PORTAL_HOST = "KOR_NATIVE_DEFAULT_HOST_NAME";
7
- const store = {
8
- map: (/* @__PURE__ */ new Map()).set(DEFAULT_PORTAL_HOST, /* @__PURE__ */ new Map()),
9
- listeners: /* @__PURE__ */ new Set()
10
- };
11
- function emit() {
12
- for (const cb of store.listeners) cb();
13
- }
14
- function getSnapshot() {
15
- return store.map;
16
- }
17
- function subscribe(cb) {
18
- store.listeners.add(cb);
19
- return () => {
20
- store.listeners.delete(cb);
21
- };
22
- }
23
- function updatePortal(hostName, name, children) {
24
- const next = new Map(store.map);
25
- const portal = next.get(hostName) ?? /* @__PURE__ */ new Map();
26
- portal.set(name, children);
27
- next.set(hostName, portal);
28
- store.map = next;
29
- emit();
30
- }
31
- function removePortal(hostName, name) {
32
- const next = new Map(store.map);
33
- const portal = next.get(hostName) ?? /* @__PURE__ */ new Map();
34
- portal.delete(name);
35
- next.set(hostName, portal);
36
- store.map = next;
37
- emit();
38
- }
39
- function PortalHost({ name = DEFAULT_PORTAL_HOST }) {
40
- const portalMap = useSyncExternalStore(subscribe, getSnapshot, getSnapshot).get(name) ?? /* @__PURE__ */ new Map();
41
- if (portalMap.size === 0) return null;
42
- return /* @__PURE__ */ jsx(Fragment, { children: Array.from(portalMap.values()) });
43
- }
44
- function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }) {
45
- useEffect(() => {
46
- updatePortal(hostName, name, children);
47
- }, [
48
- hostName,
49
- name,
50
- children
51
- ]);
52
- useEffect(() => {
53
- return () => {
54
- removePortal(hostName, name);
55
- };
56
- }, [hostName, name]);
57
- return null;
58
- }
59
-
60
- //#endregion
61
- export { PortalHost as n, Portal as t };
@@ -1,90 +0,0 @@
1
- import { createContext, useContext, useEffect, useState } from "react";
2
- import { useColorScheme } from "react-native";
3
- import { jsx } from "react/jsx-runtime";
4
-
5
- //#region src/themes/default/colors.ts
6
- const lightColors = {
7
- background: "hsla(223.81, 100%, 100%, 1)",
8
- foreground: "hsla(223.81, 0%, 3.94%, 1)",
9
- primary: "hsla(223.81, 0%, 9.05%, 1)",
10
- primaryForeground: "hsla(223.81, 0%, 98.03%, 1)",
11
- secondary: "hsla(223.81, 0%, 96.06%, 1)",
12
- secondaryForeground: "hsla(223.81, 0%, 9.05%, 1)",
13
- muted: "hsla(223.81, 0%, 96.06%, 1)",
14
- mutedForeground: "hsla(223.81, 0%, 45.15%, 1)",
15
- border: "hsla(223.81, 0%, 89.82%, 1)",
16
- surface: "hsla(223.81, 100%, 100%, 1)",
17
- danger: "hsla(0, 84.2%, 60.2%, 1)",
18
- success: "hsla(173, 58%, 39%, 1)",
19
- warning: "hsla(43, 74%, 66%, 1)",
20
- info: "hsla(197, 37%, 24%, 1)"
21
- };
22
- const darkColors = {
23
- background: "hsla(223.81, 0%, 3.94%, 1)",
24
- foreground: "hsla(223.81, 0%, 98.03%, 1)",
25
- primary: "hsla(223.81, 0%, 89.82%, 1)",
26
- primaryForeground: "hsla(223.81, 0%, 9.05%, 1)",
27
- secondary: "hsla(223.81, 0%, 14.94%, 1)",
28
- secondaryForeground: "hsla(223.81, 0%, 98.03%, 1)",
29
- muted: "hsla(223.81, 0%, 14.94%, 1)",
30
- mutedForeground: "hsla(223.81, 0%, 63.02%, 1)",
31
- border: "hsla(223.81, 0%, 15.51%, 1)",
32
- surface: "hsla(223.81, 0%, 9.05%, 1)",
33
- danger: "hsla(0, 62.8%, 30.6%, 1)",
34
- success: "hsla(160, 60%, 45%, 1)",
35
- warning: "hsla(30, 80%, 55%, 1)",
36
- info: "hsla(220, 70%, 50%, 1)"
37
- };
38
-
39
- //#endregion
40
- //#region src/themes/default/index.ts
41
- const defaultThemeAssets = {
42
- colors: {
43
- light: lightColors,
44
- dark: darkColors
45
- },
46
- radius: 10,
47
- fontFamily: "System",
48
- letterSpacing: 0,
49
- fontSize: 16
50
- };
51
-
52
- //#endregion
53
- //#region src/themes/themes.ts
54
- const themes = { default: defaultThemeAssets };
55
-
56
- //#endregion
57
- //#region src/themes/provider.tsx
58
- const ThemeContext = createContext(null);
59
- const ThemeProvider = (props) => {
60
- const [themeName, setTheme] = useState("default");
61
- const systemColorScheme = useColorScheme();
62
- const [colorScheme, setColorScheme] = useState(systemColorScheme ?? "light");
63
- const themesAssets = themes[themeName];
64
- const colors = themesAssets.colors[colorScheme];
65
- useEffect(() => {
66
- if (systemColorScheme) setColorScheme(systemColorScheme);
67
- }, [systemColorScheme]);
68
- return /* @__PURE__ */ jsx(ThemeContext.Provider, {
69
- value: {
70
- themeName,
71
- setTheme,
72
- colorScheme,
73
- setColorScheme,
74
- colors,
75
- radius: themesAssets.radius,
76
- fontFamily: themesAssets.fontFamily,
77
- letterSpacing: themesAssets.letterSpacing,
78
- fontSize: themesAssets.fontSize
79
- },
80
- children: props.children
81
- });
82
- };
83
- const useTheme = () => {
84
- const context = useContext(ThemeContext);
85
- if (!context) throw new Error("useTheme must be used within a ThemeProvider");
86
- return context;
87
- };
88
-
89
- //#endregion
90
- export { useTheme as n, ThemeProvider as t };