@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,704 @@
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 disableShift = void 0;
17
+ export let menuStyle = void 0;
18
+ export let listStyle = void 0;
19
+ export let ui = void 0;
20
+ export let disabled = void 0;
21
+ export let onOpen = void 0;
22
+ export let searchable = void 0;
23
+ export let onClose = void 0;
24
+ export let options = void 0;
25
+ export let onChange = void 0;
26
+ export let onSearch = void 0;
27
+ export let readOnly = void 0;
28
+ export let className = void 0;
29
+ export let error = void 0;
30
+ export let errorMessage = void 0;
31
+ export let size = void 0;
32
+ export let block = void 0;
33
+ export let label = void 0;
34
+ export let labelClass = void 0;
35
+ export let id = void 0;
36
+ export let labelStyle = void 0;
37
+ export let required = void 0;
38
+ export let optional = void 0;
39
+ export let optionalText = void 0;
40
+ export let helperText = void 0;
41
+ export let helperTextPosition = void 0;
42
+ export let helperTextClass = void 0;
43
+ export let helperTextStyle = void 0;
44
+ export let controlClass = void 0;
45
+ export let rounded = void 0;
46
+ export let controlStyle = void 0;
47
+ export let loading = void 0;
48
+ export let placeholder = void 0;
49
+ export let clearable = void 0;
50
+ export let menuClass = void 0;
51
+ export let searchPlaceholder = void 0;
52
+ export let listClass = void 0;
53
+ export let resetText = void 0;
54
+ export let applyText = void 0;
55
+ export let errorMessageClass = void 0;
56
+ export let errorMessageStyle = void 0;
57
+ function stringifyStyles(stylesObj) {
58
+ let styles = "";
59
+ for (let key in stylesObj) {
60
+ const dashedKey = key.replace(/[A-Z]/g, function(match) {
61
+ return "-" + match.toLowerCase();
62
+ });
63
+ styles += dashedKey + ":" + stylesObj[key] + ";";
64
+ }
65
+ return styles;
66
+ }
67
+ function updatePosition() {
68
+ if (!controlRef || !dropdownRef)
69
+ return;
70
+ computePosition(controlRef, dropdownRef, {
71
+ placement: "bottom-start",
72
+ strategy: "absolute",
73
+ middleware: [
74
+ offset(4),
75
+ flip({
76
+ padding: {
77
+ top: 80,
78
+ bottom: 16,
79
+ left: 16,
80
+ right: 16
81
+ }
82
+ }),
83
+ ...disableShift ? [] : [
84
+ shift({
85
+ padding: {
86
+ top: 80,
87
+ bottom: 16,
88
+ left: 16,
89
+ right: 16
90
+ }
91
+ })
92
+ ],
93
+ floatingSize({
94
+ apply({ rects, elements, availableHeight }) {
95
+ const customWidth = menuStyle?.width !== void 0 && menuStyle?.width !== null && menuStyle?.width !== "" ? typeof menuStyle.width === "number" || /^\d+(\.\d+)?$/.test(String(menuStyle.width).trim()) ? `${String(menuStyle.width).trim()}px` : String(menuStyle.width) : 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) : ui?.dropdownWidth !== void 0 && ui?.dropdownWidth !== null && ui?.dropdownWidth !== "" ? typeof ui.dropdownWidth === "number" || /^\d+(\.\d+)?$/.test(String(ui.dropdownWidth).trim()) ? `${String(ui.dropdownWidth).trim()}px` : String(ui.dropdownWidth) : void 0;
96
+ Object.assign(elements.floating.style, {
97
+ width: customWidth || `${rects.reference.width}px`,
98
+ minWidth: customWidth ? customWidth : void 0,
99
+ maxHeight: `${Math.min(availableHeight, 360)}px`
100
+ });
101
+ },
102
+ padding: {
103
+ top: 80,
104
+ bottom: 16,
105
+ left: 16,
106
+ right: 16
107
+ }
108
+ })
109
+ ]
110
+ }).then(({ x, y, placement }) => {
111
+ if (!dropdownRef)
112
+ return;
113
+ dropdownRef.style.left = `${x}px`;
114
+ dropdownRef.style.top = `${y}px`;
115
+ dropdownRef.setAttribute("data-placement", placement);
116
+ });
117
+ }
118
+ function startFloating() {
119
+ stopFloating();
120
+ if (controlRef && dropdownRef) {
121
+ cleanupAutoUpdate = autoUpdate(controlRef, dropdownRef, () => {
122
+ updatePosition();
123
+ });
124
+ }
125
+ }
126
+ function stopFloating() {
127
+ if (typeof cleanupAutoUpdate === "function") {
128
+ cleanupAutoUpdate();
129
+ cleanupAutoUpdate = null;
130
+ }
131
+ }
132
+ function handleClickOutside(event) {
133
+ if (!dropdownRef)
134
+ return;
135
+ const target = event.target;
136
+ if (rootRef && !rootRef.contains(target) && dropdownRef && !dropdownRef.contains(target)) {
137
+ closeDropdown();
138
+ }
139
+ }
140
+ function onPointerDown(event) {
141
+ handleClickOutside(event);
142
+ }
143
+ function toggleDropdown() {
144
+ if (disabled)
145
+ return;
146
+ const nextOpen = !isOpen;
147
+ isOpen = nextOpen;
148
+ if (nextOpen) {
149
+ if (multiple) {
150
+ tempMultiValue = Array.isArray(currentValue) ? [...currentValue] : [];
151
+ }
152
+ if (onOpen)
153
+ onOpen();
154
+ setTimeout(() => {
155
+ startFloating();
156
+ if (searchable && dropdownRef) {
157
+ const searchInput = dropdownRef.querySelector?.(
158
+ ".ttdk-selectbox-search-input"
159
+ );
160
+ if (searchInput) {
161
+ searchInput.focus();
162
+ }
163
+ }
164
+ }, 0);
165
+ } else {
166
+ stopFloating();
167
+ searchQuery = "";
168
+ if (onClose)
169
+ onClose();
170
+ }
171
+ }
172
+ function closeDropdown() {
173
+ stopFloating();
174
+ isOpen = false;
175
+ searchQuery = "";
176
+ if (onClose)
177
+ onClose();
178
+ }
179
+ function normalizedOptions() {
180
+ if (!options || !Array.isArray(options))
181
+ return [];
182
+ return options.map((opt) => {
183
+ if (typeof opt === "object" && opt !== null) {
184
+ return {
185
+ label: String(opt.label ?? opt.value ?? ""),
186
+ value: opt.value ?? opt.label ?? "",
187
+ disabled: Boolean(opt.disabled)
188
+ };
189
+ }
190
+ return {
191
+ label: String(opt),
192
+ value: opt,
193
+ disabled: false
194
+ };
195
+ });
196
+ }
197
+ function filteredOptions(query, _opts) {
198
+ const opts = normalizedOptions();
199
+ const currentQ = query !== void 0 ? query : searchQuery;
200
+ if (!currentQ || !currentQ.trim())
201
+ return opts;
202
+ const q = currentQ.toLowerCase().trim();
203
+ return opts.filter((opt) => opt.label && opt.label.toLowerCase().includes(q));
204
+ }
205
+ function isOptionSelected(optValue, _multi, _curr) {
206
+ if (multiple) {
207
+ const list = isOpen ? tempMultiValue : Array.isArray(currentValue) ? currentValue : [];
208
+ return list.some((v) => String(v) === String(optValue));
209
+ }
210
+ return String(currentValue) === String(optValue);
211
+ }
212
+ function handleSingleSelect(opt) {
213
+ if (opt.disabled || disabled)
214
+ return;
215
+ currentValue = opt.value;
216
+ if (onChange) {
217
+ onChange(opt.value);
218
+ }
219
+ closeDropdown();
220
+ }
221
+ function handleMultiToggle(opt) {
222
+ if (opt.disabled || disabled)
223
+ return;
224
+ const index = tempMultiValue.findIndex(
225
+ (v) => String(v) === String(opt.value)
226
+ );
227
+ if (index > -1) {
228
+ tempMultiValue = tempMultiValue.filter((_, i) => i !== index);
229
+ } else {
230
+ tempMultiValue = [...tempMultiValue, opt.value];
231
+ }
232
+ }
233
+ function handleRemoveTag(val, event) {
234
+ if (event && event.stopPropagation)
235
+ event.stopPropagation();
236
+ if (disabled)
237
+ return;
238
+ if (Array.isArray(currentValue)) {
239
+ const next = currentValue.filter((v) => String(v) !== String(val));
240
+ currentValue = next;
241
+ tempMultiValue = [...next];
242
+ if (onChange) {
243
+ onChange(next);
244
+ }
245
+ }
246
+ }
247
+ function handleApply() {
248
+ currentValue = [...tempMultiValue];
249
+ if (onChange) {
250
+ onChange(currentValue);
251
+ }
252
+ closeDropdown();
253
+ }
254
+ function handleReset() {
255
+ tempMultiValue = [];
256
+ currentValue = [];
257
+ if (onChange) {
258
+ onChange([]);
259
+ }
260
+ }
261
+ function handleSearchInput(e) {
262
+ searchQuery = e.target.value;
263
+ if (onSearch) {
264
+ onSearch(e.target.value);
265
+ }
266
+ }
267
+ function getSingleSelectedLabel() {
268
+ const opts = normalizedOptions();
269
+ const match = opts.find(
270
+ (opt) => String(opt.value) === String(currentValue)
271
+ );
272
+ return match ? match.label : "";
273
+ }
274
+ function getMultiSelectedChips() {
275
+ const list = Array.isArray(currentValue) ? currentValue : [];
276
+ const opts = normalizedOptions();
277
+ return list.map((val) => {
278
+ const match = opts.find((o) => String(o.value) === String(val));
279
+ return {
280
+ value: val,
281
+ label: match ? match.label : String(val)
282
+ };
283
+ });
284
+ }
285
+ function hasValue() {
286
+ if (multiple) {
287
+ return Array.isArray(currentValue) && currentValue.length > 0;
288
+ }
289
+ return currentValue !== void 0 && currentValue !== "" && currentValue !== null;
290
+ }
291
+ function handleClear(event) {
292
+ if (event && event.stopPropagation)
293
+ event.stopPropagation();
294
+ if (disabled || readOnly)
295
+ return;
296
+ const emptyVal = multiple ? [] : "";
297
+ currentValue = emptyVal;
298
+ tempMultiValue = [];
299
+ if (onChange) {
300
+ onChange(emptyVal);
301
+ }
302
+ }
303
+ let rootRef;
304
+ let controlRef;
305
+ let dropdownRef;
306
+ let isOpen = false;
307
+ let searchQuery = "";
308
+ let currentValue = value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : multiple ? [] : "";
309
+ let tempMultiValue = [];
310
+ let cleanupAutoUpdate = null;
311
+ onMount(() => {
312
+ if (typeof document !== "undefined") {
313
+ document.addEventListener(
314
+ "pointerdown",
315
+ (e) => onPointerDown(e),
316
+ true
317
+ );
318
+ }
319
+ });
320
+ onDestroy(() => {
321
+ stopFloating();
322
+ if (typeof document !== "undefined") {
323
+ document.removeEventListener(
324
+ "pointerdown",
325
+ (e) => onPointerDown(e),
326
+ true
327
+ );
328
+ }
329
+ });
330
+ </script>
331
+
332
+ <div
333
+ style={stringifyStyles({
334
+ ...buildUiVars(ui),
335
+ ...(ui || {}),
336
+ })}
337
+ bind:this={rootRef}
338
+ class={`ttdk-form-item ${className || ""}`.trim()}
339
+ data-disabled={disabled}
340
+ data-error={Boolean(error || errorMessage)}
341
+ data-size={size || "md"}
342
+ data-block={block ? "true" : undefined}
343
+ >
344
+ {#if label}
345
+ <label
346
+ style={stringifyStyles({
347
+ ...buildUiVars(labelStyle),
348
+ })}
349
+ class={`ttdk-form-label ${labelClass || ""}`.trim()}
350
+ for={id}
351
+ ><span>{label}</span>
352
+ {#if required}
353
+ <span class="ttdk-form-required" aria-hidden="true"> * </span>
354
+ {/if}
355
+ {#if optional}
356
+ <span class="ttdk-form-optional">{optionalText || "(Opsional)"}</span>
357
+ {/if}</label
358
+ >
359
+ {/if}
360
+ {#if helperText && helperTextPosition === "top"}
361
+ <div
362
+ style={stringifyStyles({
363
+ ...buildUiVars(helperTextStyle),
364
+ })}
365
+ class={`ttdk-form-helper ${helperTextClass || ""}`.trim()}
366
+ >
367
+ {helperText}
368
+ </div>
369
+ {/if}
370
+ <div
371
+ style={stringifyStyles({
372
+ ...buildUiVars(controlStyle),
373
+ })}
374
+ role="combobox"
375
+ aria-haspopup="listbox"
376
+ bind:this={controlRef}
377
+ class={`ttdk-selectbox-control ${controlClass || ""}`.trim()}
378
+ {id}
379
+ tabIndex={disabled ? -1 : 0}
380
+ aria-expanded={isOpen}
381
+ aria-disabled={disabled}
382
+ aria-invalid={Boolean(error || errorMessage)}
383
+ data-open={isOpen ? "true" : "false"}
384
+ data-filled={hasValue() ? "true" : "false"}
385
+ data-error={Boolean(error || errorMessage)}
386
+ data-disabled={Boolean(disabled)}
387
+ data-size={size || "md"}
388
+ data-rounded={rounded || "md"}
389
+ on:click={(event) => {
390
+ disabled || readOnly || loading ? undefined : toggleDropdown();
391
+ }}
392
+ on:keydown={(e) => {
393
+ if (e.key === "Enter" || e.key === " ") {
394
+ e.preventDefault();
395
+ toggleDropdown();
396
+ } else if (e.key === "Escape") {
397
+ closeDropdown();
398
+ }
399
+ }}
400
+ >
401
+ <div class="ttdk-selectbox-display">
402
+ {#if multiple && hasValue()}
403
+ <div class="ttdk-selectbox-chips">
404
+ {#each getMultiSelectedChips() as chip (chip.value)}
405
+ <span class="ttdk-select-chip"
406
+ ><span class="ttdk-select-chip-text">{chip.label}</span><button
407
+ type="button"
408
+ class="ttdk-select-chip-remove"
409
+ aria-label={`Hapus ${chip.label}`}
410
+ on:click={(e) => {
411
+ handleRemoveTag(chip.value, e);
412
+ }}
413
+ ><svg
414
+ class="ttdk-select-chip-remove-icon"
415
+ viewBox="0 0 24 24"
416
+ fill="none"
417
+ ><line x1="18" y1="6" x2="6" y2="18" /><line
418
+ x1="6"
419
+ y1="6"
420
+ x2="18"
421
+ y2="18"
422
+ /></svg
423
+ ></button
424
+ ></span
425
+ >
426
+ {/each}
427
+ </div>
428
+ {/if}
429
+ {#if !multiple && hasValue()}
430
+ <span class="ttdk-selectbox-value">{getSingleSelectedLabel()}</span>
431
+ {/if}
432
+ {#if !hasValue()}
433
+ <span class="ttdk-selectbox-placeholder"
434
+ >{placeholder || "Pilih dropdown menu"}</span
435
+ >
436
+ {/if}
437
+ </div>
438
+ {#if clearable && hasValue() && !disabled && !readOnly && !loading}
439
+ <button
440
+ type="button"
441
+ class="ttdk-selectbox-clear"
442
+ aria-label="Hapus pilihan"
443
+ on:click={(e) => {
444
+ handleClear(e);
445
+ }}
446
+ ><svg class="ttdk-selectbox-clear-icon" viewBox="0 0 24 24" fill="none"
447
+ ><line x1="18" y1="6" x2="6" y2="18" /><line
448
+ x1="6"
449
+ y1="6"
450
+ x2="18"
451
+ y2="18"
452
+ /></svg
453
+ ></button
454
+ >
455
+ {/if}
456
+ {#if loading}
457
+ <span class="ttdk-selectbox-spinner" aria-hidden="true"
458
+ ><svg
459
+ class="ttdk-selectbox-spinner-icon"
460
+ viewBox="0 0 24 24"
461
+ fill="none"
462
+ ><line
463
+ x1="12"
464
+ y1="2.5"
465
+ x2="12"
466
+ y2="6.5"
467
+ opacity="0.175"
468
+ transform="rotate(0 12 12)"
469
+ /><line
470
+ x1="12"
471
+ y1="2.5"
472
+ x2="12"
473
+ y2="6.5"
474
+ opacity="0.25"
475
+ transform="rotate(30 12 12)"
476
+ /><line
477
+ x1="12"
478
+ y1="2.5"
479
+ x2="12"
480
+ y2="6.5"
481
+ opacity="0.325"
482
+ transform="rotate(60 12 12)"
483
+ /><line
484
+ x1="12"
485
+ y1="2.5"
486
+ x2="12"
487
+ y2="6.5"
488
+ opacity="0.4"
489
+ transform="rotate(90 12 12)"
490
+ /><line
491
+ x1="12"
492
+ y1="2.5"
493
+ x2="12"
494
+ y2="6.5"
495
+ opacity="0.475"
496
+ transform="rotate(120 12 12)"
497
+ /><line
498
+ x1="12"
499
+ y1="2.5"
500
+ x2="12"
501
+ y2="6.5"
502
+ opacity="0.55"
503
+ transform="rotate(150 12 12)"
504
+ /><line
505
+ x1="12"
506
+ y1="2.5"
507
+ x2="12"
508
+ y2="6.5"
509
+ opacity="0.625"
510
+ transform="rotate(180 12 12)"
511
+ /><line
512
+ x1="12"
513
+ y1="2.5"
514
+ x2="12"
515
+ y2="6.5"
516
+ opacity="0.7"
517
+ transform="rotate(210 12 12)"
518
+ /><line
519
+ x1="12"
520
+ y1="2.5"
521
+ x2="12"
522
+ y2="6.5"
523
+ opacity="0.775"
524
+ transform="rotate(240 12 12)"
525
+ /><line
526
+ x1="12"
527
+ y1="2.5"
528
+ x2="12"
529
+ y2="6.5"
530
+ opacity="0.85"
531
+ transform="rotate(270 12 12)"
532
+ /><line
533
+ x1="12"
534
+ y1="2.5"
535
+ x2="12"
536
+ y2="6.5"
537
+ opacity="0.925"
538
+ transform="rotate(300 12 12)"
539
+ /><line
540
+ x1="12"
541
+ y1="2.5"
542
+ x2="12"
543
+ y2="6.5"
544
+ opacity="1"
545
+ transform="rotate(330 12 12)"
546
+ /></svg
547
+ ></span
548
+ >
549
+ {/if}
550
+ {#if !loading}
551
+ <span class="ttdk-selectbox-arrow" data-open={isOpen ? "true" : "false"}
552
+ ><svg class="ttdk-selectbox-arrow-icon" viewBox="0 0 24 24" fill="none"
553
+ ><polyline points="6 9 12 15 18 9" /></svg
554
+ ></span
555
+ >
556
+ {/if}
557
+ </div>
558
+ {#if isOpen && !disabled}
559
+ <div
560
+ style={stringifyStyles({
561
+ ...buildUiVars(menuStyle || listStyle),
562
+ })}
563
+ role="listbox"
564
+ bind:this={dropdownRef}
565
+ class={`ttdk-selectbox-dropdown ${menuClass || ""}`.trim()}
566
+ >
567
+ {#if searchable}
568
+ <div
569
+ class="ttdk-selectbox-search"
570
+ on:click={(e) => {
571
+ e.stopPropagation();
572
+ }}
573
+ >
574
+ <input
575
+ type="text"
576
+ class="ttdk-selectbox-search-input"
577
+ placeholder={searchPlaceholder || "Cari"}
578
+ value={searchQuery}
579
+ on:input={(e) => {
580
+ handleSearchInput(e);
581
+ }}
582
+ autoFocus={true}
583
+ /><span class="ttdk-selectbox-search-icon" aria-hidden="true"
584
+ ><svg
585
+ class="ttdk-selectbox-search-svg"
586
+ viewBox="0 0 24 24"
587
+ fill="none"
588
+ ><circle cx="11" cy="11" r="8" /><line
589
+ x1="21"
590
+ y1="21"
591
+ x2="16.65"
592
+ y2="16.65"
593
+ /></svg
594
+ ></span
595
+ >
596
+ </div>
597
+ {/if}
598
+ <div class="ttdk-selectbox-options-list">
599
+ {#each filteredOptions(searchQuery, options) as opt (opt.value)}
600
+ <div
601
+ role="option"
602
+ class={`ttdk-selectbox-option ${listClass || ""}`.trim()}
603
+ aria-selected={isOptionSelected(opt.value, tempMultiValue, currentValue)}
604
+ aria-disabled={opt.disabled}
605
+ data-selected={isOptionSelected(opt.value, tempMultiValue, currentValue) ? "true" : "false"}
606
+ data-disabled={opt.disabled ? "true" : "false"}
607
+ on:click={(e) => {
608
+ e.stopPropagation();
609
+ if (multiple) {
610
+ handleMultiToggle(opt);
611
+ } else {
612
+ handleSingleSelect(opt);
613
+ }
614
+ }}
615
+ >
616
+ {#if multiple}
617
+ <span
618
+ class="ttdk-selectbox-checkbox"
619
+ data-checked={isOptionSelected(opt.value, tempMultiValue, currentValue) ? "true" : "false"}
620
+ >
621
+ {#if isOptionSelected(opt.value, tempMultiValue, currentValue)}
622
+ <svg
623
+ class="ttdk-selectbox-checkbox-icon"
624
+ viewBox="0 0 24 24"
625
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
626
+ >
627
+ {/if}</span
628
+ >
629
+ {/if}<span class="ttdk-selectbox-option-label">{opt.label}</span>
630
+ {#if !multiple && isOptionSelected(opt.value, tempMultiValue, currentValue)}
631
+ <span class="ttdk-selectbox-check-icon" aria-hidden="true"
632
+ ><svg
633
+ class="ttdk-selectbox-check-svg"
634
+ viewBox="0 0 24 24"
635
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
636
+ ></span
637
+ >
638
+ {/if}
639
+ </div>
640
+ {/each}
641
+
642
+ {#if filteredOptions(searchQuery, options).length === 0}
643
+ <div class="ttdk-selectbox-empty">Tidak ada pilihan ditemukan</div>
644
+ {/if}
645
+ </div>
646
+ {#if multiple}
647
+ <div
648
+ class="ttdk-selectbox-actions"
649
+ on:click={(e) => {
650
+ e.stopPropagation();
651
+ }}
652
+ >
653
+ <button
654
+ type="button"
655
+ class="ttdk-selectbox-btn-reset"
656
+ on:click={(event) => {
657
+ handleReset();
658
+ }}
659
+ ><svg
660
+ class="ttdk-selectbox-btn-reset-icon"
661
+ viewBox="0 0 24 24"
662
+ fill="none"
663
+ ><path
664
+ d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"
665
+ /><path d="M3 3v5h5" /></svg
666
+ ><span>{resetText || "Reset"}</span></button
667
+ ><button
668
+ type="button"
669
+ class="ttdk-selectbox-btn-apply"
670
+ on:click={(event) => {
671
+ handleApply();
672
+ }}
673
+ ><span>{applyText || "Terapkan"}</span><svg
674
+ class="ttdk-selectbox-btn-apply-icon"
675
+ viewBox="0 0 24 24"
676
+ fill="none"><polyline points="20 6 9 17 4 12" /></svg
677
+ ></button
678
+ >
679
+ </div>
680
+ {/if}
681
+ </div>
682
+ {/if}
683
+ {#if helperText && helperTextPosition !== "top"}
684
+ <div
685
+ style={stringifyStyles({
686
+ ...buildUiVars(helperTextStyle),
687
+ })}
688
+ class={`ttdk-form-helper ${helperTextClass || ""}`.trim()}
689
+ >
690
+ {helperText}
691
+ </div>
692
+ {/if}
693
+ {#if errorMessage}
694
+ <div
695
+ style={stringifyStyles({
696
+ ...buildUiVars(errorMessageStyle),
697
+ })}
698
+ role="alert"
699
+ class={`ttdk-form-error ${errorMessageClass || ""}`.trim()}
700
+ >
701
+ {errorMessage}
702
+ </div>
703
+ {/if}
704
+ </div>