@ttdk-design-system/library-vue 0.0.0-stage → 1.0.1

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 (232) hide show
  1. package/AI_GUIDE.md +6518 -0
  2. package/README.md +104 -2
  3. package/llms.txt +6518 -0
  4. package/package.json +1097 -4
  5. package/src/core/index.ts +2 -0
  6. package/src/core/tailwind-preset.cjs +62 -0
  7. package/src/core/tailwind-preset.ts +85 -0
  8. package/src/core/theme/tokens.css +663 -0
  9. package/src/core/types.ts +836 -0
  10. package/src/index.ts +17 -0
  11. package/src/tailwind-preset.cjs +62 -0
  12. package/src/tailwind-preset.ts +85 -0
  13. package/src/types.ts +1 -0
  14. package/src/web/accordion/AI_GUIDE.md +149 -0
  15. package/src/web/accordion/accordion.css +1 -0
  16. package/src/web/accordion/accordion.vue +432 -0
  17. package/src/web/accordion/accordion.vue.d.ts +227 -0
  18. package/src/web/accordion/index.ts +3 -0
  19. package/src/web/accordion/manifest.json +351 -0
  20. package/src/web/alert/AI_GUIDE.md +139 -0
  21. package/src/web/alert/alert.css +1 -0
  22. package/src/web/alert/alert.vue +290 -0
  23. package/src/web/alert/alert.vue.d.ts +154 -0
  24. package/src/web/alert/index.ts +3 -0
  25. package/src/web/alert/manifest.json +240 -0
  26. package/src/web/avatar/AI_GUIDE.md +118 -0
  27. package/src/web/avatar/avatar.css +1 -0
  28. package/src/web/avatar/avatar.vue +217 -0
  29. package/src/web/avatar/avatar.vue.d.ts +135 -0
  30. package/src/web/avatar/index.ts +3 -0
  31. package/src/web/avatar/manifest.json +195 -0
  32. package/src/web/badge/AI_GUIDE.md +94 -0
  33. package/src/web/badge/badge.css +1 -0
  34. package/src/web/badge/badge.vue +135 -0
  35. package/src/web/badge/badge.vue.d.ts +108 -0
  36. package/src/web/badge/index.ts +3 -0
  37. package/src/web/badge/manifest.json +141 -0
  38. package/src/web/banner/AI_GUIDE.md +130 -0
  39. package/src/web/banner/banner.css +1 -0
  40. package/src/web/banner/banner.vue +303 -0
  41. package/src/web/banner/banner.vue.d.ts +162 -0
  42. package/src/web/banner/index.ts +3 -0
  43. package/src/web/banner/manifest.json +240 -0
  44. package/src/web/breadcrumb/AI_GUIDE.md +120 -0
  45. package/src/web/breadcrumb/breadcrumb.css +1 -0
  46. package/src/web/breadcrumb/breadcrumb.vue +313 -0
  47. package/src/web/breadcrumb/breadcrumb.vue.d.ts +139 -0
  48. package/src/web/breadcrumb/index.ts +3 -0
  49. package/src/web/breadcrumb/manifest.json +225 -0
  50. package/src/web/button/AI_GUIDE.md +121 -0
  51. package/src/web/button/button.css +1 -0
  52. package/src/web/button/button.vue +283 -0
  53. package/src/web/button/button.vue.d.ts +147 -0
  54. package/src/web/button/index.ts +3 -0
  55. package/src/web/button/manifest.json +177 -0
  56. package/src/web/calendar/AI_GUIDE.md +151 -0
  57. package/src/web/calendar/calendar.css +1 -0
  58. package/src/web/calendar/calendar.vue +1536 -0
  59. package/src/web/calendar/calendar.vue.d.ts +261 -0
  60. package/src/web/calendar/index.ts +3 -0
  61. package/src/web/calendar/manifest.json +470 -0
  62. package/src/web/card/AI_GUIDE.md +133 -0
  63. package/src/web/card/card.css +1 -0
  64. package/src/web/card/card.vue +423 -0
  65. package/src/web/card/card.vue.d.ts +232 -0
  66. package/src/web/card/index.ts +3 -0
  67. package/src/web/card/manifest.json +357 -0
  68. package/src/web/checkbox/AI_GUIDE.md +146 -0
  69. package/src/web/checkbox/checkbox.css +1 -0
  70. package/src/web/checkbox/checkbox.vue +304 -0
  71. package/src/web/checkbox/checkbox.vue.d.ts +189 -0
  72. package/src/web/checkbox/index.ts +3 -0
  73. package/src/web/checkbox/manifest.json +294 -0
  74. package/src/web/chip/AI_GUIDE.md +186 -0
  75. package/src/web/chip/chip.css +1 -0
  76. package/src/web/chip/chip.vue +220 -0
  77. package/src/web/chip/chip.vue.d.ts +140 -0
  78. package/src/web/chip/index.ts +3 -0
  79. package/src/web/chip/manifest.json +186 -0
  80. package/src/web/dropdown/AI_GUIDE.md +167 -0
  81. package/src/web/dropdown/dropdown.css +1 -0
  82. package/src/web/dropdown/dropdown.vue +1257 -0
  83. package/src/web/dropdown/dropdown.vue.d.ts +381 -0
  84. package/src/web/dropdown/index.ts +3 -0
  85. package/src/web/dropdown/manifest.json +576 -0
  86. package/src/web/flex/AI_GUIDE.md +113 -0
  87. package/src/web/flex/flex-item.vue +94 -0
  88. package/src/web/flex/flex-item.vue.d.ts +84 -0
  89. package/src/web/flex/flex.css +1 -0
  90. package/src/web/flex/flex.vue +103 -0
  91. package/src/web/flex/flex.vue.d.ts +92 -0
  92. package/src/web/flex/index.ts +5 -0
  93. package/src/web/flex/manifest.json +162 -0
  94. package/src/web/form/index.ts +7 -0
  95. package/src/web/grid/AI_GUIDE.md +112 -0
  96. package/src/web/grid/grid-item.vue +109 -0
  97. package/src/web/grid/grid-item.vue.d.ts +99 -0
  98. package/src/web/grid/grid.css +1 -0
  99. package/src/web/grid/grid.vue +94 -0
  100. package/src/web/grid/grid.vue.d.ts +84 -0
  101. package/src/web/grid/index.ts +5 -0
  102. package/src/web/grid/manifest.json +153 -0
  103. package/src/web/index.ts +86 -0
  104. package/src/web/input/AI_GUIDE.md +159 -0
  105. package/src/web/input/index.ts +3 -0
  106. package/src/web/input/input.css +1 -0
  107. package/src/web/input/input.vue +521 -0
  108. package/src/web/input/input.vue.d.ts +274 -0
  109. package/src/web/input/manifest.json +465 -0
  110. package/src/web/input-number/AI_GUIDE.md +164 -0
  111. package/src/web/input-number/index.ts +3 -0
  112. package/src/web/input-number/input-number.css +1 -0
  113. package/src/web/input-number/input-number.vue +1153 -0
  114. package/src/web/input-number/input-number.vue.d.ts +343 -0
  115. package/src/web/input-number/manifest.json +575 -0
  116. package/src/web/modal/AI_GUIDE.md +171 -0
  117. package/src/web/modal/index.ts +3 -0
  118. package/src/web/modal/manifest.json +375 -0
  119. package/src/web/modal/modal.css +1 -0
  120. package/src/web/modal/modal.vue +344 -0
  121. package/src/web/modal/modal.vue.d.ts +64 -0
  122. package/src/web/pagination/AI_GUIDE.md +148 -0
  123. package/src/web/pagination/index.ts +21 -0
  124. package/src/web/pagination/manifest.json +432 -0
  125. package/src/web/pagination/pagination-content.vue +42 -0
  126. package/src/web/pagination/pagination-content.vue.d.ts +28 -0
  127. package/src/web/pagination/pagination-ellipsis.vue +55 -0
  128. package/src/web/pagination/pagination-ellipsis.vue.d.ts +28 -0
  129. package/src/web/pagination/pagination-first.vue +161 -0
  130. package/src/web/pagination/pagination-first.vue.d.ts +67 -0
  131. package/src/web/pagination/pagination-item.vue +42 -0
  132. package/src/web/pagination/pagination-item.vue.d.ts +28 -0
  133. package/src/web/pagination/pagination-last.vue +161 -0
  134. package/src/web/pagination/pagination-last.vue.d.ts +67 -0
  135. package/src/web/pagination/pagination-link.vue +118 -0
  136. package/src/web/pagination/pagination-link.vue.d.ts +61 -0
  137. package/src/web/pagination/pagination-next.vue +160 -0
  138. package/src/web/pagination/pagination-next.vue.d.ts +68 -0
  139. package/src/web/pagination/pagination-previous.vue +160 -0
  140. package/src/web/pagination/pagination-previous.vue.d.ts +68 -0
  141. package/src/web/pagination/pagination.css +1 -0
  142. package/src/web/pagination/pagination.vue +730 -0
  143. package/src/web/pagination/pagination.vue.d.ts +247 -0
  144. package/src/web/popover/AI_GUIDE.md +163 -0
  145. package/src/web/popover/index.ts +3 -0
  146. package/src/web/popover/manifest.json +396 -0
  147. package/src/web/popover/popover.css +1 -0
  148. package/src/web/popover/popover.vue +579 -0
  149. package/src/web/popover/popover.vue.d.ts +83 -0
  150. package/src/web/radio/AI_GUIDE.md +155 -0
  151. package/src/web/radio/index.ts +3 -0
  152. package/src/web/radio/manifest.json +294 -0
  153. package/src/web/radio/radio.css +1 -0
  154. package/src/web/radio/radio.vue +288 -0
  155. package/src/web/radio/radio.vue.d.ts +182 -0
  156. package/src/web/selectbox/AI_GUIDE.md +216 -0
  157. package/src/web/selectbox/index.ts +3 -0
  158. package/src/web/selectbox/manifest.json +477 -0
  159. package/src/web/selectbox/selectbox.css +1 -0
  160. package/src/web/selectbox/selectbox.vue +1024 -0
  161. package/src/web/selectbox/selectbox.vue.d.ts +300 -0
  162. package/src/web/sonner/AI_GUIDE.md +98 -0
  163. package/src/web/sonner/index.ts +114 -0
  164. package/src/web/sonner/manifest.json +132 -0
  165. package/src/web/sonner/sonner.css +1 -0
  166. package/src/web/sonner/sonner.vue +180 -0
  167. package/src/web/sonner/sonner.vue.d.ts +113 -0
  168. package/src/web/table/AI_GUIDE.md +145 -0
  169. package/src/web/table/index.ts +34 -0
  170. package/src/web/table/manifest.json +168 -0
  171. package/src/web/table/table-body.vue +42 -0
  172. package/src/web/table/table-body.vue.d.ts +28 -0
  173. package/src/web/table/table-caption.vue +42 -0
  174. package/src/web/table/table-caption.vue.d.ts +28 -0
  175. package/src/web/table/table-cell.vue +71 -0
  176. package/src/web/table/table-cell.vue.d.ts +49 -0
  177. package/src/web/table/table-empty.vue +105 -0
  178. package/src/web/table/table-empty.vue.d.ts +57 -0
  179. package/src/web/table/table-footer.vue +42 -0
  180. package/src/web/table/table-footer.vue.d.ts +28 -0
  181. package/src/web/table/table-head.vue +78 -0
  182. package/src/web/table/table-head.vue.d.ts +50 -0
  183. package/src/web/table/table-header.vue +42 -0
  184. package/src/web/table/table-header.vue.d.ts +28 -0
  185. package/src/web/table/table-row.vue +70 -0
  186. package/src/web/table/table-row.vue.d.ts +44 -0
  187. package/src/web/table/table.css +1 -0
  188. package/src/web/table/table.vue +298 -0
  189. package/src/web/table/table.vue.d.ts +119 -0
  190. package/src/web/tabs/AI_GUIDE.md +150 -0
  191. package/src/web/tabs/index.ts +2 -0
  192. package/src/web/tabs/manifest.json +315 -0
  193. package/src/web/tabs/tabs.css +1 -0
  194. package/src/web/tabs/tabs.vue +164 -0
  195. package/src/web/tabs/tabs.vue.d.ts +60 -0
  196. package/src/web/text/AI_GUIDE.md +129 -0
  197. package/src/web/text/index.ts +2 -0
  198. package/src/web/text/manifest.json +195 -0
  199. package/src/web/text/text.css +1 -0
  200. package/src/web/text/text.vue +195 -0
  201. package/src/web/text/text.vue.d.ts +161 -0
  202. package/src/web/textarea/AI_GUIDE.md +141 -0
  203. package/src/web/textarea/index.ts +3 -0
  204. package/src/web/textarea/manifest.json +438 -0
  205. package/src/web/textarea/textarea.css +1 -0
  206. package/src/web/textarea/textarea.vue +458 -0
  207. package/src/web/textarea/textarea.vue.d.ts +265 -0
  208. package/src/web/tooltip/AI_GUIDE.md +110 -0
  209. package/src/web/tooltip/index.ts +3 -0
  210. package/src/web/tooltip/manifest.json +222 -0
  211. package/src/web/tooltip/tooltip.css +1 -0
  212. package/src/web/tooltip/tooltip.vue +417 -0
  213. package/src/web/tooltip/tooltip.vue.d.ts +150 -0
  214. package/src/webview/bottomsheet/AI_GUIDE.md +141 -0
  215. package/src/webview/bottomsheet/bottomsheet.css +1 -0
  216. package/src/webview/bottomsheet/bottomsheet.vue +441 -0
  217. package/src/webview/bottomsheet/bottomsheet.vue.d.ts +178 -0
  218. package/src/webview/bottomsheet/index.ts +4 -0
  219. package/src/webview/bottomsheet/manifest.json +377 -0
  220. package/src/webview/button/AI_GUIDE.md +79 -0
  221. package/src/webview/button/button-ios.css +1 -0
  222. package/src/webview/button/button-ios.vue +138 -0
  223. package/src/webview/button/button-ios.vue.d.ts +102 -0
  224. package/src/webview/button/button-material.css +1 -0
  225. package/src/webview/button/button-material.vue +138 -0
  226. package/src/webview/button/button-material.vue.d.ts +102 -0
  227. package/src/webview/button/index.ts +7 -0
  228. package/src/webview/button/manifest.json +148 -0
  229. package/src/webview/index.ts +7 -0
  230. package/tailwind-preset.cjs +62 -0
  231. package/tailwind-preset.js +62 -0
  232. package/ttdk-manifest.json +10188 -0
