@tallyui/components 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +1076 -76
- package/dist/index.js +4662 -355
- package/package.json +27 -5
- package/src/cart/cart-line-actions.tsx +40 -0
- package/src/cart/cart-line.tsx +18 -32
- package/src/cart/cart-note-input.tsx +46 -0
- package/src/cart/cart-panel.tsx +39 -26
- package/src/cart/cart-total.tsx +43 -47
- package/src/cart/discount-badge.tsx +19 -0
- package/src/cart/index.ts +4 -1
- package/src/checkout/cash-tendered.tsx +101 -0
- package/src/checkout/change-display.tsx +19 -0
- package/src/checkout/index.ts +3 -0
- package/src/checkout/order-summary-line.tsx +7 -8
- package/src/checkout/order-summary.tsx +8 -7
- package/src/checkout/payment-method-card.tsx +10 -9
- package/src/checkout/payment-selector.tsx +5 -5
- package/src/checkout/receipt-preview.tsx +78 -0
- package/src/customer/customer-card.tsx +8 -9
- package/src/customer/customer-form.tsx +70 -0
- package/src/customer/customer-order-history.tsx +34 -0
- package/src/customer/customer-select.tsx +63 -24
- package/src/customer/index.ts +2 -0
- package/src/index.ts +112 -1
- package/src/input/filter-chip.tsx +85 -27
- package/src/input/index.ts +1 -0
- package/src/input/quantity-stepper.tsx +64 -0
- package/src/input/search-input.tsx +30 -7
- package/src/layout/checkout-layout.tsx +46 -0
- package/src/layout/index.ts +5 -0
- package/src/layout/live-tab-screen.tsx +54 -0
- package/src/layout/pos-layout.tsx +64 -0
- package/src/layout/settings-layout.tsx +58 -0
- package/src/layout/store-settings-choice-screen.tsx +142 -0
- package/src/order/index.ts +4 -0
- package/src/order/order-card.tsx +48 -0
- package/src/order/order-detail.tsx +82 -0
- package/src/order/order-list.tsx +39 -0
- package/src/order/order-status-badge.tsx +32 -0
- package/src/product/category-nav.tsx +70 -0
- package/src/product/index.ts +3 -0
- package/src/product/product-card.tsx +36 -8
- package/src/product/product-grid.tsx +25 -6
- package/src/product/product-image.tsx +28 -7
- package/src/product/product-list.tsx +44 -0
- package/src/product/product-price.tsx +77 -22
- package/src/product/product-sku.tsx +5 -5
- package/src/product/product-stock-badge.tsx +41 -28
- package/src/product/product-title.tsx +2 -3
- package/src/product/product-variant-picker.tsx +61 -0
- package/src/register/cash-count-input.tsx +85 -0
- package/src/register/closure-sheet.tsx +155 -0
- package/src/register/index.ts +12 -0
- package/src/register/movement-sheet.tsx +118 -0
- package/src/register/open-register-card.tsx +109 -0
- package/src/register/register-bar.helpers.ts +57 -0
- package/src/register/register-bar.tsx +85 -0
- package/src/register/register-column.tsx +117 -0
- package/src/register/register-count.tsx +330 -0
- package/src/register/register-open-close.tsx +52 -0
- package/src/register/register-panel.tsx +151 -0
- package/src/register/register-picker.tsx +60 -0
- package/src/register/register-summary.tsx +72 -0
- package/src/sale/cart-bar.tsx +18 -0
- package/src/sale/cart.tsx +66 -0
- package/src/sale/catalogue.tsx +131 -0
- package/src/sale/discount-form.tsx +85 -0
- package/src/sale/index.ts +9 -0
- package/src/sale/orders-list.tsx +66 -0
- package/src/sale/print-style.ts +11 -0
- package/src/sale/receipt.tsx +61 -0
- package/src/sale/sync-status.tsx +20 -0
- package/src/sale/tender.tsx +35 -0
- package/src/settings/connector-status.tsx +65 -0
- package/src/settings/index.ts +3 -0
- package/src/settings/settings-group.tsx +23 -0
- package/src/settings/settings-row.tsx +23 -0
- package/src/ui/accordion/index.tsx +59 -0
- package/src/ui/alert-dialog/index.tsx +91 -0
- package/src/ui/avatar/index.tsx +50 -0
- package/src/ui/badge/index.tsx +60 -0
- package/src/ui/button/index.tsx +90 -0
- package/src/ui/card/index.tsx +60 -0
- package/src/ui/checkbox/index.tsx +29 -0
- package/src/ui/collapsible/index.tsx +24 -0
- package/src/ui/combobox/index.tsx +98 -0
- package/src/ui/context-menu/index.tsx +159 -0
- package/src/ui/dialog/index.tsx +92 -0
- package/src/ui/dropdown-menu/index.tsx +161 -0
- package/src/ui/hover-card/index.tsx +31 -0
- package/src/ui/hstack/index.tsx +43 -0
- package/src/ui/icon/index.tsx +44 -0
- package/src/ui/icon/search-icon.tsx +9 -0
- package/src/ui/icon/svg-icon.tsx +36 -0
- package/src/ui/icon-button/index.tsx +58 -0
- package/src/ui/index.ts +99 -0
- package/src/ui/input/index.tsx +100 -0
- package/src/ui/label/index.tsx +26 -0
- package/src/ui/loader/index.tsx +37 -0
- package/src/ui/popover/index.tsx +31 -0
- package/src/ui/progress/index.tsx +28 -0
- package/src/ui/radio-group/index.tsx +38 -0
- package/src/ui/select/index.tsx +96 -0
- package/src/ui/separator/index.tsx +29 -0
- package/src/ui/slider/index.tsx +28 -0
- package/src/ui/switch/index.tsx +31 -0
- package/src/ui/table/index.tsx +59 -0
- package/src/ui/tabs/index.tsx +53 -0
- package/src/ui/text/index.tsx +36 -0
- package/src/ui/textarea/index.tsx +29 -0
- package/src/ui/toast/index.tsx +52 -0
- package/src/ui/toggle/index.tsx +69 -0
- package/src/ui/toggle-group/index.tsx +66 -0
- package/src/ui/tooltip/index.tsx +30 -0
- package/src/ui/vstack/index.tsx +43 -0
- package/src/uniwind-env.d.ts +9 -1
- package/src/__tests__/cart-line.test.tsx +0 -53
- package/src/__tests__/cart-panel.test.tsx +0 -55
- package/src/__tests__/cart-total.test.tsx +0 -60
- package/src/__tests__/customer-card.test.tsx +0 -47
- package/src/__tests__/customer-select.test.tsx +0 -33
- package/src/__tests__/filter-chip.test.tsx +0 -40
- package/src/__tests__/helpers.ts +0 -111
- package/src/__tests__/order-summary-line.test.tsx +0 -18
- package/src/__tests__/order-summary.test.tsx +0 -32
- package/src/__tests__/payment-method-card.test.tsx +0 -24
- package/src/__tests__/payment-selector.test.tsx +0 -23
- package/src/__tests__/product-card.test.tsx +0 -31
- package/src/__tests__/product-grid.test.tsx +0 -37
- package/src/__tests__/product-image.test.tsx +0 -54
- package/src/__tests__/product-price.test.tsx +0 -68
- package/src/__tests__/product-sku.test.tsx +0 -47
- package/src/__tests__/product-stock-badge.test.tsx +0 -58
- package/src/__tests__/product-title.test.tsx +0 -38
- package/src/__tests__/search-input.test.tsx +0 -22
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ContextMenu as ContextMenuPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
const ContextMenu = ContextMenuPrimitive.Root;
|
|
6
|
+
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
7
|
+
const ContextMenuGroup = ContextMenuPrimitive.Group;
|
|
8
|
+
const ContextMenuPortal = ContextMenuPrimitive.Portal;
|
|
9
|
+
const ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
10
|
+
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
11
|
+
|
|
12
|
+
const ContextMenuContent = React.forwardRef<
|
|
13
|
+
React.ComponentRef<typeof ContextMenuPrimitive.Content>,
|
|
14
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
|
|
15
|
+
>(function ContextMenuContent({ className, ...props }, ref) {
|
|
16
|
+
return (
|
|
17
|
+
<ContextMenuPrimitive.Portal>
|
|
18
|
+
<ContextMenuPrimitive.Content
|
|
19
|
+
ref={ref}
|
|
20
|
+
className={cn(
|
|
21
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md',
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
</ContextMenuPrimitive.Portal>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
ContextMenuContent.displayName = 'ContextMenuContent';
|
|
30
|
+
|
|
31
|
+
const ContextMenuItem = React.forwardRef<
|
|
32
|
+
React.ComponentRef<typeof ContextMenuPrimitive.Item>,
|
|
33
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & { inset?: boolean }
|
|
34
|
+
>(function ContextMenuItem({ className, inset, ...props }, ref) {
|
|
35
|
+
return (
|
|
36
|
+
<TextClassContext.Provider value="select-none text-sm">
|
|
37
|
+
<ContextMenuPrimitive.Item
|
|
38
|
+
ref={ref}
|
|
39
|
+
className={cn(
|
|
40
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm px-2 py-1.5 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
41
|
+
inset && 'pl-8',
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
</TextClassContext.Provider>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
ContextMenuItem.displayName = 'ContextMenuItem';
|
|
50
|
+
|
|
51
|
+
const ContextMenuCheckboxItem = React.forwardRef<
|
|
52
|
+
React.ComponentRef<typeof ContextMenuPrimitive.CheckboxItem>,
|
|
53
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
|
|
54
|
+
>(function ContextMenuCheckboxItem({ className, children, checked, ...props }, ref) {
|
|
55
|
+
return (
|
|
56
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
57
|
+
ref={ref}
|
|
58
|
+
checked={checked}
|
|
59
|
+
className={cn(
|
|
60
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
ContextMenuCheckboxItem.displayName = 'ContextMenuCheckboxItem';
|
|
70
|
+
|
|
71
|
+
const ContextMenuRadioItem = React.forwardRef<
|
|
72
|
+
React.ComponentRef<typeof ContextMenuPrimitive.RadioItem>,
|
|
73
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
|
|
74
|
+
>(function ContextMenuRadioItem({ className, children, ...props }, ref) {
|
|
75
|
+
return (
|
|
76
|
+
<ContextMenuPrimitive.RadioItem
|
|
77
|
+
ref={ref}
|
|
78
|
+
className={cn(
|
|
79
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
80
|
+
className,
|
|
81
|
+
)}
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</ContextMenuPrimitive.RadioItem>
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
ContextMenuRadioItem.displayName = 'ContextMenuRadioItem';
|
|
89
|
+
|
|
90
|
+
const ContextMenuLabel = React.forwardRef<
|
|
91
|
+
React.ComponentRef<typeof ContextMenuPrimitive.Label>,
|
|
92
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & { inset?: boolean }
|
|
93
|
+
>(function ContextMenuLabel({ className, inset, ...props }, ref) {
|
|
94
|
+
return (
|
|
95
|
+
<ContextMenuPrimitive.Label
|
|
96
|
+
ref={ref}
|
|
97
|
+
className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
ContextMenuLabel.displayName = 'ContextMenuLabel';
|
|
103
|
+
|
|
104
|
+
const ContextMenuSeparator = React.forwardRef<
|
|
105
|
+
React.ComponentRef<typeof ContextMenuPrimitive.Separator>,
|
|
106
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
|
|
107
|
+
>(function ContextMenuSeparator({ className, ...props }, ref) {
|
|
108
|
+
return (
|
|
109
|
+
<ContextMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
ContextMenuSeparator.displayName = 'ContextMenuSeparator';
|
|
113
|
+
|
|
114
|
+
const ContextMenuSubTrigger = React.forwardRef<
|
|
115
|
+
React.ComponentRef<typeof ContextMenuPrimitive.SubTrigger>,
|
|
116
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }
|
|
117
|
+
>(function ContextMenuSubTrigger({ className, inset, children, ...props }, ref) {
|
|
118
|
+
return (
|
|
119
|
+
<TextClassContext.Provider value="select-none text-sm">
|
|
120
|
+
<ContextMenuPrimitive.SubTrigger
|
|
121
|
+
ref={ref}
|
|
122
|
+
className={cn(
|
|
123
|
+
'flex cursor-default select-none flex-row items-center rounded-sm px-2 py-1.5 text-sm outline-none web:focus:bg-accent',
|
|
124
|
+
inset && 'pl-8',
|
|
125
|
+
className,
|
|
126
|
+
)}
|
|
127
|
+
{...props}
|
|
128
|
+
>
|
|
129
|
+
{children}
|
|
130
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
131
|
+
</TextClassContext.Provider>
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
ContextMenuSubTrigger.displayName = 'ContextMenuSubTrigger';
|
|
135
|
+
|
|
136
|
+
const ContextMenuSubContent = React.forwardRef<
|
|
137
|
+
React.ComponentRef<typeof ContextMenuPrimitive.SubContent>,
|
|
138
|
+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
|
|
139
|
+
>(function ContextMenuSubContent({ className, ...props }, ref) {
|
|
140
|
+
return (
|
|
141
|
+
<ContextMenuPrimitive.SubContent
|
|
142
|
+
ref={ref}
|
|
143
|
+
className={cn(
|
|
144
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg',
|
|
145
|
+
className,
|
|
146
|
+
)}
|
|
147
|
+
{...props}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
ContextMenuSubContent.displayName = 'ContextMenuSubContent';
|
|
152
|
+
|
|
153
|
+
export {
|
|
154
|
+
ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem,
|
|
155
|
+
ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel,
|
|
156
|
+
ContextMenuSeparator, ContextMenuGroup, ContextMenuPortal,
|
|
157
|
+
ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger,
|
|
158
|
+
ContextMenuRadioGroup,
|
|
159
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, Text, Pressable } from 'react-native';
|
|
3
|
+
import { Dialog as DialogPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
const Dialog = DialogPrimitive.Root;
|
|
7
|
+
const DialogTrigger = DialogPrimitive.Trigger;
|
|
8
|
+
const DialogPortal = DialogPrimitive.Portal;
|
|
9
|
+
const DialogClose = DialogPrimitive.Close;
|
|
10
|
+
|
|
11
|
+
const DialogOverlay = React.forwardRef<
|
|
12
|
+
React.ComponentRef<typeof DialogPrimitive.Overlay>,
|
|
13
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
|
14
|
+
>(function DialogOverlay({ className, ...props }, ref) {
|
|
15
|
+
return (
|
|
16
|
+
<DialogPrimitive.Overlay
|
|
17
|
+
ref={ref}
|
|
18
|
+
className={cn('fixed inset-0 z-50 bg-black/80', className)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
DialogOverlay.displayName = 'DialogOverlay';
|
|
24
|
+
|
|
25
|
+
const DialogContent = React.forwardRef<
|
|
26
|
+
React.ComponentRef<typeof DialogPrimitive.Content>,
|
|
27
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
|
28
|
+
>(function DialogContent({ className, children, ...props }, ref) {
|
|
29
|
+
return (
|
|
30
|
+
<DialogPortal>
|
|
31
|
+
<DialogOverlay />
|
|
32
|
+
<DialogPrimitive.Content
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn(
|
|
35
|
+
'fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border border-border bg-background p-6 shadow-lg',
|
|
36
|
+
className,
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
{children}
|
|
41
|
+
</DialogPrimitive.Content>
|
|
42
|
+
</DialogPortal>
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
DialogContent.displayName = 'DialogContent';
|
|
46
|
+
|
|
47
|
+
function DialogHeader({ className, ...props }: React.ComponentPropsWithoutRef<typeof View>) {
|
|
48
|
+
return (
|
|
49
|
+
<View className={cn('flex flex-col gap-1.5 text-center sm:text-left', className)} {...props} />
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function DialogFooter({ className, ...props }: React.ComponentPropsWithoutRef<typeof View>) {
|
|
54
|
+
return (
|
|
55
|
+
<View className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2', className)} {...props} />
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const DialogTitle = React.forwardRef<
|
|
60
|
+
React.ComponentRef<typeof DialogPrimitive.Title>,
|
|
61
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
|
62
|
+
>(function DialogTitle({ className, ...props }, ref) {
|
|
63
|
+
return (
|
|
64
|
+
<TextClassContext.Provider value="text-lg font-semibold leading-none text-foreground">
|
|
65
|
+
<DialogPrimitive.Title ref={ref} className={cn('text-lg font-semibold leading-none text-foreground', className)} {...props} />
|
|
66
|
+
</TextClassContext.Provider>
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
DialogTitle.displayName = 'DialogTitle';
|
|
70
|
+
|
|
71
|
+
const DialogDescription = React.forwardRef<
|
|
72
|
+
React.ComponentRef<typeof DialogPrimitive.Description>,
|
|
73
|
+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
|
74
|
+
>(function DialogDescription({ className, ...props }, ref) {
|
|
75
|
+
return (
|
|
76
|
+
<DialogPrimitive.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
DialogDescription.displayName = 'DialogDescription';
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
Dialog,
|
|
83
|
+
DialogTrigger,
|
|
84
|
+
DialogPortal,
|
|
85
|
+
DialogOverlay,
|
|
86
|
+
DialogContent,
|
|
87
|
+
DialogHeader,
|
|
88
|
+
DialogFooter,
|
|
89
|
+
DialogTitle,
|
|
90
|
+
DialogDescription,
|
|
91
|
+
DialogClose,
|
|
92
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { DropdownMenu as DropdownMenuPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
7
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
8
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
9
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
10
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
11
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
12
|
+
|
|
13
|
+
const DropdownMenuContent = React.forwardRef<
|
|
14
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Content>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
16
|
+
>(function DropdownMenuContent({ className, sideOffset = 4, ...props }, ref) {
|
|
17
|
+
return (
|
|
18
|
+
<DropdownMenuPrimitive.Portal>
|
|
19
|
+
<DropdownMenuPrimitive.Content
|
|
20
|
+
ref={ref}
|
|
21
|
+
sideOffset={sideOffset}
|
|
22
|
+
className={cn(
|
|
23
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md',
|
|
24
|
+
className,
|
|
25
|
+
)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
</DropdownMenuPrimitive.Portal>
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
DropdownMenuContent.displayName = 'DropdownMenuContent';
|
|
32
|
+
|
|
33
|
+
const DropdownMenuItem = React.forwardRef<
|
|
34
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Item>,
|
|
35
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { inset?: boolean }
|
|
36
|
+
>(function DropdownMenuItem({ className, inset, ...props }, ref) {
|
|
37
|
+
return (
|
|
38
|
+
<TextClassContext.Provider value="select-none text-sm">
|
|
39
|
+
<DropdownMenuPrimitive.Item
|
|
40
|
+
ref={ref}
|
|
41
|
+
className={cn(
|
|
42
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm px-2 py-1.5 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
43
|
+
inset && 'pl-8',
|
|
44
|
+
className,
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
</TextClassContext.Provider>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
DropdownMenuItem.displayName = 'DropdownMenuItem';
|
|
52
|
+
|
|
53
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
54
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
55
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
56
|
+
>(function DropdownMenuCheckboxItem({ className, children, checked, ...props }, ref) {
|
|
57
|
+
return (
|
|
58
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
59
|
+
ref={ref}
|
|
60
|
+
checked={checked}
|
|
61
|
+
className={cn(
|
|
62
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
DropdownMenuCheckboxItem.displayName = 'DropdownMenuCheckboxItem';
|
|
72
|
+
|
|
73
|
+
const DropdownMenuRadioItem = React.forwardRef<
|
|
74
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
75
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
76
|
+
>(function DropdownMenuRadioItem({ className, children, ...props }, ref) {
|
|
77
|
+
return (
|
|
78
|
+
<DropdownMenuPrimitive.RadioItem
|
|
79
|
+
ref={ref}
|
|
80
|
+
className={cn(
|
|
81
|
+
'relative flex cursor-default select-none flex-row items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none web:focus:bg-accent web:focus:text-accent-foreground',
|
|
82
|
+
className,
|
|
83
|
+
)}
|
|
84
|
+
{...props}
|
|
85
|
+
>
|
|
86
|
+
{children}
|
|
87
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
DropdownMenuRadioItem.displayName = 'DropdownMenuRadioItem';
|
|
91
|
+
|
|
92
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
93
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Label>,
|
|
94
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }
|
|
95
|
+
>(function DropdownMenuLabel({ className, inset, ...props }, ref) {
|
|
96
|
+
return (
|
|
97
|
+
<DropdownMenuPrimitive.Label
|
|
98
|
+
ref={ref}
|
|
99
|
+
className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
DropdownMenuLabel.displayName = 'DropdownMenuLabel';
|
|
105
|
+
|
|
106
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
107
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,
|
|
108
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
109
|
+
>(function DropdownMenuSeparator({ className, ...props }, ref) {
|
|
110
|
+
return (
|
|
111
|
+
<DropdownMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
DropdownMenuSeparator.displayName = 'DropdownMenuSeparator';
|
|
115
|
+
|
|
116
|
+
const DropdownMenuSubTrigger = React.forwardRef<
|
|
117
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
118
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }
|
|
119
|
+
>(function DropdownMenuSubTrigger({ className, inset, children, ...props }, ref) {
|
|
120
|
+
return (
|
|
121
|
+
<TextClassContext.Provider value="select-none text-sm">
|
|
122
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
123
|
+
ref={ref}
|
|
124
|
+
className={cn(
|
|
125
|
+
'flex cursor-default select-none flex-row items-center rounded-sm px-2 py-1.5 text-sm outline-none web:focus:bg-accent',
|
|
126
|
+
inset && 'pl-8',
|
|
127
|
+
className,
|
|
128
|
+
)}
|
|
129
|
+
{...props}
|
|
130
|
+
>
|
|
131
|
+
{children}
|
|
132
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
133
|
+
</TextClassContext.Provider>
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
DropdownMenuSubTrigger.displayName = 'DropdownMenuSubTrigger';
|
|
137
|
+
|
|
138
|
+
const DropdownMenuSubContent = React.forwardRef<
|
|
139
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
140
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
141
|
+
>(function DropdownMenuSubContent({ className, ...props }, ref) {
|
|
142
|
+
return (
|
|
143
|
+
<DropdownMenuPrimitive.SubContent
|
|
144
|
+
ref={ref}
|
|
145
|
+
className={cn(
|
|
146
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg',
|
|
147
|
+
className,
|
|
148
|
+
)}
|
|
149
|
+
{...props}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
DropdownMenuSubContent.displayName = 'DropdownMenuSubContent';
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem,
|
|
157
|
+
DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel,
|
|
158
|
+
DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuPortal,
|
|
159
|
+
DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger,
|
|
160
|
+
DropdownMenuRadioGroup,
|
|
161
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { HoverCard as HoverCardPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
const HoverCard = HoverCardPrimitive.Root;
|
|
6
|
+
const HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
7
|
+
|
|
8
|
+
const HoverCardContent = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof HoverCardPrimitive.Content>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
|
|
11
|
+
>(function HoverCardContent({ className, align = 'center', sideOffset = 4, ...props }, ref) {
|
|
12
|
+
return (
|
|
13
|
+
<HoverCardPrimitive.Portal>
|
|
14
|
+
<TextClassContext.Provider value="text-popover-foreground">
|
|
15
|
+
<HoverCardPrimitive.Content
|
|
16
|
+
ref={ref}
|
|
17
|
+
align={align}
|
|
18
|
+
sideOffset={sideOffset}
|
|
19
|
+
className={cn(
|
|
20
|
+
'z-50 w-64 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
</TextClassContext.Provider>
|
|
26
|
+
</HoverCardPrimitive.Portal>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
HoverCardContent.displayName = 'HoverCardContent';
|
|
30
|
+
|
|
31
|
+
export { HoverCard, HoverCardTrigger, HoverCardContent };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, type ViewProps } from 'react-native';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
const hstackVariants = cva('flex-row items-center', {
|
|
7
|
+
variants: {
|
|
8
|
+
space: {
|
|
9
|
+
none: 'gap-0',
|
|
10
|
+
xs: 'gap-1',
|
|
11
|
+
sm: 'gap-2',
|
|
12
|
+
md: 'gap-3',
|
|
13
|
+
lg: 'gap-4',
|
|
14
|
+
xl: 'gap-6',
|
|
15
|
+
},
|
|
16
|
+
reversed: {
|
|
17
|
+
true: 'flex-row-reverse',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
space: 'md',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
type HStackProps = ViewProps & VariantProps<typeof hstackVariants>;
|
|
26
|
+
|
|
27
|
+
const HStack = React.forwardRef<View, HStackProps>(function HStack(
|
|
28
|
+
{ className, space, reversed, ...props },
|
|
29
|
+
ref
|
|
30
|
+
) {
|
|
31
|
+
return (
|
|
32
|
+
<View
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn(hstackVariants({ space, reversed }), className)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
HStack.displayName = 'HStack';
|
|
41
|
+
|
|
42
|
+
export { HStack, hstackVariants };
|
|
43
|
+
export type { HStackProps };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, type ViewProps } from 'react-native';
|
|
3
|
+
import { TextClassContext } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
const iconVariants = cva('items-center justify-center', {
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
xs: 'h-3 w-3',
|
|
11
|
+
sm: 'h-4 w-4',
|
|
12
|
+
md: 'h-5 w-5',
|
|
13
|
+
lg: 'h-6 w-6',
|
|
14
|
+
xl: 'h-8 w-8',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
size: 'md',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
type IconProps = ViewProps & VariantProps<typeof iconVariants>;
|
|
23
|
+
|
|
24
|
+
const Icon = React.forwardRef<View, IconProps>(function Icon(
|
|
25
|
+
{ className, size, children, ...props },
|
|
26
|
+
ref
|
|
27
|
+
) {
|
|
28
|
+
const textClass = React.useContext(TextClassContext);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<View
|
|
32
|
+
ref={ref}
|
|
33
|
+
className={cn(iconVariants({ size }), textClass, className)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</View>
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
Icon.displayName = 'Icon';
|
|
42
|
+
|
|
43
|
+
export { Icon, iconVariants };
|
|
44
|
+
export type { IconProps };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import Svg, { type SvgProps } from 'react-native-svg';
|
|
3
|
+
|
|
4
|
+
export type SvgIconProps = {
|
|
5
|
+
size?: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
strokeWidth?: number;
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
} & Omit<SvgProps, 'width' | 'height' | 'color'>;
|
|
10
|
+
|
|
11
|
+
export function createSvgIcon(name: string, render: (props: { strokeWidth: number }) => React.ReactNode) {
|
|
12
|
+
function SvgIcon({ size = 16, color, strokeWidth = 2, accessibilityLabel, ...props }: SvgIconProps) {
|
|
13
|
+
return (
|
|
14
|
+
<Svg
|
|
15
|
+
{...props}
|
|
16
|
+
viewBox="0 0 24 24"
|
|
17
|
+
width={size}
|
|
18
|
+
height={size}
|
|
19
|
+
fill="none"
|
|
20
|
+
stroke={color ?? 'currentColor'}
|
|
21
|
+
strokeWidth={strokeWidth}
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
color={color}
|
|
25
|
+
aria-hidden={accessibilityLabel === undefined}
|
|
26
|
+
role={accessibilityLabel === undefined ? undefined : 'img'}
|
|
27
|
+
aria-label={accessibilityLabel}
|
|
28
|
+
>
|
|
29
|
+
{render({ strokeWidth })}
|
|
30
|
+
</Svg>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
SvgIcon.displayName = name;
|
|
35
|
+
return SvgIcon;
|
|
36
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Pressable, type PressableProps } from 'react-native';
|
|
3
|
+
import { Slot } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
const iconButtonVariants = cva(
|
|
8
|
+
'inline-flex items-center justify-center rounded-md web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'bg-primary active:opacity-90',
|
|
13
|
+
destructive: 'bg-destructive active:opacity-90',
|
|
14
|
+
outline: 'border border-input bg-background active:bg-accent',
|
|
15
|
+
secondary: 'bg-secondary active:opacity-80',
|
|
16
|
+
ghost: 'active:bg-accent',
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
sm: 'h-8 w-8',
|
|
20
|
+
md: 'h-10 w-10',
|
|
21
|
+
lg: 'h-12 w-12',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: 'ghost',
|
|
26
|
+
size: 'md',
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
type IconButtonProps = PressableProps & VariantProps<typeof iconButtonVariants> & {
|
|
32
|
+
asChild?: boolean;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const IconButton = React.forwardRef<React.ComponentRef<typeof Pressable>, IconButtonProps>(
|
|
36
|
+
function IconButton({ className, variant, size, asChild = false, disabled, ...props }, ref) {
|
|
37
|
+
const Component = asChild ? Slot : Pressable;
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Component
|
|
41
|
+
ref={ref}
|
|
42
|
+
role="button"
|
|
43
|
+
disabled={disabled}
|
|
44
|
+
className={cn(
|
|
45
|
+
iconButtonVariants({ variant, size }),
|
|
46
|
+
disabled && 'opacity-50 web:pointer-events-none',
|
|
47
|
+
className,
|
|
48
|
+
)}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
IconButton.displayName = 'IconButton';
|
|
56
|
+
|
|
57
|
+
export { IconButton, iconButtonVariants };
|
|
58
|
+
export type { IconButtonProps };
|