@rkosafo/cai.components 0.0.1 → 0.0.3

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 (255) hide show
  1. package/dist/baseEditor/index.svelte +32 -0
  2. package/dist/baseEditor/index.svelte.d.ts +18 -0
  3. package/dist/builders/filters/FilterBuilder.svelte +638 -0
  4. package/dist/builders/filters/FilterBuilder.svelte.d.ts +4 -0
  5. package/dist/builders/filters/index.d.ts +1 -0
  6. package/dist/builders/filters/index.js +1 -0
  7. package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -0
  8. package/dist/forms/FormCheckbox/FormCheckbox.svelte.d.ts +4 -0
  9. package/dist/forms/FormCheckbox/index.d.ts +1 -0
  10. package/dist/forms/FormCheckbox/index.js +1 -0
  11. package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -0
  12. package/dist/forms/FormDatepicker/FormDatepicker.svelte.d.ts +13 -0
  13. package/dist/forms/FormDatepicker/index.d.ts +1 -0
  14. package/dist/forms/FormDatepicker/index.js +1 -0
  15. package/dist/forms/FormInput/FormInput.svelte +87 -0
  16. package/dist/forms/FormInput/FormInput.svelte.d.ts +4 -0
  17. package/dist/forms/FormInput/index.d.ts +1 -0
  18. package/dist/forms/FormInput/index.js +1 -0
  19. package/dist/forms/FormRadio/FormRadio.svelte +53 -0
  20. package/dist/forms/FormRadio/FormRadio.svelte.d.ts +4 -0
  21. package/dist/forms/FormRadio/index.d.ts +1 -0
  22. package/dist/forms/FormRadio/index.js +1 -0
  23. package/dist/forms/FormSelect/FormSelect.svelte +86 -0
  24. package/dist/forms/FormSelect/FormSelect.svelte.d.ts +4 -0
  25. package/dist/forms/FormSelect/index.d.ts +1 -0
  26. package/dist/forms/FormSelect/index.js +1 -0
  27. package/dist/forms/FormTextarea/FormTextarea.svelte +77 -0
  28. package/dist/forms/FormTextarea/FormTextarea.svelte.d.ts +4 -0
  29. package/dist/forms/FormTextarea/index.d.ts +1 -0
  30. package/dist/forms/FormTextarea/index.js +1 -0
  31. package/dist/forms/checkbox/Checkbox.svelte +82 -0
  32. package/dist/forms/checkbox/Checkbox.svelte.d.ts +4 -0
  33. package/dist/forms/checkbox/CheckboxButton.svelte +92 -0
  34. package/dist/forms/checkbox/CheckboxButton.svelte.d.ts +18 -0
  35. package/dist/forms/checkbox/index.d.ts +3 -0
  36. package/dist/forms/checkbox/index.js +3 -0
  37. package/dist/forms/checkbox/theme.d.ts +317 -0
  38. package/dist/forms/checkbox/theme.js +113 -0
  39. package/dist/forms/datepicker/Datepicker.svelte +706 -0
  40. package/dist/forms/datepicker/Datepicker.svelte.d.ts +41 -0
  41. package/dist/forms/datepicker/index.d.ts +2 -0
  42. package/dist/forms/datepicker/index.js +2 -0
  43. package/dist/forms/datepicker/theme.d.ts +385 -0
  44. package/dist/forms/datepicker/theme.js +56 -0
  45. package/dist/forms/form/Form.svelte +69 -0
  46. package/dist/forms/form/Form.svelte.d.ts +6 -0
  47. package/dist/forms/form/index.d.ts +2 -0
  48. package/dist/forms/form/index.js +2 -0
  49. package/dist/forms/input/Input.svelte +363 -0
  50. package/dist/forms/input/Input.svelte.d.ts +4 -0
  51. package/dist/forms/input/index.d.ts +4 -0
  52. package/dist/forms/input/index.js +5 -0
  53. package/dist/forms/input/theme.d.ts +301 -0
  54. package/dist/forms/input/theme.js +100 -0
  55. package/dist/forms/label/Label.svelte +38 -0
  56. package/dist/forms/label/Label.svelte.d.ts +15 -0
  57. package/dist/forms/label/index.d.ts +2 -0
  58. package/dist/forms/label/index.js +2 -0
  59. package/dist/forms/label/theme.d.ts +75 -0
  60. package/dist/forms/label/theme.js +29 -0
  61. package/dist/forms/radio/Radio.svelte +48 -0
  62. package/dist/forms/radio/Radio.svelte.d.ts +25 -0
  63. package/dist/forms/radio/RadioButton.svelte +22 -0
  64. package/dist/forms/radio/RadioButton.svelte.d.ts +25 -0
  65. package/dist/forms/radio/index.d.ts +3 -0
  66. package/dist/forms/radio/index.js +3 -0
  67. package/dist/forms/radio/theme.d.ts +290 -0
  68. package/dist/forms/radio/theme.js +95 -0
  69. package/dist/forms/select/Select.svelte +50 -0
  70. package/dist/forms/select/Select.svelte.d.ts +4 -0
  71. package/dist/forms/select/index.d.ts +1 -0
  72. package/dist/forms/select/index.js +1 -0
  73. package/dist/forms/textarea/Textarea.svelte +165 -0
  74. package/dist/forms/textarea/Textarea.svelte.d.ts +4 -0
  75. package/dist/forms/textarea/index.d.ts +2 -0
  76. package/dist/forms/textarea/index.js +2 -0
  77. package/dist/forms/textarea/theme.d.ts +100 -0
  78. package/dist/forms/textarea/theme.js +35 -0
  79. package/dist/index.d.ts +42 -2
  80. package/dist/index.js +42 -2
  81. package/dist/layout/TF/Content/Content.svelte +28 -0
  82. package/dist/layout/TF/Content/Content.svelte.d.ts +8 -0
  83. package/dist/layout/TF/Content/index.d.ts +1 -0
  84. package/dist/layout/TF/Content/index.js +1 -0
  85. package/dist/layout/TF/Header/Header.svelte +159 -0
  86. package/dist/layout/TF/Header/Header.svelte.d.ts +21 -0
  87. package/dist/layout/TF/Header/index.d.ts +1 -0
  88. package/dist/layout/TF/Header/index.js +1 -0
  89. package/dist/layout/TF/Sidebar/Sidebar.svelte +74 -0
  90. package/dist/layout/TF/Sidebar/Sidebar.svelte.d.ts +23 -0
  91. package/dist/layout/TF/Sidebar/index.d.ts +1 -0
  92. package/dist/layout/TF/Sidebar/index.js +1 -0
  93. package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -0
  94. package/dist/layout/TF/Wrapper/Wrapper.svelte.d.ts +8 -0
  95. package/dist/layout/TF/Wrapper/index.d.ts +1 -0
  96. package/dist/layout/TF/Wrapper/index.js +1 -0
  97. package/dist/layout/TF/index.d.ts +5 -0
  98. package/dist/layout/TF/index.js +5 -0
  99. package/dist/themes/ThemeProvider.svelte +20 -0
  100. package/dist/themes/ThemeProvider.svelte.d.ts +9 -0
  101. package/dist/themes/index.d.ts +7 -0
  102. package/dist/themes/index.js +1 -0
  103. package/dist/themes/themeUtils.d.ts +24 -0
  104. package/dist/themes/themeUtils.js +74 -0
  105. package/dist/themes/themes.d.ts +18 -0
  106. package/dist/themes/themes.js +18 -0
  107. package/dist/types/index.d.ts +755 -0
  108. package/dist/types/index.js +1 -0
  109. package/dist/typography/heading/Heading.svelte +35 -0
  110. package/dist/typography/heading/Heading.svelte.d.ts +10 -0
  111. package/dist/typography/heading/index.d.ts +2 -0
  112. package/dist/typography/heading/index.js +2 -0
  113. package/dist/typography/heading/theme.d.ts +30 -0
  114. package/dist/typography/heading/theme.js +17 -0
  115. package/dist/ui/accordion/Accordion.svelte +49 -0
  116. package/dist/ui/accordion/Accordion.svelte.d.ts +4 -0
  117. package/dist/ui/accordion/AccordionItem.svelte +173 -0
  118. package/dist/ui/accordion/AccordionItem.svelte.d.ts +4 -0
  119. package/dist/ui/accordion/index.d.ts +3 -0
  120. package/dist/ui/accordion/index.js +3 -0
  121. package/dist/ui/accordion/theme.d.ts +96 -0
  122. package/dist/ui/accordion/theme.js +59 -0
  123. package/dist/ui/alert/Alert.svelte +83 -0
  124. package/dist/ui/alert/Alert.svelte.d.ts +5 -0
  125. package/dist/ui/alert/index.d.ts +2 -0
  126. package/dist/ui/alert/index.js +2 -0
  127. package/dist/ui/alert/theme.d.ts +108 -0
  128. package/dist/ui/alert/theme.js +149 -0
  129. package/dist/ui/alertDialog/AlertDialog.svelte +40 -0
  130. package/dist/ui/alertDialog/AlertDialog.svelte.d.ts +4 -0
  131. package/dist/ui/alertDialog/index.d.ts +1 -0
  132. package/dist/ui/alertDialog/index.js +1 -0
  133. package/dist/ui/avatar/Avatar.svelte +77 -0
  134. package/dist/ui/avatar/Avatar.svelte.d.ts +4 -0
  135. package/dist/ui/avatar/index.d.ts +2 -0
  136. package/dist/ui/avatar/index.js +2 -0
  137. package/dist/ui/avatar/theme.d.ts +63 -0
  138. package/dist/ui/avatar/theme.js +31 -0
  139. package/dist/ui/buttons/Button.svelte +102 -0
  140. package/dist/ui/buttons/Button.svelte.d.ts +4 -0
  141. package/dist/ui/buttons/GradientButton.svelte +59 -0
  142. package/dist/ui/buttons/GradientButton.svelte.d.ts +4 -0
  143. package/dist/ui/buttons/index.d.ts +3 -0
  144. package/dist/ui/buttons/index.js +3 -0
  145. package/dist/ui/buttons/theme.d.ts +704 -0
  146. package/dist/ui/buttons/theme.js +332 -0
  147. package/dist/ui/datatable/Datatable.svelte +516 -0
  148. package/dist/ui/datatable/Datatable.svelte.d.ts +5 -0
  149. package/dist/ui/datatable/index.d.ts +2 -0
  150. package/dist/ui/datatable/index.js +2 -0
  151. package/dist/ui/drawer/Drawer.svelte +280 -0
  152. package/dist/ui/drawer/Drawer.svelte.d.ts +37 -0
  153. package/dist/ui/drawer/index.d.ts +2 -0
  154. package/dist/ui/drawer/index.js +2 -0
  155. package/dist/ui/drawer/theme.d.ts +211 -0
  156. package/dist/ui/drawer/theme.js +46 -0
  157. package/dist/ui/dropdown/Dropdown.svelte +36 -0
  158. package/dist/ui/dropdown/Dropdown.svelte.d.ts +4 -0
  159. package/dist/ui/dropdown/DropdownDivider.svelte +11 -0
  160. package/dist/ui/dropdown/DropdownDivider.svelte.d.ts +4 -0
  161. package/dist/ui/dropdown/DropdownGroup.svelte +14 -0
  162. package/dist/ui/dropdown/DropdownGroup.svelte.d.ts +4 -0
  163. package/dist/ui/dropdown/DropdownHeader.svelte +14 -0
  164. package/dist/ui/dropdown/DropdownHeader.svelte.d.ts +4 -0
  165. package/dist/ui/dropdown/DropdownItem.svelte +52 -0
  166. package/dist/ui/dropdown/DropdownItem.svelte.d.ts +4 -0
  167. package/dist/ui/dropdown/index.d.ts +6 -0
  168. package/dist/ui/dropdown/index.js +6 -0
  169. package/dist/ui/dropdown/theme.d.ts +55 -0
  170. package/dist/ui/dropdown/theme.js +20 -0
  171. package/dist/ui/footer/Footer.svelte +15 -0
  172. package/dist/ui/footer/Footer.svelte.d.ts +4 -0
  173. package/dist/ui/footer/FooterBrand.svelte +37 -0
  174. package/dist/ui/footer/FooterBrand.svelte.d.ts +4 -0
  175. package/dist/ui/footer/FooterCopyright.svelte +45 -0
  176. package/dist/ui/footer/FooterCopyright.svelte.d.ts +4 -0
  177. package/dist/ui/footer/FooterIcon.svelte +22 -0
  178. package/dist/ui/footer/FooterIcon.svelte.d.ts +4 -0
  179. package/dist/ui/footer/FooterLink.svelte +33 -0
  180. package/dist/ui/footer/FooterLink.svelte.d.ts +4 -0
  181. package/dist/ui/footer/FooterLinkGroup.svelte +13 -0
  182. package/dist/ui/footer/FooterLinkGroup.svelte.d.ts +4 -0
  183. package/dist/ui/footer/index.d.ts +7 -0
  184. package/dist/ui/footer/index.js +7 -0
  185. package/dist/ui/footer/theme.d.ts +137 -0
  186. package/dist/ui/footer/theme.js +39 -0
  187. package/dist/ui/indicator/Indicator.svelte +42 -0
  188. package/dist/ui/indicator/Indicator.svelte.d.ts +4 -0
  189. package/dist/ui/indicator/index.d.ts +2 -0
  190. package/dist/ui/indicator/index.js +2 -0
  191. package/dist/ui/indicator/theme.d.ts +177 -0
  192. package/dist/ui/indicator/theme.js +114 -0
  193. package/dist/ui/modal/Modal.svelte +265 -0
  194. package/dist/ui/modal/Modal.svelte.d.ts +38 -0
  195. package/dist/ui/modal/index.d.ts +2 -0
  196. package/dist/ui/modal/index.js +2 -0
  197. package/dist/ui/modal/theme.d.ts +190 -0
  198. package/dist/ui/modal/theme.js +41 -0
  199. package/dist/ui/notificationList/NotificationList.svelte +123 -0
  200. package/dist/ui/notificationList/NotificationList.svelte.d.ts +25 -0
  201. package/dist/ui/notificationList/index.d.ts +1 -0
  202. package/dist/ui/notificationList/index.js +1 -0
  203. package/dist/ui/pageLoader/PageLoader.svelte +10 -0
  204. package/dist/ui/pageLoader/PageLoader.svelte.d.ts +4 -0
  205. package/dist/ui/pageLoader/index.d.ts +1 -0
  206. package/dist/ui/pageLoader/index.js +1 -0
  207. package/dist/ui/paginate/Paginate.svelte +96 -0
  208. package/dist/ui/paginate/Paginate.svelte.d.ts +4 -0
  209. package/dist/ui/paginate/index.d.ts +1 -0
  210. package/dist/ui/paginate/index.js +1 -0
  211. package/dist/ui/tab/Tab.svelte +65 -0
  212. package/dist/ui/tab/Tab.svelte.d.ts +4 -0
  213. package/dist/ui/tab/index.d.ts +2 -0
  214. package/dist/ui/tab/index.js +2 -0
  215. package/dist/ui/tab/theme.d.ts +135 -0
  216. package/dist/ui/tab/theme.js +83 -0
  217. package/dist/ui/table/Table.svelte +385 -0
  218. package/dist/ui/table/Table.svelte.d.ts +4 -0
  219. package/dist/ui/table/index.d.ts +1 -0
  220. package/dist/ui/table/index.js +1 -0
  221. package/dist/ui/tableLoader/TableLoader.svelte +24 -0
  222. package/dist/ui/tableLoader/TableLoader.svelte.d.ts +13 -0
  223. package/dist/ui/tableLoader/index.d.ts +1 -0
  224. package/dist/ui/tableLoader/index.js +1 -0
  225. package/dist/ui/toolbar/Toolbar.svelte +59 -0
  226. package/dist/ui/toolbar/Toolbar.svelte.d.ts +17 -0
  227. package/dist/ui/toolbar/ToolbarButton.svelte +56 -0
  228. package/dist/ui/toolbar/ToolbarButton.svelte.d.ts +17 -0
  229. package/dist/ui/toolbar/ToolbarGroup.svelte +43 -0
  230. package/dist/ui/toolbar/ToolbarGroup.svelte.d.ts +16 -0
  231. package/dist/ui/toolbar/index.d.ts +4 -0
  232. package/dist/ui/toolbar/index.js +4 -0
  233. package/dist/ui/toolbar/theme.d.ts +320 -0
  234. package/dist/ui/toolbar/theme.js +155 -0
  235. package/dist/utils/Popper.svelte +257 -0
  236. package/dist/utils/Popper.svelte.d.ts +4 -0
  237. package/dist/utils/action.d.ts +16 -0
  238. package/dist/utils/action.js +107 -0
  239. package/dist/utils/closeButton/CloseButton.svelte +88 -0
  240. package/dist/utils/closeButton/CloseButton.svelte.d.ts +12 -0
  241. package/dist/utils/closeButton/index.d.ts +2 -0
  242. package/dist/utils/closeButton/index.js +2 -0
  243. package/dist/utils/closeButton/theme.d.ts +100 -0
  244. package/dist/utils/closeButton/theme.js +69 -0
  245. package/dist/utils/dismissable.d.ts +9 -0
  246. package/dist/utils/dismissable.js +16 -0
  247. package/dist/utils/index.d.ts +8 -0
  248. package/dist/utils/index.js +35 -0
  249. package/dist/utils/paginate.svelte.d.ts +22 -0
  250. package/dist/utils/paginate.svelte.js +167 -0
  251. package/dist/utils/singleSelection.svelte.d.ts +15 -0
  252. package/dist/utils/singleSelection.svelte.js +49 -0
  253. package/dist/utils/svelte-legos.d.ts +7 -0
  254. package/dist/utils/svelte-legos.js +14 -0
  255. package/package.json +24 -2
