@ttdk-design-system/library-svelte 0.0.0-stage → 1.0.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 (270) hide show
  1. package/AI_GUIDE.md +6518 -0
  2. package/dist/core/index.d.ts +2 -0
  3. package/dist/core/index.js +2 -0
  4. package/dist/core/tailwind-preset.cjs +62 -0
  5. package/dist/core/tailwind-preset.d.cts +63 -0
  6. package/dist/core/tailwind-preset.d.ts +74 -0
  7. package/dist/core/tailwind-preset.js +79 -0
  8. package/dist/core/theme/tokens.css +663 -0
  9. package/dist/core/types.d.ts +152 -0
  10. package/dist/core/types.js +735 -0
  11. package/dist/index.d.ts +14 -0
  12. package/dist/index.js +15 -0
  13. package/dist/tailwind-preset.cjs +62 -0
  14. package/dist/tailwind-preset.d.cts +63 -0
  15. package/dist/tailwind-preset.d.ts +74 -0
  16. package/dist/tailwind-preset.js +79 -0
  17. package/dist/types.d.ts +1 -0
  18. package/dist/types.js +1 -0
  19. package/dist/web/accordion/AI_GUIDE.md +149 -0
  20. package/dist/web/accordion/accordion.css +1 -0
  21. package/dist/web/accordion/accordion.svelte +217 -0
  22. package/dist/web/accordion/accordion.svelte.d.ts +224 -0
  23. package/dist/web/accordion/index.d.ts +2 -0
  24. package/dist/web/accordion/index.js +2 -0
  25. package/dist/web/accordion/manifest.json +351 -0
  26. package/dist/web/alert/AI_GUIDE.md +139 -0
  27. package/dist/web/alert/alert.css +1 -0
  28. package/dist/web/alert/alert.svelte +175 -0
  29. package/dist/web/alert/alert.svelte.d.ts +165 -0
  30. package/dist/web/alert/index.d.ts +2 -0
  31. package/dist/web/alert/index.js +2 -0
  32. package/dist/web/alert/manifest.json +240 -0
  33. package/dist/web/avatar/AI_GUIDE.md +118 -0
  34. package/dist/web/avatar/avatar.css +1 -0
  35. package/dist/web/avatar/avatar.svelte +108 -0
  36. package/dist/web/avatar/avatar.svelte.d.ts +147 -0
  37. package/dist/web/avatar/index.d.ts +2 -0
  38. package/dist/web/avatar/index.js +2 -0
  39. package/dist/web/avatar/manifest.json +195 -0
  40. package/dist/web/badge/AI_GUIDE.md +94 -0
  41. package/dist/web/badge/badge.css +1 -0
  42. package/dist/web/badge/badge.svelte +50 -0
  43. package/dist/web/badge/badge.svelte.d.ts +111 -0
  44. package/dist/web/badge/index.d.ts +2 -0
  45. package/dist/web/badge/index.js +2 -0
  46. package/dist/web/badge/manifest.json +141 -0
  47. package/dist/web/banner/AI_GUIDE.md +130 -0
  48. package/dist/web/banner/banner.css +1 -0
  49. package/dist/web/banner/banner.svelte +180 -0
  50. package/dist/web/banner/banner.svelte.d.ts +172 -0
  51. package/dist/web/banner/index.d.ts +2 -0
  52. package/dist/web/banner/index.js +2 -0
  53. package/dist/web/banner/manifest.json +240 -0
  54. package/dist/web/breadcrumb/AI_GUIDE.md +120 -0
  55. package/dist/web/breadcrumb/breadcrumb.css +1 -0
  56. package/dist/web/breadcrumb/breadcrumb.svelte +168 -0
  57. package/dist/web/breadcrumb/breadcrumb.svelte.d.ts +141 -0
  58. package/dist/web/breadcrumb/index.d.ts +2 -0
  59. package/dist/web/breadcrumb/index.js +2 -0
  60. package/dist/web/breadcrumb/manifest.json +225 -0
  61. package/dist/web/button/AI_GUIDE.md +121 -0
  62. package/dist/web/button/button.css +1 -0
  63. package/dist/web/button/button.svelte +154 -0
  64. package/dist/web/button/button.svelte.d.ts +159 -0
  65. package/dist/web/button/index.d.ts +2 -0
  66. package/dist/web/button/index.js +2 -0
  67. package/dist/web/button/manifest.json +177 -0
  68. package/dist/web/calendar/AI_GUIDE.md +151 -0
  69. package/dist/web/calendar/calendar.css +1 -0
  70. package/dist/web/calendar/calendar.svelte +1091 -0
  71. package/dist/web/calendar/calendar.svelte.d.ts +268 -0
  72. package/dist/web/calendar/index.d.ts +2 -0
  73. package/dist/web/calendar/index.js +2 -0
  74. package/dist/web/calendar/manifest.json +470 -0
  75. package/dist/web/card/AI_GUIDE.md +133 -0
  76. package/dist/web/card/card.css +1 -0
  77. package/dist/web/card/card.svelte +217 -0
  78. package/dist/web/card/card.svelte.d.ts +242 -0
  79. package/dist/web/card/index.d.ts +2 -0
  80. package/dist/web/card/index.js +2 -0
  81. package/dist/web/card/manifest.json +357 -0
  82. package/dist/web/checkbox/AI_GUIDE.md +146 -0
  83. package/dist/web/checkbox/checkbox.css +1 -0
  84. package/dist/web/checkbox/checkbox.svelte +131 -0
  85. package/dist/web/checkbox/checkbox.svelte.d.ts +199 -0
  86. package/dist/web/checkbox/index.d.ts +2 -0
  87. package/dist/web/checkbox/index.js +2 -0
  88. package/dist/web/checkbox/manifest.json +294 -0
  89. package/dist/web/chip/AI_GUIDE.md +186 -0
  90. package/dist/web/chip/chip.css +1 -0
  91. package/dist/web/chip/chip.svelte +113 -0
  92. package/dist/web/chip/chip.svelte.d.ts +145 -0
  93. package/dist/web/chip/index.d.ts +2 -0
  94. package/dist/web/chip/index.js +2 -0
  95. package/dist/web/chip/manifest.json +186 -0
  96. package/dist/web/dropdown/AI_GUIDE.md +167 -0
  97. package/dist/web/dropdown/dropdown.css +1 -0
  98. package/dist/web/dropdown/dropdown.svelte +844 -0
  99. package/dist/web/dropdown/dropdown.svelte.d.ts +361 -0
  100. package/dist/web/dropdown/index.d.ts +2 -0
  101. package/dist/web/dropdown/index.js +2 -0
  102. package/dist/web/dropdown/manifest.json +576 -0
  103. package/dist/web/flex/AI_GUIDE.md +113 -0
  104. package/dist/web/flex/flex-item.svelte +37 -0
  105. package/dist/web/flex/flex-item.svelte.d.ts +96 -0
  106. package/dist/web/flex/flex.css +1 -0
  107. package/dist/web/flex/flex.svelte +39 -0
  108. package/dist/web/flex/flex.svelte.d.ts +104 -0
  109. package/dist/web/flex/index.d.ts +3 -0
  110. package/dist/web/flex/index.js +3 -0
  111. package/dist/web/flex/manifest.json +162 -0
  112. package/dist/web/form/index.d.ts +1 -0
  113. package/dist/web/form/index.js +2 -0
  114. package/dist/web/grid/AI_GUIDE.md +112 -0
  115. package/dist/web/grid/grid-item.svelte +41 -0
  116. package/dist/web/grid/grid-item.svelte.d.ts +112 -0
  117. package/dist/web/grid/grid.css +1 -0
  118. package/dist/web/grid/grid.svelte +37 -0
  119. package/dist/web/grid/grid.svelte.d.ts +96 -0
  120. package/dist/web/grid/index.d.ts +3 -0
  121. package/dist/web/grid/index.js +3 -0
  122. package/dist/web/grid/manifest.json +153 -0
  123. package/dist/web/index.d.ts +58 -0
  124. package/dist/web/index.js +57 -0
  125. package/dist/web/input/AI_GUIDE.md +159 -0
  126. package/dist/web/input/index.d.ts +2 -0
  127. package/dist/web/input/index.js +2 -0
  128. package/dist/web/input/input.css +1 -0
  129. package/dist/web/input/input.svelte +283 -0
  130. package/dist/web/input/input.svelte.d.ts +283 -0
  131. package/dist/web/input/manifest.json +465 -0
  132. package/dist/web/input-number/AI_GUIDE.md +164 -0
  133. package/dist/web/input-number/index.d.ts +2 -0
  134. package/dist/web/input-number/index.js +2 -0
  135. package/dist/web/input-number/input-number.css +1 -0
  136. package/dist/web/input-number/input-number.svelte +783 -0
  137. package/dist/web/input-number/input-number.svelte.d.ts +352 -0
  138. package/dist/web/input-number/manifest.json +575 -0
  139. package/dist/web/modal/AI_GUIDE.md +171 -0
  140. package/dist/web/modal/index.d.ts +2 -0
  141. package/dist/web/modal/index.js +2 -0
  142. package/dist/web/modal/manifest.json +375 -0
  143. package/dist/web/modal/modal.css +1 -0
  144. package/dist/web/modal/modal.svelte +333 -0
  145. package/dist/web/modal/modal.svelte.d.ts +231 -0
  146. package/dist/web/pagination/AI_GUIDE.md +148 -0
  147. package/dist/web/pagination/index.d.ts +19 -0
  148. package/dist/web/pagination/index.js +19 -0
  149. package/dist/web/pagination/manifest.json +432 -0
  150. package/dist/web/pagination/pagination-content.svelte +25 -0
  151. package/dist/web/pagination/pagination-content.svelte.d.ts +36 -0
  152. package/dist/web/pagination/pagination-ellipsis.svelte +38 -0
  153. package/dist/web/pagination/pagination-ellipsis.svelte.d.ts +35 -0
  154. package/dist/web/pagination/pagination-first.svelte +105 -0
  155. package/dist/web/pagination/pagination-first.svelte.d.ts +74 -0
  156. package/dist/web/pagination/pagination-item.svelte +25 -0
  157. package/dist/web/pagination/pagination-item.svelte.d.ts +36 -0
  158. package/dist/web/pagination/pagination-last.svelte +105 -0
  159. package/dist/web/pagination/pagination-last.svelte.d.ts +74 -0
  160. package/dist/web/pagination/pagination-link.svelte +67 -0
  161. package/dist/web/pagination/pagination-link.svelte.d.ts +69 -0
  162. package/dist/web/pagination/pagination-next.svelte +99 -0
  163. package/dist/web/pagination/pagination-next.svelte.d.ts +75 -0
  164. package/dist/web/pagination/pagination-previous.svelte +99 -0
  165. package/dist/web/pagination/pagination-previous.svelte.d.ts +75 -0
  166. package/dist/web/pagination/pagination.css +1 -0
  167. package/dist/web/pagination/pagination.svelte +471 -0
  168. package/dist/web/pagination/pagination.svelte.d.ts +256 -0
  169. package/dist/web/popover/AI_GUIDE.md +163 -0
  170. package/dist/web/popover/index.d.ts +3 -0
  171. package/dist/web/popover/index.js +3 -0
  172. package/dist/web/popover/manifest.json +396 -0
  173. package/dist/web/popover/popover.css +1 -0
  174. package/dist/web/popover/popover.svelte +497 -0
  175. package/dist/web/popover/popover.svelte.d.ts +116 -0
  176. package/dist/web/radio/AI_GUIDE.md +155 -0
  177. package/dist/web/radio/index.d.ts +2 -0
  178. package/dist/web/radio/index.js +2 -0
  179. package/dist/web/radio/manifest.json +294 -0
  180. package/dist/web/radio/radio.css +1 -0
  181. package/dist/web/radio/radio.svelte +123 -0
  182. package/dist/web/radio/radio.svelte.d.ts +192 -0
  183. package/dist/web/selectbox/AI_GUIDE.md +216 -0
  184. package/dist/web/selectbox/index.d.ts +2 -0
  185. package/dist/web/selectbox/index.js +2 -0
  186. package/dist/web/selectbox/manifest.json +477 -0
  187. package/dist/web/selectbox/selectbox.css +1 -0
  188. package/dist/web/selectbox/selectbox.svelte +704 -0
  189. package/dist/web/selectbox/selectbox.svelte.d.ts +296 -0
  190. package/dist/web/sonner/AI_GUIDE.md +98 -0
  191. package/dist/web/sonner/index.d.ts +46 -0
  192. package/dist/web/sonner/index.js +64 -0
  193. package/dist/web/sonner/manifest.json +132 -0
  194. package/dist/web/sonner/sonner.css +1 -0
  195. package/dist/web/sonner/sonner.svelte +85 -0
  196. package/dist/web/sonner/sonner.svelte.d.ts +105 -0
  197. package/dist/web/table/AI_GUIDE.md +145 -0
  198. package/dist/web/table/index.d.ts +21 -0
  199. package/dist/web/table/index.js +22 -0
  200. package/dist/web/table/manifest.json +168 -0
  201. package/dist/web/table/table-body.svelte +23 -0
  202. package/dist/web/table/table-body.svelte.d.ts +36 -0
  203. package/dist/web/table/table-caption.svelte +23 -0
  204. package/dist/web/table/table-caption.svelte.d.ts +36 -0
  205. package/dist/web/table/table-cell.svelte +35 -0
  206. package/dist/web/table/table-cell.svelte.d.ts +57 -0
  207. package/dist/web/table/table-empty.svelte +56 -0
  208. package/dist/web/table/table-empty.svelte.d.ts +65 -0
  209. package/dist/web/table/table-footer.svelte +23 -0
  210. package/dist/web/table/table-footer.svelte.d.ts +36 -0
  211. package/dist/web/table/table-head.svelte +39 -0
  212. package/dist/web/table/table-head.svelte.d.ts +58 -0
  213. package/dist/web/table/table-header.svelte +23 -0
  214. package/dist/web/table/table-header.svelte.d.ts +36 -0
  215. package/dist/web/table/table-row.svelte +33 -0
  216. package/dist/web/table/table-row.svelte.d.ts +52 -0
  217. package/dist/web/table/table.css +1 -0
  218. package/dist/web/table/table.svelte +178 -0
  219. package/dist/web/table/table.svelte.d.ts +120 -0
  220. package/dist/web/tabs/AI_GUIDE.md +150 -0
  221. package/dist/web/tabs/index.d.ts +2 -0
  222. package/dist/web/tabs/index.js +2 -0
  223. package/dist/web/tabs/manifest.json +315 -0
  224. package/dist/web/tabs/tabs.css +1 -0
  225. package/dist/web/tabs/tabs.svelte +138 -0
  226. package/dist/web/tabs/tabs.svelte.d.ts +204 -0
  227. package/dist/web/text/AI_GUIDE.md +129 -0
  228. package/dist/web/text/index.d.ts +2 -0
  229. package/dist/web/text/index.js +2 -0
  230. package/dist/web/text/manifest.json +195 -0
  231. package/dist/web/text/text.css +1 -0
  232. package/dist/web/text/text.svelte +515 -0
  233. package/dist/web/text/text.svelte.d.ts +168 -0
  234. package/dist/web/textarea/AI_GUIDE.md +141 -0
  235. package/dist/web/textarea/index.d.ts +2 -0
  236. package/dist/web/textarea/index.js +2 -0
  237. package/dist/web/textarea/manifest.json +438 -0
  238. package/dist/web/textarea/textarea.css +1 -0
  239. package/dist/web/textarea/textarea.svelte +224 -0
  240. package/dist/web/textarea/textarea.svelte.d.ts +274 -0
  241. package/dist/web/tooltip/AI_GUIDE.md +110 -0
  242. package/dist/web/tooltip/index.d.ts +2 -0
  243. package/dist/web/tooltip/index.js +2 -0
  244. package/dist/web/tooltip/manifest.json +222 -0
  245. package/dist/web/tooltip/tooltip.css +1 -0
  246. package/dist/web/tooltip/tooltip.svelte +292 -0
  247. package/dist/web/tooltip/tooltip.svelte.d.ts +140 -0
  248. package/dist/webview/bottomsheet/AI_GUIDE.md +141 -0
  249. package/dist/webview/bottomsheet/bottomsheet.css +1 -0
  250. package/dist/webview/bottomsheet/bottomsheet.svelte +462 -0
  251. package/dist/webview/bottomsheet/bottomsheet.svelte.d.ts +200 -0
  252. package/dist/webview/bottomsheet/index.d.ts +4 -0
  253. package/dist/webview/bottomsheet/index.js +3 -0
  254. package/dist/webview/bottomsheet/manifest.json +377 -0
  255. package/dist/webview/button/AI_GUIDE.md +79 -0
  256. package/dist/webview/button/button-ios.css +1 -0
  257. package/dist/webview/button/button-ios.svelte +58 -0
  258. package/dist/webview/button/button-ios.svelte.d.ts +114 -0
  259. package/dist/webview/button/button-material.css +1 -0
  260. package/dist/webview/button/button-material.svelte +58 -0
  261. package/dist/webview/button/button-material.svelte.d.ts +114 -0
  262. package/dist/webview/button/index.d.ts +6 -0
  263. package/dist/webview/button/index.js +4 -0
  264. package/dist/webview/button/manifest.json +148 -0
  265. package/dist/webview/index.d.ts +6 -0
  266. package/dist/webview/index.js +6 -0
  267. package/llms.txt +6518 -0
  268. package/package.json +709 -4
  269. package/ttdk-manifest.json +10188 -0
  270. package/README.md +0 -3
