@flowselections/floriday-voorraad 1.0.152 → 1.0.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist-lib/components/fs-ui/DataTable.d.ts.map +1 -1
  2. package/dist-lib/components/fs-ui/DataTable.js +8 -8
  3. package/dist-lib/components/fs-ui/FilterChips.d.ts +1 -1
  4. package/dist-lib/components/fs-ui/FilterChips.d.ts.map +1 -1
  5. package/dist-lib/components/fs-ui/FilterChips.js +3 -3
  6. package/dist-lib/components/fs-ui/FilterPanel.d.ts +19 -0
  7. package/dist-lib/components/fs-ui/FilterPanel.d.ts.map +1 -0
  8. package/dist-lib/components/fs-ui/FilterPanel.js +10 -0
  9. package/dist-lib/components/fs-ui/FiltersButton.d.ts +6 -0
  10. package/dist-lib/components/fs-ui/FiltersButton.d.ts.map +1 -0
  11. package/dist-lib/components/fs-ui/FiltersButton.js +7 -0
  12. package/dist-lib/components/fs-ui/HeaderButton.d.ts +16 -0
  13. package/dist-lib/components/fs-ui/HeaderButton.d.ts.map +1 -0
  14. package/dist-lib/components/fs-ui/HeaderButton.js +10 -0
  15. package/dist-lib/components/fs-ui/KpiRow.d.ts +2 -2
  16. package/dist-lib/components/fs-ui/KpiRow.js +3 -3
  17. package/dist-lib/components/fs-ui/NoticeBar.d.ts +10 -0
  18. package/dist-lib/components/fs-ui/NoticeBar.d.ts.map +1 -0
  19. package/dist-lib/components/fs-ui/NoticeBar.js +16 -0
  20. package/dist-lib/components/fs-ui/PageHeader.d.ts +6 -5
  21. package/dist-lib/components/fs-ui/PageHeader.d.ts.map +1 -1
  22. package/dist-lib/components/fs-ui/PageHeader.js +4 -3
  23. package/dist-lib/components/fs-ui/Pagination.d.ts +10 -0
  24. package/dist-lib/components/fs-ui/Pagination.d.ts.map +1 -0
  25. package/dist-lib/components/fs-ui/Pagination.js +10 -0
  26. package/dist-lib/components/fs-ui/PillTabs.d.ts +3 -5
  27. package/dist-lib/components/fs-ui/PillTabs.d.ts.map +1 -1
  28. package/dist-lib/components/fs-ui/PillTabs.js +25 -15
  29. package/dist-lib/components/fs-ui/RowMenu.d.ts +13 -0
  30. package/dist-lib/components/fs-ui/RowMenu.d.ts.map +1 -0
  31. package/dist-lib/components/fs-ui/RowMenu.js +7 -0
  32. package/dist-lib/components/fs-ui/SearchInput.d.ts +1 -4
  33. package/dist-lib/components/fs-ui/SearchInput.d.ts.map +1 -1
  34. package/dist-lib/components/fs-ui/SearchInput.js +23 -19
  35. package/dist-lib/components/fs-ui/ShortcutHelp.d.ts +8 -0
  36. package/dist-lib/components/fs-ui/ShortcutHelp.d.ts.map +1 -0
  37. package/dist-lib/components/fs-ui/ShortcutHelp.js +6 -0
  38. package/dist-lib/components/fs-ui/Toolbar.d.ts +7 -3
  39. package/dist-lib/components/fs-ui/Toolbar.d.ts.map +1 -1
  40. package/dist-lib/components/fs-ui/Toolbar.js +6 -3
  41. package/dist-lib/components/fs-ui/UpdatedAt.d.ts +6 -2
  42. package/dist-lib/components/fs-ui/UpdatedAt.d.ts.map +1 -1
  43. package/dist-lib/components/fs-ui/UpdatedAt.js +16 -8
  44. package/dist-lib/components/voorraad/FloridayConnectionNotice.d.ts +2 -1
  45. package/dist-lib/components/voorraad/FloridayConnectionNotice.d.ts.map +1 -1
  46. package/dist-lib/components/voorraad/FloridayConnectionNotice.js +9 -4
  47. package/dist-lib/components/voorraad/FustenPage.d.ts.map +1 -1
  48. package/dist-lib/components/voorraad/FustenPage.js +90 -26
  49. package/dist-lib/components/voorraad/OrderHistoryCard.d.ts +3 -1
  50. package/dist-lib/components/voorraad/OrderHistoryCard.d.ts.map +1 -1
  51. package/dist-lib/components/voorraad/OrderHistoryCard.js +26 -50
  52. package/dist-lib/components/voorraad/PublicatiesPage.d.ts.map +1 -1
  53. package/dist-lib/components/voorraad/PublicatiesPage.js +41 -36
  54. package/dist-lib/components/voorraad/Sneltoetsen.d.ts +1 -1
  55. package/dist-lib/components/voorraad/Sneltoetsen.d.ts.map +1 -1
  56. package/dist-lib/components/voorraad/Sneltoetsen.js +12 -13
  57. package/dist-lib/components/voorraad/StockIntegrityAlert.d.ts +42 -1
  58. package/dist-lib/components/voorraad/StockIntegrityAlert.d.ts.map +1 -1
  59. package/dist-lib/components/voorraad/StockIntegrityAlert.js +30 -6
  60. package/dist-lib/components/voorraad/StockMutationHistoryCard.d.ts.map +1 -1
  61. package/dist-lib/components/voorraad/StockMutationHistoryCard.js +10 -46
  62. package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -1
  63. package/dist-lib/components/voorraad/ValidationOverviewTable.js +7 -38
  64. package/dist-lib/components/voorraad/ValidationPage.d.ts.map +1 -1
  65. package/dist-lib/components/voorraad/ValidationPage.js +3 -3
  66. package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
  67. package/dist-lib/components/voorraad/VoorraadPage.js +28 -10
  68. package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts.map +1 -1
  69. package/dist-lib/components/voorraad/artikel/ArtikelPagina.js +16 -3
  70. package/dist-lib/components/voorraad/lijst/ImporteerKnop.d.ts.map +1 -1
  71. package/dist-lib/components/voorraad/lijst/ImporteerKnop.js +1 -1
  72. package/dist-lib/components/voorraad/lijst/LijstExportKnop.d.ts.map +1 -1
  73. package/dist-lib/components/voorraad/lijst/LijstExportKnop.js +1 -1
  74. package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.js +10 -10
  75. package/dist-lib/integrations/supabase/types.d.ts +102 -0
  76. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  77. package/dist-lib/lib/labels.d.ts +42 -0
  78. package/dist-lib/lib/labels.d.ts.map +1 -0
  79. package/dist-lib/lib/labels.js +152 -0
  80. package/dist-lib/lib/notatie.d.ts +4 -0
  81. package/dist-lib/lib/notatie.d.ts.map +1 -0
  82. package/dist-lib/lib/notatie.js +18 -0
  83. package/dist-lib/lib/voorraad-lijst.d.ts +4 -1
  84. package/dist-lib/lib/voorraad-lijst.d.ts.map +1 -1
  85. package/dist-lib/lib/voorraad-lijst.js +16 -5
  86. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAC3B,OAAO,EACP,IAAI,EACJ,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,MAAM,EACN,SAAoB,EACpB,SAAS,EACT,KAAK,EACL,UAAU,EACV,UAAU,EACV,YAAgB,EAChB,QAAe,GAChB,EAAE;IACD,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACzB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;KAAE,CAAC;IACrI,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,+BA0IA"}
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAC3B,OAAO,EACP,IAAI,EACJ,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,MAAM,EACN,SAAoB,EACpB,SAAS,EACT,KAAK,EACL,UAAU,EACV,UAAU,EACV,YAAgB,EAChB,QAAe,GAChB,EAAE;IACD,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACzB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;KAAE,CAAC;IACrI,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,+BAoJA"}
@@ -50,19 +50,19 @@ export function DataTable({ columns, rows, getId, loading, sort, onSort, onOpen,
50
50
  document.querySelector(`[data-rij="${actief}"]`)?.scrollIntoView({ block: "nearest" });
51
51
  }, [actief]);
