@alfakit/react 0.1.2 → 0.1.6

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 (171) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/components/actions/action-modals.js +4 -0
  3. package/dist/components/actions/action-modals.js.map +1 -1
  4. package/dist/components/ai/copilot.d.ts +3 -1
  5. package/dist/components/ai/copilot.d.ts.map +1 -1
  6. package/dist/components/ai/copilot.js +4 -1
  7. package/dist/components/ai/copilot.js.map +1 -1
  8. package/dist/components/cms/live-preview.js +3 -2
  9. package/dist/components/cms/live-preview.js.map +1 -1
  10. package/dist/components/cms/page.js +1 -1
  11. package/dist/components/fields/builder.js +15 -6
  12. package/dist/components/fields/builder.js.map +1 -1
  13. package/dist/components/fields/image-editor-dialog.js +4 -2
  14. package/dist/components/fields/image-editor-dialog.js.map +1 -1
  15. package/dist/components/fields/item-actions.js +10 -10
  16. package/dist/components/fields/item-actions.js.map +1 -1
  17. package/dist/components/fields/key-value.d.ts.map +1 -1
  18. package/dist/components/fields/key-value.js +3 -3
  19. package/dist/components/fields/key-value.js.map +1 -1
  20. package/dist/components/fields/modal-table-select.js +6 -5
  21. package/dist/components/fields/modal-table-select.js.map +1 -1
  22. package/dist/components/fields/repeater.js +2 -2
  23. package/dist/components/fields/repeater.js.map +1 -1
  24. package/dist/components/fields/rich-editor.js +2 -1
  25. package/dist/components/fields/rich-editor.js.map +1 -1
  26. package/dist/components/form/form-block.js +1 -1
  27. package/dist/components/form/form-block.js.map +1 -1
  28. package/dist/components/form/form-context.js +2 -2
  29. package/dist/components/form/form-context.js.map +1 -1
  30. package/dist/components/kanban/kanban.js +4 -3
  31. package/dist/components/kanban/kanban.js.map +1 -1
  32. package/dist/components/layout/section.js +2 -2
  33. package/dist/components/layout/section.js.map +1 -1
  34. package/dist/components/panel/app-sidebar.d.ts +2 -3
  35. package/dist/components/panel/app-sidebar.d.ts.map +1 -1
  36. package/dist/components/panel/app-sidebar.js +1 -24
  37. package/dist/components/panel/app-sidebar.js.map +1 -1
  38. package/dist/components/panel/brand.d.ts +10 -0
  39. package/dist/components/panel/brand.d.ts.map +1 -0
  40. package/dist/components/panel/brand.js +37 -0
  41. package/dist/components/panel/brand.js.map +1 -0
  42. package/dist/components/panel/index.d.ts +2 -1
  43. package/dist/components/panel/topbar.js +1 -1
  44. package/dist/components/realtime/live-records-pill.d.ts.map +1 -1
  45. package/dist/components/realtime/live-records-pill.js +6 -3
  46. package/dist/components/realtime/live-records-pill.js.map +1 -1
  47. package/dist/components/table/cells.d.ts +6 -0
  48. package/dist/components/table/cells.d.ts.map +1 -1
  49. package/dist/components/table/cells.js +6 -2
  50. package/dist/components/table/cells.js.map +1 -1
  51. package/dist/components/table/column-manager.js +8 -7
  52. package/dist/components/table/column-manager.js.map +1 -1
  53. package/dist/components/table/content-layout.js +2 -1
  54. package/dist/components/table/content-layout.js.map +1 -1
  55. package/dist/components/table/pagination.js +16 -13
  56. package/dist/components/table/pagination.js.map +1 -1
  57. package/dist/components/table/table-block.js +14 -4
  58. package/dist/components/table/table-block.js.map +1 -1
  59. package/dist/components/ui/dialog.d.ts.map +1 -1
  60. package/dist/components/ui/dialog.js +3 -1
  61. package/dist/components/ui/dialog.js.map +1 -1
  62. package/dist/components/ui/popover.d.ts.map +1 -1
  63. package/dist/components/ui/popover.js +3 -1
  64. package/dist/components/ui/popover.js.map +1 -1
  65. package/dist/components/ui/sheet.d.ts.map +1 -1
  66. package/dist/components/ui/sheet.js +3 -1
  67. package/dist/components/ui/sheet.js.map +1 -1
  68. package/dist/components/ui/tooltip.js +3 -1
  69. package/dist/components/ui/tooltip.js.map +1 -1
  70. package/dist/context.d.ts +5 -0
  71. package/dist/context.d.ts.map +1 -1
  72. package/dist/context.js +5 -1
  73. package/dist/context.js.map +1 -1
  74. package/dist/create-alfakit.d.ts.map +1 -1
  75. package/dist/create-alfakit.js +8 -5
  76. package/dist/create-alfakit.js.map +1 -1
  77. package/dist/eject-manifest.json +16 -3
  78. package/dist/index.d.ts +6 -3
  79. package/dist/index.js +24 -21
  80. package/dist/layouts/app-layout.d.ts.map +1 -1
  81. package/dist/layouts/app-layout.js +2 -29
  82. package/dist/layouts/app-layout.js.map +1 -1
  83. package/dist/layouts/auth-layout.js +2 -2
  84. package/dist/layouts/auth-layout.js.map +1 -1
  85. package/dist/layouts/fullscreen-layout.js +1 -1
  86. package/dist/layouts/fullscreen-layout.js.map +1 -1
  87. package/dist/layouts/lazy-layouts.js +15 -0
  88. package/dist/layouts/lazy-layouts.js.map +1 -0
  89. package/dist/layouts/max-widths.js +34 -0
  90. package/dist/layouts/max-widths.js.map +1 -0
  91. package/dist/layouts/panel-layouts.d.ts +10 -0
  92. package/dist/layouts/panel-layouts.d.ts.map +1 -0
  93. package/dist/layouts/panel-layouts.js +20 -0
  94. package/dist/layouts/panel-layouts.js.map +1 -0
  95. package/dist/layouts/top-nav-layout.js +2 -2
  96. package/dist/layouts/top-nav-layout.js.map +1 -1
  97. package/dist/pages/page.d.ts.map +1 -1
  98. package/dist/pages/page.js +12 -7
  99. package/dist/pages/page.js.map +1 -1
  100. package/dist/standalone/alfakit-component.js +11 -6
  101. package/dist/standalone/alfakit-component.js.map +1 -1
  102. package/dist/standalone.css +7 -0
  103. package/dist/starter-kit/dashboard-widgets.d.ts +33 -0
  104. package/dist/starter-kit/dashboard-widgets.d.ts.map +1 -0
  105. package/dist/starter-kit/dashboard-widgets.js +53 -0
  106. package/dist/starter-kit/dashboard-widgets.js.map +1 -0
  107. package/dist/starter-kit/impersonation-banner.js +34 -0
  108. package/dist/starter-kit/impersonation-banner.js.map +1 -0
  109. package/dist/starter-kit/index.d.ts +3 -2
  110. package/dist/starter-kit/index.js +3 -2
  111. package/dist/starter-kit/starter-kit.d.ts +6 -0
  112. package/dist/starter-kit/starter-kit.d.ts.map +1 -1
  113. package/dist/starter-kit/starter-kit.js +18 -7
  114. package/dist/starter-kit/starter-kit.js.map +1 -1
  115. package/dist/starter-kit/widgets-loaded.js +20 -4
  116. package/dist/starter-kit/widgets-loaded.js.map +1 -1
  117. package/dist/starter-kit/widgets-triggers.js +34 -3
  118. package/dist/starter-kit/widgets-triggers.js.map +1 -1
  119. package/dist/starter-kit/widgets.d.ts +13 -5
  120. package/dist/starter-kit/widgets.d.ts.map +1 -1
  121. package/dist/starter-kit/widgets.js +56 -18
  122. package/dist/starter-kit/widgets.js.map +1 -1
  123. package/dist/styles.css +15 -2
  124. package/dist/themes.css +6 -1
  125. package/package.json +2 -2
  126. package/src/components/actions/action-modals.tsx +10 -0
  127. package/src/components/ai/copilot.tsx +14 -1
  128. package/src/components/cms/live-preview.tsx +5 -2
  129. package/src/components/fields/builder.tsx +14 -5
  130. package/src/components/fields/image-editor-dialog.tsx +7 -2
  131. package/src/components/fields/item-actions.tsx +32 -9
  132. package/src/components/fields/key-value.tsx +3 -2
  133. package/src/components/fields/modal-table-select.tsx +8 -3
  134. package/src/components/fields/repeater.tsx +2 -3
  135. package/src/components/fields/rich-editor.tsx +3 -0
  136. package/src/components/form/form-block.tsx +2 -1
  137. package/src/components/form/form-context.tsx +2 -2
  138. package/src/components/kanban/kanban.tsx +16 -3
  139. package/src/components/layout/section.tsx +2 -2
  140. package/src/components/panel/app-sidebar.tsx +2 -38
  141. package/src/components/panel/brand.tsx +46 -0
  142. package/src/components/realtime/live-records-pill.tsx +4 -3
  143. package/src/components/table/cells.tsx +9 -2
  144. package/src/components/table/column-manager.tsx +12 -10
  145. package/src/components/table/content-layout.tsx +5 -1
  146. package/src/components/table/pagination.tsx +16 -9
  147. package/src/components/table/table-block.tsx +25 -12
  148. package/src/components/ui/dialog.tsx +5 -1
  149. package/src/components/ui/popover.tsx +5 -1
  150. package/src/components/ui/sheet.tsx +5 -1
  151. package/src/components/ui/tooltip.tsx +5 -1
  152. package/src/context.tsx +10 -0
  153. package/src/create-alfakit.tsx +11 -2
  154. package/src/index.ts +2 -0
  155. package/src/layouts/app-layout.tsx +4 -28
  156. package/src/layouts/auth-layout.tsx +2 -2
  157. package/src/layouts/fullscreen-layout.tsx +1 -1
  158. package/src/layouts/lazy-layouts.ts +14 -0
  159. package/src/layouts/max-widths.ts +29 -0
  160. package/src/layouts/panel-layouts.ts +17 -0
  161. package/src/layouts/top-nav-layout.tsx +2 -2
  162. package/src/pages/page.tsx +21 -12
  163. package/src/standalone/alfakit-component.tsx +18 -7
  164. package/src/starter-kit/dashboard-widgets.tsx +78 -0
  165. package/src/starter-kit/impersonation-banner.tsx +48 -0
  166. package/src/starter-kit/index.ts +2 -0
  167. package/src/starter-kit/starter-kit.tsx +31 -4
  168. package/src/starter-kit/widgets-loaded.tsx +22 -0
  169. package/src/starter-kit/widgets-triggers.tsx +36 -1
  170. package/src/starter-kit/widgets.tsx +95 -20
  171. package/src/styles.css +15 -2
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","names":[],"sources":["../../../src/components/table/pagination.tsx"],"sourcesContent":["import type { AnyPaginationSchema, TableSchema } from '@alfakit/core'\nimport {\n extremePageLinks,\n isAppendingPagination,\n nextPageQuery,\n prefetchTablePage,\n previousPageQuery,\n visitTable,\n} from '@alfakit/core'\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n} from 'lucide-react'\nimport { useEffect, useRef, useState } from 'react'\nimport { useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { Button } from '../ui/button'\n\nexport function TablePagination({ table }: { table: TableSchema }) {\n const t = useT()\n const pagination = table.pagination\n\n if (!pagination) {\n return null\n }\n\n if (isAppendingPagination(pagination)) {\n return <AppendingPagination table={table} pagination={pagination} />\n }\n\n const numbered = pagination.mode === undefined || pagination.mode === 'default'\n const pages = numbered ? pageWindow(pagination.currentPage, pagination.lastPage) : []\n const previous = previousPageQuery(pagination)\n const next = nextPageQuery(pagination)\n // `extremePaginationLinks()`: first / last page buttons around numbered pages.\n const extremes = numbered\n ? extremePageLinks(table, pagination.currentPage, pagination.lastPage)\n : null\n const summary = numbered\n ? t(\n 'table.showing',\n { first: pagination.from, last: pagination.to, total: pagination.total },\n `Showing ${pagination.from}–${pagination.to} of ${pagination.total}`,\n )\n : t(\n 'table.showing_range',\n { first: pagination.from, last: pagination.to },\n `Showing ${pagination.from}–${pagination.to}`,\n )\n\n return (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"text-muted-foreground flex items-center gap-3 text-sm\">\n <span>{summary}</span>\n {/* `deferTotals()`: the total and page numbers arrive after the rows. */}\n {pagination.mode === 'simple' && pagination.pendingTotal && (\n <span\n data-slot=\"pagination-total\"\n aria-busy=\"true\"\n aria-label={t('loading', {}, 'Loading')}\n className=\"bg-muted-foreground/20 inline-block h-4 w-12 animate-pulse rounded-md\"\n />\n )}\n <PerPageSelect table={table} pagination={pagination} />\n </div>\n {(previous || next) && (\n <nav className=\"flex items-center gap-1\" aria-label={t('pagination', {}, 'Pagination')}>\n {extremes && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n data-slot=\"pagination-first\"\n disabled={extremes.first === null}\n onClick={() => visitTable(table.identifier, { page: 1 }, ['page'])}\n aria-label={t('table.first_page', {}, 'First page')}\n >\n <Icon\n name=\"alfakit::support.pagination.first-button\"\n fallback={ChevronsLeftIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n disabled={!previous}\n onClick={() => previous && visitTable(table.identifier, previous, ['page'])}\n aria-label={t('table.previous', {}, 'Previous')}\n >\n <Icon\n name=\"alfakit::support.pagination.previous-button\"\n fallback={ChevronLeftIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n {numbered &&\n !pagination.simple &&\n pages.map((page, index) =>\n page === null ? (\n <span key={`gap-${index}`} className=\"text-muted-foreground px-1\">\n …\n </span>\n ) : (\n <Button\n key={page}\n type=\"button\"\n variant={page === pagination.currentPage ? 'default' : 'outline'}\n size=\"icon-sm\"\n onClick={() => visitTable(table.identifier, { page }, ['page'])}\n aria-current={page === pagination.currentPage ? 'page' : undefined}\n >\n {page}\n </Button>\n ),\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n disabled={!next}\n onClick={() => next && visitTable(table.identifier, next, ['page'])}\n // The next page is fetched while hovering or focusing (cached for a few seconds).\n onPointerEnter={() => next && prefetchTablePage(table.identifier, next)}\n onFocus={() => next && prefetchTablePage(table.identifier, next)}\n aria-label={t('table.next', {}, 'Next')}\n >\n <Icon\n name=\"alfakit::support.pagination.next-button\"\n fallback={ChevronRightIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n {extremes && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n data-slot=\"pagination-last\"\n disabled={extremes.last === null}\n onClick={() =>\n extremes.last !== null &&\n visitTable(table.identifier, { page: extremes.last }, ['page'])\n }\n aria-label={t('table.last_page', {}, 'Last page')}\n >\n <Icon\n name=\"alfakit::support.pagination.last-button\"\n fallback={ChevronsRightIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n )}\n </nav>\n )}\n </div>\n )\n}\n\nfunction PerPageSelect({\n table,\n pagination,\n}: {\n table: TableSchema\n pagination: AnyPaginationSchema\n}) {\n const t = useT()\n\n if (pagination.pageOptions.length <= 1) return null\n\n return (\n <label className=\"flex items-center gap-2\">\n <span className=\"sr-only sm:not-sr-only\">{t('table.per_page', {}, 'Per page')}</span>\n <select\n value={String(pagination.perPage)}\n onChange={(event) =>\n visitTable(\n table.identifier,\n { perPage: event.target.value === 'all' ? 'all' : Number(event.target.value) },\n ['page'],\n )\n }\n className=\"border-input h-8 rounded-md border bg-transparent px-2 text-sm\"\n >\n {pagination.pageOptions.map((option) => (\n <option key={option} value={String(option)}>\n {option === 'all' ? t('table.all', {}, 'All') : option}\n </option>\n ))}\n </select>\n </label>\n )\n}\n\n/**\n * Load more / infinite scroll: the server returns every record up to the requested page,\n * so asking for the next page appends it (and reloads keep what was already shown). A\n * request that fails (network, server error) shows a retry control instead of staying on\n * \"Loading more…\"; infinite scroll waits for the retry rather than requesting again.\n */\nfunction AppendingPagination({\n table,\n pagination,\n}: {\n table: TableSchema\n pagination: Extract<AnyPaginationSchema, { mode: 'load-more' | 'infinite' }>\n}) {\n const t = useT()\n const sentinel = useRef<HTMLDivElement>(null)\n const [loading, setLoading] = useState(false)\n const [failed, setFailed] = useState(false)\n const [loadedTo, setLoadedTo] = useState(pagination.to)\n const next = nextPageQuery(pagination)\n\n // A response with more records ends the in-flight request.\n if (loadedTo !== pagination.to) {\n setLoadedTo(pagination.to)\n setLoading(false)\n setFailed(false)\n }\n\n const loadMore = () => {\n if (!next || loading) return\n\n let succeeded = false\n let cancelled = false\n setLoading(true)\n setFailed(false)\n visitTable(table.identifier, next, ['page'], {\n onSuccess: () => {\n succeeded = true\n },\n onCancel: () => {\n cancelled = true\n },\n onFinish: () => {\n setLoading(false)\n if (!succeeded && !cancelled) setFailed(true)\n },\n })\n }\n\n const loadMoreRef = useRef(loadMore)\n\n useEffect(() => {\n loadMoreRef.current = loadMore\n })\n\n useEffect(() => {\n if (\n pagination.mode !== 'infinite' ||\n !next ||\n failed ||\n typeof IntersectionObserver === 'undefined'\n ) {\n return\n }\n\n const element = sentinel.current\n\n if (!element) return\n\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) loadMoreRef.current()\n })\n\n observer.observe(element)\n\n return () => observer.disconnect()\n }, [pagination.mode, next, failed])\n\n const retry = (\n <div className=\"flex items-center gap-2 text-sm\" role=\"alert\">\n <span className=\"text-destructive\">\n {t('table.load_more_failed', {}, \"Couldn't load more records.\")}\n </span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={loadMore}>\n {t('retry', {}, 'Retry')}\n </Button>\n </div>\n )\n\n return (\n <div className=\"flex flex-col items-center gap-3 sm:flex-row sm:justify-between\">\n <div className=\"text-muted-foreground flex items-center gap-3 text-sm\">\n <span>\n {t(\n 'table.showing_range',\n { first: pagination.from, last: pagination.to },\n `Showing ${pagination.from}–${pagination.to}`,\n )}\n </span>\n <PerPageSelect table={table} pagination={pagination} />\n </div>\n {next &&\n (failed ? (\n retry\n ) : pagination.mode === 'infinite' ? (\n <div ref={sentinel} className=\"text-muted-foreground text-sm\" aria-live=\"polite\">\n {loading ? t('table.loading_more', {}, 'Loading more…') : null}\n </div>\n ) : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={loading} onClick={loadMore}>\n {loading\n ? t('table.loading_more', {}, 'Loading more…')\n : t('load_more', {}, 'Load more')}\n </Button>\n ))}\n </div>\n )\n}\n\nfunction pageWindow(current: number, last: number): Array<number | null> {\n if (last <= 7) {\n return Array.from({ length: last }, (_, index) => index + 1)\n }\n\n const pages = new Set<number>([1, last, current - 1, current, current + 1])\n const sorted = [...pages].filter((page) => page >= 1 && page <= last).sort((a, b) => a - b)\n const result: Array<number | null> = []\n\n sorted.forEach((page, index) => {\n if (index > 0 && page - (sorted[index - 1] ?? 0) > 1) {\n result.push(null)\n }\n\n result.push(page)\n })\n\n return result\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../../src/components/table/pagination.tsx"],"sourcesContent":["import type { AnyPaginationSchema, TableSchema } from '@alfakit/core'\nimport {\n extremePageLinks,\n isAppendingPagination,\n nextPageQuery,\n prefetchTablePage,\n previousPageQuery,\n visitTable,\n} from '@alfakit/core'\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n} from 'lucide-react'\nimport { useEffect, useRef, useState } from 'react'\nimport { useFormatter, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { Button } from '../ui/button'\n\nexport function TablePagination({ table }: { table: TableSchema }) {\n const t = useT()\n const format = useFormatter()\n const pagination = table.pagination\n\n if (!pagination) {\n return null\n }\n\n if (isAppendingPagination(pagination)) {\n return <AppendingPagination table={table} pagination={pagination} />\n }\n\n const numbered = pagination.mode === undefined || pagination.mode === 'default'\n const pages = numbered ? pageWindow(pagination.currentPage, pagination.lastPage) : []\n const previous = previousPageQuery(pagination)\n const next = nextPageQuery(pagination)\n // `extremePaginationLinks()`: first / last page buttons around numbered pages.\n const extremes = numbered\n ? extremePageLinks(table, pagination.currentPage, pagination.lastPage)\n : null\n const summary = numbered\n ? t(\n 'table.showing',\n {\n first: format.number(pagination.from),\n last: format.number(pagination.to),\n total: format.number(pagination.total),\n },\n 'Showing :first–:last of :total',\n )\n : t(\n 'table.showing_range',\n { first: format.number(pagination.from), last: format.number(pagination.to) },\n 'Showing :first–:last',\n )\n\n return (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"text-muted-foreground flex items-center gap-3 text-sm\">\n <span>{summary}</span>\n {/* `deferTotals()`: the total and page numbers arrive after the rows. */}\n {pagination.mode === 'simple' && pagination.pendingTotal && (\n <span\n data-slot=\"pagination-total\"\n aria-busy=\"true\"\n aria-label={t('loading', {}, 'Loading')}\n className=\"bg-muted-foreground/20 inline-block h-4 w-12 animate-pulse rounded-md\"\n />\n )}\n <PerPageSelect table={table} pagination={pagination} />\n </div>\n {(previous || next) && (\n <nav className=\"flex items-center gap-1\" aria-label={t('pagination', {}, 'Pagination')}>\n {extremes && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n data-slot=\"pagination-first\"\n disabled={extremes.first === null}\n onClick={() => visitTable(table.identifier, { page: 1 }, ['page'])}\n aria-label={t('table.first_page', {}, 'First page')}\n >\n <Icon\n name=\"alfakit::support.pagination.first-button\"\n fallback={ChevronsLeftIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n disabled={!previous}\n onClick={() => previous && visitTable(table.identifier, previous, ['page'])}\n aria-label={t('table.previous', {}, 'Previous')}\n >\n <Icon\n name=\"alfakit::support.pagination.previous-button\"\n fallback={ChevronLeftIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n {numbered &&\n !pagination.simple &&\n pages.map((page, index) =>\n page === null ? (\n <span key={`gap-${index}`} className=\"text-muted-foreground px-1\">\n …\n </span>\n ) : (\n <Button\n key={page}\n type=\"button\"\n variant={page === pagination.currentPage ? 'default' : 'outline'}\n size=\"icon-sm\"\n onClick={() => visitTable(table.identifier, { page }, ['page'])}\n aria-current={page === pagination.currentPage ? 'page' : undefined}\n >\n {format.number(page)}\n </Button>\n ),\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n disabled={!next}\n onClick={() => next && visitTable(table.identifier, next, ['page'])}\n // The next page is fetched while hovering or focusing (cached for a few seconds).\n onPointerEnter={() => next && prefetchTablePage(table.identifier, next)}\n onFocus={() => next && prefetchTablePage(table.identifier, next)}\n aria-label={t('table.next', {}, 'Next')}\n >\n <Icon\n name=\"alfakit::support.pagination.next-button\"\n fallback={ChevronRightIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n {extremes && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n data-slot=\"pagination-last\"\n disabled={extremes.last === null}\n onClick={() =>\n extremes.last !== null &&\n visitTable(table.identifier, { page: extremes.last }, ['page'])\n }\n aria-label={t('table.last_page', {}, 'Last page')}\n >\n <Icon\n name=\"alfakit::support.pagination.last-button\"\n fallback={ChevronsRightIcon}\n className=\"rtl:rotate-180\"\n />\n </Button>\n )}\n </nav>\n )}\n </div>\n )\n}\n\nfunction PerPageSelect({\n table,\n pagination,\n}: {\n table: TableSchema\n pagination: AnyPaginationSchema\n}) {\n const t = useT()\n const format = useFormatter()\n\n if (pagination.pageOptions.length <= 1) return null\n\n return (\n <label className=\"flex items-center gap-2\">\n <span className=\"sr-only sm:not-sr-only\">{t('table.per_page', {}, 'Per page')}</span>\n <select\n value={String(pagination.perPage)}\n onChange={(event) =>\n visitTable(\n table.identifier,\n { perPage: event.target.value === 'all' ? 'all' : Number(event.target.value) },\n ['page'],\n )\n }\n className=\"border-input h-8 rounded-md border bg-transparent px-2 text-sm\"\n >\n {pagination.pageOptions.map((option) => (\n <option key={option} value={String(option)}>\n {option === 'all' ? t('table.all', {}, 'All') : format.number(option)}\n </option>\n ))}\n </select>\n </label>\n )\n}\n\n/**\n * Load more / infinite scroll: the server returns every record up to the requested page,\n * so asking for the next page appends it (and reloads keep what was already shown). A\n * request that fails (network, server error) shows a retry control instead of staying on\n * \"Loading more…\"; infinite scroll waits for the retry rather than requesting again.\n */\nfunction AppendingPagination({\n table,\n pagination,\n}: {\n table: TableSchema\n pagination: Extract<AnyPaginationSchema, { mode: 'load-more' | 'infinite' }>\n}) {\n const t = useT()\n const format = useFormatter()\n const sentinel = useRef<HTMLDivElement>(null)\n const [loading, setLoading] = useState(false)\n const [failed, setFailed] = useState(false)\n const [loadedTo, setLoadedTo] = useState(pagination.to)\n const next = nextPageQuery(pagination)\n\n // A response with more records ends the in-flight request.\n if (loadedTo !== pagination.to) {\n setLoadedTo(pagination.to)\n setLoading(false)\n setFailed(false)\n }\n\n const loadMore = () => {\n if (!next || loading) return\n\n let succeeded = false\n let cancelled = false\n setLoading(true)\n setFailed(false)\n visitTable(table.identifier, next, ['page'], {\n onSuccess: () => {\n succeeded = true\n },\n onCancel: () => {\n cancelled = true\n },\n onFinish: () => {\n setLoading(false)\n if (!succeeded && !cancelled) setFailed(true)\n },\n })\n }\n\n const loadMoreRef = useRef(loadMore)\n\n useEffect(() => {\n loadMoreRef.current = loadMore\n })\n\n useEffect(() => {\n if (\n pagination.mode !== 'infinite' ||\n !next ||\n failed ||\n typeof IntersectionObserver === 'undefined'\n ) {\n return\n }\n\n const element = sentinel.current\n\n if (!element) return\n\n const observer = new IntersectionObserver((entries) => {\n if (entries.some((entry) => entry.isIntersecting)) loadMoreRef.current()\n })\n\n observer.observe(element)\n\n return () => observer.disconnect()\n }, [pagination.mode, next, failed])\n\n const retry = (\n <div className=\"flex items-center gap-2 text-sm\" role=\"alert\">\n <span className=\"text-destructive\">\n {t('table.load_more_failed', {}, \"Couldn't load more records.\")}\n </span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={loadMore}>\n {t('retry', {}, 'Retry')}\n </Button>\n </div>\n )\n\n return (\n <div className=\"flex flex-col items-center gap-3 sm:flex-row sm:justify-between\">\n <div className=\"text-muted-foreground flex items-center gap-3 text-sm\">\n <span>\n {t(\n 'table.showing_range',\n { first: format.number(pagination.from), last: format.number(pagination.to) },\n 'Showing :first–:last',\n )}\n </span>\n <PerPageSelect table={table} pagination={pagination} />\n </div>\n {next &&\n (failed ? (\n retry\n ) : pagination.mode === 'infinite' ? (\n <div ref={sentinel} className=\"text-muted-foreground text-sm\" aria-live=\"polite\">\n {loading ? t('table.loading_more', {}, 'Loading more…') : null}\n </div>\n ) : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={loading} onClick={loadMore}>\n {loading\n ? t('table.loading_more', {}, 'Loading more…')\n : t('load_more', {}, 'Load more')}\n </Button>\n ))}\n </div>\n )\n}\n\nfunction pageWindow(current: number, last: number): Array<number | null> {\n if (last <= 7) {\n return Array.from({ length: last }, (_, index) => index + 1)\n }\n\n const pages = new Set<number>([1, last, current - 1, current, current + 1])\n const sorted = [...pages].filter((page) => page >= 1 && page <= last).sort((a, b) => a - b)\n const result: Array<number | null> = []\n\n sorted.forEach((page, index) => {\n if (index > 0 && page - (sorted[index - 1] ?? 0) > 1) {\n result.push(null)\n }\n\n result.push(page)\n })\n\n return result\n}\n"],"mappings":"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"}
@@ -106,6 +106,11 @@ function DataTable({ table: serverTable, component = "table", token: tokenProp,
106
106
  setSearch(table.search ?? "");
107
107
  }
108
108
  const pushSearch = useMemo(() => debounce((value) => visitTable(table.identifier, { search: value || null }, ["page"]), table.searchDebounce), [table.identifier, table.searchDebounce]);
109
+ const pushColumnSearch = useMemo(() => debounce((columnSearch) => visitTable(table.identifier, { columnSearch }, ["page"]), table.searchDebounce), [table.identifier, table.searchDebounce]);
110
+ const searchColumn = (name, value) => pushColumnSearch({
111
+ ...table.columnSearches ?? {},
112
+ [name]: value
113
+ });
109
114
  const pollComponent = usePollComponent();
110
115
  useEffect(() => pollComponent(component, table.pollingInterval), [
111
116
  pollComponent,
@@ -496,10 +501,15 @@ function DataTable({ table: serverTable, component = "table", token: tokenProp,
496
501
  placeholder: t("search", {}, "Search"),
497
502
  "aria-label": `${t("search", {}, "Search")} ${column.label}`,
498
503
  className: "h-7 text-xs font-normal",
499
- onKeyDown: (event) => event.key === "Enter" && visitTable(table.identifier, { columnSearch: {
500
- ...table.columnSearches ?? {},
501
- [column.name]: event.target.value
502
- } }, ["page"])
504
+ onChange: (event) => {
505
+ if (!table.searchOnBlur) searchColumn(column.name, event.target.value);
506
+ },
507
+ onBlur: (event) => table.searchOnBlur && searchColumn(column.name, event.target.value),
508
+ onKeyDown: (event) => {
509
+ if (event.key !== "Enter") return;
510
+ searchColumn(column.name, event.target.value);
511
+ pushColumnSearch.flush();
512
+ }
503
513
  })
504
514
  ]
505
515
  })
@@ -1 +1 @@
1
- {"version":3,"file":"table-block.js","names":[],"sources":["../../../src/components/table/table-block.tsx"],"sourcesContent":["import type { ActionContext, RecordKey, TableRecordSchema, TableSchema } from '@alfakit/core'\nimport {\n STACKED_TABLE_CLASSES,\n TableSelection,\n VIRTUAL_ESTIMATES,\n ariaSort,\n cachedTableTotals,\n canSelectAllRecords,\n columnGroupHeaderRow,\n columnVisibilityClasses,\n debounce,\n filtersPlacement,\n groupTableRows,\n isGroupedColumn,\n isTableLoading,\n loadTableTotals,\n mobileTable,\n moveListItem,\n pageFlash,\n pageSelectionState,\n paginationTotal,\n primaryColumnName,\n reorderTable,\n resolvePartialProps,\n selectedRecordsArguments,\n skeletonRowCount,\n stackedCellClasses,\n startTableReordering,\n stopTableReordering,\n tableLoadingStore,\n tableTotalsFailed,\n tableTotalsStore,\n triggerButtonView,\n virtualizeOptions,\n visitTable,\n withTableTotals,\n} from '@alfakit/core'\nimport { Link, router } from '@inertiajs/react'\nimport {\n ArrowDownIcon,\n ArrowUpDownIcon,\n ArrowUpIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n GripVerticalIcon,\n SearchIcon,\n Table2Icon,\n XIcon,\n} from 'lucide-react'\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport {\n useActionRunner,\n useChoice,\n usePageSchema,\n usePanel,\n usePollComponent,\n useT,\n} from '../../context'\nimport { useIsMobile } from '../../hooks/use-mobile'\nimport { useStore } from '../../hooks/use-store'\nimport { useVirtualList } from '../../hooks/use-virtual-list'\nimport { extraProps } from '../../lib/attributes'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { ActionList } from '../actions/action-list'\nimport { showToast } from '../notifications/flash-toasts'\nimport { Slot } from '../panel/slot'\nimport { LiveRecordsPill, useLiveUpdates } from '../realtime/live-records-pill'\nimport { VirtualSpacerRow } from '../schema/virtual-spacer'\nimport { Button } from '../ui/button'\nimport { Checkbox } from '../ui/checkbox'\nimport { Input } from '../ui/input'\nimport { Spinner } from '../ui/spinner'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table'\nimport { TableCellContent } from './cells'\nimport { ColumnManager } from './column-manager'\nimport { ContentLayout, ContentLayoutSort } from './content-layout'\nimport { FilterIndicators, TableFilters } from './filters'\nimport {\n GroupHeaderRow,\n TableGroupingMenu,\n useCollapsedGroups,\n useTablePersistence,\n} from './grouping'\nimport { TablePagination } from './pagination'\nimport { Spreadsheet } from './spreadsheet-lazy'\nimport { SummaryRow, TableSummaryFooter } from './summary-rows'\nimport { TableViews } from './table-views'\nimport { TableTriggerButton } from './trigger-button'\n\nexport interface DataTableProps {\n table: TableSchema\n /** Context component (`table`, `relationManager:…`, `widget:…`). */\n component?: string\n token?: string\n className?: string\n}\n\nconst ALIGN: Record<string, string> = {\n start: 'text-start',\n center: 'text-center',\n end: 'text-end',\n between: 'text-start',\n justify: 'text-justify',\n}\n\nconst VERTICAL_ALIGN: Record<string, string> = {\n start: 'align-top',\n center: 'align-middle',\n end: 'align-bottom',\n}\n\nexport function DataTable({\n table: serverTable,\n component = 'table',\n token: tokenProp,\n className,\n}: DataTableProps) {\n const t = useT()\n const choice = useChoice()\n const panel = usePanel()\n const isMobile = useIsMobile()\n const page = usePageSchema()\n const runner = useActionRunner()\n const token = tokenProp ?? page?.token ?? ''\n // `deferTotals()`: the total and summaries load after the rows (placeholders meanwhile).\n const totalsVersion = useStore(tableTotalsStore)\n const totalsUrl = panel.endpoints.tableTotals\n\n useEffect(() => {\n void loadTableTotals(serverTable, { url: totalsUrl, token, component })\n }, [serverTable, totalsUrl, token, component, totalsVersion])\n\n const tableProp = useMemo(\n () =>\n withTableTotals(\n serverTable,\n cachedTableTotals(serverTable, component),\n tableTotalsFailed(serverTable, component),\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the store version invalidates the cache read\n [serverTable, component, totalsVersion],\n )\n // Under the mobile preset a phone renders the rows as stacked cards; the server and\n // desktop markup keep the table.\n const table = useMemo(\n () =>\n mobileTable(\n tableProp,\n tableProp.columns.filter((column) => tableProp.visibleColumns.includes(column.name)),\n { isMobile, panel },\n ),\n [tableProp, isMobile, panel],\n )\n\n const context = useMemo<ActionContext>(() => ({ token, component }), [token, component])\n const selection = useMemo(() => new TableSelection(), [])\n const selectionState = useStore(selection.store)\n const [search, setSearch] = useState(table.search ?? '')\n // A reload in reorder mode (`?reordering=1`) comes back still reordering.\n const [reordering, setReordering] = useState(Boolean(table.reordering))\n const [order, setOrder] = useState<RecordKey[] | null>(null)\n const [dragKey, setDragKey] = useState<RecordKey | null>(null)\n // Live-region text announced after a keyboard move in reorder mode.\n const [announcement, setAnnouncement] = useState('')\n // `spreadsheet()`: the grid editing mode, toggled from the toolbar.\n const [spreadsheet, setSpreadsheet] = useState(false)\n const spreadsheetOpen = spreadsheet && Boolean(table.spreadsheet) && !reordering\n\n const records = table.records ?? []\n const columns = table.columns.filter((column) => table.visibleColumns.includes(column.name))\n const hasActions = records.some((record) => record.actions && record.actions.length > 0)\n const selectable = Boolean(table.selectable)\n const [collapsedGroups, toggleGroup] = useCollapsedGroups(table)\n // Cells around the columns, so group and summary rows line up with the records.\n const leadingCells =\n Number(table.recordActionsPosition === 'before-cells' && hasActions) +\n Number(reordering) +\n Number(selectable) +\n Number(table.recordActionsPosition === 'before-columns' && hasActions)\n const trailingCells = Number(\n (table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions,\n )\n\n useTablePersistence(table)\n\n const [syncedSearch, setSyncedSearch] = useState(table.search)\n\n if (syncedSearch !== table.search) {\n setSyncedSearch(table.search)\n setSearch(table.search ?? '')\n }\n\n const pushSearch = useMemo(\n () =>\n debounce(\n (value: string) => visitTable(table.identifier, { search: value || null }, ['page']),\n table.searchDebounce,\n ),\n [table.identifier, table.searchDebounce],\n )\n\n // Polls refresh only this table (a partial reload of its own schema), share one request\n // with other components on the same interval and pause while the tab is hidden.\n const pollComponent = usePollComponent()\n\n useEffect(\n () => pollComponent(component, table.pollingInterval),\n [pollComponent, component, table.pollingInterval],\n )\n\n // `live()`: refresh in place when records change (broadcast), else poll as a fallback.\n const live = useLiveUpdates(table.live, component, {\n polling: Boolean(table.pollingInterval),\n records,\n })\n\n // A deferred table arrives without records: fetch them with a partial reload, which the\n // server always fills. Ask once per gap so a failing reload cannot loop.\n const awaitingRecords = Boolean(table.deferLoading) && !table.records\n const deferredRequested = useRef(false)\n\n useEffect(() => {\n if (!awaitingRecords) {\n deferredRequested.current = false\n return\n }\n\n if (deferredRequested.current) return\n\n deferredRequested.current = true\n router.reload({ only: resolvePartialProps(['page']) })\n }, [awaitingRecords])\n\n // `deselectAllRecordsWhenFiltered()`: new filters, search or tab clear the selection.\n useEffect(() => selection.syncScope(table.selectionScope), [selection, table.selectionScope])\n\n // `maxSelectableRecords()` / `selectGroupsOnly()`.\n selection.configure(table)\n\n // Clear selection after a bulk action completes.\n useEffect(() => {\n return router.on('success', (event) => {\n const flash = pageFlash(event.detail.page).alfakitAction\n\n if (flash?.deselectRecords) {\n selection.clear()\n }\n })\n }, [selection])\n\n // The column whose sort was just clicked shows a spinner until its records arrive.\n const [sortingColumn, setSortingColumn] = useState<string | null>(null)\n\n const sort = (column: string) => {\n const direction =\n table.sort?.column === column && table.sort.direction === 'asc' ? 'desc' : 'asc'\n setSortingColumn(column)\n visitTable(table.identifier, { sort: column, direction }, ['page'], {\n onFinish: () => setSortingColumn(null),\n })\n }\n\n const bulkContext = useMemo<ActionContext>(\n () => ({\n token,\n component,\n records: selectionState.allSelected ? [] : [...selectionState.selected],\n allRecords: selectionState.allSelected,\n }),\n [token, component, selectionState],\n )\n\n const orderedRecords = order\n ? order\n .map((key) => records.find((record) => String(record.key) === String(key)))\n .filter((record): record is TableRecordSchema => Boolean(record))\n : records\n\n const finishReorder = async () => {\n // Leave reorder mode even when saving fails, so the table shows the server order again.\n try {\n if (order && panel.endpoints.tableReorder && panel.endpoints.tableCell) {\n await reorderTable(\n { reorder: panel.endpoints.tableReorder, cell: panel.endpoints.tableCell },\n token,\n component,\n order,\n // Leaving a server-side reorder mode reloads the table anyway.\n { reload: !table.reordering },\n )\n }\n } catch (error) {\n showToast({\n id: 'alfakit-reorder-failed',\n title: t('table.reorder_failed', {}, \"Couldn't save the new order\"),\n body: error instanceof Error ? error.message : String(error),\n status: 'danger',\n format: 'alfakit',\n })\n } finally {\n setOrder(null)\n setReordering(false)\n stopTableReordering(table)\n }\n }\n\n // Keyboard alternative to drag-and-drop: the move up/down buttons in reorder mode.\n const moveRow = (index: number, offset: -1 | 1) => {\n const keys = orderedRecords.map((item) => item.key)\n const target = index + offset\n\n if (target < 0 || target >= keys.length) return\n\n setOrder(moveListItem(keys, index, target))\n setAnnouncement(\n t(\n 'table.row_moved',\n { position: target + 1, total: keys.length },\n 'Row moved to position :position of :total',\n ),\n )\n }\n\n const groupRow = columnGroupHeaderRow(columns, table.columnGroups)\n const headerRowSpan = groupRow ? 2 : undefined\n\n // Long pages render only the visible rows (plus a few around them); the spacer rows keep\n // the scroll height, `aria-rowcount` / `aria-rowindex` keep the real positions.\n const rows = groupTableRows(table, orderedRecords, collapsedGroups)\n const {\n range: rowWindow,\n indexes: positions,\n attach: attachBody,\n item: attachRow,\n } = useVirtualList(rows.length, virtualizeOptions(table.virtualize, VIRTUAL_ESTIMATES.row))\n const headerRows = groupRow ? 2 : 1\n const rowCells = columns.length + leadingCells + trailingCells\n\n // The column whose cell holds a clickable row's focusable link or button.\n const primaryColumn = primaryColumnName(columns)\n\n const rowClick = (record: TableRecordSchema) => {\n if (reordering) return\n\n if (table.recordAction) {\n const action = record.actions\n ?.flatMap((item) => ('actions' in item ? item.actions : [item]))\n .find((item) => 'name' in item && item.name === table.recordAction)\n\n if (action && 'name' in action) {\n void runner.trigger(action, { ...context, record: record.key })\n\n return\n }\n }\n\n if (record.url) {\n if (record.openUrlInNewTab) {\n window.open(record.url, '_blank', 'noopener')\n } else {\n router.visit(record.url)\n }\n }\n }\n\n // `reorderRecordsTriggerAction()`: one look per state.\n const reorderTrigger = triggerButtonView(\n table,\n reordering ? 'reorderRecordsActive' : 'reorderRecords',\n {\n label: reordering\n ? t('table.reorder_stop', {}, 'Done')\n : t('table.reorder_start', {}, 'Reorder'),\n variant: reordering ? 'default' : 'outline',\n },\n )\n const loadingState = useStore(tableLoadingStore)\n const showSkeleton =\n Boolean(table.loadingSkeleton) && isTableLoading(loadingState, table.identifier)\n\n const filtersAt = filtersPlacement(table.filtersLayout)\n const stacked = Boolean(table.stackedOnMobile)\n\n const toolbar = (\n <div className=\"flex flex-col gap-3\">\n <Slot name=\"table.header.before\" scope={component} />\n {(table.heading || table.description || table.headerActions?.length) && (\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n {table.heading && <h3 className=\"text-base font-semibold\">{table.heading}</h3>}\n {table.description && (\n <p className=\"text-muted-foreground text-sm\">{table.description}</p>\n )}\n </div>\n {table.headerActions && (\n <ActionList actions={table.headerActions} context={context} size=\"sm\" />\n )}\n </div>\n )}\n <Slot name=\"table.header.after\" scope={component} />\n <Slot name=\"table.toolbar.before\" scope={component} />\n {table.views && <TableViews table={table} token={token} component={component} />}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Slot name=\"table.toolbar.search.before\" scope={component} />\n {table.searchable && (\n <div className=\"relative min-w-48 flex-1 sm:max-w-xs\">\n <Icon\n name=\"alfakit::tables.search-field\"\n fallback={SearchIcon}\n className=\"text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 size-4 -translate-y-1/2\"\n />\n <Input\n type=\"search\"\n value={search}\n placeholder={table.searchPlaceholder}\n onChange={(event) => {\n setSearch(event.target.value)\n\n if (!table.searchOnBlur) pushSearch(event.target.value)\n }}\n onBlur={() => table.searchOnBlur && pushSearch(search)}\n onKeyDown={(event) => event.key === 'Enter' && pushSearch.flush()}\n className=\"h-8 ps-8\"\n aria-label={t('search', {}, 'Search')}\n />\n {search && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground absolute end-2 top-1/2 -translate-y-1/2\"\n aria-label={t('clear', {}, 'Clear')}\n onClick={() => {\n setSearch('')\n pushSearch('')\n pushSearch.flush()\n }}\n >\n <XIcon className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n <Slot name=\"table.toolbar.search.after\" scope={component} />\n <Slot name=\"table.toolbar.start\" scope={component} />\n <span className=\"flex-1\" />\n <Slot name=\"table.toolbar.end\" scope={component} />\n <Slot name=\"table.toolbar.reorder-trigger.before\" scope={component} />\n {table.reorderable && reorderTrigger && (\n <TableTriggerButton\n view={reorderTrigger}\n defaultIcon={\n <Icon name=\"alfakit::tables.actions.enable-reordering\" fallback={GripVerticalIcon} />\n }\n aria-pressed={reordering}\n onClick={() => {\n if (reordering) {\n void finishReorder()\n\n return\n }\n\n // Pagination is off while reordering unless `paginatedWhileReordering()`.\n setReordering(true)\n startTableReordering(table)\n }}\n />\n )}\n <Slot name=\"table.toolbar.reorder-trigger.after\" scope={component} />\n {table.spreadsheet && !reordering && (\n <Button\n type=\"button\"\n variant={spreadsheetOpen ? 'default' : 'outline'}\n size=\"sm\"\n data-slot=\"spreadsheet-trigger\"\n aria-pressed={spreadsheetOpen}\n onClick={() => setSpreadsheet((open) => !open)}\n onMouseEnter={() => void Spreadsheet.preload()}\n onFocus={() => void Spreadsheet.preload()}\n >\n <Icon name=\"alfakit::tables.actions.spreadsheet\" fallback={Table2Icon} />\n {t('table.spreadsheet.open', {}, 'Edit as spreadsheet')}\n </Button>\n )}\n {table.contentLayout && <ContentLayoutSort table={table} columns={columns} />}\n <Slot name=\"table.toolbar.grouping-selector.before\" scope={component} />\n <TableGroupingMenu table={table} />\n <Slot name=\"table.toolbar.grouping-selector.after\" scope={component} />\n {filtersAt === 'toolbar' && <TableFilters table={table} component={component} />}\n <Slot name=\"table.toolbar.column-manager-trigger.before\" scope={component} />\n <ColumnManager table={table} token={token} component={component} />\n <Slot name=\"table.toolbar.column-manager-trigger.after\" scope={component} />\n </div>\n <Slot name=\"table.toolbar.after\" scope={component} />\n {filtersAt === 'above' && <TableFilters table={table} component={component} />}\n {!table.hiddenFilterIndicators && <FilterIndicators table={table} />}\n <Slot name=\"table.filter-indicators\" scope={component} />\n {live && table.live?.newRecordsIndicator && <LiveRecordsPill live={live} />}\n </div>\n )\n\n // Simple, cursor and appending pagination don't count the records.\n const total = paginationTotal(table.pagination)\n const selectedCount = selectionState.allSelected\n ? (total ?? records.length)\n : selectionState.selected.size\n\n const bulkBar =\n selectable && selectedCount > 0 && table.bulkActions ? (\n <div className=\"bg-primary/5 border-primary/20 flex flex-wrap items-center gap-3 rounded-md border px-3 py-2 text-sm\">\n <span className=\"font-medium\">\n {choice('table.selected', selectedCount, {}, ':count selected')}\n </span>\n <Slot name=\"table.selection-indicator.actions.before\" scope={component} />\n {!selectionState.allSelected &&\n total !== null &&\n total > records.length &&\n canSelectAllRecords(table) && (\n <Button type=\"button\" variant=\"link\" size=\"sm\" onClick={() => selection.selectAll()}>\n {t('table.select_all', {}, 'Select all')} ({total})\n </Button>\n )}\n <Button type=\"button\" variant=\"link\" size=\"sm\" onClick={() => selection.clear()}>\n {t('table.deselect_all', {}, 'Deselect all')}\n </Button>\n <Slot name=\"table.selection-indicator.actions.after\" scope={component} />\n {selection.isFull && (\n <span className=\"text-muted-foreground text-xs\">\n {choice(\n 'table.max_selected',\n table.maxSelectableRecords ?? 0,\n {},\n 'You can select up to :count records',\n )}\n </span>\n )}\n <span className=\"flex-1\" />\n <ActionList actions={table.bulkActions} context={bulkContext} size=\"sm\" />\n </div>\n ) : null\n\n const columnHeader = (column: TableSchema['columns'][number], rowSpan?: number): ReactNode => {\n const active = table.sort?.column === column.name\n\n const label = column.sortable ? (\n <button\n type=\"button\"\n className=\"hover:text-foreground inline-flex items-center gap-1\"\n aria-busy={sortingColumn === column.name || undefined}\n onClick={() => sort(column.name)}\n >\n {column.label}\n {sortingColumn === column.name ? (\n <Spinner data-slot=\"table-sort-spinner\" className=\"size-3.5\" />\n ) : active ? (\n table.sort?.direction === 'asc' ? (\n <Icon\n name=\"alfakit::tables.header-cell.sort-asc-button\"\n fallback={ArrowUpIcon}\n className=\"size-3.5\"\n aria-hidden=\"true\"\n />\n ) : (\n <Icon\n name=\"alfakit::tables.header-cell.sort-desc-button\"\n fallback={ArrowDownIcon}\n className=\"size-3.5\"\n aria-hidden=\"true\"\n />\n )\n ) : (\n <Icon\n name=\"alfakit::tables.header-cell.sort-button\"\n fallback={ArrowUpDownIcon}\n className=\"size-3.5 opacity-40\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n ) : (\n column.label\n )\n\n return (\n <TableHead\n key={column.name}\n rowSpan={rowSpan}\n aria-sort={\n column.sortable\n ? ariaSort(column.name, table.sort?.column, table.sort?.direction)\n : undefined\n }\n style={column.width ? { width: column.width } : undefined}\n {...extraProps(\n column.extraHeaderAttributes,\n cn(\n ALIGN[column.alignment ?? 'start'],\n column.wrapHeader ? 'whitespace-normal' : undefined,\n column.grow === false && 'w-0',\n columnVisibilityClasses(column),\n ),\n )}\n >\n <div className=\"flex flex-col gap-1\">\n {column.headerTooltip ? (\n <span title={column.headerTooltip} data-slot=\"header-tooltip\">\n {label}\n <span className=\"sr-only\"> ({column.headerTooltip})</span>\n </span>\n ) : (\n label\n )}\n <Slot name=\"table.header-cell\" scope={component} data={{ column: column.name }} />\n {column.searchable && (\n <Input\n type=\"search\"\n defaultValue={table.columnSearches?.[column.name] ?? ''}\n placeholder={t('search', {}, 'Search')}\n aria-label={`${t('search', {}, 'Search')} ${column.label}`}\n className=\"h-7 text-xs font-normal\"\n onKeyDown={(event) =>\n event.key === 'Enter' &&\n visitTable(\n table.identifier,\n {\n columnSearch: {\n ...(table.columnSearches ?? {}),\n [column.name]: (event.target as HTMLInputElement).value,\n },\n },\n ['page'],\n )\n }\n />\n )}\n </div>\n </TableHead>\n )\n }\n\n const groupsOnlySelection = selectable && Boolean(table.selectGroupsOnly)\n\n const content = (\n <div\n data-surface=\"table\"\n aria-busy={showSkeleton || undefined}\n className=\"bg-card relative overflow-hidden rounded-xl border shadow-xs\"\n >\n {showSkeleton && (\n <div\n data-slot=\"table-loading-skeleton\"\n aria-hidden=\"true\"\n className=\"bg-card/80 absolute inset-0 z-10 flex flex-col gap-3 p-4\"\n >\n {Array.from({ length: skeletonRowCount(records) }, (_, index) => (\n <div key={index} className=\"bg-muted h-6 animate-pulse rounded-md\" />\n ))}\n </div>\n )}\n {awaitingRecords ? (\n <div className=\"text-muted-foreground p-8 text-center text-sm\">\n {t('loading', {}, 'Loading…')}\n </div>\n ) : records.length === 0 && !(table.grouping?.groupsOnly && table.recordGroups?.length) ? (\n <div className=\"flex flex-col items-center gap-3 px-6 py-12 text-center\">\n <div className=\"bg-muted text-muted-foreground flex size-12 items-center justify-center rounded-full\">\n <Icon name={table.emptyState.icon} className=\"size-6\" />\n </div>\n <div>\n <p className=\"font-medium\">{table.emptyState.heading}</p>\n {table.emptyState.description && (\n <p className=\"text-muted-foreground text-sm\">{table.emptyState.description}</p>\n )}\n </div>\n {table.emptyState.actions && (\n <ActionList actions={table.emptyState.actions} context={context} size=\"sm\" />\n )}\n </div>\n ) : table.contentLayout ? (\n <ContentLayout\n table={table}\n records={records}\n columns={columns}\n token={token}\n component={component}\n context={context}\n selectable={selectable}\n selection={selection}\n onRecordClick={rowClick}\n />\n ) : (\n <Table\n aria-rowcount={rowWindow.active ? rows.length + headerRows : undefined}\n data-stacked-on-mobile={stacked || undefined}\n className={cn(stacked && STACKED_TABLE_CLASSES.table)}\n >\n <TableHeader className={cn(stacked && STACKED_TABLE_CLASSES.header)}>\n {/* With column groups, the leading / trailing cells and ungrouped columns span\n both header rows; grouped columns get their own header in the second row. */}\n <TableRow className=\"hover:bg-transparent\">\n {table.recordActionsPosition === 'before-cells' && hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0\">\n {t('actions', {}, 'Actions')}\n </TableHead>\n )}\n {reordering && (\n <TableHead rowSpan={headerRowSpan} className=\"w-16\">\n <span className=\"sr-only\">{t('table.reorder_start', {}, 'Reorder')}</span>\n </TableHead>\n )}\n {selectable && (\n <TableHead rowSpan={headerRowSpan} className=\"w-10\">\n {!groupsOnlySelection && (\n <Checkbox\n checked={pageSelectionState(selection, records)}\n onCheckedChange={(checked) =>\n checked === true\n ? selection.selectPage(records)\n : selection.deselectPage(records)\n }\n aria-label={t('table.select_page', {}, 'Select page')}\n />\n )}\n </TableHead>\n )}\n {table.recordActionsPosition === 'before-columns' && hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0\">\n {t('actions', {}, 'Actions')}\n </TableHead>\n )}\n {groupRow\n ? groupRow.map((cell) =>\n cell.group ? (\n <TableHead\n key={cell.key}\n colSpan={cell.span}\n scope=\"colgroup\"\n {...extraProps(\n cell.group.extraHeaderAttributes,\n cn(\n 'border-b',\n ALIGN[cell.group.alignment ?? 'center'],\n cell.group.wrapHeader ? 'whitespace-normal' : undefined,\n ),\n )}\n >\n {cell.group.label}\n </TableHead>\n ) : cell.column ? (\n columnHeader(cell.column, 2)\n ) : null,\n )\n : columns.map((column) => columnHeader(column))}\n {(table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0 text-end\">\n <span className=\"sr-only\">{t('actions', {}, 'Actions')}</span>\n </TableHead>\n )}\n </TableRow>\n {groupRow && (\n <TableRow className=\"hover:bg-transparent\">\n {columns\n .filter((column) => isGroupedColumn(column.name, table.columnGroups))\n .map((column) => columnHeader(column))}\n </TableRow>\n )}\n </TableHeader>\n <TableBody ref={attachBody} className={cn(stacked && STACKED_TABLE_CLASSES.body)}>\n <VirtualSpacerRow height={rowWindow.before} colSpan={rowCells} />\n {positions.map((position) => {\n const row = rows[position] as (typeof rows)[number]\n\n if (row.kind === 'group') {\n return (\n <GroupHeaderRow\n key={`group:${row.group.key}`}\n group={row.group}\n collapsed={row.collapsed}\n collapsible={Boolean(table.grouping?.collapsible && !table.grouping.groupsOnly)}\n colSpan={columns.length + leadingCells + trailingCells}\n onToggle={() => toggleGroup(row.group.key)}\n selection={\n groupsOnlySelection\n ? {\n checked: selection.groupState(row.group.key, records),\n onChange: (checked) =>\n checked\n ? selection.selectGroup(row.group.key, records)\n : selection.deselectGroup(row.group.key, records),\n }\n : undefined\n }\n />\n )\n }\n\n if (row.kind === 'summary') {\n return (\n <SummaryRow\n key={`summary:${row.group.key}`}\n columns={columns}\n values={row.summary}\n leading={leadingCells}\n trailing={trailingCells}\n />\n )\n }\n\n const { record, index } = row\n const clickable = !reordering && Boolean(record.url || table.recordAction)\n const actions = record.actions ? (\n <ActionList\n actions={record.actions}\n context={{\n ...context,\n record: record.key,\n arguments: selectedRecordsArguments(selectionState, record.actions),\n }}\n size=\"sm\"\n align=\"end\"\n className=\"flex-nowrap\"\n />\n ) : null\n\n return (\n <TableRow\n key={String(record.key)}\n ref={attachRow}\n data-index={position}\n aria-rowindex={rowWindow.active ? position + headerRows + 1 : undefined}\n data-state={selection.isSelected(record.key) ? 'selected' : undefined}\n draggable={reordering}\n onDragStart={() => setDragKey(record.key)}\n onDragOver={(event) => event.preventDefault()}\n onDrop={() => {\n if (dragKey === null) return\n\n const keys = orderedRecords.map((item) => item.key)\n const from = keys.findIndex((key) => String(key) === String(dragKey))\n const [moved] = keys.splice(from, 1)\n\n if (moved !== undefined) keys.splice(index, 0, moved)\n\n setOrder(keys)\n setDragKey(null)\n }}\n className={cn(\n clickable && 'cursor-pointer',\n table.striped && index % 2 === 1 && 'bg-muted/30',\n stacked && STACKED_TABLE_CLASSES.row,\n record.classes,\n )}\n onClick={() => clickable && rowClick(record)}\n >\n {reordering && (\n <TableCell className=\"w-16 cursor-grab\">\n <div className=\"flex items-center\">\n <Icon\n name=\"alfakit::tables.reorder.handle\"\n fallback={GripVerticalIcon}\n className=\"text-muted-foreground size-4\"\n aria-hidden=\"true\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={t('form.move_up', {}, 'Move up')}\n disabled={index === 0}\n onClick={() => moveRow(index, -1)}\n >\n <ChevronUpIcon />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={t('form.move_down', {}, 'Move down')}\n disabled={index === orderedRecords.length - 1}\n onClick={() => moveRow(index, 1)}\n >\n <ChevronDownIcon />\n </Button>\n </div>\n </TableCell>\n )}\n {table.recordActionsPosition === 'before-cells' && hasActions && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n {selectable && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.controlCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {record.selectable !== false && (\n <Checkbox\n checked={selection.isSelected(record.key)}\n disabled={!selection.canSelect(record.key)}\n onCheckedChange={(checked) =>\n selection.toggle(record.key, checked === true, record.group ?? '')\n }\n aria-label={t('table.select_row', {}, 'Select row')}\n />\n )}\n </TableCell>\n )}\n {table.recordActionsPosition === 'before-columns' && hasActions && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n {columns.map((column) => {\n const cell = record.cells[column.name] ?? {}\n // `disabledClick()`: the cell is plain content and swallows the row click.\n const clickDisabled = Boolean(cell.disabledClick)\n const content = (\n <TableCellContent\n column={column}\n cell={cell}\n recordKey={record.key}\n token={token}\n component={component}\n />\n )\n const wrapped = clickDisabled ? (\n content\n ) : cell.url ? (\n cell.openUrlInNewTab ? (\n <a\n href={cell.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:underline\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n <span className=\"sr-only\">\n {' '}\n {t('opens_in_new_tab', {}, '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <Link\n href={cell.url}\n className=\"hover:underline\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n </Link>\n )\n ) : cell.action && record.actions ? (\n <button\n type=\"button\"\n className=\"text-start hover:underline\"\n onClick={(event) => {\n event.stopPropagation()\n const action = record.actions\n ?.flatMap((item) => ('actions' in item ? item.actions : [item]))\n .find((item) => 'name' in item && item.name === cell.action)\n\n if (action && 'name' in action)\n void runner.trigger(action, { ...context, record: record.key })\n }}\n >\n {content}\n </button>\n ) : clickable && column.name === primaryColumn ? (\n // Keyboard path for a clickable row: its primary cell is a real link or\n // button (the row itself stays a mouse convenience, not a tab stop).\n table.recordAction || !record.url ? (\n <button\n type=\"button\"\n className=\"focus-visible:ring-ring/50 rounded-sm text-start outline-none focus-visible:ring-[3px]\"\n onClick={(event) => {\n event.stopPropagation()\n rowClick(record)\n }}\n >\n {content}\n </button>\n ) : record.openUrlInNewTab ? (\n <a\n href={record.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n <span className=\"sr-only\">\n {' '}\n {t('opens_in_new_tab', {}, '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <Link\n href={record.url}\n className=\"focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n </Link>\n )\n ) : (\n content\n )\n\n return (\n <TableCell\n key={column.name}\n\n title={cell.tooltip}\n data-click-disabled={clickDisabled || undefined}\n onClick={clickDisabled ? (event) => event.stopPropagation() : undefined}\n {...extraProps(\n cell.extraAttributes,\n cn(\n clickDisabled && 'cursor-default',\n ALIGN[column.alignment ?? 'start'],\n column.verticalAlignment && VERTICAL_ALIGN[column.verticalAlignment],\n (column as { wrap?: boolean }).wrap && 'whitespace-normal',\n cell.hidden && 'invisible',\n columnVisibilityClasses(column),\n stacked && stackedCellClasses(column),\n ),\n )}\n >\n {stacked && (\n <span className={STACKED_TABLE_CLASSES.label} aria-hidden=\"true\">\n {column.label}\n </span>\n )}\n {wrapped}\n </TableCell>\n )\n })}\n {(table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions && (\n <TableCell\n className={cn('text-end', stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n </TableRow>\n )\n })}\n <VirtualSpacerRow height={rowWindow.after} colSpan={rowCells} />\n </TableBody>\n <TableSummaryFooter\n table={table}\n columns={columns}\n leading={leadingCells}\n trailing={trailingCells}\n className={cn(stacked && STACKED_TABLE_CLASSES.footer)}\n />\n </Table>\n )}\n </div>\n )\n\n const surface = spreadsheetOpen ? (\n <Spreadsheet\n table={table}\n token={token}\n component={component}\n onClose={() => setSpreadsheet(false)}\n />\n ) : (\n content\n )\n\n return (\n <div data-slot=\"table-block\" className={cn('flex flex-col gap-4', className)}>\n {toolbar}\n {bulkBar}\n <Slot name=\"table.content.before\" scope={component} />\n {filtersAt === 'before' || filtersAt === 'after' ? (\n // Sidebar filters: beside the table from `lg`, above it on smaller screens.\n <div\n data-slot=\"table-filters-layout\"\n className=\"flex flex-col gap-4 lg:flex-row lg:items-start\"\n >\n {filtersAt === 'before' && <TableFilters table={table} component={component} />}\n <div className=\"min-w-0 flex-1\">{surface}</div>\n {filtersAt === 'after' && <TableFilters table={table} component={component} />}\n </div>\n ) : (\n surface\n )}\n <Slot name=\"table.content.after\" scope={component} />\n {filtersAt === 'below' && <TableFilters table={table} component={component} />}\n <TablePagination table={table} />\n <span aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {announcement}\n </span>\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-block.js","names":[],"sources":["../../../src/components/table/table-block.tsx"],"sourcesContent":["import type { ActionContext, RecordKey, TableRecordSchema, TableSchema } from '@alfakit/core'\nimport {\n STACKED_TABLE_CLASSES,\n TableSelection,\n VIRTUAL_ESTIMATES,\n ariaSort,\n cachedTableTotals,\n canSelectAllRecords,\n columnGroupHeaderRow,\n columnVisibilityClasses,\n debounce,\n filtersPlacement,\n groupTableRows,\n isGroupedColumn,\n isTableLoading,\n loadTableTotals,\n mobileTable,\n moveListItem,\n pageFlash,\n pageSelectionState,\n paginationTotal,\n primaryColumnName,\n reorderTable,\n resolvePartialProps,\n selectedRecordsArguments,\n skeletonRowCount,\n stackedCellClasses,\n startTableReordering,\n stopTableReordering,\n tableLoadingStore,\n tableTotalsFailed,\n tableTotalsStore,\n triggerButtonView,\n virtualizeOptions,\n visitTable,\n withTableTotals,\n} from '@alfakit/core'\nimport { Link, router } from '@inertiajs/react'\nimport {\n ArrowDownIcon,\n ArrowUpDownIcon,\n ArrowUpIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n GripVerticalIcon,\n SearchIcon,\n Table2Icon,\n XIcon,\n} from 'lucide-react'\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport {\n useActionRunner,\n useChoice,\n usePageSchema,\n usePanel,\n usePollComponent,\n useT,\n} from '../../context'\nimport { useIsMobile } from '../../hooks/use-mobile'\nimport { useStore } from '../../hooks/use-store'\nimport { useVirtualList } from '../../hooks/use-virtual-list'\nimport { extraProps } from '../../lib/attributes'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { ActionList } from '../actions/action-list'\nimport { showToast } from '../notifications/flash-toasts'\nimport { Slot } from '../panel/slot'\nimport { LiveRecordsPill, useLiveUpdates } from '../realtime/live-records-pill'\nimport { VirtualSpacerRow } from '../schema/virtual-spacer'\nimport { Button } from '../ui/button'\nimport { Checkbox } from '../ui/checkbox'\nimport { Input } from '../ui/input'\nimport { Spinner } from '../ui/spinner'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table'\nimport { TableCellContent } from './cells'\nimport { ColumnManager } from './column-manager'\nimport { ContentLayout, ContentLayoutSort } from './content-layout'\nimport { FilterIndicators, TableFilters } from './filters'\nimport {\n GroupHeaderRow,\n TableGroupingMenu,\n useCollapsedGroups,\n useTablePersistence,\n} from './grouping'\nimport { TablePagination } from './pagination'\nimport { Spreadsheet } from './spreadsheet-lazy'\nimport { SummaryRow, TableSummaryFooter } from './summary-rows'\nimport { TableViews } from './table-views'\nimport { TableTriggerButton } from './trigger-button'\n\nexport interface DataTableProps {\n table: TableSchema\n /** Context component (`table`, `relationManager:…`, `widget:…`). */\n component?: string\n token?: string\n className?: string\n}\n\nconst ALIGN: Record<string, string> = {\n start: 'text-start',\n center: 'text-center',\n end: 'text-end',\n between: 'text-start',\n justify: 'text-justify',\n}\n\nconst VERTICAL_ALIGN: Record<string, string> = {\n start: 'align-top',\n center: 'align-middle',\n end: 'align-bottom',\n}\n\nexport function DataTable({\n table: serverTable,\n component = 'table',\n token: tokenProp,\n className,\n}: DataTableProps) {\n const t = useT()\n const choice = useChoice()\n const panel = usePanel()\n const isMobile = useIsMobile()\n const page = usePageSchema()\n const runner = useActionRunner()\n const token = tokenProp ?? page?.token ?? ''\n // `deferTotals()`: the total and summaries load after the rows (placeholders meanwhile).\n const totalsVersion = useStore(tableTotalsStore)\n const totalsUrl = panel.endpoints.tableTotals\n\n useEffect(() => {\n void loadTableTotals(serverTable, { url: totalsUrl, token, component })\n }, [serverTable, totalsUrl, token, component, totalsVersion])\n\n const tableProp = useMemo(\n () =>\n withTableTotals(\n serverTable,\n cachedTableTotals(serverTable, component),\n tableTotalsFailed(serverTable, component),\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the store version invalidates the cache read\n [serverTable, component, totalsVersion],\n )\n // Under the mobile preset a phone renders the rows as stacked cards; the server and\n // desktop markup keep the table.\n const table = useMemo(\n () =>\n mobileTable(\n tableProp,\n tableProp.columns.filter((column) => tableProp.visibleColumns.includes(column.name)),\n { isMobile, panel },\n ),\n [tableProp, isMobile, panel],\n )\n\n const context = useMemo<ActionContext>(() => ({ token, component }), [token, component])\n const selection = useMemo(() => new TableSelection(), [])\n const selectionState = useStore(selection.store)\n const [search, setSearch] = useState(table.search ?? '')\n // A reload in reorder mode (`?reordering=1`) comes back still reordering.\n const [reordering, setReordering] = useState(Boolean(table.reordering))\n const [order, setOrder] = useState<RecordKey[] | null>(null)\n const [dragKey, setDragKey] = useState<RecordKey | null>(null)\n // Live-region text announced after a keyboard move in reorder mode.\n const [announcement, setAnnouncement] = useState('')\n // `spreadsheet()`: the grid editing mode, toggled from the toolbar.\n const [spreadsheet, setSpreadsheet] = useState(false)\n const spreadsheetOpen = spreadsheet && Boolean(table.spreadsheet) && !reordering\n\n const records = table.records ?? []\n const columns = table.columns.filter((column) => table.visibleColumns.includes(column.name))\n const hasActions = records.some((record) => record.actions && record.actions.length > 0)\n const selectable = Boolean(table.selectable)\n const [collapsedGroups, toggleGroup] = useCollapsedGroups(table)\n // Cells around the columns, so group and summary rows line up with the records.\n const leadingCells =\n Number(table.recordActionsPosition === 'before-cells' && hasActions) +\n Number(reordering) +\n Number(selectable) +\n Number(table.recordActionsPosition === 'before-columns' && hasActions)\n const trailingCells = Number(\n (table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions,\n )\n\n useTablePersistence(table)\n\n const [syncedSearch, setSyncedSearch] = useState(table.search)\n\n if (syncedSearch !== table.search) {\n setSyncedSearch(table.search)\n setSearch(table.search ?? '')\n }\n\n const pushSearch = useMemo(\n () =>\n debounce(\n (value: string) => visitTable(table.identifier, { search: value || null }, ['page']),\n table.searchDebounce,\n ),\n [table.identifier, table.searchDebounce],\n )\n\n // Column searches (`searchable(isIndividual: true)`) apply after the same pause as the table\n // search; Enter applies at once. Callers pass every column's search (the others unchanged).\n const pushColumnSearch = useMemo(\n () =>\n debounce(\n (columnSearch: Record<string, string>) =>\n visitTable(table.identifier, { columnSearch }, ['page']),\n table.searchDebounce,\n ),\n [table.identifier, table.searchDebounce],\n )\n const searchColumn = (name: string, value: string) =>\n pushColumnSearch({ ...(table.columnSearches ?? {}), [name]: value })\n\n // Polls refresh only this table (a partial reload of its own schema), share one request\n // with other components on the same interval and pause while the tab is hidden.\n const pollComponent = usePollComponent()\n\n useEffect(\n () => pollComponent(component, table.pollingInterval),\n [pollComponent, component, table.pollingInterval],\n )\n\n // `live()`: refresh in place when records change (broadcast), else poll as a fallback.\n const live = useLiveUpdates(table.live, component, {\n polling: Boolean(table.pollingInterval),\n records,\n })\n\n // A deferred table arrives without records: fetch them with a partial reload, which the\n // server always fills. Ask once per gap so a failing reload cannot loop.\n const awaitingRecords = Boolean(table.deferLoading) && !table.records\n const deferredRequested = useRef(false)\n\n useEffect(() => {\n if (!awaitingRecords) {\n deferredRequested.current = false\n return\n }\n\n if (deferredRequested.current) return\n\n deferredRequested.current = true\n router.reload({ only: resolvePartialProps(['page']) })\n }, [awaitingRecords])\n\n // `deselectAllRecordsWhenFiltered()`: new filters, search or tab clear the selection.\n useEffect(() => selection.syncScope(table.selectionScope), [selection, table.selectionScope])\n\n // `maxSelectableRecords()` / `selectGroupsOnly()`.\n selection.configure(table)\n\n // Clear selection after a bulk action completes.\n useEffect(() => {\n return router.on('success', (event) => {\n const flash = pageFlash(event.detail.page).alfakitAction\n\n if (flash?.deselectRecords) {\n selection.clear()\n }\n })\n }, [selection])\n\n // The column whose sort was just clicked shows a spinner until its records arrive.\n const [sortingColumn, setSortingColumn] = useState<string | null>(null)\n\n const sort = (column: string) => {\n const direction =\n table.sort?.column === column && table.sort.direction === 'asc' ? 'desc' : 'asc'\n setSortingColumn(column)\n visitTable(table.identifier, { sort: column, direction }, ['page'], {\n onFinish: () => setSortingColumn(null),\n })\n }\n\n const bulkContext = useMemo<ActionContext>(\n () => ({\n token,\n component,\n records: selectionState.allSelected ? [] : [...selectionState.selected],\n allRecords: selectionState.allSelected,\n }),\n [token, component, selectionState],\n )\n\n const orderedRecords = order\n ? order\n .map((key) => records.find((record) => String(record.key) === String(key)))\n .filter((record): record is TableRecordSchema => Boolean(record))\n : records\n\n const finishReorder = async () => {\n // Leave reorder mode even when saving fails, so the table shows the server order again.\n try {\n if (order && panel.endpoints.tableReorder && panel.endpoints.tableCell) {\n await reorderTable(\n { reorder: panel.endpoints.tableReorder, cell: panel.endpoints.tableCell },\n token,\n component,\n order,\n // Leaving a server-side reorder mode reloads the table anyway.\n { reload: !table.reordering },\n )\n }\n } catch (error) {\n showToast({\n id: 'alfakit-reorder-failed',\n title: t('table.reorder_failed', {}, \"Couldn't save the new order\"),\n body: error instanceof Error ? error.message : String(error),\n status: 'danger',\n format: 'alfakit',\n })\n } finally {\n setOrder(null)\n setReordering(false)\n stopTableReordering(table)\n }\n }\n\n // Keyboard alternative to drag-and-drop: the move up/down buttons in reorder mode.\n const moveRow = (index: number, offset: -1 | 1) => {\n const keys = orderedRecords.map((item) => item.key)\n const target = index + offset\n\n if (target < 0 || target >= keys.length) return\n\n setOrder(moveListItem(keys, index, target))\n setAnnouncement(\n t(\n 'table.row_moved',\n { position: target + 1, total: keys.length },\n 'Row moved to position :position of :total',\n ),\n )\n }\n\n const groupRow = columnGroupHeaderRow(columns, table.columnGroups)\n const headerRowSpan = groupRow ? 2 : undefined\n\n // Long pages render only the visible rows (plus a few around them); the spacer rows keep\n // the scroll height, `aria-rowcount` / `aria-rowindex` keep the real positions.\n const rows = groupTableRows(table, orderedRecords, collapsedGroups)\n const {\n range: rowWindow,\n indexes: positions,\n attach: attachBody,\n item: attachRow,\n } = useVirtualList(rows.length, virtualizeOptions(table.virtualize, VIRTUAL_ESTIMATES.row))\n const headerRows = groupRow ? 2 : 1\n const rowCells = columns.length + leadingCells + trailingCells\n\n // The column whose cell holds a clickable row's focusable link or button.\n const primaryColumn = primaryColumnName(columns)\n\n const rowClick = (record: TableRecordSchema) => {\n if (reordering) return\n\n if (table.recordAction) {\n const action = record.actions\n ?.flatMap((item) => ('actions' in item ? item.actions : [item]))\n .find((item) => 'name' in item && item.name === table.recordAction)\n\n if (action && 'name' in action) {\n void runner.trigger(action, { ...context, record: record.key })\n\n return\n }\n }\n\n if (record.url) {\n if (record.openUrlInNewTab) {\n window.open(record.url, '_blank', 'noopener')\n } else {\n router.visit(record.url)\n }\n }\n }\n\n // `reorderRecordsTriggerAction()`: one look per state.\n const reorderTrigger = triggerButtonView(\n table,\n reordering ? 'reorderRecordsActive' : 'reorderRecords',\n {\n label: reordering\n ? t('table.reorder_stop', {}, 'Done')\n : t('table.reorder_start', {}, 'Reorder'),\n variant: reordering ? 'default' : 'outline',\n },\n )\n const loadingState = useStore(tableLoadingStore)\n const showSkeleton =\n Boolean(table.loadingSkeleton) && isTableLoading(loadingState, table.identifier)\n\n const filtersAt = filtersPlacement(table.filtersLayout)\n const stacked = Boolean(table.stackedOnMobile)\n\n const toolbar = (\n <div className=\"flex flex-col gap-3\">\n <Slot name=\"table.header.before\" scope={component} />\n {(table.heading || table.description || table.headerActions?.length) && (\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n {table.heading && <h3 className=\"text-base font-semibold\">{table.heading}</h3>}\n {table.description && (\n <p className=\"text-muted-foreground text-sm\">{table.description}</p>\n )}\n </div>\n {table.headerActions && (\n <ActionList actions={table.headerActions} context={context} size=\"sm\" />\n )}\n </div>\n )}\n <Slot name=\"table.header.after\" scope={component} />\n <Slot name=\"table.toolbar.before\" scope={component} />\n {table.views && <TableViews table={table} token={token} component={component} />}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Slot name=\"table.toolbar.search.before\" scope={component} />\n {table.searchable && (\n <div className=\"relative min-w-48 flex-1 sm:max-w-xs\">\n <Icon\n name=\"alfakit::tables.search-field\"\n fallback={SearchIcon}\n className=\"text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 size-4 -translate-y-1/2\"\n />\n <Input\n type=\"search\"\n value={search}\n placeholder={table.searchPlaceholder}\n onChange={(event) => {\n setSearch(event.target.value)\n\n if (!table.searchOnBlur) pushSearch(event.target.value)\n }}\n onBlur={() => table.searchOnBlur && pushSearch(search)}\n onKeyDown={(event) => event.key === 'Enter' && pushSearch.flush()}\n className=\"h-8 ps-8\"\n aria-label={t('search', {}, 'Search')}\n />\n {search && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground absolute end-2 top-1/2 -translate-y-1/2\"\n aria-label={t('clear', {}, 'Clear')}\n onClick={() => {\n setSearch('')\n pushSearch('')\n pushSearch.flush()\n }}\n >\n <XIcon className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n <Slot name=\"table.toolbar.search.after\" scope={component} />\n <Slot name=\"table.toolbar.start\" scope={component} />\n <span className=\"flex-1\" />\n <Slot name=\"table.toolbar.end\" scope={component} />\n <Slot name=\"table.toolbar.reorder-trigger.before\" scope={component} />\n {table.reorderable && reorderTrigger && (\n <TableTriggerButton\n view={reorderTrigger}\n defaultIcon={\n <Icon name=\"alfakit::tables.actions.enable-reordering\" fallback={GripVerticalIcon} />\n }\n aria-pressed={reordering}\n onClick={() => {\n if (reordering) {\n void finishReorder()\n\n return\n }\n\n // Pagination is off while reordering unless `paginatedWhileReordering()`.\n setReordering(true)\n startTableReordering(table)\n }}\n />\n )}\n <Slot name=\"table.toolbar.reorder-trigger.after\" scope={component} />\n {table.spreadsheet && !reordering && (\n <Button\n type=\"button\"\n variant={spreadsheetOpen ? 'default' : 'outline'}\n size=\"sm\"\n data-slot=\"spreadsheet-trigger\"\n aria-pressed={spreadsheetOpen}\n onClick={() => setSpreadsheet((open) => !open)}\n onMouseEnter={() => void Spreadsheet.preload()}\n onFocus={() => void Spreadsheet.preload()}\n >\n <Icon name=\"alfakit::tables.actions.spreadsheet\" fallback={Table2Icon} />\n {t('table.spreadsheet.open', {}, 'Edit as spreadsheet')}\n </Button>\n )}\n {table.contentLayout && <ContentLayoutSort table={table} columns={columns} />}\n <Slot name=\"table.toolbar.grouping-selector.before\" scope={component} />\n <TableGroupingMenu table={table} />\n <Slot name=\"table.toolbar.grouping-selector.after\" scope={component} />\n {filtersAt === 'toolbar' && <TableFilters table={table} component={component} />}\n <Slot name=\"table.toolbar.column-manager-trigger.before\" scope={component} />\n <ColumnManager table={table} token={token} component={component} />\n <Slot name=\"table.toolbar.column-manager-trigger.after\" scope={component} />\n </div>\n <Slot name=\"table.toolbar.after\" scope={component} />\n {filtersAt === 'above' && <TableFilters table={table} component={component} />}\n {!table.hiddenFilterIndicators && <FilterIndicators table={table} />}\n <Slot name=\"table.filter-indicators\" scope={component} />\n {live && table.live?.newRecordsIndicator && <LiveRecordsPill live={live} />}\n </div>\n )\n\n // Simple, cursor and appending pagination don't count the records.\n const total = paginationTotal(table.pagination)\n const selectedCount = selectionState.allSelected\n ? (total ?? records.length)\n : selectionState.selected.size\n\n const bulkBar =\n selectable && selectedCount > 0 && table.bulkActions ? (\n <div className=\"bg-primary/5 border-primary/20 flex flex-wrap items-center gap-3 rounded-md border px-3 py-2 text-sm\">\n <span className=\"font-medium\">\n {choice('table.selected', selectedCount, {}, ':count selected')}\n </span>\n <Slot name=\"table.selection-indicator.actions.before\" scope={component} />\n {!selectionState.allSelected &&\n total !== null &&\n total > records.length &&\n canSelectAllRecords(table) && (\n <Button type=\"button\" variant=\"link\" size=\"sm\" onClick={() => selection.selectAll()}>\n {t('table.select_all', {}, 'Select all')} ({total})\n </Button>\n )}\n <Button type=\"button\" variant=\"link\" size=\"sm\" onClick={() => selection.clear()}>\n {t('table.deselect_all', {}, 'Deselect all')}\n </Button>\n <Slot name=\"table.selection-indicator.actions.after\" scope={component} />\n {selection.isFull && (\n <span className=\"text-muted-foreground text-xs\">\n {choice(\n 'table.max_selected',\n table.maxSelectableRecords ?? 0,\n {},\n 'You can select up to :count records',\n )}\n </span>\n )}\n <span className=\"flex-1\" />\n <ActionList actions={table.bulkActions} context={bulkContext} size=\"sm\" />\n </div>\n ) : null\n\n const columnHeader = (column: TableSchema['columns'][number], rowSpan?: number): ReactNode => {\n const active = table.sort?.column === column.name\n\n const label = column.sortable ? (\n <button\n type=\"button\"\n className=\"hover:text-foreground inline-flex items-center gap-1\"\n aria-busy={sortingColumn === column.name || undefined}\n onClick={() => sort(column.name)}\n >\n {column.label}\n {sortingColumn === column.name ? (\n <Spinner data-slot=\"table-sort-spinner\" className=\"size-3.5\" />\n ) : active ? (\n table.sort?.direction === 'asc' ? (\n <Icon\n name=\"alfakit::tables.header-cell.sort-asc-button\"\n fallback={ArrowUpIcon}\n className=\"size-3.5\"\n aria-hidden=\"true\"\n />\n ) : (\n <Icon\n name=\"alfakit::tables.header-cell.sort-desc-button\"\n fallback={ArrowDownIcon}\n className=\"size-3.5\"\n aria-hidden=\"true\"\n />\n )\n ) : (\n <Icon\n name=\"alfakit::tables.header-cell.sort-button\"\n fallback={ArrowUpDownIcon}\n className=\"size-3.5 opacity-40\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n ) : (\n column.label\n )\n\n return (\n <TableHead\n key={column.name}\n rowSpan={rowSpan}\n aria-sort={\n column.sortable\n ? ariaSort(column.name, table.sort?.column, table.sort?.direction)\n : undefined\n }\n style={column.width ? { width: column.width } : undefined}\n {...extraProps(\n column.extraHeaderAttributes,\n cn(\n ALIGN[column.alignment ?? 'start'],\n column.wrapHeader ? 'whitespace-normal' : undefined,\n column.grow === false && 'w-0',\n columnVisibilityClasses(column),\n ),\n )}\n >\n <div className=\"flex flex-col gap-1\">\n {column.headerTooltip ? (\n <span title={column.headerTooltip} data-slot=\"header-tooltip\">\n {label}\n <span className=\"sr-only\"> ({column.headerTooltip})</span>\n </span>\n ) : (\n label\n )}\n <Slot name=\"table.header-cell\" scope={component} data={{ column: column.name }} />\n {column.searchable && (\n <Input\n type=\"search\"\n defaultValue={table.columnSearches?.[column.name] ?? ''}\n placeholder={t('search', {}, 'Search')}\n aria-label={`${t('search', {}, 'Search')} ${column.label}`}\n className=\"h-7 text-xs font-normal\"\n onChange={(event) => {\n if (!table.searchOnBlur) searchColumn(column.name, event.target.value)\n }}\n onBlur={(event) =>\n table.searchOnBlur && searchColumn(column.name, event.target.value)\n }\n onKeyDown={(event) => {\n if (event.key !== 'Enter') return\n\n searchColumn(column.name, (event.target as HTMLInputElement).value)\n pushColumnSearch.flush()\n }}\n />\n )}\n </div>\n </TableHead>\n )\n }\n\n const groupsOnlySelection = selectable && Boolean(table.selectGroupsOnly)\n\n const content = (\n <div\n data-surface=\"table\"\n aria-busy={showSkeleton || undefined}\n className=\"bg-card relative overflow-hidden rounded-xl border shadow-xs\"\n >\n {showSkeleton && (\n <div\n data-slot=\"table-loading-skeleton\"\n aria-hidden=\"true\"\n className=\"bg-card/80 absolute inset-0 z-10 flex flex-col gap-3 p-4\"\n >\n {Array.from({ length: skeletonRowCount(records) }, (_, index) => (\n <div key={index} className=\"bg-muted h-6 animate-pulse rounded-md\" />\n ))}\n </div>\n )}\n {awaitingRecords ? (\n <div className=\"text-muted-foreground p-8 text-center text-sm\">\n {t('loading', {}, 'Loading…')}\n </div>\n ) : records.length === 0 && !(table.grouping?.groupsOnly && table.recordGroups?.length) ? (\n <div className=\"flex flex-col items-center gap-3 px-6 py-12 text-center\">\n <div className=\"bg-muted text-muted-foreground flex size-12 items-center justify-center rounded-full\">\n <Icon name={table.emptyState.icon} className=\"size-6\" />\n </div>\n <div>\n <p className=\"font-medium\">{table.emptyState.heading}</p>\n {table.emptyState.description && (\n <p className=\"text-muted-foreground text-sm\">{table.emptyState.description}</p>\n )}\n </div>\n {table.emptyState.actions && (\n <ActionList actions={table.emptyState.actions} context={context} size=\"sm\" />\n )}\n </div>\n ) : table.contentLayout ? (\n <ContentLayout\n table={table}\n records={records}\n columns={columns}\n token={token}\n component={component}\n context={context}\n selectable={selectable}\n selection={selection}\n onRecordClick={rowClick}\n />\n ) : (\n <Table\n aria-rowcount={rowWindow.active ? rows.length + headerRows : undefined}\n data-stacked-on-mobile={stacked || undefined}\n className={cn(stacked && STACKED_TABLE_CLASSES.table)}\n >\n <TableHeader className={cn(stacked && STACKED_TABLE_CLASSES.header)}>\n {/* With column groups, the leading / trailing cells and ungrouped columns span\n both header rows; grouped columns get their own header in the second row. */}\n <TableRow className=\"hover:bg-transparent\">\n {table.recordActionsPosition === 'before-cells' && hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0\">\n {t('actions', {}, 'Actions')}\n </TableHead>\n )}\n {reordering && (\n <TableHead rowSpan={headerRowSpan} className=\"w-16\">\n <span className=\"sr-only\">{t('table.reorder_start', {}, 'Reorder')}</span>\n </TableHead>\n )}\n {selectable && (\n <TableHead rowSpan={headerRowSpan} className=\"w-10\">\n {!groupsOnlySelection && (\n <Checkbox\n checked={pageSelectionState(selection, records)}\n onCheckedChange={(checked) =>\n checked === true\n ? selection.selectPage(records)\n : selection.deselectPage(records)\n }\n aria-label={t('table.select_page', {}, 'Select page')}\n />\n )}\n </TableHead>\n )}\n {table.recordActionsPosition === 'before-columns' && hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0\">\n {t('actions', {}, 'Actions')}\n </TableHead>\n )}\n {groupRow\n ? groupRow.map((cell) =>\n cell.group ? (\n <TableHead\n key={cell.key}\n colSpan={cell.span}\n scope=\"colgroup\"\n {...extraProps(\n cell.group.extraHeaderAttributes,\n cn(\n 'border-b',\n ALIGN[cell.group.alignment ?? 'center'],\n cell.group.wrapHeader ? 'whitespace-normal' : undefined,\n ),\n )}\n >\n {cell.group.label}\n </TableHead>\n ) : cell.column ? (\n columnHeader(cell.column, 2)\n ) : null,\n )\n : columns.map((column) => columnHeader(column))}\n {(table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions && (\n <TableHead rowSpan={headerRowSpan} className=\"w-0 text-end\">\n <span className=\"sr-only\">{t('actions', {}, 'Actions')}</span>\n </TableHead>\n )}\n </TableRow>\n {groupRow && (\n <TableRow className=\"hover:bg-transparent\">\n {columns\n .filter((column) => isGroupedColumn(column.name, table.columnGroups))\n .map((column) => columnHeader(column))}\n </TableRow>\n )}\n </TableHeader>\n <TableBody ref={attachBody} className={cn(stacked && STACKED_TABLE_CLASSES.body)}>\n <VirtualSpacerRow height={rowWindow.before} colSpan={rowCells} />\n {positions.map((position) => {\n const row = rows[position] as (typeof rows)[number]\n\n if (row.kind === 'group') {\n return (\n <GroupHeaderRow\n key={`group:${row.group.key}`}\n group={row.group}\n collapsed={row.collapsed}\n collapsible={Boolean(table.grouping?.collapsible && !table.grouping.groupsOnly)}\n colSpan={columns.length + leadingCells + trailingCells}\n onToggle={() => toggleGroup(row.group.key)}\n selection={\n groupsOnlySelection\n ? {\n checked: selection.groupState(row.group.key, records),\n onChange: (checked) =>\n checked\n ? selection.selectGroup(row.group.key, records)\n : selection.deselectGroup(row.group.key, records),\n }\n : undefined\n }\n />\n )\n }\n\n if (row.kind === 'summary') {\n return (\n <SummaryRow\n key={`summary:${row.group.key}`}\n columns={columns}\n values={row.summary}\n leading={leadingCells}\n trailing={trailingCells}\n />\n )\n }\n\n const { record, index } = row\n const clickable = !reordering && Boolean(record.url || table.recordAction)\n const actions = record.actions ? (\n <ActionList\n actions={record.actions}\n context={{\n ...context,\n record: record.key,\n arguments: selectedRecordsArguments(selectionState, record.actions),\n }}\n size=\"sm\"\n align=\"end\"\n className=\"flex-nowrap\"\n />\n ) : null\n\n return (\n <TableRow\n key={String(record.key)}\n ref={attachRow}\n data-index={position}\n aria-rowindex={rowWindow.active ? position + headerRows + 1 : undefined}\n data-state={selection.isSelected(record.key) ? 'selected' : undefined}\n draggable={reordering}\n onDragStart={() => setDragKey(record.key)}\n onDragOver={(event) => event.preventDefault()}\n onDrop={() => {\n if (dragKey === null) return\n\n const keys = orderedRecords.map((item) => item.key)\n const from = keys.findIndex((key) => String(key) === String(dragKey))\n const [moved] = keys.splice(from, 1)\n\n if (moved !== undefined) keys.splice(index, 0, moved)\n\n setOrder(keys)\n setDragKey(null)\n }}\n className={cn(\n clickable && 'cursor-pointer',\n table.striped && index % 2 === 1 && 'bg-muted/30',\n stacked && STACKED_TABLE_CLASSES.row,\n record.classes,\n )}\n onClick={() => clickable && rowClick(record)}\n >\n {reordering && (\n <TableCell className=\"w-16 cursor-grab\">\n <div className=\"flex items-center\">\n <Icon\n name=\"alfakit::tables.reorder.handle\"\n fallback={GripVerticalIcon}\n className=\"text-muted-foreground size-4\"\n aria-hidden=\"true\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={t('form.move_up', {}, 'Move up')}\n disabled={index === 0}\n onClick={() => moveRow(index, -1)}\n >\n <ChevronUpIcon />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={t('form.move_down', {}, 'Move down')}\n disabled={index === orderedRecords.length - 1}\n onClick={() => moveRow(index, 1)}\n >\n <ChevronDownIcon />\n </Button>\n </div>\n </TableCell>\n )}\n {table.recordActionsPosition === 'before-cells' && hasActions && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n {selectable && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.controlCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {record.selectable !== false && (\n <Checkbox\n checked={selection.isSelected(record.key)}\n disabled={!selection.canSelect(record.key)}\n onCheckedChange={(checked) =>\n selection.toggle(record.key, checked === true, record.group ?? '')\n }\n aria-label={t('table.select_row', {}, 'Select row')}\n />\n )}\n </TableCell>\n )}\n {table.recordActionsPosition === 'before-columns' && hasActions && (\n <TableCell\n className={cn(stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n {columns.map((column) => {\n const cell = record.cells[column.name] ?? {}\n // `disabledClick()`: the cell is plain content and swallows the row click.\n const clickDisabled = Boolean(cell.disabledClick)\n const content = (\n <TableCellContent\n column={column}\n cell={cell}\n recordKey={record.key}\n token={token}\n component={component}\n />\n )\n const wrapped = clickDisabled ? (\n content\n ) : cell.url ? (\n cell.openUrlInNewTab ? (\n <a\n href={cell.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:underline\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n <span className=\"sr-only\">\n {' '}\n {t('opens_in_new_tab', {}, '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <Link\n href={cell.url}\n className=\"hover:underline\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n </Link>\n )\n ) : cell.action && record.actions ? (\n <button\n type=\"button\"\n className=\"text-start hover:underline\"\n onClick={(event) => {\n event.stopPropagation()\n const action = record.actions\n ?.flatMap((item) => ('actions' in item ? item.actions : [item]))\n .find((item) => 'name' in item && item.name === cell.action)\n\n if (action && 'name' in action)\n void runner.trigger(action, { ...context, record: record.key })\n }}\n >\n {content}\n </button>\n ) : clickable && column.name === primaryColumn ? (\n // Keyboard path for a clickable row: its primary cell is a real link or\n // button (the row itself stays a mouse convenience, not a tab stop).\n table.recordAction || !record.url ? (\n <button\n type=\"button\"\n className=\"focus-visible:ring-ring/50 rounded-sm text-start outline-none focus-visible:ring-[3px]\"\n onClick={(event) => {\n event.stopPropagation()\n rowClick(record)\n }}\n >\n {content}\n </button>\n ) : record.openUrlInNewTab ? (\n <a\n href={record.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n <span className=\"sr-only\">\n {' '}\n {t('opens_in_new_tab', {}, '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <Link\n href={record.url}\n className=\"focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]\"\n onClick={(event) => event.stopPropagation()}\n >\n {content}\n </Link>\n )\n ) : (\n content\n )\n\n return (\n <TableCell\n key={column.name}\n\n title={cell.tooltip}\n data-click-disabled={clickDisabled || undefined}\n onClick={clickDisabled ? (event) => event.stopPropagation() : undefined}\n {...extraProps(\n cell.extraAttributes,\n cn(\n clickDisabled && 'cursor-default',\n ALIGN[column.alignment ?? 'start'],\n column.verticalAlignment && VERTICAL_ALIGN[column.verticalAlignment],\n (column as { wrap?: boolean }).wrap && 'whitespace-normal',\n cell.hidden && 'invisible',\n columnVisibilityClasses(column),\n stacked && stackedCellClasses(column),\n ),\n )}\n >\n {stacked && (\n <span className={STACKED_TABLE_CLASSES.label} aria-hidden=\"true\">\n {column.label}\n </span>\n )}\n {wrapped}\n </TableCell>\n )\n })}\n {(table.recordActionsPosition === 'after-columns' ||\n table.recordActionsPosition === 'after-cells') &&\n hasActions && (\n <TableCell\n className={cn('text-end', stacked && STACKED_TABLE_CLASSES.actionsCell)}\n onClick={(event) => event.stopPropagation()}\n >\n {actions}\n </TableCell>\n )}\n </TableRow>\n )\n })}\n <VirtualSpacerRow height={rowWindow.after} colSpan={rowCells} />\n </TableBody>\n <TableSummaryFooter\n table={table}\n columns={columns}\n leading={leadingCells}\n trailing={trailingCells}\n className={cn(stacked && STACKED_TABLE_CLASSES.footer)}\n />\n </Table>\n )}\n </div>\n )\n\n const surface = spreadsheetOpen ? (\n <Spreadsheet\n table={table}\n token={token}\n component={component}\n onClose={() => setSpreadsheet(false)}\n />\n ) : (\n content\n )\n\n return (\n <div data-slot=\"table-block\" className={cn('flex flex-col gap-4', className)}>\n {toolbar}\n {bulkBar}\n <Slot name=\"table.content.before\" scope={component} />\n {filtersAt === 'before' || filtersAt === 'after' ? (\n // Sidebar filters: beside the table from `lg`, above it on smaller screens.\n <div\n data-slot=\"table-filters-layout\"\n className=\"flex flex-col gap-4 lg:flex-row lg:items-start\"\n >\n {filtersAt === 'before' && <TableFilters table={table} component={component} />}\n <div className=\"min-w-0 flex-1\">{surface}</div>\n {filtersAt === 'after' && <TableFilters table={table} component={component} />}\n </div>\n ) : (\n surface\n )}\n <Slot name=\"table.content.after\" scope={component} />\n {filtersAt === 'below' && <TableFilters table={table} component={component} />}\n <TablePagination table={table} />\n <span aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {announcement}\n </span>\n </div>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","names":["Dialog","DialogPrimitive"],"sources":["../../../src/components/ui/dialog.tsx"],"mappings":";;;iBAOSA,cAAY,SAAS,sBAAsBC,OAAgB,wBAAK,IAAA;iBAIhE,mBAAmB,SAAS,sBAAsBA,OAAgB,2BAAQ,IAAA;iBAI1E,kBAAkB,SAAS,sBAAsBA,OAAgB,0BAAO,IAAA;iBAIxE,iBAAiB,SAAS,sBAAsBA,OAAgB,yBAAM,IAAA;iBAItE,gBAAgB,cAAc,SAAS,sBAAsBA,OAAgB,2BAAQ,IAAA;iBAarF,gBACP,WACA,UACA,oBACG,SACF,sBAAsBA,OAAgB;EAAa;oBAA2B,IAAA;iBA4BxE,eAAe,cAAc,SAAS,wCAAqB,IAAA;iBAU3D,eAAe,cAAc,SAAS,wCAAqB,IAAA;iBAU3D,cAAc,cAAc,SAAS,sBAAsBA,OAAgB,yBAAM,IAAA;iBAUjF,oBACP,cACG,SACF,sBAAsBA,OAAgB,+BAAY,IAAA"}
1
+ {"version":3,"file":"dialog.d.ts","names":["Dialog","DialogPrimitive"],"sources":["../../../src/components/ui/dialog.tsx"],"mappings":";;;iBAOSA,cAAY,SAAS,sBAAsBC,OAAgB,wBAAK,IAAA;iBAIhE,mBAAmB,SAAS,sBAAsBA,OAAgB,2BAAQ,IAAA;iBAI1E,kBAAkB,SAAS,sBAAsBA,OAAgB,0BAAO,IAAA;iBAIxE,iBAAiB,SAAS,sBAAsBA,OAAgB,yBAAM,IAAA;iBAItE,gBAAgB,cAAc,SAAS,sBAAsBA,OAAgB,2BAAQ,IAAA;iBAarF,gBACP,WACA,UACA,oBACG,SACF,sBAAsBA,OAAgB;EAAa;oBAA2B,IAAA;iBAgCxE,eAAe,cAAc,SAAS,wCAAqB,IAAA;iBAU3D,eAAe,cAAc,SAAS,wCAAqB,IAAA;iBAU3D,cAAc,cAAc,SAAS,sBAAsBA,OAAgB,yBAAM,IAAA;iBAUjF,oBACP,cACG,SACF,sBAAsBA,OAAgB,+BAAY,IAAA"}
@@ -2,7 +2,7 @@ import { useT } from "../../context.js";
2
2
  import { cn } from "../../lib/utils.js";
3
3
  import { Icon } from "../../lib/icons.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { Dialog } from "radix-ui";
5
+ import { Dialog, Direction } from "radix-ui";
6
6
  import { XIcon } from "lucide-react";
7
7
  //#region src/components/ui/dialog.tsx
8
8
  function Dialog$1({ ...props }) {
@@ -37,10 +37,12 @@ function DialogOverlay({ className, ...props }) {
37
37
  });
38
38
  }
39
39
  function DialogContent({ className, children, showCloseButton = true, ...props }) {
40
+ const dir = Direction.useDirection();
40
41
  const t = useT();
41
42
  return /* @__PURE__ */ jsxs(DialogPortal, {
42
43
  "data-slot": "dialog-portal",
43
44
  children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(Dialog.Content, {
45
+ dir,
44
46
  "data-slot": "dialog-content",
45
47
  className: cn("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg", className),
46
48
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","names":["Dialog","DialogPrimitive"],"sources":["../../../src/components/ui/dialog.tsx"],"sourcesContent":["import { XIcon } from 'lucide-react'\nimport { Dialog as DialogPrimitive } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\n\nfunction Dialog({ ...props }: ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({ className, ...props }: ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & { showCloseButton?: boolean }) {\n const t = useT()\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <Icon name=\"alfakit::support.modal.close-button\" fallback={XIcon} />\n <span className=\"sr-only\">{t('close', {}, 'Close')}</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn('flex flex-col gap-2 text-center sm:text-start', className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({ className, ...props }: ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn('text-lg leading-none font-semibold', className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n"],"mappings":";;;;;;;AAOA,SAASA,SAAO,EAAE,GAAG,SAAsD;CACzE,OAAO,oBAACC,OAAgB,MAAjB;EAAsB,aAAU;EAAS,GAAI;CAAQ,CAAA;AAC9D;AAEA,SAAS,cAAc,EAAE,GAAG,SAAyD;CACnF,OAAO,oBAACA,OAAgB,SAAjB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,aAAa,EAAE,GAAG,SAAwD;CACjF,OAAO,oBAACA,OAAgB,QAAjB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAEA,SAAS,YAAY,EAAE,GAAG,SAAuD;CAC/E,OAAO,oBAACA,OAAgB,OAAjB;EAAuB,aAAU;EAAe,GAAI;CAAQ,CAAA;AACrE;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAyD;CAC9F,OACE,oBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,WAAW,GACT,0JACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,WACA,UACA,kBAAkB,MAClB,GAAG,SAC8E;CACjF,MAAM,IAAI,KAAK;CACf,OACE,qBAAC,cAAD;EAAc,aAAU;EAAxB,UAAA,CACE,oBAAC,eAAD,CAAgB,CAAA,GAChB,qBAACA,OAAgB,SAAjB;GACE,aAAU;GACV,WAAW,GACT,+WACA,SACF;GACA,GAAI;GANN,UAAA,CAQG,UACA,mBACC,qBAACA,OAAgB,OAAjB;IACE,aAAU;IACV,WAAU;IAFZ,UAAA,CAIE,oBAAC,MAAD;KAAM,MAAK;KAAsC,UAAU;IAAQ,CAAA,GACnE,oBAAC,QAAD;KAAM,WAAU;KAAW,UAAA,EAAE,SAAS,CAAC,GAAG,OAAO;IAAQ,CAAA,CACpC;GAEF,CAAA,CAAA;EACb,CAAA,CAAA;;AAElB;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAgC;CACpE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAgC;CACpE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAuD;CAC1F,OACE,oBAACA,OAAgB,OAAjB;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACkD;CACrD,OACE,oBAACA,OAAgB,aAAjB;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"dialog.js","names":["Dialog","DialogPrimitive"],"sources":["../../../src/components/ui/dialog.tsx"],"sourcesContent":["import { XIcon } from 'lucide-react'\nimport { Dialog as DialogPrimitive, Direction } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\n\nfunction Dialog({ ...props }: ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({ className, ...props }: ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & { showCloseButton?: boolean }) {\n // Portaled outside Alfakit's root: carry the reading direction (starter kit pages and\n // standalone components leave <html dir> to the host).\n const dir = Direction.useDirection()\n const t = useT()\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n dir={dir}\n data-slot=\"dialog-content\"\n className={cn(\n 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <Icon name=\"alfakit::support.modal.close-button\" fallback={XIcon} />\n <span className=\"sr-only\">{t('close', {}, 'Close')}</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn('flex flex-col gap-2 text-center sm:text-start', className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({ className, ...props }: ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn('text-lg leading-none font-semibold', className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n"],"mappings":";;;;;;;AAOA,SAASA,SAAO,EAAE,GAAG,SAAsD;CACzE,OAAO,oBAACC,OAAgB,MAAjB;EAAsB,aAAU;EAAS,GAAI;CAAQ,CAAA;AAC9D;AAEA,SAAS,cAAc,EAAE,GAAG,SAAyD;CACnF,OAAO,oBAACA,OAAgB,SAAjB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,aAAa,EAAE,GAAG,SAAwD;CACjF,OAAO,oBAACA,OAAgB,QAAjB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAEA,SAAS,YAAY,EAAE,GAAG,SAAuD;CAC/E,OAAO,oBAACA,OAAgB,OAAjB;EAAuB,aAAU;EAAe,GAAI;CAAQ,CAAA;AACrE;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAyD;CAC9F,OACE,oBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,WAAW,GACT,0JACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,WACA,UACA,kBAAkB,MAClB,GAAG,SAC8E;CAGjF,MAAM,MAAM,UAAU,aAAa;CACnC,MAAM,IAAI,KAAK;CACf,OACE,qBAAC,cAAD;EAAc,aAAU;EAAxB,UAAA,CACE,oBAAC,eAAD,CAAgB,CAAA,GAChB,qBAACA,OAAgB,SAAjB;GACO;GACL,aAAU;GACV,WAAW,GACT,+WACA,SACF;GACA,GAAI;GAPN,UAAA,CASG,UACA,mBACC,qBAACA,OAAgB,OAAjB;IACE,aAAU;IACV,WAAU;IAFZ,UAAA,CAIE,oBAAC,MAAD;KAAM,MAAK;KAAsC,UAAU;IAAQ,CAAA,GACnE,oBAAC,QAAD;KAAM,WAAU;KAAW,UAAA,EAAE,SAAS,CAAC,GAAG,OAAO;IAAQ,CAAA,CACpC;GAEF,CAAA,CAAA;EACb,CAAA,CAAA;;AAElB;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAgC;CACpE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAgC;CACpE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAuD;CAC1F,OACE,oBAACA,OAAgB,OAAjB;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACkD;CACrD,OACE,oBAACA,OAAgB,aAAjB;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","names":["Popover","PopoverPrimitive"],"sources":["../../../src/components/ui/popover.tsx"],"mappings":";;;iBAISA,eAAa,SAAS,sBAAsBC,QAAiB,wBAAK,IAAA;iBAIlE,oBAAoB,SAAS,sBAAsBA,QAAiB,2BAAQ,IAAA;iBAI5E,iBACP,WACA,OACA,eACG,SACF,sBAAsBA,QAAiB,2BAAQ,IAAA;iBAiBzC,mBAAmB,SAAS,sBAAsBA,QAAiB,0BAAO,IAAA"}
1
+ {"version":3,"file":"popover.d.ts","names":["Popover","PopoverPrimitive"],"sources":["../../../src/components/ui/popover.tsx"],"mappings":";;;iBAISA,eAAa,SAAS,sBAAsBC,QAAiB,wBAAK,IAAA;iBAIlE,oBAAoB,SAAS,sBAAsBA,QAAiB,2BAAQ,IAAA;iBAI5E,iBACP,WACA,OACA,eACG,SACF,sBAAsBA,QAAiB,2BAAQ,IAAA;iBAqBzC,mBAAmB,SAAS,sBAAsBA,QAAiB,0BAAO,IAAA"}
@@ -1,6 +1,6 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { Popover } from "radix-ui";
3
+ import { Direction, Popover } from "radix-ui";
4
4
  //#region src/components/ui/popover.tsx
5
5
  function Popover$1({ ...props }) {
6
6
  return /* @__PURE__ */ jsx(Popover.Root, {
@@ -15,7 +15,9 @@ function PopoverTrigger({ ...props }) {
15
15
  });
16
16
  }
17
17
  function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
18
+ const dir = Direction.useDirection();
18
19
  return /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Content, {
20
+ dir,
19
21
  "data-slot": "popover-content",
20
22
  align,
21
23
  sideOffset,
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","names":["Popover","PopoverPrimitive"],"sources":["../../../src/components/ui/popover.tsx"],"sourcesContent":["import { Popover as PopoverPrimitive } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { cn } from '../../lib/utils'\n\nfunction Popover({ ...props }: ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n ...props\n}: ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({ ...props }: ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger }\n"],"mappings":";;;;AAIA,SAASA,UAAQ,EAAE,GAAG,SAAuD;CAC3E,OAAO,oBAACC,QAAiB,MAAlB;EAAuB,aAAU;EAAU,GAAI;CAAQ,CAAA;AAChE;AAEA,SAAS,eAAe,EAAE,GAAG,SAA0D;CACrF,OAAO,oBAACA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC3E;AAEA,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,aAAa,GACb,GAAG,SAC+C;CAClD,OACE,oBAACA,QAAiB,QAAlB,EAAA,UACE,oBAACA,QAAiB,SAAlB;EACE,aAAU;EACH;EACK;EACZ,WAAW,GACT,keACA,SACF;EACA,GAAI;CACL,CAAA,EACsB,CAAA;AAE7B;AAEA,SAAS,cAAc,EAAE,GAAG,SAAyD;CACnF,OAAO,oBAACA,QAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE"}
1
+ {"version":3,"file":"popover.js","names":["Popover","PopoverPrimitive"],"sources":["../../../src/components/ui/popover.tsx"],"sourcesContent":["import { Direction, Popover as PopoverPrimitive } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { cn } from '../../lib/utils'\n\nfunction Popover({ ...props }: ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n ...props\n}: ComponentProps<typeof PopoverPrimitive.Content>) {\n // Portaled outside Alfakit's root: carry the reading direction (starter kit pages and\n // standalone components leave <html dir> to the host).\n const dir = Direction.useDirection()\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n dir={dir}\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({ ...props }: ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger }\n"],"mappings":";;;;AAIA,SAASA,UAAQ,EAAE,GAAG,SAAuD;CAC3E,OAAO,oBAACC,QAAiB,MAAlB;EAAuB,aAAU;EAAU,GAAI;CAAQ,CAAA;AAChE;AAEA,SAAS,eAAe,EAAE,GAAG,SAA0D;CACrF,OAAO,oBAACA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC3E;AAEA,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,aAAa,GACb,GAAG,SAC+C;CAGlD,MAAM,MAAM,UAAU,aAAa;CACnC,OACE,oBAACA,QAAiB,QAAlB,EAAA,UACE,oBAACA,QAAiB,SAAlB;EACO;EACL,aAAU;EACH;EACK;EACZ,WAAW,GACT,keACA,SACF;EACA,GAAI;CACL,CAAA,EACsB,CAAA;AAE7B;AAEA,SAAS,cAAc,EAAE,GAAG,SAAyD;CACnF,OAAO,oBAACA,QAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.d.ts","names":["SheetPrimitive"],"sources":["../../../src/components/ui/sheet.tsx"],"mappings":";;;iBAOS,WAAW,SAAS,sBAAsBA,OAAe,wBAAK,IAAA;iBAI9D,kBAAkB,SAAS,sBAAsBA,OAAe,2BAAQ,IAAA;iBAIxE,gBAAgB,SAAS,sBAAsBA,OAAe,yBAAM,IAAA;iBAqBpE,eACP,WACA,UACA,MACA,oBACG,SACF,sBAAsBA,OAAe;EACtC;EACA;oBACD,IAAA;iBAiCQ,cAAc,cAAc,SAAS,wCAAqB,IAAA;iBAU1D,cAAc,cAAc,SAAS,wCAAqB,IAAA;iBAU1D,aAAa,cAAc,SAAS,sBAAsBA,OAAe,yBAAM,IAAA;iBAU/E,mBACP,cACG,SACF,sBAAsBA,OAAe,+BAAY,IAAA"}
1
+ {"version":3,"file":"sheet.d.ts","names":["SheetPrimitive"],"sources":["../../../src/components/ui/sheet.tsx"],"mappings":";;;iBAOS,WAAW,SAAS,sBAAsBA,OAAe,wBAAK,IAAA;iBAI9D,kBAAkB,SAAS,sBAAsBA,OAAe,2BAAQ,IAAA;iBAIxE,gBAAgB,SAAS,sBAAsBA,OAAe,yBAAM,IAAA;iBAqBpE,eACP,WACA,UACA,MACA,oBACG,SACF,sBAAsBA,OAAe;EACtC;EACA;oBACD,IAAA;iBAqCQ,cAAc,cAAc,SAAS,wCAAqB,IAAA;iBAU1D,cAAc,cAAc,SAAS,wCAAqB,IAAA;iBAU1D,aAAa,cAAc,SAAS,sBAAsBA,OAAe,yBAAM,IAAA;iBAU/E,mBACP,cACG,SACF,sBAAsBA,OAAe,+BAAY,IAAA"}
@@ -2,7 +2,7 @@ import { useT } from "../../context.js";
2
2
  import { cn } from "../../lib/utils.js";
3
3
  import { Icon } from "../../lib/icons.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { Dialog } from "radix-ui";
5
+ import { Dialog, Direction } from "radix-ui";
6
6
  import { XIcon } from "lucide-react";
7
7
  //#region src/components/ui/sheet.tsx
8
8
  function Sheet({ ...props }) {
@@ -37,8 +37,10 @@ function SheetOverlay({ className, ...props }) {
37
37
  });
38
38
  }
39
39
  function SheetContent({ className, children, side = "right", showCloseButton = true, ...props }) {
40
+ const dir = Direction.useDirection();
40
41
  const t = useT();
41
42
  return /* @__PURE__ */ jsxs(SheetPortal, { children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsxs(Dialog.Content, {
43
+ dir,
42
44
  "data-slot": "sheet-content",
43
45
  className: cn("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500", side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm", side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm", side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b", side === "bottom" && "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t", className),
44
46
  ...props,