@tallyui/components 3.4.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1848,10 +1848,158 @@ function ProductGrid({
1848
1848
  ] });
1849
1849
  }
1850
1850
 
1851
- // src/product/product-list.tsx
1852
- import { ScrollView as ScrollView2, View as View20 } from "react-native";
1851
+ // src/product/view-toggle.tsx
1852
+ import { Pressable as Pressable8, Text as Text11, View as View20 } from "react-native";
1853
1853
  import { cn as cn43 } from "@tallyui/theme";
1854
- import { jsx as jsx46, jsxs as jsxs10 } from "react/jsx-runtime";
1854
+ import { jsx as jsx46 } from "react/jsx-runtime";
1855
+ function ViewToggle({ value, onChange, labels, className, ...viewProps }) {
1856
+ return /* @__PURE__ */ jsx46(
1857
+ View20,
1858
+ {
1859
+ ...viewProps,
1860
+ role: "radiogroup",
1861
+ accessibilityLabel: "View",
1862
+ testID: "view-toggle",
1863
+ className: cn43("flex-row self-start overflow-hidden rounded-md border border-border", className),
1864
+ children: ["grid", "table"].map((view) => {
1865
+ const selected = value === view;
1866
+ const label = labels?.[view] ?? (view === "grid" ? "Grid" : "Table");
1867
+ return /* @__PURE__ */ jsx46(
1868
+ Pressable8,
1869
+ {
1870
+ role: "radio",
1871
+ "aria-checked": selected,
1872
+ testID: `view-toggle-${view}`,
1873
+ accessibilityLabel: label,
1874
+ onPress: () => {
1875
+ if (!selected) onChange(view);
1876
+ },
1877
+ className: cn43("px-3 py-2", selected ? "bg-primary" : "bg-card"),
1878
+ children: /* @__PURE__ */ jsx46(Text11, { className: cn43("text-sm font-medium", selected ? "text-primary-foreground" : "text-foreground"), children: label })
1879
+ },
1880
+ view
1881
+ );
1882
+ })
1883
+ }
1884
+ );
1885
+ }
1886
+
1887
+ // src/product/product-table.tsx
1888
+ import { useMemo, useState as useState3 } from "react";
1889
+ import { FlatList as FlatList2, Pressable as Pressable9, View as View21 } from "react-native";
1890
+ import { useProductTraits as useProductTraits7, useTraitContext as useTraitContext2, useStockOverlaid } from "@tallyui/core";
1891
+ import { productSortValue, sortProducts } from "@tallyui/pos";
1892
+ import { cn as cn44 } from "@tallyui/theme";
1893
+ import { jsx as jsx47, jsxs as jsxs10 } from "react/jsx-runtime";
1894
+ var INITIAL_ROWS2 = 8;
1895
+ var BATCH_ROWS2 = 8;
1896
+ var WINDOW_SIZE2 = 5;
1897
+ function defaultProductColumns(traits, context, options) {
1898
+ const columns = [
1899
+ { id: "name", header: "Name", flex: 3, render: (doc) => /* @__PURE__ */ jsx47(ProductTitle, { doc, numberOfLines: 2 }) },
1900
+ { id: "sku", header: "SKU", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductSku, { doc }) },
1901
+ { id: "barcode", header: "Barcode", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(Text, { children: traits.getBarcode(doc) ?? "\u2014" }) },
1902
+ { id: "price", header: "Price", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductPrice, { doc, currencySymbol: options?.currencySymbol }) },
1903
+ { id: "stock", header: "Stock", flex: 1, render: (doc) => /* @__PURE__ */ jsx47(ProductStockBadge, { doc, showQuantity: true, showAsOf: false }) },
1904
+ { id: "category", header: "Category", flex: 2, render: (doc) => /* @__PURE__ */ jsx47(Text, { children: traits.getCategoryNames(doc).join(", ") || "\u2014" }) }
1905
+ ];
1906
+ return columns.map((column) => ({
1907
+ ...column,
1908
+ sortValue: (doc) => productSortValue(doc, column.id, traits, context)
1909
+ }));
1910
+ }
1911
+ function useDefaultProductColumns(options) {
1912
+ const traits = useProductTraits7();
1913
+ const context = useTraitContext2();
1914
+ const currencySymbol4 = options?.currencySymbol;
1915
+ return useMemo(() => defaultProductColumns(traits, context, { currencySymbol: currencySymbol4 }), [traits, context, currencySymbol4]);
1916
+ }
1917
+ function ProductTable({
1918
+ items,
1919
+ columns,
1920
+ sort,
1921
+ defaultSort = null,
1922
+ onSortChange,
1923
+ sortItems = true,
1924
+ onSelect,
1925
+ searchSlot,
1926
+ filterSlot,
1927
+ emptyState,
1928
+ showUnsellable = false,
1929
+ currencySymbol: currencySymbol4,
1930
+ className,
1931
+ ...viewProps
1932
+ }) {
1933
+ let traits;
1934
+ try {
1935
+ traits = useProductTraits7();
1936
+ } catch {
1937
+ traits = void 0;
1938
+ }
1939
+ const context = useTraitContext2();
1940
+ const resolvedColumns = useMemo(() => columns ?? (traits ? defaultProductColumns(traits, context, { currencySymbol: currencySymbol4 }) : []), [columns, traits, context, currencySymbol4]);
1941
+ const [internalSort, setInternalSort] = useState3(defaultSort);
1942
+ const activeSort = sort === void 0 ? internalSort : sort;
1943
+ const visibleItems = showUnsellable || !traits ? items : items.filter((item) => traits.isSellable(item));
1944
+ const overlaidItems = useStockOverlaid(visibleItems);
1945
+ const rows = sortItems ? sortProducts(
1946
+ [...overlaidItems],
1947
+ activeSort,
1948
+ (doc, field) => resolvedColumns.find((column) => column.id === field)?.sortValue?.(doc)
1949
+ ) : overlaidItems;
1950
+ const changeSort = (id) => {
1951
+ const next = activeSort?.field !== id ? { field: id, dir: "asc" } : activeSort.dir === "asc" ? { field: id, dir: "desc" } : null;
1952
+ if (sort === void 0) setInternalSort(next);
1953
+ onSortChange?.(next);
1954
+ };
1955
+ return /* @__PURE__ */ jsxs10(VStack, { space: "none", className: cn44("flex-1", className), ...viewProps, children: [
1956
+ searchSlot && /* @__PURE__ */ jsx47(View21, { className: "px-3 py-2", children: searchSlot }),
1957
+ filterSlot && /* @__PURE__ */ jsx47(View21, { className: "px-3 pb-2", children: filterSlot }),
1958
+ rows.length ? /* @__PURE__ */ jsxs10(Table, { className: "flex-1", children: [
1959
+ /* @__PURE__ */ jsx47(TableHeader, { children: /* @__PURE__ */ jsx47(TableRow, { children: resolvedColumns.map((column) => /* @__PURE__ */ jsx47(
1960
+ TableHead,
1961
+ {
1962
+ style: { flex: column.flex ?? 1 },
1963
+ ...column.sortValue ? { "aria-sort": activeSort?.field === column.id ? activeSort.dir === "asc" ? "ascending" : "descending" : "none" } : {},
1964
+ children: column.sortValue ? /* @__PURE__ */ jsx47(
1965
+ Pressable9,
1966
+ {
1967
+ accessibilityRole: "button",
1968
+ accessibilityLabel: "Sort by " + column.header,
1969
+ testID: "product-table-sort-" + column.id,
1970
+ onPress: () => changeSort(column.id),
1971
+ children: /* @__PURE__ */ jsxs10(Text, { children: [
1972
+ column.header,
1973
+ activeSort?.field === column.id ? activeSort.dir === "asc" ? " \u25B2" : " \u25BC" : ""
1974
+ ] })
1975
+ }
1976
+ ) : /* @__PURE__ */ jsx47(Text, { children: column.header })
1977
+ },
1978
+ column.id
1979
+ )) }) }),
1980
+ /* @__PURE__ */ jsx47(TableBody, { className: "flex-1", children: /* @__PURE__ */ jsx47(
1981
+ FlatList2,
1982
+ {
1983
+ data: rows,
1984
+ keyExtractor: (item, index) => String(item.id ?? index),
1985
+ initialNumToRender: INITIAL_ROWS2,
1986
+ maxToRenderPerBatch: BATCH_ROWS2,
1987
+ windowSize: WINDOW_SIZE2,
1988
+ renderItem: ({ item, index }) => {
1989
+ const key = String(item.id ?? index);
1990
+ const row = /* @__PURE__ */ jsx47(TableRow, { testID: onSelect ? void 0 : "product-row-" + key, children: resolvedColumns.map((column) => /* @__PURE__ */ jsx47(TableCell, { style: { flex: column.flex ?? 1 }, children: column.render(item) }, column.id)) });
1991
+ return onSelect ? /* @__PURE__ */ jsx47(Pressable9, { accessibilityRole: "button", testID: "product-row-" + key, onPress: () => onSelect(item), children: row }) : row;
1992
+ }
1993
+ }
1994
+ ) })
1995
+ ] }) : emptyState ?? null
1996
+ ] });
1997
+ }
1998
+
1999
+ // src/product/product-list.tsx
2000
+ import { ScrollView as ScrollView2, View as View22 } from "react-native";
2001
+ import { cn as cn45 } from "@tallyui/theme";
2002
+ import { jsx as jsx48, jsxs as jsxs11 } from "react/jsx-runtime";
1855
2003
  function ProductList({
1856
2004
  items,
1857
2005
  renderItem,
@@ -1862,17 +2010,17 @@ function ProductList({
1862
2010
  ...viewProps
1863
2011
  }) {
1864
2012
  const hasItems = items.length > 0;
1865
- return /* @__PURE__ */ jsxs10(View20, { className: cn43("flex-1", className), ...viewProps, children: [
1866
- searchSlot && /* @__PURE__ */ jsx46(View20, { className: "px-3 py-2", children: searchSlot }),
1867
- filterSlot && /* @__PURE__ */ jsx46(View20, { className: "px-3 pb-2", children: filterSlot }),
1868
- hasItems ? /* @__PURE__ */ jsx46(ScrollView2, { className: "flex-1", children: items.map((item, index) => /* @__PURE__ */ jsx46(View20, { className: "border-b border-border", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
2013
+ return /* @__PURE__ */ jsxs11(View22, { className: cn45("flex-1", className), ...viewProps, children: [
2014
+ searchSlot && /* @__PURE__ */ jsx48(View22, { className: "px-3 py-2", children: searchSlot }),
2015
+ filterSlot && /* @__PURE__ */ jsx48(View22, { className: "px-3 pb-2", children: filterSlot }),
2016
+ hasItems ? /* @__PURE__ */ jsx48(ScrollView2, { className: "flex-1", children: items.map((item, index) => /* @__PURE__ */ jsx48(View22, { className: "border-b border-border", children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
1869
2017
  ] });
1870
2018
  }
1871
2019
 
1872
2020
  // src/product/category-nav.tsx
1873
- import { Pressable as Pressable8, ScrollView as ScrollView3, Text as Text11, View as View21 } from "react-native";
1874
- import { cn as cn44 } from "@tallyui/theme";
1875
- import { jsx as jsx47 } from "react/jsx-runtime";
2021
+ import { Pressable as Pressable10, ScrollView as ScrollView3, Text as Text12, View as View23 } from "react-native";
2022
+ import { cn as cn46 } from "@tallyui/theme";
2023
+ import { jsx as jsx49 } from "react/jsx-runtime";
1876
2024
  function CategoryNav({
1877
2025
  categories,
1878
2026
  selectedId,
@@ -1884,18 +2032,21 @@ function CategoryNav({
1884
2032
  const isHorizontal = orientation === "horizontal";
1885
2033
  const content = categories.map((cat) => {
1886
2034
  const active = cat.id === selectedId;
1887
- return /* @__PURE__ */ jsx47(
1888
- Pressable8,
2035
+ return /* @__PURE__ */ jsx49(
2036
+ Pressable10,
1889
2037
  {
2038
+ testID: `category-nav-${cat.id}`,
2039
+ role: "radio",
2040
+ "aria-checked": active,
1890
2041
  onPress: () => onSelect(cat.id),
1891
- className: cn44(
1892
- "rounded-full px-3 py-1.5",
2042
+ className: cn46(
2043
+ "rounded-md px-3 py-1.5",
1893
2044
  active ? "bg-primary" : "bg-muted"
1894
2045
  ),
1895
- children: /* @__PURE__ */ jsx47(
1896
- Text11,
2046
+ children: /* @__PURE__ */ jsx49(
2047
+ Text12,
1897
2048
  {
1898
- className: cn44(
2049
+ className: cn46(
1899
2050
  "text-sm font-medium",
1900
2051
  active ? "text-primary-foreground" : "text-foreground"
1901
2052
  ),
@@ -1907,25 +2058,27 @@ function CategoryNav({
1907
2058
  );
1908
2059
  });
1909
2060
  if (isHorizontal) {
1910
- return /* @__PURE__ */ jsx47(
2061
+ return /* @__PURE__ */ jsx49(
1911
2062
  ScrollView3,
1912
2063
  {
1913
2064
  horizontal: true,
1914
2065
  showsHorizontalScrollIndicator: false,
1915
2066
  contentContainerClassName: "flex-row gap-2 px-3 py-2",
1916
2067
  className,
2068
+ role: "radiogroup",
2069
+ accessibilityLabel: "Categories",
1917
2070
  ...viewProps,
1918
2071
  children: content
1919
2072
  }
1920
2073
  );
1921
2074
  }
1922
- return /* @__PURE__ */ jsx47(View21, { className: cn44("gap-1 p-2", className), ...viewProps, children: content });
2075
+ return /* @__PURE__ */ jsx49(View23, { className: cn46("gap-1 p-2", className), role: "radiogroup", accessibilityLabel: "Categories", ...viewProps, children: content });
1923
2076
  }
1924
2077
 
1925
2078
  // src/product/product-variant-picker.tsx
1926
- import { Pressable as Pressable9, Text as Text12, View as View22 } from "react-native";
1927
- import { cn as cn45 } from "@tallyui/theme";
1928
- import { jsx as jsx48, jsxs as jsxs11 } from "react/jsx-runtime";
2079
+ import { Pressable as Pressable11, Text as Text13, View as View24 } from "react-native";
2080
+ import { cn as cn47 } from "@tallyui/theme";
2081
+ import { jsx as jsx50, jsxs as jsxs12 } from "react/jsx-runtime";
1929
2082
  function ProductVariantPicker({
1930
2083
  options,
1931
2084
  selected = {},
@@ -1936,22 +2089,22 @@ function ProductVariantPicker({
1936
2089
  const handleSelect = (optionName, value) => {
1937
2090
  onSelect?.({ ...selected, [optionName]: value });
1938
2091
  };
1939
- return /* @__PURE__ */ jsx48(View22, { className: cn45("gap-3", className), ...viewProps, children: options.map((option) => /* @__PURE__ */ jsxs11(View22, { className: "gap-1.5", children: [
1940
- /* @__PURE__ */ jsx48(Text12, { className: "text-xs font-semibold text-muted-foreground", children: option.name }),
1941
- /* @__PURE__ */ jsx48(View22, { className: "flex-row flex-wrap gap-2", children: option.values.map((value) => {
2092
+ return /* @__PURE__ */ jsx50(View24, { className: cn47("gap-3", className), ...viewProps, children: options.map((option) => /* @__PURE__ */ jsxs12(View24, { className: "gap-1.5", children: [
2093
+ /* @__PURE__ */ jsx50(Text13, { className: "text-xs font-semibold text-muted-foreground", children: option.name }),
2094
+ /* @__PURE__ */ jsx50(View24, { className: "flex-row flex-wrap gap-2", children: option.values.map((value) => {
1942
2095
  const active = selected[option.name] === value;
1943
- return /* @__PURE__ */ jsx48(
1944
- Pressable9,
2096
+ return /* @__PURE__ */ jsx50(
2097
+ Pressable11,
1945
2098
  {
1946
2099
  onPress: () => handleSelect(option.name, value),
1947
- className: cn45(
2100
+ className: cn47(
1948
2101
  "rounded-lg border px-3 py-1.5",
1949
2102
  active ? "border-primary bg-primary/10" : "border-border bg-card"
1950
2103
  ),
1951
- children: /* @__PURE__ */ jsx48(
1952
- Text12,
2104
+ children: /* @__PURE__ */ jsx50(
2105
+ Text13,
1953
2106
  {
1954
- className: cn45(
2107
+ className: cn47(
1955
2108
  "text-sm font-medium",
1956
2109
  active ? "text-primary" : "text-foreground"
1957
2110
  ),
@@ -1967,22 +2120,22 @@ function ProductVariantPicker({
1967
2120
 
1968
2121
  // src/cart/cart-line.tsx
1969
2122
  import { formatMoney as formatMoney2 } from "@tallyui/core";
1970
- import { cn as cn46 } from "@tallyui/theme";
1971
- import { jsx as jsx49, jsxs as jsxs12 } from "react/jsx-runtime";
2123
+ import { cn as cn48 } from "@tallyui/theme";
2124
+ import { jsx as jsx51, jsxs as jsxs13 } from "react/jsx-runtime";
1972
2125
  function CartLine({ name, quantity, unitPrice, lineTotal, locale, className, ...props }) {
1973
- return /* @__PURE__ */ jsxs12(HStack, { className: cn46("px-3 py-2.5", className), ...props, children: [
1974
- /* @__PURE__ */ jsxs12(VStack, { space: "none", className: "flex-1 gap-0.5", children: [
1975
- /* @__PURE__ */ jsx49(Text, { className: "text-sm font-medium", numberOfLines: 1, children: name }),
1976
- /* @__PURE__ */ jsx49(Text, { className: "text-xs text-muted-foreground", children: `${formatMoney2(unitPrice, locale) ?? "\u2014"} \xD7 ${quantity}` })
2126
+ return /* @__PURE__ */ jsxs13(HStack, { className: cn48("px-3 py-2.5", className), ...props, children: [
2127
+ /* @__PURE__ */ jsxs13(VStack, { space: "none", className: "flex-1 gap-0.5", children: [
2128
+ /* @__PURE__ */ jsx51(Text, { className: "text-sm font-medium", numberOfLines: 1, children: name }),
2129
+ /* @__PURE__ */ jsx51(Text, { className: "text-xs text-muted-foreground", children: `${formatMoney2(unitPrice, locale) ?? "\u2014"} \xD7 ${quantity}` })
1977
2130
  ] }),
1978
- /* @__PURE__ */ jsx49(Text, { className: "text-sm font-semibold", children: formatMoney2(lineTotal, locale) ?? "\u2014" })
2131
+ /* @__PURE__ */ jsx51(Text, { className: "text-sm font-semibold", children: formatMoney2(lineTotal, locale) ?? "\u2014" })
1979
2132
  ] });
1980
2133
  }
1981
2134
 
1982
2135
  // src/cart/cart-total.tsx
1983
2136
  import { formatMoney as formatMoney3 } from "@tallyui/core";
1984
- import { cn as cn47 } from "@tallyui/theme";
1985
- import { jsx as jsx50, jsxs as jsxs13 } from "react/jsx-runtime";
2137
+ import { cn as cn49 } from "@tallyui/theme";
2138
+ import { jsx as jsx52, jsxs as jsxs14 } from "react/jsx-runtime";
1986
2139
  function CartTotal({
1987
2140
  subtotal,
1988
2141
  taxLines,
@@ -1993,33 +2146,33 @@ function CartTotal({
1993
2146
  className,
1994
2147
  ...props
1995
2148
  }) {
1996
- return /* @__PURE__ */ jsxs13(VStack, { space: "none", className: cn47("gap-1.5 px-3 py-3", className), ...props, children: [
1997
- /* @__PURE__ */ jsxs13(HStack, { space: "none", className: "justify-between", children: [
1998
- /* @__PURE__ */ jsx50(Text, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
1999
- /* @__PURE__ */ jsx50(Text, { className: "text-sm", children: formatMoney3(subtotal, locale) ?? "\u2014" })
2149
+ return /* @__PURE__ */ jsxs14(VStack, { space: "none", className: cn49("gap-1.5 px-3 py-3", className), ...props, children: [
2150
+ /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
2151
+ /* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2152
+ /* @__PURE__ */ jsx52(Text, { className: "text-sm", children: formatMoney3(subtotal, locale) ?? "\u2014" })
2000
2153
  ] }),
2001
- discount && discount.amount > 0 && /* @__PURE__ */ jsxs13(HStack, { space: "none", className: "justify-between", children: [
2002
- /* @__PURE__ */ jsx50(Text, { className: "text-sm text-muted-foreground", children: "Discount" }),
2003
- /* @__PURE__ */ jsxs13(Text, { className: "text-sm", children: [
2154
+ discount && discount.amount > 0 && /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
2155
+ /* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: "Discount" }),
2156
+ /* @__PURE__ */ jsxs14(Text, { className: "text-sm", children: [
2004
2157
  "\u2212",
2005
2158
  formatMoney3(discount, locale) ?? "\u2014"
2006
2159
  ] })
2007
2160
  ] }),
2008
- taxLines?.map((line, index) => /* @__PURE__ */ jsxs13(HStack, { space: "none", className: "justify-between", children: [
2009
- /* @__PURE__ */ jsx50(Text, { className: "text-sm text-muted-foreground", children: taxInclusive ? `incl. ${line.label}` : line.label }),
2010
- /* @__PURE__ */ jsx50(Text, { className: "text-sm", children: formatMoney3(line.amount, locale) ?? "\u2014" })
2161
+ taxLines?.map((line, index) => /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "justify-between", children: [
2162
+ /* @__PURE__ */ jsx52(Text, { className: "text-sm text-muted-foreground", children: taxInclusive ? `incl. ${line.label}` : line.label }),
2163
+ /* @__PURE__ */ jsx52(Text, { className: "text-sm", children: formatMoney3(line.amount, locale) ?? "\u2014" })
2011
2164
  ] }, index)),
2012
- /* @__PURE__ */ jsxs13(HStack, { space: "none", className: "mt-1.5 justify-between border-t border-border pt-2", children: [
2013
- /* @__PURE__ */ jsx50(Text, { className: "font-bold", children: "Total" }),
2014
- /* @__PURE__ */ jsx50(Text, { className: "font-bold", children: formatMoney3(total, locale) ?? "\u2014" })
2165
+ /* @__PURE__ */ jsxs14(HStack, { space: "none", className: "mt-1.5 justify-between border-t border-border pt-2", children: [
2166
+ /* @__PURE__ */ jsx52(Text, { className: "font-bold", children: "Total" }),
2167
+ /* @__PURE__ */ jsx52(Text, { className: "font-bold", children: formatMoney3(total, locale) ?? "\u2014" })
2015
2168
  ] })
2016
2169
  ] });
2017
2170
  }
2018
2171
 
2019
2172
  // src/cart/cart-panel.tsx
2020
- import { ScrollView as ScrollView4, View as View23 } from "react-native";
2021
- import { cn as cn48 } from "@tallyui/theme";
2022
- import { jsx as jsx51, jsxs as jsxs14 } from "react/jsx-runtime";
2173
+ import { ScrollView as ScrollView4, View as View25 } from "react-native";
2174
+ import { cn as cn50 } from "@tallyui/theme";
2175
+ import { jsx as jsx53, jsxs as jsxs15 } from "react/jsx-runtime";
2023
2176
  function defaultKey(item, index) {
2024
2177
  const id = item?.id;
2025
2178
  return typeof id === "string" || typeof id === "number" ? String(id) : String(index);
@@ -2036,36 +2189,36 @@ function CartPanel({
2036
2189
  ...props
2037
2190
  }) {
2038
2191
  const hasItems = items.length > 0;
2039
- return /* @__PURE__ */ jsxs14(VStack, { space: "none", className: cn48("flex-1 min-h-0", className), ...props, children: [
2040
- header && /* @__PURE__ */ jsx51(View23, { className: "border-b border-border px-3 py-2", children: header }),
2041
- /* @__PURE__ */ jsxs14(ScrollView4, { className: "flex-1 min-h-0", contentContainerClassName: "flex-grow", children: [
2042
- hasItems ? items.map((item, index) => /* @__PURE__ */ jsx51(View23, { children: renderItem(item, index) }, keyExtractor ? keyExtractor(item, index) : defaultKey(item, index))) : emptyState ?? null,
2192
+ return /* @__PURE__ */ jsxs15(VStack, { space: "none", className: cn50("flex-1 min-h-0", className), ...props, children: [
2193
+ header && /* @__PURE__ */ jsx53(View25, { className: "border-b border-border px-3 py-2", children: header }),
2194
+ /* @__PURE__ */ jsxs15(ScrollView4, { className: "flex-1 min-h-0", contentContainerClassName: "flex-grow", children: [
2195
+ hasItems ? items.map((item, index) => /* @__PURE__ */ jsx53(View25, { children: renderItem(item, index) }, keyExtractor ? keyExtractor(item, index) : defaultKey(item, index))) : emptyState ?? null,
2043
2196
  afterItems
2044
2197
  ] }),
2045
- footer && /* @__PURE__ */ jsx51(View23, { className: "border-t border-border px-3 py-2", children: footer })
2198
+ footer && /* @__PURE__ */ jsx53(View25, { className: "border-t border-border px-3 py-2", children: footer })
2046
2199
  ] });
2047
2200
  }
2048
2201
 
2049
2202
  // src/cart/discount-badge.tsx
2050
- import { Text as Text13, View as View24 } from "react-native";
2051
- import { cn as cn49 } from "@tallyui/theme";
2052
- import { jsx as jsx52 } from "react/jsx-runtime";
2203
+ import { Text as Text14, View as View26 } from "react-native";
2204
+ import { cn as cn51 } from "@tallyui/theme";
2205
+ import { jsx as jsx54 } from "react/jsx-runtime";
2053
2206
  function DiscountBadge({ label, className, ...viewProps }) {
2054
- return /* @__PURE__ */ jsx52(
2055
- View24,
2207
+ return /* @__PURE__ */ jsx54(
2208
+ View26,
2056
2209
  {
2057
- className: cn49("flex-row items-center self-start gap-1 rounded-md bg-sale/15 px-1.5 py-0.5", className),
2210
+ className: cn51("flex-row items-center self-start gap-1 rounded-md bg-sale/15 px-1.5 py-0.5", className),
2058
2211
  ...viewProps,
2059
- children: /* @__PURE__ */ jsx52(Text13, { className: "text-xs font-semibold text-sale", children: label })
2212
+ children: /* @__PURE__ */ jsx54(Text14, { className: "text-xs font-semibold text-sale", children: label })
2060
2213
  }
2061
2214
  );
2062
2215
  }
2063
2216
 
2064
2217
  // src/cart/cart-note-input.tsx
2065
- import { useState as useState3 } from "react";
2066
- import { Pressable as Pressable10, Text as Text14, TextInput as TextInput4, View as View25 } from "react-native";
2067
- import { cn as cn50 } from "@tallyui/theme";
2068
- import { jsx as jsx53 } from "react/jsx-runtime";
2218
+ import { useState as useState4 } from "react";
2219
+ import { Pressable as Pressable12, Text as Text15, TextInput as TextInput4, View as View27 } from "react-native";
2220
+ import { cn as cn52 } from "@tallyui/theme";
2221
+ import { jsx as jsx55 } from "react/jsx-runtime";
2069
2222
  function CartNoteInput({
2070
2223
  value,
2071
2224
  onChangeText,
@@ -2073,19 +2226,19 @@ function CartNoteInput({
2073
2226
  className,
2074
2227
  ...viewProps
2075
2228
  }) {
2076
- const [expanded, setExpanded] = useState3(value.length > 0);
2229
+ const [expanded, setExpanded] = useState4(value.length > 0);
2077
2230
  if (!expanded) {
2078
- return /* @__PURE__ */ jsx53(
2079
- Pressable10,
2231
+ return /* @__PURE__ */ jsx55(
2232
+ Pressable12,
2080
2233
  {
2081
2234
  onPress: () => setExpanded(true),
2082
- className: cn50("flex-row items-center gap-1.5 px-3 py-2", className),
2235
+ className: cn52("flex-row items-center gap-1.5 px-3 py-2", className),
2083
2236
  ...viewProps,
2084
- children: /* @__PURE__ */ jsx53(Text14, { className: "text-xs text-primary", children: "Add note" })
2237
+ children: /* @__PURE__ */ jsx55(Text15, { className: "text-xs text-primary", children: "Add note" })
2085
2238
  }
2086
2239
  );
2087
2240
  }
2088
- return /* @__PURE__ */ jsx53(View25, { className: cn50("px-3 py-2", className), ...viewProps, children: /* @__PURE__ */ jsx53(
2241
+ return /* @__PURE__ */ jsx55(View27, { className: cn52("px-3 py-2", className), ...viewProps, children: /* @__PURE__ */ jsx55(
2089
2242
  TextInput4,
2090
2243
  {
2091
2244
  value,
@@ -2099,20 +2252,20 @@ function CartNoteInput({
2099
2252
  }
2100
2253
 
2101
2254
  // src/cart/cart-line-actions.tsx
2102
- import { Pressable as Pressable11, Text as Text15, View as View26 } from "react-native";
2103
- import { cn as cn51 } from "@tallyui/theme";
2104
- import { jsx as jsx54, jsxs as jsxs15 } from "react/jsx-runtime";
2255
+ import { Pressable as Pressable13, Text as Text16, View as View28 } from "react-native";
2256
+ import { cn as cn53 } from "@tallyui/theme";
2257
+ import { jsx as jsx56, jsxs as jsxs16 } from "react/jsx-runtime";
2105
2258
  function CartLineActions({ children, actions, className, ...viewProps }) {
2106
- return /* @__PURE__ */ jsxs15(View26, { className: cn51("flex-row items-center", className), ...viewProps, children: [
2107
- /* @__PURE__ */ jsx54(View26, { className: "flex-1", children }),
2108
- /* @__PURE__ */ jsx54(View26, { className: "flex-row gap-1 px-2", children: actions.map((action) => /* @__PURE__ */ jsxs15(
2109
- Pressable11,
2259
+ return /* @__PURE__ */ jsxs16(View28, { className: cn53("flex-row items-center", className), ...viewProps, children: [
2260
+ /* @__PURE__ */ jsx56(View28, { className: "flex-1", children }),
2261
+ /* @__PURE__ */ jsx56(View28, { className: "flex-row gap-1 px-2", children: actions.map((action) => /* @__PURE__ */ jsxs16(
2262
+ Pressable13,
2110
2263
  {
2111
2264
  onPress: action.onPress,
2112
2265
  className: "rounded-md px-2 py-1.5",
2113
2266
  children: [
2114
2267
  action.iconSlot,
2115
- /* @__PURE__ */ jsx54(Text15, { className: cn51("text-xs font-medium", action.color ?? "text-destructive"), children: action.label })
2268
+ /* @__PURE__ */ jsx56(Text16, { className: cn53("text-xs font-medium", action.color ?? "text-destructive"), children: action.label })
2116
2269
  ]
2117
2270
  },
2118
2271
  action.id
@@ -2121,21 +2274,21 @@ function CartLineActions({ children, actions, className, ...viewProps }) {
2121
2274
  }
2122
2275
 
2123
2276
  // src/input/search-input.tsx
2124
- import { useId, useState as useState4 } from "react";
2125
- import { TextInput as TextInput5, View as View27 } from "react-native";
2277
+ import { useId, useState as useState5 } from "react";
2278
+ import { TextInput as TextInput5, View as View29 } from "react-native";
2126
2279
  import { Label as Label3 } from "@tallyui/primitives";
2127
- import { cn as cn52 } from "@tallyui/theme";
2128
- import { jsx as jsx55, jsxs as jsxs16 } from "react/jsx-runtime";
2280
+ import { cn as cn54 } from "@tallyui/theme";
2281
+ import { jsx as jsx57, jsxs as jsxs17 } from "react/jsx-runtime";
2129
2282
  function SearchInput({ value, onChangeText, className, placeholder = "Search...", style, onFocus, onBlur, ...props }) {
2130
2283
  const labelId = useId();
2131
- const [focused, setFocused] = useState4(false);
2132
- return /* @__PURE__ */ jsxs16(HStack, { space: "sm", className: cn52(
2284
+ const [focused, setFocused] = useState5(false);
2285
+ return /* @__PURE__ */ jsxs17(HStack, { space: "sm", className: cn54(
2133
2286
  "rounded-lg border bg-card px-3 py-2.5",
2134
2287
  focused ? "border-ring" : "border-border",
2135
2288
  className
2136
2289
  ), children: [
2137
- /* @__PURE__ */ jsx55(Label3.Root, { nativeID: labelId, asChild: true, children: /* @__PURE__ */ jsx55(View27, { "aria-hidden": true, className: "text-muted-foreground", children: /* @__PURE__ */ jsx55(SearchIcon, { size: 16 }) }) }),
2138
- /* @__PURE__ */ jsx55(
2290
+ /* @__PURE__ */ jsx57(Label3.Root, { nativeID: labelId, asChild: true, children: /* @__PURE__ */ jsx57(View29, { "aria-hidden": true, className: "text-muted-foreground", children: /* @__PURE__ */ jsx57(SearchIcon, { size: 16 }) }) }),
2291
+ /* @__PURE__ */ jsx57(
2139
2292
  TextInput5,
2140
2293
  {
2141
2294
  role: "searchbox",
@@ -2161,39 +2314,39 @@ function SearchInput({ value, onChangeText, className, placeholder = "Search..."
2161
2314
  }
2162
2315
 
2163
2316
  // src/input/filter-chip.tsx
2164
- import { useMemo } from "react";
2165
- import { Pressable as Pressable12, ScrollView as ScrollView5 } from "react-native";
2317
+ import { useMemo as useMemo2 } from "react";
2318
+ import { Pressable as Pressable14, ScrollView as ScrollView5 } from "react-native";
2166
2319
  import { ToggleGroup as ToggleGroup3 } from "@tallyui/primitives";
2167
- import { cn as cn53 } from "@tallyui/theme";
2168
- import { jsx as jsx56 } from "react/jsx-runtime";
2320
+ import { cn as cn55 } from "@tallyui/theme";
2321
+ import { jsx as jsx58 } from "react/jsx-runtime";
2169
2322
  function FilterChip({ label, active, onPress, className }) {
2170
- const value = useMemo(() => active ? [label] : [], [active, label]);
2171
- return /* @__PURE__ */ jsx56(
2323
+ const value = useMemo2(() => active ? [label] : [], [active, label]);
2324
+ return /* @__PURE__ */ jsx58(
2172
2325
  ToggleGroup3.Root,
2173
2326
  {
2174
2327
  type: "multiple",
2175
2328
  value,
2176
2329
  onValueChange: () => onPress(),
2177
- children: /* @__PURE__ */ jsx56(ToggleGroup3.Item, { value: label, asChild: true, children: /* @__PURE__ */ jsx56(
2178
- Pressable12,
2330
+ children: /* @__PURE__ */ jsx58(ToggleGroup3.Item, { value: label, asChild: true, children: /* @__PURE__ */ jsx58(
2331
+ Pressable14,
2179
2332
  {
2180
- className: cn53(
2333
+ className: cn55(
2181
2334
  "rounded-full px-3 py-1.5",
2182
2335
  active ? "bg-primary" : "bg-accent",
2183
2336
  className
2184
2337
  ),
2185
- children: /* @__PURE__ */ jsx56(Text, { className: cn53("text-xs font-semibold", active ? "text-primary-foreground" : "text-muted-foreground"), children: label })
2338
+ children: /* @__PURE__ */ jsx58(Text, { className: cn55("text-xs font-semibold", active ? "text-primary-foreground" : "text-muted-foreground"), children: label })
2186
2339
  }
2187
2340
  ) })
2188
2341
  }
2189
2342
  );
2190
2343
  }
2191
2344
  function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
2192
- const activeValues = useMemo(
2345
+ const activeValues = useMemo2(
2193
2346
  () => chips.filter((c) => c.active).map((c) => c.label),
2194
2347
  [chips]
2195
2348
  );
2196
- const labelToIndex = useMemo(() => {
2349
+ const labelToIndex = useMemo2(() => {
2197
2350
  const map = /* @__PURE__ */ new Map();
2198
2351
  chips.forEach((chip, i) => map.set(chip.label, i));
2199
2352
  return map;
@@ -2207,28 +2360,28 @@ function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
2207
2360
  if (index !== void 0) onChipPress(index);
2208
2361
  }
2209
2362
  }
2210
- return /* @__PURE__ */ jsx56(
2363
+ return /* @__PURE__ */ jsx58(
2211
2364
  ToggleGroup3.Root,
2212
2365
  {
2213
2366
  type: "multiple",
2214
2367
  value: activeValues,
2215
2368
  onValueChange: handleValueChange,
2216
2369
  asChild: true,
2217
- children: /* @__PURE__ */ jsx56(
2370
+ children: /* @__PURE__ */ jsx58(
2218
2371
  ScrollView5,
2219
2372
  {
2220
2373
  horizontal: true,
2221
2374
  showsHorizontalScrollIndicator: false,
2222
- contentContainerClassName: cn53("flex-row gap-2", className),
2375
+ contentContainerClassName: cn55("flex-row gap-2", className),
2223
2376
  ...viewProps,
2224
- children: chips.map((chip) => /* @__PURE__ */ jsx56(ToggleGroup3.Item, { value: chip.label, asChild: true, children: /* @__PURE__ */ jsx56(
2225
- Pressable12,
2377
+ children: chips.map((chip) => /* @__PURE__ */ jsx58(ToggleGroup3.Item, { value: chip.label, asChild: true, children: /* @__PURE__ */ jsx58(
2378
+ Pressable14,
2226
2379
  {
2227
- className: cn53(
2380
+ className: cn55(
2228
2381
  "rounded-full px-3 py-1.5",
2229
2382
  chip.active ? "bg-primary" : "bg-accent"
2230
2383
  ),
2231
- children: /* @__PURE__ */ jsx56(Text, { className: cn53("text-xs font-semibold", chip.active ? "text-primary-foreground" : "text-muted-foreground"), children: chip.label })
2384
+ children: /* @__PURE__ */ jsx58(Text, { className: cn55("text-xs font-semibold", chip.active ? "text-primary-foreground" : "text-muted-foreground"), children: chip.label })
2232
2385
  }
2233
2386
  ) }, chip.label))
2234
2387
  }
@@ -2238,10 +2391,10 @@ function FilterChipGroup({ chips, onChipPress, className, ...viewProps }) {
2238
2391
  }
2239
2392
 
2240
2393
  // src/input/quantity-stepper.tsx
2241
- import { useState as useState5 } from "react";
2242
- import { Pressable as Pressable13, Text as Text16, View as View28 } from "react-native";
2243
- import { cn as cn54 } from "@tallyui/theme";
2244
- import { jsx as jsx57, jsxs as jsxs17 } from "react/jsx-runtime";
2394
+ import { useState as useState6 } from "react";
2395
+ import { Pressable as Pressable15, Text as Text17, View as View30 } from "react-native";
2396
+ import { cn as cn56 } from "@tallyui/theme";
2397
+ import { jsx as jsx59, jsxs as jsxs18 } from "react/jsx-runtime";
2245
2398
  function QuantityStepper({
2246
2399
  defaultQuantity = 1,
2247
2400
  quantity: controlledQuantity,
@@ -2251,37 +2404,37 @@ function QuantityStepper({
2251
2404
  className,
2252
2405
  ...viewProps
2253
2406
  }) {
2254
- const [internalQuantity, setInternalQuantity] = useState5(defaultQuantity);
2407
+ const [internalQuantity, setInternalQuantity] = useState6(defaultQuantity);
2255
2408
  const quantity = controlledQuantity ?? internalQuantity;
2256
2409
  const handleChange = (next) => {
2257
2410
  if (next < min || next > max) return;
2258
2411
  if (controlledQuantity === void 0) setInternalQuantity(next);
2259
2412
  onChangeQuantity?.(next);
2260
2413
  };
2261
- return /* @__PURE__ */ jsxs17(View28, { className: cn54("flex-row items-center gap-2", className), ...viewProps, children: [
2262
- /* @__PURE__ */ jsx57(
2263
- Pressable13,
2414
+ return /* @__PURE__ */ jsxs18(View30, { className: cn56("flex-row items-center gap-2", className), ...viewProps, children: [
2415
+ /* @__PURE__ */ jsx59(
2416
+ Pressable15,
2264
2417
  {
2265
2418
  onPress: () => handleChange(quantity - 1),
2266
2419
  disabled: quantity <= min,
2267
- className: cn54(
2420
+ className: cn56(
2268
2421
  "h-8 w-8 items-center justify-center rounded-lg",
2269
2422
  quantity <= min ? "bg-muted/50" : "bg-muted"
2270
2423
  ),
2271
- children: /* @__PURE__ */ jsx57(Text16, { className: cn54("text-base font-semibold", quantity <= min ? "text-muted-foreground" : "text-foreground"), children: "\u2212" })
2424
+ children: /* @__PURE__ */ jsx59(Text17, { className: cn56("text-base font-semibold", quantity <= min ? "text-muted-foreground" : "text-foreground"), children: "\u2212" })
2272
2425
  }
2273
2426
  ),
2274
- /* @__PURE__ */ jsx57(Text16, { className: "min-w-[2rem] text-center text-base font-semibold text-foreground", children: quantity }),
2275
- /* @__PURE__ */ jsx57(
2276
- Pressable13,
2427
+ /* @__PURE__ */ jsx59(Text17, { className: "min-w-[2rem] text-center text-base font-semibold text-foreground", children: quantity }),
2428
+ /* @__PURE__ */ jsx59(
2429
+ Pressable15,
2277
2430
  {
2278
2431
  onPress: () => handleChange(quantity + 1),
2279
2432
  disabled: quantity >= max,
2280
- className: cn54(
2433
+ className: cn56(
2281
2434
  "h-8 w-8 items-center justify-center rounded-lg",
2282
2435
  quantity >= max ? "bg-muted/50" : "bg-muted"
2283
2436
  ),
2284
- children: /* @__PURE__ */ jsx57(Text16, { className: cn54("text-base font-semibold", quantity >= max ? "text-muted-foreground" : "text-foreground"), children: "+" })
2437
+ children: /* @__PURE__ */ jsx59(Text17, { className: cn56("text-base font-semibold", quantity >= max ? "text-muted-foreground" : "text-foreground"), children: "+" })
2285
2438
  }
2286
2439
  )
2287
2440
  ] });
@@ -2289,36 +2442,36 @@ function QuantityStepper({
2289
2442
 
2290
2443
  // src/customer/customer-card.tsx
2291
2444
  import { useCustomerTraits } from "@tallyui/core";
2292
- import { cn as cn55 } from "@tallyui/theme";
2293
- import { jsx as jsx58, jsxs as jsxs18 } from "react/jsx-runtime";
2445
+ import { cn as cn57 } from "@tallyui/theme";
2446
+ import { jsx as jsx60, jsxs as jsxs19 } from "react/jsx-runtime";
2294
2447
  function CustomerCardFromContext(props) {
2295
2448
  const traits = useCustomerTraits();
2296
- return traits ? /* @__PURE__ */ jsx58(CustomerCard, { ...props, traits }) : null;
2449
+ return traits ? /* @__PURE__ */ jsx60(CustomerCard, { ...props, traits }) : null;
2297
2450
  }
2298
2451
  function CustomerCard({ doc, traits, className, ...props }) {
2299
- if (!traits) return /* @__PURE__ */ jsx58(CustomerCardFromContext, { doc, className, ...props });
2452
+ if (!traits) return /* @__PURE__ */ jsx60(CustomerCardFromContext, { doc, className, ...props });
2300
2453
  const name = traits.getName(doc);
2301
2454
  const email = traits.getEmail(doc);
2302
2455
  const address = traits.getAddressSummary(doc);
2303
- return /* @__PURE__ */ jsxs18(VStack, { space: "none", className: cn55("gap-0.5", className), ...props, children: [
2304
- /* @__PURE__ */ jsx58(Text, { className: "text-sm font-semibold", children: name }),
2305
- email && /* @__PURE__ */ jsx58(Text, { className: "text-xs text-muted-foreground", children: email }),
2306
- address && /* @__PURE__ */ jsx58(Text, { className: "text-xs text-muted-foreground", children: address })
2456
+ return /* @__PURE__ */ jsxs19(VStack, { space: "none", className: cn57("gap-0.5", className), ...props, children: [
2457
+ /* @__PURE__ */ jsx60(Text, { className: "text-sm font-semibold", children: name }),
2458
+ email && /* @__PURE__ */ jsx60(Text, { className: "text-xs text-muted-foreground", children: email }),
2459
+ address && /* @__PURE__ */ jsx60(Text, { className: "text-xs text-muted-foreground", children: address })
2307
2460
  ] });
2308
2461
  }
2309
2462
 
2310
2463
  // src/customer/customer-select.tsx
2311
- import { useState as useState6 } from "react";
2312
- import { Pressable as Pressable14, ScrollView as ScrollView6, View as View29 } from "react-native";
2464
+ import { useState as useState7 } from "react";
2465
+ import { Pressable as Pressable16, ScrollView as ScrollView6, View as View31 } from "react-native";
2313
2466
  import { Select as Select2 } from "@tallyui/primitives";
2314
2467
  import { useCustomerTraits as useCustomerTraits2 } from "@tallyui/core";
2315
- import { cn as cn56 } from "@tallyui/theme";
2316
- import { jsx as jsx59, jsxs as jsxs19 } from "react/jsx-runtime";
2468
+ import { cn as cn58 } from "@tallyui/theme";
2469
+ import { jsx as jsx61, jsxs as jsxs20 } from "react/jsx-runtime";
2317
2470
  function CustomerSelect(props) {
2318
- return props.traits ? /* @__PURE__ */ jsx59(CustomerSelectView, { ...props }) : /* @__PURE__ */ jsx59(CustomerSelectFromContext, { ...props });
2471
+ return props.traits ? /* @__PURE__ */ jsx61(CustomerSelectView, { ...props }) : /* @__PURE__ */ jsx61(CustomerSelectFromContext, { ...props });
2319
2472
  }
2320
2473
  function CustomerSelectFromContext(props) {
2321
- return /* @__PURE__ */ jsx59(CustomerSelectView, { ...props, traits: useCustomerTraits2() });
2474
+ return /* @__PURE__ */ jsx61(CustomerSelectView, { ...props, traits: useCustomerTraits2() });
2322
2475
  }
2323
2476
  function CustomerSelectView({
2324
2477
  customers,
@@ -2331,7 +2484,7 @@ function CustomerSelectView({
2331
2484
  traits,
2332
2485
  ...props
2333
2486
  }) {
2334
- const [search, setSearch] = useState6("");
2487
+ const [search, setSearch] = useState7("");
2335
2488
  const selectedOption = selected && traits ? { value: traits.getId(selected), label: traits.getName(selected) } : void 0;
2336
2489
  const customerById = /* @__PURE__ */ new Map();
2337
2490
  if (traits) {
@@ -2343,14 +2496,14 @@ function CustomerSelectView({
2343
2496
  const doc = customerById.get(option.value);
2344
2497
  if (doc) onSelect(doc);
2345
2498
  }
2346
- return /* @__PURE__ */ jsx59(
2499
+ return /* @__PURE__ */ jsx61(
2347
2500
  Select2.Root,
2348
2501
  {
2349
2502
  value: selectedOption,
2350
2503
  onValueChange: handleValueChange,
2351
2504
  defaultOpen: true,
2352
- children: /* @__PURE__ */ jsxs19(VStack, { space: "sm", className: cn56(className), ...props, children: [
2353
- showSearch && /* @__PURE__ */ jsx59(
2505
+ children: /* @__PURE__ */ jsxs20(VStack, { space: "sm", className: cn58(className), ...props, children: [
2506
+ showSearch && /* @__PURE__ */ jsx61(
2354
2507
  SearchInput,
2355
2508
  {
2356
2509
  value: search,
@@ -2363,18 +2516,18 @@ function CustomerSelectView({
2363
2516
  accessibilityLabel: "Search customers"
2364
2517
  }
2365
2518
  ),
2366
- selected && traits && /* @__PURE__ */ jsx59(Select2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx59(View29, { className: "rounded-lg border border-primary bg-primary/5 px-3 py-2", children: /* @__PURE__ */ jsx59(CustomerCard, { doc: selected, traits }) }) }),
2367
- customers.length > 0 && /* @__PURE__ */ jsx59(Select2.Content, { asChild: true, forceMount: true, disablePositioningStyle: true, children: /* @__PURE__ */ jsx59(ScrollView6, { className: "max-h-60", children: customers.map((customer, index) => {
2519
+ selected && traits && /* @__PURE__ */ jsx61(Select2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx61(View31, { className: "rounded-lg border border-primary bg-primary/5 px-3 py-2", children: /* @__PURE__ */ jsx61(CustomerCard, { doc: selected, traits }) }) }),
2520
+ customers.length > 0 && /* @__PURE__ */ jsx61(Select2.Content, { asChild: true, forceMount: true, disablePositioningStyle: true, children: /* @__PURE__ */ jsx61(ScrollView6, { className: "max-h-60", children: customers.map((customer, index) => {
2368
2521
  const id = traits?.getId(customer) ?? String(index);
2369
2522
  const label = traits?.getName(customer) ?? "";
2370
2523
  const email = traits?.getEmail(customer);
2371
- return /* @__PURE__ */ jsx59(
2524
+ return /* @__PURE__ */ jsx61(
2372
2525
  Select2.Item,
2373
2526
  {
2374
2527
  value: id,
2375
2528
  label,
2376
2529
  asChild: true,
2377
- children: /* @__PURE__ */ jsx59(Pressable14, { accessibilityLabel: email ? `${label}, ${email}` : label, className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx59(CustomerCard, { doc: customer, traits }) })
2530
+ children: /* @__PURE__ */ jsx61(Pressable16, { accessibilityLabel: email ? `${label}, ${email}` : label, className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx61(CustomerCard, { doc: customer, traits }) })
2378
2531
  },
2379
2532
  id
2380
2533
  );
@@ -2385,18 +2538,18 @@ function CustomerSelectView({
2385
2538
  }
2386
2539
 
2387
2540
  // src/customer/customer-form.tsx
2388
- import { Pressable as Pressable15, Text as Text17, TextInput as TextInput6, View as View30 } from "react-native";
2389
- import { cn as cn57 } from "@tallyui/theme";
2390
- import { jsx as jsx60, jsxs as jsxs20 } from "react/jsx-runtime";
2541
+ import { Pressable as Pressable17, Text as Text18, TextInput as TextInput6, View as View32 } from "react-native";
2542
+ import { cn as cn59 } from "@tallyui/theme";
2543
+ import { jsx as jsx62, jsxs as jsxs21 } from "react/jsx-runtime";
2391
2544
  function FormField({
2392
2545
  label,
2393
2546
  value,
2394
2547
  onChangeText,
2395
2548
  ...props
2396
2549
  }) {
2397
- return /* @__PURE__ */ jsxs20(View30, { className: "gap-1", children: [
2398
- /* @__PURE__ */ jsx60(Text17, { className: "text-xs font-medium text-muted-foreground", children: label }),
2399
- /* @__PURE__ */ jsx60(
2550
+ return /* @__PURE__ */ jsxs21(View32, { className: "gap-1", children: [
2551
+ /* @__PURE__ */ jsx62(Text18, { className: "text-xs font-medium text-muted-foreground", children: label }),
2552
+ /* @__PURE__ */ jsx62(
2400
2553
  TextInput6,
2401
2554
  {
2402
2555
  value,
@@ -2417,22 +2570,22 @@ function CustomerForm({
2417
2570
  className,
2418
2571
  ...viewProps
2419
2572
  }) {
2420
- return /* @__PURE__ */ jsxs20(View30, { className: cn57("gap-3 p-4", className), ...viewProps, children: [
2421
- /* @__PURE__ */ jsxs20(View30, { className: "flex-row gap-3", children: [
2422
- /* @__PURE__ */ jsx60(View30, { className: "flex-1", children: /* @__PURE__ */ jsx60(FormField, { label: "First Name", value: values.firstName, onChangeText: (v) => onChangeField("firstName", v), placeholder: "First name" }) }),
2423
- /* @__PURE__ */ jsx60(View30, { className: "flex-1", children: /* @__PURE__ */ jsx60(FormField, { label: "Last Name", value: values.lastName, onChangeText: (v) => onChangeField("lastName", v), placeholder: "Last name" }) })
2573
+ return /* @__PURE__ */ jsxs21(View32, { className: cn59("gap-3 p-4", className), ...viewProps, children: [
2574
+ /* @__PURE__ */ jsxs21(View32, { className: "flex-row gap-3", children: [
2575
+ /* @__PURE__ */ jsx62(View32, { className: "flex-1", children: /* @__PURE__ */ jsx62(FormField, { label: "First Name", value: values.firstName, onChangeText: (v) => onChangeField("firstName", v), placeholder: "First name" }) }),
2576
+ /* @__PURE__ */ jsx62(View32, { className: "flex-1", children: /* @__PURE__ */ jsx62(FormField, { label: "Last Name", value: values.lastName, onChangeText: (v) => onChangeField("lastName", v), placeholder: "Last name" }) })
2424
2577
  ] }),
2425
- /* @__PURE__ */ jsx60(FormField, { label: "Email", value: values.email, onChangeText: (v) => onChangeField("email", v), placeholder: "email@example.com", keyboardType: "email-address" }),
2426
- /* @__PURE__ */ jsx60(FormField, { label: "Phone", value: values.phone, onChangeText: (v) => onChangeField("phone", v), placeholder: "Phone number", keyboardType: "phone-pad" }),
2427
- showAddress && /* @__PURE__ */ jsx60(FormField, { label: "Address", value: values.address, onChangeText: (v) => onChangeField("address", v), placeholder: "Street address", multiline: true }),
2428
- onSubmit && /* @__PURE__ */ jsx60(Pressable15, { onPress: onSubmit, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx60(Text17, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel }) })
2578
+ /* @__PURE__ */ jsx62(FormField, { label: "Email", value: values.email, onChangeText: (v) => onChangeField("email", v), placeholder: "email@example.com", keyboardType: "email-address" }),
2579
+ /* @__PURE__ */ jsx62(FormField, { label: "Phone", value: values.phone, onChangeText: (v) => onChangeField("phone", v), placeholder: "Phone number", keyboardType: "phone-pad" }),
2580
+ showAddress && /* @__PURE__ */ jsx62(FormField, { label: "Address", value: values.address, onChangeText: (v) => onChangeField("address", v), placeholder: "Street address", multiline: true }),
2581
+ onSubmit && /* @__PURE__ */ jsx62(Pressable17, { onPress: onSubmit, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx62(Text18, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel }) })
2429
2582
  ] });
2430
2583
  }
2431
2584
 
2432
2585
  // src/customer/customer-order-history.tsx
2433
- import { ScrollView as ScrollView7, Text as Text18, View as View31 } from "react-native";
2434
- import { cn as cn58 } from "@tallyui/theme";
2435
- import { jsx as jsx61, jsxs as jsxs21 } from "react/jsx-runtime";
2586
+ import { ScrollView as ScrollView7, Text as Text19, View as View33 } from "react-native";
2587
+ import { cn as cn60 } from "@tallyui/theme";
2588
+ import { jsx as jsx63, jsxs as jsxs22 } from "react/jsx-runtime";
2436
2589
  function CustomerOrderHistory({
2437
2590
  orders,
2438
2591
  renderItem,
@@ -2440,31 +2593,31 @@ function CustomerOrderHistory({
2440
2593
  className,
2441
2594
  ...viewProps
2442
2595
  }) {
2443
- return /* @__PURE__ */ jsxs21(View31, { className: cn58("flex-1", className), ...viewProps, children: [
2444
- /* @__PURE__ */ jsx61(Text18, { className: "px-3 py-2 text-xs font-semibold text-muted-foreground", children: "Order History" }),
2445
- orders.length > 0 ? /* @__PURE__ */ jsx61(ScrollView7, { contentContainerClassName: "gap-2 px-3 pb-3", children: orders.map((order, index) => /* @__PURE__ */ jsx61(View31, { children: renderItem(order, index) }, order.id ?? index)) }) : emptyState ?? null
2596
+ return /* @__PURE__ */ jsxs22(View33, { className: cn60("flex-1", className), ...viewProps, children: [
2597
+ /* @__PURE__ */ jsx63(Text19, { className: "px-3 py-2 text-xs font-semibold text-muted-foreground", children: "Order History" }),
2598
+ orders.length > 0 ? /* @__PURE__ */ jsx63(ScrollView7, { contentContainerClassName: "gap-2 px-3 pb-3", children: orders.map((order, index) => /* @__PURE__ */ jsx63(View33, { children: renderItem(order, index) }, order.id ?? index)) }) : emptyState ?? null
2446
2599
  ] });
2447
2600
  }
2448
2601
 
2449
2602
  // src/customer/customer-picker.tsx
2450
- import { useEffect, useRef, useState as useState7 } from "react";
2451
- import { Pressable as Pressable16, Text as Text19, TextInput as TextInput7, View as View32 } from "react-native";
2603
+ import { useEffect, useRef, useState as useState8 } from "react";
2604
+ import { Pressable as Pressable18, Text as Text20, TextInput as TextInput7, View as View34 } from "react-native";
2452
2605
  import { customerTraits, CustomerServiceError, ConnectorUnauthorizedError } from "@tallyui/core";
2453
- import { cn as cn59 } from "@tallyui/theme";
2454
- import { jsx as jsx62, jsxs as jsxs22 } from "react/jsx-runtime";
2606
+ import { cn as cn61 } from "@tallyui/theme";
2607
+ import { jsx as jsx64, jsxs as jsxs23 } from "react/jsx-runtime";
2455
2608
  var EMAIL_MAX = 254;
2456
2609
  var EMAIL_SHAPE = /^[^\s@\u0000]+@[^\s@\u0000]+\.[^\s@\u0000]+$/u;
2457
2610
  function CustomerPicker({ search, create, selected, onSelect, onError, online, debounceMs = 250, className }) {
2458
- const [query, setQuery] = useState7("");
2459
- const [customers, setCustomers] = useState7([]);
2460
- const [error, setError] = useState7(null);
2461
- const [showForm, setShowForm] = useState7(false);
2462
- const [creating, setCreating] = useState7(false);
2463
- const [values, setValues] = useState7({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2611
+ const [query, setQuery] = useState8("");
2612
+ const [customers, setCustomers] = useState8([]);
2613
+ const [error, setError] = useState8(null);
2614
+ const [showForm, setShowForm] = useState8(false);
2615
+ const [creating, setCreating] = useState8(false);
2616
+ const [values, setValues] = useState8({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2464
2617
  const sequence = useRef(0);
2465
2618
  const searchRef = useRef(search);
2466
2619
  searchRef.current = search;
2467
- const [noResults, setNoResults] = useState7(false);
2620
+ const [noResults, setNoResults] = useState8(false);
2468
2621
  function handleError(error2) {
2469
2622
  if (error2 instanceof CustomerServiceError) {
2470
2623
  setError(error2.code === "network" ? "Couldn't reach the store. Try again." : error2.code === "server" ? "The store couldn't do that. Try again." : error2.message);
@@ -2519,13 +2672,13 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2519
2672
  setCreating(false);
2520
2673
  }
2521
2674
  }
2522
- return /* @__PURE__ */ jsxs22(View32, { className: cn59("gap-3", className), children: [
2523
- selected && /* @__PURE__ */ jsxs22(View32, { children: [
2524
- /* @__PURE__ */ jsx62(CustomerCard, { doc: selected, traits: customerTraits }),
2525
- /* @__PURE__ */ jsx62(Pressable16, { accessibilityRole: "button", className: "items-center rounded-lg border border-border px-4 py-3", onPress: () => onSelect(null), children: /* @__PURE__ */ jsx62(Text19, { className: "text-sm font-semibold text-foreground", children: "Remove customer" }) })
2675
+ return /* @__PURE__ */ jsxs23(View34, { className: cn61("gap-3", className), children: [
2676
+ selected && /* @__PURE__ */ jsxs23(View34, { children: [
2677
+ /* @__PURE__ */ jsx64(CustomerCard, { doc: selected, traits: customerTraits }),
2678
+ /* @__PURE__ */ jsx64(Pressable18, { accessibilityRole: "button", className: "items-center rounded-lg border border-border px-4 py-3", onPress: () => onSelect(null), children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "Remove customer" }) })
2526
2679
  ] }),
2527
- /* @__PURE__ */ jsx62(Text19, { className: "text-xs font-medium text-muted-foreground", children: "Search customers" }),
2528
- /* @__PURE__ */ jsx62(
2680
+ /* @__PURE__ */ jsx64(Text20, { className: "text-xs font-medium text-muted-foreground", children: "Search customers" }),
2681
+ /* @__PURE__ */ jsx64(
2529
2682
  TextInput7,
2530
2683
  {
2531
2684
  accessibilityLabel: "Search customers",
@@ -2537,10 +2690,10 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2537
2690
  placeholder: "Name or email"
2538
2691
  }
2539
2692
  ),
2540
- !online && /* @__PURE__ */ jsx62(Text19, { className: "text-sm text-muted-foreground", children: "Connect to search or add customers." }),
2541
- noResults && /* @__PURE__ */ jsx62(Text19, { className: "text-sm text-muted-foreground", children: "No customers found." }),
2542
- error && /* @__PURE__ */ jsx62(Text19, { accessibilityRole: "alert", className: "text-sm text-destructive", children: error }),
2543
- /* @__PURE__ */ jsx62(
2693
+ !online && /* @__PURE__ */ jsx64(Text20, { className: "text-sm text-muted-foreground", children: "Connect to search or add customers." }),
2694
+ noResults && /* @__PURE__ */ jsx64(Text20, { className: "text-sm text-muted-foreground", children: "No customers found." }),
2695
+ error && /* @__PURE__ */ jsx64(Text20, { accessibilityRole: "alert", className: "text-sm text-destructive", children: error }),
2696
+ /* @__PURE__ */ jsx64(
2544
2697
  CustomerSelect,
2545
2698
  {
2546
2699
  customers,
@@ -2553,18 +2706,18 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2553
2706
  }
2554
2707
  }
2555
2708
  ),
2556
- create && /* @__PURE__ */ jsx62(
2557
- Pressable16,
2709
+ create && /* @__PURE__ */ jsx64(
2710
+ Pressable18,
2558
2711
  {
2559
2712
  accessibilityRole: "button",
2560
2713
  disabled: !online || creating,
2561
2714
  onPress: () => setShowForm(true),
2562
- className: cn59("items-center rounded-lg border border-border px-4 py-3", (!online || creating) && "opacity-50"),
2563
- children: /* @__PURE__ */ jsx62(Text19, { className: "text-sm font-semibold text-foreground", children: "New customer" })
2715
+ className: cn61("items-center rounded-lg border border-border px-4 py-3", (!online || creating) && "opacity-50"),
2716
+ children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "New customer" })
2564
2717
  }
2565
2718
  ),
2566
- showForm && /* @__PURE__ */ jsxs22(View32, { children: [
2567
- /* @__PURE__ */ jsx62(
2719
+ showForm && /* @__PURE__ */ jsxs23(View34, { children: [
2720
+ /* @__PURE__ */ jsx64(
2568
2721
  CustomerForm,
2569
2722
  {
2570
2723
  values,
@@ -2572,19 +2725,19 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2572
2725
  onChangeField: (field, value) => setValues((current) => ({ ...current, [field]: value }))
2573
2726
  }
2574
2727
  ),
2575
- /* @__PURE__ */ jsxs22(View32, { className: "flex-row gap-3", children: [
2576
- /* @__PURE__ */ jsx62(
2577
- Pressable16,
2728
+ /* @__PURE__ */ jsxs23(View34, { className: "flex-row gap-3", children: [
2729
+ /* @__PURE__ */ jsx64(
2730
+ Pressable18,
2578
2731
  {
2579
2732
  accessibilityRole: "button",
2580
2733
  disabled: !online || creating || !values.email.trim(),
2581
2734
  onPress: submit,
2582
- className: cn59("items-center rounded-lg bg-primary px-4 py-3", (!online || creating || !values.email.trim()) && "opacity-50"),
2583
- children: /* @__PURE__ */ jsx62(Text19, { className: "text-sm font-semibold text-primary-foreground", children: "Save Customer" })
2735
+ className: cn61("items-center rounded-lg bg-primary px-4 py-3", (!online || creating || !values.email.trim()) && "opacity-50"),
2736
+ children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-primary-foreground", children: "Save Customer" })
2584
2737
  }
2585
2738
  ),
2586
- /* @__PURE__ */ jsx62(
2587
- Pressable16,
2739
+ /* @__PURE__ */ jsx64(
2740
+ Pressable18,
2588
2741
  {
2589
2742
  accessibilityRole: "button",
2590
2743
  className: "items-center rounded-lg border border-border px-4 py-3",
@@ -2592,7 +2745,7 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2592
2745
  setShowForm(false);
2593
2746
  setValues({ firstName: "", lastName: "", email: "", phone: "", address: "" });
2594
2747
  },
2595
- children: /* @__PURE__ */ jsx62(Text19, { className: "text-sm font-semibold text-foreground", children: "Cancel" })
2748
+ children: /* @__PURE__ */ jsx64(Text20, { className: "text-sm font-semibold text-foreground", children: "Cancel" })
2596
2749
  }
2597
2750
  )
2598
2751
  ] })
@@ -2601,40 +2754,40 @@ function CustomerPicker({ search, create, selected, onSelect, onError, online, d
2601
2754
  }
2602
2755
 
2603
2756
  // src/checkout/payment-method-card.tsx
2604
- import { Pressable as Pressable17, View as View33 } from "react-native";
2605
- import { cn as cn60 } from "@tallyui/theme";
2606
- import { jsx as jsx63, jsxs as jsxs23 } from "react/jsx-runtime";
2757
+ import { Pressable as Pressable19, View as View35 } from "react-native";
2758
+ import { cn as cn62 } from "@tallyui/theme";
2759
+ import { jsx as jsx65, jsxs as jsxs24 } from "react/jsx-runtime";
2607
2760
  function PaymentMethodCard({ label, selected, onPress, icon, className, ...props }) {
2608
- return /* @__PURE__ */ jsx63(Pressable17, { onPress, ...props, children: /* @__PURE__ */ jsxs23(
2761
+ return /* @__PURE__ */ jsx65(Pressable19, { onPress, ...props, children: /* @__PURE__ */ jsxs24(
2609
2762
  HStack,
2610
2763
  {
2611
- className: cn60(
2764
+ className: cn62(
2612
2765
  "rounded-lg border px-4 py-3",
2613
2766
  selected ? "border-primary bg-primary/5" : "border-border bg-card",
2614
2767
  className
2615
2768
  ),
2616
2769
  children: [
2617
- icon && /* @__PURE__ */ jsx63(View33, { children: icon }),
2618
- /* @__PURE__ */ jsx63(Text, { className: cn60("flex-1 text-sm font-medium", selected ? "text-primary" : ""), children: label }),
2619
- selected && /* @__PURE__ */ jsx63(View33, { className: "h-5 w-5 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx63(Text, { className: "text-xs text-primary-foreground", children: "\u2713" }) })
2770
+ icon && /* @__PURE__ */ jsx65(View35, { children: icon }),
2771
+ /* @__PURE__ */ jsx65(Text, { className: cn62("flex-1 text-sm font-medium", selected ? "text-primary" : ""), children: label }),
2772
+ selected && /* @__PURE__ */ jsx65(View35, { className: "h-5 w-5 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx65(Text, { className: "text-xs text-primary-foreground", children: "\u2713" }) })
2620
2773
  ]
2621
2774
  }
2622
2775
  ) });
2623
2776
  }
2624
2777
 
2625
2778
  // src/checkout/order-summary-line.tsx
2626
- import { cn as cn61 } from "@tallyui/theme";
2627
- import { jsx as jsx64, jsxs as jsxs24 } from "react/jsx-runtime";
2779
+ import { cn as cn63 } from "@tallyui/theme";
2780
+ import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
2628
2781
  function OrderSummaryLine({ label, amount, bold = false, className, ...props }) {
2629
- return /* @__PURE__ */ jsxs24(HStack, { space: "none", className: cn61("justify-between", className), ...props, children: [
2630
- /* @__PURE__ */ jsx64(Text, { className: cn61("text-sm", bold ? "font-bold" : "text-muted-foreground"), children: label }),
2631
- /* @__PURE__ */ jsx64(Text, { className: cn61("text-sm", bold && "font-bold"), children: amount })
2782
+ return /* @__PURE__ */ jsxs25(HStack, { space: "none", className: cn63("justify-between", className), ...props, children: [
2783
+ /* @__PURE__ */ jsx66(Text, { className: cn63("text-sm", bold ? "font-bold" : "text-muted-foreground"), children: label }),
2784
+ /* @__PURE__ */ jsx66(Text, { className: cn63("text-sm", bold && "font-bold"), children: amount })
2632
2785
  ] });
2633
2786
  }
2634
2787
 
2635
2788
  // src/checkout/payment-selector.tsx
2636
- import { cn as cn62 } from "@tallyui/theme";
2637
- import { jsx as jsx65 } from "react/jsx-runtime";
2789
+ import { cn as cn64 } from "@tallyui/theme";
2790
+ import { jsx as jsx67 } from "react/jsx-runtime";
2638
2791
  function PaymentSelector({
2639
2792
  methods,
2640
2793
  selected,
@@ -2642,7 +2795,7 @@ function PaymentSelector({
2642
2795
  className,
2643
2796
  ...props
2644
2797
  }) {
2645
- return /* @__PURE__ */ jsx65(VStack, { space: "sm", className: cn62(className), ...props, children: methods.map((method) => /* @__PURE__ */ jsx65(
2798
+ return /* @__PURE__ */ jsx67(VStack, { space: "sm", className: cn64(className), ...props, children: methods.map((method) => /* @__PURE__ */ jsx67(
2646
2799
  PaymentMethodCard,
2647
2800
  {
2648
2801
  label: method.label,
@@ -2655,9 +2808,9 @@ function PaymentSelector({
2655
2808
  }
2656
2809
 
2657
2810
  // src/checkout/order-summary.tsx
2658
- import { View as View34 } from "react-native";
2659
- import { cn as cn63 } from "@tallyui/theme";
2660
- import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
2811
+ import { View as View36 } from "react-native";
2812
+ import { cn as cn65 } from "@tallyui/theme";
2813
+ import { jsx as jsx68, jsxs as jsxs26 } from "react/jsx-runtime";
2661
2814
  function OrderSummary({
2662
2815
  subtotal,
2663
2816
  tax,
@@ -2669,34 +2822,34 @@ function OrderSummary({
2669
2822
  className,
2670
2823
  ...props
2671
2824
  }) {
2672
- return /* @__PURE__ */ jsxs25(VStack, { space: "none", className: cn63("gap-1.5 px-3 py-3", className), ...props, children: [
2673
- header && /* @__PURE__ */ jsx66(View34, { className: "mb-2", children: header }),
2674
- /* @__PURE__ */ jsx66(OrderSummaryLine, { label: "Subtotal", amount: subtotal }),
2675
- tax && /* @__PURE__ */ jsx66(OrderSummaryLine, { label: taxLabel, amount: tax }),
2676
- /* @__PURE__ */ jsx66(OrderSummaryLine, { label: "Total", amount: total, bold: true }),
2677
- payments && payments.length > 0 && /* @__PURE__ */ jsx66(VStack, { space: "none", className: "mt-2 gap-1.5 border-t border-border pt-2", children: payments.map((payment) => /* @__PURE__ */ jsx66(OrderSummaryLine, { label: payment.label, amount: payment.amount }, payment.label)) }),
2678
- footer && /* @__PURE__ */ jsx66(View34, { className: "mt-2", children: footer })
2825
+ return /* @__PURE__ */ jsxs26(VStack, { space: "none", className: cn65("gap-1.5 px-3 py-3", className), ...props, children: [
2826
+ header && /* @__PURE__ */ jsx68(View36, { className: "mb-2", children: header }),
2827
+ /* @__PURE__ */ jsx68(OrderSummaryLine, { label: "Subtotal", amount: subtotal }),
2828
+ tax && /* @__PURE__ */ jsx68(OrderSummaryLine, { label: taxLabel, amount: tax }),
2829
+ /* @__PURE__ */ jsx68(OrderSummaryLine, { label: "Total", amount: total, bold: true }),
2830
+ payments && payments.length > 0 && /* @__PURE__ */ jsx68(VStack, { space: "none", className: "mt-2 gap-1.5 border-t border-border pt-2", children: payments.map((payment) => /* @__PURE__ */ jsx68(OrderSummaryLine, { label: payment.label, amount: payment.amount }, payment.label)) }),
2831
+ footer && /* @__PURE__ */ jsx68(View36, { className: "mt-2", children: footer })
2679
2832
  ] });
2680
2833
  }
2681
2834
 
2682
2835
  // src/checkout/change-display.tsx
2683
- import { Text as Text20, View as View35 } from "react-native";
2836
+ import { Text as Text21, View as View37 } from "react-native";
2684
2837
  import { formatMoney as formatMoney4 } from "@tallyui/core";
2685
- import { cn as cn64 } from "@tallyui/theme";
2686
- import { jsx as jsx67, jsxs as jsxs26 } from "react/jsx-runtime";
2838
+ import { cn as cn66 } from "@tallyui/theme";
2839
+ import { jsx as jsx69, jsxs as jsxs27 } from "react/jsx-runtime";
2687
2840
  function ChangeDisplay({ change, locale, className, ...viewProps }) {
2688
- return /* @__PURE__ */ jsxs26(View35, { className: cn64("items-center gap-1 rounded-xl bg-muted p-4", className), ...viewProps, children: [
2689
- /* @__PURE__ */ jsx67(Text20, { className: "text-sm text-muted-foreground", children: "Change Due" }),
2690
- /* @__PURE__ */ jsx67(Text20, { className: "text-3xl font-bold text-success", children: formatMoney4(change, locale) ?? "\u2014" })
2841
+ return /* @__PURE__ */ jsxs27(View37, { className: cn66("items-center gap-1 rounded-xl bg-muted p-4", className), ...viewProps, children: [
2842
+ /* @__PURE__ */ jsx69(Text21, { className: "text-sm text-muted-foreground", children: "Change Due" }),
2843
+ /* @__PURE__ */ jsx69(Text21, { className: "text-3xl font-bold text-success", children: formatMoney4(change, locale) ?? "\u2014" })
2691
2844
  ] });
2692
2845
  }
2693
2846
 
2694
2847
  // src/checkout/cash-tendered.tsx
2695
- import { useEffect as useEffect2, useRef as useRef2, useState as useState8 } from "react";
2696
- import { Pressable as Pressable18, Text as Text21, TextInput as TextInput8, View as View36 } from "react-native";
2848
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState9 } from "react";
2849
+ import { Pressable as Pressable20, Text as Text22, TextInput as TextInput8, View as View38 } from "react-native";
2697
2850
  import { formatMoney as formatMoney5, minorUnitDigits as minorUnitDigits2, moneyFromDecimalString } from "@tallyui/core";
2698
- import { cn as cn65 } from "@tallyui/theme";
2699
- import { jsx as jsx68, jsxs as jsxs27 } from "react/jsx-runtime";
2851
+ import { cn as cn67 } from "@tallyui/theme";
2852
+ import { jsx as jsx70, jsxs as jsxs28 } from "react/jsx-runtime";
2700
2853
  function defaultQuickAmounts(total) {
2701
2854
  const unit = 10 ** minorUnitDigits2(total.currency);
2702
2855
  const amounts = [
@@ -2717,13 +2870,13 @@ function CashTendered({
2717
2870
  className,
2718
2871
  ...viewProps
2719
2872
  }) {
2720
- const [internalAmount, setInternalAmount] = useState8(defaultAmount ?? total);
2873
+ const [internalAmount, setInternalAmount] = useState9(defaultAmount ?? total);
2721
2874
  const amount = controlledAmount ?? internalAmount;
2722
2875
  const buttons = quickAmounts ?? defaultQuickAmounts(total);
2723
2876
  const digits = minorUnitDigits2(amount.currency);
2724
2877
  const amountText = String(Math.abs(amount.amount)).padStart(digits + 1, "0");
2725
2878
  const decimal2 = (amount.amount < 0 ? "-" : "") + (digits ? `${amountText.slice(0, -digits)}.${amountText.slice(-digits)}` : amountText);
2726
- const [text, setText] = useState8(decimal2);
2879
+ const [text, setText] = useState9(decimal2);
2727
2880
  const lastTextAmount = useRef2(amount);
2728
2881
  useEffect2(() => {
2729
2882
  if (amount.amount !== lastTextAmount.current.amount || amount.currency !== lastTextAmount.current.currency) {
@@ -2735,20 +2888,20 @@ function CashTendered({
2735
2888
  if (controlledAmount === void 0) setInternalAmount(value);
2736
2889
  onChangeAmount?.(value);
2737
2890
  };
2738
- return /* @__PURE__ */ jsxs27(View36, { className: cn65("gap-3", className), ...viewProps, children: [
2739
- /* @__PURE__ */ jsx68(Text21, { className: "text-sm font-semibold text-foreground", children: "Cash Tendered" }),
2740
- /* @__PURE__ */ jsx68(View36, { className: "flex-row flex-wrap gap-2", children: buttons.map((val) => /* @__PURE__ */ jsx68(
2741
- Pressable18,
2891
+ return /* @__PURE__ */ jsxs28(View38, { className: cn67("gap-3", className), ...viewProps, children: [
2892
+ /* @__PURE__ */ jsx70(Text22, { className: "text-sm font-semibold text-foreground", children: "Cash Tendered" }),
2893
+ /* @__PURE__ */ jsx70(View38, { className: "flex-row flex-wrap gap-2", children: buttons.map((val) => /* @__PURE__ */ jsx70(
2894
+ Pressable20,
2742
2895
  {
2743
2896
  onPress: () => handleChange(val),
2744
- className: cn65(
2897
+ className: cn67(
2745
2898
  "rounded-lg border px-4 py-2",
2746
2899
  amount.amount === val.amount && amount.currency === val.currency ? "border-primary bg-primary" : "border-input bg-card"
2747
2900
  ),
2748
- children: /* @__PURE__ */ jsx68(
2749
- Text21,
2901
+ children: /* @__PURE__ */ jsx70(
2902
+ Text22,
2750
2903
  {
2751
- className: cn65(
2904
+ className: cn67(
2752
2905
  "text-sm font-semibold",
2753
2906
  amount.amount === val.amount && amount.currency === val.currency ? "text-primary-foreground" : "text-foreground"
2754
2907
  ),
@@ -2758,7 +2911,7 @@ function CashTendered({
2758
2911
  },
2759
2912
  `${val.currency}:${val.amount}`
2760
2913
  )) }),
2761
- /* @__PURE__ */ jsx68(
2914
+ /* @__PURE__ */ jsx70(
2762
2915
  TextInput8,
2763
2916
  {
2764
2917
  value: text,
@@ -2780,9 +2933,9 @@ function CashTendered({
2780
2933
  }
2781
2934
 
2782
2935
  // src/checkout/receipt-preview.tsx
2783
- import { Text as Text22, View as View37 } from "react-native";
2784
- import { cn as cn66 } from "@tallyui/theme";
2785
- import { jsx as jsx69, jsxs as jsxs28 } from "react/jsx-runtime";
2936
+ import { Text as Text23, View as View39 } from "react-native";
2937
+ import { cn as cn68 } from "@tallyui/theme";
2938
+ import { jsx as jsx71, jsxs as jsxs29 } from "react/jsx-runtime";
2786
2939
  function ReceiptPreview({
2787
2940
  items,
2788
2941
  subtotal,
@@ -2794,42 +2947,42 @@ function ReceiptPreview({
2794
2947
  className,
2795
2948
  ...viewProps
2796
2949
  }) {
2797
- return /* @__PURE__ */ jsxs28(View37, { className: cn66("rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
2798
- headerSlot && /* @__PURE__ */ jsx69(View37, { className: "mb-3 items-center border-b border-dashed border-border pb-3", children: headerSlot }),
2799
- /* @__PURE__ */ jsx69(View37, { className: "gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs28(View37, { className: "flex-row justify-between", children: [
2800
- /* @__PURE__ */ jsxs28(Text22, { className: "flex-1 text-sm text-foreground", children: [
2950
+ return /* @__PURE__ */ jsxs29(View39, { className: cn68("rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
2951
+ headerSlot && /* @__PURE__ */ jsx71(View39, { className: "mb-3 items-center border-b border-dashed border-border pb-3", children: headerSlot }),
2952
+ /* @__PURE__ */ jsx71(View39, { className: "gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
2953
+ /* @__PURE__ */ jsxs29(Text23, { className: "flex-1 text-sm text-foreground", children: [
2801
2954
  item.name,
2802
2955
  " x",
2803
2956
  item.quantity
2804
2957
  ] }),
2805
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-foreground", children: item.total })
2958
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: item.total })
2806
2959
  ] }, i)) }),
2807
- /* @__PURE__ */ jsxs28(View37, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: [
2808
- /* @__PURE__ */ jsxs28(View37, { className: "flex-row justify-between", children: [
2809
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2810
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-foreground", children: subtotal })
2960
+ /* @__PURE__ */ jsxs29(View39, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: [
2961
+ /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
2962
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2963
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: subtotal })
2811
2964
  ] }),
2812
- /* @__PURE__ */ jsxs28(View37, { className: "flex-row justify-between", children: [
2813
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-muted-foreground", children: "Tax" }),
2814
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-foreground", children: tax })
2965
+ /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
2966
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: "Tax" }),
2967
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: tax })
2815
2968
  ] }),
2816
- /* @__PURE__ */ jsxs28(View37, { className: "flex-row justify-between border-t border-border pt-1", children: [
2817
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm font-bold text-foreground", children: "Total" }),
2818
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm font-bold text-foreground", children: total })
2969
+ /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between border-t border-border pt-1", children: [
2970
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm font-bold text-foreground", children: "Total" }),
2971
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm font-bold text-foreground", children: total })
2819
2972
  ] })
2820
2973
  ] }),
2821
- payments && payments.length > 0 && /* @__PURE__ */ jsx69(View37, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: payments.map((p, i) => /* @__PURE__ */ jsxs28(View37, { className: "flex-row justify-between", children: [
2822
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-muted-foreground", children: p.method }),
2823
- /* @__PURE__ */ jsx69(Text22, { className: "text-sm text-foreground", children: p.amount })
2974
+ payments && payments.length > 0 && /* @__PURE__ */ jsx71(View39, { className: "mt-3 gap-1 border-t border-dashed border-border pt-3", children: payments.map((p, i) => /* @__PURE__ */ jsxs29(View39, { className: "flex-row justify-between", children: [
2975
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-muted-foreground", children: p.method }),
2976
+ /* @__PURE__ */ jsx71(Text23, { className: "text-sm text-foreground", children: p.amount })
2824
2977
  ] }, i)) }),
2825
- footerSlot && /* @__PURE__ */ jsx69(View37, { className: "mt-3 items-center border-t border-dashed border-border pt-3", children: footerSlot })
2978
+ footerSlot && /* @__PURE__ */ jsx71(View39, { className: "mt-3 items-center border-t border-dashed border-border pt-3", children: footerSlot })
2826
2979
  ] });
2827
2980
  }
2828
2981
 
2829
2982
  // src/order/order-status-badge.tsx
2830
- import { Text as Text23, View as View38 } from "react-native";
2831
- import { cn as cn67 } from "@tallyui/theme";
2832
- import { jsx as jsx70, jsxs as jsxs29 } from "react/jsx-runtime";
2983
+ import { Text as Text24, View as View40 } from "react-native";
2984
+ import { cn as cn69 } from "@tallyui/theme";
2985
+ import { jsx as jsx72, jsxs as jsxs30 } from "react/jsx-runtime";
2833
2986
  var STATUS_CONFIG = {
2834
2987
  pending: { label: "Pending", badge: "bg-warning/15", dot: "bg-warning", text: "text-foreground" },
2835
2988
  processing: { label: "Processing", badge: "bg-info/15", dot: "bg-info", text: "text-foreground" },
@@ -2839,23 +2992,23 @@ var STATUS_CONFIG = {
2839
2992
  };
2840
2993
  function OrderStatusBadge({ status, className, ...viewProps }) {
2841
2994
  const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.pending;
2842
- return /* @__PURE__ */ jsxs29(
2843
- View38,
2995
+ return /* @__PURE__ */ jsxs30(
2996
+ View40,
2844
2997
  {
2845
- className: cn67("flex-row items-center self-start gap-1.5 rounded-xl px-2 py-1", config.badge, className),
2998
+ className: cn69("flex-row items-center self-start gap-1.5 rounded-xl px-2 py-1", config.badge, className),
2846
2999
  ...viewProps,
2847
3000
  children: [
2848
- /* @__PURE__ */ jsx70(View38, { className: cn67("h-1.5 w-1.5 rounded-full", config.dot) }),
2849
- /* @__PURE__ */ jsx70(Text23, { className: cn67("text-xs font-semibold", config.text), children: config.label })
3001
+ /* @__PURE__ */ jsx72(View40, { className: cn69("h-1.5 w-1.5 rounded-full", config.dot) }),
3002
+ /* @__PURE__ */ jsx72(Text24, { className: cn69("text-xs font-semibold", config.text), children: config.label })
2850
3003
  ]
2851
3004
  }
2852
3005
  );
2853
3006
  }
2854
3007
 
2855
3008
  // src/order/order-card.tsx
2856
- import { Pressable as Pressable19, Text as Text24, View as View39 } from "react-native";
2857
- import { cn as cn68 } from "@tallyui/theme";
2858
- import { jsx as jsx71, jsxs as jsxs30 } from "react/jsx-runtime";
3009
+ import { Pressable as Pressable21, Text as Text25, View as View41 } from "react-native";
3010
+ import { cn as cn70 } from "@tallyui/theme";
3011
+ import { jsx as jsx73, jsxs as jsxs31 } from "react/jsx-runtime";
2859
3012
  function OrderCard({
2860
3013
  orderNumber,
2861
3014
  date,
@@ -2866,24 +3019,24 @@ function OrderCard({
2866
3019
  className,
2867
3020
  ...viewProps
2868
3021
  }) {
2869
- const Wrapper = onPress ? Pressable19 : View39;
2870
- return /* @__PURE__ */ jsxs30(
3022
+ const Wrapper = onPress ? Pressable21 : View41;
3023
+ return /* @__PURE__ */ jsxs31(
2871
3024
  Wrapper,
2872
3025
  {
2873
3026
  onPress,
2874
- className: cn68("gap-2 rounded-lg border border-border bg-card p-3", className),
3027
+ className: cn70("gap-2 rounded-lg border border-border bg-card p-3", className),
2875
3028
  ...viewProps,
2876
3029
  children: [
2877
- /* @__PURE__ */ jsxs30(View39, { className: "flex-row items-center justify-between", children: [
2878
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm font-semibold text-foreground", children: orderNumber }),
2879
- /* @__PURE__ */ jsx71(OrderStatusBadge, { status })
3030
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between", children: [
3031
+ /* @__PURE__ */ jsx73(Text25, { className: "text-sm font-semibold text-foreground", children: orderNumber }),
3032
+ /* @__PURE__ */ jsx73(OrderStatusBadge, { status })
2880
3033
  ] }),
2881
- /* @__PURE__ */ jsxs30(View39, { className: "flex-row items-center justify-between", children: [
2882
- /* @__PURE__ */ jsxs30(View39, { className: "gap-0.5", children: [
2883
- /* @__PURE__ */ jsx71(Text24, { className: "text-xs text-muted-foreground", children: date }),
2884
- customerName && /* @__PURE__ */ jsx71(Text24, { className: "text-xs text-muted-foreground", children: customerName })
3034
+ /* @__PURE__ */ jsxs31(View41, { className: "flex-row items-center justify-between", children: [
3035
+ /* @__PURE__ */ jsxs31(View41, { className: "gap-0.5", children: [
3036
+ /* @__PURE__ */ jsx73(Text25, { className: "text-xs text-muted-foreground", children: date }),
3037
+ customerName && /* @__PURE__ */ jsx73(Text25, { className: "text-xs text-muted-foreground", children: customerName })
2885
3038
  ] }),
2886
- /* @__PURE__ */ jsx71(Text24, { className: "text-sm font-semibold text-foreground", children: total })
3039
+ /* @__PURE__ */ jsx73(Text25, { className: "text-sm font-semibold text-foreground", children: total })
2887
3040
  ] })
2888
3041
  ]
2889
3042
  }
@@ -2891,9 +3044,9 @@ function OrderCard({
2891
3044
  }
2892
3045
 
2893
3046
  // src/order/order-list.tsx
2894
- import { ScrollView as ScrollView8, View as View40 } from "react-native";
2895
- import { cn as cn69 } from "@tallyui/theme";
2896
- import { jsx as jsx72, jsxs as jsxs31 } from "react/jsx-runtime";
3047
+ import { ScrollView as ScrollView8, View as View42 } from "react-native";
3048
+ import { cn as cn71 } from "@tallyui/theme";
3049
+ import { jsx as jsx74, jsxs as jsxs32 } from "react/jsx-runtime";
2897
3050
  function OrderList({
2898
3051
  items,
2899
3052
  renderItem,
@@ -2903,16 +3056,16 @@ function OrderList({
2903
3056
  ...viewProps
2904
3057
  }) {
2905
3058
  const hasItems = items.length > 0;
2906
- return /* @__PURE__ */ jsxs31(View40, { className: cn69("flex-1", className), ...viewProps, children: [
2907
- headerSlot && /* @__PURE__ */ jsx72(View40, { className: "px-3 py-2", children: headerSlot }),
2908
- hasItems ? /* @__PURE__ */ jsx72(ScrollView8, { contentContainerClassName: "gap-2 p-3", children: items.map((item, index) => /* @__PURE__ */ jsx72(View40, { children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
3059
+ return /* @__PURE__ */ jsxs32(View42, { className: cn71("flex-1", className), ...viewProps, children: [
3060
+ headerSlot && /* @__PURE__ */ jsx74(View42, { className: "px-3 py-2", children: headerSlot }),
3061
+ hasItems ? /* @__PURE__ */ jsx74(ScrollView8, { contentContainerClassName: "gap-2 p-3", children: items.map((item, index) => /* @__PURE__ */ jsx74(View42, { children: renderItem(item, index) }, item.id ?? index)) }) : emptyState ?? null
2909
3062
  ] });
2910
3063
  }
2911
3064
 
2912
3065
  // src/order/order-detail.tsx
2913
- import { ScrollView as ScrollView9, Text as Text25, View as View41 } from "react-native";
2914
- import { cn as cn70 } from "@tallyui/theme";
2915
- import { jsx as jsx73, jsxs as jsxs32 } from "react/jsx-runtime";
3066
+ import { ScrollView as ScrollView9, Text as Text26, View as View43 } from "react-native";
3067
+ import { cn as cn72 } from "@tallyui/theme";
3068
+ import { jsx as jsx75, jsxs as jsxs33 } from "react/jsx-runtime";
2916
3069
  function OrderDetail({
2917
3070
  orderNumber,
2918
3071
  status,
@@ -2926,47 +3079,47 @@ function OrderDetail({
2926
3079
  className,
2927
3080
  ...viewProps
2928
3081
  }) {
2929
- return /* @__PURE__ */ jsx73(ScrollView9, { className: cn70("flex-1", className), ...viewProps, children: /* @__PURE__ */ jsxs32(View41, { className: "gap-4 p-4", children: [
2930
- /* @__PURE__ */ jsxs32(View41, { className: "flex-row items-center justify-between", children: [
2931
- /* @__PURE__ */ jsx73(Text25, { className: "text-lg font-bold text-foreground", children: orderNumber }),
2932
- /* @__PURE__ */ jsx73(OrderStatusBadge, { status })
3082
+ return /* @__PURE__ */ jsx75(ScrollView9, { className: cn72("flex-1", className), ...viewProps, children: /* @__PURE__ */ jsxs33(View43, { className: "gap-4 p-4", children: [
3083
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row items-center justify-between", children: [
3084
+ /* @__PURE__ */ jsx75(Text26, { className: "text-lg font-bold text-foreground", children: orderNumber }),
3085
+ /* @__PURE__ */ jsx75(OrderStatusBadge, { status })
2933
3086
  ] }),
2934
- customerSlot && /* @__PURE__ */ jsx73(View41, { className: "border-b border-border pb-3", children: customerSlot }),
2935
- /* @__PURE__ */ jsxs32(View41, { className: "gap-1", children: [
2936
- /* @__PURE__ */ jsx73(Text25, { className: "text-xs font-semibold text-muted-foreground", children: "Items" }),
2937
- lineItems.map((item, i) => /* @__PURE__ */ jsxs32(View41, { className: "flex-row items-center justify-between py-1", children: [
2938
- /* @__PURE__ */ jsxs32(Text25, { className: "flex-1 text-sm text-foreground", children: [
3087
+ customerSlot && /* @__PURE__ */ jsx75(View43, { className: "border-b border-border pb-3", children: customerSlot }),
3088
+ /* @__PURE__ */ jsxs33(View43, { className: "gap-1", children: [
3089
+ /* @__PURE__ */ jsx75(Text26, { className: "text-xs font-semibold text-muted-foreground", children: "Items" }),
3090
+ lineItems.map((item, i) => /* @__PURE__ */ jsxs33(View43, { className: "flex-row items-center justify-between py-1", children: [
3091
+ /* @__PURE__ */ jsxs33(Text26, { className: "flex-1 text-sm text-foreground", children: [
2939
3092
  item.name,
2940
3093
  " x",
2941
3094
  item.quantity
2942
3095
  ] }),
2943
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm text-foreground", children: item.total })
3096
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: item.total })
2944
3097
  ] }, i))
2945
3098
  ] }),
2946
- /* @__PURE__ */ jsxs32(View41, { className: "gap-1 border-t border-border pt-3", children: [
2947
- /* @__PURE__ */ jsxs32(View41, { className: "flex-row justify-between", children: [
2948
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
2949
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm text-foreground", children: subtotal })
3099
+ /* @__PURE__ */ jsxs33(View43, { className: "gap-1 border-t border-border pt-3", children: [
3100
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
3101
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm text-muted-foreground", children: "Subtotal" }),
3102
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: subtotal })
2950
3103
  ] }),
2951
- /* @__PURE__ */ jsxs32(View41, { className: "flex-row justify-between", children: [
2952
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm text-muted-foreground", children: "Tax" }),
2953
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm text-foreground", children: tax })
3104
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between", children: [
3105
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm text-muted-foreground", children: "Tax" }),
3106
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm text-foreground", children: tax })
2954
3107
  ] }),
2955
- /* @__PURE__ */ jsxs32(View41, { className: "flex-row justify-between pt-1", children: [
2956
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm font-bold text-foreground", children: "Total" }),
2957
- /* @__PURE__ */ jsx73(Text25, { className: "text-sm font-bold text-foreground", children: total })
3108
+ /* @__PURE__ */ jsxs33(View43, { className: "flex-row justify-between pt-1", children: [
3109
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm font-bold text-foreground", children: "Total" }),
3110
+ /* @__PURE__ */ jsx75(Text26, { className: "text-sm font-bold text-foreground", children: total })
2958
3111
  ] })
2959
3112
  ] }),
2960
- paymentSlot && /* @__PURE__ */ jsx73(View41, { className: "border-t border-border pt-3", children: paymentSlot }),
2961
- footerSlot && /* @__PURE__ */ jsx73(View41, { className: "border-t border-border pt-3", children: footerSlot })
3113
+ paymentSlot && /* @__PURE__ */ jsx75(View43, { className: "border-t border-border pt-3", children: paymentSlot }),
3114
+ footerSlot && /* @__PURE__ */ jsx75(View43, { className: "border-t border-border pt-3", children: footerSlot })
2962
3115
  ] }) });
2963
3116
  }
2964
3117
 
2965
3118
  // src/register/cash-count-input.tsx
2966
- import { useState as useState9 } from "react";
2967
- import { Text as Text26, View as View42 } from "react-native";
2968
- import { cn as cn71 } from "@tallyui/theme";
2969
- import { jsx as jsx74, jsxs as jsxs33 } from "react/jsx-runtime";
3119
+ import { useState as useState10 } from "react";
3120
+ import { Text as Text27, View as View44 } from "react-native";
3121
+ import { cn as cn73 } from "@tallyui/theme";
3122
+ import { jsx as jsx76, jsxs as jsxs34 } from "react/jsx-runtime";
2970
3123
  var DEFAULT_DENOMINATIONS = [
2971
3124
  { label: "$100", value: 100 },
2972
3125
  { label: "$50", value: 50 },
@@ -2988,7 +3141,7 @@ function CashCountInput({
2988
3141
  className,
2989
3142
  ...viewProps
2990
3143
  }) {
2991
- const [internalCounts, setInternalCounts] = useState9(defaultCounts ?? {});
3144
+ const [internalCounts, setInternalCounts] = useState10(defaultCounts ?? {});
2992
3145
  const counts = controlledCounts ?? internalCounts;
2993
3146
  const total = denominations2.reduce(
2994
3147
  (sum, d) => sum + d.value * (counts[d.value] ?? 0),
@@ -3004,10 +3157,10 @@ function CashCountInput({
3004
3157
  );
3005
3158
  onChangeTotal?.(newTotal);
3006
3159
  };
3007
- return /* @__PURE__ */ jsxs33(View42, { className: cn71("gap-2", className), ...viewProps, children: [
3008
- denominations2.map((d) => /* @__PURE__ */ jsxs33(View42, { className: "flex-row items-center justify-between px-3 py-1", children: [
3009
- /* @__PURE__ */ jsx74(Text26, { className: "w-16 text-sm font-medium text-foreground", children: d.label }),
3010
- /* @__PURE__ */ jsx74(
3160
+ return /* @__PURE__ */ jsxs34(View44, { className: cn73("gap-2", className), ...viewProps, children: [
3161
+ denominations2.map((d) => /* @__PURE__ */ jsxs34(View44, { className: "flex-row items-center justify-between px-3 py-1", children: [
3162
+ /* @__PURE__ */ jsx76(Text27, { className: "w-16 text-sm font-medium text-foreground", children: d.label }),
3163
+ /* @__PURE__ */ jsx76(
3011
3164
  QuantityStepper,
3012
3165
  {
3013
3166
  quantity: counts[d.value] ?? 0,
@@ -3015,9 +3168,9 @@ function CashCountInput({
3015
3168
  onChangeQuantity: (qty) => handleCountChange(d.value, qty)
3016
3169
  }
3017
3170
  ),
3018
- /* @__PURE__ */ jsx74(Text26, { className: "w-20 text-right text-sm text-muted-foreground", children: (d.value * (counts[d.value] ?? 0)).toFixed(2) })
3171
+ /* @__PURE__ */ jsx76(Text27, { className: "w-20 text-right text-sm text-muted-foreground", children: (d.value * (counts[d.value] ?? 0)).toFixed(2) })
3019
3172
  ] }, d.value)),
3020
- /* @__PURE__ */ jsx74(View42, { className: "border-t border-border px-3 pt-2", children: /* @__PURE__ */ jsxs33(Text26, { className: "text-right text-base font-bold text-foreground", children: [
3173
+ /* @__PURE__ */ jsx76(View44, { className: "border-t border-border px-3 pt-2", children: /* @__PURE__ */ jsxs34(Text27, { className: "text-right text-base font-bold text-foreground", children: [
3021
3174
  "Total: ",
3022
3175
  total.toFixed(2)
3023
3176
  ] }) })
@@ -3025,9 +3178,9 @@ function CashCountInput({
3025
3178
  }
3026
3179
 
3027
3180
  // src/register/register-summary.tsx
3028
- import { Text as Text27, View as View43 } from "react-native";
3029
- import { cn as cn72 } from "@tallyui/theme";
3030
- import { jsx as jsx75, jsxs as jsxs34 } from "react/jsx-runtime";
3181
+ import { Text as Text28, View as View45 } from "react-native";
3182
+ import { cn as cn74 } from "@tallyui/theme";
3183
+ import { jsx as jsx77, jsxs as jsxs35 } from "react/jsx-runtime";
3031
3184
  function RegisterSummary({
3032
3185
  expectedCash,
3033
3186
  actualCash,
@@ -3038,37 +3191,37 @@ function RegisterSummary({
3038
3191
  ...viewProps
3039
3192
  }) {
3040
3193
  const discrepancy = actualCash - expectedCash;
3041
- return /* @__PURE__ */ jsxs34(View43, { className: cn72("gap-4 rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
3194
+ return /* @__PURE__ */ jsxs35(View45, { className: cn74("gap-4 rounded-lg border border-border bg-card p-4", className), ...viewProps, children: [
3042
3195
  headerSlot,
3043
- /* @__PURE__ */ jsxs34(View43, { className: "gap-2", children: [
3044
- /* @__PURE__ */ jsx75(Text27, { className: "text-xs font-semibold text-muted-foreground", children: "Cash Drawer" }),
3045
- /* @__PURE__ */ jsxs34(View43, { className: "flex-row justify-between", children: [
3046
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm text-foreground", children: "Expected" }),
3047
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm text-foreground", children: expectedCash.toFixed(2) })
3196
+ /* @__PURE__ */ jsxs35(View45, { className: "gap-2", children: [
3197
+ /* @__PURE__ */ jsx77(Text28, { className: "text-xs font-semibold text-muted-foreground", children: "Cash Drawer" }),
3198
+ /* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between", children: [
3199
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: "Expected" }),
3200
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: expectedCash.toFixed(2) })
3048
3201
  ] }),
3049
- /* @__PURE__ */ jsxs34(View43, { className: "flex-row justify-between", children: [
3050
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm text-foreground", children: "Actual" }),
3051
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm text-foreground", children: actualCash.toFixed(2) })
3202
+ /* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between", children: [
3203
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: "Actual" }),
3204
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: actualCash.toFixed(2) })
3052
3205
  ] }),
3053
- /* @__PURE__ */ jsxs34(View43, { className: "flex-row justify-between border-t border-border pt-1", children: [
3054
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm font-semibold text-foreground", children: "Discrepancy" }),
3055
- /* @__PURE__ */ jsxs34(Text27, { className: cn72("text-sm font-semibold", discrepancy === 0 ? "text-success" : "text-destructive"), children: [
3206
+ /* @__PURE__ */ jsxs35(View45, { className: "flex-row justify-between border-t border-border pt-1", children: [
3207
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm font-semibold text-foreground", children: "Discrepancy" }),
3208
+ /* @__PURE__ */ jsxs35(Text28, { className: cn74("text-sm font-semibold", discrepancy === 0 ? "text-success" : "text-destructive"), children: [
3056
3209
  discrepancy >= 0 ? "" : "-",
3057
3210
  Math.abs(discrepancy).toFixed(2)
3058
3211
  ] })
3059
3212
  ] })
3060
3213
  ] }),
3061
- transactions.length > 0 && /* @__PURE__ */ jsxs34(View43, { className: "gap-2", children: [
3062
- /* @__PURE__ */ jsx75(Text27, { className: "text-xs font-semibold text-muted-foreground", children: "Transactions" }),
3063
- transactions.map((t) => /* @__PURE__ */ jsxs34(View43, { className: "flex-row items-center justify-between", children: [
3064
- /* @__PURE__ */ jsxs34(View43, { className: "gap-0.5", children: [
3065
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm text-foreground", children: t.method }),
3066
- /* @__PURE__ */ jsxs34(Text27, { className: "text-xs text-muted-foreground", children: [
3214
+ transactions.length > 0 && /* @__PURE__ */ jsxs35(View45, { className: "gap-2", children: [
3215
+ /* @__PURE__ */ jsx77(Text28, { className: "text-xs font-semibold text-muted-foreground", children: "Transactions" }),
3216
+ transactions.map((t) => /* @__PURE__ */ jsxs35(View45, { className: "flex-row items-center justify-between", children: [
3217
+ /* @__PURE__ */ jsxs35(View45, { className: "gap-0.5", children: [
3218
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm text-foreground", children: t.method }),
3219
+ /* @__PURE__ */ jsxs35(Text28, { className: "text-xs text-muted-foreground", children: [
3067
3220
  t.count,
3068
3221
  " transactions"
3069
3222
  ] })
3070
3223
  ] }),
3071
- /* @__PURE__ */ jsx75(Text27, { className: "text-sm font-semibold text-foreground", children: t.total.toFixed(2) })
3224
+ /* @__PURE__ */ jsx77(Text28, { className: "text-sm font-semibold text-foreground", children: t.total.toFixed(2) })
3072
3225
  ] }, t.method))
3073
3226
  ] }),
3074
3227
  footerSlot
@@ -3076,9 +3229,9 @@ function RegisterSummary({
3076
3229
  }
3077
3230
 
3078
3231
  // src/register/register-open-close.tsx
3079
- import { Pressable as Pressable20, Text as Text28, View as View44 } from "react-native";
3080
- import { cn as cn73 } from "@tallyui/theme";
3081
- import { jsx as jsx76, jsxs as jsxs35 } from "react/jsx-runtime";
3232
+ import { Pressable as Pressable22, Text as Text29, View as View46 } from "react-native";
3233
+ import { cn as cn75 } from "@tallyui/theme";
3234
+ import { jsx as jsx78, jsxs as jsxs36 } from "react/jsx-runtime";
3082
3235
  function RegisterOpenClose({
3083
3236
  isOpen,
3084
3237
  onOpen,
@@ -3089,20 +3242,20 @@ function RegisterOpenClose({
3089
3242
  className,
3090
3243
  ...viewProps
3091
3244
  }) {
3092
- return /* @__PURE__ */ jsxs35(View44, { className: cn73("gap-4 p-4", className), ...viewProps, children: [
3093
- /* @__PURE__ */ jsx76(Text28, { className: "text-lg font-bold text-foreground", children: isOpen ? "Close Register" : "Open Register" }),
3094
- isOpen && expectedBalance != null && /* @__PURE__ */ jsxs35(View44, { className: "flex-row justify-between rounded-lg bg-muted px-3 py-2", children: [
3095
- /* @__PURE__ */ jsx76(Text28, { className: "text-sm text-muted-foreground", children: "Expected Balance" }),
3096
- /* @__PURE__ */ jsx76(Text28, { className: "text-sm font-semibold text-foreground", children: expectedBalance.toFixed(2) })
3245
+ return /* @__PURE__ */ jsxs36(View46, { className: cn75("gap-4 p-4", className), ...viewProps, children: [
3246
+ /* @__PURE__ */ jsx78(Text29, { className: "text-lg font-bold text-foreground", children: isOpen ? "Close Register" : "Open Register" }),
3247
+ isOpen && expectedBalance != null && /* @__PURE__ */ jsxs36(View46, { className: "flex-row justify-between rounded-lg bg-muted px-3 py-2", children: [
3248
+ /* @__PURE__ */ jsx78(Text29, { className: "text-sm text-muted-foreground", children: "Expected Balance" }),
3249
+ /* @__PURE__ */ jsx78(Text29, { className: "text-sm font-semibold text-foreground", children: expectedBalance.toFixed(2) })
3097
3250
  ] }),
3098
- cashCountSlot && /* @__PURE__ */ jsx76(View44, { children: cashCountSlot }),
3099
- notesSlot && /* @__PURE__ */ jsx76(View44, { children: notesSlot }),
3100
- /* @__PURE__ */ jsx76(
3101
- Pressable20,
3251
+ cashCountSlot && /* @__PURE__ */ jsx78(View46, { children: cashCountSlot }),
3252
+ notesSlot && /* @__PURE__ */ jsx78(View46, { children: notesSlot }),
3253
+ /* @__PURE__ */ jsx78(
3254
+ Pressable22,
3102
3255
  {
3103
3256
  onPress: isOpen ? onClose : onOpen,
3104
3257
  className: "items-center rounded-lg bg-primary px-4 py-3",
3105
- children: /* @__PURE__ */ jsx76(Text28, { className: "text-sm font-semibold text-primary-foreground", children: isOpen ? "Close Register" : "Open Register" })
3258
+ children: /* @__PURE__ */ jsx78(Text29, { className: "text-sm font-semibold text-primary-foreground", children: isOpen ? "Close Register" : "Open Register" })
3106
3259
  }
3107
3260
  )
3108
3261
  ] });
@@ -3110,46 +3263,46 @@ function RegisterOpenClose({
3110
3263
 
3111
3264
  // src/register/register-picker.tsx
3112
3265
  import { ScrollView as ScrollView10 } from "react-native";
3113
- import { jsx as jsx77, jsxs as jsxs36 } from "react/jsx-runtime";
3266
+ import { jsx as jsx79, jsxs as jsxs37 } from "react/jsx-runtime";
3114
3267
  function RegisterPicker({ registers, onPick, className }) {
3115
- return /* @__PURE__ */ jsxs36(Card, { testID: "register-picker", className, children: [
3116
- /* @__PURE__ */ jsx77(CardHeader, { children: /* @__PURE__ */ jsx77(CardTitle, { children: "Choose a register" }) }),
3117
- /* @__PURE__ */ jsx77(CardContent, { children: /* @__PURE__ */ jsxs36(ScrollView10, { children: [
3118
- registers.map((register) => /* @__PURE__ */ jsx77(
3268
+ return /* @__PURE__ */ jsxs37(Card, { testID: "register-picker", className, children: [
3269
+ /* @__PURE__ */ jsx79(CardHeader, { children: /* @__PURE__ */ jsx79(CardTitle, { children: "Choose a register" }) }),
3270
+ /* @__PURE__ */ jsx79(CardContent, { children: /* @__PURE__ */ jsxs37(ScrollView10, { children: [
3271
+ registers.map((register) => /* @__PURE__ */ jsx79(
3119
3272
  Button,
3120
3273
  {
3121
3274
  testID: `register-picker-row-${register.id}`,
3122
3275
  variant: "ghost",
3123
3276
  className: "h-auto min-h-11 items-start justify-start py-2",
3124
3277
  onPress: () => onPick(register.id),
3125
- children: /* @__PURE__ */ jsxs36(VStack, { space: "none", children: [
3126
- /* @__PURE__ */ jsx77(Text, { numberOfLines: 1, children: register.name }),
3127
- /* @__PURE__ */ jsx77(Text, { testID: `register-picker-row-${register.id}-status`, className: "text-muted-foreground text-sm", children: "Not opened" })
3278
+ children: /* @__PURE__ */ jsxs37(VStack, { space: "none", children: [
3279
+ /* @__PURE__ */ jsx79(Text, { numberOfLines: 1, children: register.name }),
3280
+ /* @__PURE__ */ jsx79(Text, { testID: `register-picker-row-${register.id}-status`, className: "text-muted-foreground text-sm", children: "Not opened" })
3128
3281
  ] })
3129
3282
  },
3130
3283
  register.id
3131
3284
  )),
3132
- registers.length === 0 && /* @__PURE__ */ jsx77(Text, { testID: "register-picker-empty", className: "text-muted-foreground p-4", children: "No registers are set up for this store yet." })
3285
+ registers.length === 0 && /* @__PURE__ */ jsx79(Text, { testID: "register-picker-empty", className: "text-muted-foreground p-4", children: "No registers are set up for this store yet." })
3133
3286
  ] }) })
3134
3287
  ] });
3135
3288
  }
3136
3289
 
3137
3290
  // src/register/open-register-card.tsx
3138
- import { useState as useState10 } from "react";
3139
- import { View as View45 } from "react-native";
3291
+ import { useState as useState11 } from "react";
3292
+ import { View as View47 } from "react-native";
3140
3293
  import { parseMinor, validAmount } from "@tallyui/pos";
3141
3294
  import { currencySymbol, formatMoney as formatMoney6, minorUnitDigits as minorUnitDigits3 } from "@tallyui/core";
3142
- import { cn as cn74 } from "@tallyui/theme";
3143
- import { jsx as jsx78, jsxs as jsxs37 } from "react/jsx-runtime";
3295
+ import { cn as cn76 } from "@tallyui/theme";
3296
+ import { jsx as jsx80, jsxs as jsxs38 } from "react/jsx-runtime";
3144
3297
  var AMOUNT_LABEL_ID = "open-register-amount-label";
3145
3298
  function OpenRegisterCard({ register, currency, configuredFloatMinor, className }) {
3146
3299
  const digits = minorUnitDigits3(currency);
3147
3300
  const lastCountedMinor = register.lastClosure?.counted?.cash ?? null;
3148
3301
  const expectedFloatMinor = configuredFloatMinor ?? lastCountedMinor ?? null;
3149
- const [enteredAmount, setEnteredAmount] = useState10(null);
3302
+ const [enteredAmount, setEnteredAmount] = useState11(null);
3150
3303
  const amount = enteredAmount ?? (expectedFloatMinor != null ? decimal(expectedFloatMinor, digits) : "");
3151
- const [busy, setBusy] = useState10(false);
3152
- const [error, setError] = useState10("");
3304
+ const [busy, setBusy] = useState11(false);
3305
+ const [error, setError] = useState11("");
3153
3306
  const valid = validAmount(amount, digits);
3154
3307
  const countedMinor = valid ? parseMinor(amount, digits) : NaN;
3155
3308
  const open = async () => {
@@ -3165,10 +3318,10 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
3165
3318
  }
3166
3319
  };
3167
3320
  const amountLabel = `Cash in the drawer to start (${currencySymbol(currency)})`;
3168
- return /* @__PURE__ */ jsxs37(View45, { testID: "open-register-card", className: cn74("bg-card gap-3 rounded-md p-4", className), children: [
3169
- /* @__PURE__ */ jsx78(Text, { className: "text-lg font-semibold", children: "Open register" }),
3170
- /* @__PURE__ */ jsx78(Label, { testID: "open-register-amount-label", nativeID: AMOUNT_LABEL_ID, children: amountLabel }),
3171
- /* @__PURE__ */ jsx78(Input, { children: /* @__PURE__ */ jsx78(
3321
+ return /* @__PURE__ */ jsxs38(View47, { testID: "open-register-card", className: cn76("bg-card gap-3 rounded-md p-4", className), children: [
3322
+ /* @__PURE__ */ jsx80(Text, { className: "text-lg font-semibold", children: "Open register" }),
3323
+ /* @__PURE__ */ jsx80(Label, { testID: "open-register-amount-label", nativeID: AMOUNT_LABEL_ID, children: amountLabel }),
3324
+ /* @__PURE__ */ jsx80(Input, { children: /* @__PURE__ */ jsx80(
3172
3325
  Input.Field,
3173
3326
  {
3174
3327
  testID: "open-register-amount",
@@ -3179,40 +3332,40 @@ function OpenRegisterCard({ register, currency, configuredFloatMinor, className
3179
3332
  accessibilityLabelledBy: AMOUNT_LABEL_ID
3180
3333
  }
3181
3334
  ) }),
3182
- configuredFloatMinor != null && /* @__PURE__ */ jsx78(
3335
+ configuredFloatMinor != null && /* @__PURE__ */ jsx80(
3183
3336
  Button,
3184
3337
  {
3185
3338
  testID: "open-register-chip-configured",
3186
3339
  variant: "outline",
3187
3340
  className: "min-h-11",
3188
3341
  onPress: () => setEnteredAmount(decimal(configuredFloatMinor, digits)),
3189
- children: /* @__PURE__ */ jsxs37(Text, { children: [
3342
+ children: /* @__PURE__ */ jsxs38(Text, { children: [
3190
3343
  "Use the configured float (",
3191
3344
  formatMoney6({ amount: configuredFloatMinor, currency }),
3192
3345
  ")"
3193
3346
  ] })
3194
3347
  }
3195
3348
  ),
3196
- lastCountedMinor != null && /* @__PURE__ */ jsx78(
3349
+ lastCountedMinor != null && /* @__PURE__ */ jsx80(
3197
3350
  Button,
3198
3351
  {
3199
3352
  testID: "open-register-chip-last",
3200
3353
  variant: "outline",
3201
3354
  className: "min-h-11",
3202
3355
  onPress: () => setEnteredAmount(decimal(lastCountedMinor, digits)),
3203
- children: /* @__PURE__ */ jsxs37(Text, { children: [
3356
+ children: /* @__PURE__ */ jsxs38(Text, { children: [
3204
3357
  "Use the last counted cash (",
3205
3358
  formatMoney6({ amount: lastCountedMinor, currency }),
3206
3359
  ")"
3207
3360
  ] })
3208
3361
  }
3209
3362
  ),
3210
- expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */ jsxs37(Text, { testID: "opening-variance", children: [
3363
+ expectedFloatMinor !== null && valid && countedMinor !== expectedFloatMinor && /* @__PURE__ */ jsxs38(Text, { testID: "opening-variance", children: [
3211
3364
  formatMoney6({ amount: countedMinor - expectedFloatMinor, currency }),
3212
3365
  " vs the expected float"
3213
3366
  ] }),
3214
- !!error && /* @__PURE__ */ jsx78(Text, { className: "text-destructive", children: error }),
3215
- /* @__PURE__ */ jsx78(Button, { testID: "open-register-button", className: "min-h-14", disabled: busy || !valid, onPress: open, children: /* @__PURE__ */ jsx78(Text, { children: busy ? "Opening\u2026" : "Open register" }) })
3367
+ !!error && /* @__PURE__ */ jsx80(Text, { className: "text-destructive", children: error }),
3368
+ /* @__PURE__ */ jsx80(Button, { testID: "open-register-button", className: "min-h-14", disabled: busy || !valid, onPress: open, children: /* @__PURE__ */ jsx80(Text, { children: busy ? "Opening\u2026" : "Open register" }) })
3216
3369
  ] });
3217
3370
  }
3218
3371
  function decimal(minor, digits) {
@@ -3221,8 +3374,8 @@ function decimal(minor, digits) {
3221
3374
  }
3222
3375
 
3223
3376
  // src/register/register-bar.tsx
3224
- import { Pressable as Pressable21, View as View46 } from "react-native";
3225
- import { cn as cn75 } from "@tallyui/theme";
3377
+ import { Pressable as Pressable23, View as View48 } from "react-native";
3378
+ import { cn as cn77 } from "@tallyui/theme";
3226
3379
 
3227
3380
  // src/register/register-bar.helpers.ts
3228
3381
  function describeRegisterBarPill({
@@ -3245,7 +3398,7 @@ function describeRegisterBarPill({
3245
3398
  }
3246
3399
 
3247
3400
  // src/register/register-bar.tsx
3248
- import { jsx as jsx79, jsxs as jsxs38 } from "react/jsx-runtime";
3401
+ import { jsx as jsx81, jsxs as jsxs39 } from "react/jsx-runtime";
3249
3402
  function RegisterBar({
3250
3403
  register,
3251
3404
  registerId,
@@ -3266,10 +3419,10 @@ function RegisterBar({
3266
3419
  sessionsOn: enabled,
3267
3420
  closing
3268
3421
  });
3269
- return /* @__PURE__ */ jsxs38(HStack, { testID: "register-bar", className: cn75("bg-card border-border h-12 border-b px-3", className), children: [
3270
- /* @__PURE__ */ jsx79(View46, { className: "min-w-0 flex-1 shrink", children: multiRegister && registerId !== null && /* @__PURE__ */ jsx79(Text, { testID: "register-bar-name", numberOfLines: 1, children: registerName }) }),
3271
- pill && (onPressPill ? /* @__PURE__ */ jsx79(Pressable21, { testID: "register-bar-pill", accessibilityRole: "button", accessibilityLabel: pill, onPress: onPressPill, children: /* @__PURE__ */ jsx79(Badge, { label: pill, variant: "warning" }) }) : /* @__PURE__ */ jsx79(Badge, { testID: "register-bar-pill", label: pill, variant: "warning" })),
3272
- (session || lastClosure) && /* @__PURE__ */ jsx79(
3422
+ return /* @__PURE__ */ jsxs39(HStack, { testID: "register-bar", className: cn77("bg-card border-border h-12 border-b px-3", className), children: [
3423
+ /* @__PURE__ */ jsx81(View48, { className: "min-w-0 flex-1 shrink", children: multiRegister && registerId !== null && /* @__PURE__ */ jsx81(Text, { testID: "register-bar-name", numberOfLines: 1, children: registerName }) }),
3424
+ pill && (onPressPill ? /* @__PURE__ */ jsx81(Pressable23, { testID: "register-bar-pill", accessibilityRole: "button", accessibilityLabel: pill, onPress: onPressPill, children: /* @__PURE__ */ jsx81(Badge, { label: pill, variant: "warning" }) }) : /* @__PURE__ */ jsx81(Badge, { testID: "register-bar-pill", label: pill, variant: "warning" })),
3425
+ (session || lastClosure) && /* @__PURE__ */ jsx81(
3273
3426
  Button,
3274
3427
  {
3275
3428
  variant: "ghost",
@@ -3277,17 +3430,17 @@ function RegisterBar({
3277
3430
  testID: "register-bar-open-panel",
3278
3431
  accessibilityLabel: "Open register panel",
3279
3432
  onPress: onOpenPanel,
3280
- children: /* @__PURE__ */ jsx79(Text, { className: overdue ? "text-warning" : void 0, children: "Register \u203A" })
3433
+ children: /* @__PURE__ */ jsx81(Text, { className: overdue ? "text-warning" : void 0, children: "Register \u203A" })
3281
3434
  }
3282
3435
  )
3283
3436
  ] });
3284
3437
  }
3285
3438
 
3286
3439
  // src/register/movement-sheet.tsx
3287
- import { useRef as useRef3, useState as useState11 } from "react";
3440
+ import { useRef as useRef3, useState as useState12 } from "react";
3288
3441
  import { movementFieldError, normalizeAmount, parseMinor as parseMinor2 } from "@tallyui/pos";
3289
3442
  import { currencySymbol as currencySymbol2, minorUnitDigits as minorUnitDigits4 } from "@tallyui/core";
3290
- import { Fragment as Fragment3, jsx as jsx80, jsxs as jsxs39 } from "react/jsx-runtime";
3443
+ import { Fragment as Fragment3, jsx as jsx82, jsxs as jsxs40 } from "react/jsx-runtime";
3291
3444
  var LABELS = {
3292
3445
  paid_in: "Paid in",
3293
3446
  paid_out: "Paid out",
@@ -3297,11 +3450,11 @@ var AMOUNT_LABEL_ID2 = "movement-amount-label";
3297
3450
  var REASON_LABEL_ID = "movement-reason-label";
3298
3451
  function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenDrawer }) {
3299
3452
  const digits = minorUnitDigits4(currency);
3300
- const [amount, setAmount] = useState11("");
3301
- const [reason, setReason] = useState11("");
3302
- const [busy, setBusy] = useState11(false);
3453
+ const [amount, setAmount] = useState12("");
3454
+ const [reason, setReason] = useState12("");
3455
+ const [busy, setBusy] = useState12(false);
3303
3456
  const busyRef = useRef3(false);
3304
- const [error, setError] = useState11("");
3457
+ const [error, setError] = useState12("");
3305
3458
  const invalid = movementFieldError({ type, amount, reason });
3306
3459
  const confirm = async () => {
3307
3460
  if (invalid || busyRef.current) return;
@@ -3323,11 +3476,11 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3323
3476
  setBusy(false);
3324
3477
  }
3325
3478
  };
3326
- return /* @__PURE__ */ jsx80(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs39(DialogContent, { testID: "movement-sheet", children: [
3327
- /* @__PURE__ */ jsx80(DialogTitle, { children: LABELS[type] }),
3328
- type !== "no_sale" && /* @__PURE__ */ jsxs39(Fragment3, { children: [
3329
- /* @__PURE__ */ jsx80(Label, { testID: "movement-amount-label", nativeID: AMOUNT_LABEL_ID2, children: `Amount (${currencySymbol2(currency)})` }),
3330
- /* @__PURE__ */ jsx80(Input, { children: /* @__PURE__ */ jsx80(
3479
+ return /* @__PURE__ */ jsx82(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs40(DialogContent, { testID: "movement-sheet", children: [
3480
+ /* @__PURE__ */ jsx82(DialogTitle, { children: LABELS[type] }),
3481
+ type !== "no_sale" && /* @__PURE__ */ jsxs40(Fragment3, { children: [
3482
+ /* @__PURE__ */ jsx82(Label, { testID: "movement-amount-label", nativeID: AMOUNT_LABEL_ID2, children: `Amount (${currencySymbol2(currency)})` }),
3483
+ /* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
3331
3484
  Input.Field,
3332
3485
  {
3333
3486
  testID: "movement-amount",
@@ -3339,8 +3492,8 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3339
3492
  }
3340
3493
  ) })
3341
3494
  ] }),
3342
- /* @__PURE__ */ jsx80(Label, { testID: "movement-reason-label", nativeID: REASON_LABEL_ID, children: "Reason" }),
3343
- /* @__PURE__ */ jsx80(Input, { children: /* @__PURE__ */ jsx80(
3495
+ /* @__PURE__ */ jsx82(Label, { testID: "movement-reason-label", nativeID: REASON_LABEL_ID, children: "Reason" }),
3496
+ /* @__PURE__ */ jsx82(Input, { children: /* @__PURE__ */ jsx82(
3344
3497
  Input.Field,
3345
3498
  {
3346
3499
  testID: "movement-reason",
@@ -3351,20 +3504,20 @@ function MovementSheet({ register, type, currency, onDone, onOpenChange, onOpenD
3351
3504
  accessibilityLabelledBy: REASON_LABEL_ID
3352
3505
  }
3353
3506
  ) }),
3354
- !!error && /* @__PURE__ */ jsx80(Text, { className: "text-destructive", children: error }),
3355
- !!invalid && /* @__PURE__ */ jsx80(Text, { testID: "movement-invalid", className: "text-muted-foreground", children: invalid === "amount" ? "Enter a valid amount." : "Enter a reason." }),
3356
- /* @__PURE__ */ jsx80(Button, { testID: "movement-confirm", disabled: !!invalid || busy, onPress: confirm, children: /* @__PURE__ */ jsx80(Text, { children: busy ? "Recording\u2026" : "Record" }) })
3507
+ !!error && /* @__PURE__ */ jsx82(Text, { className: "text-destructive", children: error }),
3508
+ !!invalid && /* @__PURE__ */ jsx82(Text, { testID: "movement-invalid", className: "text-muted-foreground", children: invalid === "amount" ? "Enter a valid amount." : "Enter a reason." }),
3509
+ /* @__PURE__ */ jsx82(Button, { testID: "movement-confirm", disabled: !!invalid || busy, onPress: confirm, children: /* @__PURE__ */ jsx82(Text, { children: busy ? "Recording\u2026" : "Record" }) })
3357
3510
  ] }) });
3358
3511
  }
3359
3512
 
3360
3513
  // src/register/register-panel.tsx
3361
- import { useState as useState13 } from "react";
3362
- import { ScrollView as ScrollView12, useWindowDimensions as useWindowDimensions2, View as View48 } from "react-native";
3514
+ import { useState as useState14 } from "react";
3515
+ import { ScrollView as ScrollView12, useWindowDimensions as useWindowDimensions2, View as View50 } from "react-native";
3363
3516
  import { formatMoney as formatMoney8 } from "@tallyui/core";
3364
3517
 
3365
3518
  // src/register/register-count.tsx
3366
- import { useEffect as useEffect3, useRef as useRef4, useState as useState12 } from "react";
3367
- import { Platform, Pressable as Pressable22, ScrollView as ScrollView11, useWindowDimensions, View as View47 } from "react-native";
3519
+ import { useEffect as useEffect3, useRef as useRef4, useState as useState13 } from "react";
3520
+ import { Platform, Pressable as Pressable24, ScrollView as ScrollView11, useWindowDimensions, View as View49 } from "react-native";
3368
3521
  import {
3369
3522
  closeNeedsApproval,
3370
3523
  countVariance,
@@ -3376,8 +3529,8 @@ import {
3376
3529
  varianceText
3377
3530
  } from "@tallyui/pos";
3378
3531
  import { currencySymbol as currencySymbol3, formatMoney as formatMoney7, minorUnitDigits as minorUnitDigits5 } from "@tallyui/core";
3379
- import { cn as cn76 } from "@tallyui/theme";
3380
- import { jsx as jsx81, jsxs as jsxs40 } from "react/jsx-runtime";
3532
+ import { cn as cn78 } from "@tallyui/theme";
3533
+ import { jsx as jsx83, jsxs as jsxs41 } from "react/jsx-runtime";
3381
3534
  var AMOUNT_LABEL_ID3 = "count-amount-label";
3382
3535
  var APPROVAL_REQUIRED_TEXT = "Manager approval needed. Ask a manager to approve, or count again.";
3383
3536
  function varianceWord(key) {
@@ -3408,8 +3561,8 @@ function DenominationTile({ value, count: count2, currency, onAdd }) {
3408
3561
  timer.current = void 0;
3409
3562
  };
3410
3563
  useEffect3(() => stop, []);
3411
- return /* @__PURE__ */ jsxs40(
3412
- Pressable22,
3564
+ return /* @__PURE__ */ jsxs41(
3565
+ Pressable24,
3413
3566
  {
3414
3567
  testID: `den-tile-${value}`,
3415
3568
  accessibilityRole: "button",
@@ -3430,8 +3583,8 @@ function DenominationTile({ value, count: count2, currency, onAdd }) {
3430
3583
  if (!held.current) onAdd(1);
3431
3584
  },
3432
3585
  children: [
3433
- /* @__PURE__ */ jsx81(Text, { className: "text-sm tabular-nums", numberOfLines: 1, children: label }),
3434
- /* @__PURE__ */ jsx81(Text, { testID: `den-count-${value}`, className: "bg-background min-w-6 rounded-full px-1.5 text-center text-xs tabular-nums", children: count2 })
3586
+ /* @__PURE__ */ jsx83(Text, { className: "text-sm tabular-nums", numberOfLines: 1, children: label }),
3587
+ /* @__PURE__ */ jsx83(Text, { testID: `den-count-${value}`, className: "bg-background min-w-6 rounded-full px-1.5 text-center text-xs tabular-nums", children: count2 })
3435
3588
  ]
3436
3589
  }
3437
3590
  );
@@ -3442,18 +3595,18 @@ function RegisterCount({ register, currency, approve, className }) {
3442
3595
  const faces = denominations[currency] ?? denominations.default;
3443
3596
  const { width } = useWindowDimensions();
3444
3597
  const columns = width < 480 ? 3 : 4;
3445
- const [pieces, setPieces] = useState12({});
3446
- const [cashText, setCashText] = useState12(
3598
+ const [pieces, setPieces] = useState13({});
3599
+ const [cashText, setCashText] = useState13(
3447
3600
  () => session?.counted?.cash != null ? minorToDecimal(session.counted.cash, digits) : ""
3448
3601
  );
3449
- const [others, setOthers] = useState12(
3602
+ const [others, setOthers] = useState13(
3450
3603
  () => Object.fromEntries(
3451
3604
  Object.entries(session?.counted ?? {}).filter(([method]) => method !== "cash").map(([method, minor]) => [method, minorToDecimal(minor, digits)])
3452
3605
  )
3453
3606
  );
3454
- const [busy, setBusy] = useState12(false);
3455
- const [error, setError] = useState12("");
3456
- const [refusal, setRefusal] = useState12("");
3607
+ const [busy, setBusy] = useState13(false);
3608
+ const [error, setError] = useState13("");
3609
+ const [refusal, setRefusal] = useState13("");
3457
3610
  const usingTiles = Object.keys(pieces).length > 0;
3458
3611
  const tilesTotal = denominationTotal(pieces);
3459
3612
  const displayAmount = usingTiles ? minorToDecimal(tilesTotal, digits) : cashText;
@@ -3501,11 +3654,11 @@ function RegisterCount({ register, currency, approve, className }) {
3501
3654
  void attempt(() => actions.closeSession({ counted }));
3502
3655
  };
3503
3656
  if (!session) return null;
3504
- return /* @__PURE__ */ jsxs40(View47, { testID: "register-count", className: cn76("bg-card flex-1 rounded-md", className), children: [
3505
- /* @__PURE__ */ jsxs40(ScrollView11, { className: "flex-1", contentContainerClassName: "gap-3 p-4", children: [
3506
- /* @__PURE__ */ jsx81(Text, { className: "min-h-11 text-lg font-semibold", children: "Count the drawer" }),
3507
- /* @__PURE__ */ jsx81(Label, { testID: "count-amount-label", nativeID: AMOUNT_LABEL_ID3, children: `Cash counted (${currencySymbol3(currency)})` }),
3508
- /* @__PURE__ */ jsx81(Input, { children: /* @__PURE__ */ jsx81(
3657
+ return /* @__PURE__ */ jsxs41(View49, { testID: "register-count", className: cn78("bg-card flex-1 rounded-md", className), children: [
3658
+ /* @__PURE__ */ jsxs41(ScrollView11, { className: "flex-1", contentContainerClassName: "gap-3 p-4", children: [
3659
+ /* @__PURE__ */ jsx83(Text, { className: "min-h-11 text-lg font-semibold", children: "Count the drawer" }),
3660
+ /* @__PURE__ */ jsx83(Label, { testID: "count-amount-label", nativeID: AMOUNT_LABEL_ID3, children: `Cash counted (${currencySymbol3(currency)})` }),
3661
+ /* @__PURE__ */ jsx83(Input, { children: /* @__PURE__ */ jsx83(
3509
3662
  Input.Field,
3510
3663
  {
3511
3664
  testID: "count-amount",
@@ -3519,16 +3672,16 @@ function RegisterCount({ register, currency, approve, className }) {
3519
3672
  accessibilityLabelledBy: AMOUNT_LABEL_ID3
3520
3673
  }
3521
3674
  ) }),
3522
- !blind && valid && /* @__PURE__ */ jsx81(Text, { testID: "count-variance", className: "min-h-11 tabular-nums", children: `Expected ${formatMoney7({ amount: expected.cash ?? 0, currency })} \xB7 ${varianceText(
3675
+ !blind && valid && /* @__PURE__ */ jsx83(Text, { testID: "count-variance", className: "min-h-11 tabular-nums", children: `Expected ${formatMoney7({ amount: expected.cash ?? 0, currency })} \xB7 ${varianceText(
3523
3676
  variance,
3524
3677
  digits,
3525
3678
  (major) => formatMoney7({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
3526
3679
  varianceWord
3527
3680
  )}` }),
3528
- /* @__PURE__ */ jsxs40(View47, { testID: "count-denominations", className: "gap-2", children: [
3529
- Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */ jsx81(View47, { className: "flex-row gap-2", children: Array.from({ length: columns }, (_2, column) => {
3681
+ /* @__PURE__ */ jsxs41(View49, { testID: "count-denominations", className: "gap-2", children: [
3682
+ Array.from({ length: Math.ceil(faces.length / columns) }, (_, row) => /* @__PURE__ */ jsx83(View49, { className: "flex-row gap-2", children: Array.from({ length: columns }, (_2, column) => {
3530
3683
  const value = faces[row * columns + column];
3531
- return value ? /* @__PURE__ */ jsx81(
3684
+ return value ? /* @__PURE__ */ jsx83(
3532
3685
  DenominationTile,
3533
3686
  {
3534
3687
  value,
@@ -3537,9 +3690,9 @@ function RegisterCount({ register, currency, approve, className }) {
3537
3690
  onAdd: (n) => addPieces(value, n)
3538
3691
  },
3539
3692
  value
3540
- ) : /* @__PURE__ */ jsx81(View47, { className: "flex-1" }, column);
3693
+ ) : /* @__PURE__ */ jsx83(View49, { className: "flex-1" }, column);
3541
3694
  }) }, row)),
3542
- /* @__PURE__ */ jsx81(
3695
+ /* @__PURE__ */ jsx83(
3543
3696
  Button,
3544
3697
  {
3545
3698
  testID: "count-clear",
@@ -3549,16 +3702,16 @@ function RegisterCount({ register, currency, approve, className }) {
3549
3702
  setPieces({});
3550
3703
  setCashText(minorToDecimal(0, digits));
3551
3704
  },
3552
- children: /* @__PURE__ */ jsx81(Text, { children: "Clear" })
3705
+ children: /* @__PURE__ */ jsx83(Text, { children: "Clear" })
3553
3706
  }
3554
3707
  )
3555
3708
  ] }),
3556
3709
  otherMethods.map((method) => {
3557
3710
  const labelId = `count-tender-${method}-label`;
3558
3711
  const label = `${tenderLabel(method)} counted (${currencySymbol3(currency)})`;
3559
- return /* @__PURE__ */ jsxs40(View47, { className: "gap-2", children: [
3560
- /* @__PURE__ */ jsx81(Label, { testID: labelId, nativeID: labelId, children: label }),
3561
- /* @__PURE__ */ jsx81(Input, { children: /* @__PURE__ */ jsx81(
3712
+ return /* @__PURE__ */ jsxs41(View49, { className: "gap-2", children: [
3713
+ /* @__PURE__ */ jsx83(Label, { testID: labelId, nativeID: labelId, children: label }),
3714
+ /* @__PURE__ */ jsx83(Input, { children: /* @__PURE__ */ jsx83(
3562
3715
  Input.Field,
3563
3716
  {
3564
3717
  testID: `count-tender-${method}`,
@@ -3571,11 +3724,11 @@ function RegisterCount({ register, currency, approve, className }) {
3571
3724
  ) })
3572
3725
  ] }, method);
3573
3726
  }),
3574
- !!refusal && /* @__PURE__ */ jsx81(Text, { testID: "count-manager-line", className: "text-warning min-h-11", children: refusal }),
3575
- !!error && /* @__PURE__ */ jsx81(Text, { testID: "count-error", className: "text-destructive min-h-11", children: error })
3727
+ !!refusal && /* @__PURE__ */ jsx83(Text, { testID: "count-manager-line", className: "text-warning min-h-11", children: refusal }),
3728
+ !!error && /* @__PURE__ */ jsx83(Text, { testID: "count-error", className: "text-destructive min-h-11", children: error })
3576
3729
  ] }),
3577
- /* @__PURE__ */ jsxs40(View47, { className: "gap-2 border-t border-border p-4", children: [
3578
- /* @__PURE__ */ jsx81(
3730
+ /* @__PURE__ */ jsxs41(View49, { className: "gap-2 border-t border-border p-4", children: [
3731
+ /* @__PURE__ */ jsx83(
3579
3732
  Button,
3580
3733
  {
3581
3734
  testID: "count-back",
@@ -3583,17 +3736,17 @@ function RegisterCount({ register, currency, approve, className }) {
3583
3736
  className: "min-h-11",
3584
3737
  disabled: busy,
3585
3738
  onPress: () => attempt(actions.backToSelling),
3586
- children: /* @__PURE__ */ jsx81(Text, { children: "Back to selling" })
3739
+ children: /* @__PURE__ */ jsx83(Text, { children: "Back to selling" })
3587
3740
  }
3588
3741
  ),
3589
- /* @__PURE__ */ jsx81(
3742
+ /* @__PURE__ */ jsx83(
3590
3743
  Button,
3591
3744
  {
3592
3745
  testID: "count-close",
3593
3746
  className: "min-h-14",
3594
3747
  disabled: !valid || otherTendersInvalid || busy,
3595
3748
  onPress: onClose,
3596
- children: /* @__PURE__ */ jsx81(Text, { children: busy ? "Closing\u2026" : "Close register" })
3749
+ children: /* @__PURE__ */ jsx83(Text, { children: busy ? "Closing\u2026" : "Close register" })
3597
3750
  }
3598
3751
  )
3599
3752
  ] })
@@ -3601,16 +3754,16 @@ function RegisterCount({ register, currency, approve, className }) {
3601
3754
  }
3602
3755
 
3603
3756
  // src/register/register-panel.tsx
3604
- import { jsx as jsx82, jsxs as jsxs41 } from "react/jsx-runtime";
3757
+ import { jsx as jsx84, jsxs as jsxs42 } from "react/jsx-runtime";
3605
3758
  var DIALOG_VERTICAL_MARGIN = 64;
3606
3759
  function RegisterPanel({ register, currency, registerName, open, onOpenChange, className }) {
3607
3760
  const { session, expected, salesCount, blind, movements, lastClosure, actions } = register;
3608
3761
  const otherTenders = Object.entries(expected).filter(([method, amount]) => method !== "cash" && amount !== 0);
3609
3762
  const { height: windowHeight } = useWindowDimensions2();
3610
3763
  const maxHeight = Math.max(280, windowHeight - DIALOG_VERTICAL_MARGIN);
3611
- const [movementType, setMovementType] = useState13(null);
3612
- const [expanded, setExpanded] = useState13(false);
3613
- const [error, setError] = useState13("");
3764
+ const [movementType, setMovementType] = useState14(null);
3765
+ const [expanded, setExpanded] = useState14(false);
3766
+ const [error, setError] = useState14("");
3614
3767
  const attempt = async (action) => {
3615
3768
  try {
3616
3769
  await action();
@@ -3622,25 +3775,25 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3622
3775
  const activeMovements = movements.filter(
3623
3776
  (row) => row.type !== "void" && !row.voided_by && !movements.some((entry) => entry.voids === row.id)
3624
3777
  );
3625
- return /* @__PURE__ */ jsx82(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs41(
3778
+ return /* @__PURE__ */ jsx84(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs42(
3626
3779
  DialogContent,
3627
3780
  {
3628
3781
  testID: "register-panel",
3629
3782
  className: `flex-col overflow-hidden ${className ?? ""}`,
3630
3783
  style: { maxHeight },
3631
3784
  children: [
3632
- /* @__PURE__ */ jsxs41(View48, { className: "flex-row items-center justify-between gap-2", children: [
3633
- /* @__PURE__ */ jsx82(DialogTitle, { testID: "register-panel-amount", children: registerName ?? "Register" }),
3634
- /* @__PURE__ */ jsx82(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx82(IconButton, { variant: "ghost", size: "sm", testID: "register-panel-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx82(XIcon, { size: 16 }) }) })
3785
+ /* @__PURE__ */ jsxs42(View50, { className: "flex-row items-center justify-between gap-2", children: [
3786
+ /* @__PURE__ */ jsx84(DialogTitle, { testID: "register-panel-amount", children: registerName ?? "Register" }),
3787
+ /* @__PURE__ */ jsx84(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx84(IconButton, { variant: "ghost", size: "sm", testID: "register-panel-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx84(XIcon, { size: 16 }) }) })
3635
3788
  ] }),
3636
- /* @__PURE__ */ jsxs41(Text, { testID: "register-panel-sales-count", children: [
3789
+ /* @__PURE__ */ jsxs42(Text, { testID: "register-panel-sales-count", children: [
3637
3790
  salesCount,
3638
3791
  " sale",
3639
3792
  salesCount === 1 ? "" : "s",
3640
3793
  " this session"
3641
3794
  ] }),
3642
- /* @__PURE__ */ jsxs41(ScrollView12, { testID: "register-panel-body", className: "flex-1", contentContainerClassName: "gap-3", children: [
3643
- /* @__PURE__ */ jsx82(View48, { className: "flex-row gap-2", children: ["paid_in", "paid_out", "no_sale"].map((type) => /* @__PURE__ */ jsx82(
3795
+ /* @__PURE__ */ jsxs42(ScrollView12, { testID: "register-panel-body", className: "flex-1", contentContainerClassName: "gap-3", children: [
3796
+ /* @__PURE__ */ jsx84(View50, { className: "flex-row gap-2", children: ["paid_in", "paid_out", "no_sale"].map((type) => /* @__PURE__ */ jsx84(
3644
3797
  Button,
3645
3798
  {
3646
3799
  testID: `register-panel-${type.replace("_", "-")}`,
@@ -3648,40 +3801,40 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3648
3801
  variant: "outline",
3649
3802
  disabled: session?.status !== "open",
3650
3803
  onPress: () => setMovementType(type),
3651
- children: /* @__PURE__ */ jsx82(Text, { children: type === "paid_in" ? "Paid in" : type === "paid_out" ? "Paid out" : "No sale" })
3804
+ children: /* @__PURE__ */ jsx84(Text, { children: type === "paid_in" ? "Paid in" : type === "paid_out" ? "Paid out" : "No sale" })
3652
3805
  },
3653
3806
  type
3654
3807
  )) }),
3655
- !blind && /* @__PURE__ */ jsxs41(View48, { testID: "register-panel-expected", className: "gap-1", children: [
3656
- /* @__PURE__ */ jsx82(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Expected in the drawer" }),
3657
- Object.entries(expected).filter(([method]) => method === "cash").map(([method, amount]) => /* @__PURE__ */ jsxs41(View48, { className: "min-h-11 flex-row items-center justify-between", children: [
3658
- /* @__PURE__ */ jsx82(Text, { children: tenderLabel("cash") }),
3659
- /* @__PURE__ */ jsx82(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
3808
+ !blind && /* @__PURE__ */ jsxs42(View50, { testID: "register-panel-expected", className: "gap-1", children: [
3809
+ /* @__PURE__ */ jsx84(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Expected in the drawer" }),
3810
+ Object.entries(expected).filter(([method]) => method === "cash").map(([method, amount]) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center justify-between", children: [
3811
+ /* @__PURE__ */ jsx84(Text, { children: tenderLabel("cash") }),
3812
+ /* @__PURE__ */ jsx84(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
3660
3813
  ] }, method))
3661
3814
  ] }),
3662
- !blind && otherTenders.length > 0 && /* @__PURE__ */ jsxs41(View48, { testID: "register-panel-other-tenders", className: "gap-1", children: [
3663
- /* @__PURE__ */ jsx82(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Other tenders" }),
3664
- otherTenders.map(([method, amount]) => /* @__PURE__ */ jsxs41(View48, { className: "min-h-11 flex-row items-center justify-between", children: [
3665
- /* @__PURE__ */ jsx82(Text, { children: tenderLabel(method) }),
3666
- /* @__PURE__ */ jsx82(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
3815
+ !blind && otherTenders.length > 0 && /* @__PURE__ */ jsxs42(View50, { testID: "register-panel-other-tenders", className: "gap-1", children: [
3816
+ /* @__PURE__ */ jsx84(Text, { className: "text-muted-foreground text-sm font-semibold", children: "Other tenders" }),
3817
+ otherTenders.map(([method, amount]) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center justify-between", children: [
3818
+ /* @__PURE__ */ jsx84(Text, { children: tenderLabel(method) }),
3819
+ /* @__PURE__ */ jsx84(Text, { className: "tabular-nums", children: formatMoney8({ amount, currency }) })
3667
3820
  ] }, method))
3668
3821
  ] }),
3669
- /* @__PURE__ */ jsx82(
3822
+ /* @__PURE__ */ jsx84(
3670
3823
  Button,
3671
3824
  {
3672
3825
  testID: "register-panel-movements",
3673
3826
  variant: "ghost",
3674
3827
  className: "min-h-11",
3675
3828
  onPress: () => setExpanded(!expanded),
3676
- children: /* @__PURE__ */ jsx82(Text, { children: "Paid in / out" })
3829
+ children: /* @__PURE__ */ jsx84(Text, { children: "Paid in / out" })
3677
3830
  }
3678
3831
  ),
3679
- expanded && activeMovements.map((row) => /* @__PURE__ */ jsxs41(View48, { className: "min-h-11 flex-row items-center gap-2", children: [
3680
- /* @__PURE__ */ jsxs41(Text, { testID: `movement-row-${row.id}`, className: "flex-1", children: [
3832
+ expanded && activeMovements.map((row) => /* @__PURE__ */ jsxs42(View50, { className: "min-h-11 flex-row items-center gap-2", children: [
3833
+ /* @__PURE__ */ jsxs42(Text, { testID: `movement-row-${row.id}`, className: "flex-1", children: [
3681
3834
  row.type === "paid_in" ? "Paid in" : row.type === "paid_out" ? "Paid out" : "No sale",
3682
3835
  !blind ? ` \xB7 ${formatMoney8({ amount: row.amountMinor, currency })} \xB7 ${row.reason}` : ""
3683
3836
  ] }),
3684
- /* @__PURE__ */ jsx82(
3837
+ /* @__PURE__ */ jsx84(
3685
3838
  Button,
3686
3839
  {
3687
3840
  variant: "ghost",
@@ -3689,12 +3842,12 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3689
3842
  testID: `movement-void-${row.id}`,
3690
3843
  disabled: session?.status !== "open",
3691
3844
  onPress: () => attempt(() => actions.voidMovement(row.id)),
3692
- children: /* @__PURE__ */ jsx82(Text, { children: "Undo" })
3845
+ children: /* @__PURE__ */ jsx84(Text, { children: "Undo" })
3693
3846
  }
3694
3847
  )
3695
3848
  ] }, row.id)),
3696
- !!error && /* @__PURE__ */ jsx82(Text, { className: "text-destructive", children: error }),
3697
- /* @__PURE__ */ jsx82(
3849
+ !!error && /* @__PURE__ */ jsx84(Text, { className: "text-destructive", children: error }),
3850
+ /* @__PURE__ */ jsx84(
3698
3851
  Button,
3699
3852
  {
3700
3853
  testID: "register-panel-close",
@@ -3705,11 +3858,11 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3705
3858
  await actions.startCounting();
3706
3859
  onOpenChange(false);
3707
3860
  }),
3708
- children: /* @__PURE__ */ jsx82(Text, { children: "Close register" })
3861
+ children: /* @__PURE__ */ jsx84(Text, { children: "Close register" })
3709
3862
  }
3710
3863
  )
3711
3864
  ] }),
3712
- movementType && /* @__PURE__ */ jsx82(
3865
+ movementType && /* @__PURE__ */ jsx84(
3713
3866
  MovementSheet,
3714
3867
  {
3715
3868
  register,
@@ -3727,9 +3880,9 @@ function RegisterPanel({ register, currency, registerName, open, onOpenChange, c
3727
3880
  }
3728
3881
 
3729
3882
  // src/register/register-column.tsx
3730
- import { useState as useState14 } from "react";
3731
- import { View as View49 } from "react-native";
3732
- import { Fragment as Fragment4, jsx as jsx83, jsxs as jsxs42 } from "react/jsx-runtime";
3883
+ import { useState as useState15 } from "react";
3884
+ import { View as View51 } from "react-native";
3885
+ import { Fragment as Fragment4, jsx as jsx85, jsxs as jsxs43 } from "react/jsx-runtime";
3733
3886
  function RegisterColumn({
3734
3887
  register,
3735
3888
  registerId,
@@ -3741,30 +3894,30 @@ function RegisterColumn({
3741
3894
  cartEmpty,
3742
3895
  children
3743
3896
  }) {
3744
- const [finishing, setFinishing] = useState14(false);
3897
+ const [finishing, setFinishing] = useState15(false);
3745
3898
  if (registerId === null) {
3746
- return /* @__PURE__ */ jsx83(RegisterPicker, { registers, onPick, className: "flex-1" });
3899
+ return /* @__PURE__ */ jsx85(RegisterPicker, { registers, onPick, className: "flex-1" });
3747
3900
  }
3748
3901
  if (register.session?.status === "closed") {
3749
- return register.closing && !finishing ? /* @__PURE__ */ jsx83(Fragment4, { children: countSlot }) : /* @__PURE__ */ jsx83(FinishClose, { register, busy: finishing, setBusy: setFinishing });
3902
+ return register.closing && !finishing ? /* @__PURE__ */ jsx85(Fragment4, { children: countSlot }) : /* @__PURE__ */ jsx85(FinishClose, { register, busy: finishing, setBusy: setFinishing });
3750
3903
  }
3751
3904
  if (!register.session) {
3752
- return /* @__PURE__ */ jsx83(OpenRegisterCard, { register, currency, configuredFloatMinor, className: "flex-1" });
3905
+ return /* @__PURE__ */ jsx85(OpenRegisterCard, { register, currency, configuredFloatMinor, className: "flex-1" });
3753
3906
  }
3754
3907
  if (register.session.status === "counting") {
3755
- return /* @__PURE__ */ jsx83(Fragment4, { children: countSlot });
3908
+ return /* @__PURE__ */ jsx85(Fragment4, { children: countSlot });
3756
3909
  }
3757
- return /* @__PURE__ */ jsxs42(View49, { testID: "register-column", className: "flex-1", children: [
3758
- register.overdue && cartEmpty && /* @__PURE__ */ jsxs42(View49, { testID: "register-column-overdue", className: "bg-warning/10 flex-row items-center justify-between gap-2 px-3 py-2", children: [
3759
- /* @__PURE__ */ jsx83(Text, { className: "flex-1", children: "This register is overdue for closing." }),
3760
- /* @__PURE__ */ jsx83(
3910
+ return /* @__PURE__ */ jsxs43(View51, { testID: "register-column", className: "flex-1", children: [
3911
+ register.overdue && cartEmpty && /* @__PURE__ */ jsxs43(View51, { testID: "register-column-overdue", className: "bg-warning/10 flex-row items-center justify-between gap-2 px-3 py-2", children: [
3912
+ /* @__PURE__ */ jsx85(Text, { className: "flex-1", children: "This register is overdue for closing." }),
3913
+ /* @__PURE__ */ jsx85(
3761
3914
  Button,
3762
3915
  {
3763
3916
  testID: "register-column-close-overdue",
3764
3917
  variant: "outline",
3765
3918
  className: "min-h-11",
3766
3919
  onPress: () => register.actions.startCounting(),
3767
- children: /* @__PURE__ */ jsx83(Text, { children: "Close register" })
3920
+ children: /* @__PURE__ */ jsx85(Text, { children: "Close register" })
3768
3921
  }
3769
3922
  )
3770
3923
  ] }),
@@ -3772,7 +3925,7 @@ function RegisterColumn({
3772
3925
  ] });
3773
3926
  }
3774
3927
  function FinishClose({ register, busy, setBusy }) {
3775
- const [error, setError] = useState14("");
3928
+ const [error, setError] = useState15("");
3776
3929
  const finish = async () => {
3777
3930
  setBusy(true);
3778
3931
  setError("");
@@ -3784,19 +3937,19 @@ function FinishClose({ register, busy, setBusy }) {
3784
3937
  setBusy(false);
3785
3938
  }
3786
3939
  };
3787
- return /* @__PURE__ */ jsxs42(View49, { testID: "register-column-finish-close", className: "flex-1 gap-3 p-4", children: [
3788
- /* @__PURE__ */ jsx83(Text, { children: "The last close didn't finish." }),
3789
- /* @__PURE__ */ jsx83(Button, { testID: "register-column-finish-close-button", nativeID: "register-column-finish-close-button", disabled: busy, onPress: finish, children: /* @__PURE__ */ jsx83(Text, { children: "Finish closing" }) }),
3790
- !!error && /* @__PURE__ */ jsx83(Text, { testID: "register-column-finish-close-error", className: "text-destructive", children: error })
3940
+ return /* @__PURE__ */ jsxs43(View51, { testID: "register-column-finish-close", className: "flex-1 gap-3 p-4", children: [
3941
+ /* @__PURE__ */ jsx85(Text, { children: "The last close didn't finish." }),
3942
+ /* @__PURE__ */ jsx85(Button, { testID: "register-column-finish-close-button", nativeID: "register-column-finish-close-button", disabled: busy, onPress: finish, children: /* @__PURE__ */ jsx85(Text, { children: "Finish closing" }) }),
3943
+ !!error && /* @__PURE__ */ jsx85(Text, { testID: "register-column-finish-close-error", className: "text-destructive", children: error })
3791
3944
  ] });
3792
3945
  }
3793
3946
 
3794
3947
  // src/register/closure-sheet.tsx
3795
- import { useEffect as useEffect4, useRef as useRef5, useState as useState15 } from "react";
3796
- import { AccessibilityInfo, Animated, View as View50 } from "react-native";
3948
+ import { useEffect as useEffect4, useRef as useRef5, useState as useState16 } from "react";
3949
+ import { AccessibilityInfo, Animated, View as View52 } from "react-native";
3797
3950
  import { countVariance as countVariance2, TAX_ROUNDING_MIXED_NOTE, varianceText as varianceText2 } from "@tallyui/pos";
3798
3951
  import { formatMoney as formatMoney9, minorUnitDigits as minorUnitDigits6 } from "@tallyui/core";
3799
- import { jsx as jsx84, jsxs as jsxs43 } from "react/jsx-runtime";
3952
+ import { jsx as jsx86, jsxs as jsxs44 } from "react/jsx-runtime";
3800
3953
  function useCompletionMotion() {
3801
3954
  const opacity = useRef5(new Animated.Value(0)).current;
3802
3955
  const scale = useRef5(new Animated.Value(0.6)).current;
@@ -3824,8 +3977,8 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3824
3977
  const { lastClosure: closure, blind } = register;
3825
3978
  const digits = minorUnitDigits6(currency);
3826
3979
  const { opacity, scale } = useCompletionMotion();
3827
- const [busy, setBusy] = useState15(false);
3828
- const [error, setError] = useState15("");
3980
+ const [busy, setBusy] = useState16(false);
3981
+ const [error, setError] = useState16("");
3829
3982
  if (!closure) return null;
3830
3983
  const methods = Object.keys(closure.counted);
3831
3984
  const approvedByName = closure.breakdowns.approved_by_name;
@@ -3843,34 +3996,34 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3843
3996
  setBusy(false);
3844
3997
  }
3845
3998
  };
3846
- return /* @__PURE__ */ jsx84(
3999
+ return /* @__PURE__ */ jsx86(
3847
4000
  Dialog,
3848
4001
  {
3849
4002
  open: true,
3850
4003
  onOpenChange: (open) => {
3851
4004
  if (!open) onDone();
3852
4005
  },
3853
- children: /* @__PURE__ */ jsxs43(DialogContent, { testID: "closure-sheet", children: [
3854
- /* @__PURE__ */ jsx84(
4006
+ children: /* @__PURE__ */ jsxs44(DialogContent, { testID: "closure-sheet", children: [
4007
+ /* @__PURE__ */ jsx86(
3855
4008
  Animated.View,
3856
4009
  {
3857
4010
  testID: "closure-check",
3858
4011
  style: { opacity, transform: [{ scale }] },
3859
4012
  className: "bg-success/10 h-10 w-10 items-center justify-center rounded-full",
3860
- children: /* @__PURE__ */ jsx84(Text, { className: "text-success text-lg font-bold", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: "\u2713" })
4013
+ children: /* @__PURE__ */ jsx86(Text, { className: "text-success text-lg font-bold", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: "\u2713" })
3861
4014
  }
3862
4015
  ),
3863
- /* @__PURE__ */ jsx84(DialogTitle, { testID: "closure-title", children: "Register closed" }),
3864
- /* @__PURE__ */ jsx84(Text, { testID: "closure-number", className: "text-muted-foreground min-h-11", children: `Closure #${closure.number}` }),
3865
- !blind && /* @__PURE__ */ jsx84(View50, { testID: "closure-figures", className: "gap-3", children: methods.map((method) => {
4016
+ /* @__PURE__ */ jsx86(DialogTitle, { testID: "closure-title", children: "Register closed" }),
4017
+ /* @__PURE__ */ jsx86(Text, { testID: "closure-number", className: "text-muted-foreground min-h-11", children: `Closure #${closure.number}` }),
4018
+ !blind && /* @__PURE__ */ jsx86(View52, { testID: "closure-figures", className: "gap-3", children: methods.map((method) => {
3866
4019
  const countedMinor = closure.counted[method] ?? 0;
3867
4020
  const expectedMinor = closure.expected[method] ?? 0;
3868
4021
  const varianceMinor = closure.variance[method] ?? countVariance2(countedMinor, expectedMinor);
3869
- return /* @__PURE__ */ jsxs43(View50, { className: "gap-1", children: [
3870
- /* @__PURE__ */ jsx84(Text, { className: "text-muted-foreground text-xs font-semibold", children: tenderLabel(method) }),
3871
- /* @__PURE__ */ jsx84(Text, { testID: `closure-counted-${method}`, className: "min-h-11 tabular-nums", children: `Counted ${formatMoney9({ amount: countedMinor, currency })}` }),
3872
- /* @__PURE__ */ jsx84(Text, { testID: `closure-expected-${method}`, className: "min-h-11 tabular-nums", children: `Expected ${formatMoney9({ amount: expectedMinor, currency })}` }),
3873
- /* @__PURE__ */ jsx84(Text, { testID: `closure-variance-${method}`, className: "min-h-11 tabular-nums", children: varianceText2(
4022
+ return /* @__PURE__ */ jsxs44(View52, { className: "gap-1", children: [
4023
+ /* @__PURE__ */ jsx86(Text, { className: "text-muted-foreground text-xs font-semibold", children: tenderLabel(method) }),
4024
+ /* @__PURE__ */ jsx86(Text, { testID: `closure-counted-${method}`, className: "min-h-11 tabular-nums", children: `Counted ${formatMoney9({ amount: countedMinor, currency })}` }),
4025
+ /* @__PURE__ */ jsx86(Text, { testID: `closure-expected-${method}`, className: "min-h-11 tabular-nums", children: `Expected ${formatMoney9({ amount: expectedMinor, currency })}` }),
4026
+ /* @__PURE__ */ jsx86(Text, { testID: `closure-variance-${method}`, className: "min-h-11 tabular-nums", children: varianceText2(
3874
4027
  varianceMinor,
3875
4028
  digits,
3876
4029
  (major) => formatMoney9({ amount: Math.round(major * 10 ** digits), currency }) ?? "",
@@ -3878,51 +4031,51 @@ function ClosureSheet({ register, currency, onPrint, onDone }) {
3878
4031
  ) })
3879
4032
  ] }, method);
3880
4033
  }) }),
3881
- !!approvedBy && /* @__PURE__ */ jsxs43(Text, { testID: "closure-approved-by", children: [
4034
+ !!approvedBy && /* @__PURE__ */ jsxs44(Text, { testID: "closure-approved-by", children: [
3882
4035
  "Approved by ",
3883
4036
  approvedBy
3884
4037
  ] }),
3885
- closure.breakdowns.tax_rounding_mixed === true && /* @__PURE__ */ jsx84(Text, { testID: "closure-tax-rounding-mixed", className: "text-muted-foreground", children: TAX_ROUNDING_MIXED_NOTE }),
3886
- !!error && /* @__PURE__ */ jsx84(Text, { testID: "closure-print-error", className: "text-destructive", children: error }),
3887
- !blind && !!onPrint && /* @__PURE__ */ jsx84(Button, { testID: "closure-print", className: "min-h-14", disabled: busy, onPress: print, children: /* @__PURE__ */ jsx84(Text, { children: busy ? "Printing\u2026" : "Print the Z report" }) }),
3888
- /* @__PURE__ */ jsx84(Button, { testID: "closure-done", variant: "outline", className: "min-h-14", onPress: onDone, children: /* @__PURE__ */ jsx84(Text, { children: "Done" }) })
4038
+ closure.breakdowns.tax_rounding_mixed === true && /* @__PURE__ */ jsx86(Text, { testID: "closure-tax-rounding-mixed", className: "text-muted-foreground", children: TAX_ROUNDING_MIXED_NOTE }),
4039
+ !!error && /* @__PURE__ */ jsx86(Text, { testID: "closure-print-error", className: "text-destructive", children: error }),
4040
+ !blind && !!onPrint && /* @__PURE__ */ jsx86(Button, { testID: "closure-print", className: "min-h-14", disabled: busy, onPress: print, children: /* @__PURE__ */ jsx86(Text, { children: busy ? "Printing\u2026" : "Print the Z report" }) }),
4041
+ /* @__PURE__ */ jsx86(Button, { testID: "closure-done", variant: "outline", className: "min-h-14", onPress: onDone, children: /* @__PURE__ */ jsx86(Text, { children: "Done" }) })
3889
4042
  ] })
3890
4043
  }
3891
4044
  );
3892
4045
  }
3893
4046
 
3894
4047
  // src/settings/settings-row.tsx
3895
- import { Text as Text29, View as View51 } from "react-native";
3896
- import { cn as cn77 } from "@tallyui/theme";
3897
- import { jsx as jsx85, jsxs as jsxs44 } from "react/jsx-runtime";
4048
+ import { Text as Text30, View as View53 } from "react-native";
4049
+ import { cn as cn79 } from "@tallyui/theme";
4050
+ import { jsx as jsx87, jsxs as jsxs45 } from "react/jsx-runtime";
3898
4051
  function SettingsRow({ label, description, action, className, ...viewProps }) {
3899
- return /* @__PURE__ */ jsxs44(View51, { className: cn77("flex-row items-center gap-3 px-4 py-3", className), ...viewProps, children: [
3900
- /* @__PURE__ */ jsxs44(View51, { className: "flex-1 gap-0.5", children: [
3901
- /* @__PURE__ */ jsx85(Text29, { className: "text-sm font-medium text-foreground", children: label }),
3902
- description && /* @__PURE__ */ jsx85(Text29, { className: "text-xs text-muted-foreground", children: description })
4052
+ return /* @__PURE__ */ jsxs45(View53, { className: cn79("flex-row items-center gap-3 px-4 py-3", className), ...viewProps, children: [
4053
+ /* @__PURE__ */ jsxs45(View53, { className: "flex-1 gap-0.5", children: [
4054
+ /* @__PURE__ */ jsx87(Text30, { className: "text-sm font-medium text-foreground", children: label }),
4055
+ description && /* @__PURE__ */ jsx87(Text30, { className: "text-xs text-muted-foreground", children: description })
3903
4056
  ] }),
3904
- action && /* @__PURE__ */ jsx85(View51, { children: action })
4057
+ action && /* @__PURE__ */ jsx87(View53, { children: action })
3905
4058
  ] });
3906
4059
  }
3907
4060
 
3908
4061
  // src/settings/settings-group.tsx
3909
- import { Text as Text30, View as View52 } from "react-native";
3910
- import { cn as cn78 } from "@tallyui/theme";
3911
- import { jsx as jsx86, jsxs as jsxs45 } from "react/jsx-runtime";
4062
+ import { Text as Text31, View as View54 } from "react-native";
4063
+ import { cn as cn80 } from "@tallyui/theme";
4064
+ import { jsx as jsx88, jsxs as jsxs46 } from "react/jsx-runtime";
3912
4065
  function SettingsGroup({ title, description, children, className, ...viewProps }) {
3913
- return /* @__PURE__ */ jsxs45(View52, { className: cn78("gap-1", className), ...viewProps, children: [
3914
- /* @__PURE__ */ jsxs45(View52, { className: "px-4 py-2", children: [
3915
- /* @__PURE__ */ jsx86(Text30, { className: "text-sm font-semibold text-foreground", children: title }),
3916
- description && /* @__PURE__ */ jsx86(Text30, { className: "text-xs text-muted-foreground", children: description })
4066
+ return /* @__PURE__ */ jsxs46(View54, { className: cn80("gap-1", className), ...viewProps, children: [
4067
+ /* @__PURE__ */ jsxs46(View54, { className: "px-4 py-2", children: [
4068
+ /* @__PURE__ */ jsx88(Text31, { className: "text-sm font-semibold text-foreground", children: title }),
4069
+ description && /* @__PURE__ */ jsx88(Text31, { className: "text-xs text-muted-foreground", children: description })
3917
4070
  ] }),
3918
- /* @__PURE__ */ jsx86(View52, { className: "rounded-lg border border-border bg-card", children })
4071
+ /* @__PURE__ */ jsx88(View54, { className: "rounded-lg border border-border bg-card", children })
3919
4072
  ] });
3920
4073
  }
3921
4074
 
3922
4075
  // src/settings/connector-status.tsx
3923
- import { Text as Text31, View as View53 } from "react-native";
3924
- import { cn as cn79 } from "@tallyui/theme";
3925
- import { jsx as jsx87, jsxs as jsxs46 } from "react/jsx-runtime";
4076
+ import { Text as Text32, View as View55 } from "react-native";
4077
+ import { cn as cn81 } from "@tallyui/theme";
4078
+ import { jsx as jsx89, jsxs as jsxs47 } from "react/jsx-runtime";
3926
4079
  function defaultFormatUnsold(count2, stale) {
3927
4080
  return `${count2} ${count2 === 1 ? "product" : "products"} not sold in this channel${stale ? " (last check failed)" : ""}`;
3928
4081
  }
@@ -3944,34 +4097,34 @@ function ConnectorStatus({
3944
4097
  ...viewProps
3945
4098
  }) {
3946
4099
  const config = STATUS_CONFIG2[status];
3947
- return /* @__PURE__ */ jsxs46(View53, { className: cn79("gap-2 rounded-lg border border-border bg-card p-3", className), ...viewProps, children: [
3948
- /* @__PURE__ */ jsxs46(View53, { className: "flex-row items-center justify-between", children: [
3949
- /* @__PURE__ */ jsx87(Text31, { className: "text-sm font-semibold text-foreground", children: name }),
3950
- /* @__PURE__ */ jsxs46(View53, { className: "flex-row items-center gap-1.5", children: [
3951
- /* @__PURE__ */ jsx87(View53, { className: cn79("h-2 w-2 rounded-full", config.dot) }),
3952
- /* @__PURE__ */ jsx87(Text31, { className: cn79("text-xs font-medium", config.text), children: config.label })
4100
+ return /* @__PURE__ */ jsxs47(View55, { className: cn81("gap-2 rounded-lg border border-border bg-card p-3", className), ...viewProps, children: [
4101
+ /* @__PURE__ */ jsxs47(View55, { className: "flex-row items-center justify-between", children: [
4102
+ /* @__PURE__ */ jsx89(Text32, { className: "text-sm font-semibold text-foreground", children: name }),
4103
+ /* @__PURE__ */ jsxs47(View55, { className: "flex-row items-center gap-1.5", children: [
4104
+ /* @__PURE__ */ jsx89(View55, { className: cn81("h-2 w-2 rounded-full", config.dot) }),
4105
+ /* @__PURE__ */ jsx89(Text32, { className: cn81("text-xs font-medium", config.text), children: config.label })
3953
4106
  ] })
3954
4107
  ] }),
3955
- lastSync && /* @__PURE__ */ jsxs46(Text31, { className: "text-xs text-muted-foreground", children: [
4108
+ lastSync && /* @__PURE__ */ jsxs47(Text32, { className: "text-xs text-muted-foreground", children: [
3956
4109
  "Last sync: ",
3957
4110
  lastSync
3958
4111
  ] }),
3959
- error && /* @__PURE__ */ jsx87(Text31, { className: "text-xs text-destructive", children: error }),
3960
- !!unsoldCount && /* @__PURE__ */ jsx87(Text31, { className: cn79("text-xs", unsoldStale ? "text-muted-foreground" : "text-warning"), children: formatUnsold(unsoldCount, !!unsoldStale) })
4112
+ error && /* @__PURE__ */ jsx89(Text32, { className: "text-xs text-destructive", children: error }),
4113
+ !!unsoldCount && /* @__PURE__ */ jsx89(Text32, { className: cn81("text-xs", unsoldStale ? "text-muted-foreground" : "text-warning"), children: formatUnsold(unsoldCount, !!unsoldStale) })
3961
4114
  ] });
3962
4115
  }
3963
4116
 
3964
4117
  // src/sale/cart.tsx
3965
- import { useState as useState19 } from "react";
3966
- import { Pressable as Pressable26, Text as Text35, View as View57 } from "react-native";
4118
+ import { useState as useState20 } from "react";
4119
+ import { Pressable as Pressable28, Text as Text36, View as View59 } from "react-native";
3967
4120
  import { formatMoney as formatMoney12 } from "@tallyui/core";
3968
4121
  import { buildReceiptData } from "@tallyui/pos";
3969
4122
 
3970
4123
  // src/sale/discount-form.tsx
3971
- import { useState as useState16 } from "react";
3972
- import { Pressable as Pressable23, Text as Text32, TextInput as TextInput9, View as View54 } from "react-native";
4124
+ import { useState as useState17 } from "react";
4125
+ import { Pressable as Pressable25, Text as Text33, TextInput as TextInput9, View as View56 } from "react-native";
3973
4126
  import { formatMoney as formatMoney10, minorUnitDigits as minorUnitDigits7, moneyFromDecimalString as moneyFromDecimalString2 } from "@tallyui/core";
3974
- import { jsx as jsx88, jsxs as jsxs47 } from "react/jsx-runtime";
4127
+ import { jsx as jsx90, jsxs as jsxs48 } from "react/jsx-runtime";
3975
4128
  function parseDiscount(type, text, currency) {
3976
4129
  const raw = text.trim();
3977
4130
  const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
@@ -3988,30 +4141,30 @@ function parseDiscount(type, text, currency) {
3988
4141
  var discountLabel = (discount, currency) => discount.type === "percentage" ? `${discount.value}%` : formatMoney10({ amount: discount.amountMinor, currency }) ?? String(discount.amountMinor);
3989
4142
  var button = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
3990
4143
  function DiscountForm({ title, currency, onApply, onClose }) {
3991
- const [type, setType] = useState16("percentage");
3992
- const [text, setText] = useState16("");
3993
- const [error, setError] = useState16(null);
4144
+ const [type, setType] = useState17("percentage");
4145
+ const [text, setText] = useState17("");
4146
+ const [error, setError] = useState17(null);
3994
4147
  function apply() {
3995
4148
  const parsed = parseDiscount(type, text, currency);
3996
4149
  const refused = typeof parsed === "string" ? parsed : onApply(parsed);
3997
4150
  setError(refused);
3998
4151
  if (refused === null) onClose();
3999
4152
  }
4000
- return /* @__PURE__ */ jsxs47(View54, { role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
4001
- /* @__PURE__ */ jsx88(Text32, { className: "font-semibold text-foreground", children: title }),
4002
- /* @__PURE__ */ jsxs47(View54, { className: "flex-row gap-2", children: [
4003
- ["percentage", "fixed"].map((option) => /* @__PURE__ */ jsx88(
4004
- Pressable23,
4153
+ return /* @__PURE__ */ jsxs48(View56, { role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
4154
+ /* @__PURE__ */ jsx90(Text33, { className: "font-semibold text-foreground", children: title }),
4155
+ /* @__PURE__ */ jsxs48(View56, { className: "flex-row gap-2", children: [
4156
+ ["percentage", "fixed"].map((option) => /* @__PURE__ */ jsx90(
4157
+ Pressable25,
4005
4158
  {
4006
4159
  accessibilityRole: "button",
4007
4160
  accessibilityState: { selected: type === option },
4008
4161
  onPress: () => setType(option),
4009
4162
  className: `${button} ${type === option ? "bg-primary" : "bg-card"}`,
4010
- children: /* @__PURE__ */ jsx88(Text32, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
4163
+ children: /* @__PURE__ */ jsx90(Text33, { className: type === option ? "text-primary-foreground" : "text-foreground", children: option === "percentage" ? "Percent" : "Amount" })
4011
4164
  },
4012
4165
  option
4013
4166
  )),
4014
- /* @__PURE__ */ jsx88(
4167
+ /* @__PURE__ */ jsx90(
4015
4168
  TextInput9,
4016
4169
  {
4017
4170
  accessibilityLabel: "Discount value",
@@ -4024,16 +4177,16 @@ function DiscountForm({ title, currency, onApply, onClose }) {
4024
4177
  }
4025
4178
  )
4026
4179
  ] }),
4027
- error ? /* @__PURE__ */ jsx88(Text32, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4028
- /* @__PURE__ */ jsxs47(View54, { className: "flex-row gap-2", children: [
4029
- /* @__PURE__ */ jsx88(Pressable23, { accessibilityRole: "button", onPress: apply, className: `${button} bg-primary`, children: /* @__PURE__ */ jsx88(Text32, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4030
- /* @__PURE__ */ jsx88(Pressable23, { accessibilityRole: "button", onPress: onClose, className: `${button} bg-card`, children: /* @__PURE__ */ jsx88(Text32, { className: "text-foreground", children: "Cancel" }) })
4180
+ error ? /* @__PURE__ */ jsx90(Text33, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4181
+ /* @__PURE__ */ jsxs48(View56, { className: "flex-row gap-2", children: [
4182
+ /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: apply, className: `${button} bg-primary`, children: /* @__PURE__ */ jsx90(Text33, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4183
+ /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: onClose, className: `${button} bg-card`, children: /* @__PURE__ */ jsx90(Text33, { className: "text-foreground", children: "Cancel" }) })
4031
4184
  ] })
4032
4185
  ] });
4033
4186
  }
4034
4187
  function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] }) {
4035
4188
  if (!discounts.length) return null;
4036
- return /* @__PURE__ */ jsx88(View54, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
4189
+ return /* @__PURE__ */ jsx90(View56, { className: "flex-row flex-wrap gap-2 px-3", children: discounts.map((discount) => {
4037
4190
  const amount = amounts.find((row) => row.discountId === discount.id)?.amountMinor;
4038
4191
  const own = discountLabel(discount, currency);
4039
4192
  const label = [
@@ -4041,16 +4194,16 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
4041
4194
  amount === void 0 ? prefix ? `\u2212${own}` : own : discount.type === "percentage" ? own : null,
4042
4195
  amount === void 0 ? null : `\u2212${formatMoney10({ amount, currency })}`
4043
4196
  ].filter(Boolean).join(" ");
4044
- return /* @__PURE__ */ jsxs47(
4045
- Pressable23,
4197
+ return /* @__PURE__ */ jsxs48(
4198
+ Pressable25,
4046
4199
  {
4047
4200
  accessibilityRole: "button",
4048
4201
  accessibilityLabel: `Remove discount ${label}`,
4049
4202
  onPress: () => onRemove(discount.id),
4050
4203
  className: "min-h-11 flex-row items-center gap-1",
4051
4204
  children: [
4052
- /* @__PURE__ */ jsx88(DiscountBadge, { label, className: "self-center" }),
4053
- /* @__PURE__ */ jsx88(Text32, { className: "text-muted-foreground", children: "\u2715" })
4205
+ /* @__PURE__ */ jsx90(DiscountBadge, { label, className: "self-center" }),
4206
+ /* @__PURE__ */ jsx90(Text33, { className: "text-muted-foreground", children: "\u2715" })
4054
4207
  ]
4055
4208
  },
4056
4209
  discount.id
@@ -4059,10 +4212,10 @@ function DiscountChips({ discounts, currency, onRemove, prefix, amounts = [] })
4059
4212
  }
4060
4213
 
4061
4214
  // src/sale/price-form.tsx
4062
- import { useState as useState17 } from "react";
4063
- import { Pressable as Pressable24, Text as Text33, TextInput as TextInput10, View as View55 } from "react-native";
4215
+ import { useState as useState18 } from "react";
4216
+ import { Pressable as Pressable26, Text as Text34, TextInput as TextInput10, View as View57 } from "react-native";
4064
4217
  import { formatMoney as formatMoney11, minorUnitDigits as minorUnitDigits8, moneyFromDecimalString as moneyFromDecimalString3 } from "@tallyui/core";
4065
- import { jsx as jsx89, jsxs as jsxs48 } from "react/jsx-runtime";
4218
+ import { jsx as jsx91, jsxs as jsxs49 } from "react/jsx-runtime";
4066
4219
  function parsePrice(text, currency) {
4067
4220
  const raw = text.trim();
4068
4221
  const trimmed = raw.split(",").length === 2 ? raw.replace(",", ".") : raw;
@@ -4075,9 +4228,9 @@ function parsePrice(text, currency) {
4075
4228
  }
4076
4229
  var button2 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
4077
4230
  function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
4078
- const [text, setText] = useState17("");
4079
- const [reason, setReason] = useState17("");
4080
- const [error, setError] = useState17(null);
4231
+ const [text, setText] = useState18("");
4232
+ const [reason, setReason] = useState18("");
4233
+ const [error, setError] = useState18(null);
4081
4234
  const title = `Price for ${lineName}`;
4082
4235
  function apply() {
4083
4236
  const parsed = parsePrice(text, currency);
@@ -4085,10 +4238,10 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
4085
4238
  setError(refused);
4086
4239
  if (refused === null) onClose();
4087
4240
  }
4088
- return /* @__PURE__ */ jsxs48(View55, { testID: "price-form", role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
4089
- /* @__PURE__ */ jsx89(Text33, { className: "font-semibold text-foreground", children: title }),
4090
- /* @__PURE__ */ jsx89(Text33, { className: "text-muted-foreground", children: formatMoney11({ amount: currentMinor, currency }) }),
4091
- /* @__PURE__ */ jsx89(
4241
+ return /* @__PURE__ */ jsxs49(View57, { testID: "price-form", role: "group", accessibilityLabel: title, className: "gap-2 px-3 py-2", children: [
4242
+ /* @__PURE__ */ jsx91(Text34, { className: "font-semibold text-foreground", children: title }),
4243
+ /* @__PURE__ */ jsx91(Text34, { className: "text-muted-foreground", children: formatMoney11({ amount: currentMinor, currency }) }),
4244
+ /* @__PURE__ */ jsx91(
4092
4245
  TextInput10,
4093
4246
  {
4094
4247
  testID: "price-input",
@@ -4101,7 +4254,7 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
4101
4254
  className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4102
4255
  }
4103
4256
  ),
4104
- /* @__PURE__ */ jsx89(
4257
+ /* @__PURE__ */ jsx91(
4105
4258
  TextInput10,
4106
4259
  {
4107
4260
  testID: "price-reason",
@@ -4112,26 +4265,26 @@ function PriceForm({ lineName, currency, currentMinor, onApply, onClose }) {
4112
4265
  className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4113
4266
  }
4114
4267
  ),
4115
- error ? /* @__PURE__ */ jsx89(Text33, { testID: "price-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4116
- /* @__PURE__ */ jsxs48(View55, { className: "flex-row gap-2", children: [
4117
- /* @__PURE__ */ jsx89(Pressable24, { testID: "price-apply", accessibilityRole: "button", onPress: apply, className: `${button2} bg-primary`, children: /* @__PURE__ */ jsx89(Text33, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4118
- /* @__PURE__ */ jsx89(Pressable24, { testID: "price-cancel", accessibilityRole: "button", onPress: onClose, className: `${button2} bg-card`, children: /* @__PURE__ */ jsx89(Text33, { className: "text-foreground", children: "Cancel" }) })
4268
+ error ? /* @__PURE__ */ jsx91(Text34, { testID: "price-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4269
+ /* @__PURE__ */ jsxs49(View57, { className: "flex-row gap-2", children: [
4270
+ /* @__PURE__ */ jsx91(Pressable26, { testID: "price-apply", accessibilityRole: "button", onPress: apply, className: `${button2} bg-primary`, children: /* @__PURE__ */ jsx91(Text34, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4271
+ /* @__PURE__ */ jsx91(Pressable26, { testID: "price-cancel", accessibilityRole: "button", onPress: onClose, className: `${button2} bg-card`, children: /* @__PURE__ */ jsx91(Text34, { className: "text-foreground", children: "Cancel" }) })
4119
4272
  ] })
4120
4273
  ] });
4121
4274
  }
4122
4275
 
4123
4276
  // src/sale/charge-form.tsx
4124
- import { useState as useState18 } from "react";
4125
- import { Pressable as Pressable25, Text as Text34, TextInput as TextInput11, View as View56 } from "react-native";
4126
- import { Fragment as Fragment5, jsx as jsx90, jsxs as jsxs49 } from "react/jsx-runtime";
4277
+ import { useState as useState19 } from "react";
4278
+ import { Pressable as Pressable27, Text as Text35, TextInput as TextInput11, View as View58 } from "react-native";
4279
+ import { Fragment as Fragment5, jsx as jsx92, jsxs as jsxs50 } from "react/jsx-runtime";
4127
4280
  var button3 = "rounded-md border border-border px-3 py-2 min-h-11 items-center justify-center";
4128
4281
  function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApply, onClose }) {
4129
- const [kind, setKind] = useState18("fee");
4130
- const [name, setName] = useState18("");
4131
- const [text, setText] = useState18("");
4132
- const [noTax, setNoTax] = useState18(false);
4133
- const [taxClass, setTaxClass] = useState18("");
4134
- const [error, setError] = useState18(null);
4282
+ const [kind, setKind] = useState19("fee");
4283
+ const [name, setName] = useState19("");
4284
+ const [text, setText] = useState19("");
4285
+ const [noTax, setNoTax] = useState19(false);
4286
+ const [taxClass, setTaxClass] = useState19("");
4287
+ const [error, setError] = useState19(null);
4135
4288
  const storeShipping = kind === "shipping" && shippingTaxFromStore;
4136
4289
  function apply() {
4137
4290
  const parsed = parsePrice(text, currency);
@@ -4145,21 +4298,21 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
4145
4298
  setError(refused);
4146
4299
  if (refused === null) onClose();
4147
4300
  }
4148
- return /* @__PURE__ */ jsxs49(View56, { testID: "charge-form", role: "group", accessibilityLabel: "Add charge", className: "gap-2 px-3 py-2", children: [
4149
- /* @__PURE__ */ jsx90(Text34, { className: "font-semibold text-foreground", children: "Add charge" }),
4150
- /* @__PURE__ */ jsx90(View56, { className: "flex-row gap-2", children: ["fee", "shipping", "custom"].map((option) => /* @__PURE__ */ jsx90(
4151
- Pressable25,
4301
+ return /* @__PURE__ */ jsxs50(View58, { testID: "charge-form", role: "group", accessibilityLabel: "Add charge", className: "gap-2 px-3 py-2", children: [
4302
+ /* @__PURE__ */ jsx92(Text35, { className: "font-semibold text-foreground", children: "Add charge" }),
4303
+ /* @__PURE__ */ jsx92(View58, { className: "flex-row gap-2", children: ["fee", "shipping", "custom"].map((option) => /* @__PURE__ */ jsx92(
4304
+ Pressable27,
4152
4305
  {
4153
4306
  accessibilityRole: "button",
4154
4307
  accessibilityState: { selected: kind === option },
4155
4308
  "aria-selected": kind === option,
4156
4309
  onPress: () => setKind(option),
4157
4310
  className: `${button3} ${kind === option ? "bg-primary" : "bg-card"}`,
4158
- children: /* @__PURE__ */ jsx90(Text34, { className: kind === option ? "text-primary-foreground" : "text-foreground", children: option === "fee" ? "Fee" : option === "shipping" ? "Shipping" : "Custom item" })
4311
+ children: /* @__PURE__ */ jsx92(Text35, { className: kind === option ? "text-primary-foreground" : "text-foreground", children: option === "fee" ? "Fee" : option === "shipping" ? "Shipping" : "Custom item" })
4159
4312
  },
4160
4313
  option
4161
4314
  )) }),
4162
- /* @__PURE__ */ jsx90(
4315
+ /* @__PURE__ */ jsx92(
4163
4316
  TextInput11,
4164
4317
  {
4165
4318
  accessibilityLabel: "Name",
@@ -4169,7 +4322,7 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
4169
4322
  className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4170
4323
  }
4171
4324
  ),
4172
- /* @__PURE__ */ jsx90(
4325
+ /* @__PURE__ */ jsx92(
4173
4326
  TextInput11,
4174
4327
  {
4175
4328
  accessibilityLabel: "Amount",
@@ -4181,9 +4334,9 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
4181
4334
  className: "min-w-0 rounded-md border border-border bg-background px-3 py-2 text-foreground"
4182
4335
  }
4183
4336
  ),
4184
- storeShipping ? /* @__PURE__ */ jsx90(Text34, { className: "text-muted-foreground", children: "Shipping is taxed at the store's shipping tax class." }) : /* @__PURE__ */ jsxs49(Fragment5, { children: [
4185
- lineTax?.none ? /* @__PURE__ */ jsx90(
4186
- Pressable25,
4337
+ storeShipping ? /* @__PURE__ */ jsx92(Text35, { className: "text-muted-foreground", children: "Shipping is taxed at the store's shipping tax class." }) : /* @__PURE__ */ jsxs50(Fragment5, { children: [
4338
+ lineTax?.none ? /* @__PURE__ */ jsx92(
4339
+ Pressable27,
4187
4340
  {
4188
4341
  accessibilityRole: "switch",
4189
4342
  accessibilityLabel: "No tax",
@@ -4191,32 +4344,32 @@ function ChargeForm({ currency, lineTax, taxClasses, shippingTaxFromStore, onApp
4191
4344
  "aria-checked": noTax,
4192
4345
  onPress: () => setNoTax(!noTax),
4193
4346
  className: `${button3} ${noTax ? "bg-primary" : "bg-card"}`,
4194
- children: /* @__PURE__ */ jsx90(Text34, { className: noTax ? "text-primary-foreground" : "text-foreground", children: "No tax" })
4347
+ children: /* @__PURE__ */ jsx92(Text35, { className: noTax ? "text-primary-foreground" : "text-foreground", children: "No tax" })
4195
4348
  }
4196
4349
  ) : null,
4197
- lineTax?.classes && taxClasses?.length ? /* @__PURE__ */ jsx90(View56, { role: "group", accessibilityLabel: "Tax class", className: "flex-row flex-wrap gap-2", children: [{ id: "", label: "No class" }, ...taxClasses].map((option) => /* @__PURE__ */ jsx90(
4198
- Pressable25,
4350
+ lineTax?.classes && taxClasses?.length ? /* @__PURE__ */ jsx92(View58, { role: "group", accessibilityLabel: "Tax class", className: "flex-row flex-wrap gap-2", children: [{ id: "", label: "No class" }, ...taxClasses].map((option) => /* @__PURE__ */ jsx92(
4351
+ Pressable27,
4199
4352
  {
4200
4353
  accessibilityRole: "button",
4201
4354
  accessibilityState: { selected: taxClass === option.id },
4202
4355
  "aria-selected": taxClass === option.id,
4203
4356
  onPress: () => setTaxClass(option.id),
4204
4357
  className: `${button3} ${taxClass === option.id ? "bg-primary" : "bg-card"}`,
4205
- children: /* @__PURE__ */ jsx90(Text34, { className: taxClass === option.id ? "text-primary-foreground" : "text-foreground", children: option.label })
4358
+ children: /* @__PURE__ */ jsx92(Text35, { className: taxClass === option.id ? "text-primary-foreground" : "text-foreground", children: option.label })
4206
4359
  },
4207
4360
  option.id
4208
4361
  )) }) : null
4209
4362
  ] }),
4210
- error ? /* @__PURE__ */ jsx90(Text34, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4211
- /* @__PURE__ */ jsxs49(View56, { className: "flex-row gap-2", children: [
4212
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: apply, className: `${button3} bg-primary`, children: /* @__PURE__ */ jsx90(Text34, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4213
- /* @__PURE__ */ jsx90(Pressable25, { accessibilityRole: "button", onPress: onClose, className: `${button3} bg-card`, children: /* @__PURE__ */ jsx90(Text34, { className: "text-foreground", children: "Cancel" }) })
4363
+ error ? /* @__PURE__ */ jsx92(Text35, { accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4364
+ /* @__PURE__ */ jsxs50(View58, { className: "flex-row gap-2", children: [
4365
+ /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: apply, className: `${button3} bg-primary`, children: /* @__PURE__ */ jsx92(Text35, { className: "font-semibold text-primary-foreground", children: "Apply" }) }),
4366
+ /* @__PURE__ */ jsx92(Pressable27, { accessibilityRole: "button", onPress: onClose, className: `${button3} bg-card`, children: /* @__PURE__ */ jsx92(Text35, { className: "text-foreground", children: "Cancel" }) })
4214
4367
  ] })
4215
4368
  ] });
4216
4369
  }
4217
4370
 
4218
4371
  // src/sale/cart.tsx
4219
- import { Fragment as Fragment6, jsx as jsx91, jsxs as jsxs50 } from "react/jsx-runtime";
4372
+ import { Fragment as Fragment6, jsx as jsx93, jsxs as jsxs51 } from "react/jsx-runtime";
4220
4373
  function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPrice = false, onPriceChange, taxClasses }) {
4221
4374
  const { order } = sale;
4222
4375
  const money = (amount) => ({ amount, currency: order.currency });
@@ -4224,9 +4377,9 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4224
4377
  const taxRows = totals.taxLines.map((line) => ({ label: taxLabel(line.ratePpm), amount: money(line.amountMinor) }));
4225
4378
  const display = (lineId) => order.display.lines.find((line) => line.lineId === lineId);
4226
4379
  const orderAmounts = order.discounts.length === 1 ? [{ discountId: order.discounts[0].id, amountMinor: order.display.orderDiscountMinor }] : [];
4227
- const [form, setForm] = useState19(null);
4380
+ const [form, setForm] = useState20(null);
4228
4381
  const chargesOffered = (sale.capabilities?.orderCreate ?? 0) >= 5;
4229
- const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx91(
4382
+ const discountForm = (lineId, title) => form?.type === "discount" && form.lineId === lineId ? /* @__PURE__ */ jsx93(
4230
4383
  DiscountForm,
4231
4384
  {
4232
4385
  title,
@@ -4237,11 +4390,11 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4237
4390
  lineId ?? "order"
4238
4391
  ) : null;
4239
4392
  const pay = `min-h-12 flex-1 justify-center rounded-md bg-primary px-4 py-3 ${!order.lineItems.length ? "opacity-50" : ""}`;
4240
- const renderItem = (line) => /* @__PURE__ */ jsxs50(Fragment6, { children: [
4241
- /* @__PURE__ */ jsx91(CartLineActions, { actions: [
4393
+ const renderItem = (line) => /* @__PURE__ */ jsxs51(Fragment6, { children: [
4394
+ /* @__PURE__ */ jsx93(CartLineActions, { actions: [
4242
4395
  { id: "discount", label: "Discount", color: "text-primary", onPress: () => setForm({ type: "discount", lineId: line.id }) },
4243
4396
  ...canEditPrice ? [{ id: "price", label: "Price", color: "text-primary", onPress: () => setForm({ type: "price", lineId: line.id }) }] : []
4244
- ], children: /* @__PURE__ */ jsx91(
4397
+ ], children: /* @__PURE__ */ jsx93(
4245
4398
  CartLine,
4246
4399
  {
4247
4400
  name: line.name,
@@ -4250,41 +4403,41 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4250
4403
  lineTotal: money(display(line.id).amountMinor)
4251
4404
  }
4252
4405
  ) }),
4253
- /* @__PURE__ */ jsx91(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
4254
- /* @__PURE__ */ jsxs50(View57, { className: "flex-row gap-4 px-3 py-2", children: [
4255
- /* @__PURE__ */ jsx91(
4256
- Pressable26,
4406
+ /* @__PURE__ */ jsx93(DiscountChips, { discounts: line.discounts, amounts: display(line.id).discounts, currency: order.currency, onRemove: sale.removeDiscount }),
4407
+ /* @__PURE__ */ jsxs51(View59, { className: "flex-row gap-4 px-3 py-2", children: [
4408
+ /* @__PURE__ */ jsx93(
4409
+ Pressable28,
4257
4410
  {
4258
4411
  accessibilityRole: "button",
4259
4412
  accessibilityLabel: `Decrease ${line.name}`,
4260
4413
  onPress: () => sale.setQuantity(line.id, line.quantity - 1),
4261
4414
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4262
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "\u2212" })
4415
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "\u2212" })
4263
4416
  }
4264
4417
  ),
4265
- /* @__PURE__ */ jsx91(
4266
- Pressable26,
4418
+ /* @__PURE__ */ jsx93(
4419
+ Pressable28,
4267
4420
  {
4268
4421
  accessibilityRole: "button",
4269
4422
  accessibilityLabel: `Increase ${line.name}`,
4270
4423
  onPress: () => sale.setQuantity(line.id, line.quantity + 1),
4271
4424
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4272
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "+" })
4425
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "+" })
4273
4426
  }
4274
4427
  ),
4275
- /* @__PURE__ */ jsx91(
4276
- Pressable26,
4428
+ /* @__PURE__ */ jsx93(
4429
+ Pressable28,
4277
4430
  {
4278
4431
  accessibilityRole: "button",
4279
4432
  accessibilityLabel: `Remove ${line.name}`,
4280
4433
  onPress: () => sale.remove(line.id),
4281
4434
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 min-w-11 items-center justify-center",
4282
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-center text-foreground", children: "Remove" })
4435
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-center text-foreground", children: "Remove" })
4283
4436
  }
4284
4437
  )
4285
4438
  ] }),
4286
4439
  discountForm(line.id, `Discount on ${line.name}`),
4287
- canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx91(
4440
+ canEditPrice && form?.type === "price" && form.lineId === line.id ? /* @__PURE__ */ jsx93(
4288
4441
  PriceForm,
4289
4442
  {
4290
4443
  lineName: line.name,
@@ -4301,31 +4454,31 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4301
4454
  line.id
4302
4455
  ) : null
4303
4456
  ] });
4304
- return /* @__PURE__ */ jsx91(
4457
+ return /* @__PURE__ */ jsx93(
4305
4458
  CartPanel,
4306
4459
  {
4307
4460
  dataSet: { print: "hide" },
4308
4461
  items: order.lineItems,
4309
4462
  renderItem,
4310
- emptyState: /* @__PURE__ */ jsx91(Text35, { testID: "cart-empty", className: "px-3 py-2 text-muted-foreground", children: "Scan or tap a product to start a sale." }),
4311
- afterItems: /* @__PURE__ */ jsxs50(Fragment6, { children: [
4312
- ["fees", "shipping"].map((kind) => order[kind]?.map((charge, index) => /* @__PURE__ */ jsxs50(View57, { testID: `cart-${kind === "fees" ? "fee" : "shipping"}-${index}`, className: "flex-row items-center gap-3 px-3 py-2", children: [
4313
- /* @__PURE__ */ jsx91(Text35, { className: "flex-1 text-foreground", children: charge.name }),
4314
- /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: formatMoney12(money(order.display[kind].find((row) => row.id === charge.id).amountMinor)) }),
4315
- /* @__PURE__ */ jsx91(
4316
- Pressable26,
4463
+ emptyState: /* @__PURE__ */ jsx93(Text36, { testID: "cart-empty", className: "px-3 py-2 text-muted-foreground", children: "Scan or tap a product to start a sale." }),
4464
+ afterItems: /* @__PURE__ */ jsxs51(Fragment6, { children: [
4465
+ ["fees", "shipping"].map((kind) => order[kind]?.map((charge, index) => /* @__PURE__ */ jsxs51(View59, { testID: `cart-${kind === "fees" ? "fee" : "shipping"}-${index}`, className: "flex-row items-center gap-3 px-3 py-2", children: [
4466
+ /* @__PURE__ */ jsx93(Text36, { className: "flex-1 text-foreground", children: charge.name }),
4467
+ /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: formatMoney12(money(order.display[kind].find((row) => row.id === charge.id).amountMinor)) }),
4468
+ /* @__PURE__ */ jsx93(
4469
+ Pressable28,
4317
4470
  {
4318
4471
  accessibilityRole: "button",
4319
4472
  accessibilityLabel: `Remove ${charge.name}`,
4320
4473
  onPress: () => kind === "fees" ? sale.removeFee(charge.id) : sale.removeShipping(charge.id),
4321
4474
  className: "rounded-md border border-border bg-card px-3 py-2 min-h-11 items-center justify-center",
4322
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Remove" })
4475
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Remove" })
4323
4476
  }
4324
4477
  )
4325
4478
  ] }, charge.id))),
4326
- order.lineItems.length || chargesOffered ? /* @__PURE__ */ jsxs50(View57, { className: "gap-3 px-3 py-2", children: [
4327
- order.lineItems.length ? /* @__PURE__ */ jsxs50(Fragment6, { children: [
4328
- /* @__PURE__ */ jsx91(
4479
+ order.lineItems.length || chargesOffered ? /* @__PURE__ */ jsxs51(View59, { className: "gap-3 px-3 py-2", children: [
4480
+ order.lineItems.length ? /* @__PURE__ */ jsxs51(Fragment6, { children: [
4481
+ /* @__PURE__ */ jsx93(
4329
4482
  DiscountChips,
4330
4483
  {
4331
4484
  discounts: order.discounts,
@@ -4335,17 +4488,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4335
4488
  prefix: "Order discount"
4336
4489
  }
4337
4490
  ),
4338
- form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx91(
4339
- Pressable26,
4491
+ form?.type === "discount" && form.lineId === null ? discountForm(null, "Order discount") : /* @__PURE__ */ jsx93(
4492
+ Pressable28,
4340
4493
  {
4341
4494
  accessibilityRole: "button",
4342
4495
  onPress: () => setForm({ type: "discount", lineId: null }),
4343
4496
  className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
4344
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Order discount" })
4497
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Order discount" })
4345
4498
  }
4346
4499
  )
4347
4500
  ] }) : null,
4348
- chargesOffered ? form?.type === "charge" ? /* @__PURE__ */ jsx91(
4501
+ chargesOffered ? form?.type === "charge" ? /* @__PURE__ */ jsx93(
4349
4502
  ChargeForm,
4350
4503
  {
4351
4504
  currency: order.currency,
@@ -4358,19 +4511,19 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4358
4511
  return typeof result === "string" ? result : null;
4359
4512
  }
4360
4513
  }
4361
- ) : /* @__PURE__ */ jsx91(
4362
- Pressable26,
4514
+ ) : /* @__PURE__ */ jsx93(
4515
+ Pressable28,
4363
4516
  {
4364
4517
  accessibilityRole: "button",
4365
4518
  onPress: () => setForm({ type: "charge" }),
4366
4519
  className: "self-start rounded-md border border-border bg-card px-4 py-2 min-h-11 justify-center",
4367
- children: /* @__PURE__ */ jsx91(Text35, { className: "text-foreground", children: "Add charge" })
4520
+ children: /* @__PURE__ */ jsx93(Text36, { className: "text-foreground", children: "Add charge" })
4368
4521
  }
4369
4522
  ) : null
4370
4523
  ] }) : null
4371
4524
  ] }),
4372
- footer: /* @__PURE__ */ jsxs50(View57, { testID: "cart-footer", className: "gap-3 pb-4", children: [
4373
- /* @__PURE__ */ jsx91(
4525
+ footer: /* @__PURE__ */ jsxs51(View59, { testID: "cart-footer", className: "gap-3 pb-4", children: [
4526
+ /* @__PURE__ */ jsx93(
4374
4527
  CartTotal,
4375
4528
  {
4376
4529
  subtotal: money(totals.subtotalMinor),
@@ -4380,10 +4533,10 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4380
4533
  taxInclusive: totals.taxInclusive
4381
4534
  }
4382
4535
  ),
4383
- sale.error ? /* @__PURE__ */ jsx91(Text35, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4384
- /* @__PURE__ */ jsxs50(View57, { className: "flex-row gap-3", children: [
4385
- /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx91(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
4386
- /* @__PURE__ */ jsx91(Pressable26, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx91(Text35, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
4536
+ sale.error ? /* @__PURE__ */ jsx93(Text36, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4537
+ /* @__PURE__ */ jsxs51(View59, { className: "flex-row gap-3", children: [
4538
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("cash"), className: pay, children: /* @__PURE__ */ jsx93(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Cash" }) }),
4539
+ /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: !order.lineItems.length, onPress: () => sale.startTender("external"), className: pay, children: /* @__PURE__ */ jsx93(Text36, { className: "text-center font-semibold text-primary-foreground", children: "Card terminal" }) })
4387
4540
  ] })
4388
4541
  ] })
4389
4542
  }
@@ -4391,17 +4544,17 @@ function Cart({ sale, taxLabel = (ratePpm) => `Tax ${ratePpm / 1e4}%`, canEditPr
4391
4544
  }
4392
4545
 
4393
4546
  // src/sale/cart-bar.tsx
4394
- import { Pressable as Pressable27, Text as Text36 } from "react-native";
4547
+ import { Pressable as Pressable29, Text as Text37 } from "react-native";
4395
4548
  import { formatMoney as formatMoney13 } from "@tallyui/core";
4396
4549
  import { buildReceiptData as buildReceiptData2 } from "@tallyui/pos";
4397
- import { jsx as jsx92, jsxs as jsxs51 } from "react/jsx-runtime";
4550
+ import { jsx as jsx94, jsxs as jsxs52 } from "react/jsx-runtime";
4398
4551
  function CartBar({ sale, onOpen }) {
4399
4552
  const { order } = sale;
4400
4553
  const count2 = order.lineItems.reduce((sum, line) => sum + line.quantity, 0);
4401
4554
  const total = formatMoney13({ amount: buildReceiptData2(order, { storeName: "" }).totals.totalMinor, currency: order.currency });
4402
4555
  const items = `${count2} ${count2 === 1 ? "item" : "items"}`;
4403
- return /* @__PURE__ */ jsxs51(
4404
- Pressable27,
4556
+ return /* @__PURE__ */ jsxs52(
4557
+ Pressable29,
4405
4558
  {
4406
4559
  accessibilityRole: "button",
4407
4560
  accessibilityLabel: count2 ? `Open cart, ${items}, ${total}` : "Cart is empty",
@@ -4409,8 +4562,8 @@ function CartBar({ sale, onOpen }) {
4409
4562
  onPress: onOpen,
4410
4563
  className: `min-h-14 mx-3 mb-3 flex-row items-center justify-between rounded-md bg-primary px-4 py-3 ${count2 ? "" : "opacity-50"}`,
4411
4564
  children: [
4412
- /* @__PURE__ */ jsx92(Text36, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
4413
- count2 ? /* @__PURE__ */ jsxs51(Text36, { className: "font-bold text-primary-foreground", children: [
4565
+ /* @__PURE__ */ jsx94(Text37, { className: "font-bold text-primary-foreground", children: count2 ? `Cart \xB7 ${items}` : "Cart is empty" }),
4566
+ count2 ? /* @__PURE__ */ jsxs52(Text37, { className: "font-bold text-primary-foreground", children: [
4414
4567
  total,
4415
4568
  " \u203A"
4416
4569
  ] }) : null
@@ -4420,17 +4573,17 @@ function CartBar({ sale, onOpen }) {
4420
4573
  }
4421
4574
 
4422
4575
  // src/sale/tender.tsx
4423
- import { Pressable as Pressable28, Text as Text37, TextInput as TextInput12, View as View58 } from "react-native";
4576
+ import { Pressable as Pressable30, Text as Text38, TextInput as TextInput12, View as View60 } from "react-native";
4424
4577
  import { formatMoney as formatMoney14 } from "@tallyui/core";
4425
- import { Fragment as Fragment7, jsx as jsx93, jsxs as jsxs52 } from "react/jsx-runtime";
4578
+ import { Fragment as Fragment7, jsx as jsx95, jsxs as jsxs53 } from "react/jsx-runtime";
4426
4579
  var REFERENCE_MAX = 255;
4427
4580
  function Tender({ sale }) {
4428
4581
  const { order, stage } = sale;
4429
4582
  if (stage.kind !== "tender") return null;
4430
4583
  const money = (amount) => ({ amount, currency: order.currency });
4431
- return /* @__PURE__ */ jsxs52(View58, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4432
- stage.method === "cash" ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4433
- /* @__PURE__ */ jsx93(
4584
+ return /* @__PURE__ */ jsxs53(View60, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4585
+ stage.method === "cash" ? /* @__PURE__ */ jsxs53(Fragment7, { children: [
4586
+ /* @__PURE__ */ jsx95(
4434
4587
  CashTendered,
4435
4588
  {
4436
4589
  total: money(order.totalMinor),
@@ -4438,18 +4591,18 @@ function Tender({ sale }) {
4438
4591
  onChangeAmount: (amount) => sale.setTender({ method: "cash", amountMinor: amount.amount })
4439
4592
  }
4440
4593
  ),
4441
- /* @__PURE__ */ jsx93(ChangeDisplay, { change: money(order.changeDueMinor) }),
4442
- order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4594
+ /* @__PURE__ */ jsx95(ChangeDisplay, { change: money(order.changeDueMinor) }),
4595
+ order.balanceDueMinor > 0 ? /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4443
4596
  "Balance due: ",
4444
4597
  formatMoney14(money(order.balanceDueMinor))
4445
4598
  ] }) : null,
4446
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", disabled: order.balanceDueMinor > 0, onPress: sale.complete, className: `rounded-md bg-primary px-4 py-3 ${order.balanceDueMinor > 0 ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4447
- ] }) : /* @__PURE__ */ jsxs52(Fragment7, { children: [
4448
- /* @__PURE__ */ jsxs52(Text37, { className: "text-foreground", children: [
4599
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", disabled: order.balanceDueMinor > 0, onPress: sale.complete, className: `rounded-md bg-primary px-4 py-3 ${order.balanceDueMinor > 0 ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" }) })
4600
+ ] }) : /* @__PURE__ */ jsxs53(Fragment7, { children: [
4601
+ /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4449
4602
  "Card terminal: ",
4450
4603
  formatMoney14(money(order.totalMinor))
4451
4604
  ] }),
4452
- /* @__PURE__ */ jsx93(
4605
+ /* @__PURE__ */ jsx95(
4453
4606
  TextInput12,
4454
4607
  {
4455
4608
  accessibilityLabel: "Terminal reference",
@@ -4460,28 +4613,28 @@ function Tender({ sale }) {
4460
4613
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4461
4614
  }
4462
4615
  ),
4463
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4616
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: sale.complete, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Payment approved on terminal" }) })
4464
4617
  ] }),
4465
- sale.error ? /* @__PURE__ */ jsx93(Text37, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4466
- sale.canContinue ? /* @__PURE__ */ jsxs52(Fragment7, { children: [
4467
- /* @__PURE__ */ jsx93(Text37, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4468
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4618
+ sale.error ? /* @__PURE__ */ jsx95(Text38, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4619
+ sale.canContinue ? /* @__PURE__ */ jsxs53(Fragment7, { children: [
4620
+ /* @__PURE__ */ jsx95(Text38, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4621
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4469
4622
  ] }) : null,
4470
- /* @__PURE__ */ jsx93(Pressable28, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx93(Text37, { className: "text-center text-foreground", children: "Back" }) })
4623
+ /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx95(Text38, { className: "text-center text-foreground", children: "Back" }) })
4471
4624
  ] });
4472
4625
  }
4473
4626
 
4474
4627
  // src/sale/split-tender.tsx
4475
- import { useState as useState20 } from "react";
4476
- import { Pressable as Pressable29, Text as Text38, TextInput as TextInput13, View as View59 } from "react-native";
4628
+ import { useState as useState21 } from "react";
4629
+ import { Pressable as Pressable31, Text as Text39, TextInput as TextInput13, View as View61 } from "react-native";
4477
4630
  import { formatMoney as formatMoney15, minorUnitDigits as minorUnitDigits9 } from "@tallyui/core";
4478
- import { Fragment as Fragment8, jsx as jsx94, jsxs as jsxs53 } from "react/jsx-runtime";
4631
+ import { Fragment as Fragment8, jsx as jsx96, jsxs as jsxs54 } from "react/jsx-runtime";
4479
4632
  function SplitTender({ sale }) {
4480
4633
  const { order, stage } = sale;
4481
- const [method, setMethod] = useState20("cash");
4482
- const [amount, setAmount] = useState20(null);
4483
- const [reference, setReference] = useState20("");
4484
- const [error, setError] = useState20(null);
4634
+ const [method, setMethod] = useState21("cash");
4635
+ const [amount, setAmount] = useState21(null);
4636
+ const [reference, setReference] = useState21("");
4637
+ const [error, setError] = useState21(null);
4485
4638
  if (stage.kind !== "tender") return null;
4486
4639
  const money = (value) => formatMoney15({ amount: value, currency: order.currency });
4487
4640
  const digits = minorUnitDigits9(order.currency);
@@ -4506,58 +4659,58 @@ function SplitTender({ sale }) {
4506
4659
  setReference("");
4507
4660
  setAmount(null);
4508
4661
  }
4509
- return /* @__PURE__ */ jsxs53(View59, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4510
- /* @__PURE__ */ jsxs53(View59, { testID: "split-tender-summary", className: "gap-2", children: [
4511
- /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4662
+ return /* @__PURE__ */ jsxs54(View61, { dataSet: { print: "hide" }, className: "gap-4 p-4", children: [
4663
+ /* @__PURE__ */ jsxs54(View61, { testID: "split-tender-summary", className: "gap-2", children: [
4664
+ /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
4512
4665
  "Total: ",
4513
4666
  money(order.totalMinor)
4514
4667
  ] }),
4515
- /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4668
+ /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
4516
4669
  "Paid: ",
4517
4670
  money(order.paidMinor)
4518
4671
  ] }),
4519
- /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4672
+ /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
4520
4673
  "Remaining: ",
4521
4674
  money(order.balanceDueMinor)
4522
4675
  ] }),
4523
- order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4676
+ order.changeDueMinor > 0 ? /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
4524
4677
  "Change: ",
4525
4678
  money(order.changeDueMinor)
4526
4679
  ] }) : null
4527
4680
  ] }),
4528
- /* @__PURE__ */ jsx94(View59, { testID: "split-tender-list", className: "gap-2", children: order.payments.map((payment) => /* @__PURE__ */ jsxs53(View59, { testID: `split-tender-row-${payment.id}`, className: "gap-2", children: [
4529
- /* @__PURE__ */ jsxs53(Text38, { className: "text-foreground", children: [
4681
+ /* @__PURE__ */ jsx96(View61, { testID: "split-tender-list", className: "gap-2", children: order.payments.map((payment) => /* @__PURE__ */ jsxs54(View61, { testID: `split-tender-row-${payment.id}`, className: "gap-2", children: [
4682
+ /* @__PURE__ */ jsxs54(Text39, { className: "text-foreground", children: [
4530
4683
  tenderLabel(payment.method),
4531
4684
  " ",
4532
4685
  money(payment.amountMinor)
4533
4686
  ] }),
4534
- payment.reference ? /* @__PURE__ */ jsx94(Text38, { className: "text-foreground", children: payment.reference }) : null,
4535
- /* @__PURE__ */ jsx94(
4536
- Pressable29,
4687
+ payment.reference ? /* @__PURE__ */ jsx96(Text39, { className: "text-foreground", children: payment.reference }) : null,
4688
+ /* @__PURE__ */ jsx96(
4689
+ Pressable31,
4537
4690
  {
4538
4691
  testID: `split-tender-remove-${payment.id}`,
4539
4692
  accessibilityRole: "button",
4540
4693
  accessibilityLabel: "Remove tender",
4541
4694
  onPress: () => sale.removeTender(payment.id),
4542
4695
  className: "rounded-md border border-border bg-card px-4 py-3",
4543
- children: /* @__PURE__ */ jsx94(Text38, { className: "text-center text-foreground", children: "Remove" })
4696
+ children: /* @__PURE__ */ jsx96(Text39, { className: "text-center text-foreground", children: "Remove" })
4544
4697
  }
4545
4698
  )
4546
4699
  ] }, payment.id)) }),
4547
- /* @__PURE__ */ jsxs53(View59, { testID: "split-tender-add", className: "gap-2", children: [
4548
- /* @__PURE__ */ jsx94(View59, { className: "flex-row gap-2", children: ["cash", "external"].map((value) => /* @__PURE__ */ jsx94(
4549
- Pressable29,
4700
+ /* @__PURE__ */ jsxs54(View61, { testID: "split-tender-add", className: "gap-2", children: [
4701
+ /* @__PURE__ */ jsx96(View61, { className: "flex-row gap-2", children: ["cash", "external"].map((value) => /* @__PURE__ */ jsx96(
4702
+ Pressable31,
4550
4703
  {
4551
4704
  testID: `split-tender-method-${value === "cash" ? "cash" : "card"}`,
4552
4705
  accessibilityRole: "button",
4553
4706
  accessibilityState: { selected: method === value },
4554
4707
  onPress: () => setMethod(value),
4555
4708
  className: `rounded-md border border-border px-4 py-3 ${method === value ? "bg-primary" : "bg-card"}`,
4556
- children: /* @__PURE__ */ jsx94(Text38, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
4709
+ children: /* @__PURE__ */ jsx96(Text39, { className: `text-center ${method === value ? "text-primary-foreground" : "text-foreground"}`, children: tenderLabel(value) })
4557
4710
  },
4558
4711
  value
4559
4712
  )) }),
4560
- /* @__PURE__ */ jsx94(
4713
+ /* @__PURE__ */ jsx96(
4561
4714
  TextInput13,
4562
4715
  {
4563
4716
  testID: "split-tender-amount",
@@ -4568,7 +4721,7 @@ function SplitTender({ sale }) {
4568
4721
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4569
4722
  }
4570
4723
  ),
4571
- method === "external" ? /* @__PURE__ */ jsx94(
4724
+ method === "external" ? /* @__PURE__ */ jsx96(
4572
4725
  TextInput13,
4573
4726
  {
4574
4727
  testID: "split-tender-reference",
@@ -4580,36 +4733,48 @@ function SplitTender({ sale }) {
4580
4733
  className: "rounded-md border border-border px-3 py-2 text-foreground"
4581
4734
  }
4582
4735
  ) : null,
4583
- error ? /* @__PURE__ */ jsx94(Text38, { testID: "split-tender-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4584
- /* @__PURE__ */ jsx94(Pressable29, { testID: "split-tender-add-button", accessibilityRole: "button", onPress: add, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Add" }) })
4736
+ error ? /* @__PURE__ */ jsx96(Text39, { testID: "split-tender-error", accessibilityRole: "alert", className: "text-destructive", children: error }) : null,
4737
+ /* @__PURE__ */ jsx96(Pressable31, { testID: "split-tender-add-button", accessibilityRole: "button", onPress: add, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Add" }) })
4585
4738
  ] }),
4586
- /* @__PURE__ */ jsx94(
4587
- Pressable29,
4739
+ /* @__PURE__ */ jsx96(
4740
+ Pressable31,
4588
4741
  {
4589
4742
  testID: "split-tender-complete",
4590
4743
  accessibilityRole: "button",
4591
4744
  disabled: incomplete,
4592
4745
  onPress: sale.complete,
4593
4746
  className: `rounded-md bg-primary px-4 py-3 ${incomplete ? "opacity-50" : ""}`,
4594
- children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
4747
+ children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Complete sale" })
4595
4748
  }
4596
4749
  ),
4597
- sale.error ? /* @__PURE__ */ jsx94(Text38, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4598
- sale.canContinue ? /* @__PURE__ */ jsxs53(Fragment8, { children: [
4599
- /* @__PURE__ */ jsx94(Text38, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4600
- /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4750
+ sale.error ? /* @__PURE__ */ jsx96(Text39, { accessibilityRole: "alert", className: "text-destructive", children: sale.error }) : null,
4751
+ sale.canContinue ? /* @__PURE__ */ jsxs54(Fragment8, { children: [
4752
+ /* @__PURE__ */ jsx96(Text39, { className: "text-foreground", children: "This sale is stored and will be sent. Continue to the next sale." }),
4753
+ /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: () => sale.continueSale(), className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center font-semibold text-primary-foreground", children: "Continue" }) })
4601
4754
  ] }) : null,
4602
- /* @__PURE__ */ jsx94(Pressable29, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx94(Text38, { className: "text-center text-foreground", children: "Back" }) })
4755
+ /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: sale.cancelTender, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx96(Text39, { className: "text-center text-foreground", children: "Back" }) })
4603
4756
  ] });
4604
4757
  }
4605
4758
 
4606
4759
  // src/sale/catalogue.tsx
4607
- import { useEffect as useEffect5, useMemo as useMemo2, useState as useState21 } from "react";
4608
- import { Pressable as Pressable30, Text as Text39, View as View60 } from "react-native";
4609
- import { useStockOverlaid, useStockOverlayAsOf } from "@tallyui/core";
4610
- import { catalogueEntries, findEntryByCode, searchProducts, variantPriceLabel } from "@tallyui/pos";
4611
- import { jsx as jsx95, jsxs as jsxs54 } from "react/jsx-runtime";
4612
- var MIN_TILE_WIDTH = 160;
4760
+ import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef6, useState as useState22 } from "react";
4761
+ import { Pressable as Pressable32, Text as Text40, View as View62 } from "react-native";
4762
+ import { useStockOverlaid as useStockOverlaid2, useStockOverlayAsOf } from "@tallyui/core";
4763
+ import {
4764
+ catalogueEntries,
4765
+ findEntryByCode,
4766
+ searchProducts,
4767
+ variantPriceLabel,
4768
+ sortProducts as sortProducts2,
4769
+ productSortValue as productSortValue2,
4770
+ catalogueViewReducer,
4771
+ normalizeCatalogueViewState,
4772
+ resolveGridColumns,
4773
+ DEFAULT_CATALOGUE_VIEW_STATE,
4774
+ listCategories,
4775
+ inCategory
4776
+ } from "@tallyui/pos";
4777
+ import { jsx as jsx97, jsxs as jsxs55 } from "react/jsx-runtime";
4613
4778
  var STOCK_LABEL = {
4614
4779
  in_stock: "In Stock",
4615
4780
  out_of_stock: "Out of Stock",
@@ -4627,20 +4792,98 @@ function laterOf(a, b) {
4627
4792
  if (!b) return a;
4628
4793
  return a.getTime() >= b.getTime() ? a : b;
4629
4794
  }
4630
- function Catalogue({ products, traits, currency, onSelect, statusText, statusAccessory, lastSyncedAt, loading, pullError, lastStockCheckAt, hour12, minCodeLength }) {
4795
+ function Catalogue({
4796
+ products,
4797
+ traits,
4798
+ currency,
4799
+ onSelect,
4800
+ statusText,
4801
+ statusAccessory,
4802
+ lastSyncedAt,
4803
+ loading,
4804
+ pullError,
4805
+ lastStockCheckAt,
4806
+ hour12,
4807
+ minCodeLength,
4808
+ viewState,
4809
+ defaultViewState,
4810
+ loadViewState,
4811
+ saveViewState,
4812
+ onViewStateError,
4813
+ onStateChange,
4814
+ showViewToggle = false,
4815
+ items,
4816
+ onQueryChange,
4817
+ showCategoryNav = false,
4818
+ categories
4819
+ }) {
4820
+ const [initial] = useState22(() => {
4821
+ const state2 = normalizeCatalogueViewState({ ...DEFAULT_CATALOGUE_VIEW_STATE, ...defaultViewState });
4822
+ if (viewState !== void 0 || !loadViewState) return { state: state2 };
4823
+ try {
4824
+ const value = loadViewState();
4825
+ if (value instanceof Promise) return { state: state2, pending: value };
4826
+ const loaded = normalizeCatalogueViewState(value, state2);
4827
+ return { state: loaded, loaded };
4828
+ } catch (error) {
4829
+ return { state: state2, failed: true, error };
4830
+ }
4831
+ });
4832
+ const [internalState, setInternalState] = useState22(initial.state);
4833
+ const state = viewState ?? internalState;
4834
+ const cashierChanged = useRef6(false);
4835
+ useEffect5(() => {
4836
+ let mounted = true;
4837
+ if (initial.loaded) onStateChange?.(initial.loaded);
4838
+ if (initial.failed) onViewStateError?.(initial.error);
4839
+ initial.pending?.then((value) => {
4840
+ if (!mounted || cashierChanged.current) return;
4841
+ const loaded = normalizeCatalogueViewState(value, initial.state);
4842
+ setInternalState(loaded);
4843
+ onStateChange?.(loaded);
4844
+ }, (error) => {
4845
+ if (mounted) onViewStateError?.(error);
4846
+ });
4847
+ return () => {
4848
+ mounted = false;
4849
+ };
4850
+ }, [initial]);
4851
+ function changeState(action) {
4852
+ const next = catalogueViewReducer(state, action);
4853
+ if (next === state) return;
4854
+ cashierChanged.current = true;
4855
+ if (viewState !== void 0) {
4856
+ onStateChange?.(next);
4857
+ return;
4858
+ }
4859
+ setInternalState(next);
4860
+ onStateChange?.(next);
4861
+ try {
4862
+ Promise.resolve(saveViewState?.(next)).catch((error) => onViewStateError?.(error));
4863
+ } catch (error) {
4864
+ onViewStateError?.(error);
4865
+ }
4866
+ }
4631
4867
  const isLoading = loading ?? (lastSyncedAt === null && pullError == null);
4632
- const shown = useStockOverlaid(products);
4868
+ const shown = useStockOverlaid2(products);
4869
+ const categoryList = useMemo3(() => categories ?? listCategories(shown, traits), [categories, shown, traits]);
4870
+ const activeCategory = showCategoryNav ? categoryList.find((category) => category.id === state.categoryId) : void 0;
4871
+ const suppliedItems = useStockOverlaid2(items ?? products);
4633
4872
  const overlayAsOf = useStockOverlayAsOf();
4634
4873
  const parsedOverlayAsOf = overlayAsOf ? new Date(overlayAsOf) : void 0;
4635
4874
  const validOverlayAsOf = parsedOverlayAsOf && !isNaN(parsedOverlayAsOf.getTime()) ? parsedOverlayAsOf : void 0;
4636
4875
  const stockAsOf = laterOf(laterOf(lastStockCheckAt, validOverlayAsOf), lastSyncedAt);
4637
- const [query, setQuery] = useState21("");
4638
- const [chooserId, setChooserId] = useState21(null);
4639
- const [width, setWidth] = useState21(0);
4640
- const columns = Math.max(2, Math.min(6, Math.floor((width - 8) / (MIN_TILE_WIDTH + 8))));
4641
- const entries = useMemo2(() => catalogueEntries(shown, traits, { currency }), [shown, traits, currency]);
4642
- const results = useMemo2(() => searchProducts(shown, query, traits), [shown, query, traits]);
4643
- const choices = useMemo2(() => chooserId === null ? [] : entries.filter((entry) => traits.getId(entry.product) === chooserId), [entries, chooserId, traits]);
4876
+ const [query, setQuery] = useState22("");
4877
+ const [chooserId, setChooserId] = useState22(null);
4878
+ const [width, setWidth] = useState22(0);
4879
+ const columns = resolveGridColumns(state.gridColumns, width);
4880
+ const entries = useMemo3(() => catalogueEntries(shown, traits, { currency }), [shown, traits, currency]);
4881
+ const results = useMemo3(() => {
4882
+ if (items !== void 0) return suppliedItems;
4883
+ const filtered = searchProducts(activeCategory ? shown.filter((doc) => inCategory(doc, activeCategory.id, traits)) : shown, query, traits);
4884
+ return state.sort ? sortProducts2(filtered, state.sort, (doc, field) => productSortValue2(doc, field, traits, { currency })) : filtered;
4885
+ }, [items, suppliedItems, shown, query, traits, state.sort, currency, showCategoryNav, activeCategory]);
4886
+ const choices = useMemo3(() => chooserId === null ? [] : entries.filter((entry) => traits.getId(entry.product) === chooserId), [entries, chooserId, traits]);
4644
4887
  useEffect5(() => {
4645
4888
  if (chooserId !== null && choices.length === 0) setChooserId(null);
4646
4889
  }, [chooserId, choices]);
@@ -4648,13 +4891,22 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4648
4891
  onSelect(entry);
4649
4892
  setChooserId(null);
4650
4893
  }
4651
- return /* @__PURE__ */ jsxs54(View60, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4652
- /* @__PURE__ */ jsxs54(View60, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4653
- /* @__PURE__ */ jsx95(
4894
+ function selectProduct(product) {
4895
+ const variants = entries.filter((entry) => traits.getId(entry.product) === traits.getId(product));
4896
+ if (variants.length === 1) select(variants[0]);
4897
+ else setChooserId(traits.getId(product));
4898
+ }
4899
+ const emptyState = /* @__PURE__ */ jsx97(Text40, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : activeCategory ? `No products in ${activeCategory.name}.` : isLoading ? "Loading products\u2026" : "No products yet." });
4900
+ return /* @__PURE__ */ jsxs55(View62, { className: "flex-1", onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [
4901
+ /* @__PURE__ */ jsxs55(View62, { className: "gap-2 border-b border-border bg-card px-4 pb-3 pt-3", children: [
4902
+ /* @__PURE__ */ jsx97(
4654
4903
  SearchInput,
4655
4904
  {
4656
4905
  value: query,
4657
- onChangeText: setQuery,
4906
+ onChangeText: (text) => {
4907
+ setQuery(text);
4908
+ onQueryChange?.(text);
4909
+ },
4658
4910
  placeholder: "Search or scan barcode / SKU",
4659
4911
  autoFocus: true,
4660
4912
  onSubmitEditing: () => {
@@ -4667,25 +4919,34 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4667
4919
  }
4668
4920
  }
4669
4921
  ),
4670
- statusText || statusAccessory ? /* @__PURE__ */ jsxs54(View60, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4671
- statusText ? /* @__PURE__ */ jsxs54(Text39, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4922
+ statusText || statusAccessory || showViewToggle ? /* @__PURE__ */ jsxs55(View62, { testID: "catalogue-status-row", className: "flex-row items-center gap-2", children: [
4923
+ statusText ? /* @__PURE__ */ jsxs55(Text40, { className: "flex-1 text-xs text-muted-foreground", numberOfLines: statusAccessory ? 1 : void 0, children: [
4672
4924
  statusText,
4673
4925
  query.trim() ? ` \xB7 ${results.length.toLocaleString()} matching` : ""
4674
4926
  ] }) : null,
4675
- statusAccessory
4927
+ statusAccessory,
4928
+ showViewToggle ? /* @__PURE__ */ jsx97(ViewToggle, { value: state.view, onChange: (view) => changeState({ type: "setView", view }) }) : null
4676
4929
  ] }) : null,
4677
- choices.length > 0 ? /* @__PURE__ */ jsxs54(View60, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4678
- choices.map((entry) => /* @__PURE__ */ jsxs54(
4679
- Pressable30,
4930
+ showCategoryNav ? /* @__PURE__ */ jsx97(
4931
+ CategoryNav,
4932
+ {
4933
+ categories: [{ id: "", name: "All products" }, ...categoryList],
4934
+ selectedId: activeCategory?.id ?? "",
4935
+ onSelect: (id) => changeState({ type: "setCategory", categoryId: id === "" ? null : id })
4936
+ }
4937
+ ) : null,
4938
+ choices.length > 0 ? /* @__PURE__ */ jsxs55(View62, { accessibilityLabel: "Choose variant", className: "gap-2", children: [
4939
+ choices.map((entry) => /* @__PURE__ */ jsxs55(
4940
+ Pressable32,
4680
4941
  {
4681
4942
  accessibilityRole: "button",
4682
4943
  onPress: () => select(entry),
4683
4944
  className: "gap-1 rounded-md border border-border p-3",
4684
4945
  children: [
4685
- /* @__PURE__ */ jsx95(Text39, { className: "font-semibold text-foreground", children: entry.variant.title }),
4686
- /* @__PURE__ */ jsx95(Text39, { className: "text-muted-foreground", children: entry.variant.sku }),
4687
- /* @__PURE__ */ jsx95(Text39, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4688
- /* @__PURE__ */ jsxs54(Text39, { className: "text-muted-foreground", children: [
4946
+ /* @__PURE__ */ jsx97(Text40, { className: "font-semibold text-foreground", children: entry.variant.title }),
4947
+ /* @__PURE__ */ jsx97(Text40, { className: "text-muted-foreground", children: entry.variant.sku }),
4948
+ /* @__PURE__ */ jsx97(Text40, { className: "text-foreground", children: variantPriceLabel(entry.variant, currency) }),
4949
+ /* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
4689
4950
  STOCK_LABEL[entry.variant.stock.status],
4690
4951
  " \xB7 ",
4691
4952
  stockAsOf ? `as of ${formatStockSyncTime(stockAsOf, void 0, hour12)}` : "not yet synced"
@@ -4694,10 +4955,20 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4694
4955
  },
4695
4956
  entry.variant.id
4696
4957
  )),
4697
- /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx95(Text39, { className: "text-center text-foreground", children: "Cancel" }) })
4958
+ /* @__PURE__ */ jsx97(Pressable32, { accessibilityRole: "button", onPress: () => setChooserId(null), className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx97(Text40, { className: "text-center text-foreground", children: "Cancel" }) })
4698
4959
  ] }) : null
4699
4960
  ] }),
4700
- /* @__PURE__ */ jsx95(
4961
+ state.view === "table" ? /* @__PURE__ */ jsx97(
4962
+ ProductTable,
4963
+ {
4964
+ items: results,
4965
+ sort: state.sort,
4966
+ onSortChange: (sort) => changeState({ type: "setSort", sort }),
4967
+ sortItems: false,
4968
+ onSelect: selectProduct,
4969
+ emptyState
4970
+ }
4971
+ ) : /* @__PURE__ */ jsx97(
4701
4972
  ProductGrid,
4702
4973
  {
4703
4974
  items: results,
@@ -4706,18 +4977,14 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4706
4977
  // TallyUI's ProductCard has no children slot, so the tile is composed directly here
4707
4978
  // (same structure/classes as ProductCard) to add the stock badge as a fourth child,
4708
4979
  // inside the card and centred with the rest, rather than adding a slot to ProductCard (out of scope for TV6b).
4709
- /* @__PURE__ */ jsx95(Pressable30, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => {
4710
- const variants = entries.filter((entry) => entry.product === product);
4711
- if (variants.length === 1) select(variants[0]);
4712
- else setChooserId(traits.getId(product));
4713
- }, children: /* @__PURE__ */ jsxs54(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4714
- /* @__PURE__ */ jsx95(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4715
- /* @__PURE__ */ jsx95(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4716
- /* @__PURE__ */ jsx95(ProductPrice, { doc: product }),
4717
- /* @__PURE__ */ jsx95(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4980
+ /* @__PURE__ */ jsx97(Pressable32, { accessibilityRole: "button", testID: `product-tile-${traits.getName(product)}`, onPress: () => selectProduct(product), children: /* @__PURE__ */ jsxs55(VStack, { space: "sm", className: "items-center rounded-lg border border-border bg-card p-3", children: [
4981
+ /* @__PURE__ */ jsx97(ProductImage, { doc: product, size: 80, className: "rounded-md" }),
4982
+ /* @__PURE__ */ jsx97(ProductTitle, { doc: product, className: "text-sm", numberOfLines: 2 }),
4983
+ /* @__PURE__ */ jsx97(ProductPrice, { doc: product }),
4984
+ /* @__PURE__ */ jsx97(ProductStockBadge, { doc: product, showAsOf: false, className: "self-center" })
4718
4985
  ] }) })
4719
4986
  ),
4720
- emptyState: /* @__PURE__ */ jsx95(Text39, { className: "mt-10 text-center text-sm text-muted-foreground", children: query.trim() ? `No products match "${query.trim()}".` : isLoading ? "Loading products\u2026" : "No products yet." })
4987
+ emptyState
4721
4988
  }
4722
4989
  )
4723
4990
  ] });
@@ -4725,7 +4992,7 @@ function Catalogue({ products, traits, currency, onSelect, statusText, statusAcc
4725
4992
 
4726
4993
  // src/sale/receipt.tsx
4727
4994
  import { useEffect as useEffect6 } from "react";
4728
- import { Pressable as Pressable31, Text as Text40, View as View61 } from "react-native";
4995
+ import { Pressable as Pressable33, Text as Text41, View as View63 } from "react-native";
4729
4996
  import { formatMoney as formatMoney16 } from "@tallyui/core";
4730
4997
  import { buildReceiptData as buildReceiptData3 } from "@tallyui/pos";
4731
4998
 
@@ -4746,7 +5013,7 @@ function orderReference(order) {
4746
5013
  }
4747
5014
 
4748
5015
  // src/sale/receipt.tsx
4749
- import { Fragment as Fragment9, jsx as jsx96, jsxs as jsxs55 } from "react/jsx-runtime";
5016
+ import { Fragment as Fragment9, jsx as jsx98, jsxs as jsxs56 } from "react/jsx-runtime";
4750
5017
  var defaultFormatDate = (iso) => new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
4751
5018
  function Receipt({
4752
5019
  order,
@@ -4767,32 +5034,32 @@ function Receipt({
4767
5034
  register: registerId
4768
5035
  });
4769
5036
  const money = (amount) => formatMoney16({ amount, currency: receipt.currency }) ?? "";
4770
- const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs55(View61, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
4771
- /* @__PURE__ */ jsx96(Text40, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
4772
- /* @__PURE__ */ jsx96(Text40, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
5037
+ const row = (label, amount, bold = false, key) => /* @__PURE__ */ jsxs56(View63, { accessibilityLabel: `${label}: ${amount}`, className: "flex-row justify-between gap-4", children: [
5038
+ /* @__PURE__ */ jsx98(Text41, { className: `text-foreground ${bold ? "font-semibold" : ""}`, children: label }),
5039
+ /* @__PURE__ */ jsx98(Text41, { className: `text-right text-foreground ${bold ? "font-semibold" : ""}`, children: amount })
4773
5040
  ] }, key);
4774
5041
  const { totals } = receipt;
4775
5042
  const lineDiscountMinor = totals.discountMinor - receipt.orderDiscountMinor;
4776
5043
  const taxRows = totals.taxLines.map((line, index) => row(`${totals.taxInclusive ? "incl. " : ""}${taxLabel(line.ratePpm)}`, money(line.amountMinor), false, index));
4777
- return /* @__PURE__ */ jsxs55(Fragment9, { children: [
4778
- topInset > 0 ? /* @__PURE__ */ jsx96(View61, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
4779
- /* @__PURE__ */ jsxs55(View61, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
4780
- /* @__PURE__ */ jsx96(Text40, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
4781
- receipt.header.storeAddress ? /* @__PURE__ */ jsx96(Text40, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
4782
- /* @__PURE__ */ jsx96(Text40, { testID: "receipt-order", className: "text-foreground", children: posOrder ? `Order ${orderReference(posOrder)}` : `Order ${receipt.header.orderNumber.slice(-8)} (draft)` }),
4783
- /* @__PURE__ */ jsx96(Text40, { className: "text-muted-foreground", children: formatDate(posOrder?.createdAt ?? receipt.header.date) }),
4784
- /* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
5044
+ return /* @__PURE__ */ jsxs56(Fragment9, { children: [
5045
+ topInset > 0 ? /* @__PURE__ */ jsx98(View63, { dataSet: { print: "hide" }, style: { height: topInset, flexShrink: 0 } }) : null,
5046
+ /* @__PURE__ */ jsxs56(View63, { className: "w-full max-w-md self-center gap-3 p-4 bg-card", children: [
5047
+ /* @__PURE__ */ jsx98(Text41, { className: "text-lg font-semibold text-foreground", children: receipt.header.storeName }),
5048
+ receipt.header.storeAddress ? /* @__PURE__ */ jsx98(Text41, { className: "text-muted-foreground", children: receipt.header.storeAddress }) : null,
5049
+ /* @__PURE__ */ jsx98(Text41, { testID: "receipt-order", className: "text-foreground", children: posOrder ? `Order ${orderReference(posOrder)}` : `Order ${receipt.header.orderNumber.slice(-8)} (draft)` }),
5050
+ /* @__PURE__ */ jsx98(Text41, { className: "text-muted-foreground", children: formatDate(posOrder?.createdAt ?? receipt.header.date) }),
5051
+ /* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
4785
5052
  "Cashier: ",
4786
5053
  receipt.header.cashier
4787
5054
  ] }),
4788
- receipt.header.customer && /* @__PURE__ */ jsxs55(Text40, { className: "text-muted-foreground", children: [
5055
+ receipt.header.customer && /* @__PURE__ */ jsxs56(Text41, { className: "text-muted-foreground", children: [
4789
5056
  "Customer: ",
4790
5057
  receipt.header.customer
4791
5058
  ] }),
4792
- receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs55(View61, { children: [
4793
- /* @__PURE__ */ jsx96(Text40, { className: "text-foreground", children: line.name }),
5059
+ receipt.lineItems.map((line, index) => /* @__PURE__ */ jsxs56(View63, { children: [
5060
+ /* @__PURE__ */ jsx98(Text41, { className: "text-foreground", children: line.name }),
4794
5061
  row(`${line.quantity} \xD7 ${money(line.unitPriceMinor)}`, money(line.displayAmountMinor)),
4795
- line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx96(View61, { className: "pl-4", children: row(`${discountLabel(
5062
+ line.displayDiscounts.map((discount, i) => /* @__PURE__ */ jsx98(View63, { className: "pl-4", children: row(`${discountLabel(
4796
5063
  order.lineItems[index].discounts[i],
4797
5064
  receipt.currency
4798
5065
  )} off`, `\u2212${money(discount.amountMinor)}`) }, i))
@@ -4811,19 +5078,19 @@ function Receipt({
4811
5078
  index
4812
5079
  )),
4813
5080
  row("Change", money(receipt.changeDueMinor)),
4814
- /* @__PURE__ */ jsxs55(View61, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
4815
- /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: () => {
5081
+ /* @__PURE__ */ jsxs56(View63, { dataSet: { print: "hide" }, className: "flex-row gap-4", children: [
5082
+ /* @__PURE__ */ jsx98(Pressable33, { accessibilityRole: "button", onPress: () => {
4816
5083
  if (typeof window !== "undefined" && typeof window.print === "function") window.print();
4817
- }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx96(Text40, { className: "text-center text-foreground", children: "Print receipt" }) }),
4818
- /* @__PURE__ */ jsx96(Pressable31, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx96(Text40, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
5084
+ }, className: "rounded-md border border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx98(Text41, { className: "text-center text-foreground", children: "Print receipt" }) }),
5085
+ /* @__PURE__ */ jsx98(Pressable33, { accessibilityRole: "button", onPress: newSale, className: "rounded-md bg-primary px-4 py-3", children: /* @__PURE__ */ jsx98(Text41, { className: "text-center font-semibold text-primary-foreground", children: "New sale" }) })
4819
5086
  ] })
4820
5087
  ] })
4821
5088
  ] });
4822
5089
  }
4823
5090
 
4824
5091
  // src/sale/sync-status.tsx
4825
- import { useEffect as useEffect7, useRef as useRef6, useState as useState22 } from "react";
4826
- import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text41, View as View62 } from "react-native";
5092
+ import { useEffect as useEffect7, useRef as useRef7, useState as useState23 } from "react";
5093
+ import { AccessibilityInfo as AccessibilityInfo2, Platform as Platform3, Text as Text42, View as View64 } from "react-native";
4827
5094
 
4828
5095
  // src/sale/since-text.ts
4829
5096
  function sinceText(clock) {
@@ -4832,7 +5099,7 @@ function sinceText(clock) {
4832
5099
  }
4833
5100
 
4834
5101
  // src/sale/sync-status.tsx
4835
- import { Fragment as Fragment10, jsx as jsx97, jsxs as jsxs56 } from "react/jsx-runtime";
5102
+ import { Fragment as Fragment10, jsx as jsx99, jsxs as jsxs57 } from "react/jsx-runtime";
4836
5103
  var PULL_NOTICE_TEXT = {
4837
5104
  unauthorized: {
4838
5105
  line: () => "Products aren't updating: this till needs to sign in to the online store again.",
@@ -4874,7 +5141,7 @@ var SALES_REFUSED = "The online store refused the last send. This till will try
4874
5141
  var TILL_UPDATES_REFUSED = "The online store refused the last send. This till will try again with the next till update, or when the app is reopened.";
4875
5142
  var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
4876
5143
  function useAnnounceOnIos(...texts) {
4877
- const announced = useRef6(texts);
5144
+ const announced = useRef7(texts);
4878
5145
  useEffect7(() => {
4879
5146
  const changed = texts.filter((text, index) => text && text !== announced.current[index]);
4880
5147
  announced.current = texts;
@@ -4884,7 +5151,7 @@ function useAnnounceOnIos(...texts) {
4884
5151
  function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullNotice }) {
4885
5152
  const updates = registerState?.pending ?? 0;
4886
5153
  const outbox = state.pending === 0 && registerState?.pending ? registerState : state;
4887
- const [now, setNow] = useState22(Date.now);
5154
+ const [now, setNow] = useState23(Date.now);
4888
5155
  useEffect7(() => {
4889
5156
  setNow(Date.now());
4890
5157
  if (!outbox.nextAttemptAt) return;
@@ -4908,24 +5175,24 @@ function SyncStatus({ state, registerState, pluginName = "the POS plugin", pullN
4908
5175
  const notice = pullNotice && text && { line: text.line(pluginName), detail: text.detail(pullNotice, pluginName) };
4909
5176
  useAnnounceOnIos(notice?.line, spoken);
4910
5177
  const oneDetail = pullNotice?.code === "missing_plugin" && !!backendMissing;
4911
- return /* @__PURE__ */ jsxs56(View62, { children: [
4912
- notice ? /* @__PURE__ */ jsxs56(Fragment10, { children: [
4913
- /* @__PURE__ */ jsx97(Text41, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
4914
- oneDetail ? null : /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
5178
+ return /* @__PURE__ */ jsxs57(View64, { children: [
5179
+ notice ? /* @__PURE__ */ jsxs57(Fragment10, { children: [
5180
+ /* @__PURE__ */ jsx99(Text42, { accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: notice.line }),
5181
+ oneDetail ? null : /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail })
4915
5182
  ] }) : null,
4916
- /* @__PURE__ */ jsx97(Text41, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
4917
- doing ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
4918
- refused ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
4919
- oneDetail && notice ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx97(Text41, { className: "px-4 pb-2 text-xs text-muted-foreground", children: BACKEND_MISSING_DETAIL.replace("{pluginName}", () => pluginName).replace("{lastTime}", () => upToDate ? " the last time it checked" : "") }) : null
5183
+ /* @__PURE__ */ jsx99(Text42, { accessibilityLabel: spoken, accessibilityLiveRegion: "polite", className: "px-4 py-2 text-xs text-muted-foreground", children: spoken }),
5184
+ doing ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: doing }) : null,
5185
+ refused ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: REFUSED_DETAIL }) : null,
5186
+ oneDetail && notice ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: notice.detail }) : backendMissing ? /* @__PURE__ */ jsx99(Text42, { className: "px-4 pb-2 text-xs text-muted-foreground", children: BACKEND_MISSING_DETAIL.replace("{pluginName}", () => pluginName).replace("{lastTime}", () => upToDate ? " the last time it checked" : "") }) : null
4920
5187
  ] });
4921
5188
  }
4922
5189
 
4923
5190
  // src/sale/orders-list.tsx
4924
- import { useEffect as useEffect8, useRef as useRef7, useState as useState23 } from "react";
4925
- import { Pressable as Pressable32, ScrollView as ScrollView13, Text as Text42, View as View63 } from "react-native";
5191
+ import { useEffect as useEffect8, useRef as useRef8, useState as useState24 } from "react";
5192
+ import { Pressable as Pressable34, ScrollView as ScrollView13, Text as Text43, View as View65 } from "react-native";
4926
5193
  import { formatMoney as formatMoney17, knownWarnings } from "@tallyui/core";
4927
5194
  import { needsAttention } from "@tallyui/pos";
4928
- import { jsx as jsx98, jsxs as jsxs57 } from "react/jsx-runtime";
5195
+ import { jsx as jsx100, jsxs as jsxs58 } from "react/jsx-runtime";
4929
5196
  var STATUS_LABEL = { pending: "Waiting to sync", applied: "Synced", rejected: "Not accepted" };
4930
5197
  var FIGURE_LABELS = /* @__PURE__ */ new Map([["subtotalMinor", "Subtotal"], ["taxMinor", "Tax"], ["discountMinor", "Discount"]]);
4931
5198
  var REFUSAL_SENTENCES = /* @__PURE__ */ new Map([
@@ -4948,27 +5215,27 @@ function defaultFormatDate2(iso) {
4948
5215
  return Number.isNaN(date.getTime()) ? iso : new Intl.DateTimeFormat(void 0, { dateStyle: "medium", timeStyle: "short" }).format(date);
4949
5216
  }
4950
5217
  function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer, stuck }) {
4951
- const retrying = useRef7(/* @__PURE__ */ new Set());
4952
- const [retryingIds, setRetryingIds] = useState23(/* @__PURE__ */ new Set());
4953
- const [expanded, setExpanded] = useState23(/* @__PURE__ */ new Set());
5218
+ const retrying = useRef8(/* @__PURE__ */ new Set());
5219
+ const [retryingIds, setRetryingIds] = useState24(/* @__PURE__ */ new Set());
5220
+ const [expanded, setExpanded] = useState24(/* @__PURE__ */ new Set());
4954
5221
  useEffect8(() => {
4955
5222
  for (const id of retrying.current) {
4956
5223
  if (!orders.some((order) => order.id === id && order.syncStatus === "rejected")) retrying.current.delete(id);
4957
5224
  }
4958
5225
  setRetryingIds(new Set(retrying.current));
4959
5226
  }, [orders]);
4960
- return /* @__PURE__ */ jsxs57(ScrollView13, { className: "flex-1 bg-background p-4", children: [
4961
- [{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs57(View63, { className: "mb-6 gap-3", children: [
4962
- /* @__PURE__ */ jsx98(Text42, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
4963
- section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */ jsx98(Text42, { testID: "orders-empty", className: "text-muted-foreground", children: "No sales yet. Completed sales appear here." }) : null,
5227
+ return /* @__PURE__ */ jsxs58(ScrollView13, { className: "flex-1 bg-background p-4", children: [
5228
+ [{ title: "Needs attention", orders: needsAttention(orders, { stuckCommandIds: stuck?.commandIds }) }, { title: "Recent", orders }].filter((section) => section.title === "Recent" || section.orders.length > 0).map((section) => /* @__PURE__ */ jsxs58(View65, { className: "mb-6 gap-3", children: [
5229
+ /* @__PURE__ */ jsx100(Text43, { accessibilityRole: "header", className: "text-xl font-semibold text-foreground", children: section.title }),
5230
+ section.title === "Recent" && orders.length === 0 ? /* @__PURE__ */ jsx100(Text43, { testID: "orders-empty", className: "text-muted-foreground", children: "No sales yet. Completed sales appear here." }) : null,
4964
5231
  section.orders.map((order) => {
4965
5232
  const count2 = order.lines.reduce((sum, line) => sum + line.quantity, 0);
4966
5233
  const key = `${section.title}:${order.id}`;
4967
5234
  const isExpanded = expanded.has(key);
4968
5235
  const stuckEntry = order.syncStatus === "pending" ? stuck?.orders.find((entry) => entry.commandId === order.commandId) : void 0;
4969
- return /* @__PURE__ */ jsxs57(View63, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
4970
- /* @__PURE__ */ jsxs57(
4971
- Pressable32,
5236
+ return /* @__PURE__ */ jsxs58(View65, { className: "gap-1 rounded-md border border-border bg-card p-3", children: [
5237
+ /* @__PURE__ */ jsxs58(
5238
+ Pressable34,
4972
5239
  {
4973
5240
  accessibilityRole: "button",
4974
5241
  "aria-expanded": isExpanded,
@@ -4982,8 +5249,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
4982
5249
  return next;
4983
5250
  }),
4984
5251
  children: [
4985
- /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: `Order ${orderReference(order)} \xB7 ${count2} ${count2 === 1 ? "item" : "items"}` }),
4986
- /* @__PURE__ */ jsxs57(Text42, { className: "text-muted-foreground", children: [
5252
+ /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: `Order ${orderReference(order)} \xB7 ${count2} ${count2 === 1 ? "item" : "items"}` }),
5253
+ /* @__PURE__ */ jsxs58(Text43, { className: "text-muted-foreground", children: [
4987
5254
  formatDate(order.createdAt),
4988
5255
  " \xB7 ",
4989
5256
  formatMoney17({ amount: order.totalMinor, currency: order.currency }),
@@ -4993,15 +5260,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
4993
5260
  ]
4994
5261
  }
4995
5262
  ),
4996
- isExpanded ? /* @__PURE__ */ jsxs57(View63, { testID: `order-detail-${order.id}`, className: "mt-1 gap-1 border-t border-border pt-2", children: [
4997
- order.lines.map((line) => /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: `${line.quantity} \xD7 ${line.name}` }, line.id)),
4998
- order.payments.map((payment) => /* @__PURE__ */ jsx98(Text42, { className: "text-muted-foreground", children: `${payment.method === "cash" ? "Cash" : "Card terminal"} ${formatMoney17({ amount: payment.amountMinor, currency: order.currency })}${payment.reference ? ` \xB7 ${payment.reference}` : ""}` }, payment.id))
5263
+ isExpanded ? /* @__PURE__ */ jsxs58(View65, { testID: `order-detail-${order.id}`, className: "mt-1 gap-1 border-t border-border pt-2", children: [
5264
+ order.lines.map((line) => /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: `${line.quantity} \xD7 ${line.name}` }, line.id)),
5265
+ order.payments.map((payment) => /* @__PURE__ */ jsx100(Text43, { className: "text-muted-foreground", children: `${payment.method === "cash" ? "Cash" : "Card terminal"} ${formatMoney17({ amount: payment.amountMinor, currency: order.currency })}${payment.reference ? ` \xB7 ${payment.reference}` : ""}` }, payment.id))
4999
5266
  ] }) : null,
5000
- stuckEntry ? /* @__PURE__ */ jsx98(Text42, { className: "text-destructive", children: `Hasn't reached the online store since ${sinceText(stuckEntry)}.` }) : null,
5001
- order.syncStatus === "rejected" ? /* @__PURE__ */ jsx98(Text42, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
5002
- order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
5003
- order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: warning.code === "customer_omitted" ? `The customer's ${warning.field} couldn't be sent to the store, so the order isn't linked to them.` : "The terminal's payment reference couldn't be kept; the payment is recorded without it." }, index)),
5004
- section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx98(Pressable32, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
5267
+ stuckEntry ? /* @__PURE__ */ jsx100(Text43, { className: "text-destructive", children: `Hasn't reached the online store since ${sinceText(stuckEntry)}.` }) : null,
5268
+ order.syncStatus === "rejected" ? /* @__PURE__ */ jsx100(Text43, { className: "text-destructive", children: refusalSentence(order.error?.code) }) : null,
5269
+ order.lateSessionId !== void 0 ? /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: "Taken after the register closed. It is not in that register's closure." }) : null,
5270
+ order.localWarnings?.map((warning, index) => /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: warning.code === "customer_omitted" ? `The customer's ${warning.field} couldn't be sent to the store, so the order isn't linked to them.` : "The terminal's payment reference couldn't be kept; the payment is recorded without it." }, index)),
5271
+ section.title === "Needs attention" && order.syncStatus === "rejected" && order.error?.code !== "idempotency_mismatch" ? /* @__PURE__ */ jsx100(Pressable34, { accessibilityRole: "button", disabled: retryingIds.has(order.id), onPress: async () => {
5005
5272
  if (retrying.current.has(order.id)) return;
5006
5273
  retrying.current.add(order.id);
5007
5274
  setRetryingIds(new Set(retrying.current));
@@ -5009,8 +5276,8 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
5009
5276
  retrying.current.delete(order.id);
5010
5277
  setRetryingIds(new Set(retrying.current));
5011
5278
  }
5012
- }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx98(Text42, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
5013
- knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx98(View63, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx98(Text42, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : warning.code === "tax_rate_mismatch" ? `Tax at ${(warning.ratePpm / 1e4).toLocaleString(void 0, { maximumFractionDigits: 4 })}%: store ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : warning.code === "customer_ignored" ? `The online store didn't recognise the customer on this sale, so it was saved as a guest sale. Customer id: ${warning.customerId}.` : warning.code === "figures_mismatch" ? `The online store worked out different figures for this sale. ${warning.fields.map(({ field, tillMinor, serverMinor }) => `${FIGURE_LABELS.get(field) ?? field}: till ${formatMoney17({ amount: tillMinor, currency: order.currency })}, store ${formatMoney17({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney17({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
5279
+ }, className: "rounded-md bg-primary px-4 py-2", children: /* @__PURE__ */ jsx100(Text43, { className: "text-center font-semibold text-primary-foreground", children: "Retry" }) }) : null,
5280
+ knownWarnings(order.warnings).map((warning, index) => /* @__PURE__ */ jsx100(View65, { className: "border-l-4 border-warning pl-2", children: /* @__PURE__ */ jsx100(Text43, { className: "text-foreground", children: warning.code === "insufficient_stock" ? `Stock short by ${warning.quantity} for ${order.lines.find((line) => line.variantId === warning.variantId)?.name}` : warning.code === "tax_rate_mismatch" ? `Tax at ${(warning.ratePpm / 1e4).toLocaleString(void 0, { maximumFractionDigits: 4 })}%: store ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : warning.code === "customer_ignored" ? `The online store didn't recognise the customer on this sale, so it was saved as a guest sale. Customer id: ${warning.customerId}.` : warning.code === "figures_mismatch" ? `The online store worked out different figures for this sale. ${warning.fields.map(({ field, tillMinor, serverMinor }) => `${FIGURE_LABELS.get(field) ?? field}: till ${formatMoney17({ amount: tillMinor, currency: order.currency })}, store ${formatMoney17({ amount: serverMinor, currency: order.currency })}.`).join(" ")}` : warning.bridgeMinor !== void 0 ? `Store calculated ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })}; a rounding line of ${warning.bridgeMinor > 0 ? "+" : ""}${formatMoney17({ amount: warning.bridgeMinor, currency: order.currency })} brought it to ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` : `Store total ${formatMoney17({ amount: warning.serverMinor, currency: order.currency })} vs POS ${formatMoney17({ amount: warning.expectedMinor, currency: order.currency })}` }) }, index))
5014
5281
  ] }, order.id);
5015
5282
  })
5016
5283
  ] }, section.title)),
@@ -5019,15 +5286,15 @@ function OrdersList({ orders, onRetry, formatDate = defaultFormatDate2, footer,
5019
5286
  }
5020
5287
 
5021
5288
  // src/sale/parked-sales.tsx
5022
- import { useState as useState24 } from "react";
5023
- import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View64 } from "react-native";
5289
+ import { useState as useState25 } from "react";
5290
+ import { ScrollView as ScrollView14, useWindowDimensions as useWindowDimensions3, View as View66 } from "react-native";
5024
5291
  import { formatMoney as formatMoney18 } from "@tallyui/core";
5025
- import { Fragment as Fragment11, jsx as jsx99, jsxs as jsxs58 } from "react/jsx-runtime";
5292
+ import { Fragment as Fragment11, jsx as jsx101, jsxs as jsxs59 } from "react/jsx-runtime";
5026
5293
  function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open, onOpenChange, hour12 }) {
5027
5294
  const { height: windowHeight } = useWindowDimensions3();
5028
5295
  const maxHeight = Math.max(280, windowHeight - 64);
5029
- const [confirming, setConfirming] = useState24(null);
5030
- const [error, setError] = useState24("");
5296
+ const [confirming, setConfirming] = useState25(null);
5297
+ const [error, setError] = useState25("");
5031
5298
  const attempt = async (action) => {
5032
5299
  setError("");
5033
5300
  try {
@@ -5036,28 +5303,28 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
5036
5303
  setError(String(e));
5037
5304
  }
5038
5305
  };
5039
- return /* @__PURE__ */ jsx99(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs58(DialogContent, { testID: "parked-sales", className: "flex-col overflow-hidden", style: { maxHeight }, children: [
5040
- /* @__PURE__ */ jsxs58(View64, { className: "flex-row items-center justify-between gap-2", children: [
5041
- /* @__PURE__ */ jsx99(DialogTitle, { children: "Parked sales" }),
5042
- /* @__PURE__ */ jsx99(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx99(IconButton, { variant: "ghost", size: "sm", testID: "parked-sales-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx99(XIcon, { size: 16 }) }) })
5306
+ return /* @__PURE__ */ jsx101(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs59(DialogContent, { testID: "parked-sales", className: "flex-col overflow-hidden", style: { maxHeight }, children: [
5307
+ /* @__PURE__ */ jsxs59(View66, { className: "flex-row items-center justify-between gap-2", children: [
5308
+ /* @__PURE__ */ jsx101(DialogTitle, { children: "Parked sales" }),
5309
+ /* @__PURE__ */ jsx101(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx101(IconButton, { variant: "ghost", size: "sm", testID: "parked-sales-dismiss", accessibilityLabel: "Close panel", children: /* @__PURE__ */ jsx101(XIcon, { size: 16 }) }) })
5043
5310
  ] }),
5044
- /* @__PURE__ */ jsxs58(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
5045
- /* @__PURE__ */ jsx99(
5311
+ /* @__PURE__ */ jsxs59(ScrollView14, { className: "flex-1", contentContainerClassName: "gap-3", children: [
5312
+ /* @__PURE__ */ jsx101(
5046
5313
  Button,
5047
5314
  {
5048
5315
  testID: "parked-sales-park",
5049
5316
  accessibilityLabel: "Park this sale",
5050
5317
  disabled: sale.order.lineItems.length === 0,
5051
5318
  onPress: () => attempt(async () => setError(await (onPark ?? sale.park)() ?? "")),
5052
- children: /* @__PURE__ */ jsx99(Text, { children: "Park this sale" })
5319
+ children: /* @__PURE__ */ jsx101(Text, { children: "Park this sale" })
5053
5320
  }
5054
5321
  ),
5055
- !!error && /* @__PURE__ */ jsx99(Text, { testID: "parked-sales-error", className: "text-destructive", children: error }),
5056
- parked.length === 0 && /* @__PURE__ */ jsx99(Text, { testID: "parked-sales-empty", children: "No parked sales." }),
5057
- parked.map((row) => /* @__PURE__ */ jsx99(View64, { testID: `parked-row-${row.id}`, className: "gap-2 rounded-md border border-border p-3", children: confirming === row.id ? /* @__PURE__ */ jsxs58(Fragment11, { children: [
5058
- /* @__PURE__ */ jsx99(Text, { children: "Discard this parked sale?" }),
5059
- /* @__PURE__ */ jsxs58(View64, { className: "flex-row gap-2", children: [
5060
- /* @__PURE__ */ jsx99(
5322
+ !!error && /* @__PURE__ */ jsx101(Text, { testID: "parked-sales-error", className: "text-destructive", children: error }),
5323
+ parked.length === 0 && /* @__PURE__ */ jsx101(Text, { testID: "parked-sales-empty", children: "No parked sales." }),
5324
+ parked.map((row) => /* @__PURE__ */ jsx101(View66, { testID: `parked-row-${row.id}`, className: "gap-2 rounded-md border border-border p-3", children: confirming === row.id ? /* @__PURE__ */ jsxs59(Fragment11, { children: [
5325
+ /* @__PURE__ */ jsx101(Text, { children: "Discard this parked sale?" }),
5326
+ /* @__PURE__ */ jsxs59(View66, { className: "flex-row gap-2", children: [
5327
+ /* @__PURE__ */ jsx101(
5061
5328
  Button,
5062
5329
  {
5063
5330
  testID: `parked-discard-confirm-${row.id}`,
@@ -5066,22 +5333,22 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
5066
5333
  await onDiscard(row.id);
5067
5334
  setConfirming(null);
5068
5335
  }),
5069
- children: /* @__PURE__ */ jsx99(Text, { children: "Discard" })
5336
+ children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
5070
5337
  }
5071
5338
  ),
5072
- /* @__PURE__ */ jsx99(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx99(Text, { children: "Cancel" }) })
5339
+ /* @__PURE__ */ jsx101(Button, { testID: `parked-discard-cancel-${row.id}`, variant: "outline", onPress: () => setConfirming(null), children: /* @__PURE__ */ jsx101(Text, { children: "Cancel" }) })
5073
5340
  ] })
5074
- ] }) : /* @__PURE__ */ jsxs58(Fragment11, { children: [
5075
- /* @__PURE__ */ jsx99(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
5076
- /* @__PURE__ */ jsxs58(Text, { children: [
5341
+ ] }) : /* @__PURE__ */ jsxs59(Fragment11, { children: [
5342
+ /* @__PURE__ */ jsx101(Text, { children: formatStockSyncTime(new Date(row.parkedAt), void 0, hour12) }),
5343
+ /* @__PURE__ */ jsxs59(Text, { children: [
5077
5344
  row.itemCount,
5078
5345
  " ",
5079
5346
  row.itemCount === 1 ? "item" : "items"
5080
5347
  ] }),
5081
- /* @__PURE__ */ jsx99(Text, { children: formatMoney18({ amount: row.totalMinor, currency }) }),
5082
- !!row.customerName && /* @__PURE__ */ jsx99(Text, { children: row.customerName }),
5083
- /* @__PURE__ */ jsxs58(View64, { className: "flex-row gap-2", children: [
5084
- /* @__PURE__ */ jsx99(
5348
+ /* @__PURE__ */ jsx101(Text, { children: formatMoney18({ amount: row.totalMinor, currency }) }),
5349
+ !!row.customerName && /* @__PURE__ */ jsx101(Text, { children: row.customerName }),
5350
+ /* @__PURE__ */ jsxs59(View66, { className: "flex-row gap-2", children: [
5351
+ /* @__PURE__ */ jsx101(
5085
5352
  Button,
5086
5353
  {
5087
5354
  testID: `parked-resume-${row.id}`,
@@ -5091,17 +5358,17 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
5091
5358
  if (refusal === null) onOpenChange(false);
5092
5359
  else setError(refusal);
5093
5360
  }),
5094
- children: /* @__PURE__ */ jsx99(Text, { children: "Resume" })
5361
+ children: /* @__PURE__ */ jsx101(Text, { children: "Resume" })
5095
5362
  }
5096
5363
  ),
5097
- /* @__PURE__ */ jsx99(
5364
+ /* @__PURE__ */ jsx101(
5098
5365
  Button,
5099
5366
  {
5100
5367
  testID: `parked-discard-${row.id}`,
5101
5368
  accessibilityLabel: "Discard parked sale",
5102
5369
  variant: "outline",
5103
5370
  onPress: () => setConfirming(row.id),
5104
- children: /* @__PURE__ */ jsx99(Text, { children: "Discard" })
5371
+ children: /* @__PURE__ */ jsx101(Text, { children: "Discard" })
5105
5372
  }
5106
5373
  )
5107
5374
  ] })
@@ -5111,10 +5378,10 @@ function ParkedSales({ sale, parked, onDiscard, onPark, onResume, currency, open
5111
5378
  }
5112
5379
 
5113
5380
  // src/layout/pos-layout.tsx
5114
- import { useState as useState25 } from "react";
5115
- import { Pressable as Pressable33, Text as Text43, View as View65, useWindowDimensions as useWindowDimensions4 } from "react-native";
5116
- import { cn as cn80 } from "@tallyui/theme";
5117
- import { Fragment as Fragment12, jsx as jsx100, jsxs as jsxs59 } from "react/jsx-runtime";
5381
+ import { useState as useState26 } from "react";
5382
+ import { Pressable as Pressable35, Text as Text44, View as View67, useWindowDimensions as useWindowDimensions4 } from "react-native";
5383
+ import { cn as cn82 } from "@tallyui/theme";
5384
+ import { Fragment as Fragment12, jsx as jsx102, jsxs as jsxs60 } from "react/jsx-runtime";
5118
5385
  function POSLayout({
5119
5386
  browseSlot,
5120
5387
  cartSlot,
@@ -5126,40 +5393,40 @@ function POSLayout({
5126
5393
  }) {
5127
5394
  const { width } = useWindowDimensions4();
5128
5395
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
5129
- const [activeTab, setActiveTab] = useState25("browse");
5130
- return /* @__PURE__ */ jsxs59(View65, { className: cn80("flex-1 bg-bg", className), ...viewProps, children: [
5131
- headerSlot && /* @__PURE__ */ jsx100(View65, { className: "border-b border-border", children: headerSlot }),
5132
- layout === "split" ? /* @__PURE__ */ jsxs59(View65, { className: "flex-1 flex-row", children: [
5133
- /* @__PURE__ */ jsx100(View65, { className: "flex-[3]", children: browseSlot }),
5134
- /* @__PURE__ */ jsx100(View65, { className: "flex-[2] border-l border-border", children: cartSlot })
5135
- ] }) : /* @__PURE__ */ jsxs59(Fragment12, { children: [
5136
- /* @__PURE__ */ jsxs59(View65, { className: "flex-row border-b border-border", children: [
5137
- /* @__PURE__ */ jsx100(
5138
- Pressable33,
5396
+ const [activeTab, setActiveTab] = useState26("browse");
5397
+ return /* @__PURE__ */ jsxs60(View67, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
5398
+ headerSlot && /* @__PURE__ */ jsx102(View67, { className: "border-b border-border", children: headerSlot }),
5399
+ layout === "split" ? /* @__PURE__ */ jsxs60(View67, { className: "flex-1 flex-row", children: [
5400
+ /* @__PURE__ */ jsx102(View67, { className: "flex-[3]", children: browseSlot }),
5401
+ /* @__PURE__ */ jsx102(View67, { className: "flex-[2] border-l border-border", children: cartSlot })
5402
+ ] }) : /* @__PURE__ */ jsxs60(Fragment12, { children: [
5403
+ /* @__PURE__ */ jsxs60(View67, { className: "flex-row border-b border-border", children: [
5404
+ /* @__PURE__ */ jsx102(
5405
+ Pressable35,
5139
5406
  {
5140
5407
  onPress: () => setActiveTab("browse"),
5141
- className: cn80("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
5142
- children: /* @__PURE__ */ jsx100(Text43, { className: cn80("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
5408
+ className: cn82("flex-1 py-3", activeTab === "browse" && "border-b-2 border-primary"),
5409
+ children: /* @__PURE__ */ jsx102(Text44, { className: cn82("text-center text-sm font-semibold", activeTab === "browse" ? "text-primary" : "text-muted-foreground"), children: "Browse" })
5143
5410
  }
5144
5411
  ),
5145
- /* @__PURE__ */ jsx100(
5146
- Pressable33,
5412
+ /* @__PURE__ */ jsx102(
5413
+ Pressable35,
5147
5414
  {
5148
5415
  onPress: () => setActiveTab("cart"),
5149
- className: cn80("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
5150
- children: /* @__PURE__ */ jsx100(Text43, { className: cn80("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
5416
+ className: cn82("flex-1 py-3", activeTab === "cart" && "border-b-2 border-primary"),
5417
+ children: /* @__PURE__ */ jsx102(Text44, { className: cn82("text-center text-sm font-semibold", activeTab === "cart" ? "text-primary" : "text-muted-foreground"), children: "Cart" })
5151
5418
  }
5152
5419
  )
5153
5420
  ] }),
5154
- /* @__PURE__ */ jsx100(View65, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
5421
+ /* @__PURE__ */ jsx102(View67, { className: "flex-1", children: activeTab === "browse" ? browseSlot : cartSlot })
5155
5422
  ] })
5156
5423
  ] });
5157
5424
  }
5158
5425
 
5159
5426
  // src/layout/checkout-layout.tsx
5160
- import { ScrollView as ScrollView15, View as View66, useWindowDimensions as useWindowDimensions5 } from "react-native";
5161
- import { cn as cn81 } from "@tallyui/theme";
5162
- import { jsx as jsx101, jsxs as jsxs60 } from "react/jsx-runtime";
5427
+ import { ScrollView as ScrollView15, View as View68, useWindowDimensions as useWindowDimensions5 } from "react-native";
5428
+ import { cn as cn83 } from "@tallyui/theme";
5429
+ import { jsx as jsx103, jsxs as jsxs61 } from "react/jsx-runtime";
5163
5430
  function CheckoutLayout({
5164
5431
  summarySlot,
5165
5432
  paymentSlot,
@@ -5171,12 +5438,12 @@ function CheckoutLayout({
5171
5438
  }) {
5172
5439
  const { width } = useWindowDimensions5();
5173
5440
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
5174
- return /* @__PURE__ */ jsxs60(View66, { className: cn81("flex-1 bg-bg", className), ...viewProps, children: [
5175
- headerSlot && /* @__PURE__ */ jsx101(View66, { className: "border-b border-border", children: headerSlot }),
5176
- layout === "split" ? /* @__PURE__ */ jsxs60(View66, { className: "flex-1 flex-row", children: [
5177
- /* @__PURE__ */ jsx101(View66, { className: "flex-1 border-r border-border", children: summarySlot }),
5178
- /* @__PURE__ */ jsx101(View66, { className: "flex-1", children: paymentSlot })
5179
- ] }) : /* @__PURE__ */ jsx101(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs60(View66, { className: "gap-4 p-4", children: [
5441
+ return /* @__PURE__ */ jsxs61(View68, { className: cn83("flex-1 bg-bg", className), ...viewProps, children: [
5442
+ headerSlot && /* @__PURE__ */ jsx103(View68, { className: "border-b border-border", children: headerSlot }),
5443
+ layout === "split" ? /* @__PURE__ */ jsxs61(View68, { className: "flex-1 flex-row", children: [
5444
+ /* @__PURE__ */ jsx103(View68, { className: "flex-1 border-r border-border", children: summarySlot }),
5445
+ /* @__PURE__ */ jsx103(View68, { className: "flex-1", children: paymentSlot })
5446
+ ] }) : /* @__PURE__ */ jsx103(ScrollView15, { className: "flex-1", children: /* @__PURE__ */ jsxs61(View68, { className: "gap-4 p-4", children: [
5180
5447
  summarySlot,
5181
5448
  paymentSlot
5182
5449
  ] }) })
@@ -5184,10 +5451,10 @@ function CheckoutLayout({
5184
5451
  }
5185
5452
 
5186
5453
  // src/layout/settings-layout.tsx
5187
- import { useState as useState26 } from "react";
5188
- import { Pressable as Pressable34, Text as Text44, View as View67, useWindowDimensions as useWindowDimensions6 } from "react-native";
5189
- import { cn as cn82 } from "@tallyui/theme";
5190
- import { jsx as jsx102, jsxs as jsxs61 } from "react/jsx-runtime";
5454
+ import { useState as useState27 } from "react";
5455
+ import { Pressable as Pressable36, Text as Text45, View as View69, useWindowDimensions as useWindowDimensions6 } from "react-native";
5456
+ import { cn as cn84 } from "@tallyui/theme";
5457
+ import { jsx as jsx104, jsxs as jsxs62 } from "react/jsx-runtime";
5191
5458
  function SettingsLayout({
5192
5459
  navSlot,
5193
5460
  contentSlot,
@@ -5199,26 +5466,26 @@ function SettingsLayout({
5199
5466
  }) {
5200
5467
  const { width } = useWindowDimensions6();
5201
5468
  const layout = layoutProp ?? (width >= breakpoint ? "split" : "stacked");
5202
- const [showNav, setShowNav] = useState26(false);
5203
- return /* @__PURE__ */ jsxs61(View67, { className: cn82("flex-1 bg-bg", className), ...viewProps, children: [
5204
- headerSlot && /* @__PURE__ */ jsx102(View67, { className: "border-b border-border", children: headerSlot }),
5205
- layout === "split" ? /* @__PURE__ */ jsxs61(View67, { className: "flex-1 flex-row", children: [
5206
- /* @__PURE__ */ jsx102(View67, { className: "w-64 border-r border-border", children: navSlot }),
5207
- /* @__PURE__ */ jsx102(View67, { className: "flex-1", children: contentSlot })
5208
- ] }) : /* @__PURE__ */ jsx102(View67, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs61(View67, { className: "flex-1", children: [
5469
+ const [showNav, setShowNav] = useState27(false);
5470
+ return /* @__PURE__ */ jsxs62(View69, { className: cn84("flex-1 bg-bg", className), ...viewProps, children: [
5471
+ headerSlot && /* @__PURE__ */ jsx104(View69, { className: "border-b border-border", children: headerSlot }),
5472
+ layout === "split" ? /* @__PURE__ */ jsxs62(View69, { className: "flex-1 flex-row", children: [
5473
+ /* @__PURE__ */ jsx104(View69, { className: "w-64 border-r border-border", children: navSlot }),
5474
+ /* @__PURE__ */ jsx104(View69, { className: "flex-1", children: contentSlot })
5475
+ ] }) : /* @__PURE__ */ jsx104(View69, { className: "flex-1", children: showNav ? /* @__PURE__ */ jsxs62(View69, { className: "flex-1", children: [
5209
5476
  navSlot,
5210
- /* @__PURE__ */ jsx102(Pressable34, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx102(Text44, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
5211
- ] }) : /* @__PURE__ */ jsxs61(View67, { className: "flex-1", children: [
5212
- /* @__PURE__ */ jsx102(Pressable34, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx102(Text44, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
5477
+ /* @__PURE__ */ jsx104(Pressable36, { onPress: () => setShowNav(false), className: "border-t border-border p-3", children: /* @__PURE__ */ jsx104(Text45, { className: "text-center text-sm font-medium text-primary", children: "Done" }) })
5478
+ ] }) : /* @__PURE__ */ jsxs62(View69, { className: "flex-1", children: [
5479
+ /* @__PURE__ */ jsx104(Pressable36, { onPress: () => setShowNav(true), className: "border-b border-border px-4 py-2", children: /* @__PURE__ */ jsx104(Text45, { className: "text-sm font-medium text-primary", children: "Menu" }) }),
5213
5480
  contentSlot
5214
5481
  ] }) })
5215
5482
  ] });
5216
5483
  }
5217
5484
 
5218
5485
  // src/layout/live-tab-screen.tsx
5219
- import { Pressable as Pressable35, Text as Text45, View as View68 } from "react-native";
5220
- import { cn as cn83 } from "@tallyui/theme";
5221
- import { jsx as jsx103, jsxs as jsxs62 } from "react/jsx-runtime";
5486
+ import { Pressable as Pressable37, Text as Text46, View as View70 } from "react-native";
5487
+ import { cn as cn85 } from "@tallyui/theme";
5488
+ import { jsx as jsx105, jsxs as jsxs63 } from "react/jsx-runtime";
5222
5489
  function LiveTabScreen({
5223
5490
  state,
5224
5491
  onUseHere,
@@ -5235,21 +5502,21 @@ function LiveTabScreen({
5235
5502
  const body = state === "parked" ? parkedBody : blockedBody;
5236
5503
  const buttonLabel = state === "parked" ? useHereLabel : reloadLabel;
5237
5504
  const onPress = state === "parked" ? onUseHere : onReload;
5238
- return /* @__PURE__ */ jsxs62(View68, { className: cn83("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
5239
- /* @__PURE__ */ jsx103(Text45, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
5240
- /* @__PURE__ */ jsx103(Text45, { className: "text-center text-sm text-muted-foreground", children: body }),
5241
- /* @__PURE__ */ jsx103(Pressable35, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx103(Text45, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
5505
+ return /* @__PURE__ */ jsxs63(View70, { className: cn85("flex-1 items-center justify-center gap-4 bg-bg p-6", className), ...viewProps, children: [
5506
+ /* @__PURE__ */ jsx105(Text46, { className: "text-center text-lg font-bold text-foreground", children: parkedTitle }),
5507
+ /* @__PURE__ */ jsx105(Text46, { className: "text-center text-sm text-muted-foreground", children: body }),
5508
+ /* @__PURE__ */ jsx105(Pressable37, { onPress, className: "items-center rounded-lg bg-primary px-4 py-3", children: /* @__PURE__ */ jsx105(Text46, { className: "text-sm font-semibold text-primary-foreground", children: buttonLabel }) })
5242
5509
  ] });
5243
5510
  }
5244
5511
 
5245
5512
  // src/layout/store-settings-choice-screen.tsx
5246
- import { useState as useState27 } from "react";
5247
- import { Pressable as Pressable36, Text as Text46, View as View69 } from "react-native";
5248
- import { cn as cn84 } from "@tallyui/theme";
5249
- import { jsx as jsx104, jsxs as jsxs63 } from "react/jsx-runtime";
5513
+ import { useState as useState28 } from "react";
5514
+ import { Pressable as Pressable38, Text as Text47, View as View71 } from "react-native";
5515
+ import { cn as cn86 } from "@tallyui/theme";
5516
+ import { jsx as jsx106, jsxs as jsxs64 } from "react/jsx-runtime";
5250
5517
  function useSectionSelection(options, initialValue) {
5251
5518
  const preset = options.length === 1 ? options[0].value : options.find((o) => o.value === initialValue)?.value;
5252
- return useState27(preset);
5519
+ return useState28(preset);
5253
5520
  }
5254
5521
  function defaultCountryName(code, locale) {
5255
5522
  try {
@@ -5295,41 +5562,41 @@ function StoreSettingsChoiceScreen({
5295
5562
  else if (initial?.channel !== void 0) choice.channel = initial.channel;
5296
5563
  onSubmit(choice);
5297
5564
  };
5298
- return /* @__PURE__ */ jsxs63(View69, { className: cn84("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
5299
- /* @__PURE__ */ jsxs63(View69, { className: "gap-2", children: [
5300
- /* @__PURE__ */ jsx104(Text46, { className: "text-lg font-bold text-foreground", children: title }),
5301
- /* @__PURE__ */ jsx104(Text46, { className: "text-sm text-muted-foreground", children: body })
5565
+ return /* @__PURE__ */ jsxs64(View71, { className: cn86("w-full max-w-[560px] flex-1 self-center gap-6 bg-bg p-6", className), ...viewProps, children: [
5566
+ /* @__PURE__ */ jsxs64(View71, { className: "gap-2", children: [
5567
+ /* @__PURE__ */ jsx106(Text47, { className: "text-lg font-bold text-foreground", children: title }),
5568
+ /* @__PURE__ */ jsx106(Text47, { className: "text-sm text-muted-foreground", children: body })
5302
5569
  ] }),
5303
- showRegions && /* @__PURE__ */ jsx104(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
5304
- showCountries && /* @__PURE__ */ jsx104(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
5305
- showChannels && /* @__PURE__ */ jsx104(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
5306
- /* @__PURE__ */ jsx104(
5307
- Pressable36,
5570
+ showRegions && /* @__PURE__ */ jsx106(ChoiceSection, { label: regionLabel, options: regionOptions, selected: region, onSelect: setRegion }),
5571
+ showCountries && /* @__PURE__ */ jsx106(ChoiceSection, { label: countryLabel, options: countryOptions, selected: country, onSelect: setCountry }),
5572
+ showChannels && /* @__PURE__ */ jsx106(ChoiceSection, { label: channelLabel, options: channelOptions, selected: channel, onSelect: setChannel }),
5573
+ /* @__PURE__ */ jsx106(
5574
+ Pressable38,
5308
5575
  {
5309
5576
  onPress: handleSubmit,
5310
5577
  disabled: !complete,
5311
- className: cn84("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
5312
- children: /* @__PURE__ */ jsx104(Text46, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
5578
+ className: cn86("items-center rounded-lg bg-primary px-4 py-3", !complete && "opacity-50"),
5579
+ children: /* @__PURE__ */ jsx106(Text47, { className: "text-sm font-semibold text-primary-foreground", children: submitLabel })
5313
5580
  }
5314
5581
  )
5315
5582
  ] });
5316
5583
  }
5317
5584
  function ChoiceSection({ label, options, selected, onSelect }) {
5318
- return /* @__PURE__ */ jsxs63(View69, { className: "gap-1.5", children: [
5319
- /* @__PURE__ */ jsx104(Text46, { className: "text-xs font-semibold text-muted-foreground", children: label }),
5320
- /* @__PURE__ */ jsx104(View69, { className: "rounded-lg border border-border", children: options.map((option, index) => {
5585
+ return /* @__PURE__ */ jsxs64(View71, { className: "gap-1.5", children: [
5586
+ /* @__PURE__ */ jsx106(Text47, { className: "text-xs font-semibold text-muted-foreground", children: label }),
5587
+ /* @__PURE__ */ jsx106(View71, { className: "rounded-lg border border-border", children: options.map((option, index) => {
5321
5588
  const checked = option.value === selected;
5322
- return /* @__PURE__ */ jsxs63(
5323
- Pressable36,
5589
+ return /* @__PURE__ */ jsxs64(
5590
+ Pressable38,
5324
5591
  {
5325
5592
  onPress: () => onSelect(option.value),
5326
5593
  accessibilityRole: "radio",
5327
5594
  "aria-checked": checked,
5328
5595
  testID: `choice-option-${option.value}`,
5329
- className: cn84("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
5596
+ className: cn86("flex-row items-center gap-3 px-4 py-3", index > 0 && "border-t border-border", checked && "bg-primary/10"),
5330
5597
  children: [
5331
- /* @__PURE__ */ jsx104(View69, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx104(View69, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
5332
- /* @__PURE__ */ jsx104(Text46, { className: cn84("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
5598
+ /* @__PURE__ */ jsx106(View71, { className: "h-4 w-4 items-center justify-center rounded-full border border-primary", children: checked && /* @__PURE__ */ jsx106(View71, { testID: `choice-option-${option.value}-dot`, className: "h-2.5 w-2.5 rounded-full bg-primary" }) }),
5599
+ /* @__PURE__ */ jsx106(Text47, { className: cn86("text-sm", checked ? "font-semibold text-primary" : "text-foreground"), children: option.label })
5333
5600
  ]
5334
5601
  },
5335
5602
  option.value
@@ -5474,6 +5741,7 @@ export {
5474
5741
  ProductPrice,
5475
5742
  ProductSku,
5476
5743
  ProductStockBadge,
5744
+ ProductTable,
5477
5745
  ProductTitle,
5478
5746
  ProductVariantPicker,
5479
5747
  Progress,
@@ -5534,6 +5802,7 @@ export {
5534
5802
  TooltipContent,
5535
5803
  TooltipTrigger,
5536
5804
  VStack,
5805
+ ViewToggle,
5537
5806
  XIcon,
5538
5807
  avatarVariants,
5539
5808
  badgeTextVariants,
@@ -5541,6 +5810,7 @@ export {
5541
5810
  buttonTextVariants,
5542
5811
  buttonVariants,
5543
5812
  createSvgIcon,
5813
+ defaultProductColumns,
5544
5814
  describeRegisterBarPill,
5545
5815
  discountLabel,
5546
5816
  formatStockSyncTime,
@@ -5556,6 +5826,7 @@ export {
5556
5826
  toastVariants,
5557
5827
  toggleTextVariants,
5558
5828
  toggleVariants,
5829
+ useDefaultProductColumns,
5559
5830
  useInputContext,
5560
5831
  vstackVariants
5561
5832
  };