@ttdk-design-system/library-react 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.
- package/AI_GUIDE.md +6518 -0
- package/llms.txt +6518 -0
- package/package.json +1098 -4
- package/src/core/index.ts +2 -0
- package/src/core/tailwind-preset.cjs +62 -0
- package/src/core/tailwind-preset.ts +85 -0
- package/src/core/theme/tokens.css +663 -0
- package/src/core/types.ts +836 -0
- package/src/index.ts +17 -0
- package/src/tailwind-preset.cjs +62 -0
- package/src/tailwind-preset.ts +85 -0
- package/src/types.ts +1 -0
- package/src/web/accordion/AI_GUIDE.md +149 -0
- package/src/web/accordion/accordion.css +1 -0
- package/src/web/accordion/accordion.tsx +430 -0
- package/src/web/accordion/index.ts +3 -0
- package/src/web/accordion/manifest.json +351 -0
- package/src/web/alert/AI_GUIDE.md +139 -0
- package/src/web/alert/alert.css +1 -0
- package/src/web/alert/alert.tsx +318 -0
- package/src/web/alert/index.ts +3 -0
- package/src/web/alert/manifest.json +240 -0
- package/src/web/avatar/AI_GUIDE.md +118 -0
- package/src/web/avatar/avatar.css +1 -0
- package/src/web/avatar/avatar.tsx +233 -0
- package/src/web/avatar/index.ts +3 -0
- package/src/web/avatar/manifest.json +195 -0
- package/src/web/badge/AI_GUIDE.md +94 -0
- package/src/web/badge/badge.css +1 -0
- package/src/web/badge/badge.tsx +140 -0
- package/src/web/badge/index.ts +2 -0
- package/src/web/badge/manifest.json +141 -0
- package/src/web/banner/AI_GUIDE.md +130 -0
- package/src/web/banner/banner.css +1 -0
- package/src/web/banner/banner.tsx +334 -0
- package/src/web/banner/index.ts +3 -0
- package/src/web/banner/manifest.json +240 -0
- package/src/web/breadcrumb/AI_GUIDE.md +120 -0
- package/src/web/breadcrumb/breadcrumb.css +1 -0
- package/src/web/breadcrumb/breadcrumb.tsx +306 -0
- package/src/web/breadcrumb/index.ts +3 -0
- package/src/web/breadcrumb/manifest.json +225 -0
- package/src/web/button/AI_GUIDE.md +121 -0
- package/src/web/button/button.css +1 -0
- package/src/web/button/button.tsx +287 -0
- package/src/web/button/index.ts +2 -0
- package/src/web/button/manifest.json +177 -0
- package/src/web/calendar/AI_GUIDE.md +151 -0
- package/src/web/calendar/calendar.css +1 -0
- package/src/web/calendar/calendar.tsx +1611 -0
- package/src/web/calendar/index.ts +3 -0
- package/src/web/calendar/manifest.json +470 -0
- package/src/web/card/AI_GUIDE.md +133 -0
- package/src/web/card/card.css +1 -0
- package/src/web/card/card.tsx +408 -0
- package/src/web/card/index.ts +4 -0
- package/src/web/card/manifest.json +357 -0
- package/src/web/checkbox/AI_GUIDE.md +146 -0
- package/src/web/checkbox/checkbox.css +1 -0
- package/src/web/checkbox/checkbox.tsx +307 -0
- package/src/web/checkbox/index.ts +2 -0
- package/src/web/checkbox/manifest.json +294 -0
- package/src/web/chip/AI_GUIDE.md +186 -0
- package/src/web/chip/chip.css +1 -0
- package/src/web/chip/chip.tsx +230 -0
- package/src/web/chip/index.ts +2 -0
- package/src/web/chip/manifest.json +186 -0
- package/src/web/dropdown/AI_GUIDE.md +167 -0
- package/src/web/dropdown/dropdown.css +1 -0
- package/src/web/dropdown/dropdown.tsx +1274 -0
- package/src/web/dropdown/index.ts +3 -0
- package/src/web/dropdown/manifest.json +576 -0
- package/src/web/flex/AI_GUIDE.md +113 -0
- package/src/web/flex/flex-item.tsx +97 -0
- package/src/web/flex/flex.css +1 -0
- package/src/web/flex/flex.tsx +108 -0
- package/src/web/flex/index.ts +5 -0
- package/src/web/flex/manifest.json +162 -0
- package/src/web/form/index.ts +7 -0
- package/src/web/grid/AI_GUIDE.md +112 -0
- package/src/web/grid/grid-item.tsx +112 -0
- package/src/web/grid/grid.css +1 -0
- package/src/web/grid/grid.tsx +99 -0
- package/src/web/grid/index.ts +5 -0
- package/src/web/grid/manifest.json +153 -0
- package/src/web/index.ts +86 -0
- package/src/web/input/AI_GUIDE.md +159 -0
- package/src/web/input/index.ts +3 -0
- package/src/web/input/input.css +1 -0
- package/src/web/input/input.tsx +537 -0
- package/src/web/input/manifest.json +465 -0
- package/src/web/input-number/AI_GUIDE.md +164 -0
- package/src/web/input-number/index.ts +3 -0
- package/src/web/input-number/input-number.css +1 -0
- package/src/web/input-number/input-number.tsx +1193 -0
- package/src/web/input-number/manifest.json +575 -0
- package/src/web/modal/AI_GUIDE.md +171 -0
- package/src/web/modal/index.ts +3 -0
- package/src/web/modal/manifest.json +375 -0
- package/src/web/modal/modal.css +1 -0
- package/src/web/modal/modal.tsx +571 -0
- package/src/web/pagination/AI_GUIDE.md +148 -0
- package/src/web/pagination/index.ts +21 -0
- package/src/web/pagination/manifest.json +432 -0
- package/src/web/pagination/pagination-content.tsx +45 -0
- package/src/web/pagination/pagination-ellipsis.tsx +54 -0
- package/src/web/pagination/pagination-first.tsx +155 -0
- package/src/web/pagination/pagination-item.tsx +45 -0
- package/src/web/pagination/pagination-last.tsx +155 -0
- package/src/web/pagination/pagination-link.tsx +121 -0
- package/src/web/pagination/pagination-next.tsx +158 -0
- package/src/web/pagination/pagination-previous.tsx +158 -0
- package/src/web/pagination/pagination.css +1 -0
- package/src/web/pagination/pagination.tsx +687 -0
- package/src/web/popover/AI_GUIDE.md +163 -0
- package/src/web/popover/index.ts +3 -0
- package/src/web/popover/manifest.json +396 -0
- package/src/web/popover/popover.css +1 -0
- package/src/web/popover/popover.tsx +702 -0
- package/src/web/radio/AI_GUIDE.md +155 -0
- package/src/web/radio/index.ts +2 -0
- package/src/web/radio/manifest.json +294 -0
- package/src/web/radio/radio.css +1 -0
- package/src/web/radio/radio.tsx +290 -0
- package/src/web/selectbox/AI_GUIDE.md +216 -0
- package/src/web/selectbox/index.ts +3 -0
- package/src/web/selectbox/manifest.json +477 -0
- package/src/web/selectbox/selectbox.css +1 -0
- package/src/web/selectbox/selectbox.tsx +1048 -0
- package/src/web/sonner/AI_GUIDE.md +98 -0
- package/src/web/sonner/index.ts +114 -0
- package/src/web/sonner/manifest.json +132 -0
- package/src/web/sonner/sonner.css +1 -0
- package/src/web/sonner/sonner.tsx +177 -0
- package/src/web/table/AI_GUIDE.md +145 -0
- package/src/web/table/index.ts +35 -0
- package/src/web/table/manifest.json +168 -0
- package/src/web/table/table-body.tsx +45 -0
- package/src/web/table/table-caption.tsx +45 -0
- package/src/web/table/table-cell.tsx +74 -0
- package/src/web/table/table-empty.tsx +108 -0
- package/src/web/table/table-footer.tsx +45 -0
- package/src/web/table/table-head.tsx +80 -0
- package/src/web/table/table-header.tsx +45 -0
- package/src/web/table/table-row.tsx +69 -0
- package/src/web/table/table.css +1 -0
- package/src/web/table/table.tsx +305 -0
- package/src/web/tabs/AI_GUIDE.md +150 -0
- package/src/web/tabs/index.ts +3 -0
- package/src/web/tabs/manifest.json +315 -0
- package/src/web/tabs/tabs.css +1 -0
- package/src/web/tabs/tabs.tsx +332 -0
- package/src/web/text/AI_GUIDE.md +129 -0
- package/src/web/text/index.ts +3 -0
- package/src/web/text/manifest.json +195 -0
- package/src/web/text/text.css +1 -0
- package/src/web/text/text.tsx +689 -0
- package/src/web/textarea/AI_GUIDE.md +141 -0
- package/src/web/textarea/index.ts +3 -0
- package/src/web/textarea/manifest.json +438 -0
- package/src/web/textarea/textarea.css +1 -0
- package/src/web/textarea/textarea.tsx +467 -0
- package/src/web/tooltip/AI_GUIDE.md +110 -0
- package/src/web/tooltip/index.ts +3 -0
- package/src/web/tooltip/manifest.json +222 -0
- package/src/web/tooltip/tooltip.css +1 -0
- package/src/web/tooltip/tooltip.tsx +423 -0
- package/src/webview/bottomsheet/AI_GUIDE.md +141 -0
- package/src/webview/bottomsheet/bottomsheet.css +1 -0
- package/src/webview/bottomsheet/bottomsheet.tsx +603 -0
- package/src/webview/bottomsheet/index.ts +4 -0
- package/src/webview/bottomsheet/manifest.json +377 -0
- package/src/webview/button/AI_GUIDE.md +79 -0
- package/src/webview/button/button-ios.css +1 -0
- package/src/webview/button/button-ios.tsx +138 -0
- package/src/webview/button/button-material.css +1 -0
- package/src/webview/button/button-material.tsx +138 -0
- package/src/webview/button/index.ts +7 -0
- package/src/webview/button/manifest.json +148 -0
- package/src/webview/index.ts +7 -0
- package/tailwind-preset.cjs +62 -0
- package/tailwind-preset.js +62 -0
- package/ttdk-manifest.json +10188 -0
- package/README.md +0 -3
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
export type BannerUiProps = UiProps;
|
|
6
|
+
export interface BannerProps {
|
|
7
|
+
/**
|
|
8
|
+
* Judul utama banner yang ditampilkan dengan tipografi tegas (misal: "Katalog Dataset Publik").
|
|
9
|
+
*/
|
|
10
|
+
title?: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Deskripsi atau pesan teks penjelasan tambahan di bawah judul.
|
|
14
|
+
*/
|
|
15
|
+
description?: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Varian warna semantik tema banner:
|
|
19
|
+
* - `'primary'`: Brand Teal utama (#16B3AC).
|
|
20
|
+
* - `'success'`: Hijau konfirmasi keberhasilan.
|
|
21
|
+
* - `'info'`: Biru informasi.
|
|
22
|
+
* - `'warning'`: Kuning / amber peringatan.
|
|
23
|
+
* - `'danger'`: Merah kesalahan / bahaya.
|
|
24
|
+
*
|
|
25
|
+
* @default 'primary'
|
|
26
|
+
*/
|
|
27
|
+
variant?: "primary" | "success" | "info" | "warning" | "danger";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Gaya tampilan visual latar belakang banner.
|
|
31
|
+
* - `'gradient'`: Latar belakang gradasi halus elegan (standar sesuai desain katalog).
|
|
32
|
+
* - `'subtle'`: Latar belakang warna lembut transparan.
|
|
33
|
+
* - `'solid'`: Latar belakang warna pekat penuh dengan teks kontras tinggi.
|
|
34
|
+
* - `'outline'`: Garis tepi minimalis tanpa latar belakang gradasi.
|
|
35
|
+
* - `'flat'`: Latar polos solid netral.
|
|
36
|
+
*
|
|
37
|
+
* @default 'gradient'
|
|
38
|
+
*/
|
|
39
|
+
appearance?: "gradient" | "subtle" | "solid" | "outline" | "flat";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Skala ukuran tinggi dan padding ruang dalam banner.
|
|
43
|
+
* - `'sm'`: Kompak (padding 10px 16px, judul 14px).
|
|
44
|
+
* - `'md'`: Standar (padding 14px 20px, judul 16px).
|
|
45
|
+
* - `'lg'`: Besar / Page Header (padding 18px 24px, judul 18px).
|
|
46
|
+
* - `'xl'`: Ekstra Besar / Hero Banner (padding 24px 32px, judul 22px).
|
|
47
|
+
*
|
|
48
|
+
* @default 'md'
|
|
49
|
+
*/
|
|
50
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Bentuk sudut kelengkungan container banner.
|
|
54
|
+
* - `'none'`: Sudut siku 0px.
|
|
55
|
+
* - `'sm'`: Sudut 4px.
|
|
56
|
+
* - `'md'`: Sudut 8px (standar).
|
|
57
|
+
* - `'lg'`: Sudut 12px.
|
|
58
|
+
* - `'full'`: Sudut kapsul 9999px.
|
|
59
|
+
*
|
|
60
|
+
* @default 'md'
|
|
61
|
+
*/
|
|
62
|
+
rounded?: "none" | "sm" | "md" | "lg" | "full";
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Menampilkan ikon indikator status semantik (boolean) atau elemen ikon kustom.
|
|
66
|
+
*
|
|
67
|
+
* @default false
|
|
68
|
+
*/
|
|
69
|
+
icon?: boolean | any;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Elemen ikon SVG kustom untuk menggantikan ikon bawaan banner.
|
|
73
|
+
*/
|
|
74
|
+
customIcon?: any;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Warna kustom untuk ikon banner secara langsung.
|
|
78
|
+
*/
|
|
79
|
+
iconColor?: string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Ukuran kustom untuk ikon banner secara langsung.
|
|
83
|
+
*/
|
|
84
|
+
iconSize?: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Style kustom untuk ikon banner (UiProps).
|
|
88
|
+
*/
|
|
89
|
+
iconStyle?: UiProps;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Class CSS kustom untuk ikon banner.
|
|
93
|
+
*/
|
|
94
|
+
iconClass?: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Style kustom untuk judul banner (UiProps).
|
|
98
|
+
*/
|
|
99
|
+
titleStyle?: UiProps;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Class CSS kustom untuk judul banner.
|
|
103
|
+
*/
|
|
104
|
+
titleClass?: string;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Style kustom untuk deskripsi banner (UiProps).
|
|
108
|
+
*/
|
|
109
|
+
descStyle?: UiProps;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Class CSS kustom untuk deskripsi banner.
|
|
113
|
+
*/
|
|
114
|
+
descClass?: string;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Menampilkan tombol silang (x) untuk menutup atau menyembunyikan banner.
|
|
118
|
+
*
|
|
119
|
+
* @default false
|
|
120
|
+
*/
|
|
121
|
+
closable?: boolean;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Style kustom untuk tombol tutup banner (UiProps).
|
|
125
|
+
*/
|
|
126
|
+
closableStyle?: UiProps;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Class CSS kustom untuk tombol tutup banner.
|
|
130
|
+
*/
|
|
131
|
+
closableClass?: string;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active).
|
|
135
|
+
*/
|
|
136
|
+
ui?: UiProps;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Inline CSS style object native.
|
|
140
|
+
*/
|
|
141
|
+
style?: React.CSSProperties;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Konten kustom tambahan / isi banner (children slot).
|
|
145
|
+
*/
|
|
146
|
+
children?: any;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Class CSS kustom.
|
|
150
|
+
*/
|
|
151
|
+
className?: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Event callback saat tombol tutup diklik.
|
|
155
|
+
*/
|
|
156
|
+
onClose?: (event?: any) => void;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Komponen Banner untuk header halaman portal, pengumuman penting, atau judul kategori katalog data dengan desain visual bersih dan elegan.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
import { buildUiVars, UiProps } from "../../core/types";
|
|
164
|
+
|
|
165
|
+
function Banner(props: BannerProps) {
|
|
166
|
+
const [isVisible, setIsVisible] = useState(() => true);
|
|
167
|
+
|
|
168
|
+
function handleDismiss(event: any) {
|
|
169
|
+
setIsVisible(false);
|
|
170
|
+
if (props.onClose) {
|
|
171
|
+
props.onClose(event);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<>
|
|
177
|
+
{isVisible ? (
|
|
178
|
+
<>
|
|
179
|
+
<div
|
|
180
|
+
role="region"
|
|
181
|
+
className={`ttdk-banner ${props.className || ""}`.trim()}
|
|
182
|
+
data-variant={props.variant || "primary"}
|
|
183
|
+
data-appearance={props.appearance || "gradient"}
|
|
184
|
+
data-size={props.size || "md"}
|
|
185
|
+
data-rounded={props.rounded || "md"}
|
|
186
|
+
aria-label={props.title || "Banner"}
|
|
187
|
+
style={{
|
|
188
|
+
...buildUiVars(props.ui),
|
|
189
|
+
...(props.iconColor
|
|
190
|
+
? {
|
|
191
|
+
"--ttdk-ui-icon-color": props.iconColor,
|
|
192
|
+
}
|
|
193
|
+
: {}),
|
|
194
|
+
...(props.iconSize
|
|
195
|
+
? {
|
|
196
|
+
"--ttdk-ui-icon-size": props.iconSize,
|
|
197
|
+
}
|
|
198
|
+
: {}),
|
|
199
|
+
...((props as any)["style"] || {}),
|
|
200
|
+
...props.style,
|
|
201
|
+
}}
|
|
202
|
+
>
|
|
203
|
+
<div className="ttdk-banner-main">
|
|
204
|
+
{props.customIcon || (props.icon && props.icon !== false) ? (
|
|
205
|
+
<div
|
|
206
|
+
className={`ttdk-banner-icon-wrapper ${
|
|
207
|
+
props.iconClass || ""
|
|
208
|
+
}`.trim()}
|
|
209
|
+
style={{
|
|
210
|
+
...buildUiVars(props.iconStyle),
|
|
211
|
+
}}
|
|
212
|
+
>
|
|
213
|
+
{props.customIcon ||
|
|
214
|
+
(props.icon && typeof props.icon !== "boolean") ? (
|
|
215
|
+
<span className="ttdk-banner-icon">
|
|
216
|
+
{props.customIcon || props.icon}
|
|
217
|
+
</span>
|
|
218
|
+
) : null}
|
|
219
|
+
{!props.customIcon && props.icon === true ? (
|
|
220
|
+
<>
|
|
221
|
+
{!props.variant || props.variant === "primary" ? (
|
|
222
|
+
<svg
|
|
223
|
+
className="ttdk-banner-icon"
|
|
224
|
+
viewBox="0 0 24 24"
|
|
225
|
+
fill="none"
|
|
226
|
+
>
|
|
227
|
+
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
|
|
228
|
+
</svg>
|
|
229
|
+
) : null}
|
|
230
|
+
{props.variant === "info" ? (
|
|
231
|
+
<svg
|
|
232
|
+
className="ttdk-banner-icon"
|
|
233
|
+
viewBox="0 0 24 24"
|
|
234
|
+
fill="none"
|
|
235
|
+
>
|
|
236
|
+
<circle cx="12" cy="12" r="10" />
|
|
237
|
+
<line x1="12" y1="16" x2="12" y2="12" />
|
|
238
|
+
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
239
|
+
</svg>
|
|
240
|
+
) : null}
|
|
241
|
+
{props.variant === "success" ? (
|
|
242
|
+
<svg
|
|
243
|
+
className="ttdk-banner-icon"
|
|
244
|
+
viewBox="0 0 24 24"
|
|
245
|
+
fill="none"
|
|
246
|
+
>
|
|
247
|
+
<circle cx="12" cy="12" r="10" />
|
|
248
|
+
<polyline points="9 12 11 14 15 10" />
|
|
249
|
+
</svg>
|
|
250
|
+
) : null}
|
|
251
|
+
{props.variant === "warning" ? (
|
|
252
|
+
<svg
|
|
253
|
+
className="ttdk-banner-icon"
|
|
254
|
+
viewBox="0 0 24 24"
|
|
255
|
+
fill="none"
|
|
256
|
+
>
|
|
257
|
+
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" />
|
|
258
|
+
<line x1="12" y1="9" x2="12" y2="13" />
|
|
259
|
+
<line x1="12" y1="17" x2="12.01" y2="17" />
|
|
260
|
+
</svg>
|
|
261
|
+
) : null}
|
|
262
|
+
{props.variant === "danger" ? (
|
|
263
|
+
<svg
|
|
264
|
+
className="ttdk-banner-icon"
|
|
265
|
+
viewBox="0 0 24 24"
|
|
266
|
+
fill="none"
|
|
267
|
+
>
|
|
268
|
+
<circle cx="12" cy="12" r="10" />
|
|
269
|
+
<line x1="12" y1="8" x2="12" y2="12" />
|
|
270
|
+
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
271
|
+
</svg>
|
|
272
|
+
) : null}
|
|
273
|
+
</>
|
|
274
|
+
) : null}
|
|
275
|
+
</div>
|
|
276
|
+
) : null}
|
|
277
|
+
<div className="ttdk-banner-text-group">
|
|
278
|
+
{props.title ? (
|
|
279
|
+
<div
|
|
280
|
+
className={`ttdk-banner-title ${
|
|
281
|
+
props.titleClass || ""
|
|
282
|
+
}`.trim()}
|
|
283
|
+
style={{
|
|
284
|
+
...buildUiVars(props.titleStyle),
|
|
285
|
+
}}
|
|
286
|
+
>
|
|
287
|
+
{props.title}
|
|
288
|
+
</div>
|
|
289
|
+
) : null}
|
|
290
|
+
{props.description ? (
|
|
291
|
+
<div
|
|
292
|
+
className={`ttdk-banner-desc ${
|
|
293
|
+
props.descClass || ""
|
|
294
|
+
}`.trim()}
|
|
295
|
+
style={{
|
|
296
|
+
...buildUiVars(props.descStyle),
|
|
297
|
+
}}
|
|
298
|
+
>
|
|
299
|
+
{props.description}
|
|
300
|
+
</div>
|
|
301
|
+
) : null}
|
|
302
|
+
<>{props.children}</>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
{props.closable ? (
|
|
306
|
+
<div className="ttdk-banner-actions">
|
|
307
|
+
<button
|
|
308
|
+
type="button"
|
|
309
|
+
aria-label="Tutup banner"
|
|
310
|
+
className={`ttdk-banner-close-btn ${
|
|
311
|
+
props.closableClass || ""
|
|
312
|
+
}`.trim()}
|
|
313
|
+
style={{
|
|
314
|
+
...buildUiVars(props.closableStyle),
|
|
315
|
+
}}
|
|
316
|
+
onClick={(e) => handleDismiss(e)}
|
|
317
|
+
>
|
|
318
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
319
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
320
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
321
|
+
</svg>
|
|
322
|
+
</button>
|
|
323
|
+
</div>
|
|
324
|
+
) : null}
|
|
325
|
+
</div>
|
|
326
|
+
</>
|
|
327
|
+
) : null}
|
|
328
|
+
</>
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export default Banner;
|
|
333
|
+
|
|
334
|
+
export { Banner };
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ttdk-design-system/banner",
|
|
3
|
+
"component": "Banner",
|
|
4
|
+
"folder": "banner",
|
|
5
|
+
"description": "Komponen Banner untuk header halaman portal, pengumuman penting, atau judul kategori katalog data dengan desain visual bersih dan elegan.",
|
|
6
|
+
"stylesheets": [
|
|
7
|
+
{
|
|
8
|
+
"theme": "common",
|
|
9
|
+
"file": "banner.css",
|
|
10
|
+
"importPath": "web/banner/banner.css"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"props": {
|
|
14
|
+
"title": {
|
|
15
|
+
"name": "title",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"optional": true,
|
|
18
|
+
"default": null,
|
|
19
|
+
"description": "Judul utama banner yang ditampilkan dengan tipografi tegas (misal: \"Katalog Dataset Publik\").",
|
|
20
|
+
"example": null,
|
|
21
|
+
"param": null
|
|
22
|
+
},
|
|
23
|
+
"description": {
|
|
24
|
+
"name": "description",
|
|
25
|
+
"type": "string",
|
|
26
|
+
"optional": true,
|
|
27
|
+
"default": null,
|
|
28
|
+
"description": "Deskripsi atau pesan teks penjelasan tambahan di bawah judul.",
|
|
29
|
+
"example": null,
|
|
30
|
+
"param": null
|
|
31
|
+
},
|
|
32
|
+
"variant": {
|
|
33
|
+
"name": "variant",
|
|
34
|
+
"type": "| 'primary'\n | 'success'\n | 'info'\n | 'warning'\n | 'danger'",
|
|
35
|
+
"optional": true,
|
|
36
|
+
"default": "primary",
|
|
37
|
+
"description": "Varian warna semantik tema banner: - `'primary'`: Brand Teal utama (#16B3AC). - `'success'`: Hijau konfirmasi keberhasilan. - `'info'`: Biru informasi. - `'warning'`: Kuning / amber peringatan. - `'danger'`: Merah kesalahan / bahaya.",
|
|
38
|
+
"example": null,
|
|
39
|
+
"param": null
|
|
40
|
+
},
|
|
41
|
+
"appearance": {
|
|
42
|
+
"name": "appearance",
|
|
43
|
+
"type": "'gradient' | 'subtle' | 'solid' | 'outline' | 'flat'",
|
|
44
|
+
"optional": true,
|
|
45
|
+
"default": "gradient",
|
|
46
|
+
"description": "Gaya tampilan visual latar belakang banner. - `'gradient'`: Latar belakang gradasi halus elegan (standar sesuai desain katalog). - `'subtle'`: Latar belakang warna lembut transparan. - `'solid'`: Latar belakang warna pekat penuh dengan teks kontras tinggi. - `'outline'`: Garis tepi minimalis tanpa latar belakang gradasi. - `'flat'`: Latar polos solid netral.",
|
|
47
|
+
"example": null,
|
|
48
|
+
"param": null
|
|
49
|
+
},
|
|
50
|
+
"size": {
|
|
51
|
+
"name": "size",
|
|
52
|
+
"type": "'sm' | 'md' | 'lg' | 'xl'",
|
|
53
|
+
"optional": true,
|
|
54
|
+
"default": "md",
|
|
55
|
+
"description": "Skala ukuran tinggi dan padding ruang dalam banner. - `'sm'`: Kompak (padding 10px 16px, judul 14px). - `'md'`: Standar (padding 14px 20px, judul 16px). - `'lg'`: Besar / Page Header (padding 18px 24px, judul 18px). - `'xl'`: Ekstra Besar / Hero Banner (padding 24px 32px, judul 22px).",
|
|
56
|
+
"example": null,
|
|
57
|
+
"param": null
|
|
58
|
+
},
|
|
59
|
+
"rounded": {
|
|
60
|
+
"name": "rounded",
|
|
61
|
+
"type": "'none' | 'sm' | 'md' | 'lg' | 'full'",
|
|
62
|
+
"optional": true,
|
|
63
|
+
"default": "md",
|
|
64
|
+
"description": "Bentuk sudut kelengkungan container banner. - `'none'`: Sudut siku 0px. - `'sm'`: Sudut 4px. - `'md'`: Sudut 8px (standar). - `'lg'`: Sudut 12px. - `'full'`: Sudut kapsul 9999px.",
|
|
65
|
+
"example": null,
|
|
66
|
+
"param": null
|
|
67
|
+
},
|
|
68
|
+
"icon": {
|
|
69
|
+
"name": "icon",
|
|
70
|
+
"type": "boolean | any",
|
|
71
|
+
"optional": true,
|
|
72
|
+
"default": "false",
|
|
73
|
+
"description": "Menampilkan ikon indikator status semantik (boolean) atau elemen ikon kustom.",
|
|
74
|
+
"example": null,
|
|
75
|
+
"param": null
|
|
76
|
+
},
|
|
77
|
+
"customIcon": {
|
|
78
|
+
"name": "customIcon",
|
|
79
|
+
"type": "any",
|
|
80
|
+
"optional": true,
|
|
81
|
+
"default": null,
|
|
82
|
+
"description": "Elemen ikon SVG kustom untuk menggantikan ikon bawaan banner.",
|
|
83
|
+
"example": null,
|
|
84
|
+
"param": null
|
|
85
|
+
},
|
|
86
|
+
"iconColor": {
|
|
87
|
+
"name": "iconColor",
|
|
88
|
+
"type": "string",
|
|
89
|
+
"optional": true,
|
|
90
|
+
"default": null,
|
|
91
|
+
"description": "Warna kustom untuk ikon banner secara langsung.",
|
|
92
|
+
"example": null,
|
|
93
|
+
"param": null
|
|
94
|
+
},
|
|
95
|
+
"iconSize": {
|
|
96
|
+
"name": "iconSize",
|
|
97
|
+
"type": "string",
|
|
98
|
+
"optional": true,
|
|
99
|
+
"default": null,
|
|
100
|
+
"description": "Ukuran kustom untuk ikon banner secara langsung.",
|
|
101
|
+
"example": null,
|
|
102
|
+
"param": null
|
|
103
|
+
},
|
|
104
|
+
"iconStyle": {
|
|
105
|
+
"name": "iconStyle",
|
|
106
|
+
"type": "UiProps",
|
|
107
|
+
"optional": true,
|
|
108
|
+
"default": null,
|
|
109
|
+
"description": "Style kustom untuk ikon banner (UiProps).",
|
|
110
|
+
"example": null,
|
|
111
|
+
"param": null
|
|
112
|
+
},
|
|
113
|
+
"iconClass": {
|
|
114
|
+
"name": "iconClass",
|
|
115
|
+
"type": "string",
|
|
116
|
+
"optional": true,
|
|
117
|
+
"default": null,
|
|
118
|
+
"description": "Class CSS kustom untuk ikon banner.",
|
|
119
|
+
"example": null,
|
|
120
|
+
"param": null
|
|
121
|
+
},
|
|
122
|
+
"titleStyle": {
|
|
123
|
+
"name": "titleStyle",
|
|
124
|
+
"type": "UiProps",
|
|
125
|
+
"optional": true,
|
|
126
|
+
"default": null,
|
|
127
|
+
"description": "Style kustom untuk judul banner (UiProps).",
|
|
128
|
+
"example": null,
|
|
129
|
+
"param": null
|
|
130
|
+
},
|
|
131
|
+
"titleClass": {
|
|
132
|
+
"name": "titleClass",
|
|
133
|
+
"type": "string",
|
|
134
|
+
"optional": true,
|
|
135
|
+
"default": null,
|
|
136
|
+
"description": "Class CSS kustom untuk judul banner.",
|
|
137
|
+
"example": null,
|
|
138
|
+
"param": null
|
|
139
|
+
},
|
|
140
|
+
"descStyle": {
|
|
141
|
+
"name": "descStyle",
|
|
142
|
+
"type": "UiProps",
|
|
143
|
+
"optional": true,
|
|
144
|
+
"default": null,
|
|
145
|
+
"description": "Style kustom untuk deskripsi banner (UiProps).",
|
|
146
|
+
"example": null,
|
|
147
|
+
"param": null
|
|
148
|
+
},
|
|
149
|
+
"descClass": {
|
|
150
|
+
"name": "descClass",
|
|
151
|
+
"type": "string",
|
|
152
|
+
"optional": true,
|
|
153
|
+
"default": null,
|
|
154
|
+
"description": "Class CSS kustom untuk deskripsi banner.",
|
|
155
|
+
"example": null,
|
|
156
|
+
"param": null
|
|
157
|
+
},
|
|
158
|
+
"closable": {
|
|
159
|
+
"name": "closable",
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"optional": true,
|
|
162
|
+
"default": "false",
|
|
163
|
+
"description": "Menampilkan tombol silang (x) untuk menutup atau menyembunyikan banner.",
|
|
164
|
+
"example": null,
|
|
165
|
+
"param": null
|
|
166
|
+
},
|
|
167
|
+
"closableStyle": {
|
|
168
|
+
"name": "closableStyle",
|
|
169
|
+
"type": "UiProps",
|
|
170
|
+
"optional": true,
|
|
171
|
+
"default": null,
|
|
172
|
+
"description": "Style kustom untuk tombol tutup banner (UiProps).",
|
|
173
|
+
"example": null,
|
|
174
|
+
"param": null
|
|
175
|
+
},
|
|
176
|
+
"closableClass": {
|
|
177
|
+
"name": "closableClass",
|
|
178
|
+
"type": "string",
|
|
179
|
+
"optional": true,
|
|
180
|
+
"default": null,
|
|
181
|
+
"description": "Class CSS kustom untuk tombol tutup banner.",
|
|
182
|
+
"example": null,
|
|
183
|
+
"param": null
|
|
184
|
+
},
|
|
185
|
+
"ui": {
|
|
186
|
+
"name": "ui",
|
|
187
|
+
"type": "UiProps",
|
|
188
|
+
"optional": true,
|
|
189
|
+
"default": null,
|
|
190
|
+
"description": "Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active).",
|
|
191
|
+
"example": null,
|
|
192
|
+
"param": null
|
|
193
|
+
},
|
|
194
|
+
"style": {
|
|
195
|
+
"name": "style",
|
|
196
|
+
"type": "any",
|
|
197
|
+
"optional": true,
|
|
198
|
+
"default": null,
|
|
199
|
+
"description": "Inline CSS style object native.",
|
|
200
|
+
"example": null,
|
|
201
|
+
"param": null
|
|
202
|
+
},
|
|
203
|
+
"children": {
|
|
204
|
+
"name": "children",
|
|
205
|
+
"type": "any",
|
|
206
|
+
"optional": true,
|
|
207
|
+
"default": null,
|
|
208
|
+
"description": "Konten kustom tambahan / isi banner (children slot).",
|
|
209
|
+
"example": null,
|
|
210
|
+
"param": null
|
|
211
|
+
},
|
|
212
|
+
"className": {
|
|
213
|
+
"name": "className",
|
|
214
|
+
"type": "string",
|
|
215
|
+
"optional": true,
|
|
216
|
+
"default": null,
|
|
217
|
+
"description": "Class CSS kustom.",
|
|
218
|
+
"example": null,
|
|
219
|
+
"param": null
|
|
220
|
+
},
|
|
221
|
+
"onClose": {
|
|
222
|
+
"name": "onClose",
|
|
223
|
+
"type": "(event?: any) => void",
|
|
224
|
+
"optional": true,
|
|
225
|
+
"default": null,
|
|
226
|
+
"description": "Event callback saat tombol tutup diklik.",
|
|
227
|
+
"example": null,
|
|
228
|
+
"param": null
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"subInterfaces": {},
|
|
232
|
+
"supportedFrameworks": [
|
|
233
|
+
"react",
|
|
234
|
+
"vue",
|
|
235
|
+
"svelte"
|
|
236
|
+
],
|
|
237
|
+
"themes": [
|
|
238
|
+
"tw"
|
|
239
|
+
]
|
|
240
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# <Breadcrumb /> — TTDK Component Reference
|
|
2
|
+
|
|
3
|
+
Komponen Breadcrumb untuk menampilkan hierarki navigasi lokasi halaman saat ini dengan dukungan penyingkatan (collapse ellipsis).
|
|
4
|
+
|
|
5
|
+
## 1. Stylesheets & Theming (Pure CSS)
|
|
6
|
+
Import the corresponding stylesheet for the theme you wish to use:
|
|
7
|
+
- **COMMON Theme**: `import "@ttdk-design-system/library-<react|vue|svelte>/web/breadcrumb/breadcrumb.css";`
|
|
8
|
+
|
|
9
|
+
## 2. Subpath Component Import
|
|
10
|
+
```ts
|
|
11
|
+
// React
|
|
12
|
+
import Breadcrumb from "@ttdk-design-system/library-react/web/breadcrumb";
|
|
13
|
+
|
|
14
|
+
// Vue 3
|
|
15
|
+
import Breadcrumb from "@ttdk-design-system/library-vue/web/breadcrumb";
|
|
16
|
+
|
|
17
|
+
// Svelte
|
|
18
|
+
import Breadcrumb from "@ttdk-design-system/library-svelte/web/breadcrumb";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 3. Props & API Reference
|
|
22
|
+
|
|
23
|
+
| Prop | Type | Default | Description |
|
|
24
|
+
| :--- | :--- | :--- | :--- |
|
|
25
|
+
| `items` | `BreadcrumbItem[]` | `-` | Daftar item navigasi breadcrumb dari tingkat teratas hingga halaman saat ini. |
|
|
26
|
+
| `separator?` | `BreadcrumbSeparator` | `arrow` | Jenis karakter atau ikon pemisah antar item: - `'arrow'`: Ikon panah kanan `→`. |
|
|
27
|
+
| `customSeparator?` | `string` | `-` | Karakter atau string teks khusus untuk pemisah antarelemen. |
|
|
28
|
+
| `size?` | `'sm' | 'md' | 'lg'` | `md` | Skala ukuran tampilan breadcrumb: - `'sm'`: Kompak (12px, gap 6px). - `'md'`: Standar (14px, gap 8px). - `'lg'`: Besar (16px, gap 12px). |
|
|
29
|
+
| `maxLabelLength?` | `number` | `20` | Batas maksimum panjang karakter label sebelum dipotong (truncate). |
|
|
30
|
+
| `ui?` | `UiProps` | `-` | Kustomisasi visual granular melalui style-like object (+ support pseudo-class: hover, active). |
|
|
31
|
+
| `style?` | `any` | `-` | Inline CSS style object native. |
|
|
32
|
+
| `textLinkStyle?` | `UiProps` | `-` | Style kustom untuk teks tautan breadcrumb / item non-aktif (UiProps). |
|
|
33
|
+
| `textLinkClass?` | `string` | `-` | Class CSS kustom untuk teks tautan breadcrumb / item non-aktif (Tailwind / class kustom). |
|
|
34
|
+
| `textActiveStyle?` | `UiProps` | `-` | Style kustom untuk teks item aktif / halaman saat ini (UiProps). |
|
|
35
|
+
| `textActiveClass?` | `string` | `-` | Class CSS kustom untuk teks item aktif / halaman saat ini (Tailwind / class kustom). |
|
|
36
|
+
| `separatorStyle?` | `UiProps` | `-` | Style kustom untuk karakter atau ikon pemisah (UiProps). |
|
|
37
|
+
| `separatorClass?` | `string` | `-` | Class CSS kustom untuk karakter atau ikon pemisah (Tailwind / class kustom). |
|
|
38
|
+
| `onItemClick?` | `(item: BreadcrumbItem, index: number, event: any) => void` | `-` | Handler event klik yang dipanggil saat suatu item breadcrumb diklik. |
|
|
39
|
+
| `className?` | `string` | `-` | Class CSS kustom. |
|
|
40
|
+
| `children?` | `any` | `-` | Slot konten tambahan di ujung kanan breadcrumb. |
|
|
41
|
+
|
|
42
|
+
### Sub-interface: `BreadcrumbItem`
|
|
43
|
+
|
|
44
|
+
| Field | Type | Default | Description |
|
|
45
|
+
| :--- | :--- | :--- | :--- |
|
|
46
|
+
| `label` | `string` | `-` | Label teks yang ditampilkan pada breadcrumb item. |
|
|
47
|
+
| `href?` | `string` | `-` | URL tautan navigasi tujuan (href / path). |
|
|
48
|
+
| `icon?` | `any` | `-` | Ikon atau emoji opsional di samping label teks. |
|
|
49
|
+
| `current?` | `boolean` | `-` | Menandai item ini secara eksplisit sebagai halaman saat ini (current page). |
|
|
50
|
+
| `disabled?` | `boolean` | `false` | Menonaktifkan interaksi klik pada item ini. |
|
|
51
|
+
| `isEllipsis?` | `boolean` | `-` | Menandai item sebagai representasi ellipsis penyingkat item yang tersembunyi. |
|
|
52
|
+
|
|
53
|
+
## 4. Usage Examples
|
|
54
|
+
|
|
55
|
+
### React Example
|
|
56
|
+
```tsx
|
|
57
|
+
import Breadcrumb from "@ttdk-design-system/library-react/web/breadcrumb";
|
|
58
|
+
import "@ttdk-design-system/library-react/web/breadcrumb/breadcrumb.css";
|
|
59
|
+
|
|
60
|
+
export function Example() {
|
|
61
|
+
const items = [
|
|
62
|
+
{ label: "Beranda", href: "/" },
|
|
63
|
+
{ label: "Dataset", href: "/dataset" },
|
|
64
|
+
{ label: "Fasilitas Kesehatan", href: "/dataset/faskes" },
|
|
65
|
+
{ label: "Detail Puskesmas", current: true }
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
70
|
+
<Breadcrumb items={items} separator="slash" />
|
|
71
|
+
<Breadcrumb items={items} separator="chevron" size="sm" />
|
|
72
|
+
<Breadcrumb items={items} maxItems={3} />
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Vue 3 Example
|
|
79
|
+
```vue
|
|
80
|
+
<script setup lang="ts">
|
|
81
|
+
import Breadcrumb from "@ttdk-design-system/library-vue/web/breadcrumb";
|
|
82
|
+
import "@ttdk-design-system/library-vue/web/breadcrumb/breadcrumb.css";
|
|
83
|
+
|
|
84
|
+
const items = [
|
|
85
|
+
{ label: "Beranda", href: "/" },
|
|
86
|
+
{ label: "Dataset", href: "/dataset" },
|
|
87
|
+
{ label: "Fasilitas Kesehatan", href: "/dataset/faskes" },
|
|
88
|
+
{ label: "Detail Puskesmas", current: true }
|
|
89
|
+
];
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<template>
|
|
93
|
+
<div style="display: flex; flex-direction: column; gap: 16px;">
|
|
94
|
+
<Breadcrumb :items="items" separator="slash" />
|
|
95
|
+
<Breadcrumb :items="items" separator="chevron" size="sm" />
|
|
96
|
+
<Breadcrumb :items="items" :max-items="3" />
|
|
97
|
+
</div>
|
|
98
|
+
</template>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Svelte Example
|
|
102
|
+
```svelte
|
|
103
|
+
<script lang="ts">
|
|
104
|
+
import Breadcrumb from "@ttdk-design-system/library-svelte/web/breadcrumb";
|
|
105
|
+
import "@ttdk-design-system/library-svelte/web/breadcrumb/breadcrumb.css";
|
|
106
|
+
|
|
107
|
+
const items = [
|
|
108
|
+
{ label: "Beranda", href: "/" },
|
|
109
|
+
{ label: "Dataset", href: "/dataset" },
|
|
110
|
+
{ label: "Fasilitas Kesehatan", href: "/dataset/faskes" },
|
|
111
|
+
{ label: "Detail Puskesmas", current: true }
|
|
112
|
+
];
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<div style="display: flex; flex-direction: column; gap: 16px;">
|
|
116
|
+
<Breadcrumb {items} separator="slash" />
|
|
117
|
+
<Breadcrumb {items} separator="chevron" size="sm" />
|
|
118
|
+
<Breadcrumb {items} maxItems={3} />
|
|
119
|
+
</div>
|
|
120
|
+
```
|