@eifi1/ui-kit 0.32.0 → 0.32.2

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 (216) hide show
  1. package/dist/account/delete-account-setting.d.ts +1 -1
  2. package/dist/admin/admin-action-confirm.d.ts +1 -1
  3. package/dist/admin/admin-action-log.d.ts +1 -1
  4. package/dist/admin/admin-action-log.js +4 -2
  5. package/dist/admin/admin-action-log.js.map +1 -1
  6. package/dist/admin/invitations-panel.d.ts +1 -1
  7. package/dist/admin/reviewer-scope-editor.d.ts +1 -1
  8. package/dist/admin/role-select.d.ts +1 -1
  9. package/dist/admin/transfer-ownership-dialog.d.ts +1 -1
  10. package/dist/admin/user-roster.d.ts +1 -1
  11. package/dist/auth/register-form.d.ts +1 -1
  12. package/dist/billing/billing-banner.d.ts +1 -1
  13. package/dist/billing/billing-labels.d.ts +1 -1
  14. package/dist/billing/billing-labels.js +3 -1
  15. package/dist/billing/billing-labels.js.map +1 -1
  16. package/dist/billing/billing-lock.d.ts +1 -1
  17. package/dist/billing/billing-standing.d.ts +1 -1
  18. package/dist/billing/plan-card.d.ts +1 -1
  19. package/dist/billing/plan-card.js +1 -1
  20. package/dist/billing/plan-card.js.map +1 -1
  21. package/dist/billing/plan-limit-notice.d.ts +1 -1
  22. package/dist/billing/subscription-actions.d.ts +1 -1
  23. package/dist/billing/subscription-status-chip.d.ts +1 -1
  24. package/dist/chart.d.ts +2 -2
  25. package/dist/chart.js.map +1 -1
  26. package/dist/components/alert-banner.js +1 -1
  27. package/dist/components/alert-banner.js.map +1 -1
  28. package/dist/components/amount-input.d.ts +1 -1
  29. package/dist/components/appearance-labels.d.ts +6 -0
  30. package/dist/components/appearance-labels.js +2 -1
  31. package/dist/components/appearance-labels.js.map +1 -1
  32. package/dist/components/button-group.d.ts +1 -1
  33. package/dist/components/button-group.js +7 -1
  34. package/dist/components/button-group.js.map +1 -1
  35. package/dist/components/calculator.d.ts +1 -1
  36. package/dist/components/chip.js +7 -2
  37. package/dist/components/chip.js.map +1 -1
  38. package/dist/components/choice-card.js +1 -1
  39. package/dist/components/choice-card.js.map +1 -1
  40. package/dist/components/confirm-dialog.d.ts +1 -1
  41. package/dist/components/copy-button.d.ts +1 -1
  42. package/dist/components/danger-confirm.d.ts +1 -1
  43. package/dist/components/data-table-pagination.d.ts +2 -1
  44. package/dist/components/data-table-pagination.js +15 -6
  45. package/dist/components/data-table-pagination.js.map +1 -1
  46. package/dist/components/data-table.js +2 -2
  47. package/dist/components/data-table.js.map +1 -1
  48. package/dist/components/date-picker.js +11 -1
  49. package/dist/components/date-picker.js.map +1 -1
  50. package/dist/components/facing-pair.d.ts +1 -1
  51. package/dist/components/file-button.d.ts +1 -1
  52. package/dist/components/file-dropzone.d.ts +1 -1
  53. package/dist/components/form-actions.d.ts +1 -1
  54. package/dist/components/iban-input.d.ts +1 -1
  55. package/dist/components/inline-edit-field.js +4 -1
  56. package/dist/components/inline-edit-field.js.map +1 -1
  57. package/dist/components/language-select.d.ts +1 -1
  58. package/dist/components/legal-page.d.ts +1 -1
  59. package/dist/components/legal.d.ts +1 -1
  60. package/dist/components/money-field.d.ts +1 -1
  61. package/dist/components/month-picker.js +41 -34
  62. package/dist/components/month-picker.js.map +1 -1
  63. package/dist/components/number-field.d.ts +1 -1
  64. package/dist/components/number-input.d.ts +1 -1
  65. package/dist/components/numpad-sheet.d.ts +1 -1
  66. package/dist/components/page-header.js +6 -1
  67. package/dist/components/page-header.js.map +1 -1
  68. package/dist/components/phone-input.d.ts +1 -1
  69. package/dist/components/phone-input.js +2 -2
  70. package/dist/components/phone-input.js.map +1 -1
  71. package/dist/components/popover.d.ts +1 -1
  72. package/dist/components/popover.js +2 -0
  73. package/dist/components/popover.js.map +1 -1
  74. package/dist/components/row-actions.d.ts +1 -1
  75. package/dist/components/row-actions.js +97 -37
  76. package/dist/components/row-actions.js.map +1 -1
  77. package/dist/components/series-chart.d.ts +1 -1
  78. package/dist/components/settings-fields.d.ts +7 -3
  79. package/dist/components/settings-fields.js +2 -1
  80. package/dist/components/settings-fields.js.map +1 -1
  81. package/dist/components/share-card.d.ts +1 -1
  82. package/dist/components/share-card.js +6 -2
  83. package/dist/components/share-card.js.map +1 -1
  84. package/dist/components/status-dot.js +9 -2
  85. package/dist/components/status-dot.js.map +1 -1
  86. package/dist/components/swipeable-row.js +8 -1
  87. package/dist/components/swipeable-row.js.map +1 -1
  88. package/dist/components/text-link.d.ts +1 -1
  89. package/dist/components/time-input.d.ts +1 -1
  90. package/dist/components/toggle-group.d.ts +9 -2
  91. package/dist/components/toggle-group.js +3 -3
  92. package/dist/components/toggle-group.js.map +1 -1
  93. package/dist/components/translation-review-editor.js +1 -1
  94. package/dist/components/translation-review-editor.js.map +1 -1
  95. package/dist/components/translation-review.js +2 -2
  96. package/dist/components/translation-review.js.map +1 -1
  97. package/dist/components/ui.d.ts +1 -1
  98. package/dist/components/ui.js +6 -6
  99. package/dist/components/ui.js.map +1 -1
  100. package/dist/components/wizard-stepper.js +20 -14
  101. package/dist/components/wizard-stepper.js.map +1 -1
  102. package/dist/{delete-account-setting-BvdQdbv3.d.ts → delete-account-setting-Dy4kJgUm.d.ts} +53 -14
  103. package/dist/feedback/feedback-attachment.d.ts +1 -1
  104. package/dist/feedback/feedback-context.d.ts +1 -1
  105. package/dist/feedback/feedback-crash.d.ts +1 -1
  106. package/dist/feedback/feedback-dialog.d.ts +1 -1
  107. package/dist/feedback/feedback-inbox.d.ts +1 -1
  108. package/dist/feedback/feedback-labels.d.ts +1 -1
  109. package/dist/feedback/feedback-menu.d.ts +1 -1
  110. package/dist/feedback/feedback-record.d.ts +1 -1
  111. package/dist/feedback/feedback-row-detail.d.ts +1 -1
  112. package/dist/feedback/feedback-status-undo.d.ts +1 -1
  113. package/dist/feedback/feedback-submit.d.ts +1 -1
  114. package/dist/feedback/feedback-swipe.d.ts +1 -1
  115. package/dist/feedback/feedback-table.d.ts +1 -1
  116. package/dist/feedback/feedback-thread.d.ts +1 -1
  117. package/dist/feedback.d.ts +1 -1
  118. package/dist/hooks/use-breakpoint.d.ts +19 -8
  119. package/dist/hooks/use-breakpoint.js +1 -1
  120. package/dist/hooks/use-breakpoint.js.map +1 -1
  121. package/dist/hooks/use-file-drop.d.ts +1 -1
  122. package/dist/i18n/defaults.d.ts +1 -1
  123. package/dist/i18n/german.d.ts +1 -1
  124. package/dist/i18n/german.js +7 -3
  125. package/dist/i18n/german.js.map +1 -1
  126. package/dist/i18n/kit-labels.d.ts +1 -1
  127. package/dist/i18n/languages.d.ts +1 -1
  128. package/dist/i18n/locales/de-CH.d.ts +1 -1
  129. package/dist/i18n/locales/en.d.ts +1 -1
  130. package/dist/i18n/locales/es.d.ts +1 -1
  131. package/dist/i18n/locales/es.js +7 -3
  132. package/dist/i18n/locales/es.js.map +1 -1
  133. package/dist/i18n/locales/fr.d.ts +1 -1
  134. package/dist/i18n/locales/fr.js +7 -3
  135. package/dist/i18n/locales/fr.js.map +1 -1
  136. package/dist/i18n/locales/hu.d.ts +1 -1
  137. package/dist/i18n/locales/hu.js +7 -3
  138. package/dist/i18n/locales/hu.js.map +1 -1
  139. package/dist/i18n/locales/it.d.ts +1 -1
  140. package/dist/i18n/locales/it.js +7 -3
  141. package/dist/i18n/locales/it.js.map +1 -1
  142. package/dist/i18n/locales/zh.d.ts +1 -1
  143. package/dist/i18n/locales/zh.js +7 -3
  144. package/dist/i18n/locales/zh.js.map +1 -1
  145. package/dist/i18n/review.d.ts +1 -1
  146. package/dist/index.d.ts +3 -3
  147. package/dist/index.js +3 -1
  148. package/dist/index.js.map +1 -1
  149. package/dist/landing/landing-actions.d.ts +1 -1
  150. package/dist/landing/landing-sections.d.ts +1 -1
  151. package/dist/landing/landing-sections.js +7 -3
  152. package/dist/landing/landing-sections.js.map +1 -1
  153. package/dist/landing/public-header.d.ts +1 -1
  154. package/dist/landing/routing.d.ts +1 -1
  155. package/dist/rhf/fields.d.ts +1 -1
  156. package/dist/rhf/form.d.ts +1 -1
  157. package/dist/rhf.d.ts +1 -1
  158. package/dist/settings/settings-section.d.ts +1 -1
  159. package/dist/settings/use-account-appearance.d.ts +1 -1
  160. package/dist/settings/use-account-appearance.js.map +1 -1
  161. package/dist/shell/app-shell.d.ts +1 -1
  162. package/dist/shell/app-shell.js +2 -1
  163. package/dist/shell/app-shell.js.map +1 -1
  164. package/dist/shell/top-bar-brand.d.ts +1 -1
  165. package/dist/shell.d.ts +1 -1
  166. package/dist/theme/contrast.d.ts +3 -2
  167. package/dist/theme/contrast.js.map +1 -1
  168. package/dist/theme/text-size.d.ts +19 -3
  169. package/dist/theme/text-size.js.map +1 -1
  170. package/dist/wizard/stepper-nav.d.ts +1 -1
  171. package/dist/wizard/wizard-summary.js +1 -1
  172. package/dist/wizard/wizard-summary.js.map +1 -1
  173. package/dist/wizard.d.ts +1 -1
  174. package/package.json +1 -1
  175. package/src/admin/admin-action-log.tsx +6 -1
  176. package/src/billing/billing-labels.ts +16 -0
  177. package/src/billing/plan-card.tsx +1 -1
  178. package/src/chart.ts +2 -0
  179. package/src/components/alert-banner.tsx +5 -1
  180. package/src/components/appearance-labels.ts +7 -0
  181. package/src/components/button-group.tsx +21 -0
  182. package/src/components/chip.tsx +34 -6
  183. package/src/components/choice-card.tsx +1 -1
  184. package/src/components/data-table-pagination.tsx +60 -31
  185. package/src/components/data-table.tsx +8 -4
  186. package/src/components/date-picker.tsx +32 -1
  187. package/src/components/inline-edit-field.tsx +20 -1
  188. package/src/components/month-picker.tsx +6 -1
  189. package/src/components/page-header.tsx +15 -1
  190. package/src/components/phone-input.tsx +7 -2
  191. package/src/components/popover.tsx +4 -0
  192. package/src/components/row-actions.tsx +156 -49
  193. package/src/components/settings-fields.tsx +8 -3
  194. package/src/components/share-card.tsx +21 -2
  195. package/src/components/status-dot.tsx +25 -2
  196. package/src/components/swipeable-row.tsx +8 -1
  197. package/src/components/toggle-group.tsx +26 -12
  198. package/src/components/translation-review-editor.tsx +1 -1
  199. package/src/components/translation-review.tsx +5 -4
  200. package/src/components/ui.tsx +28 -9
  201. package/src/components/wizard-stepper.tsx +5 -1
  202. package/src/hooks/use-breakpoint.ts +20 -9
  203. package/src/i18n/german.ts +4 -0
  204. package/src/i18n/locales/es.ts +4 -0
  205. package/src/i18n/locales/fr.ts +4 -0
  206. package/src/i18n/locales/hu.ts +4 -0
  207. package/src/i18n/locales/it.ts +4 -0
  208. package/src/i18n/locales/zh.ts +4 -0
  209. package/src/index.ts +4 -2
  210. package/src/landing/landing-sections.tsx +7 -3
  211. package/src/settings/use-account-appearance.ts +1 -1
  212. package/src/shell/app-shell.tsx +11 -6
  213. package/src/theme/contrast.ts +3 -2
  214. package/src/theme/text-size.ts +19 -3
  215. package/src/wizard/wizard-summary.tsx +4 -2
  216. package/tokens.css +15 -7