@@ -0,0 +1,844 @@
1
+ <script context="module"></script>
2
+
3
+ <script>import { onDestroy, onMount } from "svelte";
4
+ import {
5
+ computePosition,
6
+ autoUpdate,
7
+ flip,
8
+ shift,
9
+ offset,
10
+ size as floatingSize
11
+ } from "@floating-ui/dom";
12
+ import { buildUiVars, UiProps } from "../../core/types";
13
+ export let value = void 0;
14
+ export let defaultValue = void 0;
15
+ export let multiple = void 0;
16
+ export let placement = void 0;
17
+ export let disableShift = void 0;
18
+ export let panelContent = void 0;
19
+ export let listStyle = void 0;
20
+ export let disabled = void 0;
21
+ export let readOnly = void 0;
22
+ export let loading = void 0;
23
+ export let searchable = void 0;
24
+ export let onOpen = void 0;
25
+ export let onClose = void 0;
26
+ export let options = void 0;
27
+ export let onSelect = void 0;
28
+ export let onChange = void 0;
29
+ export let closeOnSelect = void 0;
30
+ export let onSearch = void 0;
31
+ export let displayValue = void 0;
32
+ export let className = void 0;
33
+ export let error = void 0;
34
+ export let errorMessage = void 0;
35
+ export let size = void 0;
36
+ export let block = void 0;
37
+ export let ui = void 0;
38
+ export let label = void 0;
39
+ export let labelClass = void 0;
40
+ export let id = void 0;
41
+ export let labelStyle = void 0;
42
+ export let required = void 0;
43
+ export let optional = void 0;
44
+ export let optionalText = void 0;
45
+ export let helperText = void 0;
46
+ export let helperTextPosition = void 0;
47
+ export let helperTextClass = void 0;
48
+ export let helperTextStyle = void 0;
49
+ export let controlClass = void 0;
50
+ export let rounded = void 0;
51
+ export let controlStyle = void 0;
52
+ export let icon = void 0;
53
+ export let placeholder = void 0;
54
+ export let clearable = void 0;
55
+ export let arrow = void 0;
56
+ export let searchPlaceholder = void 0;
57
+ export let listClass = void 0;
58
+ export let resetText = void 0;
59
+ export let applyText = void 0;
60
+ export let errorMessageClass = void 0;
61
+ export let errorMessageStyle = void 0;
62
+ function stringifyStyles(stylesObj) {
63
+ let styles = "";
64
+ for (let key in stylesObj) {
65
+ const dashedKey = key.replace(/[A-Z]/g, function(match) {
66
+ return "-" + match.toLowerCase();
67
+ });
68
+ styles += dashedKey + ":" + stylesObj[key] + ";";
69
+ }
70
+ return styles;
71
+ }
72
+ function updatePosition() {
73
+ if (!controlRef || !dropdownRef)
74
+ return;
75
+ dropdownRef.style.maxHeight = "";
76
+ computePosition(controlRef, dropdownRef, {
77
+ placement: placement || "bottom-start",
78
+ strategy: "absolute",
79
+ middleware: [
80
+ offset(4),
81
+ flip({
82
+ fallbackPlacements: [
83
+ "top-start",
84
+ "top-end",
85
+ "bottom-start",
86
+ "bottom-end"
87
+ ],
88
+ padding: {
89
+ top: 16,
90
+ bottom: 16,
91
+ left: 16,
92
+ right: 16
93
+ }
94
+ }),
95
+ ...disableShift ? [] : [
96
+ shift({
97
+ padding: {
98
+ top: 16,
99
+ bottom: 16,
100
+ left: 16,
101
+ right: 16
102
+ }
103
+ })
104
+ ],
105
+ floatingSize({
106
+ apply({ rects, elements, availableHeight }) {
107
+ const isPanel = Boolean(panelContent || $$slots.panelContent);
108
+ const customWidth = listStyle?.width !== void 0 && listStyle?.width !== null && listStyle?.width !== "" ? typeof listStyle.width === "number" || /^\d+(\.\d+)?$/.test(String(listStyle.width).trim()) ? `${String(listStyle.width).trim()}px` : String(listStyle.width) : void 0;
109
+ const customMaxHeight = listStyle?.maxHeight !== void 0 && listStyle?.maxHeight !== null && listStyle?.maxHeight !== "" ? listStyle.maxHeight === "none" ? "none" : typeof listStyle.maxHeight === "number" || /^\d+(\.\d+)?$/.test(String(listStyle.maxHeight).trim()) ? `${String(listStyle.maxHeight).trim()}px` : String(listStyle.maxHeight) : void 0;
110
+ Object.assign(elements.floating.style, {
111
+ width: customWidth || (isPanel ? "auto" : `${rects.reference.width}px`),
112
+ minWidth: customWidth ? customWidth : isPanel ? "auto" : void 0,
113
+ maxHeight: customMaxHeight !== void 0 ? customMaxHeight : isPanel ? "none" : `${Math.max(180, Math.min(availableHeight, 360))}px`
114
+ });
115
+ },
116
+ padding: {
117
+ top: 16,
118
+ bottom: 16,
119
+ left: 16,
120
+ right: 16
121
+ }
122
+ })
123
+ ]
124
+ }).then(({ x, y, placement: placement2 }) => {
125
+ if (!dropdownRef)
126
+ return;
127
+ dropdownRef.style.position = "absolute";
128
+ dropdownRef.style.left = `${x}px`;
129
+ dropdownRef.style.top = `${y}px`;
130
+ dropdownRef.setAttribute("data-placement", placement2);
131
+ });
132
+ }
133
+ function startFloating() {
134
+ stopFloating();
135
+ if (controlRef && dropdownRef) {
136
+ cleanupAutoUpdate = autoUpdate(controlRef, dropdownRef, () => {
137
+ updatePosition();
138
+ });
139
+ }
140
+ }
141
+ function stopFloating() {
142
+ if (typeof cleanupAutoUpdate === "function") {
143
+ cleanupAutoUpdate();
144
+ cleanupAutoUpdate = null;
145
+ }
146
+ }
147
+ function handleClickOutside(event) {
148
+ if (!dropdownRef)
149
+ return;
150
+ const target = event.target;
151
+ if (rootRef && !rootRef.contains(target) && dropdownRef && !dropdownRef.contains(target)) {
152
+ closeDropdown();
153
+ }
154
+ }
155
+ function onPointerDown(event) {
156
+ handleClickOutside(event);
157
+ }
158
+ function toggleDropdown() {
159
+ if (disabled || readOnly || loading)
160
+ return;
161
+ if (isOpen) {
162
+ closeDropdown();
163
+ } else {
164
+ openDropdown();
165
+ }
166
+ }
167
+ function openDropdown() {
168
+ if (disabled || readOnly || loading)
169
+ return;
170
+ isOpen = true;
171
+ searchQuery = "";
172
+ if (multiple) {
173
+ tempMultiValue = Array.isArray(currentValue) ? [...currentValue] : [];
174
+ }
175
+ setTimeout(() => {
176
+ startFloating();
177
+ updatePosition();
178
+ if (searchable && dropdownRef) {
179
+ const searchInput = dropdownRef.querySelector?.(
180
+ ".ttdk-dropdown-search-input"
181
+ );
182
+ if (searchInput) {
183
+ searchInput.focus();
184
+ }
185
+ }
186
+ }, 0);
187
+ if (onOpen)
188
+ onOpen();
189
+ }
190
+ function closeDropdown() {
191
+ stopFloating();
192
+ isOpen = false;
193
+ searchQuery = "";
194
+ if (onClose)
195
+ onClose();
196
+ }
197
+ function normalizedOptions() {
198
+ const raw = options;
199
+ if (!raw || !Array.isArray(raw))
200
+ return [];
201
+ return raw.map((opt) => {
202
+ if (typeof opt === "object" && opt !== null) {
203
+ return {
204
+ label: String(opt.label ?? opt.value ?? ""),
205
+ value: opt.value ?? opt.label ?? "",
206
+ disabled: Boolean(opt.disabled),
207
+ icon: opt.icon,
208
+ description: opt.description,
209
+ danger: Boolean(opt.danger),
210
+ divider: Boolean(opt.divider),
211
+ onClick: opt.onClick
212
+ };
213
+ }
214
+ return {
215
+ label: String(opt),
216
+ value: opt,
217
+ disabled: false,
218
+ icon: void 0,
219
+ description: void 0,
220
+ danger: false,
221
+ divider: false,
222
+ onClick: void 0
223
+ };
224
+ });
225
+ }
226
+ function filteredOptions(query, _opts) {
227
+ const opts = normalizedOptions();
228
+ const currentQ = query !== void 0 ? query : searchQuery;
229
+ if (!currentQ || !currentQ.trim())
230
+ return opts;
231
+ const q = currentQ.toLowerCase().trim();
232
+ return opts.filter((opt) => {
233
+ const matchLabel = opt.label && opt.label.toLowerCase().includes(q);
234
+ const matchDesc = opt.description && opt.description.toLowerCase().includes(q);
235
+ return matchLabel || matchDesc;
236
+ });
237
+ }
238
+ function isOptionSelected(optValue, _multi, _curr) {
239
+ if (multiple) {
240
+ const list = isOpen ? tempMultiValue : Array.isArray(currentValue) ? currentValue : [];
241
+ return list.some((v) => String(v) === String(optValue));
242
+ }
243
+ return String(currentValue) === String(optValue);
244
+ }
245
+ function handleSingleSelect(opt) {
246
+ if (opt.disabled || disabled)
247
+ return;
248
+ if (opt.onClick) {
249
+ opt.onClick(opt);
250
+ }
251
+ currentValue = opt.value;
252
+ if (onSelect) {
253
+ onSelect(opt);
254
+ }
255
+ if (onChange) {
256
+ onChange(opt.value);
257
+ }
258
+ if (closeOnSelect !== false) {
259
+ closeDropdown();
260
+ }
261
+ }
262
+ function handleMultiToggle(opt) {
263
+ if (opt.disabled || disabled)
264
+ return;
265
+ if (opt.onClick) {
266
+ opt.onClick(opt);
267
+ }
268
+ const index = tempMultiValue.findIndex(
269
+ (v) => String(v) === String(opt.value)
270
+ );
271
+ if (index > -1) {
272
+ tempMultiValue = tempMultiValue.filter((_, i) => i !== index);
273
+ } else {
274
+ tempMultiValue = [...tempMultiValue, opt.value];
275
+ }
276
+ }
277
+ function handleRemoveTag(val, event) {
278
+ if (event && event.stopPropagation)
279
+ event.stopPropagation();
280
+ if (disabled)
281
+ return;
282
+ if (Array.isArray(currentValue)) {
283
+ const next = currentValue.filter((v) => String(v) !== String(val));
284
+ currentValue = next;
285
+ tempMultiValue = [...next];
286
+ if (onChange) {
287
+ onChange(next);
288
+ }
289
+ }
290
+ }
291
+ function handleApply() {
292
+ currentValue = [...tempMultiValue];
293
+ if (onChange) {
294
+ onChange(currentValue);
295
+ }
296
+ closeDropdown();
297
+ }
298
+ function handleReset() {
299
+ tempMultiValue = [];
300
+ currentValue = [];
301
+ if (onChange) {
302
+ onChange([]);
303
+ }
304
+ }
305
+ function handleSearchInput(e) {
306
+ searchQuery = e.target.value;
307
+ if (onSearch) {
308
+ onSearch(e.target.value);
309
+ }
310
+ }
311
+ function getSingleSelectedLabel() {
312
+ if (displayValue !== void 0 && displayValue !== null && displayValue !== "") {
313
+ return displayValue;
314
+ }
315
+ const opts = normalizedOptions();
316
+ const match = opts.find(
317
+ (opt) => String(opt.value) === String(currentValue)
318
+ );
319
+ if (match) {
320
+ return match.label;
321
+ }
322
+ if (currentValue !== void 0 && currentValue !== null && currentValue !== "") {
323
+ return String(currentValue);
324
+ }
325
+ return "";
326
+ }
327
+ function getMultiSelectedChips(_curr) {
328
+ const list = Array.isArray(currentValue) ? currentValue : [];
329
+ const opts = normalizedOptions();
330
+ return list.map((val) => {
331
+ const match = opts.find((o) => String(o.value) === String(val));
332
+ return {
333
+ value: val,
334
+ label: match ? match.label : String(val)
335
+ };
336
+ });
337
+ }
338
+ function hasValue() {
339
+ if (displayValue !== void 0 && displayValue !== null && displayValue !== "") {
340
+ return true;
341
+ }
342
+ if (multiple) {
343
+ return Array.isArray(currentValue) && currentValue.length > 0;
344
+ }
345
+ return currentValue !== void 0 && currentValue !== "" && currentValue !== null;
346
+ }
347
+ function handleClear(event) {
348
+ if (event && event.stopPropagation)
349
+ event.stopPropagation();
350
+ if (disabled || readOnly)
351
+ return;
352
+ const emptyVal = multiple ? [] : "";
353
+ currentValue = emptyVal;
354
+ tempMultiValue = [];
355
+ if (onChange) {
356
+ onChange(emptyVal);
357
+ }
358
+ }
359
+ let rootRef;
360
+ let controlRef;
361
+ let dropdownRef;
362
+ let isOpen = false;
363
+ let searchQuery = "";
364
+ $:
365
+ if (value !== void 0) {
366
+ currentValue = value;
367
+ }
368
+ $:
369
+ hasVal = Boolean(
370
+ displayValue !== void 0 && displayValue !== null && displayValue !== "" || (multiple ? Array.isArray(currentValue) && currentValue.length > 0 : currentValue !== void 0 && currentValue !== "" && currentValue !== null)
371
+ );
372
+ $:
373
+ selectedLabel = displayValue !== void 0 && displayValue !== null && displayValue !== "" ? String(displayValue) : (Array.isArray(options) ? options : []).find((o) => String(o.value) === String(currentValue))?.label ?? (currentValue !== void 0 && currentValue !== null && currentValue !== "" ? String(currentValue) : "");
374
+ let currentValue = value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : multiple ? [] : "";
375
+ let tempMultiValue = [];
376
+ let cleanupAutoUpdate = null;
377
+ onMount(() => {
378
+ if (typeof document !== "undefined") {
379
+ document.addEventListener(
380
+ "pointerdown",
381
+ (e) => onPointerDown(e),
382
+ true
383
+ );
384
+ }
385
+ });
386
+ onDestroy(() => {
387
+ stopFloating();
388
+ if (typeof document !== "undefined") {
389
+ document.removeEventListener(
390
+ "pointerdown",
391
+ (e) => onPointerDown(e),
392
+ true
393
+ );
394
+ }
395
+ });
396
+ </script>
397
+
398
+ <div
399
+ style={stringifyStyles({
400
+ ...buildUiVars(ui),
401
+ ...(ui || {}),
402
+ })}
403
+ bind:this={rootRef}
404
+ class={`ttdk-dropdown-wrapper ${className || ""}`.trim()}
405
+ data-disabled={disabled}
406
+ data-error={Boolean(error || errorMessage)}
407
+ data-size={size || "md"}
408
+ data-block={block ? "true" : undefined}
409
+ >
410
+ {#if label}
411
+ <label
412
+ style={stringifyStyles({
413
+ ...buildUiVars(labelStyle),
414
+ })}
415
+ class={`ttdk-dropdown-label ${labelClass || ""}`.trim()}
416
+ for={id}
417
+ ><span>{label}</span>
418
+ {#if required}
419
+ <span class="ttdk-dropdown-required" aria-hidden="true"> * </span>
420
+ {/if}
421
+ {#if optional}
422
+ <span class="ttdk-dropdown-optional"
423
+ >{optionalText || "(Opsional)"}</span
424
+ >
425
+ {/if}</label
426
+ >
427
+ {/if}
428
+ {#if helperText && helperTextPosition === "top"}
429
+ <div
430
+ style={stringifyStyles({
431
+ ...buildUiVars(helperTextStyle),
432
+ })}
433
+ class={`ttdk-dropdown-helper-text ${helperTextClass || ""}`.trim()}
434
+ >
435
+ {helperText}
436
+ </div>
437
+ {/if}
438
+ <div
439
+ style={stringifyStyles({
440
+ ...buildUiVars(controlStyle),
441
+ })}
442
+ role="button"
443
+ aria-haspopup="menu"
444
+ bind:this={controlRef}
445
+ class={`ttdk-dropdown-control ${controlClass || ""}`.trim()}
446
+ {id}
447
+ tabIndex={disabled ? -1 : 0}
448
+ aria-expanded={isOpen}
449
+ aria-disabled={disabled}
450
+ aria-invalid={Boolean(error || errorMessage)}
451
+ data-open={isOpen ? "true" : "false"}
452
+ data-filled={hasVal ? "true" : "false"}
453
+ data-error={Boolean(error || errorMessage)}
454
+ data-disabled={Boolean(disabled)}
455
+ data-size={size || "md"}
456
+ data-rounded={rounded || "md"}
457
+ data-custom-trigger={$$slots.default ? "true" : undefined}
458
+ on:click={(event) => {
459
+ toggleDropdown();
460
+ }}
461
+ on:keydown={(e) => {
462
+ if (e.key === "Enter" || e.key === " ") {
463
+ e.preventDefault();
464
+ toggleDropdown();
465
+ } else if (e.key === "Escape") {
466
+ closeDropdown();
467
+ }
468
+ }}
469
+ >
470
+ {#if $$slots.default}
471
+ <slot />
472
+ {/if}
473
+ {#if !$$slots.default}
474
+ <div class="ttdk-dropdown-display">
475
+ {#if icon}
476
+ <span class="ttdk-dropdown-leading-icon" aria-hidden="true"
477
+ >{icon}</span
478
+ >
479
+ {/if}
480
+ {#if multiple && hasVal}
481
+ <div class="ttdk-dropdown-chips">
482
+ {#each getMultiSelectedChips(currentValue) as chip (chip.value)}
483
+ <span class="ttdk-dropdown-chip"
484
+ ><span class="ttdk-dropdown-chip-text">{chip.label}</span
485
+ ><button
486
+ type="button"
487
+ class="ttdk-dropdown-chip-remove"
488
+ aria-label={`Hapus ${chip.label}`}
489
+ on:click={(e) => {
490
+ handleRemoveTag(chip.value, e);
491
+ }}
492
+ ><svg
493
+ class="ttdk-dropdown-chip-remove-icon"
494
+ viewBox="0 0 24 24"
495
+ fill="none"
496
+ ><line x1="18" y1="6" x2="6" y2="18" /><line
497
+ x1="6"
498
+ y1="6"
499
+ x2="18"
500
+ y2="18"
501
+ /></svg
502
+ ></button
503
+ ></span
504
+ >
505
+ {/each}
506
+ </div>
507
+ {/if}
508
+ {#if !multiple && hasVal}
509
+ <span class="ttdk-dropdown-value">{selectedLabel}</span>
510
+ {/if}
511
+ {#if !hasVal}
512
+ <span class="ttdk-dropdown-placeholder"
513
+ >{placeholder || "Pilih dropdown menu"}</span
514
+ >
515
+ {/if}
516
+ </div>
517
+
518
+ {#if clearable && hasVal && !disabled && !readOnly && !loading}
519
+ <button
520
+ type="button"
521
+ class="ttdk-dropdown-clear"
522
+ aria-label="Hapus pilihan"
523
+ on:click={(e) => {
524
+ handleClear(e);
525
+ }}
526
+ ><svg class="ttdk-dropdown-clear-icon" viewBox="0 0 24 24" fill="none"
527
+ ><line x1="18" y1="6" x2="6" y2="18" /><line
528
+ x1="6"
529
+ y1="6"
530
+ x2="18"
531
+ y2="18"
532
+ /></svg
533
+ ></button
534
+ >
535
+ {/if}
536
+
537
+ {#if loading}
538
+ <span class="ttdk-dropdown-spinner" aria-hidden="true"
539
+ ><svg
540
+ class="ttdk-dropdown-spinner-icon"
541
+ viewBox="0 0 24 24"
542
+ fill="none"
543
+ ><line
544
+ x1="12"
545
+ y1="2.5"
546
+ x2="12"
547
+ y2="6.5"
548
+ opacity="0.175"
549
+ transform="rotate(0 12 12)"
550
+ /><line
551
+ x1="12"
552
+ y1="2.5"
553
+ x2="12"
554
+ y2="6.5"
555
+ opacity="0.25"
556
+ transform="rotate(30 12 12)"
557
+ /><line
558
+ x1="12"
559
+ y1="2.5"
560
+ x2="12"
561
+ y2="6.5"
562
+ opacity="0.325"
563
+ transform="rotate(60 12 12)"
564
+ /><line
565
+ x1="12"
566
+ y1="2.5"
567
+ x2="12"
568
+ y2="6.5"
569
+ opacity="0.4"
570
+ transform="rotate(90 12 12)"
571
+ /><line
572
+ x1="12"
573
+ y1="2.5"
574
+ x2="12"
575
+ y2="6.5"
576
+ opacity="0.475"
577
+ transform="rotate(120 12 12)"
578
+ /><line
579
+ x1="12"
580
+ y1="2.5"
581
+ x2="12"
582
+ y2="6.5"
583
+ opacity="0.55"
584
+ transform="rotate(150 12 12)"
585
+ /><line
586
+ x1="12"
587
+ y1="2.5"
588
+ x2="12"
589
+ y2="6.5"
590
+ opacity="0.625"
591
+ transform="rotate(180 12 12)"
592
+ /><line
593
+ x1="12"
594
+ y1="2.5"
595
+ x2="12"
596
+ y2="6.5"
597
+ opacity="0.7"
598
+ transform="rotate(210 12 12)"
599
+ /><line
600
+ x1="12"
601
+ y1="2.5"
602
+ x2="12"
603
+ y2="6.5"
604
+ opacity="0.775"
605
+ transform="rotate(240 12 12)"
606
+ /><line
607
+ x1="12"
608
+ y1="2.5"
609
+ x2="12"
610
+ y2="6.5"
611
+ opacity="0.85"
612
+ transform="rotate(270 12 12)"
613
+ /><line
614
+ x1="12"
615
+ y1="2.5"
616
+ x2="12"
617
+ y2="6.5"
618
+ opacity="0.925"
619
+ transform="rotate(300 12 12)"
620
+ /><line
621
+ x1="12"
622
+ y1="2.5"
623
+ x2="12"
624
+ y2="6.5"
625
+ opacity="1"
626
+ transform="rotate(330 12 12)"
627
+ /></svg
628
+ ></span
629
+ >
630
+ {/if}
631
+
632
+ {#if !loading && arrow !== false}
633
+ <span class="ttdk-dropdown-arrow" data-open={isOpen ? "true" : "false"}
634
+ ><svg class="ttdk-dropdown-arrow-icon" viewBox="0 0 24 24" fill="none"
635
+ ><polyline points="6 9 12 15 18 9" /></svg
636
+ ></span
637
+ >
638
+ {/if}
639
+ {/if}
640
+ </div>
641
+ {#if isOpen && !disabled}
642
+ <div
643
+ style={stringifyStyles({
644
+ ...buildUiVars(listStyle),
645
+ ...(listStyle?.width !== undefined &&
646
+ listStyle?.width !== null &&
647
+ listStyle?.width !== ""
648
+ ? {
649
+ width:
650
+ typeof listStyle.width === "number" ||
651
+ /^\d+(\.\d+)?$/.test(String(listStyle.width).trim())
652
+ ? `${String(listStyle.width).trim()}px`
653
+ : String(listStyle.width),
654
+ minWidth:
655
+ typeof listStyle.width === "number" ||
656
+ /^\d+(\.\d+)?$/.test(String(listStyle.width).trim())
657
+ ? `${String(listStyle.width).trim()}px`
658
+ : String(listStyle.width),
659
+ }
660
+ : {}),
661
+ })}
662
+ class="ttdk-dropdown-menu"
663
+ role="menu"
664
+ bind:this={dropdownRef}
665
+ >
666
+ {#if searchable}
667
+ <div
668
+ class="ttdk-dropdown-search"
669
+ on:click={(e) => {
670
+ e.stopPropagation();
671
+ }}
672
+ >
673
+ <input
674
+ type="text"
675
+ class="ttdk-dropdown-search-input"
676
+ placeholder={searchPlaceholder || "Cari"}
677
+ value={searchQuery}
678
+ on:input={(e) => {
679
+ handleSearchInput(e);
680
+ }}
681
+ autoFocus={true}
682
+ /><span class="ttdk-dropdown-search-icon" aria-hidden="true"
683
+ ><svg
684
+ class="ttdk-dropdown-search-svg"
685
+ viewBox="0 0 24 24"
686
+ fill="none"
687
+ ><circle cx="11" cy="11" r="8" /><line
688
+ x1="21"
689
+ y1="21"
690
+ x2="16.65"
691
+ y2="16.65"
692
+ /></svg
693
+ ></span
694
+ >
695
+ </div>
696
+ {/if}
697
+ {#if panelContent || $$slots.panelContent}
698
+ <div
699
+ class="ttdk-dropdown-panel-content"
700
+ on:click={(e) => {
701
+ e.stopPropagation();
702
+ }}
703
+ >
704
+ {#if $$slots.panelContent}
705
+ <slot name="panelContent" close={() => closeDropdown()} />
706
+ {:else if typeof panelContent === "function"}
707
+ {panelContent({
708
+ close: () => closeDropdown(),
709
+ })}
710
+ {:else}
711
+ {panelContent}
712
+ {/if}
713
+ </div>
714
+ {/if}
715
+ {#if !panelContent && !$$slots.panelContent}
716
+ <div class="ttdk-dropdown-options-list" role="presentation">
717
+ {#each filteredOptions(searchQuery, options) as opt (opt.value)}
718
+ <div>
719
+ {#if opt.divider}
720
+ <div class="ttdk-dropdown-divider" role="separator" />
721
+ {/if}
722
+ <div
723
+ class={`ttdk-dropdown-option ${listClass || ""}`.trim()}
724
+ role={multiple ? "menuitemcheckbox" : "menuitem"}
725
+ aria-selected={isOptionSelected(opt.value, tempMultiValue, currentValue)}
726
+ aria-disabled={opt.disabled}
727
+ data-selected={isOptionSelected(opt.value, tempMultiValue, currentValue) ? "true" : "false"}
728
+ data-disabled={opt.disabled ? "true" : "false"}
729
+ data-danger={opt.danger ? "true" : undefined}
730
+ on:click={(e) => {
731
+ e.stopPropagation();
732
+ if (multiple) {
733
+ handleMultiToggle(opt);
734
+ } else {
735
+ handleSingleSelect(opt);
736
+ }
737
+ }}
738
+ >
739
+ {#if multiple}
740
+ <span
741
+ class="ttdk-dropdown-checkbox"
742
+ data-checked={isOptionSelected(opt.value, tempMultiValue, currentValue)
743
+ ? "true"
744
+ : "false"}
745
+ >
746
+ {#if isOptionSelected(opt.value, tempMultiValue, currentValue)}
747
+ <svg
748
+ class="ttdk-dropdown-checkbox-icon"
749
+ viewBox="0 0 24 24"
750
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
751
+ >
752
+ {/if}</span
753
+ >
754
+ {/if}
755
+ {#if opt.icon}
756
+ <span class="ttdk-dropdown-option-icon" aria-hidden="true"
757
+ >{opt.icon}</span
758
+ >
759
+ {/if}
760
+ <div class="ttdk-dropdown-option-content">
761
+ <span class="ttdk-dropdown-option-label">{opt.label}</span>
762
+ {#if opt.description}
763
+ <span class="ttdk-dropdown-option-desc"
764
+ >{opt.description}</span
765
+ >
766
+ {/if}
767
+ </div>
768
+ {#if !multiple && isOptionSelected(opt.value, tempMultiValue, currentValue)}
769
+ <span class="ttdk-dropdown-check-icon" aria-hidden="true"
770
+ ><svg
771
+ class="ttdk-dropdown-check-svg"
772
+ viewBox="0 0 24 24"
773
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
774
+ ></span
775
+ >
776
+ {/if}
777
+ </div>
778
+ </div>
779
+ {/each}
780
+
781
+ {#if filteredOptions(searchQuery, options).length === 0}
782
+ <div class="ttdk-dropdown-empty">Tidak ada pilihan ditemukan</div>
783
+ {/if}
784
+ </div>
785
+ {/if}
786
+ {#if multiple}
787
+ <div
788
+ class="ttdk-dropdown-actions"
789
+ on:click={(e) => {
790
+ e.stopPropagation();
791
+ }}
792
+ >
793
+ <button
794
+ type="button"
795
+ class="ttdk-dropdown-btn-reset"
796
+ on:click={(event) => {
797
+ handleReset();
798
+ }}
799
+ ><svg
800
+ class="ttdk-dropdown-btn-reset-icon"
801
+ viewBox="0 0 24 24"
802
+ fill="none"
803
+ ><path
804
+ d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"
805
+ /><path d="M3 3v5h5" /></svg
806
+ ><span>{resetText || "Reset"}</span></button
807
+ ><button
808
+ type="button"
809
+ class="ttdk-dropdown-btn-apply"
810
+ on:click={(event) => {
811
+ handleApply();
812
+ }}
813
+ ><span>{applyText || "Terapkan"}</span><svg
814
+ class="ttdk-dropdown-btn-apply-icon"
815
+ viewBox="0 0 24 24"
816
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
817
+ ></button
818
+ >
819
+ </div>
820
+ {/if}
821
+ </div>
822
+ {/if}
823
+ {#if helperText && helperTextPosition !== "top"}
824
+ <div
825
+ style={stringifyStyles({
826
+ ...buildUiVars(helperTextStyle),
827
+ })}
828
+ class={`ttdk-dropdown-helper-text ${helperTextClass || ""}`.trim()}
829
+ >
830
+ {helperText}
831
+ </div>
832
+ {/if}
833
+ {#if errorMessage || (typeof error === "string" && error)}
834
+ <div
835
+ style={stringifyStyles({
836
+ ...buildUiVars(errorMessageStyle),
837
+ })}
838
+ role="alert"
839
+ class={`ttdk-dropdown-error-text ${errorMessageClass || ""}`.trim()}
840
+ >
841
+ {errorMessage || (typeof error === "string" ? error : "")}
842
+ </div>
843
+ {/if}
844
+ </div>