@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
package/src/ui/index.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Core
|
|
2
|
+
export { Text, TextClassContext, textVariants, type TextProps } from './text';
|
|
3
|
+
export { HStack, hstackVariants, type HStackProps } from './hstack';
|
|
4
|
+
export { VStack, vstackVariants, type VStackProps } from './vstack';
|
|
5
|
+
|
|
6
|
+
// Visual
|
|
7
|
+
export { Icon, iconVariants, type IconProps } from './icon';
|
|
8
|
+
export { createSvgIcon, type SvgIconProps } from './icon/svg-icon';
|
|
9
|
+
export { SearchIcon } from './icon/search-icon';
|
|
10
|
+
export { Loader, loaderVariants, type LoaderProps } from './loader';
|
|
11
|
+
export { Badge, badgeVariants, badgeTextVariants, type BadgeProps } from './badge';
|
|
12
|
+
export { Avatar, avatarVariants, type AvatarProps } from './avatar';
|
|
13
|
+
|
|
14
|
+
// Interactive
|
|
15
|
+
export { Button, buttonVariants, buttonTextVariants, type ButtonProps } from './button';
|
|
16
|
+
export { IconButton, iconButtonVariants, type IconButtonProps } from './icon-button';
|
|
17
|
+
|
|
18
|
+
// Containers & Form
|
|
19
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './card';
|
|
20
|
+
export { Separator, type SeparatorProps } from './separator';
|
|
21
|
+
export { Label, type LabelProps } from './label';
|
|
22
|
+
export { Input, InputRoot, InputField, InputSlot, useInputContext, type InputRootProps } from './input';
|
|
23
|
+
export { Textarea, type TextareaProps } from './textarea';
|
|
24
|
+
|
|
25
|
+
// Tabs
|
|
26
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent } from './tabs';
|
|
27
|
+
|
|
28
|
+
// Dialog
|
|
29
|
+
export {
|
|
30
|
+
Dialog, DialogTrigger, DialogPortal, DialogOverlay, DialogContent,
|
|
31
|
+
DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogClose,
|
|
32
|
+
} from './dialog';
|
|
33
|
+
|
|
34
|
+
// Alert Dialog
|
|
35
|
+
export {
|
|
36
|
+
AlertDialog, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay,
|
|
37
|
+
AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle,
|
|
38
|
+
AlertDialogDescription, AlertDialogAction, AlertDialogCancel,
|
|
39
|
+
} from './alert-dialog';
|
|
40
|
+
|
|
41
|
+
// Select
|
|
42
|
+
export {
|
|
43
|
+
Select, SelectGroup, SelectValue, SelectTrigger, SelectContent,
|
|
44
|
+
SelectLabel, SelectItem, SelectSeparator,
|
|
45
|
+
} from './select';
|
|
46
|
+
|
|
47
|
+
// Combobox
|
|
48
|
+
export {
|
|
49
|
+
Combobox, ComboboxTrigger, ComboboxInput, ComboboxContent,
|
|
50
|
+
ComboboxItem, ComboboxEmpty,
|
|
51
|
+
} from './combobox';
|
|
52
|
+
|
|
53
|
+
// Dropdown Menu
|
|
54
|
+
export {
|
|
55
|
+
DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem,
|
|
56
|
+
DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel,
|
|
57
|
+
DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuPortal,
|
|
58
|
+
DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger,
|
|
59
|
+
DropdownMenuRadioGroup,
|
|
60
|
+
} from './dropdown-menu';
|
|
61
|
+
|
|
62
|
+
// Context Menu
|
|
63
|
+
export {
|
|
64
|
+
ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem,
|
|
65
|
+
ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel,
|
|
66
|
+
ContextMenuSeparator, ContextMenuGroup, ContextMenuPortal,
|
|
67
|
+
ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger,
|
|
68
|
+
ContextMenuRadioGroup,
|
|
69
|
+
} from './context-menu';
|
|
70
|
+
|
|
71
|
+
// Popover
|
|
72
|
+
export { Popover, PopoverTrigger, PopoverContent } from './popover';
|
|
73
|
+
|
|
74
|
+
// Tooltip
|
|
75
|
+
export { Tooltip, TooltipTrigger, TooltipContent } from './tooltip';
|
|
76
|
+
|
|
77
|
+
// Hover Card
|
|
78
|
+
export { HoverCard, HoverCardTrigger, HoverCardContent } from './hover-card';
|
|
79
|
+
|
|
80
|
+
// Accordion
|
|
81
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './accordion';
|
|
82
|
+
|
|
83
|
+
// Collapsible
|
|
84
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent } from './collapsible';
|
|
85
|
+
|
|
86
|
+
// Form Controls
|
|
87
|
+
export { Checkbox } from './checkbox';
|
|
88
|
+
export { Switch } from './switch';
|
|
89
|
+
export { RadioGroup, RadioGroupItem } from './radio-group';
|
|
90
|
+
export { Toggle, toggleVariants, toggleTextVariants, type ToggleProps } from './toggle';
|
|
91
|
+
export { ToggleGroup, ToggleGroupItem, type ToggleGroupProps, type ToggleGroupItemProps } from './toggle-group';
|
|
92
|
+
export { Progress, type ProgressProps } from './progress';
|
|
93
|
+
export { Slider, type SliderProps } from './slider';
|
|
94
|
+
|
|
95
|
+
// Toast
|
|
96
|
+
export { Toast, ToastTitle, ToastDescription, ToastClose, toastVariants, type ToastProps } from './toast';
|
|
97
|
+
|
|
98
|
+
// Table
|
|
99
|
+
export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell } from './table';
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TextInput, View, type TextInputProps, type ViewProps } from 'react-native';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
interface InputContextType {
|
|
6
|
+
focused: boolean;
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const InputContext = React.createContext<InputContextType>({
|
|
11
|
+
focused: false,
|
|
12
|
+
disabled: false,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
function useInputContext() {
|
|
16
|
+
return React.useContext(InputContext);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Root container
|
|
20
|
+
interface InputRootProps extends ViewProps {
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const InputRoot = React.forwardRef<View, InputRootProps>(
|
|
25
|
+
function InputRoot({ className, disabled = false, children, ...props }, ref) {
|
|
26
|
+
const [focused, setFocused] = React.useState(false);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<InputContext.Provider value={{ focused, disabled }}>
|
|
30
|
+
<View
|
|
31
|
+
ref={ref}
|
|
32
|
+
className={cn(
|
|
33
|
+
'flex h-10 flex-row items-center rounded-md border border-input bg-background px-3',
|
|
34
|
+
focused && 'ring-2 ring-ring ring-offset-2',
|
|
35
|
+
disabled && 'opacity-50',
|
|
36
|
+
className,
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
{React.Children.map(children, (child) => {
|
|
41
|
+
if (React.isValidElement(child) && child.type === InputField) {
|
|
42
|
+
return React.cloneElement(child as React.ReactElement<any>, {
|
|
43
|
+
onFocus: (e: any) => {
|
|
44
|
+
setFocused(true);
|
|
45
|
+
(child.props as any).onFocus?.(e);
|
|
46
|
+
},
|
|
47
|
+
onBlur: (e: any) => {
|
|
48
|
+
setFocused(false);
|
|
49
|
+
(child.props as any).onBlur?.(e);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return child;
|
|
54
|
+
})}
|
|
55
|
+
</View>
|
|
56
|
+
</InputContext.Provider>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
InputRoot.displayName = 'InputRoot';
|
|
61
|
+
|
|
62
|
+
// Left/Right slots
|
|
63
|
+
const InputSlot = React.forwardRef<View, ViewProps>(
|
|
64
|
+
function InputSlot({ className, ...props }, ref) {
|
|
65
|
+
return (
|
|
66
|
+
<View ref={ref} className={cn('justify-center', className)} {...props} />
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
InputSlot.displayName = 'InputSlot';
|
|
71
|
+
|
|
72
|
+
// The actual text input
|
|
73
|
+
const InputField = React.forwardRef<TextInput, TextInputProps>(
|
|
74
|
+
function InputField({ className, ...props }, ref) {
|
|
75
|
+
const { disabled } = useInputContext();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<TextInput
|
|
79
|
+
ref={ref}
|
|
80
|
+
editable={!disabled}
|
|
81
|
+
className={cn(
|
|
82
|
+
'flex-1 text-sm text-foreground web:outline-none placeholder:text-muted-foreground',
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
InputField.displayName = 'InputField';
|
|
91
|
+
|
|
92
|
+
// Convenience compound component
|
|
93
|
+
const Input = Object.assign(InputRoot, {
|
|
94
|
+
Left: InputSlot,
|
|
95
|
+
Field: InputField,
|
|
96
|
+
Right: InputSlot,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export { Input, InputRoot, InputField, InputSlot, useInputContext };
|
|
100
|
+
export type { InputRootProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Text } from 'react-native';
|
|
3
|
+
import { Label as LabelPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>;
|
|
7
|
+
|
|
8
|
+
const Label = React.forwardRef<React.ComponentRef<typeof Text>, LabelProps>(
|
|
9
|
+
function Label({ className, ...props }, ref) {
|
|
10
|
+
return (
|
|
11
|
+
<LabelPrimitive.Root
|
|
12
|
+
ref={ref}
|
|
13
|
+
className={cn(
|
|
14
|
+
'text-sm font-medium leading-none text-foreground web:peer-disabled:cursor-not-allowed web:peer-disabled:opacity-70',
|
|
15
|
+
className,
|
|
16
|
+
)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
Label.displayName = 'Label';
|
|
24
|
+
|
|
25
|
+
export { Label };
|
|
26
|
+
export type { LabelProps };
|
|
@@ -0,0 +1,37 @@
|
|
|
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 loaderVariants = cva('animate-spin', {
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
sm: 'h-4 w-4',
|
|
11
|
+
md: 'h-5 w-5',
|
|
12
|
+
lg: 'h-8 w-8',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
size: 'md',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
type LoaderProps = Omit<ViewProps, 'children'> & VariantProps<typeof loaderVariants>;
|
|
21
|
+
|
|
22
|
+
function Loader({ className, size, ...props }: LoaderProps) {
|
|
23
|
+
const textClass = React.useContext(TextClassContext);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<View
|
|
27
|
+
className={cn(loaderVariants({ size }), textClass, className)}
|
|
28
|
+
role="progressbar"
|
|
29
|
+
{...props}
|
|
30
|
+
>
|
|
31
|
+
<View className="h-full w-full rounded-full border-2 border-current border-t-transparent" />
|
|
32
|
+
</View>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { Loader, loaderVariants };
|
|
37
|
+
export type { LoaderProps };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Popover as PopoverPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
const Popover = PopoverPrimitive.Root;
|
|
6
|
+
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
7
|
+
|
|
8
|
+
const PopoverContent = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof PopoverPrimitive.Content>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
|
11
|
+
>(function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }, ref) {
|
|
12
|
+
return (
|
|
13
|
+
<PopoverPrimitive.Portal>
|
|
14
|
+
<TextClassContext.Provider value="text-popover-foreground">
|
|
15
|
+
<PopoverPrimitive.Content
|
|
16
|
+
ref={ref}
|
|
17
|
+
align={align}
|
|
18
|
+
sideOffset={sideOffset}
|
|
19
|
+
className={cn(
|
|
20
|
+
'z-50 w-72 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
|
+
</PopoverPrimitive.Portal>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
PopoverContent.displayName = 'PopoverContent';
|
|
30
|
+
|
|
31
|
+
export { Popover, PopoverTrigger, PopoverContent };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Progress as ProgressPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
type ProgressProps = React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>;
|
|
7
|
+
|
|
8
|
+
const Progress = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof ProgressPrimitive.Root>,
|
|
10
|
+
ProgressProps
|
|
11
|
+
>(function Progress({ className, value, ...props }, ref) {
|
|
12
|
+
return (
|
|
13
|
+
<ProgressPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn('relative h-4 w-full overflow-hidden rounded-full bg-secondary', className)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<ProgressPrimitive.Indicator
|
|
19
|
+
className="h-full w-full flex-1 rounded-full bg-primary web:transition-all"
|
|
20
|
+
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
21
|
+
/>
|
|
22
|
+
</ProgressPrimitive.Root>
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
Progress.displayName = 'Progress';
|
|
26
|
+
|
|
27
|
+
export { Progress };
|
|
28
|
+
export type { ProgressProps };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, Text } from 'react-native';
|
|
3
|
+
import { RadioGroup as RadioGroupPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
const RadioGroup = React.forwardRef<
|
|
7
|
+
React.ComponentRef<typeof RadioGroupPrimitive.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
|
|
9
|
+
>(function RadioGroup({ className, ...props }, ref) {
|
|
10
|
+
return (
|
|
11
|
+
<RadioGroupPrimitive.Root ref={ref} className={cn('grid gap-2', className)} {...props} />
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
RadioGroup.displayName = 'RadioGroup';
|
|
15
|
+
|
|
16
|
+
const RadioGroupItem = React.forwardRef<
|
|
17
|
+
React.ComponentRef<typeof RadioGroupPrimitive.Item>,
|
|
18
|
+
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
|
|
19
|
+
>(function RadioGroupItem({ className, ...props }, ref) {
|
|
20
|
+
return (
|
|
21
|
+
<RadioGroupPrimitive.Item
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
'aspect-square h-4 w-4 rounded-full border border-primary text-primary web:ring-offset-background web:focus:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2',
|
|
25
|
+
props.disabled && 'web:cursor-not-allowed opacity-50',
|
|
26
|
+
className,
|
|
27
|
+
)}
|
|
28
|
+
{...props}
|
|
29
|
+
>
|
|
30
|
+
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
31
|
+
<View className="h-2.5 w-2.5 rounded-full bg-current" />
|
|
32
|
+
</RadioGroupPrimitive.Indicator>
|
|
33
|
+
</RadioGroupPrimitive.Item>
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
RadioGroupItem.displayName = 'RadioGroupItem';
|
|
37
|
+
|
|
38
|
+
export { RadioGroup, RadioGroupItem };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Select as SelectPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
const Select = SelectPrimitive.Root;
|
|
7
|
+
const SelectGroup = SelectPrimitive.Group;
|
|
8
|
+
const SelectValue = SelectPrimitive.Value;
|
|
9
|
+
|
|
10
|
+
const SelectTrigger = React.forwardRef<
|
|
11
|
+
React.ComponentRef<typeof SelectPrimitive.Trigger>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
|
13
|
+
>(function SelectTrigger({ className, children, ...props }, ref) {
|
|
14
|
+
return (
|
|
15
|
+
<SelectPrimitive.Trigger
|
|
16
|
+
ref={ref}
|
|
17
|
+
className={cn(
|
|
18
|
+
'flex h-10 w-full flex-row items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground web:ring-offset-background web:focus:outline-none web:focus:ring-2 web:focus:ring-ring web:focus:ring-offset-2',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</SelectPrimitive.Trigger>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
SelectTrigger.displayName = 'SelectTrigger';
|
|
28
|
+
|
|
29
|
+
const SelectContent = React.forwardRef<
|
|
30
|
+
React.ComponentRef<typeof SelectPrimitive.Content>,
|
|
31
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
|
32
|
+
>(function SelectContent({ className, children, ...props }, ref) {
|
|
33
|
+
return (
|
|
34
|
+
<SelectPrimitive.Portal>
|
|
35
|
+
<SelectPrimitive.Content
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(
|
|
38
|
+
'relative z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md',
|
|
39
|
+
className,
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</SelectPrimitive.Content>
|
|
45
|
+
</SelectPrimitive.Portal>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
SelectContent.displayName = 'SelectContent';
|
|
49
|
+
|
|
50
|
+
const SelectLabel = React.forwardRef<
|
|
51
|
+
React.ComponentRef<typeof SelectPrimitive.Label>,
|
|
52
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
|
53
|
+
>(function SelectLabel({ className, ...props }, ref) {
|
|
54
|
+
return (
|
|
55
|
+
<SelectPrimitive.Label ref={ref} className={cn('py-1.5 pl-8 pr-2 text-sm font-semibold', className)} {...props} />
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
SelectLabel.displayName = 'SelectLabel';
|
|
59
|
+
|
|
60
|
+
const SelectItem = React.forwardRef<
|
|
61
|
+
React.ComponentRef<typeof SelectPrimitive.Item>,
|
|
62
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
|
63
|
+
>(function SelectItem({ className, ...props }, ref) {
|
|
64
|
+
return (
|
|
65
|
+
<SelectPrimitive.Item
|
|
66
|
+
ref={ref}
|
|
67
|
+
className={cn(
|
|
68
|
+
'relative flex w-full 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',
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
SelectItem.displayName = 'SelectItem';
|
|
76
|
+
|
|
77
|
+
const SelectSeparator = React.forwardRef<
|
|
78
|
+
React.ComponentRef<typeof SelectPrimitive.Separator>,
|
|
79
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
|
80
|
+
>(function SelectSeparator({ className, ...props }, ref) {
|
|
81
|
+
return (
|
|
82
|
+
<SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
SelectSeparator.displayName = 'SelectSeparator';
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
Select,
|
|
89
|
+
SelectGroup,
|
|
90
|
+
SelectValue,
|
|
91
|
+
SelectTrigger,
|
|
92
|
+
SelectContent,
|
|
93
|
+
SelectLabel,
|
|
94
|
+
SelectItem,
|
|
95
|
+
SelectSeparator,
|
|
96
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Separator as SeparatorPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
type SeparatorProps = React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>;
|
|
7
|
+
|
|
8
|
+
const Separator = React.forwardRef<React.ComponentRef<typeof View>, SeparatorProps>(
|
|
9
|
+
function Separator({ className, orientation = 'horizontal', decorative = true, ...props }, ref) {
|
|
10
|
+
return (
|
|
11
|
+
<SeparatorPrimitive.Root
|
|
12
|
+
ref={ref}
|
|
13
|
+
decorative={decorative}
|
|
14
|
+
orientation={orientation}
|
|
15
|
+
className={cn(
|
|
16
|
+
'shrink-0 bg-border',
|
|
17
|
+
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
Separator.displayName = 'Separator';
|
|
27
|
+
|
|
28
|
+
export { Separator };
|
|
29
|
+
export type { SeparatorProps };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Slider as SliderPrimitive } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
type SliderProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;
|
|
7
|
+
|
|
8
|
+
const Slider = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof SliderPrimitive.Root>,
|
|
10
|
+
SliderProps
|
|
11
|
+
>(function Slider({ className, ...props }, ref) {
|
|
12
|
+
return (
|
|
13
|
+
<SliderPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn('relative flex w-full touch-none select-none items-center', className)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
|
|
19
|
+
<SliderPrimitive.Range className="absolute h-full bg-primary" />
|
|
20
|
+
</SliderPrimitive.Track>
|
|
21
|
+
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2" />
|
|
22
|
+
</SliderPrimitive.Root>
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
Slider.displayName = 'Slider';
|
|
26
|
+
|
|
27
|
+
export { Slider };
|
|
28
|
+
export type { SliderProps };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Switch as SwitchPrimitive } from '@tallyui/primitives';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
const Switch = React.forwardRef<
|
|
6
|
+
React.ComponentRef<typeof SwitchPrimitive.Root>,
|
|
7
|
+
React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>
|
|
8
|
+
>(function Switch({ className, ...props }, ref) {
|
|
9
|
+
return (
|
|
10
|
+
<SwitchPrimitive.Root
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn(
|
|
13
|
+
'web:peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2 web:focus-visible:ring-offset-background',
|
|
14
|
+
props.checked ? 'bg-primary' : 'bg-input',
|
|
15
|
+
props.disabled && 'web:cursor-not-allowed opacity-50',
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
>
|
|
20
|
+
<SwitchPrimitive.Thumb
|
|
21
|
+
className={cn(
|
|
22
|
+
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 web:transition-transform',
|
|
23
|
+
props.checked ? 'translate-x-5' : 'translate-x-0',
|
|
24
|
+
)}
|
|
25
|
+
/>
|
|
26
|
+
</SwitchPrimitive.Root>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
Switch.displayName = 'Switch';
|
|
30
|
+
|
|
31
|
+
export { Switch };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, Text, Pressable, type ViewProps, type TextProps } from 'react-native';
|
|
3
|
+
import { TextClassContext } from '@tallyui/primitives';
|
|
4
|
+
import { cn } from '@tallyui/theme';
|
|
5
|
+
|
|
6
|
+
const Table = React.forwardRef<View, ViewProps>(function Table({ className, ...props }, ref) {
|
|
7
|
+
return <View ref={ref} role="table" className={cn('w-full', className)} {...props} />;
|
|
8
|
+
});
|
|
9
|
+
Table.displayName = 'Table';
|
|
10
|
+
|
|
11
|
+
const TableHeader = React.forwardRef<View, ViewProps>(function TableHeader({ className, ...props }, ref) {
|
|
12
|
+
return <View ref={ref} role="rowgroup" className={cn('border-b border-border', className)} {...props} />;
|
|
13
|
+
});
|
|
14
|
+
TableHeader.displayName = 'TableHeader';
|
|
15
|
+
|
|
16
|
+
const TableBody = React.forwardRef<View, ViewProps>(function TableBody({ className, ...props }, ref) {
|
|
17
|
+
return <View ref={ref} role="rowgroup" className={cn('[&>*:last-child]:border-0', className)} {...props} />;
|
|
18
|
+
});
|
|
19
|
+
TableBody.displayName = 'TableBody';
|
|
20
|
+
|
|
21
|
+
const TableFooter = React.forwardRef<View, ViewProps>(function TableFooter({ className, ...props }, ref) {
|
|
22
|
+
return <View ref={ref} role="rowgroup" className={cn('border-t border-border bg-muted/50 font-medium', className)} {...props} />;
|
|
23
|
+
});
|
|
24
|
+
TableFooter.displayName = 'TableFooter';
|
|
25
|
+
|
|
26
|
+
const TableRow = React.forwardRef<View, ViewProps>(function TableRow({ className, ...props }, ref) {
|
|
27
|
+
return (
|
|
28
|
+
<View
|
|
29
|
+
ref={ref}
|
|
30
|
+
role="row"
|
|
31
|
+
className={cn('flex flex-row border-b border-border web:transition-colors web:hover:bg-muted/50', className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
TableRow.displayName = 'TableRow';
|
|
37
|
+
|
|
38
|
+
const TableHead = React.forwardRef<View, ViewProps>(function TableHead({ className, ...props }, ref) {
|
|
39
|
+
return (
|
|
40
|
+
<TextClassContext.Provider value="text-muted-foreground text-xs uppercase text-left font-medium">
|
|
41
|
+
<View
|
|
42
|
+
ref={ref}
|
|
43
|
+
role="columnheader"
|
|
44
|
+
className={cn('flex-1 px-4 py-3 text-left font-medium text-muted-foreground', className)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
</TextClassContext.Provider>
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
TableHead.displayName = 'TableHead';
|
|
51
|
+
|
|
52
|
+
const TableCell = React.forwardRef<View, ViewProps>(function TableCell({ className, ...props }, ref) {
|
|
53
|
+
return (
|
|
54
|
+
<View ref={ref} role="cell" className={cn('flex-1 px-4 py-4', className)} {...props} />
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
TableCell.displayName = 'TableCell';
|
|
58
|
+
|
|
59
|
+
export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Tabs as TabsPrimitive, TextClassContext } from '@tallyui/primitives';
|
|
3
|
+
import { cn } from '@tallyui/theme';
|
|
4
|
+
|
|
5
|
+
const Tabs = TabsPrimitive.Root;
|
|
6
|
+
|
|
7
|
+
function TabsList({ className, ...props }: React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>) {
|
|
8
|
+
return (
|
|
9
|
+
<TabsPrimitive.List
|
|
10
|
+
className={cn('inline-flex h-10 items-center justify-center rounded-md bg-muted p-1', className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const TabsTrigger = React.forwardRef<
|
|
17
|
+
React.ComponentRef<typeof TabsPrimitive.Trigger>,
|
|
18
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
19
|
+
>(function TabsTrigger({ className, ...props }, ref) {
|
|
20
|
+
const { value } = TabsPrimitive.useRootContext();
|
|
21
|
+
const isActive = props.value === value;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<TextClassContext.Provider
|
|
25
|
+
value={cn(
|
|
26
|
+
'text-sm font-medium',
|
|
27
|
+
isActive ? 'text-foreground' : 'text-muted-foreground'
|
|
28
|
+
)}
|
|
29
|
+
>
|
|
30
|
+
<TabsPrimitive.Trigger
|
|
31
|
+
ref={ref}
|
|
32
|
+
className={cn(
|
|
33
|
+
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium web:ring-offset-background web:transition-all web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2',
|
|
34
|
+
isActive && 'bg-background shadow-sm',
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
</TextClassContext.Provider>
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
TabsTrigger.displayName = 'TabsTrigger';
|
|
43
|
+
|
|
44
|
+
function TabsContent({ className, ...props }: React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>) {
|
|
45
|
+
return (
|
|
46
|
+
<TabsPrimitive.Content
|
|
47
|
+
className={cn('mt-2 web:ring-offset-background web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2', className)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|