@@ -23,7 +23,8 @@ interface PaginationProps {
23
23
  density?: "comfortable" | "compact";
24
24
  }
25
25
  /** Footer for {@link DataTable}: range summary, page-size select, and a
26
- * windowed page-number strip (first/last + ±2 around the current page). */
26
+ * windowed page-number strip (first/last + ±2 around the current page, ±1 on a phone
27
+ * at Large — see {@link PAGE_WINDOW}). */
27
28
  declare function Pagination({ page, totalPages, pageSize, total, onPage, onPageSize, labels: labelsProp, locale: localeProp, density, }: PaginationProps): react.JSX.Element;
28
29
 
29
30
  export { PAGE_SIZE_OPTIONS, Pagination };
@@ -5,12 +5,18 @@ import { ChevronLeft, ChevronRight } from "lucide-react";
5
5
  import { cn } from "../lib/cn.js";
6
6
  import { DEFAULT_DATA_TABLE_LABELS } from "./data-table-labels.js";
7
7
  import { useKitLabels, useKitLocale } from "../i18n/kit-labels.js";
8
+ import { usePhoneLayout } from "../hooks/use-breakpoint.js";
9
+ import { useLargeText } from "../hooks/use-large-text.js";
8
10
  const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200];
9
11
  function sizeOptions(pageSize) {
10
12
  const steps = [...PAGE_SIZE_OPTIONS];
11
13
  if (!Number.isFinite(pageSize) || steps.includes(pageSize)) return steps;
12
14
  return [...steps, pageSize].sort((a, b) => a - b);
13
15
  }
