panelui-native 0.4.0 → 0.5.3
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 +16 -8
- package/lib/module/components/accordion/index.js +312 -0
- package/lib/module/components/accordion/index.js.map +1 -0
- package/lib/module/components/avatar/index.js +58 -17
- package/lib/module/components/avatar/index.js.map +1 -1
- package/lib/module/components/badge/index.js +26 -5
- package/lib/module/components/badge/index.js.map +1 -1
- package/lib/module/components/button/index.js +51 -19
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/checkbox/index.js +42 -14
- package/lib/module/components/checkbox/index.js.map +1 -1
- package/lib/module/components/frame/index.js +64 -13
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/timeline/index.js +658 -0
- package/lib/module/components/timeline/index.js.map +1 -0
- package/lib/module/components/toast/index.js +145 -55
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/icons/index.js +388 -27
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/accordion/index.d.ts +56 -0
- package/lib/typescript/src/components/accordion/index.d.ts.map +1 -0
- package/lib/typescript/src/components/avatar/index.d.ts +8 -1
- package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
- package/lib/typescript/src/components/badge/index.d.ts +38 -0
- package/lib/typescript/src/components/badge/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts +18 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/checkbox/index.d.ts +42 -0
- package/lib/typescript/src/components/checkbox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/frame/index.d.ts +39 -5
- package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
- package/lib/typescript/src/components/timeline/index.d.ts +96 -0
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -0
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts +38 -3
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +344 -0
- package/src/components/avatar/index.tsx +68 -20
- package/src/components/badge/index.tsx +35 -6
- package/src/components/button/index.tsx +63 -20
- package/src/components/checkbox/index.tsx +49 -11
- package/src/components/frame/index.tsx +101 -31
- package/src/components/timeline/index.tsx +482 -0
- package/src/components/toast/index.tsx +166 -45
- package/src/icons/index.tsx +292 -27
- package/src/index.ts +38 -1
|
@@ -21,10 +21,34 @@ const checkboxVariants = tv({
|
|
|
21
21
|
description: 'text-sm text-muted-foreground',
|
|
22
22
|
},
|
|
23
23
|
variants: {
|
|
24
|
+
variant: {
|
|
25
|
+
default: {},
|
|
26
|
+
/**
|
|
27
|
+
* The whole surface is the target — for pickable options where the
|
|
28
|
+
* checkbox is a confirmation rather than the affordance itself.
|
|
29
|
+
*/
|
|
30
|
+
card: {
|
|
31
|
+
row: 'w-full items-start gap-3 rounded-xl border border-border bg-card p-4',
|
|
32
|
+
label: 'text-base font-medium',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
checked: {
|
|
36
|
+
true: {},
|
|
37
|
+
},
|
|
24
38
|
disabled: {
|
|
25
39
|
true: { row: 'opacity-50' },
|
|
26
40
|
},
|
|
27
41
|
},
|
|
42
|
+
compoundVariants: [
|
|
43
|
+
{
|
|
44
|
+
variant: 'card',
|
|
45
|
+
checked: true,
|
|
46
|
+
class: { row: 'border-primary bg-accent' },
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
defaultVariants: {
|
|
50
|
+
variant: 'default',
|
|
51
|
+
},
|
|
28
52
|
});
|
|
29
53
|
|
|
30
54
|
export interface CheckboxProps extends VariantProps<typeof checkboxVariants> {
|
|
@@ -39,9 +63,12 @@ export interface CheckboxProps extends VariantProps<typeof checkboxVariants> {
|
|
|
39
63
|
}
|
|
40
64
|
|
|
41
65
|
export const Checkbox = forwardRef<View, CheckboxProps>(
|
|
42
|
-
(
|
|
66
|
+
(
|
|
67
|
+
{ className, checked, onCheckedChange, disabled, label, description, variant },
|
|
68
|
+
ref
|
|
69
|
+
) => {
|
|
43
70
|
const progress = useSharedValue(checked ? 1 : 0);
|
|
44
|
-
const slots = checkboxVariants({ disabled: !!disabled });
|
|
71
|
+
const slots = checkboxVariants({ variant, checked, disabled: !!disabled });
|
|
45
72
|
const checkColor = useCSSVariable('--color-primary-foreground');
|
|
46
73
|
|
|
47
74
|
useEffect(() => {
|
|
@@ -55,6 +82,17 @@ export const Checkbox = forwardRef<View, CheckboxProps>(
|
|
|
55
82
|
transform: [{ scale: 0.6 + progress.value * 0.4 }],
|
|
56
83
|
}));
|
|
57
84
|
|
|
85
|
+
const box = (
|
|
86
|
+
<View className={slots.box()}>
|
|
87
|
+
<Animated.View style={fillStyle} className={slots.fill()}>
|
|
88
|
+
<CheckIcon
|
|
89
|
+
size={12}
|
|
90
|
+
color={typeof checkColor === 'string' ? checkColor : '#fff'}
|
|
91
|
+
/>
|
|
92
|
+
</Animated.View>
|
|
93
|
+
</View>
|
|
94
|
+
);
|
|
95
|
+
|
|
58
96
|
return (
|
|
59
97
|
<Pressable
|
|
60
98
|
ref={ref}
|
|
@@ -67,16 +105,15 @@ export const Checkbox = forwardRef<View, CheckboxProps>(
|
|
|
67
105
|
hitSlop={8}
|
|
68
106
|
// A description makes the row two lines tall — align the box to the
|
|
69
107
|
// label rather than centring it against the whole block.
|
|
70
|
-
className={slots.row({
|
|
108
|
+
className={slots.row({
|
|
109
|
+
className:
|
|
110
|
+
description && variant !== 'card'
|
|
111
|
+
? `items-start ${className ?? ''}`
|
|
112
|
+
: className,
|
|
113
|
+
})}
|
|
71
114
|
>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<CheckIcon
|
|
75
|
-
size={12}
|
|
76
|
-
color={typeof checkColor === 'string' ? checkColor : '#fff'}
|
|
77
|
-
/>
|
|
78
|
-
</Animated.View>
|
|
79
|
-
</View>
|
|
115
|
+
{/* The card lays out content first so the box sits top-right. */}
|
|
116
|
+
{variant === 'card' ? null : box}
|
|
80
117
|
{label || description ? (
|
|
81
118
|
<View className={slots.content()}>
|
|
82
119
|
{label ? <Text className={slots.label()}>{label}</Text> : null}
|
|
@@ -85,6 +122,7 @@ export const Checkbox = forwardRef<View, CheckboxProps>(
|
|
|
85
122
|
) : null}
|
|
86
123
|
</View>
|
|
87
124
|
) : null}
|
|
125
|
+
{variant === 'card' ? box : null}
|
|
88
126
|
</Pressable>
|
|
89
127
|
);
|
|
90
128
|
}
|
|
@@ -1,5 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Frame — a widget shell: a titled surface wrapping an inset panel of rows,
|
|
3
|
+
* with an optional action on the header row and a caption underneath.
|
|
4
|
+
*
|
|
5
|
+
* Layout follows the nested-radius rule (inner radius = outer radius minus the
|
|
6
|
+
* gap between them), which is why the panel is `rounded-xl` inside a
|
|
7
|
+
* `rounded-2xl` shell. Since v0.4.0 the radius scale is theme-scoped, so this
|
|
8
|
+
* relationship holds while the absolute values change per theme.
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Frame>
|
|
12
|
+
* <Frame.Header>
|
|
13
|
+
* <Frame.Title>Usage Type</Frame.Title>
|
|
14
|
+
* <Frame.Action>Amount</Frame.Action>
|
|
15
|
+
* </Frame.Header>
|
|
16
|
+
* <Frame.Panel>
|
|
17
|
+
* <Frame.Row>…</Frame.Row>
|
|
18
|
+
* <Frame.Row divided>…</Frame.Row>
|
|
19
|
+
* </Frame.Panel>
|
|
20
|
+
* <Frame.Footer>Updated 2 minutes ago</Frame.Footer>
|
|
21
|
+
* </Frame>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import { forwardRef, type ReactNode } from 'react';
|
|
25
|
+
import { View, type Text as RNText, type ViewProps } from 'react-native';
|
|
3
26
|
import { Text, type TextProps } from '../../primitives/text';
|
|
4
27
|
import { cn } from '../../utils/cn';
|
|
5
28
|
|
|
@@ -7,39 +30,73 @@ export interface FrameProps extends ViewProps {
|
|
|
7
30
|
className?: string;
|
|
8
31
|
}
|
|
9
32
|
|
|
10
|
-
/**
|
|
11
|
-
* Grouping container (Coss UI's CardFrame): a tinted, rounded surface that
|
|
12
|
-
* holds a header, one or more inset panels, and a footer. Use it to group
|
|
13
|
-
* related settings or list sections under a single title.
|
|
14
|
-
*/
|
|
15
33
|
const FrameRoot = forwardRef<View, FrameProps>(({ className, ...props }, ref) => (
|
|
16
34
|
<View
|
|
17
35
|
ref={ref}
|
|
18
|
-
className={cn('
|
|
36
|
+
className={cn('rounded-2xl border border-border bg-surface p-1.5', className)}
|
|
19
37
|
{...props}
|
|
20
38
|
/>
|
|
21
39
|
));
|
|
22
40
|
FrameRoot.displayName = 'Frame';
|
|
23
41
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
FrameHeader.displayName = 'Frame.Header';
|
|
42
|
+
export interface FrameHeaderProps extends FrameProps {
|
|
43
|
+
children?: ReactNode;
|
|
44
|
+
}
|
|
28
45
|
|
|
29
|
-
|
|
46
|
+
/**
|
|
47
|
+
* The header row: title on the left, `Frame.Action` on the right. Add
|
|
48
|
+
* `className="flex-col items-start"` when you want a description underneath.
|
|
49
|
+
*/
|
|
50
|
+
const FrameHeader = forwardRef<View, FrameHeaderProps>(
|
|
30
51
|
({ className, ...props }, ref) => (
|
|
31
|
-
<
|
|
52
|
+
<View
|
|
32
53
|
ref={ref}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
className={cn(
|
|
55
|
+
'flex-row items-center justify-between gap-3 px-3 pb-2.5 pt-2',
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
36
58
|
{...props}
|
|
37
59
|
/>
|
|
38
60
|
)
|
|
39
61
|
);
|
|
62
|
+
FrameHeader.displayName = 'Frame.Header';
|
|
63
|
+
|
|
64
|
+
const FrameTitle = forwardRef<RNText, TextProps>(({ className, ...props }, ref) => (
|
|
65
|
+
<Text
|
|
66
|
+
ref={ref}
|
|
67
|
+
size="base"
|
|
68
|
+
weight="medium"
|
|
69
|
+
className={cn('text-foreground', className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
));
|
|
40
73
|
FrameTitle.displayName = 'Frame.Title';
|
|
41
74
|
|
|
42
|
-
|
|
75
|
+
export interface FrameActionProps extends FrameProps {
|
|
76
|
+
children?: ReactNode;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Trailing slot on the header row — a column label, a count, a button, a badge.
|
|
81
|
+
* Plain strings render as muted text; anything else renders as-is.
|
|
82
|
+
*/
|
|
83
|
+
const FrameAction = forwardRef<View, FrameActionProps>(
|
|
84
|
+
({ className, children, ...props }, ref) => (
|
|
85
|
+
<View ref={ref} className={cn('flex-row items-center gap-2', className)} {...props}>
|
|
86
|
+
{typeof children === 'string' ? (
|
|
87
|
+
<Text size="base" muted>
|
|
88
|
+
{children}
|
|
89
|
+
</Text>
|
|
90
|
+
) : (
|
|
91
|
+
children
|
|
92
|
+
)}
|
|
93
|
+
</View>
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
FrameAction.displayName = 'Frame.Action';
|
|
97
|
+
|
|
98
|
+
/** Secondary line under the title, inside a column-wrapped header. */
|
|
99
|
+
const FrameDescription = forwardRef<RNText, TextProps>(
|
|
43
100
|
({ className, ...props }, ref) => (
|
|
44
101
|
<Text ref={ref} size="sm" muted className={className} {...props} />
|
|
45
102
|
)
|
|
@@ -47,16 +104,13 @@ const FrameDescription = forwardRef<React.ElementRef<typeof Text>, TextProps>(
|
|
|
47
104
|
FrameDescription.displayName = 'Frame.Description';
|
|
48
105
|
|
|
49
106
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
107
|
+
* The inset card holding the frame's content — the raised surface sitting in
|
|
108
|
+
* from the shell's edges, with its own smaller radius.
|
|
52
109
|
*/
|
|
53
110
|
const FramePanel = forwardRef<View, FrameProps>(({ className, ...props }, ref) => (
|
|
54
111
|
<View
|
|
55
112
|
ref={ref}
|
|
56
|
-
className={cn(
|
|
57
|
-
'mx-1.5 overflow-hidden rounded-xl border border-border bg-card',
|
|
58
|
-
className
|
|
59
|
-
)}
|
|
113
|
+
className={cn('overflow-hidden rounded-xl border border-border bg-card', className)}
|
|
60
114
|
{...props}
|
|
61
115
|
/>
|
|
62
116
|
));
|
|
@@ -85,18 +139,34 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
85
139
|
);
|
|
86
140
|
FrameRow.displayName = 'Frame.Row';
|
|
87
141
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
142
|
+
export interface FrameFooterProps extends FrameProps {
|
|
143
|
+
children?: ReactNode;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Muted caption under the panel. Strings are wrapped for you. */
|
|
147
|
+
const FrameFooter = forwardRef<View, FrameFooterProps>(
|
|
148
|
+
({ className, children, ...props }, ref) => (
|
|
149
|
+
<View
|
|
150
|
+
ref={ref}
|
|
151
|
+
className={cn('flex-row items-center gap-2 px-3 pb-1.5 pt-2.5', className)}
|
|
152
|
+
{...props}
|
|
153
|
+
>
|
|
154
|
+
{typeof children === 'string' ? (
|
|
155
|
+
<Text size="sm" muted>
|
|
156
|
+
{children}
|
|
157
|
+
</Text>
|
|
158
|
+
) : (
|
|
159
|
+
children
|
|
160
|
+
)}
|
|
161
|
+
</View>
|
|
162
|
+
)
|
|
163
|
+
);
|
|
95
164
|
FrameFooter.displayName = 'Frame.Footer';
|
|
96
165
|
|
|
97
166
|
export const Frame = Object.assign(FrameRoot, {
|
|
98
167
|
Header: FrameHeader,
|
|
99
168
|
Title: FrameTitle,
|
|
169
|
+
Action: FrameAction,
|
|
100
170
|
Description: FrameDescription,
|
|
101
171
|
Panel: FramePanel,
|
|
102
172
|
Row: FrameRow,
|