@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.
Files changed (136) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +1076 -76
  3. package/dist/index.js +4662 -355
  4. package/package.json +27 -5
  5. package/src/cart/cart-line-actions.tsx +40 -0
  6. package/src/cart/cart-line.tsx +18 -32
  7. package/src/cart/cart-note-input.tsx +46 -0
  8. package/src/cart/cart-panel.tsx +39 -26
  9. package/src/cart/cart-total.tsx +43 -47
  10. package/src/cart/discount-badge.tsx +19 -0
  11. package/src/cart/index.ts +4 -1
  12. package/src/checkout/cash-tendered.tsx +101 -0
  13. package/src/checkout/change-display.tsx +19 -0
  14. package/src/checkout/index.ts +3 -0
  15. package/src/checkout/order-summary-line.tsx +7 -8
  16. package/src/checkout/order-summary.tsx +8 -7
  17. package/src/checkout/payment-method-card.tsx +10 -9
  18. package/src/checkout/payment-selector.tsx +5 -5
  19. package/src/checkout/receipt-preview.tsx +78 -0
  20. package/src/customer/customer-card.tsx +8 -9
  21. package/src/customer/customer-form.tsx +70 -0
  22. package/src/customer/customer-order-history.tsx +34 -0
  23. package/src/customer/customer-select.tsx +63 -24
  24. package/src/customer/index.ts +2 -0
  25. package/src/index.ts +112 -1
  26. package/src/input/filter-chip.tsx +85 -27
  27. package/src/input/index.ts +1 -0
  28. package/src/input/quantity-stepper.tsx +64 -0
  29. package/src/input/search-input.tsx +30 -7
  30. package/src/layout/checkout-layout.tsx +46 -0
  31. package/src/layout/index.ts +5 -0
  32. package/src/layout/live-tab-screen.tsx +54 -0
  33. package/src/layout/pos-layout.tsx +64 -0
  34. package/src/layout/settings-layout.tsx +58 -0
  35. package/src/layout/store-settings-choice-screen.tsx +142 -0
  36. package/src/order/index.ts +4 -0
  37. package/src/order/order-card.tsx +48 -0
  38. package/src/order/order-detail.tsx +82 -0
  39. package/src/order/order-list.tsx +39 -0
  40. package/src/order/order-status-badge.tsx +32 -0
  41. package/src/product/category-nav.tsx +70 -0
  42. package/src/product/index.ts +3 -0
  43. package/src/product/product-card.tsx +36 -8
  44. package/src/product/product-grid.tsx +25 -6
  45. package/src/product/product-image.tsx +28 -7
  46. package/src/product/product-list.tsx +44 -0
  47. package/src/product/product-price.tsx +77 -22
  48. package/src/product/product-sku.tsx +5 -5
  49. package/src/product/product-stock-badge.tsx +41 -28
  50. package/src/product/product-title.tsx +2 -3
  51. package/src/product/product-variant-picker.tsx +61 -0
  52. package/src/register/cash-count-input.tsx +85 -0
  53. package/src/register/closure-sheet.tsx +155 -0
  54. package/src/register/index.ts +12 -0
  55. package/src/register/movement-sheet.tsx +118 -0
  56. package/src/register/open-register-card.tsx +109 -0
  57. package/src/register/register-bar.helpers.ts +57 -0
  58. package/src/register/register-bar.tsx +85 -0
  59. package/src/register/register-column.tsx +117 -0
  60. package/src/register/register-count.tsx +330 -0
  61. package/src/register/register-open-close.tsx +52 -0
  62. package/src/register/register-panel.tsx +151 -0
  63. package/src/register/register-picker.tsx +60 -0
  64. package/src/register/register-summary.tsx +72 -0
  65. package/src/sale/cart-bar.tsx +18 -0
  66. package/src/sale/cart.tsx +66 -0
  67. package/src/sale/catalogue.tsx +131 -0
  68. package/src/sale/discount-form.tsx +85 -0
  69. package/src/sale/index.ts +9 -0
  70. package/src/sale/orders-list.tsx +66 -0
  71. package/src/sale/print-style.ts +11 -0
  72. package/src/sale/receipt.tsx +61 -0
  73. package/src/sale/sync-status.tsx +20 -0
  74. package/src/sale/tender.tsx +35 -0
  75. package/src/settings/connector-status.tsx +65 -0
  76. package/src/settings/index.ts +3 -0
  77. package/src/settings/settings-group.tsx +23 -0
  78. package/src/settings/settings-row.tsx +23 -0
  79. package/src/ui/accordion/index.tsx +59 -0
  80. package/src/ui/alert-dialog/index.tsx +91 -0
  81. package/src/ui/avatar/index.tsx +50 -0
  82. package/src/ui/badge/index.tsx +60 -0
  83. package/src/ui/button/index.tsx +90 -0
  84. package/src/ui/card/index.tsx +60 -0
  85. package/src/ui/checkbox/index.tsx +29 -0
  86. package/src/ui/collapsible/index.tsx +24 -0
  87. package/src/ui/combobox/index.tsx +98 -0
  88. package/src/ui/context-menu/index.tsx +159 -0
  89. package/src/ui/dialog/index.tsx +92 -0
  90. package/src/ui/dropdown-menu/index.tsx +161 -0
  91. package/src/ui/hover-card/index.tsx +31 -0
  92. package/src/ui/hstack/index.tsx +43 -0
  93. package/src/ui/icon/index.tsx +44 -0
  94. package/src/ui/icon/search-icon.tsx +9 -0
  95. package/src/ui/icon/svg-icon.tsx +36 -0
  96. package/src/ui/icon-button/index.tsx +58 -0
  97. package/src/ui/index.ts +99 -0
  98. package/src/ui/input/index.tsx +100 -0
  99. package/src/ui/label/index.tsx +26 -0
  100. package/src/ui/loader/index.tsx +37 -0
  101. package/src/ui/popover/index.tsx +31 -0
  102. package/src/ui/progress/index.tsx +28 -0
  103. package/src/ui/radio-group/index.tsx +38 -0
  104. package/src/ui/select/index.tsx +96 -0
  105. package/src/ui/separator/index.tsx +29 -0
  106. package/src/ui/slider/index.tsx +28 -0
  107. package/src/ui/switch/index.tsx +31 -0
  108. package/src/ui/table/index.tsx +59 -0
  109. package/src/ui/tabs/index.tsx +53 -0
  110. package/src/ui/text/index.tsx +36 -0
  111. package/src/ui/textarea/index.tsx +29 -0
  112. package/src/ui/toast/index.tsx +52 -0
  113. package/src/ui/toggle/index.tsx +69 -0
  114. package/src/ui/toggle-group/index.tsx +66 -0
  115. package/src/ui/tooltip/index.tsx +30 -0
  116. package/src/ui/vstack/index.tsx +43 -0
  117. package/src/uniwind-env.d.ts +9 -1
  118. package/src/__tests__/cart-line.test.tsx +0 -53
  119. package/src/__tests__/cart-panel.test.tsx +0 -55
  120. package/src/__tests__/cart-total.test.tsx +0 -60
  121. package/src/__tests__/customer-card.test.tsx +0 -47
  122. package/src/__tests__/customer-select.test.tsx +0 -33
  123. package/src/__tests__/filter-chip.test.tsx +0 -40
  124. package/src/__tests__/helpers.ts +0 -111
  125. package/src/__tests__/order-summary-line.test.tsx +0 -18
  126. package/src/__tests__/order-summary.test.tsx +0 -32
  127. package/src/__tests__/payment-method-card.test.tsx +0 -24
  128. package/src/__tests__/payment-selector.test.tsx +0 -23
  129. package/src/__tests__/product-card.test.tsx +0 -31
  130. package/src/__tests__/product-grid.test.tsx +0 -37
  131. package/src/__tests__/product-image.test.tsx +0 -54
  132. package/src/__tests__/product-price.test.tsx +0 -68
  133. package/src/__tests__/product-sku.test.tsx +0 -47
  134. package/src/__tests__/product-stock-badge.test.tsx +0 -58
  135. package/src/__tests__/product-title.test.tsx +0 -38
  136. package/src/__tests__/search-input.test.tsx +0 -22