52
52
  const allesGekozen = selection ? ids.length > 0 && ids.every((id) => selection.selected.has(id)) : false;
53
- const kolomBreedtes = [selection ? "44px" : undefined, ...columns.map((c) => c.width), onOpen || rowActions ? "96px" : undefined].filter((_, i, a) => i > 0 || a[0] !== undefined);
53
+ const kolomBreedtes = [selection ? "36px" : undefined, ...columns.map((c) => c.width), onOpen || rowActions ? "96px" : undefined].filter((_, i, a) => i > 0 || a[0] !== undefined);
54
54
  const leeg = !loading && rows.length === 0;
55
55
  const eersteLaad = loading && rows.length === 0;
56
- return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-border bg-card shadow-sm", children: [mobileCard && (_jsxs("ul", { className: "divide-y divide-border md:hidden", children: [eersteLaad && Array.from({ length: 5 }).map((_, i) => (_jsxs("li", { className: "space-y-2 p-4", "aria-hidden": true, children: [_jsx("div", { className: "h-4 w-2/3 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-1/2 animate-pulse rounded bg-muted" })] }, i))), rows.map((r) => (_jsx("li", { className: "transition-opacity duration-150 " + (loading ? "opacity-60" : ""), children: _jsx("div", { role: onOpen ? "button" : undefined, tabIndex: onOpen ? 0 : undefined, onClick: () => onOpen?.(r), onKeyDown: (e) => { if (e.key === "Enter" && onOpen)
57
- onOpen(r); }, className: "block min-h-11 p-4 active:bg-muted/60", children: mobileCard(r) }) }, getId(r)))), leeg && _jsx("li", { children: empty })] })), _jsx("div", { className: (mobileCard ? "hidden md:block " : "") + "max-h-[calc(100vh-12rem)] overflow-auto", children: _jsxs("table", { className: "w-full min-w-[900px] table-fixed text-sm", children: [_jsxs("colgroup", { children: [selection && _jsx("col", { style: { width: "44px" } }), columns.map((c) => _jsx("col", { style: c.width ? { width: c.width } : undefined }, c.key)), (onOpen || rowActions) && _jsx("col", { style: { width: "96px" } })] }), _jsx("thead", { className: "sticky top-0 z-10 bg-card", children: _jsxs("tr", { className: "h-10 border-b border-border", children: [selection && (_jsx("th", { className: "px-3 text-left", children: _jsx("input", { type: "checkbox", className: "h-4 w-4 rounded accent-primary", checked: allesGekozen, onChange: () => selection.onToggleAll(ids), "aria-label": "Alles op deze pagina kiezen" }) })), columns.map((c) => {
56
+ return (_jsxs("div", { className: "overflow-hidden rounded-xl border border-border bg-card shadow-sm", children: [(_jsxs("ul", { className: "divide-y divide-border md:hidden", children: [eersteLaad && Array.from({ length: 5 }).map((_, i) => (_jsxs("li", { className: "space-y-2 p-4", "aria-hidden": true, children: [_jsx("div", { className: "h-4 w-2/3 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-1/2 animate-pulse rounded bg-muted" })] }, i))), rows.map((r) => (_jsx("li", { className: "transition-opacity duration-150 " + (loading ? "opacity-60" : ""), children: _jsx("div", { role: onOpen ? "button" : undefined, tabIndex: onOpen ? 0 : undefined, onClick: () => onOpen?.(r), onKeyDown: (e) => { if (e.key === "Enter" && onOpen)
57
+ onOpen(r); }, className: "block min-h-11 p-4 active:bg-muted/60", children: mobileCard ? mobileCard(r) : (_jsx("div", { className: "space-y-1", children: columns.map((c, ci) => (_jsxs("div", { className: ci === 0 ? "min-w-0 text-sm font-medium" : "flex min-w-0 items-baseline justify-between gap-3 text-xs", children: [ci > 0 && _jsx("span", { className: "shrink-0 text-muted-foreground", children: c.header }), _jsx("div", { className: "min-w-0 truncate", children: c.render(r) })] }, c.key))) })) }) }, getId(r)))), leeg && _jsx("li", { children: empty })] })), _jsx("div", { className: "hidden max-h-[calc(100dvh-7rem)] overflow-auto md:block xl:max-h-none xl:overflow-visible", children: _jsxs("table", { className: "w-full [&_thead_th]:h-10 [&_thead_th]:text-[11px] [&_thead_th]:font-semibold [&_thead_th]:uppercase [&_thead_th]:tracking-wide [&_thead_th]:text-muted-foreground min-w-[900px] table-fixed caption-bottom text-sm [&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10 [&_thead_th]:bg-card [&_tbody_tr]:transition-colors", children: [_jsxs("colgroup", { children: [selection && _jsx("col", { style: { width: "36px" } }), columns.map((c) => _jsx("col", { style: c.width ? { width: c.width } : undefined }, c.key)), (onOpen || rowActions) && _jsx("col", { style: { width: "96px" } })] }), _jsx("thead", { children: _jsxs("tr", { className: "border-b border-border", children: [selection && (_jsx("th", { className: "px-2 text-left align-middle", children: _jsx("input", { type: "checkbox", className: "h-4 w-4 rounded accent-primary", checked: allesGekozen, onChange: () => selection.onToggleAll(ids), "aria-label": "Alles op deze pagina kiezen" }) })), columns.map((c) => {
58
58
  const act = sort && c.sortKey && sort.key === c.sortKey;
59
- return (_jsx("th", { scope: "col", className: "px-3 text-left text-[11px] font-semibold uppercase tracking-wider text-muted-foreground", "aria-sort": act ? (sort.asc ? "ascending" : "descending") : c.sortKey ? "none" : undefined, children: c.sortKey && onSort ? (_jsxs("button", { type: "button", onClick: () => onSort(c.sortKey), className: "inline-flex items-center gap-1 uppercase hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm " + (act ? "text-foreground" : ""), children: [c.header, act && (sort.asc ? _jsx(ArrowUp, { className: "h-3 w-3" }) : _jsx(ArrowDown, { className: "h-3 w-3" }))] })) : c.header }, c.key));
60
- }), (onOpen || rowActions) && _jsx("th", { className: "px-3", children: _jsx("span", { className: "sr-only", children: "Acties" }) })] }) }), _jsxs("tbody", { children: [eersteLaad && _jsx(TableSkeleton, { columns: kolomBreedtes, rows: skeletonRows }), rows.map((r, i) => {
59
+ return (_jsx("th", { scope: "col", className: "px-2 text-left align-middle", "aria-sort": act ? (sort.asc ? "ascending" : "descending") : c.sortKey ? "none" : undefined, children: c.sortKey && onSort ? (_jsxs("button", { type: "button", onClick: () => onSort(c.sortKey), className: "inline-flex items-center gap-1 uppercase tracking-wide hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm " + (act ? "text-foreground" : ""), children: [c.header, act && (sort.asc ? _jsx(ArrowUp, { className: "h-3 w-3" }) : _jsx(ArrowDown, { className: "h-3 w-3" }))] })) : c.header }, c.key));
60
+ }), (onOpen || rowActions) && _jsx("th", { className: "px-2", children: _jsx("span", { className: "sr-only", children: "Acties" }) })] }) }), _jsxs("tbody", { children: [eersteLaad && _jsx(TableSkeleton, { columns: kolomBreedtes, rows: skeletonRows }), rows.map((r, i) => {
61
61
  const id = getId(r);
62
62
  const isActief = i === actief;
63
63
  const gekozen = selection?.selected.has(id);
64
64
  return (_jsxs("tr", { "data-rij": i, onClick: () => setActief(i), onDoubleClick: () => onOpen?.(r), className: "group h-[60px] border-b border-border transition-colors duration-150 last:border-0 hover:bg-muted/40 motion-reduce:transition-none " +
65
- (isActief || gekozen ? "bg-primary/5 shadow-[inset_3px_0_0_var(--primary)] " : "") +
66
- (loading ? "opacity-60" : ""), children: [selection && (_jsx("td", { className: "px-3", onClick: (e) => e.stopPropagation(), children: _jsx("input", { type: "checkbox", className: "h-4 w-4 rounded accent-primary", checked: !!gekozen, onChange: () => selection.onToggle(id), "aria-label": `Kies ${selection.label(r)}` }) })), columns.map((c) => _jsx("td", { className: "truncate px-3 " + (c.className ?? ""), children: c.render(r) }, c.key)), (onOpen || rowActions) && (_jsx("td", { className: "px-3", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [rowActions?.(r), onOpen && (_jsx("button", { type: "button", onClick: () => onOpen(r), "aria-label": openLabel, title: openLabel, className: "inline-flex h-8 w-8 items-center justify-center rounded-lg text-muted-foreground transition-opacity duration-150 hover:bg-muted hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring " + (isActief ? "opacity-100" : "opacity-0 group-hover:opacity-100"), children: _jsx(ChevronRight, { className: "h-4 w-4" }) }))] }) }))] }, id));
67
- }), leeg && (_jsx("tr", { children: _jsx("td", { colSpan: columns.length + (selection ? 1 : 0) + (onOpen || rowActions ? 1 : 0), children: empty }) }))] })] }) })] }));
65
+ (isActief ? "bg-muted/60 " : "") +
66
+ (loading ? "opacity-60" : ""), children: [selection && (_jsxs("td", { className: "relative px-2 py-0 align-middle", onClick: (e) => e.stopPropagation(), children: [(gekozen || isActief) && _jsx("span", { "aria-hidden": true, className: "absolute inset-y-0 left-0 w-[3px] " + (gekozen ? "bg-primary" : "bg-primary/40") }), _jsx("input", { type: "checkbox", className: "h-4 w-4 rounded accent-primary", checked: !!gekozen, onChange: () => selection.onToggle(id), "aria-label": `Kies ${selection.label(r)}` })] })), columns.map((c) => _jsx("td", { className: "truncate px-2 py-0 align-middle " + (c.className ?? ""), children: c.render(r) }, c.key)), (onOpen || rowActions) && (_jsx("td", { className: "px-2 py-0 align-middle", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [rowActions?.(r), onOpen && (_jsx("button", { type: "button", onClick: () => onOpen(r), "aria-label": openLabel, title: openLabel, className: "inline-flex h-8 w-8 items-center justify-center rounded-lg text-muted-foreground transition-opacity duration-150 hover:bg-muted hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring " + (isActief ? "opacity-100" : "opacity-0 group-hover:opacity-100"), children: _jsx(ChevronRight, { className: "h-4 w-4" }) }))] }) }))] }, id));
67
+ }), leeg && (_jsx("tr", { className: "hover:bg-transparent", children: _jsx("td", { colSpan: columns.length + (selection ? 1 : 0) + (onOpen || rowActions ? 1 : 0), children: empty }) }))] })] }) })] }));
68
68
  }
