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,349 @@
1
+ <script lang="ts" generics="T">
2
+ import Minus from '$icons/lucide/minus';
3
+ import Plus from '$icons/lucide/plus';
4
+ import SimpleDropdown from '../../pika/simple-dropdown/simple-dropdown.svelte';
5
+ import Button from '../../shadcn/button/button.svelte';
6
+ import * as Command from '../../shadcn/command/index.js';
7
+ import { Input } from '../../shadcn/input/index.js';
8
+ import { cn } from '../../shadcn/utils';
9
+ import { SvelteSet } from 'svelte/reactivity';
10
+ import Combobox from '../combobox/combobox.svelte';
11
+ import type { ListMapping } from './list-types';
12
+
13
+ interface Props {
14
+ // Additional CSS classes. Can override default height of h-[250px]
15
+ classes?: string;
16
+ items?: T[];
17
+ mapping: ListMapping<T>;
18
+ emptyMessage?: string;
19
+ showValueInListEntries?: boolean;
20
+ disabled?: boolean;
21
+ // If true, the user can select items from the list.
22
+ allowSelection?: boolean;
23
+ // If true, the user can select multiple items from the list.
24
+ multiSelect?: boolean;
25
+ // If you want to detect when items are selected pass this in as a bound variable. TODO: support initializing selected items from this list passed in.
26
+ selectedItems?: T[];
27
+
28
+ // Originally, the list had a use case where the UX was better when you require the user to first select
29
+ // an entry in the dropdown and then volitionally click the add button to add it to the list.
30
+ // However, this is an extra unnecessary step for the user. So, if you want to add the item to the list
31
+ // when the user selects an item from the list, set this to true.
32
+ addOnSelect?: boolean;
33
+
34
+ // Allow the user to add and remove items from the list instead of just showing a list of items.
35
+ // You the developer are responsible for ensuring that the items are unique and that the user cannot add the same item twice.
36
+ // You implement the logic for adding and removing items from your underlying list.
37
+ addRemove?: {
38
+ addItem?: (item: T) => void;
39
+ // If true, the user can press enter to add an item to the list. Defaults to false.
40
+ triggerAddOnEnter?: boolean;
41
+ removeItem?: (item: T) => void;
42
+ allowArbitraryValues?: {
43
+ convertValueToType: (arbitraryValue: string) => T;
44
+ // The placeholder text for the input field in the popup allowing a user to filter the list or add an arbitrary value.
45
+ popupInputPlaceholder?: string;
46
+ };
47
+ // If provided, an autocomplete combobox that will search as the user types to the server will be provided.
48
+ // If this is provided then allowArbitraryValues will be ignored.
49
+ search?: {
50
+ // The function that will be called when the user types in the search input field, calling the server presumably.
51
+ onSearchValueChanged: ((value: string) => Promise<void>) | undefined;
52
+ // The minimum number of characters that the user must type before the search is triggered. Defaults to 1.
53
+ minCharactersForSearch?: number | undefined;
54
+ // If true, the value of the item will be shown in the list entries. Defaults to false.
55
+ showValueInListEntries?: boolean;
56
+ // The placeholder text for the search input field in the popup.
57
+ popupInputPlaceholder?: string;
58
+ // Indicates that the search is in progress back to the server. Defaults to false.
59
+ loading?: boolean | undefined;
60
+ // This is the name of the type of data in the dropdown that a user will understand
61
+ optionTypeName?: string;
62
+ optionTypeNamePlural?: string;
63
+
64
+ // This is the mapping of the returned search options. If not provided, the mapping of the list will be used.
65
+ mapping?: ListMapping<T>;
66
+
67
+ // Additional CSS classes for the search input field in the popup.
68
+ widthClasses?: string;
69
+
70
+ // The options that will be shown in the search dropdown. If not provided, the options will be fetched from the server.
71
+ options: T[] | undefined;
72
+ };
73
+ // Allows for pre-defined items that a user may select from to add to the list if not already present,
74
+ // changing from an input field to a dropdown list with an input field.
75
+ predefinedOptions?: {
76
+ items: T[];
77
+ // This is the name of the type of data in the dropdown that a user will understand
78
+ optionTypeName?: string;
79
+ optionTypeNamePlural?: string;
80
+ // This is the mapping of the predefined options. If not provided, the mapping of the list will be used.
81
+ mapping?: ListMapping<T>;
82
+ };
83
+ addValueInputPlaceholder?: string;
84
+ };
85
+ }
86
+
87
+ let {
88
+ classes = '',
89
+ items = [],
90
+ mapping,
91
+ addRemove,
92
+ emptyMessage,
93
+ showValueInListEntries = false,
94
+ disabled = false,
95
+ allowSelection = false,
96
+ multiSelect = false,
97
+ selectedItems = $bindable<T[]>([]),
98
+ addOnSelect = false
99
+ }: Props = $props();
100
+
101
+ const getValue = (item: T) => mapping?.value(item) ?? '';
102
+ const getLabel = (item: T) => mapping?.label(item) ?? '';
103
+ const getSecondaryLabel = (item: T) => mapping?.secondaryLabel?.(item);
104
+
105
+ const predefinedItems = $derived(addRemove?.predefinedOptions?.items || []);
106
+ const predefinedMapping = $derived.by(() => {
107
+ const customMapping = addRemove?.predefinedOptions?.mapping;
108
+ if (customMapping) {
109
+ return customMapping;
110
+ }
111
+ return mapping;
112
+ });
113
+ const getPredefinedValue = (item: T) => predefinedMapping?.value(item) ?? '';
114
+
115
+ const searchMapping = $derived.by(() => {
116
+ const customMapping = addRemove?.search?.mapping;
117
+ if (customMapping) {
118
+ return customMapping;
119
+ }
120
+ return mapping;
121
+ });
122
+ const getSearchValue = (item: T) => searchMapping?.value(item) ?? '';
123
+
124
+ let selectedValues = $state(new SvelteSet<string>());
125
+ let addValueInput = $state('');
126
+ let selectedDropdownItem = $state<T | undefined>(undefined);
127
+
128
+ // Auto-enable selection when remove functionality is available
129
+ const effectiveAllowSelection = $derived(allowSelection || addRemove?.removeItem !== undefined);
130
+
131
+ function toggleSelection(value: string) {
132
+ let changed = false;
133
+ if (multiSelect) {
134
+ // Multi-select: toggle the individual item
135
+ if (selectedValues.has(value)) {
136
+ selectedValues.delete(value);
137
+ changed = true;
138
+ } else {
139
+ selectedValues.add(value);
140
+ changed = true;
141
+ }
142
+ } else {
143
+ // Single-select: clear all and select this one, or deselect if already selected
144
+ if (selectedValues.has(value)) {
145
+ selectedValues.delete(value);
146
+ changed = true;
147
+ } else {
148
+ selectedValues.clear();
149
+ selectedValues.add(value);
150
+ changed = true;
151
+ }
152
+ }
153
+ if (changed) {
154
+ selectedItems = items.filter((item) => selectedValues.has(getValue(item)));
155
+ }
156
+ }
157
+
158
+ // Get available predefined options that aren't already in the list
159
+ const availablePredefinedOptions = $derived.by(() => {
160
+ if (!predefinedItems.length) return [];
161
+
162
+ const currentItemValues = new Set(items.map((item) => getValue(item)));
163
+ return predefinedItems.filter((item) => !currentItemValues.has(getPredefinedValue(item)));
164
+ });
165
+
166
+ const availableSearchOptions = $derived.by(() => {
167
+ if (!addRemove?.search?.options) return [];
168
+ const currentItemValues = new Set(items.map((item) => getValue(item)));
169
+ return addRemove.search.options.filter((item) => !currentItemValues.has(getSearchValue(item)));
170
+ });
171
+
172
+ function handleAddFromDropdown() {
173
+ if (selectedDropdownItem && addRemove?.addItem) {
174
+ addRemove.addItem(selectedDropdownItem);
175
+ selectedDropdownItem = undefined; // Reset selection after adding
176
+ }
177
+ }
178
+
179
+ function handleRemoveSelectedItems() {
180
+ if (addRemove?.removeItem && selectedValues.size > 0) {
181
+ // Find and remove all selected items from the actual list
182
+ const selectedItemsToRemove = items.filter((item) => selectedValues.has(getValue(item)));
183
+ selectedItemsToRemove.forEach((item) => {
184
+ addRemove.removeItem!(item);
185
+ });
186
+ selectedValues.clear(); // Clear selection after removing
187
+ selectedItems = [];
188
+ }
189
+ }
190
+ </script>
191
+
192
+ {#if mapping}
193
+ <div class={cn('h-[250px] flex flex-col', classes)}>
194
+ {#if addRemove}
195
+ <div class="flex items-center gap-2 mb-2 min-w-0">
196
+ {#if addRemove.search}
197
+ <div class="flex-1 min-w-0">
198
+ <Combobox
199
+ bind:value={
200
+ () => selectedDropdownItem,
201
+ (val) => {
202
+ selectedDropdownItem = val;
203
+ handleAddFromDropdown();
204
+ }
205
+ }
206
+ mapping={searchMapping}
207
+ options={availableSearchOptions}
208
+ onSearchValueChanged={addRemove.search.onSearchValueChanged}
209
+ loading={addRemove.search.loading}
210
+ optionTypeName="account"
211
+ optionTypeNamePlural="accounts"
212
+ wrapperClasses="w-full"
213
+ popupWidthClasses="w-[300px]"
214
+ showValueInListEntries={true}
215
+ minCharactersForSearch={1}
216
+ {disabled}
217
+ />
218
+ </div>
219
+ <div class="flex items-center flex-shrink-0">
220
+ {#if !addOnSelect}
221
+ <Button variant="ghost" size="icon" class="w-6 h-7" disabled={disabled || !selectedDropdownItem} onclick={handleAddFromDropdown}>
222
+ <Plus />
223
+ </Button>
224
+ {/if}
225
+ <Button variant="ghost" size="icon" class="w-6 h-7" disabled={disabled || selectedValues.size === 0} onclick={handleRemoveSelectedItems}>
226
+ <Minus />
227
+ </Button>
228
+ </div>
229
+ {:else if addRemove.predefinedOptions && predefinedItems.length > 0 && predefinedMapping}
230
+ <div class="flex-1 min-w-0">
231
+ <SimpleDropdown
232
+ bind:value={
233
+ () => selectedDropdownItem,
234
+ (val) => {
235
+ selectedDropdownItem = val;
236
+ handleAddFromDropdown();
237
+ }
238
+ }
239
+ mapping={predefinedMapping}
240
+ options={availablePredefinedOptions}
241
+ optionTypeName={addRemove.predefinedOptions.optionTypeName || 'option'}
242
+ optionTypeNamePlural={addRemove.predefinedOptions.optionTypeNamePlural || 'options'}
243
+ wrapperClasses="w-full"
244
+ inputPlaceholder={addRemove.addValueInputPlaceholder}
245
+ searchPlaceholder={addRemove.allowArbitraryValues?.popupInputPlaceholder}
246
+ {disabled}
247
+ allowArbitraryValues={addRemove.allowArbitraryValues}
248
+ />
249
+ </div>
250
+ <div class="flex items-center flex-shrink-0">
251
+ {#if !addOnSelect}
252
+ <Button variant="ghost" size="icon" class="w-6 h-7" disabled={disabled || !selectedDropdownItem} onclick={handleAddFromDropdown}>
253
+ <Plus />
254
+ </Button>
255
+ {/if}
256
+ <Button variant="ghost" size="icon" class="w-6 h-7" disabled={disabled || selectedValues.size === 0} onclick={handleRemoveSelectedItems}>
257
+ <Minus />
258
+ </Button>
259
+ </div>
260
+ {:else}
261
+ <!-- Fallback to Input when no predefinedOptions or for arbitrary values only -->
262
+ <Input
263
+ bind:value={addValueInput}
264
+ type="text"
265
+ placeholder={addRemove.addValueInputPlaceholder}
266
+ {disabled}
267
+ onkeydown={(e) => {
268
+ if (
269
+ e.key === 'Enter' &&
270
+ (addRemove.triggerAddOnEnter || addOnSelect) &&
271
+ addRemove.allowArbitraryValues &&
272
+ addRemove.addItem &&
273
+ addValueInput.trim().length > 0
274
+ ) {
275
+ addRemove.addItem(addRemove.allowArbitraryValues.convertValueToType(addValueInput));
276
+ addValueInput = ''; // Clear input after adding
277
+ }
278
+ }}
279
+ />
280
+ <div class="flex items-center">
281
+ <Button
282
+ variant="ghost"
283
+ size="icon"
284
+ class="w-6 h-7"
285
+ disabled={disabled || addValueInput.trim().length === 0}
286
+ onclick={() => {
287
+ if (addRemove.allowArbitraryValues && addRemove.addItem && addValueInput.trim().length > 0) {
288
+ addRemove.addItem(addRemove.allowArbitraryValues.convertValueToType(addValueInput));
289
+ addValueInput = ''; // Clear input after adding
290
+ }
291
+ }}><Plus /></Button
292
+ >
293
+ <Button variant="ghost" size="icon" class="w-6 h-7" disabled={disabled || selectedValues.size === 0} onclick={handleRemoveSelectedItems}><Minus /></Button>
294
+ </div>
295
+ {/if}
296
+ </div>
297
+ {/if}
298
+ <Command.Root class="border rounded-md">
299
+ <Command.Empty class="text-sm text-muted-foreground p-4">{emptyMessage}</Command.Empty>
300
+ <Command.List class="max-h-48 overflow-auto">
301
+ {#each items as item}
302
+ <Command.Item
303
+ value={getValue(item)}
304
+ class={cn(
305
+ 'flex items-start gap-2 px-2 py-2',
306
+ disabled ? 'cursor-not-allowed opacity-50' : effectiveAllowSelection ? 'cursor-pointer' : 'cursor-default',
307
+ (getSecondaryLabel(item) || showValueInListEntries) && 'py-2.5 min-h-[3rem]',
308
+ effectiveAllowSelection && selectedValues.has(getValue(item))
309
+ ? 'bg-accent aria-selected:bg-accent'
310
+ : effectiveAllowSelection
311
+ ? 'aria-selected:bg-transparent hover:bg-gray-50'
312
+ : 'aria-selected:bg-transparent'
313
+ )}
314
+ onSelect={() => !disabled && effectiveAllowSelection && toggleSelection(getValue(item))}
315
+ >
316
+ <div class="flex-1 min-w-0">
317
+ <!-- Primary label -->
318
+ <div class="font-medium text-sm leading-tight truncate">
319
+ {getLabel(item)}
320
+ </div>
321
+
322
+ <!-- Secondary and tertiary info in a row -->
323
+ {#if getSecondaryLabel(item) || showValueInListEntries}
324
+ <div class="flex items-center gap-2 mt-0.5">
325
+ {#if getSecondaryLabel(item)}
326
+ <span class="text-xs text-muted-foreground truncate flex-shrink-0">
327
+ {getSecondaryLabel(item)}
328
+ </span>
329
+ {/if}
330
+ {#if showValueInListEntries}
331
+ <!-- Separator dot if we have both secondary label and value -->
332
+ {#if getSecondaryLabel(item)}
333
+ <span class="text-xs text-muted-foreground/50">•</span>
334
+ {/if}
335
+ <span class="text-xs text-muted-foreground/70 font-mono truncate">
336
+ {getValue(item)}
337
+ </span>
338
+ {/if}
339
+ </div>
340
+ {/if}
341
+ </div>
342
+ </Command.Item>
343
+ {/each}
344
+ </Command.List>
345
+ </Command.Root>
346
+ </div>
347
+ {:else}
348
+ <div class="text-sm text-muted-foreground p-4">Error: List component requires a mapping configuration</div>
349
+ {/if}
@@ -0,0 +1,87 @@
1
+ .carta-theme__github {
2
+ // Core styles for light theme
3
+ $background: #ffffff; // White background
4
+ $background-light: #f6f8fa; // Slightly gray background for toolbar
5
+ $border: #d0d7de; // GitHub light gray border
6
+ $accent: #0969da; // GitHub blue accent
7
+
8
+ &.carta-editor {
9
+ background-color: $background;
10
+ border: 1px solid $border;
11
+ border-radius: 0.5rem;
12
+
13
+ &:focus-within {
14
+ outline: 3px solid #cde4fe;
15
+ }
16
+
17
+ .carta-wrapper {
18
+ padding: 1rem;
19
+ flex-grow: 1;
20
+ color: #24292f; // GitHub text gray/black
21
+ }
22
+
23
+ .carta-font-code {
24
+ font-family: 'Fira Code', monospace;
25
+ caret-color: black;
26
+ font-size: 0.825rem;
27
+ color: #24292f;
28
+ }
29
+
30
+ .carta-toolbar {
31
+ height: 2.5rem;
32
+ background-color: $background-light;
33
+
34
+ border-top-left-radius: 0.5rem;
35
+ border-top-right-radius: 0.5rem;
36
+
37
+ .carta-icon {
38
+ width: 2rem;
39
+ height: 2rem;
40
+
41
+ &:hover {
42
+ color: black;
43
+ background-color: #eaeef2;
44
+ }
45
+ }
46
+ }
47
+
48
+ .carta-toolbar-left button,
49
+ .carta-toolbar-right,
50
+ .carta-filler {
51
+ border-bottom: 1px solid $border;
52
+ }
53
+
54
+ .carta-toolbar-left {
55
+ & > * {
56
+ padding-left: 1rem;
57
+ padding-right: 1rem;
58
+ font-size: 0.775rem;
59
+ }
60
+
61
+ button {
62
+ height: 100%;
63
+ }
64
+
65
+ .carta-active {
66
+ background-color: $background;
67
+ color: black;
68
+
69
+ border-right: 1px solid $border;
70
+ border-bottom: 1px solid $background;
71
+
72
+ &:not(:first-child) {
73
+ border-left: 1px solid $border;
74
+ }
75
+ }
76
+ }
77
+
78
+ .carta-toolbar-right {
79
+ padding-right: 12px;
80
+ }
81
+ }
82
+ }
83
+
84
+ html.light .carta-theme__github .shiki,
85
+ html.light .carta-theme__github .shiki span {
86
+ color: var(--shiki-light) !important;
87
+ }
@@ -0,0 +1 @@
1
+ export { default as MarkdownEditor } from './markdown-editor.svelte';
@@ -0,0 +1,44 @@
1
+ <script lang="ts">
2
+ import { code } from '@cartamd/plugin-code';
3
+ import { Carta, MarkdownEditor } from 'carta-md';
4
+ import './github.scss';
5
+
6
+ interface Props {
7
+ value: string;
8
+ placeholder?: string;
9
+ }
10
+
11
+ let initialized = $state(false);
12
+
13
+ let { value = $bindable(), placeholder = 'Start writing...' }: Props = $props();
14
+ let carta: Carta | undefined = $state(undefined);
15
+
16
+ $effect(() => {
17
+ if (!initialized) {
18
+ carta = new Carta({
19
+ sanitizer: false,
20
+ extensions: [code()],
21
+ rendererDebounce: 100, // Shorter delay to reduce timing issues
22
+ });
23
+ initialized = true;
24
+ }
25
+ });
26
+
27
+ // Add cleanup effect
28
+ $effect(() => {
29
+ return () => {
30
+ // Hack to fix a bug in carta where it tries to render once after unmounting
31
+ if (carta) {
32
+ const dummyContainer = document.createElement('div');
33
+ dummyContainer.style.display = 'none';
34
+ // This redirects carta's internal renderer to the dummy container
35
+ // so any pending async operations won't crash on destroyed DOM
36
+ carta.$setRenderer(dummyContainer);
37
+ }
38
+ };
39
+ });
40
+ </script>
41
+
42
+ {#if carta}
43
+ <MarkdownEditor bind:value mode="tabs" theme="github" {carta} {placeholder} />
44
+ {/if}
@@ -0,0 +1 @@
1
+ export { default as PermanentToast } from './permanent-toast.svelte';
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ import CircleAlert from '$icons/lucide/circle-alert';
3
+ import Info from '$icons/lucide/info';
4
+ import TriangleAlert from '$icons/lucide/triangle-alert';
5
+ import type { Snippet } from 'svelte';
6
+
7
+ interface Props {
8
+ type: 'info' | 'warning' | 'error';
9
+ children?: Snippet<[]>;
10
+ }
11
+
12
+ const { type, children }: Props = $props();
13
+
14
+ const typeConfig = {
15
+ info: {
16
+ icon: Info,
17
+ bgColor: 'bg-blue-50',
18
+ iconColor: 'text-blue-500',
19
+ borderColor: 'border-blue-100',
20
+ },
21
+ warning: {
22
+ icon: TriangleAlert,
23
+ bgColor: 'bg-yellow-50',
24
+ iconColor: 'text-yellow-500',
25
+ borderColor: 'border-yellow-100',
26
+ },
27
+ error: {
28
+ icon: CircleAlert,
29
+ bgColor: 'bg-red-50',
30
+ iconColor: 'text-red-500',
31
+ borderColor: 'border-red-100',
32
+ },
33
+ } as const;
34
+
35
+ const config = typeConfig[type];
36
+ </script>
37
+
38
+ <div class={`py-2 ${config.bgColor} border-b ${config.borderColor}`}>
39
+ <div class="ml-4 flex items-center space-x-3">
40
+ {#if config.icon}
41
+ <config.icon class="w-5 h-5 {config.iconColor}" />
42
+ {/if}
43
+ <div class="text-sm text-gray-700">
44
+ {@render children?.()}
45
+ </div>
46
+ </div>
47
+ </div>
@@ -0,0 +1 @@
1
+ export { default as PikaAlert } from './pika-alert.svelte';
@@ -0,0 +1,53 @@
1
+ <script lang="ts">
2
+ import Button from '../../shadcn/button/button.svelte';
3
+ import * as Dialog from '../../shadcn/dialog';
4
+ interface Props {
5
+ title: string;
6
+ description: string;
7
+ open: boolean;
8
+ ok?: {
9
+ label?: string;
10
+ onClick: () => void;
11
+ };
12
+ cancel?: {
13
+ showCancel: boolean;
14
+ label?: string;
15
+ onClick: () => void;
16
+ };
17
+ }
18
+
19
+ let { title, description, ok, cancel, open = $bindable() }: Props = $props();
20
+
21
+ function handleCancel() {
22
+ open = false;
23
+ if (cancel?.onClick) {
24
+ cancel.onClick();
25
+ }
26
+ }
27
+
28
+ function handleOk() {
29
+ open = false;
30
+ if (ok?.onClick) {
31
+ ok.onClick();
32
+ }
33
+ }
34
+ </script>
35
+
36
+ <Dialog.Root bind:open>
37
+ <Dialog.Content>
38
+ <Dialog.Header>
39
+ <Dialog.Title>{title}</Dialog.Title>
40
+ </Dialog.Header>
41
+ <div class="pb-2 pt-2 max-w-3xl mx-auto w-full">
42
+ <div class="flex flex-col gap-6">
43
+ <p class="text-sm text-muted-foreground">{description}</p>
44
+ </div>
45
+ </div>
46
+ <Dialog.Footer>
47
+ {#if cancel?.showCancel}
48
+ <Button variant="outline" onclick={handleCancel}>{cancel?.label ?? 'Cancel'}</Button>
49
+ {/if}
50
+ <Button variant="default" onclick={handleOk}>{ok?.label ?? 'OK'}</Button>
51
+ </Dialog.Footer>
52
+ </Dialog.Content>
53
+ </Dialog.Root>
@@ -0,0 +1 @@
1
+ export { default as PikaBadge, pikaBadgeVariants, type PikaBadgeVariant } from './pika-badge.svelte';
@@ -0,0 +1,61 @@
1
+ <script lang="ts" module>
2
+ import { type VariantProps, tv } from 'tailwind-variants';
3
+ export const pikaBadgeVariants = tv({
4
+ base: 'focus:ring-ring inline-flex select-none items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2',
5
+ variants: {
6
+ variant: {
7
+ default: 'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent shadow',
8
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent',
9
+ destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent shadow',
10
+ success: 'bg-green-700 text-white hover:bg-green-700 border-transparent shadow',
11
+ outline: 'text-foreground'
12
+ }
13
+ },
14
+ defaultVariants: {
15
+ variant: 'default'
16
+ }
17
+ });
18
+
19
+ export type PikaBadgeVariant = VariantProps<typeof pikaBadgeVariants>['variant'];
20
+ </script>
21
+
22
+ <script lang="ts">
23
+ import PopupHelp from '../../pika/popup-help/popup-help.svelte';
24
+ import { cn } from '../../shadcn/utils.js';
25
+ import type { WithElementRef } from 'bits-ui';
26
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
27
+
28
+ let {
29
+ ref = $bindable(null),
30
+ href,
31
+ class: className,
32
+ variant = 'default',
33
+ children,
34
+ help,
35
+ helpStyles,
36
+ ...restProps
37
+ }: WithElementRef<HTMLAnchorAttributes> & {
38
+ variant?: PikaBadgeVariant;
39
+ help?: string;
40
+ helpStyles?: string;
41
+ } = $props();
42
+
43
+ // Split help text by line feeds to create paragraphs
44
+ const helpParagraphs = $derived(help ? help.split('\n') : []);
45
+ </script>
46
+
47
+ <svelte:element this={href ? 'a' : 'span'} bind:this={ref} {href} class={cn(pikaBadgeVariants({ variant }), help ? 'space-x-1' : '', className)} {...restProps}>
48
+ {@render children?.()}
49
+
50
+ {#if help}
51
+ <div class="ml-2 items-center flex">
52
+ <PopupHelp popoverClasses={`max-w-[400px] ${helpStyles ? helpStyles : ''}`}>
53
+ <div class="text-xs space-y-2 text-muted-foreground">
54
+ {#each helpParagraphs as paragraph}
55
+ <p>{paragraph}</p>
56
+ {/each}
57
+ </div>
58
+ </PopupHelp>
59
+ </div>
60
+ {/if}
61
+ </svelte:element>
@@ -0,0 +1,7 @@
1
+ export { default as PikaTableCheckbox } from './pika-table-checkbox.svelte';
2
+ export { default as PikaTableColumnHeader } from './pika-table-column-header.svelte';
3
+ export { default as PikaTableFacetedFilter } from './pika-table-faceted-filter.svelte';
4
+ export { default as PikaTablePagination } from './pika-table-pagination.svelte';
5
+ export { default as PikaTableRowActions } from './pika-table-row-actions.svelte';
6
+ export { default as PikaTableToolbar } from './pika-table-toolbar.svelte';
7
+ export { default as PikaTableViewOptions } from './pika-table-view-options.svelte';
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+
4
+ let { children, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
5
+ </script>
6
+
7
+ <div {...restProps}>
8
+ {@render children?.()}
9
+ </div>