16
+ const PAGE_WINDOW = 2;
17
+ const PAGE_WINDOW_LARGE_PHONE = 1;
18
+ const PAGE_STRIP = "flex min-w-0 max-w-full items-center gap-1";
19
+ const PAGE_NUMBERS = "flex min-w-0 flex-wrap items-center justify-center gap-1";
14
20
  function Pagination({
15
21
  page,
16
22
  totalPages,
@@ -26,15 +32,18 @@ function Pagination({
26
32
  const labels = useKitLabels("dataTable", DEFAULT_DATA_TABLE_LABELS, labelsProp);
27
33
  const locale = useKitLocale(localeProp);
28
34
  const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);
35
+ const large = useLargeText();
36
+ const phone = usePhoneLayout();
37
+ const radius = large && phone ? PAGE_WINDOW_LARGE_PHONE : PAGE_WINDOW;
29
38
  const visible = useMemo(() => {
30
- if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i);
39
+ if (totalPages <= 2 * radius + 3) return Array.from({ length: totalPages }, (_, i) => i);
31
40
  const set = /* @__PURE__ */ new Set([0, totalPages - 1, page]);
32
- for (let d = 1; d <= 2; d++) {
41
+ for (let d = 1; d <= radius; d++) {
33
42
  if (page - d >= 0) set.add(page - d);
34
43
  if (page + d <= totalPages - 1) set.add(page + d);
35
44
  }
36
45
  return Array.from(set).sort((a, b) => a - b);
37
- }, [page, totalPages]);
46
+ }, [page, totalPages, radius]);
38
47
  const items = [];
39
48
  visible.forEach((p, idx) => {
40
49
  if (idx > 0 && p - visible[idx - 1] > 1) items.push("ellipsis");
@@ -65,7 +74,7 @@ function Pagination({
65
74
  }
66
75
  )
67
76
  ] }),