@@ -1,9 +1,10 @@
1
- import { Pressable, Text, View, type ViewProps } from 'react-native';
1
+ import { Pressable, View, type PressableProps } from 'react-native';
2
2
  import type { ReactNode } from 'react';
3
3
 
4
4
  import { cn } from '@tallyui/theme';
5
+ import { Text, HStack } from '../ui';
5
6
 
6
- export interface PaymentMethodCardProps extends Omit<ViewProps, 'children'> {
7
+ export interface PaymentMethodCardProps extends Omit<PressableProps, 'children'> {
7
8
  label: string;
8
9
  selected: boolean;
9
10
  onPress: () => void;
@@ -11,18 +12,18 @@ export interface PaymentMethodCardProps extends Omit<ViewProps, 'children'> {
11
12
  className?: string;
12
13
  }
13
14
 
14
- export function PaymentMethodCard({ label, selected, onPress, icon, className, ...viewProps }: PaymentMethodCardProps) {
15
+ export function PaymentMethodCard({ label, selected, onPress, icon, className, ...props }: PaymentMethodCardProps) {
15
16
  return (
16
- <Pressable onPress={onPress} {...viewProps}>
17
- <View
17
+ <Pressable onPress={onPress} {...props}>
18
+ <HStack
18
19
  className={cn(
19
- 'flex-row items-center gap-3 rounded-lg border px-4 py-3',
20
- selected ? 'border-primary bg-primary/5' : 'border-border bg-surface',
20
+ 'rounded-lg border px-4 py-3',
21
+ selected ? 'border-primary bg-primary/5' : 'border-border bg-card',
21
22
  className,
22
23
  )}
23
24
  >
24
25
  {icon && <View>{icon}</View>}
25
- <Text className={cn('flex-1 text-sm font-medium', selected ? 'text-primary' : 'text-foreground')}>
26
+ <Text className={cn('flex-1 text-sm font-medium', selected ? 'text-primary' : '')}>
26
27
  {label}
27
28
  </Text>
28
29
  {selected && (
@@ -30,7 +31,7 @@ export function PaymentMethodCard({ label, selected, onPress, icon, className, .
30
31
  <Text className="text-xs text-primary-foreground">{'\u2713'}</Text>
31
32
  </View>
32
33
  )}
33
- </View>
34
+ </HStack>
34
35
  </Pressable>
35
36
  );
36
37
  }
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
- import { View, type ViewProps } from 'react-native';
3
2
  import { cn } from '@tallyui/theme';
3
+ import { VStack, type VStackProps } from '../ui';
4
4
  import { PaymentMethodCard } from './payment-method-card';
5
5
 
6
6
  export interface PaymentMethod {
@@ -9,7 +9,7 @@ export interface PaymentMethod {
9
9
  icon?: ReactNode;
10
10
  }
11
11
 
12
- export interface PaymentSelectorProps extends Omit<ViewProps, 'children'> {
12
+ export interface PaymentSelectorProps extends Omit<VStackProps, 'children'> {
13
13
  /** Available payment methods */
14
14
  methods: PaymentMethod[];
15
15
  /** ID of the currently selected method */
@@ -37,10 +37,10 @@ export function PaymentSelector({
37
37
  selected,
38
38
  onSelect,
39
39
  className,
40
- ...viewProps
40
+ ...props
41
41
  }: PaymentSelectorProps) {
42
42
  return (
43
- <View className={cn('gap-2', className)} {...viewProps}>
43
+ <VStack space="sm" className={cn(className)} {...props}>
44
44
  {methods.map((method) => (
45
45
  <PaymentMethodCard
46
46
  key={method.id}
@@ -50,6 +50,6 @@ export function PaymentSelector({
50
50
  icon={method.icon}
51
51
  />
52
52
  ))}
53
- </View>
53
+ </VStack>
54
54
  );
55
55
  }
@@ -0,0 +1,78 @@
1
+ import type { ReactNode } from 'react';
2
+ import { Text, View, type ViewProps } from 'react-native';
3
+
4
+ import { cn } from '@tallyui/theme';
5
+
6
+ export interface ReceiptItem {
7
+ name: string;
8
+ quantity: number;
9
+ total: string;
10
+ }
11
+
12
+ export interface ReceiptPreviewProps extends Omit<ViewProps, 'children'> {
13
+ items: ReceiptItem[];
14
+ subtotal: string;
15
+ tax: string;
16
+ total: string;
17
+ payments?: Array<{ method: string; amount: string }>;
18
+ headerSlot?: ReactNode;
19
+ footerSlot?: ReactNode;
20
+ className?: string;
21
+ }
22
+
23
+ export function ReceiptPreview({
24
+ items,
25
+ subtotal,
26
+ tax,
27
+ total,
28
+ payments,
29
+ headerSlot,
30
+ footerSlot,
31
+ className,
32
+ ...viewProps
33
+ }: ReceiptPreviewProps) {
34
+ return (
35
+ <View className={cn('rounded-lg border border-border bg-card p-4', className)} {...viewProps}>
36
+ {headerSlot && <View className="mb-3 items-center border-b border-dashed border-border pb-3">{headerSlot}</View>}
37
+
38
+ <View className="gap-1">
39
+ {items.map((item, i) => (
40
+ <View key={i} className="flex-row justify-between">
41
+ <Text className="flex-1 text-sm text-foreground">
42
+ {item.name} x{item.quantity}
43
+ </Text>
44
+ <Text className="text-sm text-foreground">{item.total}</Text>
45
+ </View>
46
+ ))}
47
+ </View>
48
+
49
+ <View className="mt-3 gap-1 border-t border-dashed border-border pt-3">
50
+ <View className="flex-row justify-between">
51
+ <Text className="text-sm text-muted-foreground">Subtotal</Text>
52
+ <Text className="text-sm text-foreground">{subtotal}</Text>
53
+ </View>
54
+ <View className="flex-row justify-between">
55
+ <Text className="text-sm text-muted-foreground">Tax</Text>
56
+ <Text className="text-sm text-foreground">{tax}</Text>
57
+ </View>
58
+ <View className="flex-row justify-between border-t border-border pt-1">
59
+ <Text className="text-sm font-bold text-foreground">Total</Text>
60
+ <Text className="text-sm font-bold text-foreground">{total}</Text>
61
+ </View>
62
+ </View>
63
+
64
+ {payments && payments.length > 0 && (
65
+ <View className="mt-3 gap-1 border-t border-dashed border-border pt-3">
66
+ {payments.map((p, i) => (
67
+ <View key={i} className="flex-row justify-between">
68
+ <Text className="text-sm text-muted-foreground">{p.method}</Text>
69
+ <Text className="text-sm text-foreground">{p.amount}</Text>
70
+ </View>
71
+ ))}
72
+ </View>
73
+ )}
74
+
75
+ {footerSlot && <View className="mt-3 items-center border-t border-dashed border-border pt-3">{footerSlot}</View>}
76
+ </View>
77
+ );
78
+ }
@@ -1,14 +1,13 @@
1
- import { Text, View, type ViewProps } from 'react-native';
2
-
3
1
  import { useCustomerTraits } from '@tallyui/core';
4
2
  import { cn } from '@tallyui/theme';
3
+ import { Text, VStack, type VStackProps } from '../ui';
5
4
 
6
- export interface CustomerCardProps extends Omit<ViewProps, 'children'> {
5
+ export interface CustomerCardProps extends Omit<VStackProps, 'children'> {
7
6
  doc: any;
8
7
  className?: string;
9
8
  }
10
9
 
11
- export function CustomerCard({ doc, className, ...viewProps }: CustomerCardProps) {
10
+ export function CustomerCard({ doc, className, ...props }: CustomerCardProps) {
12
11
  const traits = useCustomerTraits();
13
12
  if (!traits) return null;
14
13
 
@@ -17,10 +16,10 @@ export function CustomerCard({ doc, className, ...viewProps }: CustomerCardProps
17
16
  const address = traits.getAddressSummary(doc);
18
17
 
19
18
  return (
20
- <View className={cn('gap-0.5', className)} {...viewProps}>
21
- <Text className="text-sm font-semibold text-foreground">{name}</Text>
22
- {email && <Text className="text-xs text-muted">{email}</Text>}
23
- {address && <Text className="text-xs text-muted">{address}</Text>}
24
- </View>
19
+ <VStack space="none" className={cn('gap-0.5', className)} {...props}>
20
+ <Text className="text-sm font-semibold">{name}</Text>
21
+ {email && <Text className="text-xs text-muted-foreground">{email}</Text>}
22
+ {address && <Text className="text-xs text-muted-foreground">{address}</Text>}
23
+ </VStack>
25
24
  );
26
25
  }
@@ -0,0 +1,70 @@
1
+ import { Pressable, Text, TextInput, View, type ViewProps } from 'react-native';
2
+
3
+ import { cn } from '@tallyui/theme';
4
+
5
+ export interface CustomerFormValues {
6
+ firstName: string;
7
+ lastName: string;
8
+ email: string;
9
+ phone: string;
10
+ address: string;
11
+ }
12
+
13
+ export interface CustomerFormProps extends Omit<ViewProps, 'children'> {
14
+ values: CustomerFormValues;
15
+ onChangeField: (field: keyof CustomerFormValues, value: string) => void;
16
+ onSubmit?: () => void;
17
+ submitLabel?: string;
18
+ className?: string;
19
+ }
20
+
21
+ function FormField({
22
+ label,
23
+ value,
24
+ onChangeText,
25
+ ...props
26
+ }: { label: string; value: string; onChangeText: (t: string) => void } & Record<string, any>) {
27
+ return (
28
+ <View className="gap-1">
29
+ <Text className="text-xs font-medium text-muted-foreground">{label}</Text>
30
+ <TextInput
31
+ value={value}
32
+ onChangeText={onChangeText}
33
+ placeholderTextColorClassName="accent-muted-foreground"
34
+ className="rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground"
35
+ {...props}
36
+ />
37
+ </View>
38
+ );
39
+ }
40
+
41
+ export function CustomerForm({
42
+ values,
43
+ onChangeField,
44
+ onSubmit,
45
+ submitLabel = 'Save Customer',
46
+ className,
47
+ ...viewProps
48
+ }: CustomerFormProps) {
49
+ return (
50
+ <View className={cn('gap-3 p-4', className)} {...viewProps}>
51
+ <View className="flex-row gap-3">
52
+ <View className="flex-1">
53
+ <FormField label="First Name" value={values.firstName} onChangeText={(v) => onChangeField('firstName', v)} placeholder="First name" />
54
+ </View>
55
+ <View className="flex-1">
56
+ <FormField label="Last Name" value={values.lastName} onChangeText={(v) => onChangeField('lastName', v)} placeholder="Last name" />
57
+ </View>
58
+ </View>
59
+ <FormField label="Email" value={values.email} onChangeText={(v) => onChangeField('email', v)} placeholder="email@example.com" keyboardType="email-address" />
60
+ <FormField label="Phone" value={values.phone} onChangeText={(v) => onChangeField('phone', v)} placeholder="Phone number" keyboardType="phone-pad" />
61
+ <FormField label="Address" value={values.address} onChangeText={(v) => onChangeField('address', v)} placeholder="Street address" multiline />
62
+
63
+ {onSubmit && (
64
+ <Pressable onPress={onSubmit} className="items-center rounded-lg bg-primary px-4 py-3">
65
+ <Text className="text-sm font-semibold text-primary-foreground">{submitLabel}</Text>
66
+ </Pressable>
67
+ )}
68
+ </View>
69
+ );
70
+ }
@@ -0,0 +1,34 @@
1
+ import type { ReactNode } from 'react';
2
+ import { ScrollView, Text, View, type ViewProps } from 'react-native';
3
+
4
+ import { cn } from '@tallyui/theme';
5
+
6
+ export interface CustomerOrderHistoryProps extends Omit<ViewProps, 'children'> {
7
+ orders: any[];
8
+ renderItem: (order: any, index: number) => ReactNode;
9
+ emptyState?: ReactNode;
10
+ className?: string;
11
+ }
12
+
13
+ export function CustomerOrderHistory({
14
+ orders,
15
+ renderItem,
16
+ emptyState,
17
+ className,
18
+ ...viewProps
19
+ }: CustomerOrderHistoryProps) {
20
+ return (
21
+ <View className={cn('flex-1', className)} {...viewProps}>
22
+ <Text className="px-3 py-2 text-xs font-semibold text-muted-foreground">Order History</Text>
23
+ {orders.length > 0 ? (
24
+ <ScrollView contentContainerClassName="gap-2 px-3 pb-3">
25
+ {orders.map((order, index) => (
26
+ <View key={order.id ?? index}>{renderItem(order, index)}</View>
27
+ ))}
28
+ </ScrollView>
29
+ ) : (
30
+ emptyState ?? null
31
+ )}
32
+ </View>
33
+ );
34
+ }
@@ -1,9 +1,11 @@
1
- import { Pressable, ScrollView, Text, View, type ViewProps } from 'react-native';
1
+ import { ScrollView, View } from 'react-native';
2
+ import { Select } from '@tallyui/primitives';
2
3
  import { useCustomerTraits } from '@tallyui/core';
3
4
  import { cn } from '@tallyui/theme';
5
+ import { VStack, type VStackProps } from '../ui';
4
6
  import { CustomerCard } from './customer-card';
5
7
 
6
- export interface CustomerSelectProps extends Omit<ViewProps, 'children'> {
8
+ export interface CustomerSelectProps extends Omit<VStackProps, 'children'> {
7
9
  /** Customer documents to display as options */
8
10
  customers: any[];
9
11
  /** Currently selected customer (if any) */
@@ -25,6 +27,9 @@ export interface CustomerSelectProps extends Omit<ViewProps, 'children'> {
25
27
  * calls onSearch with the query text and renders whatever customers
26
28
  * are passed in.
27
29
  *
30
+ * Built on top of the Select primitive for proper accessibility
31
+ * semantics (combobox role, option roles, aria-expanded, aria-checked).
32
+ *
28
33
  * ```tsx
29
34
  * <CustomerSelect
30
35
  * customers={filteredCustomers}
@@ -41,32 +46,66 @@ export function CustomerSelect({
41
46
  onSearch,
42
47
  placeholder = 'Search customers...',
43
48
  className,
44
- ...viewProps
49
+ ...props
45
50
  }: CustomerSelectProps) {
46
51
  const traits = useCustomerTraits();
47
52
 
53
+ // Map selected customer to Select primitive's Option format
54
+ const selectedOption = selected && traits
55
+ ? { value: traits.getId(selected), label: traits.getName(selected) }
56
+ : undefined;
57
+
58
+ // Build a lookup so we can resolve the original customer doc on selection
59
+ const customerById = new Map<string, any>();
60
+ if (traits) {
61
+ for (const customer of customers) {
62
+ customerById.set(traits.getId(customer), customer);
63
+ }
64
+ }
65
+
66
+ function handleValueChange(option: { value: string; label: string }) {
67
+ const doc = customerById.get(option.value);
68
+ if (doc) onSelect(doc);
69
+ }
70
+
48
71
  return (
49
- <View className={cn('gap-2', className)} {...viewProps}>
50
- {selected && traits && (
51
- <View className="rounded-lg border border-primary bg-primary/5 px-3 py-2">
52
- <CustomerCard doc={selected} />
53
- </View>
54
- )}
72
+ <Select.Root
73
+ value={selectedOption}
74
+ onValueChange={handleValueChange}
75
+ defaultOpen={true}
76
+ >
77
+ <VStack space="sm" className={cn(className)} {...props}>
78
+ {selected && traits && (
79
+ <Select.Trigger asChild>
80
+ <View className="rounded-lg border border-primary bg-primary/5 px-3 py-2">
81
+ <CustomerCard doc={selected} />
82
+ </View>
83
+ </Select.Trigger>
84
+ )}
55
85
 
56
- {customers.length > 0 && (
57
- <ScrollView className="max-h-60">
58
- {customers.map((customer, index) => {
59
- const id = traits?.getId(customer) ?? index;
60
- return (
61
- <Pressable key={id} onPress={() => onSelect(customer)}>
62
- <View className="border-b border-border px-3 py-2">
63
- <CustomerCard doc={customer} />
64
- </View>
65
- </Pressable>
66
- );
67
- })}
68
- </ScrollView>
69
- )}
70
- </View>
86
+ {customers.length > 0 && (
87
+ <Select.Content asChild forceMount disablePositioningStyle>
88
+ <ScrollView className="max-h-60">
89
+ {customers.map((customer, index) => {
90
+ const id = traits?.getId(customer) ?? String(index);
91
+ const label = traits?.getName(customer) ?? '';
92
+ return (
93
+ <Select.Item
94
+ key={id}
95
+ value={id}
96
+ label={label}
97
+ asChild
98
+ >
99
+ <View className="border-b border-border px-3 py-2">
100
+ <CustomerCard doc={customer} />
101
+ </View>
102
+ </Select.Item>
103
+ );
104
+ })}
105
+ </ScrollView>
106
+ </Select.Content>
107
+ )}
108
+ </VStack>
109
+ </Select.Root>
71
110
  );
72
111
  }
@@ -1,2 +1,4 @@
1
1
  export { CustomerCard, type CustomerCardProps } from './customer-card';
2
2
  export { CustomerSelect, type CustomerSelectProps } from './customer-select';
3
+ export { CustomerForm, type CustomerFormProps, type CustomerFormValues } from './customer-form';
4
+ export { CustomerOrderHistory, type CustomerOrderHistoryProps } from './customer-order-history';
package/src/index.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /// <reference path="./uniwind-env.d.ts" />
2
+
3
+ // Generic UI components
4
+ export * from './ui';
5
+
1
6
  // Product components
2
7
  export {
3
8
  ProductTitle,
@@ -14,6 +19,14 @@ export {
14
19
  type ProductStockBadgeProps,
15
20
  type ProductCardProps,
16
21
  type ProductGridProps,
22
+ ProductList,
23
+ type ProductListProps,
24
+ CategoryNav,
25
+ type CategoryNavProps,
26
+ type CategoryItem,
27
+ ProductVariantPicker,
28
+ type ProductVariantPickerProps,
29
+ type VariantOption,
17
30
  } from './product';
18
31
 
19
32
  // Cart components
@@ -21,10 +34,16 @@ export {
21
34
  CartLine,
22
35
  CartTotal,
23
36
  CartPanel,
37
+ DiscountBadge,
38
+ CartNoteInput,
24
39
  type CartLineProps,
25
- type CartLineItem,
26
40
  type CartTotalProps,
27
41
  type CartPanelProps,
42
+ type DiscountBadgeProps,
43
+ type CartNoteInputProps,
44
+ CartLineActions,
45
+ type CartLineActionsProps,
46
+ type CartAction,
28
47
  } from './cart';
29
48
 
30
49
  // Input components
@@ -36,6 +55,8 @@ export {
36
55
  type FilterChipProps,
37
56
  type FilterChipGroupProps,
38
57
  type ChipItem,
58
+ QuantityStepper,
59
+ type QuantityStepperProps,
39
60
  } from './input';
40
61
 
41
62
  // Customer components
@@ -44,6 +65,11 @@ export {
44
65
  CustomerSelect,
45
66
  type CustomerCardProps,
46
67
  type CustomerSelectProps,
68
+ CustomerForm,
69
+ type CustomerFormProps,
70
+ type CustomerFormValues,
71
+ CustomerOrderHistory,
72
+ type CustomerOrderHistoryProps,
47
73
  } from './customer';
48
74
 
49
75
  // Checkout components
@@ -58,4 +84,89 @@ export {
58
84
  type OrderSummaryLineProps,
59
85
  type OrderSummaryProps,
60
86
  type OrderSummaryPayment,
87
+ ChangeDisplay,
88
+ type ChangeDisplayProps,
89
+ CashTendered,
90
+ type CashTenderedProps,
91
+ ReceiptPreview,
92
+ type ReceiptPreviewProps,
93
+ type ReceiptItem,
61
94
  } from './checkout';
95
+
96
+ // Order components
97
+ export {
98
+ OrderStatusBadge,
99
+ type OrderStatusBadgeProps,
100
+ type OrderStatus,
101
+ OrderCard,
102
+ type OrderCardProps,
103
+ OrderList,
104
+ type OrderListProps,
105
+ OrderDetail,
106
+ type OrderDetailProps,
107
+ type OrderDetailLineItem,
108
+ } from './order';
109
+
110
+ // Register components
111
+ export {
112
+ CashCountInput,
113
+ type CashCountInputProps,
114
+ type Denomination,
115
+ RegisterSummary,
116
+ type RegisterSummaryProps,
117
+ type TransactionSummary,
118
+ RegisterOpenClose,
119
+ type RegisterOpenCloseProps,
120
+ RegisterPicker,
121
+ type RegisterPickerProps,
122
+ type RegisterPickerRegister,
123
+ OpenRegisterCard,
124
+ type OpenRegisterCardProps,
125
+ RegisterBar,
126
+ type RegisterBarProps,
127
+ describeRegisterBarPill,
128
+ type RegisterBarPill,
129
+ MovementSheet,
130
+ type MovementSheetProps,
131
+ RegisterPanel,
132
+ type RegisterPanelProps,
133
+ RegisterColumn,
134
+ type RegisterColumnProps,
135
+ RegisterCount,
136
+ APPROVAL_REQUIRED_TEXT,
137
+ type RegisterCountProps,
138
+ ClosureSheet,
139
+ type ClosureSheetProps,
140
+ } from './register';
141
+
142
+ // Settings components
143
+ export {
144
+ SettingsRow,
145
+ type SettingsRowProps,
146
+ SettingsGroup,
147
+ type SettingsGroupProps,
148
+ ConnectorStatus,
149
+ type ConnectorStatusProps,
150
+ type ConnectionStatus,
151
+ } from './settings';
152
+
153
+ // Sale components
154
+ export {
155
+ Cart, CartBar, Tender, DiscountForm, DiscountChips, parseDiscount, discountLabel,
156
+ Catalogue, formatStockSyncTime, Receipt, injectPrintStyle, SyncStatus, OrdersList,
157
+ } from './sale';
158
+
159
+ // Layout components
160
+ export {
161
+ POSLayout,
162
+ type POSLayoutProps,
163
+ CheckoutLayout,
164
+ type CheckoutLayoutProps,
165
+ SettingsLayout,
166
+ type SettingsLayoutProps,
167
+ LiveTabScreen,
168
+ type LiveTabScreenProps,
169
+ type LiveTabScreenState,
170
+ StoreSettingsChoiceScreen,
171
+ type StoreSettingsChoiceScreenProps,
172
+ } from './layout';