@@ -0,0 +1,257 @@
1
+ <script lang="ts">
2
+ import type { Coords, Middleware, Placement, Strategy } from '@floating-ui/dom';
3
+ import * as dom from '@floating-ui/dom';
4
+ // import Arrow from './Arrow.svelte';
5
+ import { fade } from 'svelte/transition';
6
+ import { sineIn } from 'svelte/easing';
7
+ import clsx from 'clsx';
8
+ import type { ParamsType, PopperProps, TriggeredToggleEvent } from '../types/index.js';
9
+
10
+ let {
11
+ triggeredBy,
12
+ triggerDelay = 200,
13
+ trigger = 'click',
14
+ placement = 'top',
15
+ offset = 8,
16
+ arrow = false,
17
+ yOnly = false,
18
+ strategy = 'absolute',
19
+ reference,
20
+ middlewares = [dom.flip(), dom.shift()],
21
+ onbeforetoggle: _onbeforetoggle,
22
+ ontoggle: _ontoggle,
23
+ class: className = '',
24
+ arrowClass = '',
25
+ isOpen = $bindable(false),
26
+ transitionParams,
27
+ transition = fade,
28
+ children,
29
+ ...restProps
30
+ }: PopperProps = $props();
31
+
32
+ let focusable: boolean = true;
33
+ let clickable: boolean = $derived(trigger === 'click');
34
+ let hoverable: boolean = $derived(trigger === 'hover');
35
+
36
+ let popover: HTMLElement | null = $state(null);
37
+ let invoker: HTMLElement | null = null;
38
+ let referenceElement: HTMLElement | null = null;
39
+ let triggerEls: HTMLElement[] = [];
40
+ let arrowParams: { placement: Placement; cords: Partial<Coords>; strategy: Strategy } = $state({
41
+ placement,
42
+ cords: { x: 0, y: 0 },
43
+ strategy
44
+ });
45
+
46
+ const paramsDefault = { duration: 100, easing: sineIn };
47
+ const paramsOptions = $derived(transitionParams ?? paramsDefault);
48
+
49
+ const px = (n: number | undefined) => (n ? `${n}px` : '');
50
+
51
+ function updatePopoverPosition() {
52
+ if (!invoker || !popover) {
53
+ return;
54
+ }
55
+
56
+ const arrowEl: HTMLElement | null = popover.querySelector('.popover-arrow');
57
+
58
+ let middleware: Middleware[] = [...middlewares, dom.offset(offset)];
59
+ if (arrowEl) middleware.push(dom.arrow({ element: arrowEl }));
60
+
61
+ return dom
62
+ .computePosition(referenceElement ?? invoker, popover, { placement, middleware, strategy })
63
+ .then(({ x, y, middlewareData: { arrow }, placement: pl, strategy }) => {
64
+ if (popover) {
65
+ Object.assign(popover.style, {
66
+ position: strategy,
67
+ left: yOnly ? '0' : px(x),
68
+ top: px(y)
69
+ });
70
+
71
+ if (arrow && arrowEl) {
72
+ arrowParams = { placement: pl, cords: { x: arrow.x, y: arrow.y }, strategy };
73
+ }
74
+ }
75
+ });
76
+ }
77
+
78
+ let isTriggered: boolean = false;
79
+
80
+ async function open_popover(ev: Event) {
81
+ // throttle
82
+ isTriggered = true;
83
+ await new Promise((resolve) => setTimeout(resolve, triggerDelay));
84
+ if (!isTriggered) {
85
+ return;
86
+ }
87
+
88
+ ev.preventDefault();
89
+
90
+ if (ev.target !== invoker && triggerEls.includes(ev.target as HTMLElement)) {
91
+ invoker = ev.target as HTMLElement;
92
+ // if (invoker) invoker.popoverTargetElement = popover;
93
+ isOpen = false;
94
+ await new Promise((resolve) => setTimeout(resolve, triggerDelay));
95
+ }
96
+
97
+ if (ev.type === 'mousedown') {
98
+ isOpen = !isOpen;
99
+ } else {
100
+ isOpen = true;
101
+ }
102
+ }
103
+
104
+ async function close_popover(ev: Event) {
105
+ // For click triggers, don't close on focusout events from inside the popover
106
+ if (trigger === 'click' && ev.type === 'focusout') {
107
+ const relatedTarget = (ev as FocusEvent).relatedTarget as HTMLElement;
108
+
109
+ // If focus is moving to somewhere inside the popover, don't close
110
+ if (popover && relatedTarget && popover.contains(relatedTarget)) {
111
+ return;
112
+ }
113
+
114
+ // If focus is moving to nowhere (like when clicking), don't close for click triggers
115
+ if (!relatedTarget) {
116
+ return;
117
+ }
118
+ }
119
+
120
+ isTriggered = false;
121
+ await new Promise((resolve) => setTimeout(resolve, triggerDelay));
122
+ if (isTriggered) {
123
+ return;
124
+ }
125
+
126
+ // if popover has focus don't close when leaving the invoker
127
+ if (ev?.type === 'mouseleave' && popover?.contains(popover.ownerDocument.activeElement)) {
128
+ return;
129
+ }
130
+ if (ev?.type === 'focusout' && popover?.contains(popover.ownerDocument.activeElement)) {
131
+ return;
132
+ }
133
+
134
+ isOpen = false;
135
+ }
136
+
137
+ let autoUpdateDestroy = () => {};
138
+
139
+ function on_before_toggle(ev: ToggleEvent) {
140
+ if (!invoker || !popover) return;
141
+
142
+ (ev as TriggeredToggleEvent).trigger = invoker;
143
+ _onbeforetoggle?.(ev as TriggeredToggleEvent);
144
+
145
+ // Floating UI instance when it's closed we need to keep a autoUpdate destroy function
146
+
147
+ if (ev.newState === 'open') {
148
+ autoUpdateDestroy = dom.autoUpdate(
149
+ referenceElement ?? invoker,
150
+ popover,
151
+ updatePopoverPosition
152
+ );
153
+ popover.ownerDocument.addEventListener('click', closeOnClickOutside);
154
+ popover.ownerDocument.addEventListener('keydown', closeOnEscape);
155
+ } else {
156
+ autoUpdateDestroy();
157
+ popover.ownerDocument.removeEventListener('click', closeOnClickOutside);
158
+ popover.ownerDocument.removeEventListener('keydown', closeOnEscape);
159
+ }
160
+ }
161
+
162
+ function on_toggle(ev: ToggleEvent) {
163
+ if (!invoker) return;
164
+
165
+ // Update isOpen value when popover state changes through other means
166
+ isOpen = ev.newState === 'open';
167
+
168
+ (ev as TriggeredToggleEvent).trigger = invoker;
169
+ _ontoggle?.(ev as TriggeredToggleEvent);
170
+ }
171
+
172
+ function set_triggers(node: HTMLElement) {
173
+ const events: [string, any, boolean][] = [
174
+ ['focusin', open_popover, focusable],
175
+ ['focusout', close_popover, focusable],
176
+ ['mousedown', open_popover, clickable],
177
+ ['mouseenter', open_popover, hoverable],
178
+ ['mouseleave', close_popover, hoverable]
179
+ ];
180
+
181
+ if (triggeredBy)
182
+ triggerEls = [...node.ownerDocument.querySelectorAll<HTMLElement>(triggeredBy)];
183
+ else if (node.previousElementSibling) triggerEls = [node.previousElementSibling as HTMLElement];
184
+ else if (node.parentElement) triggerEls = [node.parentElement];
185
+
186
+ if (!triggerEls.length) {
187
+ console.error('No triggers found.', triggeredBy);
188
+ return;
189
+ }
190
+
191
+ if (reference) referenceElement = node.ownerDocument.querySelector<HTMLElement>(reference);
192
+ invoker = triggerEls[0];
193
+
194
+ triggerEls.forEach((element: HTMLElement) => {
195
+ if (element.tabIndex < 0) element.tabIndex = 0; // trigger must be focusable
196
+ for (const [name, handler, cond] of events) if (cond) element.addEventListener(name, handler);
197
+ });
198
+
199
+ $effect(() => {
200
+ return () => {
201
+ triggerEls.forEach((element: HTMLElement) => {
202
+ for (const [name, handler, cond] of events)
203
+ if (cond) element.removeEventListener(name, handler);
204
+ });
205
+ };
206
+ });
207
+ }
208
+
209
+ function closeOnEscape(event: KeyboardEvent) {
210
+ if (event.key === 'Escape') {
211
+ isOpen = false;
212
+ }
213
+ }
214
+
215
+ function closeOnClickOutside(event: MouseEvent) {
216
+ if (!popover) {
217
+ return;
218
+ }
219
+
220
+ const clickPath = event.composedPath();
221
+
222
+ const isClickInsidePopover = clickPath.includes(popover);
223
+ const isClickOnTrigger = triggerEls.some((el) => clickPath.includes(el));
224
+
225
+ // Only close if click is outside both popover and trigger elements
226
+ if (!isClickInsidePopover && !isClickOnTrigger) {
227
+ close_popover(event);
228
+ isOpen = false;
229
+ }
230
+ }
231
+ </script>
232
+
233
+ <div use:set_triggers hidden></div>
234
+
235
+ {#if isOpen}
236
+ <div
237
+ popover="manual"
238
+ role="tooltip"
239
+ bind:this={popover}
240
+ class:overflow-visible={true}
241
+ onfocusout={close_popover}
242
+ onmouseleave={hoverable ? close_popover : undefined}
243
+ onmouseenter={hoverable ? open_popover : undefined}
244
+ onbeforetoggle={on_before_toggle}
245
+ ontoggle={on_toggle}
246
+ class={clsx(className)}
247
+ transition:transition={paramsOptions as ParamsType}
248
+ onintrostart={() => popover?.showPopover()}
249
+ onoutroend={() => popover?.hidePopover()}
250
+ {...restProps}
251
+ >
252
+ {@render children()}
253
+ <!-- {#if arrow}
254
+ <Arrow {...arrowParams} class={arrowClass} />
255
+ {/if} -->
256
+ </div>
257
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { PopperProps } from '../types/index.js';
2
+ declare const Popper: import("svelte").Component<PopperProps, {}, "isOpen">;
3
+ type Popper = ReturnType<typeof Popper>;
4
+ export default Popper;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Svelte action that traps focus within a DOM node and handles Escape key
3
+ * @param node - The DOM node to trap focus within
4
+ * @param options - Optional configuration object
5
+ * @returns An action object with destroy method
6
+ */
7
+ export declare function trapFocus(node: HTMLElement, options?: {
8
+ onEscape?: () => void;
9
+ isClosing?: boolean;
10
+ } | null): {
11
+ update(newOptions?: {
12
+ onEscape?: () => void;
13
+ isClosing?: boolean;
14
+ } | null): void;
15
+ destroy(): void;
16
+ };
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Svelte action that traps focus within a DOM node and handles Escape key
3
+ * @param node - The DOM node to trap focus within
4
+ * @param options - Optional configuration object
5
+ * @returns An action object with destroy method
6
+ */
7
+ export function trapFocus(node, options = {}) {
8
+ // If options is null, don't trap focus at all
9
+ if (options === null) {
10
+ return {
11
+ update(newOptions = {}) {
12
+ options = newOptions;
13
+ },
14
+ destroy() { }
15
+ };
16
+ }
17
+ const previous = document.activeElement;
18
+ // Track if we're currently closing via outside click
19
+ let isClosingViaOutsideClick = false;
20
+ // Create a flag to prevent re-focusing when focus is moved outside
21
+ let isFocusMovedOutside = false;
22
+ function focusable() {
23
+ return Array.from(node.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
24
+ }
25
+ function handleKeydown(event) {
26
+ if (event.key === "Tab" && options !== null) {
27
+ const current = document.activeElement;
28
+ const elements = focusable();
29
+ const first = elements.at(0);
30
+ const last = elements.at(-1);
31
+ if (event.shiftKey && current === first) {
32
+ last?.focus();
33
+ event.preventDefault();
34
+ }
35
+ if (!event.shiftKey && current === last) {
36
+ first?.focus();
37
+ event.preventDefault();
38
+ }
39
+ }
40
+ else if (event.key === "Escape" && options !== null && options.onEscape) {
41
+ event.preventDefault();
42
+ // Mark as closing via escape to prevent focus restoration
43
+ isClosingViaOutsideClick = true;
44
+ options.onEscape();
45
+ }
46
+ }
47
+ // Handler for when focus moves outside the trapped area
48
+ function handleFocusOut(event) {
49
+ // If focus is moving outside our node and not to one of our triggers
50
+ if (!node.contains(event.relatedTarget) && event.relatedTarget !== previous) {
51
+ isFocusMovedOutside = true;
52
+ }
53
+ }
54
+ // Initialize the action
55
+ function initialize() {
56
+ // Only add event listeners if options is not null
57
+ if (options !== null) {
58
+ // Check if we're currently in a closing state
59
+ isClosingViaOutsideClick = !!options.isClosing;
60
+ // Only auto-focus if not closing from outside click
61
+ if (!isClosingViaOutsideClick && !isFocusMovedOutside) {
62
+ const elements = focusable();
63
+ if (elements.length > 0) {
64
+ elements[0].focus();
65
+ }
66
+ }
67
+ node.addEventListener("keydown", handleKeydown);
68
+ node.addEventListener("focusout", handleFocusOut);
69
+ }
70
+ }
71
+ // Cleanup function
72
+ function cleanup() {
73
+ if (options !== null) {
74
+ node.removeEventListener("keydown", handleKeydown);
75
+ node.removeEventListener("focusout", handleFocusOut);
76
+ // Only restore focus if not closing via outside click and focus hasn't moved outside
77
+ if (!isClosingViaOutsideClick && !isFocusMovedOutside && previous) {
78
+ setTimeout(() => {
79
+ previous.focus({ preventScroll: true });
80
+ }, 0);
81
+ }
82
+ }
83
+ }
84
+ // Initialize on mount
85
+ initialize();
86
+ // Return the action object with update and destroy methods
87
+ return {
88
+ update(newOptions = {}) {
89
+ // Clean up existing listeners first
90
+ node.removeEventListener("keydown", handleKeydown);
91
+ node.removeEventListener("focusout", handleFocusOut);
92
+ // Update the closing state
93
+ if (newOptions && newOptions.isClosing !== undefined) {
94
+ isClosingViaOutsideClick = newOptions.isClosing;
95
+ }
96
+ options = newOptions;
97
+ // Reinitialize with new options
98
+ if (options !== null) {
99
+ node.addEventListener("keydown", handleKeydown);
100
+ node.addEventListener("focusout", handleFocusOut);
101
+ }
102
+ },
103
+ destroy() {
104
+ cleanup();
105
+ }
106
+ };
107
+ }
@@ -0,0 +1,88 @@
1
+ <script lang="ts" module>
2
+ export type CloseButtonProps = CloseButtonVariants &
3
+ AnchorButtonAttributes & {
4
+ onclick?: (ev: MouseEvent) => void;
5
+ name?: string;
6
+ ariaLabel?: string;
7
+ class?: string;
8
+ svgClass?: string;
9
+ };
10
+ </script>
11
+
12
+ <script lang="ts">
13
+ import clsx from 'clsx';
14
+ import { closeButton } from './index.js';
15
+ import { useDismiss } from '../dismissable.js';
16
+ import type { AnchorButtonAttributes } from '../../types/index.js';
17
+ import type { CloseButtonVariants } from './theme.js';
18
+
19
+ let {
20
+ children,
21
+ color = 'gray',
22
+ onclick: onclickorg,
23
+ name = 'Close',
24
+ ariaLabel,
25
+ size = 'md',
26
+ class: className,
27
+ svgClass,
28
+ ...restProps
29
+ }: CloseButtonProps = $props();
30
+
31
+ const { base, svg } = $derived(closeButton({ color, size }));
32
+
33
+ const context = useDismiss();
34
+
35
+ function onclick(event: MouseEvent) {
36
+ onclickorg?.(event);
37
+ if (event.defaultPrevented) return;
38
+ context?.dismiss?.(event);
39
+ }
40
+ </script>
41
+
42
+ {#if restProps.href === undefined}
43
+ <button
44
+ type="button"
45
+ {...restProps}
46
+ class={base({ class: clsx(className) })}
47
+ {onclick}
48
+ aria-label={ariaLabel ?? name}
49
+ >
50
+ {#if name}<span class="sr-only">{name}</span>{/if}
51
+ {#if children}
52
+ {@render children()}
53
+ {:else}
54
+ <svg
55
+ class={svg({ class: svgClass })}
56
+ fill="currentColor"
57
+ viewBox="0 0 20 20"
58
+ xmlns="http://www.w3.org/2000/svg"
59
+ >
60
+ <path
61
+ fill-rule="evenodd"
62
+ d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
63
+ clip-rule="evenodd"
64
+ />
65
+ </svg>
66
+ {/if}
67
+ </button>
68
+ {:else}
69
+ <a
70
+ {...restProps}
71
+ {onclick}
72
+ class={base({ class: clsx(className) })}
73
+ aria-label={ariaLabel ?? name}
74
+ >
75
+ {#if name}<span class="sr-only">{name}</span>{/if}
76
+ {#if children}
77
+ {@render children()}
78
+ {:else}
79
+ <svg class={svg()} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
80
+ <path
81
+ fill-rule="evenodd"
82
+ d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
83
+ clip-rule="evenodd"
84
+ />
85
+ </svg>
86
+ {/if}
87
+ </a>
88
+ {/if}
@@ -0,0 +1,12 @@
1
+ export type CloseButtonProps = CloseButtonVariants & AnchorButtonAttributes & {
2
+ onclick?: (ev: MouseEvent) => void;
3
+ name?: string;
4
+ ariaLabel?: string;
5
+ class?: string;
6
+ svgClass?: string;
7
+ };
8
+ import type { AnchorButtonAttributes } from '../../types/index.js';
9
+ import type { CloseButtonVariants } from './theme.js';
10
+ declare const CloseButton: import("svelte").Component<CloseButtonProps, {}, "">;
11
+ type CloseButton = ReturnType<typeof CloseButton>;
12
+ export default CloseButton;
@@ -0,0 +1,2 @@
1
+ export { closeButton } from './theme.js';
2
+ export { default as CloseButton } from './CloseButton.svelte';
@@ -0,0 +1,2 @@
1
+ export { closeButton } from './theme.js';
2
+ export { default as CloseButton } from './CloseButton.svelte';
@@ -0,0 +1,100 @@
1
+ import type { Classes } from "../../themes/themeUtils.js";
2
+ import { type VariantProps } from "tailwind-variants";
3
+ export type CloseButtonVariants = VariantProps<typeof closeButton> & Classes<typeof closeButton>;
4
+ export declare const closeButton: import("tailwind-variants").TVReturnType<{
5
+ color: {
6
+ primary: string;
7
+ secondary: string;
8
+ gray: string;
9
+ red: string;
10
+ orange: string;
11
+ amber: string;
12
+ yellow: string;
13
+ lime: string;
14
+ green: string;
15
+ emerald: string;
16
+ teal: string;
17
+ cyan: string;
18
+ sky: string;
19
+ blue: string;
20
+ indigo: string;
21
+ violet: string;
22
+ purple: string;
23
+ fuchsia: string;
24
+ pink: string;
25
+ rose: string;
26
+ none: string;
27
+ };
28
+ size: {
29
+ xs: string;
30
+ sm: string;
31
+ md: string;
32
+ lg: string;
33
+ };
34
+ }, {
35
+ svg: string;
36
+ }, "focus:outline-hidden whitespace-normal", {
37
+ color: {
38
+ primary: string;
39
+ secondary: string;
40
+ gray: string;
41
+ red: string;
42
+ orange: string;
43
+ amber: string;
44
+ yellow: string;
45
+ lime: string;
46
+ green: string;
47
+ emerald: string;
48
+ teal: string;
49
+ cyan: string;
50
+ sky: string;
51
+ blue: string;
52
+ indigo: string;
53
+ violet: string;
54
+ purple: string;
55
+ fuchsia: string;
56
+ pink: string;
57
+ rose: string;
58
+ none: string;
59
+ };
60
+ size: {
61
+ xs: string;
62
+ sm: string;
63
+ md: string;
64
+ lg: string;
65
+ };
66
+ }, {
67
+ svg: string;
68
+ }, import("tailwind-variants").TVReturnType<{
69
+ color: {
70
+ primary: string;
71
+ secondary: string;
72
+ gray: string;
73
+ red: string;
74
+ orange: string;
75
+ amber: string;
76
+ yellow: string;
77
+ lime: string;
78
+ green: string;
79
+ emerald: string;
80
+ teal: string;
81
+ cyan: string;
82
+ sky: string;
83
+ blue: string;
84
+ indigo: string;
85
+ violet: string;
86
+ purple: string;
87
+ fuchsia: string;
88
+ pink: string;
89
+ rose: string;
90
+ none: string;
91
+ };
92
+ size: {
93
+ xs: string;
94
+ sm: string;
95
+ md: string;
96
+ lg: string;
97
+ };
98
+ }, {
99
+ svg: string;
100
+ }, "focus:outline-hidden whitespace-normal", unknown, unknown, undefined>>;
@@ -0,0 +1,69 @@
1
+ import { tv } from "tailwind-variants";
2
+ export const closeButton = tv({
3
+ base: "focus:outline-hidden whitespace-normal",
4
+ variants: {
5
+ // primary, secondary, gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose
6
+ color: {
7
+ primary: "text-primary-500 focus:ring-primary-400 hover:bg-primary-200 dark:hover:bg-primary-800 dark:hover:text-primary-300",
8
+ secondary: "text-secondary-500 focus:ring-secondary-400 hover:bg-secondary-200 dark:hover:bg-secondary-800 dark:hover:text-secondary-300",
9
+ gray: "text-gray-500 focus:ring-gray-400 hover:bg-gray-200 dark:hover:bg-gray-800 dark:hover:text-gray-300",
10
+ red: "text-red-500 focus:ring-red-400 hover:bg-red-200 dark:hover:bg-red-800 dark:hover:text-red-300",
11
+ orange: "text-orange-500 focus:ring-orange-400 hover:bg-orange-200 dark:hover:bg-orange-800 dark:hover:text-orange-300",
12
+ amber: "text-amber-500 focus:ring-amber-400 hover:bg-amber-200 dark:hover:bg-amber-800 dark:hover:text-amber-300",
13
+ yellow: "text-yellow-500 focus:ring-yellow-400 hover:bg-yellow-200 dark:hover:bg-yellow-800 dark:hover:text-yellow-300",
14
+ lime: "text-lime-500 focus:ring-lime-400 hover:bg-lime-200 dark:hover:bg-lime-800 dark:hover:text-lime-300",
15
+ green: "text-green-500 focus:ring-green-400 hover:bg-green-200 dark:hover:bg-green-800 dark:hover:text-green-300",
16
+ emerald: "text-emerald-500 focus:ring-emerald-400 hover:bg-emerald-200 dark:hover:bg-emerald-800 dark:hover:text-emerald-300",
17
+ teal: "text-teal-500 focus:ring-teal-400 hover:bg-teal-200 dark:hover:bg-teal-800 dark:hover:text-teal-300",
18
+ cyan: "text-cyan-500 focus:ring-cyan-400 hover:bg-cyan-200 dark:hover:bg-cyan-800 dark:hover:text-cyan-300",
19
+ sky: "text-sky-500 focus:ring-sky-400 hover:bg-sky-200 dark:hover:bg-sky-800 dark:hover:text-sky-300",
20
+ blue: "text-blue-500 focus:ring-blue-400 hover:bg-blue-200 dark:hover:bg-blue-800 dark:hover:text-blue-300",
21
+ indigo: "text-indigo-500 focus:ring-indigo-400 hover:bg-indigo-200 dark:hover:bg-indigo-800 dark:hover:text-indigo-300",
22
+ violet: "text-violet-500 focus:ring-violet-400 hover:bg-violet-200 dark:hover:bg-violet-800 dark:hover:text-violet-300",
23
+ purple: "text-purple-500 focus:ring-purple-400 hover:bg-purple-200 dark:hover:bg-purple-800 dark:hover:text-purple-300",
24
+ fuchsia: "text-fuchsia-500 focus:ring-fuchsia-400 hover:bg-fuchsia-200 dark:hover:bg-fuchsia-800 dark:hover:text-fuchsia-300",
25
+ pink: "text-pink-500 focus:ring-pink-400 hover:bg-pink-200 dark:hover:bg-pink-800 dark:hover:text-pink-300",
26
+ rose: "text-rose-500 focus:ring-rose-400 hover:bg-rose-200 dark:hover:bg-rose-800 dark:hover:text-rose-300",
27
+ none: ""
28
+ },
29
+ size: {
30
+ xs: "m-0.5 rounded-xs focus:ring-1 p-0.5",
31
+ sm: "m-0.5 rounded-sm focus:ring-1 p-0.5",
32
+ md: "m-0.5 rounded-lg focus:ring-2 p-1.5",
33
+ lg: "m-0.5 rounded-lg focus:ring-2 p-2.5"
34
+ }
35
+ },
36
+ defaultVariants: {
37
+ color: "gray",
38
+ size: "md",
39
+ href: null
40
+ },
41
+ slots: {
42
+ svg: ""
43
+ },
44
+ compoundVariants: [
45
+ {
46
+ size: "xs",
47
+ class: {
48
+ svg: "w-3 h-3"
49
+ }
50
+ },
51
+ {
52
+ size: "sm",
53
+ class: {
54
+ svg: "w-3.5 h-3.5"
55
+ }
56
+ },
57
+ {
58
+ size: ["md", "lg"],
59
+ class: {
60
+ svg: "w-5 h-5"
61
+ }
62
+ },
63
+ {
64
+ size: ["xs", "sm", "md", "lg"],
65
+ color: "none",
66
+ class: "focus:ring-0 rounded-none m-0"
67
+ }
68
+ ]
69
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * DismissableContext provides a way to dismiss a component or modal.
3
+ * It should be used within a component that needs to provide dismiss functionality.
4
+ */
5
+ export type DismissableContext = {
6
+ dismiss: (event: MouseEvent) => void;
7
+ };
8
+ export declare function createDismissableContext(onDismiss: (event: MouseEvent) => void): DismissableContext;
9
+ export declare function useDismiss(): DismissableContext;
@@ -0,0 +1,16 @@
1
+ import { getContext, setContext } from "svelte";
2
+ const DISMISSABLE_KEY = Symbol("dismissable");
3
+ export function createDismissableContext(onDismiss) {
4
+ const context = {
5
+ dismiss: onDismiss
6
+ };
7
+ return setContext(DISMISSABLE_KEY, context);
8
+ }
9
+ export function useDismiss() {
10
+ const context = getContext(DISMISSABLE_KEY);
11
+ if (!context) {
12
+ // uncomment below line if you want to trace usage without the context
13
+ // console.warn('useDismiss must be used within a Dismissable component'); // For development purposes
14
+ }
15
+ return context;
16
+ }