@@ -5,7 +5,7 @@ export interface FilterChip {
5
5
  icon?: ReactNode;
6
6
  onRemove: () => void;
7
7
  }
8
- /** Actieve filters als ronde chips met icoon en kruisje; "Alles wissen" bij meer dan één. */
8
+ /** FilterChip exact naar Verkooporders; "Alles wissen" bij meer dan één. Inline in de werkbalk. */
9
9
  export declare function FilterChips({ chips, onClearAll }: {
10
10
  chips: FilterChip[];
11
11
  onClearAll?: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/FilterChips.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,sCAoBlG"}
1
+ {"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/FilterChips.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,sCAwBlG"}
@@ -1,8 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { X } from "lucide-react";
3
- /** Actieve filters als ronde chips met icoon en kruisje; "Alles wissen" bij meer dan één. */
3
+ /** FilterChip exact naar Verkooporders; "Alles wissen" bij meer dan één. Inline in de werkbalk. */
4
4
  export function FilterChips({ chips, onClearAll }) {
5
5
  if (chips.length === 0)
6
6
  return null;
7
- return (_jsxs("div", { className: "flex flex-wrap items-center gap-2", "aria-label": "Actieve filters", children: [chips.map((c) => (_jsxs("span", { className: "inline-flex h-8 items-center gap-1.5 rounded-full border border-primary/30 bg-primary/10 pl-3 pr-1 text-sm text-primary [&_svg]:h-4 [&_svg]:w-4", children: [c.icon, c.label, _jsx("button", { type: "button", onClick: c.onRemove, "aria-label": `Filter ${c.label} wissen`, className: "inline-flex h-6 w-6 items-center justify-center rounded-full hover:bg-primary/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }, c.key))), onClearAll && chips.length > 1 && (_jsx("button", { type: "button", onClick: onClearAll, className: "h-8 rounded-full px-3 text-sm text-muted-foreground hover:text-foreground", children: "Alles wissen" }))] }));
7
+ return (_jsxs(_Fragment, { children: [chips.map((c) => (_jsxs("button", { type: "button", onClick: c.onRemove, "aria-label": `Filter ${c.label} wissen`, className: "inline-flex h-8 items-center gap-1.5 rounded-full border border-border bg-muted px-3 text-xs font-medium text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:h-3.5 [&_svg]:w-3.5", children: [c.icon, c.label, _jsx(X, { className: "h-3.5 w-3.5", "aria-hidden": true })] }, c.key))), onClearAll && chips.length > 1 && (_jsx("button", { type: "button", onClick: onClearAll, className: "h-8 rounded-full px-2 text-xs font-medium text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: "Alles wissen" }))] }));
8
8
  }
@@ -0,0 +1,19 @@
1
+ import type { ReactNode } from "react";
2
+ /** Zijpaneel met alle extra filters (rechts op desktop, volledig scherm op mobiel). */
3
+ export declare function FilterPanel({ open, onOpenChange, children, onClear }: {
4
+ open: boolean;
5
+ onOpenChange: (o: boolean) => void;
6
+ children: ReactNode;
7
+ onClear?: () => void;
8
+ }): import("react").JSX.Element;
9
+ /** Eén filtergroep met keuzeknoppen. */
10
+ export declare function FilterGroup<T extends string>({ title, value, options, onChange }: {
11
+ title: string;
12
+ value: T;
13
+ options: {
14
+ value: T;
15
+ label: string;
16
+ }[];
17
+ onChange: (v: T) => void;
18
+ }): import("react").JSX.Element;
19
+ //# sourceMappingURL=FilterPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterPanel.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/FilterPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,+BAatK;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAA;CAAE,+BAc/K"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Dialog, DialogContent, DialogHeader, DialogTitle } from "@flowselections/core";
3
+ /** Zijpaneel met alle extra filters (rechts op desktop, volledig scherm op mobiel). */
4
+ export function FilterPanel({ open, onOpenChange, children, onClear }) {
5
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "left-auto right-0 top-0 h-[100dvh] max-w-sm translate-x-0 translate-y-0 rounded-none sm:rounded-none flex flex-col gap-4 data-[state=open]:slide-in-from-right", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Filters" }) }), _jsx("div", { className: "min-h-0 flex-1 space-y-5 overflow-auto", children: children }), _jsxs("div", { className: "flex justify-between gap-2 border-t border-border pt-3", children: [onClear ? _jsx(Button, { variant: "ghost", size: "sm", onClick: onClear, children: "Alles wissen" }) : _jsx("span", {}), _jsx(Button, { size: "sm", onClick: () => onOpenChange(false), children: "Klaar" })] })] }) }));
6
+ }
7
+ /** Eén filtergroep met keuzeknoppen. */
8
+ export function FilterGroup({ title, value, options, onChange }) {
9
+ return (_jsxs("fieldset", { className: "space-y-2", children: [_jsx("legend", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: title }), _jsx("div", { className: "flex flex-wrap gap-2", children: options.map((o) => (_jsx("button", { type: "button", "aria-pressed": o.value === value, onClick: () => onChange(o.value), className: "h-8 rounded-full border px-3 text-xs font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring " + (o.value === value ? "border-primary/30 bg-primary/10 text-foreground" : "border-border bg-card text-foreground/80 hover:bg-muted"), children: o.label }, o.value))) })] }));
10
+ }
@@ -0,0 +1,6 @@
1
+ /** Knop "Filters" exact naar Verkooporders, met teller als er filters actief zijn. */
2
+ export declare function FiltersButton({ count, onClick }: {
3
+ count: number;
4
+ onClick: () => void;
5
+ }): import("react").JSX.Element;
6
+ //# sourceMappingURL=FiltersButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FiltersButton.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/FiltersButton.tsx"],"names":[],"mappings":"AAGA,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BAYvF"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@flowselections/core";
3
+ import { SlidersHorizontal } from "lucide-react";
4
+ /** Knop "Filters" exact naar Verkooporders, met teller als er filters actief zijn. */
5
+ export function FiltersButton({ count, onClick }) {
6
+ return (_jsxs(Button, { variant: "outline", size: "sm", onClick: onClick, "aria-label": "Filters", className: "relative h-10 px-3 sm:h-9", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4 sm:mr-2" }), _jsx("span", { className: "hidden sm:inline", children: "Filters" }), count > 0 && (_jsx("span", { className: "ml-2 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground", children: count }))] }));
7
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ /** Secundaire kopknop exact naar Verkooporders: outline sm; op mobiel alleen icoon van 40 px. */
3
+ export declare function HeaderButton({ icon, label, onClick, disabled }: {
4
+ icon: ReactNode;
5
+ label: string;
6
+ onClick?: () => void;
7
+ disabled?: boolean;
8
+ }): import("react").JSX.Element;
9
+ /** Primaire kopknop: size sm met kbd-hint; op mobiel verborgen (vaste knop onderin). */
10
+ export declare function HeaderPrimary({ icon, label, kbd, onClick }: {
11
+ icon: ReactNode;
12
+ label: string;
13
+ kbd?: string;
14
+ onClick: () => void;
15
+ }): import("react").JSX.Element;
16
+ //# sourceMappingURL=HeaderButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderButton.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/HeaderButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,+BAM5I;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BASjI"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@flowselections/core";
3
+ /** Secundaire kopknop exact naar Verkooporders: outline sm; op mobiel alleen icoon van 40 px. */
4
+ export function HeaderButton({ icon, label, onClick, disabled }) {
5
+ return (_jsxs(Button, { variant: "outline", size: "sm", onClick: onClick, disabled: disabled, "aria-label": label, className: "h-10 w-10 p-0 sm:h-9 sm:w-auto sm:px-3 [&_svg]:h-4 [&_svg]:w-4 [&_svg]:sm:mr-2", children: [icon, " ", _jsx("span", { className: "hidden sm:inline", children: label })] }));
6
+ }
7
+ /** Primaire kopknop: size sm met kbd-hint; op mobiel verborgen (vaste knop onderin). */
8
+ export function HeaderPrimary({ icon, label, kbd, onClick }) {
9
+ return (_jsxs(Button, { size: "sm", className: "hidden sm:inline-flex [&_svg]:mr-2 [&_svg]:h-4 [&_svg]:w-4", onClick: onClick, children: [icon, " ", label, kbd && (_jsx("kbd", { "aria-hidden": true, className: "ml-2 hidden rounded border border-primary-foreground/30 bg-primary-foreground/15 px-1.5 font-mono text-[10px] leading-4 text-primary-foreground sm:inline-block", children: kbd }))] }));
10
+ }
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
2
  /**
3
- * Rij KPI-tegels: 4 naast elkaar vanaf desktop, 2 op tablet; op mobiel een
4
- * veegbare rij (snap per tegel, ca. 78% breed) zonder zichtbare scrollbalk.
3
+ * Rij KPI-tegels: 4 naast elkaar vanaf desktop, 2 op tablet; op mobiel veegbaar.
4
+ * De eerste tegel staat binnen de paginamarge van 16 px (scroll-padding), nooit tegen de rand.
5
5
  */
6
6
  export declare function KpiRow({ children, label }: {
7
7
  children: ReactNode;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
- * Rij KPI-tegels: 4 naast elkaar vanaf desktop, 2 op tablet; op mobiel een
4
- * veegbare rij (snap per tegel, ca. 78% breed) zonder zichtbare scrollbalk.
3
+ * Rij KPI-tegels: 4 naast elkaar vanaf desktop, 2 op tablet; op mobiel veegbaar.
4
+ * De eerste tegel staat binnen de paginamarge van 16 px (scroll-padding), nooit tegen de rand.
5
5
  */
6
6
  export function KpiRow({ children, label = "Kerncijfers" }) {
7
- return (_jsx("section", { "aria-label": label, className: "-mx-4 flex snap-x snap-mandatory gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] sm:mx-0 sm:grid sm:grid-cols-2 sm:overflow-visible sm:px-0 sm:pb-0 lg:grid-cols-4 [&::-webkit-scrollbar]:hidden [&>*]:w-[78%] [&>*]:shrink-0 [&>*]:snap-start sm:[&>*]:w-auto", children: children }));
7
+ return (_jsx("section", { "aria-label": label, className: "-mx-4 flex snap-x snap-mandatory scroll-px-4 gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] sm:mx-0 sm:grid sm:grid-cols-2 sm:overflow-visible sm:px-0 sm:pb-0 lg:grid-cols-4 [&::-webkit-scrollbar]:hidden [&>*]:w-[78%] [&>*]:shrink-0 [&>*]:snap-start sm:[&>*]:w-auto", children: children }));
8
8
  }
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * NoticeBar naar Verkooporders: één inklapbare balk voor alle meldingen. Ingeklapt
4
+ * hooguit 2 regels (één per melding), de rest als "+ n meldingen"; uitklappen toont alles.
5
+ * `items` zijn korte zinnen, nooit lijsten van artikelen.
6
+ */
7
+ export declare function NoticeBar({ items }: {
8
+ items: ReactNode[];
9
+ }): import("react").JSX.Element | null;
10
+ //# sourceMappingURL=NoticeBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoticeBar.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/NoticeBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGjD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,sCA0B1D"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChevronDown, Info } from "lucide-react";
4
+ /**
5
+ * NoticeBar naar Verkooporders: één inklapbare balk voor alle meldingen. Ingeklapt
6
+ * hooguit 2 regels (één per melding), de rest als "+ n meldingen"; uitklappen toont alles.
7
+ * `items` zijn korte zinnen, nooit lijsten van artikelen.
8
+ */
9
+ export function NoticeBar({ items }) {
10
+ const [open, setOpen] = useState(false);
11
+ if (items.length === 0)
12
+ return null;
13
+ const zichtbaar = open ? items : items.slice(0, 2);
14
+ const rest = items.length - zichtbaar.length;
15
+ return (_jsx("div", { role: "status", className: "shrink-0 rounded-lg border border-border bg-warning-soft text-sm text-warning-soft-foreground", children: _jsxs("button", { type: "button", "aria-expanded": open, onClick: () => setOpen((o) => !o), className: "flex w-full items-start gap-2 px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-lg", children: [_jsx(Info, { className: "mt-0.5 h-4 w-4 shrink-0", "aria-hidden": true }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [zichtbaar.map((it, i) => (_jsx("span", { className: "min-w-0 " + (open ? "" : "truncate"), children: it }, i))), rest > 0 && _jsxs("span", { className: "font-medium", children: ["+ ", rest, " ", rest === 1 ? "melding" : "meldingen"] })] }), (items.length > 2 || open) && (_jsx(ChevronDown, { className: "ml-auto mt-0.5 h-4 w-4 shrink-0 transition-transform " + (open ? "rotate-180" : ""), "aria-hidden": true }))] }) }));
16
+ }
@@ -1,17 +1,18 @@
1
1
  import type { ReactNode } from "react";
2
2
  /**
3
- * Paginakop: links (kruimel), titel en bijgewerkt-tijd; rechts de acties.
4
- * Titel 24 px (20 px mobiel), zonder icoon. Knoppen wrappen netjes.
3
+ * Paginakop exact naar Verkooporders: h1 (20/24 px, 700) met daaronder alleen
4
+ * "Bijgewerkt hh:mm". Rechts periode, secundaire knoppen en één primaire knop.
5
+ * Op mobiel staat de kop in een raster: titel links, knoppen (icoon) rechts.
5
6
  */
6
7
  export declare function PageHeader({ title, updated, crumb, media, meta, actions, }: {
7
8
  title: ReactNode;
8
9
  /** Meestal <UpdatedAt />. */
9
10
  updated?: ReactNode;
10
- /** Kleine terug-link boven de titel. */
11
+ /** Kleine terug-link boven de titel (alleen detailpagina's). */
11
12
  crumb?: ReactNode;
12
- /** Optioneel beeld links van de titel (bijv. foto van het item). */
13
+ /** Optioneel beeld links van de titel (alleen detailpagina's). */
13
14
  media?: ReactNode;
14
- /** Extra regel onder de titel (status, prijs). */
15
+ /** Alleen detailpagina's: vaste kerngegevens onder de titel. */
15
16
  meta?: ReactNode;
16
17
  actions?: ReactNode;
17
18
  }): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/PageHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,IAAI,EACJ,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kDAAkD;IAClD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,+BAiBA"}
1
+ {"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/PageHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,IAAI,EACJ,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gEAAgE;IAChE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kEAAkE;IAClE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,+BAqBA"}
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * Paginakop: links (kruimel), titel en bijgewerkt-tijd; rechts de acties.
4
- * Titel 24 px (20 px mobiel), zonder icoon. Knoppen wrappen netjes.
3
+ * Paginakop exact naar Verkooporders: h1 (20/24 px, 700) met daaronder alleen
4
+ * "Bijgewerkt hh:mm". Rechts periode, secundaire knoppen en één primaire knop.
5
+ * Op mobiel staat de kop in een raster: titel links, knoppen (icoon) rechts.
5
6
  */
6
7
  export function PageHeader({ title, updated, crumb, media, meta, actions, }) {
7
- return (_jsxs("header", { className: "flex flex-col gap-2", children: [crumb && _jsx("div", { className: "text-sm text-muted-foreground", children: crumb }), _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "flex min-w-0 flex-1 basis-64 items-start gap-4", children: [media, _jsxs("div", { className: "min-w-0", children: [_jsx("h1", { className: "break-words text-xl font-bold leading-tight tracking-tight text-foreground sm:text-2xl", children: title }), updated && _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: updated }), meta && _jsx("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-sm", children: meta })] })] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions })] })] }));
8
+ return (_jsxs("header", { className: "shrink-0 flex flex-col gap-1", children: [crumb && _jsx("div", { className: "text-sm text-muted-foreground", children: crumb }), _jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:flex sm:flex-wrap sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [media, _jsxs("div", { className: "min-w-0", children: [_jsx("h1", { className: "truncate text-xl font-bold leading-tight sm:text-2xl tracking-tight text-foreground", children: title }), updated && (_jsx("p", { className: "flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground", "aria-live": "polite", children: updated })), meta && _jsx("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-sm", children: meta })] })] }), actions && _jsx("div", { className: "flex flex-wrap items-center justify-end gap-2", children: actions })] })] }));
8
9
  }
@@ -0,0 +1,10 @@
1
+ /** Paginering exact naar Verkooporders: "1–25 van 120" links, "Per pagina" en pijlen met "1 / 5" rechts. */
2
+ export declare function Pagination({ page, pageSize, totalCount, onPage, onPageSize, sizes, }: {
3
+ page: number;
4
+ pageSize: number;
5
+ totalCount: number;
6
+ onPage: (p: number) => void;
7
+ onPageSize?: (n: number) => void;
8
+ sizes?: number[];
9
+ }): import("react").JSX.Element;
10
+ //# sourceMappingURL=Pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/Pagination.tsx"],"names":[],"mappings":"AAGA,4GAA4G;AAC5G,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,MAAM,EACN,UAAU,EACV,KAAyB,GAC1B,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,+BAuCA"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@flowselections/core";
3
+ import { ChevronLeft, ChevronRight } from "lucide-react";
4
+ /** Paginering exact naar Verkooporders: "1–25 van 120" links, "Per pagina" en pijlen met "1 / 5" rechts. */
5
+ export function Pagination({ page, pageSize, totalCount, onPage, onPageSize, sizes = [10, 25, 50, 100], }) {
6
+ const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
7
+ return (_jsxs("nav", { "aria-label": "Paginering", className: "shrink-0 flex flex-wrap items-center justify-between gap-3 text-sm text-muted-foreground", children: [_jsx("div", { className: "tabular-nums", children: totalCount === 0
8
+ ? "Geen resultaten"
9
+ : `${((page - 1) * pageSize + 1).toLocaleString("nl-NL")}–${Math.min(page * pageSize, totalCount).toLocaleString("nl-NL")} van ${totalCount.toLocaleString("nl-NL")}` }), _jsxs("div", { className: "flex items-center gap-3", children: [onPageSize && (_jsxs("div", { className: "hidden items-center gap-2 sm:flex", children: [_jsx("span", { children: "Per pagina" }), _jsxs(Select, { value: String(pageSize), onValueChange: (v) => onPageSize(Number(v)), children: [_jsx(SelectTrigger, { className: "h-8 w-20", "aria-label": "Resultaten per pagina", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: sizes.map((n) => (_jsx(SelectItem, { value: String(n), children: n }, n))) })] })] })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "outline", size: "icon", className: "h-10 w-10 sm:h-8 sm:w-8", onClick: () => onPage(Math.max(1, page - 1)), disabled: page <= 1, "aria-label": "Vorige pagina", children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }), _jsxs("div", { className: "px-2 text-foreground tabular-nums", "aria-current": "page", children: [page, " / ", totalPages] }), _jsx(Button, { variant: "outline", size: "icon", className: "h-10 w-10 sm:h-8 sm:w-8", onClick: () => onPage(Math.min(totalPages, page + 1)), disabled: page >= totalPages, "aria-label": "Volgende pagina", children: _jsx(ChevronRight, { className: "h-4 w-4" }) })] })] })] }));
10
+ }
@@ -1,15 +1,13 @@
1
- import type { ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  export interface PillTab<T extends string = string> {
3
3
  value: T;
4
4
  label: string;
5
5
  icon?: ReactNode;
6
6
  /** Teller; undefined = geen teller, null = nog laden. */
7
7
  count?: number | null;
8
+ hint?: string;
8
9
  }
9
- /**
10
- * Tabbladen als pillen met icoon + label + teller. Actief: groene tint en rand,
11
- * teller groen gevuld. Leeg (0): gedempte tekst. Mobiel veegbaar met vervaging rechts.
12
- */
10
+ /** StatusTabs exact naar Verkooporders: altijd één regel, scrollt horizontaal met vervaging. */
13
11
  export declare function PillTabs<T extends string>({ tabs, value, onChange, label, }: {
14
12
  tabs: PillTab<T>[];
15
13
  value: T;
@@ -1 +1 @@
1
- {"version":3,"file":"PillTabs.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/PillTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAChD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,EACzC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAkB,GACnB,EAAE;IACD,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACnB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BA0CA"}
1
+ {"version":3,"file":"PillTabs.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/PillTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhE,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAChD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,EACzC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAkB,GACnB,EAAE;IACD,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACnB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BAwDA"}
@@ -1,18 +1,28 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Tabbladen als pillen met icoon + label + teller. Actief: groene tint en rand,
4
- * teller groen gevuld. Leeg (0): gedempte tekst. Mobiel veegbaar met vervaging rechts.
5
- */
2
+ import { useLayoutEffect, useRef } from "react";
3
+ /** StatusTabs exact naar Verkooporders: altijd één regel, scrollt horizontaal met vervaging. */
6
4
  export function PillTabs({ tabs, value, onChange, label = "Weergave", }) {
7
- return (_jsxs("div", { className: "relative", children: [_jsx("div", { role: "tablist", "aria-label": label, className: "flex gap-2 overflow-x-auto pr-6 [scrollbar-width:none] sm:flex-wrap sm:overflow-visible sm:pr-0 [&::-webkit-scrollbar]:hidden", children: tabs.map((t) => {
8
- const actief = t.value === value;
9
- const leeg = t.count === 0 && !actief;
10
- return (_jsxs("button", { type: "button", role: "tab", "aria-selected": actief, onClick: () => onChange(t.value), className: "inline-flex h-9 shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border px-3 text-sm font-medium transition-colors duration-150 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none [&_svg]:h-4 [&_svg]:w-4 " +
11
- (actief
12
- ? "border-primary/40 bg-primary/10 text-primary"
13
- : leeg
14
- ? "border-transparent text-muted-foreground/70 hover:bg-muted"
15
- : "border-transparent text-muted-foreground hover:bg-muted hover:text-foreground"), children: [t.icon, t.label, t.count !== undefined && (_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs tabular-nums " +
16
- (actief ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"), children: t.count === null ? "…" : t.count.toLocaleString("nl-NL") }))] }, t.value));
17
- }) }), _jsx("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-y-0 right-0 w-6 bg-gradient-to-l from-background to-transparent sm:hidden" })] }));
5
+ const listRef = useRef(null);
6
+ useLayoutEffect(() => {
7
+ const measure = () => {
8
+ const list = listRef.current;
9
+ const el = list?.querySelector(`[data-tab="${value}"]`);
10
+ if (el && list && (el.offsetLeft < list.scrollLeft || el.offsetLeft + el.offsetWidth > list.scrollLeft + list.clientWidth)) {
11
+ list.scrollLeft = el.offsetLeft - 8;
12
+ }
13
+ };
14
+ measure();
15
+ window.addEventListener("resize", measure);
16
+ return () => window.removeEventListener("resize", measure);
17
+ }, [value]);
18
+ return (_jsx("div", { className: "shrink-0", children: _jsx("div", { ref: listRef, role: "tablist", "aria-label": label, className: "relative -mx-4 flex items-center gap-2 overflow-x-auto px-4 pb-1 [scrollbar-width:none] [mask-image:linear-gradient(to_right,black_85%,transparent)] [&::-webkit-scrollbar]:hidden sm:mx-0 sm:px-0 sm:[mask-image:none]", children: tabs.map((t) => {
19
+ const active = t.value === value;
20
+ return (_jsxs("button", { "data-tab": t.value, type: "button", role: "tab", "aria-selected": active, onClick: () => onChange(t.value), title: t.hint, style: { transitionProperty: "color, background-color, border-color", transitionDuration: "150ms" }, className: "relative flex h-9 shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0 " +
21
+ (active
22
+ ? "border-primary/30 bg-primary/10 font-semibold text-foreground"
23
+ : t.count === 0
24
+ ? "border-border bg-card text-muted-foreground/70 hover:text-foreground"
25
+ : "border-border bg-card text-foreground/80 hover:bg-muted hover:text-foreground"), children: [t.icon, _jsx("span", { children: t.label }), t.count !== undefined && (_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[11px] font-semibold tabular-nums " +
26
+ (active ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"), children: t.count === null ? "…" : t.count.toLocaleString("nl-NL") }))] }, t.value));
27
+ }) }) }));
18
28
  }
@@ -0,0 +1,13 @@
1
+ export interface RowMenuItem {
2
+ label: string;
3
+ onClick: () => void;
4
+ disabled?: boolean;
5
+ title?: string;
6
+ destructive?: boolean;
7
+ }
8
+ /** Rijmenu exact naar Verkooporders; de acties komen van de pagina. */
9
+ export declare function RowMenu({ label, items }: {
10
+ label: string;
11
+ items: RowMenuItem[];
12
+ }): import("react").JSX.Element;
13
+ //# sourceMappingURL=RowMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/RowMenu.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,+BAyBhF"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { MoreVertical } from "lucide-react";
3
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@flowselections/core";
4
+ /** Rijmenu exact naar Verkooporders; de acties komen van de pagina. */
5
+ export function RowMenu({ label, items }) {
6
+ return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { "aria-label": `Acties voor ${label}`, onClick: (e) => e.stopPropagation(), className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsx(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: items.map((it) => (_jsx(DropdownMenuItem, { disabled: it.disabled, title: it.title, onClick: () => !it.disabled && it.onClick(), className: it.destructive ? "text-destructive focus:text-destructive" : undefined, children: it.label }, it.label))) })] }));
7
+ }
@@ -1,9 +1,6 @@
1
1
  /** True als de gebruiker in een invoerveld typt (sneltoetsen doen dan niets). */
2
2
  export declare function isTypen(t: EventTarget | null): boolean;
3
- /**
4
- * Zoekveld: filtert tijdens typen (250 ms), één zachte focusring, wis-kruisje,
5
- * "/" focust (niet tijdens typen elders), Esc wist. Mobiel 40 px hoog met 16 px tekst.
6
- */
3
+ /** Zoekveld exact naar Verkooporders: h-9 (mobiel h-10), sm:w-80, breder bij focus; "/" focust, Esc wist. */
7
4
  export declare function SearchInput({ value, onChange, placeholder, label, delay, }: {
8
5
  value: string;
9
6
  onChange: (v: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/SearchInput.tsx"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAItD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAuB,EACvB,KAAgB,EAChB,KAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BAiDA"}
1
+ {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/SearchInput.tsx"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAItD;AAED,6GAA6G;AAC7G,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAsB,EACtB,KAAgB,EAChB,KAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BA4EA"}
@@ -8,44 +8,48 @@ export function isTypen(t) {
8
8
  return false;
9
9
  return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT" || el.isContentEditable;
10
10
  }
11
- /**
12
- * Zoekveld: filtert tijdens typen (250 ms), één zachte focusring, wis-kruisje,
13
- * "/" focust (niet tijdens typen elders), Esc wist. Mobiel 40 px hoog met 16 px tekst.
14
- */
15
- export function SearchInput({ value, onChange, placeholder = "Zoeken…", label = "Zoeken", delay = 250, }) {
16
- const [tekst, setTekst] = useState(value);
17
- const ref = useRef(null);
11
+ /** Zoekveld exact naar Verkooporders: h-9 (mobiel h-10), sm:w-80, breder bij focus; "/" focust, Esc wist. */
12
+ export function SearchInput({ value, onChange, placeholder = "Zoeken", label = "Zoeken", delay = 250, }) {
13
+ const [search, setSearch] = useState(value);
14
+ const inputRef = useRef(null);
18
15
  const laatst = useRef(value);
19
16
  useEffect(() => {
20
17
  if (value !== laatst.current) {
21
18
  laatst.current = value;
22
- setTekst(value);
19
+ setSearch(value);
23
20
  }
24
21
  }, [value]);
25
22
  useEffect(() => {
26
- if (tekst === laatst.current)
23
+ if (search === laatst.current)
27
24
  return;
28
- const t = setTimeout(() => { laatst.current = tekst; onChange(tekst); }, delay);
25
+ const t = setTimeout(() => { laatst.current = search; onChange(search); }, delay);
29
26
  return () => clearTimeout(t);
30
- }, [tekst, delay, onChange]);
27
+ }, [search, delay, onChange]);
31
28
  useEffect(() => {
32
29
  const h = (e) => {
33
30
  if (e.key === "/" && !e.metaKey && !e.ctrlKey && !e.altKey && !isTypen(e.target)) {
34
31
  e.preventDefault();
35
- ref.current?.focus();
32
+ inputRef.current?.focus();
36
33
  }
37
34
  };
38
35
  window.addEventListener("keydown", h);
39
36
  return () => window.removeEventListener("keydown", h);
40
37
  }, []);
41
- const wis = () => { setTekst(""); laatst.current = ""; onChange(""); };
42
- return (_jsxs("div", { className: "relative w-full max-w-md", children: [_jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground", "aria-hidden": true }), _jsx("input", { ref: ref, type: "search", value: tekst, "aria-label": label, placeholder: placeholder, onChange: (e) => setTekst(e.target.value), onKeyDown: (e) => {
38
+ const clearSearch = () => { setSearch(""); laatst.current = ""; onChange(""); inputRef.current?.focus(); };
39
+ return (_jsxs("div", { className: "group relative flex h-10 sm:h-9 w-full items-center overflow-hidden rounded-md border border-border bg-card " +
40
+ "transition-[box-shadow,border-color,width] duration-[180ms] ease-out motion-reduce:transition-none " +
41
+ "focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring/20 " +
42
+ "sm:w-80 sm:focus-within:w-[400px]", children: [_jsx(Search, { className: "ml-3 h-4 w-4 shrink-0 text-muted-foreground transition-colors duration-[120ms] group-focus-within:text-primary", "aria-hidden": true }), _jsx("input", { ref: inputRef, type: "search", placeholder: placeholder, "aria-label": label, value: search, maxLength: 100, autoComplete: "off", spellCheck: false, onChange: (e) => setSearch(e.target.value), onKeyDown: (e) => {
43
43
  if (e.key === "Escape") {
44
- e.stopPropagation();
45
- if (tekst)
46
- wis();
44
+ if (search) {
45
+ e.preventDefault();
46
+ e.stopPropagation();
47
+ clearSearch();
48
+ }
47
49
  else
48
- ref.current?.blur();
50
+ inputRef.current?.blur();
49
51
  }
50
- }, className: "h-10 w-full rounded-lg border border-input bg-card pl-9 pr-16 text-base text-foreground shadow-sm outline-none transition-shadow duration-150 placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring/40 sm:h-9 sm:text-sm [&::-webkit-search-cancel-button]:hidden" }), _jsx("div", { className: "absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1", children: tekst ? (_jsx("button", { type: "button", onClick: wis, "aria-label": "Zoekopdracht wissen", className: "inline-flex h-7 w-7 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(X, { className: "h-4 w-4" }) })) : (_jsx("kbd", { className: "hidden rounded-sm border bg-muted px-1.5 text-[11px] text-muted-foreground md:inline", children: "/" })) })] }));
52
+ }, className: "h-full min-w-0 flex-1 appearance-none border-0 bg-transparent px-2 text-base sm:text-sm text-foreground outline-none ring-0 shadow-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 placeholder:text-muted-foreground [&::-webkit-search-cancel-button]:hidden" }), _jsxs("span", { className: "relative mr-1.5 flex h-7 w-7 shrink-0 items-center justify-center", children: [_jsx("kbd", { className: "pointer-events-none absolute rounded border border-border px-1.5 font-mono text-[11px] leading-5 text-muted-foreground transition-opacity duration-[120ms] " +
53
+ (search ? "opacity-0" : "opacity-100 group-focus-within:opacity-0"), "aria-hidden": true, children: "/" }), _jsx("button", { type: "button", onClick: clearSearch, tabIndex: search ? 0 : -1, "aria-label": "Zoekopdracht wissen", className: "absolute inline-flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-[opacity,transform,background-color] duration-[120ms] ease-out hover:bg-muted hover:text-foreground " +
54
+ (search ? "scale-100 opacity-100" : "pointer-events-none scale-90 opacity-0"), children: _jsx(X, { className: "h-4 w-4" }) })] })] }));
51
55
  }
@@ -0,0 +1,8 @@
1
+ export type Shortcut = [string[], string];
2
+ /** Sneltoetsenoverzicht exact naar Verkooporders; de lijst komt van de pagina. */
3
+ export declare function ShortcutHelp({ open, onOpenChange, shortcuts }: {
4
+ open: boolean;
5
+ onOpenChange: (o: boolean) => void;
6
+ shortcuts: Shortcut[];
7
+ }): import("react").JSX.Element;
8
+ //# sourceMappingURL=ShortcutHelp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShortcutHelp.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/ShortcutHelp.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;AAE1C,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE,+BAwB3I"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@flowselections/core";
3
+ /** Sneltoetsenoverzicht exact naar Verkooporders; de lijst komt van de pagina. */
4
+ export function ShortcutHelp({ open, onOpenChange, shortcuts }) {
5
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-sm", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Sneltoetsen" }) }), _jsx("ul", { className: "divide-y divide-border text-sm", children: shortcuts.map(([keys, label]) => (_jsxs("li", { className: "flex items-center justify-between py-2", children: [_jsx("span", { className: "text-foreground", children: label }), _jsx("span", { className: "flex gap-1", children: keys.map((k) => (_jsx("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-[11px] text-muted-foreground", children: k }, k))) })] }, label))) })] }) }));
6
+ }
@@ -1,8 +1,12 @@
1
1
  import type { ReactNode } from "react";
2
- /** Werkbalk: zoekbalk links, knoppen (Filters, Kolommen) rechts; chips op de regel eronder. */
3
- export declare function Toolbar({ children, right, chips }: {
2
+ /**
3
+ * Werkbalk exact naar Verkooporders: zoekveld, direct rechts "Filters", dan de
4
+ * actieve chips op dezelfde regel; uiterst rechts alleen "Kolommen".
5
+ */
6
+ export declare function Toolbar({ children, filters, chips, right }: {
4
7
  children?: ReactNode;
5
- right?: ReactNode;
8
+ filters?: ReactNode;
6
9
  chips?: ReactNode;
10
+ right?: ReactNode;
7
11
  }): import("react").JSX.Element;
8
12
  //# sourceMappingURL=Toolbar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/Toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,+FAA+F;AAC/F,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,+BAUjH"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/Toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,+BAS/I"}