@korsolutions/ui 0.0.4 → 0.0.6
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/dist/components/index.d.mts +84 -0
- package/dist/components/index.mjs +288 -0
- package/dist/index-Dafk8ZGv.d.mts +265 -0
- package/dist/index.d.mts +45 -0
- package/dist/index.mjs +11 -0
- package/dist/portal-DoPaAohb.mjs +61 -0
- package/dist/primitives/index.d.mts +2 -0
- package/dist/primitives/index.mjs +4 -0
- package/dist/primitives-C2enZ5Ku.mjs +441 -0
- package/dist/themes-BrLbh9h6.mjs +86 -0
- package/package.json +20 -8
- package/src/components/button/button.tsx +24 -0
- package/src/components/button/variants/default.tsx +52 -0
- package/src/components/button/variants/index.ts +5 -0
- package/src/components/card/card.tsx +26 -0
- package/src/components/card/variants/default.tsx +38 -0
- package/src/components/card/variants/index.ts +5 -0
- package/src/components/field/field.tsx +27 -0
- package/src/components/field/variants/default.tsx +29 -0
- package/src/components/field/variants/index.ts +5 -0
- package/src/components/index.ts +5 -0
- package/src/components/input/input.tsx +14 -0
- package/src/components/input/variants/default.tsx +34 -0
- package/src/components/input/variants/index.ts +5 -0
- package/src/components/select/select.tsx +35 -0
- package/src/components/select/variants/default.tsx +81 -0
- package/src/components/select/variants/index.ts +5 -0
- package/src/index.tsx +13 -0
- package/src/primitives/button/button-context.tsx +5 -5
- package/src/primitives/button/button-label.tsx +7 -5
- package/src/primitives/button/button-root.tsx +12 -8
- package/src/primitives/button/button-spinner.tsx +14 -0
- package/src/primitives/button/index.ts +5 -3
- package/src/primitives/button/types.ts +6 -5
- package/src/primitives/card/card-body.tsx +1 -1
- package/src/primitives/card/card-footer.tsx +1 -1
- package/src/primitives/card/card-header.tsx +1 -1
- package/src/primitives/card/card-root.tsx +1 -1
- package/src/primitives/card/card-title.tsx +1 -1
- package/src/primitives/card/index.ts +1 -1
- package/src/primitives/field/context.ts +5 -19
- package/src/primitives/field/field-description.tsx +17 -0
- package/src/primitives/field/field-error.tsx +17 -0
- package/src/primitives/field/field-label.tsx +7 -3
- package/src/primitives/field/field-root.tsx +13 -59
- package/src/primitives/field/index.ts +9 -6
- package/src/primitives/field/types.ts +8 -7
- package/src/primitives/index.ts +0 -2
- package/src/primitives/input/index.ts +1 -1
- package/src/primitives/input/input.tsx +48 -13
- package/src/primitives/input/types.ts +2 -4
- package/src/primitives/select/context.ts +3 -3
- package/src/primitives/select/index.ts +2 -2
- package/src/primitives/select/select-content.tsx +2 -2
- package/src/primitives/select/select-option.tsx +27 -4
- package/src/primitives/select/select-overlay.tsx +1 -1
- package/src/primitives/select/select-root.tsx +13 -11
- package/src/primitives/select/select-trigger.tsx +3 -2
- package/src/primitives/select/select-value.tsx +4 -1
- package/src/primitives/select/types.ts +3 -1
- package/src/themes/default/colors.ts +45 -0
- package/src/themes/default/index.ts +11 -0
- package/src/themes/index.ts +2 -0
- package/src/themes/provider.tsx +56 -0
- package/src/themes/themes.ts +6 -0
- package/src/themes/types.ts +30 -0
- package/src/utils/hsla-utils.ts +10 -0
- package/src/utils/use-themed-styles.ts +13 -0
- package/tsconfig.json +8 -0
- package/tsdown.config.ts +8 -0
- package/src/composites/card.tsx +0 -23
- package/src/composites/index.ts +0 -1
- package/src/index.ts +0 -1
- package/src/primitives/field/field-control.tsx +0 -29
- package/src/primitives/provider.tsx +0 -10
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ButtonStyles } from "@/primitives";
|
|
2
|
+
import { useThemedStyles } from "@/utils/use-themed-styles";
|
|
3
|
+
|
|
4
|
+
export const useButtonVariantDefault = (): ButtonStyles => {
|
|
5
|
+
return useThemedStyles(
|
|
6
|
+
({ colors, radius, fontFamily }): ButtonStyles => ({
|
|
7
|
+
root: {
|
|
8
|
+
default: {
|
|
9
|
+
flexDirection: "row",
|
|
10
|
+
backgroundColor: colors.primary,
|
|
11
|
+
paddingVertical: 12,
|
|
12
|
+
paddingHorizontal: 16,
|
|
13
|
+
borderRadius: radius,
|
|
14
|
+
gap: 8,
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
justifyContent: "center",
|
|
17
|
+
},
|
|
18
|
+
disabled: {
|
|
19
|
+
opacity: 0.5,
|
|
20
|
+
},
|
|
21
|
+
loading: {
|
|
22
|
+
opacity: 0.8,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
label: {
|
|
26
|
+
default: {
|
|
27
|
+
color: colors.primaryForeground,
|
|
28
|
+
fontSize: 16,
|
|
29
|
+
fontWeight: "bold",
|
|
30
|
+
fontFamily,
|
|
31
|
+
},
|
|
32
|
+
disabled: {
|
|
33
|
+
color: colors.mutedForeground,
|
|
34
|
+
},
|
|
35
|
+
loading: {
|
|
36
|
+
color: colors.mutedForeground,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
spinner: {
|
|
40
|
+
default: {
|
|
41
|
+
color: colors.primaryForeground,
|
|
42
|
+
},
|
|
43
|
+
disabled: {
|
|
44
|
+
color: colors.mutedForeground,
|
|
45
|
+
},
|
|
46
|
+
loading: {
|
|
47
|
+
color: colors.mutedForeground,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CardPrimitive } from "@/primitives";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { CardVariants } from "./variants";
|
|
4
|
+
|
|
5
|
+
interface CardProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
|
|
9
|
+
variant?: keyof typeof CardVariants;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function Card(props: CardProps) {
|
|
13
|
+
const useVariantStyles = CardVariants[props.variant || "default"];
|
|
14
|
+
const styles = useVariantStyles();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<CardPrimitive.Root styles={styles}>
|
|
18
|
+
{!!props.title && (
|
|
19
|
+
<CardPrimitive.Header>
|
|
20
|
+
<CardPrimitive.Title>{props.title}</CardPrimitive.Title>
|
|
21
|
+
</CardPrimitive.Header>
|
|
22
|
+
)}
|
|
23
|
+
<CardPrimitive.Body>{props.children}</CardPrimitive.Body>
|
|
24
|
+
</CardPrimitive.Root>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CardStyles } from "@/primitives";
|
|
2
|
+
import { useThemedStyles } from "@/utils/use-themed-styles";
|
|
3
|
+
|
|
4
|
+
export function useCardVariantDefault(): CardStyles {
|
|
5
|
+
return useThemedStyles(
|
|
6
|
+
({ colors, radius, fontFamily }): CardStyles => ({
|
|
7
|
+
root: {
|
|
8
|
+
default: {
|
|
9
|
+
borderWidth: 1,
|
|
10
|
+
borderColor: colors.border,
|
|
11
|
+
borderRadius: radius,
|
|
12
|
+
backgroundColor: colors.surface,
|
|
13
|
+
paddingVertical: 24,
|
|
14
|
+
gap: 24,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
header: {
|
|
18
|
+
default: {
|
|
19
|
+
paddingHorizontal: 24,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
title: {
|
|
23
|
+
default: {
|
|
24
|
+
fontFamily,
|
|
25
|
+
fontSize: 18,
|
|
26
|
+
fontWeight: "600",
|
|
27
|
+
color: colors.foreground,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
body: {
|
|
31
|
+
default: {
|
|
32
|
+
paddingHorizontal: 24,
|
|
33
|
+
gap: 24,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FieldPrimitive } from "@/primitives";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { FieldVariants } from "./variants";
|
|
4
|
+
|
|
5
|
+
export interface FieldProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
id?: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
|
|
12
|
+
variant?: keyof typeof FieldVariants;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function Field(props: FieldProps) {
|
|
16
|
+
const useVariantStyles = FieldVariants[props.variant || "default"];
|
|
17
|
+
const variantStyles = useVariantStyles();
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<FieldPrimitive.Root styles={variantStyles}>
|
|
21
|
+
{props.label && <FieldPrimitive.Label htmlFor={props.id}>{props.label}</FieldPrimitive.Label>}
|
|
22
|
+
{props.description && <FieldPrimitive.Description>{props.description}</FieldPrimitive.Description>}
|
|
23
|
+
{props.children}
|
|
24
|
+
{props.error && <FieldPrimitive.Error>{props.error}</FieldPrimitive.Error>}
|
|
25
|
+
</FieldPrimitive.Root>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FieldStyles } from "@/primitives";
|
|
2
|
+
import { useThemedStyles } from "@/utils/use-themed-styles";
|
|
3
|
+
|
|
4
|
+
export const useFieldVariantDefault = (): FieldStyles => {
|
|
5
|
+
return useThemedStyles(
|
|
6
|
+
({ colors, fontFamily }): FieldStyles => ({
|
|
7
|
+
root: {
|
|
8
|
+
flexDirection: "column",
|
|
9
|
+
gap: 8,
|
|
10
|
+
},
|
|
11
|
+
label: {
|
|
12
|
+
fontFamily,
|
|
13
|
+
fontSize: 14,
|
|
14
|
+
fontWeight: "600",
|
|
15
|
+
color: colors.foreground,
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
fontFamily,
|
|
19
|
+
fontSize: 14,
|
|
20
|
+
color: colors.mutedForeground,
|
|
21
|
+
},
|
|
22
|
+
error: {
|
|
23
|
+
fontFamily,
|
|
24
|
+
fontSize: 14,
|
|
25
|
+
color: colors.danger,
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { InputVariants } from "./variants";
|
|
3
|
+
import { InputPrimitive, InputPrimitiveBaseProps } from "@/primitives";
|
|
4
|
+
|
|
5
|
+
interface InputProps extends InputPrimitiveBaseProps {
|
|
6
|
+
variant?: keyof typeof InputVariants;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function Input(props: InputProps) {
|
|
10
|
+
const useVariantStyles = props.variant ? InputVariants[props.variant] : InputVariants["default"];
|
|
11
|
+
const variantStyles = useVariantStyles();
|
|
12
|
+
|
|
13
|
+
return <InputPrimitive {...props} styles={variantStyles} />;
|
|
14
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { InputStyles } from "@/primitives";
|
|
2
|
+
import { useThemedStyles } from "@/utils/use-themed-styles";
|
|
3
|
+
|
|
4
|
+
export function useInputVariantDefault(): InputStyles {
|
|
5
|
+
return useThemedStyles(
|
|
6
|
+
({ colors, radius, fontFamily }): InputStyles => ({
|
|
7
|
+
default: {
|
|
8
|
+
placeholderTextColor: colors.mutedForeground,
|
|
9
|
+
style: {
|
|
10
|
+
borderWidth: 1,
|
|
11
|
+
borderColor: colors.border,
|
|
12
|
+
borderRadius: radius,
|
|
13
|
+
backgroundColor: colors.surface,
|
|
14
|
+
paddingVertical: 12,
|
|
15
|
+
paddingHorizontal: 16,
|
|
16
|
+
outlineWidth: 0,
|
|
17
|
+
fontFamily,
|
|
18
|
+
height: 48,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
focused: {
|
|
22
|
+
style: {
|
|
23
|
+
borderColor: colors.primary,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
disabled: {
|
|
27
|
+
style: {
|
|
28
|
+
color: colors.mutedForeground,
|
|
29
|
+
backgroundColor: colors.muted,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { SelectPrimitive, SelectRootBaseProps } from "@/primitives";
|
|
3
|
+
import { SelectVariants } from "./variants";
|
|
4
|
+
|
|
5
|
+
export interface SelectOption<T> {
|
|
6
|
+
value: T;
|
|
7
|
+
label: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SelectProps<T> extends SelectRootBaseProps {
|
|
11
|
+
options: SelectOption<T>[];
|
|
12
|
+
variant?: keyof typeof SelectVariants;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function Select<T>(props: SelectProps<T>) {
|
|
16
|
+
const useVariantStyles = SelectVariants[props.variant ?? "default"];
|
|
17
|
+
const variantStyles = useVariantStyles();
|
|
18
|
+
return (
|
|
19
|
+
<SelectPrimitive.Root {...props} styles={variantStyles}>
|
|
20
|
+
<SelectPrimitive.Trigger>
|
|
21
|
+
<SelectPrimitive.Value />
|
|
22
|
+
</SelectPrimitive.Trigger>
|
|
23
|
+
<SelectPrimitive.Portal>
|
|
24
|
+
<SelectPrimitive.Overlay />
|
|
25
|
+
<SelectPrimitive.Content>
|
|
26
|
+
{props.options.map((option) => (
|
|
27
|
+
<SelectPrimitive.Option key={String(option.value)} value={String(option.value)}>
|
|
28
|
+
{option.label}
|
|
29
|
+
</SelectPrimitive.Option>
|
|
30
|
+
))}
|
|
31
|
+
</SelectPrimitive.Content>
|
|
32
|
+
</SelectPrimitive.Portal>
|
|
33
|
+
</SelectPrimitive.Root>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SelectStyles } from "@/primitives";
|
|
2
|
+
import { useThemedStyles } from "@/utils/use-themed-styles";
|
|
3
|
+
|
|
4
|
+
export function useSelectVariantDefault(): SelectStyles {
|
|
5
|
+
return useThemedStyles(
|
|
6
|
+
({ colors, radius, fontFamily }): SelectStyles => ({
|
|
7
|
+
root: {
|
|
8
|
+
default: {},
|
|
9
|
+
disabled: {},
|
|
10
|
+
},
|
|
11
|
+
trigger: {
|
|
12
|
+
default: {
|
|
13
|
+
borderWidth: 1,
|
|
14
|
+
borderColor: colors.border,
|
|
15
|
+
borderRadius: radius,
|
|
16
|
+
justifyContent: "center",
|
|
17
|
+
paddingVertical: 12,
|
|
18
|
+
paddingHorizontal: 16,
|
|
19
|
+
height: 48,
|
|
20
|
+
},
|
|
21
|
+
disabled: {
|
|
22
|
+
backgroundColor: colors.muted,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
value: {
|
|
26
|
+
default: {
|
|
27
|
+
fontFamily,
|
|
28
|
+
fontSize: 16,
|
|
29
|
+
color: colors.foreground,
|
|
30
|
+
},
|
|
31
|
+
disabled: {
|
|
32
|
+
color: colors.mutedForeground,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
placeholder: {
|
|
36
|
+
default: {
|
|
37
|
+
fontFamily,
|
|
38
|
+
fontSize: 16,
|
|
39
|
+
color: colors.mutedForeground,
|
|
40
|
+
},
|
|
41
|
+
disabled: {
|
|
42
|
+
color: colors.mutedForeground,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
overlay: {
|
|
46
|
+
default: {},
|
|
47
|
+
disabled: {},
|
|
48
|
+
},
|
|
49
|
+
content: {
|
|
50
|
+
default: {
|
|
51
|
+
backgroundColor: colors.surface,
|
|
52
|
+
borderRadius: radius,
|
|
53
|
+
borderWidth: 1,
|
|
54
|
+
borderColor: colors.border,
|
|
55
|
+
padding: 4,
|
|
56
|
+
gap: 4,
|
|
57
|
+
},
|
|
58
|
+
disabled: {},
|
|
59
|
+
},
|
|
60
|
+
option: {
|
|
61
|
+
default: {
|
|
62
|
+
paddingVertical: 12,
|
|
63
|
+
paddingHorizontal: 16,
|
|
64
|
+
fontFamily,
|
|
65
|
+
fontSize: 16,
|
|
66
|
+
color: colors.foreground,
|
|
67
|
+
borderRadius: radius / 2,
|
|
68
|
+
},
|
|
69
|
+
disabled: {
|
|
70
|
+
color: colors.mutedForeground,
|
|
71
|
+
},
|
|
72
|
+
selected: {
|
|
73
|
+
backgroundColor: colors.muted,
|
|
74
|
+
},
|
|
75
|
+
hovered: {
|
|
76
|
+
backgroundColor: colors.muted,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ThemeProvider } from "@/themes";
|
|
2
|
+
import { PortalHost } from "./primitives/portal";
|
|
3
|
+
|
|
4
|
+
export const UniversalUIProvider = ({ children }: { children: React.ReactNode }) => {
|
|
5
|
+
return (
|
|
6
|
+
<ThemeProvider>
|
|
7
|
+
{children}
|
|
8
|
+
<PortalHost />
|
|
9
|
+
</ThemeProvider>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { useTheme } from "./themes";
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
2
|
import { ButtonState, ButtonStyles } from "./types";
|
|
3
3
|
|
|
4
|
-
export interface
|
|
4
|
+
export interface ButtonPrimitiveContext {
|
|
5
5
|
disabled?: boolean;
|
|
6
6
|
|
|
7
7
|
state: ButtonState;
|
|
8
8
|
styles?: ButtonStyles;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const
|
|
11
|
+
export const ButtonPrimitiveContext = createContext<ButtonPrimitiveContext | undefined>(undefined);
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
const context = useContext(
|
|
13
|
+
export const useButtonPrimitive = () => {
|
|
14
|
+
const context = useContext(ButtonPrimitiveContext);
|
|
15
15
|
if (!context) {
|
|
16
|
-
throw new Error("
|
|
16
|
+
throw new Error("useButtonPrimitive must be used within a ButtonPrimitiveProvider");
|
|
17
17
|
}
|
|
18
18
|
return context;
|
|
19
19
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, Text, TextStyle } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { useButtonPrimitive } from "./button-context";
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
4
5
|
|
|
5
|
-
export interface
|
|
6
|
+
export interface ButtonPrimitiveLabelProps {
|
|
6
7
|
children?: string;
|
|
7
8
|
|
|
8
9
|
render?: (props: this) => React.ReactElement;
|
|
@@ -10,9 +11,10 @@ export interface ButtonLabelProps {
|
|
|
10
11
|
style?: StyleProp<TextStyle>;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export function ButtonLabel(props:
|
|
14
|
-
const button =
|
|
15
|
-
|
|
14
|
+
export function ButtonLabel(props: ButtonPrimitiveLabelProps) {
|
|
15
|
+
const button = useButtonPrimitive();
|
|
16
|
+
|
|
17
|
+
const calculatedStyle = calculateComposedStyles(button.styles, button.state, "label", props.style);
|
|
16
18
|
|
|
17
19
|
const Component = props.render ?? Text;
|
|
18
20
|
return <Component style={calculatedStyle}>{props.children}</Component>;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Pressable, StyleProp, ViewStyle } from "react-native";
|
|
3
3
|
import { ButtonStyles, ButtonState } from "./types";
|
|
4
|
-
import {
|
|
4
|
+
import { ButtonPrimitiveContext } from "./button-context";
|
|
5
5
|
|
|
6
|
-
export interface
|
|
6
|
+
export interface ButtonPrimitiveRootProps {
|
|
7
7
|
children?: React.ReactNode;
|
|
8
8
|
|
|
9
9
|
onPress?: () => void;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
isDisabled?: boolean;
|
|
12
|
+
isLoading?: boolean;
|
|
12
13
|
|
|
13
14
|
style?: StyleProp<ViewStyle>;
|
|
14
15
|
styles?: ButtonStyles;
|
|
@@ -16,22 +17,25 @@ export interface ButtonRootProps {
|
|
|
16
17
|
render?: (props: this) => React.ReactElement;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
const calculateState = (props:
|
|
20
|
-
if (props.
|
|
20
|
+
const calculateState = (props: ButtonPrimitiveRootProps): ButtonState => {
|
|
21
|
+
if (props.isDisabled) {
|
|
21
22
|
return "disabled";
|
|
22
23
|
}
|
|
24
|
+
if (props.isLoading) {
|
|
25
|
+
return "loading";
|
|
26
|
+
}
|
|
23
27
|
return "default";
|
|
24
28
|
};
|
|
25
29
|
|
|
26
|
-
export function ButtonRoot(props:
|
|
30
|
+
export function ButtonRoot(props: ButtonPrimitiveRootProps) {
|
|
27
31
|
const state = calculateState(props);
|
|
28
32
|
|
|
29
33
|
const calculatedStyle = [props.styles?.root?.default, props.styles?.root?.[state], props.style];
|
|
30
34
|
|
|
31
35
|
const Container = props.render ?? Pressable;
|
|
32
36
|
return (
|
|
33
|
-
<
|
|
37
|
+
<ButtonPrimitiveContext.Provider value={{ disabled: props.isDisabled, state, styles: props.styles }}>
|
|
34
38
|
<Container {...props} style={calculatedStyle} />
|
|
35
|
-
</
|
|
39
|
+
</ButtonPrimitiveContext.Provider>
|
|
36
40
|
);
|
|
37
41
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ActivityIndicator, StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
import { useButtonPrimitive } from "./button-context";
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
|
+
|
|
6
|
+
interface ButtonSpinnerProps {
|
|
7
|
+
style?: StyleProp<ViewStyle>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function ButtonSpinner(props: ButtonSpinnerProps) {
|
|
11
|
+
const button = useButtonPrimitive();
|
|
12
|
+
const composedStyle = calculateComposedStyles(button.styles, button.state, "spinner", props.style);
|
|
13
|
+
return <ActivityIndicator style={composedStyle} />;
|
|
14
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ButtonRoot } from "./button-root";
|
|
2
2
|
import { ButtonLabel } from "./button-label";
|
|
3
|
+
import { ButtonSpinner } from "./button-spinner";
|
|
3
4
|
|
|
4
|
-
export const
|
|
5
|
+
export const ButtonPrimitive = {
|
|
5
6
|
Root: ButtonRoot,
|
|
6
7
|
Label: ButtonLabel,
|
|
8
|
+
Spinner: ButtonSpinner,
|
|
7
9
|
};
|
|
8
10
|
|
|
9
|
-
export type {
|
|
10
|
-
export type {
|
|
11
|
+
export type { ButtonPrimitiveRootProps } from "./button-root";
|
|
12
|
+
export type { ButtonPrimitiveLabelProps } from "./button-label";
|
|
11
13
|
export * from "./types";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ButtonPrimitiveRootProps } from "./button-root";
|
|
2
|
+
import { ButtonPrimitiveLabelProps } from "./button-label";
|
|
3
3
|
|
|
4
|
-
export type ButtonState = "default" | "disabled";
|
|
4
|
+
export type ButtonState = "default" | "disabled" | "loading";
|
|
5
5
|
|
|
6
6
|
export interface ButtonStyles {
|
|
7
|
-
root?: Partial<Record<ButtonState,
|
|
8
|
-
label?: Partial<Record<ButtonState,
|
|
7
|
+
root?: Partial<Record<ButtonState, ButtonPrimitiveRootProps["style"]>>;
|
|
8
|
+
label?: Partial<Record<ButtonState, ButtonPrimitiveLabelProps["style"]>>;
|
|
9
|
+
spinner?: Partial<Record<ButtonState, ButtonPrimitiveLabelProps["style"]>>;
|
|
9
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, View, ViewStyle } from "react-native";
|
|
3
3
|
import { useCard } from "./context";
|
|
4
|
-
import { calculateComposedStyles } from "
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
5
|
|
|
6
6
|
export interface CardBodyProps {
|
|
7
7
|
children?: React.ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, View, ViewStyle } from "react-native";
|
|
3
3
|
import { useCard } from "./context";
|
|
4
|
-
import { calculateComposedStyles } from "
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
5
|
|
|
6
6
|
export interface CardFooterProps {
|
|
7
7
|
children?: React.ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, View, ViewStyle } from "react-native";
|
|
3
3
|
import { useCard } from "./context";
|
|
4
|
-
import { calculateComposedStyles } from "
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
5
|
|
|
6
6
|
export interface CardHeaderProps {
|
|
7
7
|
children?: React.ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, View, ViewStyle } from "react-native";
|
|
3
3
|
import { CardStyles } from "./types";
|
|
4
|
-
import { calculateComposedStyles } from "
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
5
|
import { CardContext } from "./context";
|
|
6
6
|
|
|
7
7
|
export interface CardRootProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { StyleProp, Text, TextStyle } from "react-native";
|
|
3
3
|
import { useCard } from "./context";
|
|
4
|
-
import { calculateComposedStyles } from "
|
|
4
|
+
import { calculateComposedStyles } from "@/utils/calculate-styles";
|
|
5
5
|
|
|
6
6
|
export interface CardTitleProps {
|
|
7
7
|
children?: string;
|
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { FieldStyles } from "./types";
|
|
3
3
|
|
|
4
|
-
export interface FieldContext
|
|
5
|
-
|
|
6
|
-
onChange: (value: string) => void;
|
|
7
|
-
|
|
8
|
-
focused: boolean;
|
|
9
|
-
setFocused: React.Dispatch<React.SetStateAction<boolean>>;
|
|
10
|
-
|
|
11
|
-
hovered: boolean;
|
|
12
|
-
setHovered: React.Dispatch<React.SetStateAction<boolean>>;
|
|
13
|
-
|
|
14
|
-
disabled?: boolean;
|
|
15
|
-
required?: boolean;
|
|
16
|
-
error?: string | null;
|
|
17
|
-
|
|
18
|
-
state: FieldState;
|
|
19
|
-
styles?: FieldStyles<TControlStyles>;
|
|
4
|
+
export interface FieldContext {
|
|
5
|
+
styles?: FieldStyles;
|
|
20
6
|
}
|
|
21
7
|
|
|
22
8
|
export const FieldContext = createContext<FieldContext | undefined>(undefined);
|
|
23
9
|
|
|
24
|
-
export const useField =
|
|
10
|
+
export const useField = () => {
|
|
25
11
|
const context = useContext(FieldContext);
|
|
26
12
|
if (!context) {
|
|
27
13
|
throw new Error("useField must be used within a FieldProvider");
|
|
28
14
|
}
|
|
29
|
-
return context
|
|
15
|
+
return context;
|
|
30
16
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyleProp, Text, TextStyle } from "react-native";
|
|
3
|
+
import { useField } from "./context";
|
|
4
|
+
|
|
5
|
+
export interface FieldDescriptionProps {
|
|
6
|
+
children: string;
|
|
7
|
+
|
|
8
|
+
render?: (props: FieldDescriptionProps) => React.ReactNode;
|
|
9
|
+
|
|
10
|
+
style?: StyleProp<TextStyle>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function FieldDescription(props: FieldDescriptionProps) {
|
|
14
|
+
const field = useField();
|
|
15
|
+
const Component = props.render ?? Text;
|
|
16
|
+
return <Component {...props} style={[field.styles?.description, props.style]} />;
|
|
17
|
+
}
|