@@ -0,0 +1,313 @@
1
+ <template>
2
+ <nav
3
+ aria-label="Breadcrumb"
4
+ :class="`ttdk-breadcrumb ${className || ''}`.trim()"
5
+ :data-size="size || 'md'"
6
+ :style="{
7
+ ...buildUiVars(ui),
8
+ ...(typeof style === 'object' ? style : {}),
9
+ }"
10
+ >
11
+ <ol class="ttdk-breadcrumb-list">
12
+ <template :key="index" v-for="(item, index) in getVisibleItems()">
13
+ <li class="ttdk-breadcrumb-item">
14
+ <template v-if="item.isEllipsis">
15
+ <span class="ttdk-breadcrumb-ellipsis" aria-hidden="true">
16
+ ···
17
+ </span>
18
+ </template>
19
+
20
+ <template
21
+ v-if="
22
+ !item.isEllipsis &&
23
+ (item.current || index === getVisibleItems().length - 1)
24
+ "
25
+ >
26
+ <span
27
+ aria-current="page"
28
+ :class="`ttdk-breadcrumb-current ${textActiveClass || ''}`.trim()"
29
+ :data-disabled="item.disabled ? 'true' : 'false'"
30
+ :style="{
31
+ ...buildUiVars(textActiveStyle),
32
+ }"
33
+ >
34
+ <template v-if="item.icon">
35
+ <span class="ttdk-breadcrumb-icon">{{ item.icon }}</span>
36
+ </template>
37
+
38
+ <span class="ttdk-breadcrumb-label" :title="item.label">{{
39
+ formatLabel(item.label)
40
+ }}</span></span
41
+ >
42
+ </template>
43
+
44
+ <template
45
+ v-if="
46
+ !item.isEllipsis &&
47
+ !item.current &&
48
+ index !== getVisibleItems().length - 1
49
+ "
50
+ >
51
+ <template v-if="item.href">
52
+ <a
53
+ :href="item.href"
54
+ :class="`ttdk-breadcrumb-link ${textLinkClass || ''}`.trim()"
55
+ :data-disabled="item.disabled ? 'true' : 'false'"
56
+ :title="item.label"
57
+ :style="{
58
+ ...buildUiVars(textLinkStyle),
59
+ }"
60
+ @click="
61
+ async (e) => {
62
+ if (item.disabled) {
63
+ e.preventDefault();
64
+ return;
65
+ }
66
+ if (onItemClick) {
67
+ onItemClick(item, index, e);
68
+ }
69
+ }
70
+ "
71
+ >
72
+ <template v-if="item.icon">
73
+ <span class="ttdk-breadcrumb-icon">{{ item.icon }}</span>
74
+ </template>
75
+
76
+ <span class="ttdk-breadcrumb-label">{{
77
+ formatLabel(item.label)
78
+ }}</span></a
79
+ >
80
+ </template>
81
+
82
+ <template v-if="!item.href">
83
+ <button
84
+ type="button"
85
+ :class="
86
+ `ttdk-breadcrumb-link ttdk-breadcrumb-btn ${
87
+ textLinkClass || ''
88
+ }`.trim()
89
+ "
90
+ :data-disabled="item.disabled ? 'true' : 'false'"
91
+ :disabled="item.disabled"
92
+ :title="item.label"
93
+ :style="{
94
+ ...buildUiVars(textLinkStyle),
95
+ }"
96
+ @click="
97
+ async (e) => {
98
+ if (onItemClick) {
99
+ onItemClick(item, index, e);
100
+ }
101
+ }
102
+ "
103
+ >
104
+ <template v-if="item.icon">
105
+ <span class="ttdk-breadcrumb-icon">{{ item.icon }}</span>
106
+ </template>
107
+
108
+ <span class="ttdk-breadcrumb-label">{{
109
+ formatLabel(item.label)
110
+ }}</span>
111
+ </button>
112
+ </template>
113
+ </template>
114
+
115
+ <template v-if="index !== getVisibleItems().length - 1">
116
+ <span
117
+ aria-hidden="true"
118
+ :class="
119
+ `ttdk-breadcrumb-separator ${separatorClass || ''}`.trim()
120
+ "
121
+ :style="{
122
+ ...buildUiVars(separatorStyle),
123
+ }"
124
+ >
125
+ <template v-if="customSeparator">
126
+ <span class="ttdk-separator-char">{{ customSeparator }}</span>
127
+ </template>
128
+
129
+ <template v-if="!customSeparator">
130
+ <svg
131
+ class="ttdk-separator-icon"
132
+ xmlns="http://www.w3.org/2000/svg"
133
+ viewBox="0 0 640 640"
134
+ >
135
+ <path
136
+ d="M297.4 470.6C309.9 483.1 330.2 483.1 342.7 470.6L534.7 278.6C547.2 266.1 547.2 245.8 534.7 233.3C522.2 220.8 501.9 220.8 489.4 233.3L320 402.7L150.6 233.4C138.1 220.9 117.8 220.9 105.3 233.4C92.8 245.9 92.8 266.2 105.3 278.7L297.3 470.7z"
137
+ ></path>
138
+ </svg>
139
+ </template>
140
+ </span>
141
+ </template>
142
+ </li>
143
+ </template>
144
+ </ol>
145
+ <template v-if="$slots.default">
146
+ <div class="ttdk-breadcrumb-slot"><slot /></div>
147
+ </template>
148
+ </nav>
149
+ </template>
150
+
151
+ <script setup lang="ts">
152
+ import { buildUiVars, UiProps } from "../../core/types";
153
+
154
+ export interface BreadcrumbItem {
155
+ /**
156
+ * Label teks yang ditampilkan pada breadcrumb item.
157
+ */
158
+ label: string;
159
+
160
+ /**
161
+ * URL tautan navigasi tujuan (href / path).
162
+ */
163
+ href?: string;
164
+
165
+ /**
166
+ * Ikon atau emoji opsional di samping label teks.
167
+ */
168
+ icon?: any;
169
+
170
+ /**
171
+ * Menandai item ini secara eksplisit sebagai halaman saat ini (current page).
172
+ */
173
+ current?: boolean;
174
+
175
+ /**
176
+ * Menonaktifkan interaksi klik pada item ini.
177
+ * @default false
178
+ */
179
+ disabled?: boolean;
180
+
181
+ /**
182
+ * Menandai item sebagai representasi ellipsis penyingkat item yang tersembunyi.
183
+ */
184
+ isEllipsis?: boolean;
185
+ }
186
+ export type BreadcrumbUiProps = UiProps;
187
+ export type BreadcrumbSeparator = "chevron";
188
+ export interface BreadcrumbProps {
189
+ /**
190
+ * Daftar item navigasi breadcrumb dari tingkat teratas hingga halaman saat ini.
191
+ */
192
+ items: BreadcrumbItem[];
193
+
194
+ /**
195
+ * Jenis karakter atau ikon pemisah antar item:
196
+ * - `'arrow'`: Ikon panah kanan `→`.
197
+ *
198
+ * @default 'arrow'
199
+ */
200
+ separator?: BreadcrumbSeparator;
201
+
202
+ /**
203
+ * Karakter atau string teks khusus untuk pemisah antarelemen.
204
+ */
205
+ customSeparator?: string;
206
+
207
+ /**
208
+ * Skala ukuran tampilan breadcrumb:
209
+ * - `'sm'`: Kompak (12px, gap 6px).
210
+ * - `'md'`: Standar (14px, gap 8px).
211
+ * - `'lg'`: Besar (16px, gap 12px).
212
+ *
213
+ * @default 'md'
214
+ */
215
+ size?: "sm" | "md" | "lg";
216
+
217
+ /**
218
+ * Batas maksimum panjang karakter label sebelum dipotong (truncate).
219
+ * @default 20
220
+ */
221
+ maxLabelLength?: number;
222
+
223
+ /**
224
+ * Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active).
225
+ */
226
+ ui?: UiProps;
227
+
228
+ /**
229
+ * Inline CSS style object native.
230
+ */
231
+ style?: any;
232
+
233
+ /**
234
+ * Style kustom untuk teks tautan breadcrumb / item non-aktif (UiProps).
235
+ */
236
+ textLinkStyle?: UiProps;
237
+
238
+ /**
239
+ * Class CSS kustom untuk teks tautan breadcrumb / item non-aktif (Tailwind / class kustom).
240
+ */
241
+ textLinkClass?: string;
242
+
243
+ /**
244
+ * Style kustom untuk teks item aktif / halaman saat ini (UiProps).
245
+ */
246
+ textActiveStyle?: UiProps;
247
+
248
+ /**
249
+ * Class CSS kustom untuk teks item aktif / halaman saat ini (Tailwind / class kustom).
250
+ */
251
+ textActiveClass?: string;
252
+
253
+ /**
254
+ * Style kustom untuk karakter atau ikon pemisah (UiProps).
255
+ */
256
+ separatorStyle?: UiProps;
257
+
258
+ /**
259
+ * Class CSS kustom untuk karakter atau ikon pemisah (Tailwind / class kustom).
260
+ */
261
+ separatorClass?: string;
262
+
263
+ /**
264
+ * Handler event klik yang dipanggil saat suatu item breadcrumb diklik.
265
+ *
266
+ * @param item Data item yang diklik.
267
+ * @param index Indeks urutan item dalam array.
268
+ * @param event Objek synthetic DOM event.
269
+ */
270
+ onItemClick?: (item: BreadcrumbItem, index: number, event: any) => void;
271
+
272
+ /**
273
+ * Class CSS kustom.
274
+ */
275
+ className?: string;
276
+
277
+ /**
278
+ * Slot konten tambahan di ujung kanan breadcrumb.
279
+ */
280
+ children?: any;
281
+ }
282
+
283
+ /**
284
+ * Komponen Breadcrumb untuk menampilkan hierarki navigasi lokasi halaman saat ini dengan dukungan penyingkatan (collapse ellipsis).
285
+ */
286
+
287
+ const props = defineProps<BreadcrumbProps>();
288
+
289
+ function formatLabel(label: any) {
290
+ if (!label && label !== 0) return "";
291
+ const str = String(label);
292
+ const max = props.maxLabelLength !== undefined ? props.maxLabelLength : 20;
293
+ if (max > 0 && str.length > max) {
294
+ return `${str.slice(0, max)}...`;
295
+ }
296
+ return str;
297
+ }
298
+ function getVisibleItems() {
299
+ if (!props.items || props.items.length === 0) return [];
300
+ const total = props.items.length;
301
+ if (total <= 3) {
302
+ return props.items;
303
+ }
304
+ const before = Math.max(1, Math.min(3, total - 2));
305
+ const startItems = props.items.slice(0, before);
306
+ const endItems = props.items.slice(total - 1);
307
+ const ellipsisItem: BreadcrumbItem = {
308
+ label: "...",
309
+ isEllipsis: true,
310
+ };
311
+ return [...startItems, ellipsisItem, ...endItems];
312
+ }
313
+ </script>
@@ -0,0 +1,139 @@
1
+ /* eslint-disable */
2
+ // Auto-generated by TTDK Design System Vue Type Generator
3
+ import type { DefineComponent } from "vue";
4
+ import { buildUiVars, UiProps } from "../../core/types";
5
+
6
+ export interface BreadcrumbItem {
7
+ /**
8
+ * Label teks yang ditampilkan pada breadcrumb item.
9
+ */
10
+ label: string;
11
+
12
+ /**
13
+ * URL tautan navigasi tujuan (href / path).
14
+ */
15
+ href?: string;
16
+
17
+ /**
18
+ * Ikon atau emoji opsional di samping label teks.
19
+ */
20
+ icon?: any;
21
+
22
+ /**
23
+ * Menandai item ini secara eksplisit sebagai halaman saat ini (current page).
24
+ */
25
+ current?: boolean;
26
+
27
+ /**
28
+ * Menonaktifkan interaksi klik pada item ini.
29
+ * @default false
30
+ */
31
+ disabled?: boolean;
32
+
33
+ /**
34
+ * Menandai item sebagai representasi ellipsis penyingkat item yang tersembunyi.
35
+ */
36
+ isEllipsis?: boolean;
37
+ }
38
+
39
+ export type BreadcrumbUiProps = UiProps;
40
+
41
+ export type BreadcrumbSeparator = "chevron";
42
+
43
+ export interface BreadcrumbProps {
44
+ /**
45
+ * Daftar item navigasi breadcrumb dari tingkat teratas hingga halaman saat ini.
46
+ */
47
+ items: BreadcrumbItem[];
48
+
49
+ /**
50
+ * Jenis karakter atau ikon pemisah antar item:
51
+ * - `'arrow'`: Ikon panah kanan `→`.
52
+ *
53
+ * @default 'arrow'
54
+ */
55
+ separator?: BreadcrumbSeparator;
56
+
57
+ /**
58
+ * Karakter atau string teks khusus untuk pemisah antarelemen.
59
+ */
60
+ customSeparator?: string;
61
+
62
+ /**
63
+ * Skala ukuran tampilan breadcrumb:
64
+ * - `'sm'`: Kompak (12px, gap 6px).
65
+ * - `'md'`: Standar (14px, gap 8px).
66
+ * - `'lg'`: Besar (16px, gap 12px).
67
+ *
68
+ * @default 'md'
69
+ */
70
+ size?: "sm" | "md" | "lg";
71
+
72
+ /**
73
+ * Batas maksimum panjang karakter label sebelum dipotong (truncate).
74
+ * @default 20
75
+ */
76
+ maxLabelLength?: number;
77
+
78
+ /**
79
+ * Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active).
80
+ */
81
+ ui?: UiProps;
82
+
83
+ /**
84
+ * Inline CSS style object native.
85
+ */
86
+ style?: any;
87
+
88
+ /**
89
+ * Style kustom untuk teks tautan breadcrumb / item non-aktif (UiProps).
90
+ */
91
+ textLinkStyle?: UiProps;
92
+
93
+ /**
94
+ * Class CSS kustom untuk teks tautan breadcrumb / item non-aktif (Tailwind / class kustom).
95
+ */
96
+ textLinkClass?: string;
97
+
98
+ /**
99
+ * Style kustom untuk teks item aktif / halaman saat ini (UiProps).
100
+ */
101
+ textActiveStyle?: UiProps;
102
+
103
+ /**
104
+ * Class CSS kustom untuk teks item aktif / halaman saat ini (Tailwind / class kustom).
105
+ */
106
+ textActiveClass?: string;
107
+
108
+ /**
109
+ * Style kustom untuk karakter atau ikon pemisah (UiProps).
110
+ */
111
+ separatorStyle?: UiProps;
112
+
113
+ /**
114
+ * Class CSS kustom untuk karakter atau ikon pemisah (Tailwind / class kustom).
115
+ */
116
+ separatorClass?: string;
117
+
118
+ /**
119
+ * Handler event klik yang dipanggil saat suatu item breadcrumb diklik.
120
+ *
121
+ * @param item Data item yang diklik.
122
+ * @param index Indeks urutan item dalam array.
123
+ * @param event Objek synthetic DOM event.
124
+ */
125
+ onItemClick?: (item: BreadcrumbItem, index: number, event: any) => void;
126
+
127
+ /**
128
+ * Class CSS kustom.
129
+ */
130
+ className?: string;
131
+
132
+ /**
133
+ * Slot konten tambahan di ujung kanan breadcrumb.
134
+ */
135
+ children?: any;
136
+ }
137
+
138
+ declare const component: DefineComponent<BreadcrumbProps>;
139
+ export default component;
@@ -0,0 +1,3 @@
1
+ export { default } from './breadcrumb.vue';
2
+ export { default as Breadcrumb } from './breadcrumb.vue';
3
+ export * from './breadcrumb.vue';
@@ -0,0 +1,225 @@
1
+ {
2
+ "name": "@ttdk-design-system/breadcrumb",
3
+ "component": "Breadcrumb",
4
+ "folder": "breadcrumb",
5
+ "description": "Komponen Breadcrumb untuk menampilkan hierarki navigasi lokasi halaman saat ini dengan dukungan penyingkatan (collapse ellipsis).",
6
+ "stylesheets": [
7
+ {
8
+ "theme": "common",
9
+ "file": "breadcrumb.css",
10
+ "importPath": "web/breadcrumb/breadcrumb.css"
11
+ }
12
+ ],
13
+ "props": {
14
+ "items": {
15
+ "name": "items",
16
+ "type": "BreadcrumbItem[]",
17
+ "optional": false,
18
+ "default": null,
19
+ "description": "Daftar item navigasi breadcrumb dari tingkat teratas hingga halaman saat ini.",
20
+ "example": null,
21
+ "param": null
22
+ },
23
+ "separator": {
24
+ "name": "separator",
25
+ "type": "BreadcrumbSeparator",
26
+ "optional": true,
27
+ "default": "arrow",
28
+ "description": "Jenis karakter atau ikon pemisah antar item: - `'arrow'`: Ikon panah kanan `→`.",
29
+ "example": null,
30
+ "param": null
31
+ },
32
+ "customSeparator": {
33
+ "name": "customSeparator",
34
+ "type": "string",
35
+ "optional": true,
36
+ "default": null,
37
+ "description": "Karakter atau string teks khusus untuk pemisah antarelemen.",
38
+ "example": null,
39
+ "param": null
40
+ },
41
+ "size": {
42
+ "name": "size",
43
+ "type": "'sm' | 'md' | 'lg'",
44
+ "optional": true,
45
+ "default": "md",
46
+ "description": "Skala ukuran tampilan breadcrumb: - `'sm'`: Kompak (12px, gap 6px). - `'md'`: Standar (14px, gap 8px). - `'lg'`: Besar (16px, gap 12px).",
47
+ "example": null,
48
+ "param": null
49
+ },
50
+ "maxLabelLength": {
51
+ "name": "maxLabelLength",
52
+ "type": "number",
53
+ "optional": true,
54
+ "default": "20",
55
+ "description": "Batas maksimum panjang karakter label sebelum dipotong (truncate).",
56
+ "example": null,
57
+ "param": null
58
+ },
59
+ "ui": {
60
+ "name": "ui",
61
+ "type": "UiProps",
62
+ "optional": true,
63
+ "default": null,
64
+ "description": "Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active).",
65
+ "example": null,
66
+ "param": null
67
+ },
68
+ "style": {
69
+ "name": "style",
70
+ "type": "any",
71
+ "optional": true,
72
+ "default": null,
73
+ "description": "Inline CSS style object native.",
74
+ "example": null,
75
+ "param": null
76
+ },
77
+ "textLinkStyle": {
78
+ "name": "textLinkStyle",
79
+ "type": "UiProps",
80
+ "optional": true,
81
+ "default": null,
82
+ "description": "Style kustom untuk teks tautan breadcrumb / item non-aktif (UiProps).",
83
+ "example": null,
84
+ "param": null
85
+ },
86
+ "textLinkClass": {
87
+ "name": "textLinkClass",
88
+ "type": "string",
89
+ "optional": true,
90
+ "default": null,
91
+ "description": "Class CSS kustom untuk teks tautan breadcrumb / item non-aktif (Tailwind / class kustom).",
92
+ "example": null,
93
+ "param": null
94
+ },
95
+ "textActiveStyle": {
96
+ "name": "textActiveStyle",
97
+ "type": "UiProps",
98
+ "optional": true,
99
+ "default": null,
100
+ "description": "Style kustom untuk teks item aktif / halaman saat ini (UiProps).",
101
+ "example": null,
102
+ "param": null
103
+ },
104
+ "textActiveClass": {
105
+ "name": "textActiveClass",
106
+ "type": "string",
107
+ "optional": true,
108
+ "default": null,
109
+ "description": "Class CSS kustom untuk teks item aktif / halaman saat ini (Tailwind / class kustom).",
110
+ "example": null,
111
+ "param": null
112
+ },
113
+ "separatorStyle": {
114
+ "name": "separatorStyle",
115
+ "type": "UiProps",
116
+ "optional": true,
117
+ "default": null,
118
+ "description": "Style kustom untuk karakter atau ikon pemisah (UiProps).",
119
+ "example": null,
120
+ "param": null
121
+ },
122
+ "separatorClass": {
123
+ "name": "separatorClass",
124
+ "type": "string",
125
+ "optional": true,
126
+ "default": null,
127
+ "description": "Class CSS kustom untuk karakter atau ikon pemisah (Tailwind / class kustom).",
128
+ "example": null,
129
+ "param": null
130
+ },
131
+ "onItemClick": {
132
+ "name": "onItemClick",
133
+ "type": "(item: BreadcrumbItem, index: number, event: any) => void",
134
+ "optional": true,
135
+ "default": null,
136
+ "description": "Handler event klik yang dipanggil saat suatu item breadcrumb diklik.",
137
+ "example": null,
138
+ "param": "event Objek synthetic DOM event."
139
+ },
140
+ "className": {
141
+ "name": "className",
142
+ "type": "string",
143
+ "optional": true,
144
+ "default": null,
145
+ "description": "Class CSS kustom.",
146
+ "example": null,
147
+ "param": null
148
+ },
149
+ "children": {
150
+ "name": "children",
151
+ "type": "any",
152
+ "optional": true,
153
+ "default": null,
154
+ "description": "Slot konten tambahan di ujung kanan breadcrumb.",
155
+ "example": null,
156
+ "param": null
157
+ }
158
+ },
159
+ "subInterfaces": {
160
+ "BreadcrumbItem": {
161
+ "label": {
162
+ "name": "label",
163
+ "type": "string",
164
+ "optional": false,
165
+ "default": null,
166
+ "description": "Label teks yang ditampilkan pada breadcrumb item.",
167
+ "example": null,
168
+ "param": null
169
+ },
170
+ "href": {
171
+ "name": "href",
172
+ "type": "string",
173
+ "optional": true,
174
+ "default": null,
175
+ "description": "URL tautan navigasi tujuan (href / path).",
176
+ "example": null,
177
+ "param": null
178
+ },
179
+ "icon": {
180
+ "name": "icon",
181
+ "type": "any",
182
+ "optional": true,
183
+ "default": null,
184
+ "description": "Ikon atau emoji opsional di samping label teks.",
185
+ "example": null,
186
+ "param": null
187
+ },
188
+ "current": {
189
+ "name": "current",
190
+ "type": "boolean",
191
+ "optional": true,
192
+ "default": null,
193
+ "description": "Menandai item ini secara eksplisit sebagai halaman saat ini (current page).",
194
+ "example": null,
195
+ "param": null
196
+ },
197
+ "disabled": {
198
+ "name": "disabled",
199
+ "type": "boolean",
200
+ "optional": true,
201
+ "default": "false",
202
+ "description": "Menonaktifkan interaksi klik pada item ini.",
203
+ "example": null,
204
+ "param": null
205
+ },
206
+ "isEllipsis": {
207
+ "name": "isEllipsis",
208
+ "type": "boolean",
209
+ "optional": true,
210
+ "default": null,
211
+ "description": "Menandai item sebagai representasi ellipsis penyingkat item yang tersembunyi.",
212
+ "example": null,
213
+ "param": null
214
+ }
215
+ }
216
+ },
217
+ "supportedFrameworks": [
218
+ "react",
219
+ "vue",
220
+ "svelte"
221
+ ],
222
+ "themes": [
223
+ "tw"
224
+ ]
225
+ }