68
- pageSize !== Infinity && totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
77
+ pageSize !== Infinity && totalPages > 1 && /* @__PURE__ */ jsxs("div", { "data-slot": "page-strip", className: PAGE_STRIP, children: [
69
78
  /* @__PURE__ */ jsx(
70
79
  "button",
71
80
  {
@@ -77,7 +86,7 @@ function Pagination({
77
86
  children: /* @__PURE__ */ jsx(ChevronLeft, { className: cn("rtl:-scale-x-100", compact ? "size-3.5" : "size-4") })
78
87
  }
79
88
  ),
80
- items.map(
89
+ /* @__PURE__ */ jsx("div", { "data-slot": "page-numbers", className: PAGE_NUMBERS, children: items.map(
81
90
  (it, i) => it === "ellipsis" ? /* @__PURE__ */ jsx("span", { className: "px-1 text-[var(--text-placeholder)]", children: "\u2026" }, `e${i}`) : /* @__PURE__ */ jsx(
82
91
  "button",
83
92
  {
@@ -93,7 +102,7 @@ function Pagination({
93
102
  },
94
103
  it
95
104
  )
96
- ),
105
+ ) }),
97
106
  /* @__PURE__ */ jsx(
98
107
  "button",
99
108
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/data-table-pagination.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { DEFAULT_DATA_TABLE_LABELS, type DataTableLabels } from \"./data-table-labels\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\n\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200] as const;\n\n/** The page-size steps, with the current size slotted in when it is not one of them. */\nfunction sizeOptions(pageSize: number): number[] {\n const steps: number[] = [...PAGE_SIZE_OPTIONS];\n if (!Number.isFinite(pageSize) || steps.includes(pageSize)) return steps;\n return [...steps, pageSize].sort((a, b) => a - b);\n}\n\ninterface PaginationProps {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n onPage: (p: number) => void;\n /** Omit when the page size is not the user's to change (a server that fixes it):\n * the select is then not rendered at all, rather than rendered and inert. */\n onPageSize?: (n: number) => void;\n /** Over `dataTable` from `<UiKitProvider labels>`, over the English defaults. */\n labels?: Partial<DataTableLabels>;\n /** For the page numbers and page-size options; falls back to the provider's. */\n locale?: string;\n /** `\"compact\"` for a pager under a compact {@link DataTable} (lenkbank's in-card\n * tables): a slimmer footer and page buttons, so the pager is not the tallest row\n * of a table that was made compact on purpose. */\n density?: \"comfortable\" | \"compact\";\n}\n\n/** Footer for {@link DataTable}: range summary, page-size select, and a\n * windowed page-number strip (first/last + ±2 around the current page). */\nexport function Pagination({\n page,\n totalPages,\n pageSize,\n total,\n onPage,\n onPageSize,\n labels: labelsProp,\n locale: localeProp,\n density = \"comfortable\",\n}: PaginationProps) {\n const compact = density === \"compact\";\n // prop > provider > English, like every other kit component. This defaulted straight\n // to the English object, so a standalone pager under a translated provider still\n // said \"Rows per page\" — only the pager INSIDE a DataTable was translated, because\n // the table resolved the provider's labels and handed them down.\n const labels = useKitLabels(\"dataTable\", DEFAULT_DATA_TABLE_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n // The bare numbers on the strip and in the select are text too: `String(n)` is\n // always ASCII digits, which is wrong for a locale that writes its own. The range\n // summary is not formatted here — `pageRange` / `rowCount` take NUMBERS so the\n // translation can format them itself, alongside the words around them.\n const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const visible = useMemo(() => {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i);\n const set = new Set<number>([0, totalPages - 1, page]);\n for (let d = 1; d <= 2; d++) {\n if (page - d >= 0) set.add(page - d);\n if (page + d <= totalPages - 1) set.add(page + d);\n }\n return Array.from(set).sort((a, b) => a - b);\n }, [page, totalPages]);\n\n const items: (number | \"ellipsis\")[] = [];\n visible.forEach((p, idx) => {\n if (idx > 0 && p - visible[idx - 1] > 1) items.push(\"ellipsis\");\n items.push(p);\n });\n\n return (\n <div\n data-density={density}\n className={cn(\n \"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--border)] text-xs text-[var(--text-secondary)]\",\n compact ? \"px-2 py-1\" : \"px-3 py-2\",\n )}\n >\n <div className=\"flex items-center gap-2\">\n <span>\n {pageSize === Infinity\n ? labels.rowCount(total)\n : labels.pageRange(page * pageSize + 1, Math.min(total, (page + 1) * pageSize), total)}\n </span>\n {onPageSize && (\n <select\n value={pageSize === Infinity ? \"all\" : pageSize}\n onChange={(e) =>\n onPageSize(e.target.value === \"all\" ? Infinity : Number(e.target.value))\n }\n className=\"rounded border border-[var(--border)] bg-[var(--bg-surface)] px-1 py-0.5 text-xs\"\n aria-label={labels.pageSize}\n >\n {/* A `defaultPageSize` that is not one of the steps (keksdose's 5) is offered\n too — a select whose value has no option shows its first one (\"10\"). */}\n {sizeOptions(pageSize).map((n) => (\n <option key={n} value={n}>\n {num.format(n)}\n </option>\n ))}\n <option value=\"all\">{labels.pageSizeAll}</option>\n </select>\n )}\n </div>\n {pageSize !== Infinity && totalPages > 1 && (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => onPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.prevPage}\n >\n {/* \"Previous\" points back along the line — left in LTR, right in RTL. */}\n <ChevronLeft className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n {items.map((it, i) =>\n it === \"ellipsis\" ? (\n <span key={`e${i}`} className=\"px-1 text-[var(--text-placeholder)]\">\n …\n </span>\n ) : (\n <button\n key={it}\n type=\"button\"\n onClick={() => onPage(it)}\n // Which page you are on is carried only by a background colour\n // otherwise, and the strip is a row of bare numbers with nothing\n // else to tell them apart.\n aria-current={it === page ? \"page\" : undefined}\n className={cn(\n \"rounded\",\n compact ? \"min-w-6 px-1.5 py-0\" : \"min-w-7 px-2 py-0.5\",\n it === page\n ? \"bg-[var(--bg-inverse)] text-[var(--text-inverse)]\"\n : \"hover:bg-[var(--bg-hover)]\",\n )}\n >\n {num.format(it + 1)}\n </button>\n ),\n )}\n <button\n type=\"button\"\n onClick={() => onPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.nextPage}\n >\n <ChevronRight className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/data-table-pagination.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { DEFAULT_DATA_TABLE_LABELS, type DataTableLabels } from \"./data-table-labels\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\nimport { usePhoneLayout } from \"../hooks/use-breakpoint\";\nimport { useLargeText } from \"../hooks/use-large-text\";\n\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200] as const;\n\n/** The page-size steps, with the current size slotted in when it is not one of them. */\nfunction sizeOptions(pageSize: number): number[] {\n const steps: number[] = [...PAGE_SIZE_OPTIONS];\n if (!Number.isFinite(pageSize) || steps.includes(pageSize)) return steps;\n return [...steps, pageSize].sort((a, b) => a - b);\n}\n\ninterface PaginationProps {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n onPage: (p: number) => void;\n /** Omit when the page size is not the user's to change (a server that fixes it):\n * the select is then not rendered at all, rather than rendered and inert. */\n onPageSize?: (n: number) => void;\n /** Over `dataTable` from `<UiKitProvider labels>`, over the English defaults. */\n labels?: Partial<DataTableLabels>;\n /** For the page numbers and page-size options; falls back to the provider's. */\n locale?: string;\n /** `\"compact\"` for a pager under a compact {@link DataTable} (lenkbank's in-card\n * tables): a slimmer footer and page buttons, so the pager is not the tallest row\n * of a table that was made compact on purpose. */\n density?: \"comfortable\" | \"compact\";\n}\n\n/**\n * How many page numbers flank the current one on the strip: ±2, and ±1 on a phone at\n * Large and Extra large (0.32.1, the 360 px Extra-large sweep; docs/text-size-\n * harmonization.md §4). At 150 % a number button is 42 px, and \"‹ 1 2 3 … 494 ›\" was\n * 312 px on a 360 px phone's 262; one neighbour fewer on each side saves two buttons.\n */\nconst PAGE_WINDOW = 2;\nconst PAGE_WINDOW_LARGE_PHONE = 1;\n\n/**\n * The strip's two parts (0.32.1, same sweep, §4 \"nothing overflows\"). The arrows keep\n * the ends; the numbers between them wrap, centred, when even the narrower window does\n * not fit — a middle page of a long list (\"1 … 249 250 251 … 494\") at Extra large, or at\n * Normal on a narrow phone, where the one-row strip ran past the screen. Where the\n * strip fits it is one row, as before.\n */\nconst PAGE_STRIP = \"flex min-w-0 max-w-full items-center gap-1\";\nconst PAGE_NUMBERS = \"flex min-w-0 flex-wrap items-center justify-center gap-1\";\n\n/** Footer for {@link DataTable}: range summary, page-size select, and a\n * windowed page-number strip (first/last + ±2 around the current page, ±1 on a phone\n * at Large — see {@link PAGE_WINDOW}). */\nexport function Pagination({\n page,\n totalPages,\n pageSize,\n total,\n onPage,\n onPageSize,\n labels: labelsProp,\n locale: localeProp,\n density = \"comfortable\",\n}: PaginationProps) {\n const compact = density === \"compact\";\n // prop > provider > English, like every other kit component. This defaulted straight\n // to the English object, so a standalone pager under a translated provider still\n // said \"Rows per page\" — only the pager INSIDE a DataTable was translated, because\n // the table resolved the provider's labels and handed them down.\n const labels = useKitLabels(\"dataTable\", DEFAULT_DATA_TABLE_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n // The bare numbers on the strip and in the select are text too: `String(n)` is\n // always ASCII digits, which is wrong for a locale that writes its own. The range\n // summary is not formatted here — `pageRange` / `rowCount` take NUMBERS so the\n // translation can format them itself, alongside the words around them.\n const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const large = useLargeText();\n const phone = usePhoneLayout();\n const radius = large && phone ? PAGE_WINDOW_LARGE_PHONE : PAGE_WINDOW;\n const visible = useMemo(() => {\n // Every page when that is no longer than the window would be (first, last, the\n // current one, its neighbours and two ellipses).\n if (totalPages <= 2 * radius + 3) return Array.from({ length: totalPages }, (_, i) => i);\n const set = new Set<number>([0, totalPages - 1, page]);\n for (let d = 1; d <= radius; d++) {\n if (page - d >= 0) set.add(page - d);\n if (page + d <= totalPages - 1) set.add(page + d);\n }\n return Array.from(set).sort((a, b) => a - b);\n }, [page, totalPages, radius]);\n\n const items: (number | \"ellipsis\")[] = [];\n visible.forEach((p, idx) => {\n if (idx > 0 && p - visible[idx - 1] > 1) items.push(\"ellipsis\");\n items.push(p);\n });\n\n return (\n <div\n data-density={density}\n className={cn(\n \"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--border)] text-xs text-[var(--text-secondary)]\",\n compact ? \"px-2 py-1\" : \"px-3 py-2\",\n )}\n >\n <div className=\"flex items-center gap-2\">\n <span>\n {pageSize === Infinity\n ? labels.rowCount(total)\n : labels.pageRange(page * pageSize + 1, Math.min(total, (page + 1) * pageSize), total)}\n </span>\n {onPageSize && (\n <select\n value={pageSize === Infinity ? \"all\" : pageSize}\n onChange={(e) =>\n onPageSize(e.target.value === \"all\" ? Infinity : Number(e.target.value))\n }\n className=\"rounded border border-[var(--border)] bg-[var(--bg-surface)] px-1 py-0.5 text-xs\"\n aria-label={labels.pageSize}\n >\n {/* A `defaultPageSize` that is not one of the steps (keksdose's 5) is offered\n too — a select whose value has no option shows its first one (\"10\"). */}\n {sizeOptions(pageSize).map((n) => (\n <option key={n} value={n}>\n {num.format(n)}\n </option>\n ))}\n <option value=\"all\">{labels.pageSizeAll}</option>\n </select>\n )}\n </div>\n {pageSize !== Infinity && totalPages > 1 && (\n <div data-slot=\"page-strip\" className={PAGE_STRIP}>\n <button\n type=\"button\"\n onClick={() => onPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.prevPage}\n >\n {/* \"Previous\" points back along the line — left in LTR, right in RTL. */}\n <ChevronLeft className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n <div data-slot=\"page-numbers\" className={PAGE_NUMBERS}>\n {items.map((it, i) =>\n it === \"ellipsis\" ? (\n <span key={`e${i}`} className=\"px-1 text-[var(--text-placeholder)]\">\n …\n </span>\n ) : (\n <button\n key={it}\n type=\"button\"\n onClick={() => onPage(it)}\n // Which page you are on is carried only by a background colour\n // otherwise, and the strip is a row of bare numbers with nothing\n // else to tell them apart.\n aria-current={it === page ? \"page\" : undefined}\n className={cn(\n \"rounded\",\n compact ? \"min-w-6 px-1.5 py-0\" : \"min-w-7 px-2 py-0.5\",\n it === page\n ? \"bg-[var(--bg-inverse)] text-[var(--text-inverse)]\"\n : \"hover:bg-[var(--bg-hover)]\",\n )}\n >\n {num.format(it + 1)}\n </button>\n ),\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => onPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.nextPage}\n >\n <ChevronRight className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -35,7 +35,7 @@ import { useBodyScrollLock } from "../hooks/use-body-scroll-lock.js";
35
35
  import { useOverlayHistory } from "../hooks/use-overlay-history.js";
36
36
  import { FullBleedDialog } from "./full-bleed-dialog.js";
37
37
  import { Popover } from "./popover.js";
38
- import { useBreakpoint } from "../hooks/use-breakpoint.js";
38
+ import { usePhoneLayout } from "../hooks/use-breakpoint.js";
39
39
  import { useAnnounce } from "../hooks/use-announce.js";
40
40
  import { DEFAULT_DATA_TABLE_LABELS, resolveDataTableLabels } from "./data-table-labels.js";
41
41
  import { useKitLabelOverrides, useKitLocale } from "../i18n/kit-labels.js";
@@ -637,7 +637,7 @@ function DataTable({
637
637
  const footerValue = (col) => col.footer?.(sorted, slice);
638
638
  const footerHeadingId = useId();
639
639
  const columnsCountLabel = rowActions ? labels.columnsCount(visibleCount - 1, totalCount - 1) : labels.columnsCount(visibleCount, totalCount);
640
- const isMdUp = useBreakpoint("md", true);
640
+ const isMdUp = !usePhoneLayout();
641
641
  const desktopScroller = useRef(null);
642
642
  const edgeFadeProps = useEdgeFade(desktopScroller, edgeFade && isMdUp);
643
643
  const mobileColumns = visibleColumns.filter((c) => !c.mobileHidden);