pika-ux 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/LICENSE +9 -0
  2. package/dist/icon-generator/generate-icon-ts-indices.js +78 -0
  3. package/dist/shadcn-postinstall/index.js +114 -0
  4. package/package.json +102 -0
  5. package/readme.md +50 -0
  6. package/scripts/setup.js +100 -0
  7. package/src/App.svelte +51 -0
  8. package/src/app.css +349 -0
  9. package/src/icons/ci/index.d.ts +5009 -0
  10. package/src/icons/lucide/index.d.ts +11274 -0
  11. package/src/index.ts +23 -0
  12. package/src/lib/docsite/Navigation.svelte +77 -0
  13. package/src/lib/docsite/pages/Colors.svelte +35 -0
  14. package/src/lib/docsite/pages/Components.svelte +50 -0
  15. package/src/lib/docsite/pages/GettingStarted.svelte +21 -0
  16. package/src/lib/docsite/pages/Icons.svelte +22 -0
  17. package/src/lib/docsite/pages/components/Button.svelte +40 -0
  18. package/src/main.ts +9 -0
  19. package/src/pika/chip/chip.svelte +95 -0
  20. package/src/pika/chip/index.ts +1 -0
  21. package/src/pika/combobox/combobox-types.ts +5 -0
  22. package/src/pika/combobox/combobox.svelte +221 -0
  23. package/src/pika/combobox/index.ts +2 -0
  24. package/src/pika/confirm-dialog/confirm-dialog.svelte +48 -0
  25. package/src/pika/confirm-dialog/index.ts +1 -0
  26. package/src/pika/copy-button/copy-button.svelte +134 -0
  27. package/src/pika/copy-button/index.ts +1 -0
  28. package/src/pika/create-copy-link-button/create-copy-link-button.svelte +133 -0
  29. package/src/pika/create-copy-link-button/index.ts +1 -0
  30. package/src/pika/date-picker/date-picker.svelte +33 -0
  31. package/src/pika/date-picker/index.ts +1 -0
  32. package/src/pika/date-range-picker/date-range-picker.svelte +48 -0
  33. package/src/pika/date-range-picker/index.ts +1 -0
  34. package/src/pika/date-time-picker/date-time-picker.svelte +336 -0
  35. package/src/pika/date-time-picker/index.ts +1 -0
  36. package/src/pika/expandable-container/expandable-container.svelte +155 -0
  37. package/src/pika/expandable-container/index.ts +1 -0
  38. package/src/pika/index.ts +29 -0
  39. package/src/pika/list/index.ts +2 -0
  40. package/src/pika/list/list-types.ts +5 -0
  41. package/src/pika/list/list.svelte +349 -0
  42. package/src/pika/markdown-editor/github.scss +87 -0
  43. package/src/pika/markdown-editor/index.ts +1 -0
  44. package/src/pika/markdown-editor/markdown-editor.svelte +44 -0
  45. package/src/pika/permanent-toast/index.ts +1 -0
  46. package/src/pika/permanent-toast/permanent-toast.svelte +47 -0
  47. package/src/pika/pika-alert/index.ts +1 -0
  48. package/src/pika/pika-alert/pika-alert.svelte +53 -0
  49. package/src/pika/pika-badge/index.ts +1 -0
  50. package/src/pika/pika-badge/pika-badge.svelte +61 -0
  51. package/src/pika/pika-table/index.ts +7 -0
  52. package/src/pika/pika-table/pika-table-cell.svelte +9 -0
  53. package/src/pika/pika-table/pika-table-checkbox.svelte +8 -0
  54. package/src/pika/pika-table/pika-table-column-header.svelte +88 -0
  55. package/src/pika/pika-table/pika-table-faceted-filter.svelte +109 -0
  56. package/src/pika/pika-table/pika-table-pagination.svelte +95 -0
  57. package/src/pika/pika-table/pika-table-row-actions.svelte +58 -0
  58. package/src/pika/pika-table/pika-table-toolbar.svelte +88 -0
  59. package/src/pika/pika-table/pika-table-view-options.svelte +35 -0
  60. package/src/pika/pika-table/pika-table.svelte +295 -0
  61. package/src/pika/pika-table/types.ts +106 -0
  62. package/src/pika/pika-tabs/index.ts +18 -0
  63. package/src/pika/pika-tabs/tabs-content.svelte +16 -0
  64. package/src/pika/pika-tabs/tabs-list.svelte +12 -0
  65. package/src/pika/pika-tabs/tabs-trigger.svelte +23 -0
  66. package/src/pika/popup-help/index.ts +1 -0
  67. package/src/pika/popup-help/popup-help.svelte +33 -0
  68. package/src/pika/simple-dropdown/index.ts +2 -0
  69. package/src/pika/simple-dropdown/simple-dropdown-types.ts +5 -0
  70. package/src/pika/simple-dropdown/simple-dropdown.svelte +288 -0
  71. package/src/pika/slideout/constants.ts +5 -0
  72. package/src/pika/slideout/context.svelte.ts +110 -0
  73. package/src/pika/slideout/index.ts +19 -0
  74. package/src/pika/slideout/slideout-content.svelte +36 -0
  75. package/src/pika/slideout/slideout-panel.svelte +126 -0
  76. package/src/pika/slideout/slideout-provider.svelte +49 -0
  77. package/src/pika/slideout/slideout-rail.svelte.die +69 -0
  78. package/src/pika/slideout/slideout.svelte +33 -0
  79. package/src/pika/slideout/slideout.svelte.old +113 -0
  80. package/src/pika/text-wave-shimmer/index.ts +1 -0
  81. package/src/pika/text-wave-shimmer/text-wave-shimmer.svelte +43 -0
  82. package/src/pika/tooltip-plus/index.ts +1 -0
  83. package/src/pika/tooltip-plus/tooltip-plus.svelte +42 -0
  84. package/src/shadcn/.DS_Store +0 -0
  85. package/src/shadcn/alert/alert-description.svelte +11 -0
  86. package/src/shadcn/alert/alert-title.svelte +24 -0
  87. package/src/shadcn/alert/alert.svelte +39 -0
  88. package/src/shadcn/alert/index.ts +14 -0
  89. package/src/shadcn/avatar/avatar-fallback.svelte +13 -0
  90. package/src/shadcn/avatar/avatar-image.svelte +13 -0
  91. package/src/shadcn/avatar/avatar.svelte +19 -0
  92. package/src/shadcn/avatar/index.ts +13 -0
  93. package/src/shadcn/badge/badge.svelte +48 -0
  94. package/src/shadcn/badge/index.ts +2 -0
  95. package/src/shadcn/breadcrumb/breadcrumb-ellipsis.svelte +12 -0
  96. package/src/shadcn/breadcrumb/breadcrumb-item.svelte +20 -0
  97. package/src/shadcn/breadcrumb/breadcrumb-link.svelte +31 -0
  98. package/src/shadcn/breadcrumb/breadcrumb-list.svelte +20 -0
  99. package/src/shadcn/breadcrumb/breadcrumb-page.svelte +23 -0
  100. package/src/shadcn/breadcrumb/breadcrumb-separator.svelte +15 -0
  101. package/src/shadcn/breadcrumb/breadcrumb.svelte +15 -0
  102. package/src/shadcn/breadcrumb/index.ts +25 -0
  103. package/src/shadcn/button/button.svelte +81 -0
  104. package/src/shadcn/button/index.ts +17 -0
  105. package/src/shadcn/calendar/calendar-caption.svelte +76 -0
  106. package/src/shadcn/calendar/calendar-cell.svelte +19 -0
  107. package/src/shadcn/calendar/calendar-day.svelte +31 -0
  108. package/src/shadcn/calendar/calendar-grid-body.svelte +12 -0
  109. package/src/shadcn/calendar/calendar-grid-head.svelte +12 -0
  110. package/src/shadcn/calendar/calendar-grid-row.svelte +12 -0
  111. package/src/shadcn/calendar/calendar-grid.svelte +16 -0
  112. package/src/shadcn/calendar/calendar-head-cell.svelte +16 -0
  113. package/src/shadcn/calendar/calendar-header.svelte +16 -0
  114. package/src/shadcn/calendar/calendar-heading.svelte +12 -0
  115. package/src/shadcn/calendar/calendar-month-select.svelte +25 -0
  116. package/src/shadcn/calendar/calendar-month.svelte +15 -0
  117. package/src/shadcn/calendar/calendar-months.svelte +20 -0
  118. package/src/shadcn/calendar/calendar-nav.svelte +19 -0
  119. package/src/shadcn/calendar/calendar-next-button.svelte +19 -0
  120. package/src/shadcn/calendar/calendar-prev-button.svelte +19 -0
  121. package/src/shadcn/calendar/calendar-year-select.svelte +25 -0
  122. package/src/shadcn/calendar/calendar.svelte +61 -0
  123. package/src/shadcn/calendar/index.ts +30 -0
  124. package/src/shadcn/card/card-content.svelte +16 -0
  125. package/src/shadcn/card/card-description.svelte +16 -0
  126. package/src/shadcn/card/card-footer.svelte +16 -0
  127. package/src/shadcn/card/card-header.svelte +16 -0
  128. package/src/shadcn/card/card-title.svelte +25 -0
  129. package/src/shadcn/card/card.svelte +20 -0
  130. package/src/shadcn/card/index.ts +22 -0
  131. package/src/shadcn/carousel/carousel-content.svelte +39 -0
  132. package/src/shadcn/carousel/carousel-item.svelte +26 -0
  133. package/src/shadcn/carousel/carousel-next.svelte +30 -0
  134. package/src/shadcn/carousel/carousel-previous.svelte +30 -0
  135. package/src/shadcn/carousel/carousel.svelte +88 -0
  136. package/src/shadcn/carousel/context.ts +51 -0
  137. package/src/shadcn/carousel/index.ts +19 -0
  138. package/src/shadcn/checkbox/checkbox.svelte +36 -0
  139. package/src/shadcn/checkbox/index.ts +6 -0
  140. package/src/shadcn/collapsible/collapsible-content.svelte +7 -0
  141. package/src/shadcn/collapsible/collapsible-trigger.svelte +7 -0
  142. package/src/shadcn/collapsible/collapsible.svelte +11 -0
  143. package/src/shadcn/collapsible/index.ts +13 -0
  144. package/src/shadcn/command/command-dialog.svelte +40 -0
  145. package/src/shadcn/command/command-empty.svelte +13 -0
  146. package/src/shadcn/command/command-group.svelte +30 -0
  147. package/src/shadcn/command/command-input.svelte +21 -0
  148. package/src/shadcn/command/command-item.svelte +16 -0
  149. package/src/shadcn/command/command-link-item.svelte +16 -0
  150. package/src/shadcn/command/command-list.svelte +13 -0
  151. package/src/shadcn/command/command-separator.svelte +13 -0
  152. package/src/shadcn/command/command-shortcut.svelte +20 -0
  153. package/src/shadcn/command/command.svelte +19 -0
  154. package/src/shadcn/command/index.ts +40 -0
  155. package/src/shadcn/data-table/data-table.svelte.ts +141 -0
  156. package/src/shadcn/data-table/flex-render.svelte +36 -0
  157. package/src/shadcn/data-table/index.ts +3 -0
  158. package/src/shadcn/data-table/render-helpers.ts +111 -0
  159. package/src/shadcn/dialog/dialog-close.svelte +7 -0
  160. package/src/shadcn/dialog/dialog-content.svelte +43 -0
  161. package/src/shadcn/dialog/dialog-description.svelte +13 -0
  162. package/src/shadcn/dialog/dialog-footer.svelte +20 -0
  163. package/src/shadcn/dialog/dialog-header.svelte +20 -0
  164. package/src/shadcn/dialog/dialog-overlay.svelte +16 -0
  165. package/src/shadcn/dialog/dialog-title.svelte +13 -0
  166. package/src/shadcn/dialog/dialog-trigger.svelte +7 -0
  167. package/src/shadcn/dialog/index.ts +37 -0
  168. package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-item.svelte +41 -0
  169. package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +27 -0
  170. package/src/shadcn/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  171. package/src/shadcn/dropdown-menu/dropdown-menu-group.svelte +7 -0
  172. package/src/shadcn/dropdown-menu/dropdown-menu-item.svelte +27 -0
  173. package/src/shadcn/dropdown-menu/dropdown-menu-label.svelte +24 -0
  174. package/src/shadcn/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  175. package/src/shadcn/dropdown-menu/dropdown-menu-radio-item.svelte +26 -0
  176. package/src/shadcn/dropdown-menu/dropdown-menu-separator.svelte +13 -0
  177. package/src/shadcn/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
  178. package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +16 -0
  179. package/src/shadcn/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  180. package/src/shadcn/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  181. package/src/shadcn/dropdown-menu/index.ts +49 -0
  182. package/src/shadcn/index.ts +40 -0
  183. package/src/shadcn/input/index.ts +7 -0
  184. package/src/shadcn/input/input.svelte +51 -0
  185. package/src/shadcn/is-mobile.svelte.ts +9 -0
  186. package/src/shadcn/label/index.ts +7 -0
  187. package/src/shadcn/label/label.svelte +16 -0
  188. package/src/shadcn/popover/index.ts +17 -0
  189. package/src/shadcn/popover/popover-content.svelte +29 -0
  190. package/src/shadcn/popover/popover-trigger.svelte +8 -0
  191. package/src/shadcn/radio-group/index.ts +10 -0
  192. package/src/shadcn/radio-group/radio-group-item.svelte +25 -0
  193. package/src/shadcn/radio-group/radio-group.svelte +19 -0
  194. package/src/shadcn/range-calendar/index.ts +30 -0
  195. package/src/shadcn/range-calendar/range-calendar-cell.svelte +19 -0
  196. package/src/shadcn/range-calendar/range-calendar-day.svelte +35 -0
  197. package/src/shadcn/range-calendar/range-calendar-grid-body.svelte +12 -0
  198. package/src/shadcn/range-calendar/range-calendar-grid-head.svelte +12 -0
  199. package/src/shadcn/range-calendar/range-calendar-grid-row.svelte +12 -0
  200. package/src/shadcn/range-calendar/range-calendar-grid.svelte +16 -0
  201. package/src/shadcn/range-calendar/range-calendar-head-cell.svelte +16 -0
  202. package/src/shadcn/range-calendar/range-calendar-header.svelte +16 -0
  203. package/src/shadcn/range-calendar/range-calendar-heading.svelte +16 -0
  204. package/src/shadcn/range-calendar/range-calendar-months.svelte +20 -0
  205. package/src/shadcn/range-calendar/range-calendar-next-button.svelte +18 -0
  206. package/src/shadcn/range-calendar/range-calendar-prev-button.svelte +18 -0
  207. package/src/shadcn/range-calendar/range-calendar.svelte +57 -0
  208. package/src/shadcn/resizable/index.ts +13 -0
  209. package/src/shadcn/resizable/resizable-handle.svelte +30 -0
  210. package/src/shadcn/resizable/resizable-pane-group.svelte +22 -0
  211. package/src/shadcn/scroll-area/index.ts +10 -0
  212. package/src/shadcn/scroll-area/scroll-area-scrollbar.svelte +28 -0
  213. package/src/shadcn/scroll-area/scroll-area.svelte +35 -0
  214. package/src/shadcn/select/index.ts +37 -0
  215. package/src/shadcn/select/select-content.svelte +38 -0
  216. package/src/shadcn/select/select-group-heading.svelte +21 -0
  217. package/src/shadcn/select/select-group.svelte +7 -0
  218. package/src/shadcn/select/select-item.svelte +31 -0
  219. package/src/shadcn/select/select-label.svelte +20 -0
  220. package/src/shadcn/select/select-scroll-down-button.svelte +11 -0
  221. package/src/shadcn/select/select-scroll-up-button.svelte +11 -0
  222. package/src/shadcn/select/select-separator.svelte +14 -0
  223. package/src/shadcn/select/select-trigger.svelte +30 -0
  224. package/src/shadcn/separator/index.ts +7 -0
  225. package/src/shadcn/separator/separator.svelte +16 -0
  226. package/src/shadcn/sheet/index.ts +36 -0
  227. package/src/shadcn/sheet/sheet-close.svelte +7 -0
  228. package/src/shadcn/sheet/sheet-content.svelte +66 -0
  229. package/src/shadcn/sheet/sheet-description.svelte +13 -0
  230. package/src/shadcn/sheet/sheet-footer.svelte +15 -0
  231. package/src/shadcn/sheet/sheet-header.svelte +15 -0
  232. package/src/shadcn/sheet/sheet-overlay.svelte +16 -0
  233. package/src/shadcn/sheet/sheet-title.svelte +13 -0
  234. package/src/shadcn/sheet/sheet-trigger.svelte +7 -0
  235. package/src/shadcn/sidebar/constants.ts +6 -0
  236. package/src/shadcn/sidebar/context.svelte.ts +80 -0
  237. package/src/shadcn/sidebar/index.ts +75 -0
  238. package/src/shadcn/sidebar/sidebar-content.svelte +24 -0
  239. package/src/shadcn/sidebar/sidebar-footer.svelte +21 -0
  240. package/src/shadcn/sidebar/sidebar-group-action.svelte +36 -0
  241. package/src/shadcn/sidebar/sidebar-group-content.svelte +21 -0
  242. package/src/shadcn/sidebar/sidebar-group-label.svelte +34 -0
  243. package/src/shadcn/sidebar/sidebar-group.svelte +21 -0
  244. package/src/shadcn/sidebar/sidebar-header.svelte +21 -0
  245. package/src/shadcn/sidebar/sidebar-input.svelte +21 -0
  246. package/src/shadcn/sidebar/sidebar-inset.svelte +24 -0
  247. package/src/shadcn/sidebar/sidebar-menu-action.svelte +43 -0
  248. package/src/shadcn/sidebar/sidebar-menu-badge.svelte +29 -0
  249. package/src/shadcn/sidebar/sidebar-menu-button.svelte +101 -0
  250. package/src/shadcn/sidebar/sidebar-menu-item.svelte +21 -0
  251. package/src/shadcn/sidebar/sidebar-menu-skeleton.svelte +36 -0
  252. package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +43 -0
  253. package/src/shadcn/sidebar/sidebar-menu-sub-item.svelte +21 -0
  254. package/src/shadcn/sidebar/sidebar-menu-sub.svelte +25 -0
  255. package/src/shadcn/sidebar/sidebar-menu.svelte +21 -0
  256. package/src/shadcn/sidebar/sidebar-provider.svelte +46 -0
  257. package/src/shadcn/sidebar/sidebar-rail.svelte +36 -0
  258. package/src/shadcn/sidebar/sidebar-separator.svelte +15 -0
  259. package/src/shadcn/sidebar/sidebar-trigger.svelte +35 -0
  260. package/src/shadcn/sidebar/sidebar.svelte +94 -0
  261. package/src/shadcn/skeleton/index.ts +7 -0
  262. package/src/shadcn/skeleton/skeleton.svelte +17 -0
  263. package/src/shadcn/slider/index.ts +7 -0
  264. package/src/shadcn/slider/slider.svelte +44 -0
  265. package/src/shadcn/sonner/index.ts +1 -0
  266. package/src/shadcn/sonner/sonner.svelte +13 -0
  267. package/src/shadcn/switch/index.ts +7 -0
  268. package/src/shadcn/switch/switch.svelte +27 -0
  269. package/src/shadcn/table/index.ts +28 -0
  270. package/src/shadcn/table/table-body.svelte +15 -0
  271. package/src/shadcn/table/table-caption.svelte +20 -0
  272. package/src/shadcn/table/table-cell.svelte +20 -0
  273. package/src/shadcn/table/table-footer.svelte +20 -0
  274. package/src/shadcn/table/table-head.svelte +23 -0
  275. package/src/shadcn/table/table-header.svelte +15 -0
  276. package/src/shadcn/table/table-row.svelte +23 -0
  277. package/src/shadcn/table/table.svelte +17 -0
  278. package/src/shadcn/tabs/index.ts +18 -0
  279. package/src/shadcn/tabs/tabs-content.svelte +21 -0
  280. package/src/shadcn/tabs/tabs-list.svelte +19 -0
  281. package/src/shadcn/tabs/tabs-trigger.svelte +21 -0
  282. package/src/shadcn/textarea/index.ts +7 -0
  283. package/src/shadcn/textarea/textarea.svelte +22 -0
  284. package/src/shadcn/toggle/index.ts +13 -0
  285. package/src/shadcn/toggle/toggle.svelte +51 -0
  286. package/src/shadcn/toggle-group/index.ts +10 -0
  287. package/src/shadcn/toggle-group/toggle-group-item.svelte +30 -0
  288. package/src/shadcn/toggle-group/toggle-group.svelte +41 -0
  289. package/src/shadcn/tooltip/index.ts +21 -0
  290. package/src/shadcn/tooltip/tooltip-content.svelte +47 -0
  291. package/src/shadcn/tooltip/tooltip-trigger.svelte +7 -0
  292. package/src/shadcn/utils.ts +14 -0
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import { Checkbox } from '../../shadcn/checkbox';
3
+ import type { Checkbox as CheckboxPrimitive, WithoutChildrenOrChild } from 'bits-ui';
4
+
5
+ let { checked = false, onCheckedChange = (v) => (checked = v), ...restProps }: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
6
+ </script>
7
+
8
+ <Checkbox bind:checked={() => checked, onCheckedChange} {...restProps} />
@@ -0,0 +1,88 @@
1
+ <script lang="ts" module>
2
+ type TData = unknown;
3
+ type TValue = unknown;
4
+ </script>
5
+
6
+ <script lang="ts" generics="TData, TValue">
7
+ import ArrowDown from '$icons/lucide/arrow-down';
8
+ import ArrowDownUp from '$icons/lucide/arrow-down-up';
9
+ import ArrowUp from '$icons/lucide/arrow-up';
10
+ import EllipsisVertical from '$icons/lucide/ellipsis-vertical';
11
+ import EyeOff from '$icons/lucide/eye-off';
12
+ import Button from '../../shadcn/button/button.svelte';
13
+ import * as DropdownMenu from '../../shadcn/dropdown-menu';
14
+ import { cn } from '../../shadcn/utils';
15
+ import type { Column } from '@tanstack/table-core';
16
+ import type { WithoutChildren } from 'bits-ui';
17
+ import type { HTMLAttributes } from 'svelte/elements';
18
+
19
+ type Props = HTMLAttributes<HTMLDivElement> & {
20
+ column: Column<TData, TValue>;
21
+ title: string;
22
+ };
23
+
24
+ let { column, class: className, title, ...restProps }: WithoutChildren<Props> = $props();
25
+ let mouseInside = $state(false);
26
+ let dropdownOpen = $state(false);
27
+ </script>
28
+
29
+ {#if !column?.getCanSort()}
30
+ <div class={className} {...restProps}>
31
+ {title}
32
+ </div>
33
+ {:else}
34
+ <!--TODO: why couldn't we add the restProps thing to the button below? {...restProps} -->
35
+ <Button
36
+ variant="ghost"
37
+ onmouseenter={() => (mouseInside = true)}
38
+ onmouseleave={() => (mouseInside = false)}
39
+ class={cn('flex items-center min-w-0 gap-1 group pl-0 pr-0', className)}
40
+ onclick={() => {
41
+ if (column.getIsSorted() === false) {
42
+ column.toggleSorting(false);
43
+ } else if (column.getIsSorted() === 'asc') {
44
+ column.toggleSorting(true);
45
+ } else if (column.getIsSorted() === 'desc') {
46
+ column.clearSorting();
47
+ }
48
+ }}
49
+ >
50
+ <span class="truncate flex-1">{title}</span>
51
+ {#if column.getIsSorted() === 'desc'}
52
+ <ArrowDown class="flex-shrink-0" />
53
+ {:else if column.getIsSorted() === 'asc'}
54
+ <ArrowUp class="flex-shrink-0" />
55
+ {/if}
56
+
57
+ <div class="flex-shrink-0 w-3 h-6 flex items-center justify-between {dropdownOpen ? 'visible' : 'invisible'} group-hover:visible">
58
+ <DropdownMenu.Root bind:open={dropdownOpen}>
59
+ <DropdownMenu.Trigger>
60
+ {#snippet child({ props })}
61
+ <Button {...props} variant="ghost" size="icon" class="data-[state=open]:bg-blue-200 h-8 w-8 p-0 hover:bg-blue-200 {dropdownOpen ? 'bg-blue-200' : ''} ">
62
+ <EllipsisVertical class="text-muted-foreground/70 size-3.5" />
63
+ </Button>
64
+ {/snippet}
65
+ </DropdownMenu.Trigger>
66
+ <DropdownMenu.Content align="start">
67
+ <DropdownMenu.Item disabled={column.getIsSorted() === 'asc'} onclick={() => column.toggleSorting(false)}>
68
+ <ArrowUp class="text-muted-foreground/70 mr-2 size-3.5" />
69
+ Asc
70
+ </DropdownMenu.Item>
71
+ <DropdownMenu.Item disabled={column.getIsSorted() === 'desc'} onclick={() => column.toggleSorting(true)}>
72
+ <ArrowDown class="text-muted-foreground/70 mr-2 size-3.5" />
73
+ Desc
74
+ </DropdownMenu.Item>
75
+ <DropdownMenu.Item disabled={!column.getIsSorted()} onclick={() => column.clearSorting()}>
76
+ <ArrowDownUp class="text-muted-foreground/70 mr-2 size-3.5" />
77
+ UnSort
78
+ </DropdownMenu.Item>
79
+ <DropdownMenu.Separator />
80
+ <DropdownMenu.Item onclick={() => column.toggleVisibility(false)}>
81
+ <EyeOff class="text-muted-foreground/70 mr-2 size-3.5" />
82
+ Hide
83
+ </DropdownMenu.Item>
84
+ </DropdownMenu.Content>
85
+ </DropdownMenu.Root>
86
+ </div>
87
+ </Button>
88
+ {/if}
@@ -0,0 +1,109 @@
1
+ <script lang="ts" module>
2
+ type TData = unknown;
3
+ type TValue = unknown;
4
+ </script>
5
+
6
+ <script lang="ts" generics="TData, TValue">
7
+ import CirclePlus from '$icons/lucide/circle-plus';
8
+ import Check from '$icons/lucide/check';
9
+ import { Badge } from '../../shadcn/badge';
10
+ import { Button } from '../../shadcn/button';
11
+ import * as Command from '../../shadcn/command';
12
+ import * as Popover from '../../shadcn/popover';
13
+ import { Separator } from '../../shadcn/separator';
14
+ import { cn } from '../../shadcn/utils';
15
+ import type { Column } from '@tanstack/table-core';
16
+ import { SvelteSet } from 'svelte/reactivity';
17
+ import type { FacetedFilterData } from './types';
18
+
19
+ type Props<TData, TValue> = {
20
+ column: Column<TData, TValue>;
21
+ title: string;
22
+ options: FacetedFilterData[];
23
+ };
24
+
25
+ let { column, title, options }: Props<TData, TValue> = $props();
26
+
27
+ const facets = $derived(column?.getFacetedUniqueValues());
28
+ const selectedValues = $derived(new SvelteSet(column?.getFilterValue() as string[]));
29
+ </script>
30
+
31
+ <Popover.Root>
32
+ <Popover.Trigger>
33
+ {#snippet child({ props })}
34
+ <Button {...props} variant="outline" size="sm" class="h-8 border-dashed">
35
+ <CirclePlus />
36
+ {title}
37
+ {#if selectedValues.size > 0}
38
+ <Separator orientation="vertical" class="mx-2 h-4" />
39
+ <Badge variant="secondary" class="rounded-sm px-1 font-normal lg:hidden">
40
+ {selectedValues.size}
41
+ </Badge>
42
+ <div class="hidden space-x-1 lg:flex">
43
+ {#if selectedValues.size > 2}
44
+ <Badge variant="secondary" class="rounded-sm px-1 font-normal">
45
+ {selectedValues.size} selected
46
+ </Badge>
47
+ {:else}
48
+ {#each options.filter((opt) => selectedValues.has(opt.value)) as option (option)}
49
+ <Badge variant="secondary" class="rounded-sm px-1 font-normal">
50
+ {option.label}
51
+ </Badge>
52
+ {/each}
53
+ {/if}
54
+ </div>
55
+ {/if}
56
+ </Button>
57
+ {/snippet}
58
+ </Popover.Trigger>
59
+ <Popover.Content class="w-[200px] p-0" align="start">
60
+ <Command.Root>
61
+ <Command.Input placeholder={title} />
62
+ <Command.List>
63
+ <Command.Empty>No results found.</Command.Empty>
64
+ <Command.Group>
65
+ {#each options as option (option)}
66
+ {@const isSelected = selectedValues.has(option.value)}
67
+ <Command.Item
68
+ onSelect={() => {
69
+ if (isSelected) {
70
+ selectedValues.delete(option.value);
71
+ } else {
72
+ selectedValues.add(option.value);
73
+ }
74
+ const filterValues = Array.from(selectedValues);
75
+ column?.setFilterValue(filterValues.length ? filterValues : undefined);
76
+ }}
77
+ >
78
+ <div
79
+ class={cn(
80
+ 'border-primary mr-2 flex size-4 items-center justify-center rounded-sm border',
81
+ isSelected ? 'bg-primary text-primary-foreground' : 'opacity-50 [&_svg]:invisible'
82
+ )}
83
+ >
84
+ <Check class="size-4" />
85
+ </div>
86
+ {#if option.icon}
87
+ {@const Icon = option.icon}
88
+ <Icon class="text-muted-foreground {option.iconClasses ?? ''}" />
89
+ {/if}
90
+
91
+ <span>{option.label}</span>
92
+ {#if facets?.get(option.value)}
93
+ <span class="ml-auto flex size-4 items-center justify-center font-mono text-xs">
94
+ {facets.get(option.value)}
95
+ </span>
96
+ {/if}
97
+ </Command.Item>
98
+ {/each}
99
+ </Command.Group>
100
+ {#if selectedValues.size > 0}
101
+ <Command.Separator />
102
+ <Command.Group>
103
+ <Command.Item onSelect={() => column?.setFilterValue(undefined)} class="justify-center text-center">Clear filters</Command.Item>
104
+ </Command.Group>
105
+ {/if}
106
+ </Command.List>
107
+ </Command.Root>
108
+ </Popover.Content>
109
+ </Popover.Root>
@@ -0,0 +1,95 @@
1
+ <script lang="ts" module>
2
+ type TData = unknown;
3
+ </script>
4
+
5
+ <script lang="ts" generics="TData">
6
+ import ChevronLeft from '$icons/lucide/chevron-left';
7
+ import ChevronRight from '$icons/lucide/chevron-right';
8
+ import ChevronsLeft from '$icons/lucide/chevrons-left';
9
+ import ChevronsRight from '$icons/lucide/chevrons-right';
10
+ import { Button } from '../../shadcn/button';
11
+ import * as Select from '../../shadcn/select';
12
+ import type { Table } from '@tanstack/table-core';
13
+ import type { ServerSideConfig } from './types';
14
+
15
+ interface Props {
16
+ table: Table<TData>;
17
+ serverSide: ServerSideConfig;
18
+ }
19
+
20
+ let { table, serverSide }: Props = $props();
21
+
22
+ // For cursor-based pagination, we can't jump to arbitrary pages
23
+ const isCursorBased = $derived(serverSide?.paginationMode === 'cursor');
24
+ </script>
25
+
26
+ <div class="flex items-center justify-between px-2">
27
+ <div class="text-muted-foreground flex-1 text-sm">
28
+ {#if serverSide?.tableState?.totalRecords !== undefined}
29
+ {table.getFilteredSelectedRowModel().rows.length} of
30
+ {serverSide.tableState.totalRecords} total row(s) selected.
31
+ {:else}
32
+ {table.getFilteredSelectedRowModel().rows.length} of
33
+ {table.getFilteredRowModel().rows.length} row(s) selected.
34
+ {/if}
35
+ </div>
36
+ <div class="flex items-center space-x-6 lg:space-x-8">
37
+ <div class="flex items-center space-x-2">
38
+ <p class="text-sm font-medium">Rows per page</p>
39
+ <Select.Root
40
+ allowDeselect={false}
41
+ type="single"
42
+ value={`${table.getState().pagination.pageSize}`}
43
+ onValueChange={(value) => {
44
+ table.setPageSize(Number(value));
45
+ }}
46
+ >
47
+ <Select.Trigger class="h-8 w-[70px]">
48
+ {String(table.getState().pagination.pageSize)}
49
+ </Select.Trigger>
50
+ <Select.Content side="top">
51
+ {#each [10, 20, 50, 100, 500, 1000] as pageSize (pageSize)}
52
+ <Select.Item value={`${pageSize}`}>
53
+ {pageSize}
54
+ </Select.Item>
55
+ {/each}
56
+ </Select.Content>
57
+ </Select.Root>
58
+ </div>
59
+ <div class="flex w-[100px] items-center justify-center text-sm font-medium">
60
+ {#if table.getPageCount() > 0}
61
+ Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
62
+ {:else}
63
+ Page {table.getState().pagination.pageIndex + 1}
64
+ {/if}
65
+ </div>
66
+ <div class="flex items-center space-x-2">
67
+ <Button variant="outline" class="hidden size-8 p-0 lg:flex" onclick={() => table.setPageIndex(0)} disabled={!table.getCanPreviousPage() || isCursorBased}>
68
+ <span class="sr-only">Go to first page</span>
69
+ <ChevronsLeft />
70
+ </Button>
71
+ <Button variant="outline" class="size-8 p-0" onclick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>
72
+ <span class="sr-only">Go to previous page</span>
73
+ <ChevronLeft />
74
+ </Button>
75
+ <Button variant="outline" class="size-8 p-0" onclick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
76
+ <span class="sr-only">Go to next page</span>
77
+ <ChevronRight />
78
+ </Button>
79
+ <Button
80
+ variant="outline"
81
+ class="hidden size-8 p-0 lg:flex"
82
+ onclick={() => {
83
+ const pageCount = table.getPageCount();
84
+ if (pageCount > 0) {
85
+ table.setPageIndex(pageCount - 1);
86
+ }
87
+ }}
88
+ disabled={!table.getCanNextPage() || table.getPageCount() <= 0 || isCursorBased}
89
+ >
90
+ <span class="sr-only">Go to last page</span>
91
+ <ChevronsRight />
92
+ </Button>
93
+ </div>
94
+ </div>
95
+ </div>
@@ -0,0 +1,58 @@
1
+ <script lang="ts" module>
2
+ type TData = unknown;
3
+ </script>
4
+
5
+ <script lang="ts" generics="TData">
6
+ import type { AppState } from '$client/app/app.state.svelte';
7
+ import Ellipsis from '$icons/lucide/ellipsis';
8
+ import Button from '../../shadcn/button/button.svelte';
9
+ import * as DropdownMenu from '../../shadcn/dropdown-menu';
10
+ import type { Row } from '@tanstack/table-core';
11
+ import { getContext } from 'svelte';
12
+ import type { RowActionMenuItem, RowActionMenuItemSubMenu, RowActionsProps } from './types';
13
+
14
+ let { row, actionProps }: { row: Row<TData>; actionProps: RowActionsProps<TData> } = $props();
15
+ const appState = getContext<AppState>('appState');
16
+ </script>
17
+
18
+ <DropdownMenu.Root>
19
+ <DropdownMenu.Trigger>
20
+ {#snippet child({ props })}
21
+ <Button {...props} variant="ghost" class="data-[state=open]:bg-muted flex h-8 w-8 p-0">
22
+ <Ellipsis />
23
+ <span class="sr-only">Open Menu</span>
24
+ </Button>
25
+ {/snippet}
26
+ </DropdownMenu.Trigger>
27
+ <DropdownMenu.Content class="w-[{actionProps.menuWidth ? actionProps.menuWidth : '160px'}]" align="end">
28
+ {@render menuItems(actionProps.menuItems)}
29
+ </DropdownMenu.Content>
30
+ </DropdownMenu.Root>
31
+
32
+ {#snippet subMenu(props: RowActionMenuItemSubMenu<TData>)}
33
+ <DropdownMenu.Sub>
34
+ <DropdownMenu.SubTrigger>{props.label}</DropdownMenu.SubTrigger>
35
+ <DropdownMenu.SubContent>
36
+ {@render menuItems(props.menuItems)}
37
+ </DropdownMenu.SubContent>
38
+ </DropdownMenu.Sub>
39
+ {/snippet}
40
+
41
+ {#snippet menuItems(items: RowActionMenuItem<TData>[])}
42
+ {#each items as item}
43
+ {#if item === 'Separator'}
44
+ <DropdownMenu.Separator />
45
+ {:else if 'menuItems' in item}
46
+ {@render subMenu(item)}
47
+ {:else}
48
+ <DropdownMenu.Item onclick={() => item.onclick?.(row, appState)}>
49
+ <div class="flex items-center gap-2">
50
+ {#if item.icon}
51
+ <item.icon />
52
+ {/if}
53
+ {item.label}
54
+ </div>
55
+ </DropdownMenu.Item>
56
+ {/if}
57
+ {/each}
58
+ {/snippet}
@@ -0,0 +1,88 @@
1
+ <!--TODO Make this a generic component inside of pika-table-->
2
+ <script lang="ts" module>
3
+ type TData = unknown;
4
+ </script>
5
+
6
+ <script lang="ts" generics="TData">
7
+ import X from '$icons/lucide/x';
8
+ import { PikaTableFacetedFilter, PikaTableViewOptions } from '../../pika/pika-table';
9
+ import Button from '../../shadcn/button/button.svelte';
10
+ import { Input } from '../../shadcn/input/index.js';
11
+ import type { Table } from '@tanstack/table-core';
12
+ import type { Snippet } from 'svelte';
13
+ import type { FacetedFilterPropsWithColumn, FacetedFilters, FacetedFiltersWithColumn, GlobalFilterProps } from './types';
14
+
15
+ interface Props {
16
+ table: Table<TData>;
17
+ globalFilterProps?: GlobalFilterProps;
18
+ facetedFilters?: FacetedFilters;
19
+ // If you pass in toolbar content then global filter and faceted filters will be ignored
20
+ toolbarContent?: Snippet;
21
+
22
+ // Appears beneath the toolbar and above the table
23
+ beneathToolbarContent?: Snippet;
24
+ }
25
+
26
+ let { table, globalFilterProps, facetedFilters = [], toolbarContent, beneathToolbarContent }: Props = $props();
27
+
28
+ const isFiltered = $derived(table.getState().columnFilters.length > 0 || table.getState().globalFilter);
29
+
30
+ const facetedFilterCols = $derived(
31
+ facetedFilters.reduce((acc, filter) => {
32
+ const col = table.getColumn(filter.columnId);
33
+ if (col) {
34
+ const propsWithColumn: FacetedFilterPropsWithColumn<TData> = {
35
+ ...filter,
36
+ column: col
37
+ };
38
+ acc.push(propsWithColumn);
39
+ }
40
+ return acc;
41
+ }, [] as FacetedFiltersWithColumn<TData>)
42
+ );
43
+ </script>
44
+
45
+ <div class="flex items-start justify-between">
46
+ {#if toolbarContent}
47
+ {@render toolbarContent()}
48
+ {:else}
49
+ <div class="flex flex-1 items-center space-x-2">
50
+ {#if globalFilterProps?.showGlobalFilter}
51
+ <Input
52
+ placeholder={globalFilterProps?.globalFilterPlaceholder ?? 'Filter table...'}
53
+ value={globalFilterProps?.globalFilterValue}
54
+ oninput={(e) => {
55
+ globalFilterProps.globalFilterValue = e.currentTarget.value;
56
+ }}
57
+ onchange={(e) => {
58
+ table.setGlobalFilter(e.currentTarget.value);
59
+ }}
60
+ class="h-8 w-[150px] lg:w-[250px]"
61
+ />
62
+ {/if}
63
+
64
+ {#each facetedFilterCols as col}
65
+ <PikaTableFacetedFilter column={col.column} title={col.title} options={col.options} />
66
+ {/each}
67
+
68
+ {#if isFiltered}
69
+ <Button
70
+ variant="ghost"
71
+ onclick={() => {
72
+ table.resetColumnFilters(true);
73
+ table.resetGlobalFilter(true);
74
+ }}
75
+ class="h-8 px-2 lg:px-3"
76
+ >
77
+ Reset
78
+ <X />
79
+ </Button>
80
+ {/if}
81
+ </div>
82
+ {/if}
83
+
84
+ <PikaTableViewOptions {table} />
85
+ </div>
86
+ {#if beneathToolbarContent}
87
+ {@render beneathToolbarContent()}
88
+ {/if}
@@ -0,0 +1,35 @@
1
+ <script lang="ts" module>
2
+ type TData = unknown;
3
+ </script>
4
+
5
+ <script lang="ts" generics="TData">
6
+ import Settings2 from '$icons/lucide/settings-2';
7
+ import { buttonVariants } from '../../shadcn/button';
8
+ import * as DropdownMenu from '../../shadcn/dropdown-menu';
9
+ import type { Table } from '@tanstack/table-core';
10
+
11
+ let { table }: { table: Table<TData> } = $props();
12
+ </script>
13
+
14
+ <DropdownMenu.Root>
15
+ <DropdownMenu.Trigger
16
+ class={buttonVariants({
17
+ variant: 'outline',
18
+ size: 'sm',
19
+ class: 'ml-auto hidden h-8 w-8 lg:flex '
20
+ })}
21
+ >
22
+ <Settings2 />
23
+ </DropdownMenu.Trigger>
24
+ <DropdownMenu.Content>
25
+ <DropdownMenu.Group>
26
+ <DropdownMenu.GroupHeading>Toggle columns</DropdownMenu.GroupHeading>
27
+ <DropdownMenu.Separator />
28
+ {#each table.getAllColumns().filter((col) => typeof col.accessorFn !== 'undefined' && col.getCanHide()) as column (column)}
29
+ <DropdownMenu.CheckboxItem bind:checked={() => column.getIsVisible(), (v) => column.toggleVisibility(!!v)} class="capitalize">
30
+ {column.id}
31
+ </DropdownMenu.CheckboxItem>
32
+ {/each}
33
+ </DropdownMenu.Group>
34
+ </DropdownMenu.Content>
35
+ </DropdownMenu.Root>