@cahyo-dimas/freeday 1.53.0 → 2.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/CHANGELOG.md +657 -535
- package/COMPONENTS.md +153 -135
- package/README.id.md +46 -45
- package/README.md +46 -43
- package/USAGE.md +39 -35
- package/adapters/blazor/FdyAppShell.razor +50 -0
- package/adapters/blazor/FdyAppShell.razor.cs +114 -0
- package/adapters/blazor/FdyCfl.razor.cs +1 -1
- package/adapters/blazor/FdyChart.razor +1 -1
- package/adapters/blazor/FdyChart.razor.cs +3 -3
- package/adapters/blazor/FdyChartSeries.cs +1 -1
- package/adapters/blazor/FdyCombo.razor.cs +2 -2
- package/adapters/blazor/FdyModal.razor +1 -1
- package/adapters/blazor/FdyTable.razor.cs +7 -7
- package/adapters/blazor/FdyTableFilter.razor +1 -1
- package/adapters/blazor/FdyTableFooter.razor +1 -1
- package/adapters/blazor/FdyTableFooter.razor.cs +4 -4
- package/adapters/blazor/Freeday.Blazor.csproj +1 -1
- package/adapters/blazor/FreedayComponentBase.cs +1 -1
- package/adapters/blazor/TableModel.cs +3 -3
- package/adapters/blazor/TableTypes.cs +3 -3
- package/adapters/blazor/freeday-blazor.js +5 -5
- package/adapters/core/app-shell.d.ts +30 -0
- package/adapters/core/app-shell.js +134 -0
- package/adapters/core/table-model.d.ts +2 -2
- package/adapters/core/table-model.js +8 -8
- package/adapters/react/components/FdyAppShell.tsx +159 -0
- package/adapters/react/components/FdyAutocomplete.tsx +1 -1
- package/adapters/react/components/FdyCascade.tsx +1 -1
- package/adapters/react/components/FdyCfl.tsx +11 -11
- package/adapters/react/components/FdyDateRange.tsx +2 -2
- package/adapters/react/components/FdyDatepicker.tsx +5 -5
- package/adapters/react/components/FdyDrawer.tsx +1 -1
- package/adapters/react/components/FdyModal.tsx +2 -2
- package/adapters/react/components/FdyTable.tsx +7 -7
- package/adapters/react/components/FdyTableFilter.tsx +1 -1
- package/adapters/react/components/FdyTableFooter.tsx +5 -5
- package/adapters/react/index.d.ts +2 -1
- package/adapters/react/index.js +1 -0
- package/adapters/react/useFreeday.js +3 -3
- package/adapters/vue/components/FdyAppShell.vue +160 -0
- package/adapters/vue/components/FdyAutocomplete.vue +1 -1
- package/adapters/vue/components/FdyCascade.vue +1 -1
- package/adapters/vue/components/FdyCfl.vue +8 -8
- package/adapters/vue/components/FdyChart.vue +2 -2
- package/adapters/vue/components/FdyCombo.vue +1 -1
- package/adapters/vue/components/FdyDateRange.vue +2 -2
- package/adapters/vue/components/FdyDatepicker.vue +5 -5
- package/adapters/vue/components/FdyDrawer.vue +3 -3
- package/adapters/vue/components/FdyModal.vue +3 -3
- package/adapters/vue/components/FdyTable.vue +7 -7
- package/adapters/vue/components/FdyTableFilter.vue +1 -1
- package/adapters/vue/components/FdyTableFooter.vue +5 -5
- package/adapters/vue/index.d.ts +3 -2
- package/adapters/vue/index.js +1 -0
- package/adapters/vue/useFreeday.js +3 -3
- package/dist/asset.d.ts +3 -3
- package/dist/freeday-app-shell.js +49 -9
- package/dist/freeday-autocomplete.js +2 -2
- package/dist/freeday-breakpoint.js +1 -1
- package/dist/freeday-carousel.js +5 -5
- package/dist/freeday-cascade.js +7 -7
- package/dist/freeday-cfl.js +9 -9
- package/dist/freeday-chart.js +11 -11
- package/dist/freeday-chip.js +3 -3
- package/dist/freeday-datepicker.js +11 -7
- package/dist/freeday-datetime.js +5 -5
- package/dist/freeday-drawer.js +1 -1
- package/dist/freeday-form.js +14 -14
- package/dist/freeday-mask.js +6 -6
- package/dist/freeday-menu.js +1 -1
- package/dist/freeday-number.js +3 -3
- package/dist/freeday-popover.js +3 -3
- package/dist/freeday-rating.js +2 -2
- package/dist/freeday-select.js +5 -5
- package/dist/freeday-slider.js +2 -2
- package/dist/freeday-stepper.js +7 -7
- package/dist/freeday-table.js +15 -15
- package/dist/freeday-tabs.js +1 -1
- package/dist/freeday-timepicker.js +2 -2
- package/dist/freeday-toast.js +8 -8
- package/dist/freeday-tree.js +3 -3
- package/dist/freeday-upload.js +25 -25
- package/dist/freeday.bundle.css +176 -176
- package/dist/freeday.css +170 -170
- package/dist/freeday.d.ts +2 -2
- package/dist/freeday.js +202 -158
- package/dist/freeday.tokens.css +5 -5
- package/docs/agent-onboarding.md +42 -42
- package/docs/getting-started.md +35 -35
- package/docs/integrations.md +18 -18
- package/docs/reference-screen.html +14 -14
- package/package.json +5 -4
- package/src/base.css +6 -6
- package/src/components/accordion.css +4 -4
- package/src/components/alert.css +1 -1
- package/src/components/app-shell.css +10 -10
- package/src/components/appbar.css +3 -3
- package/src/components/autocomplete.css +1 -1
- package/src/components/avatar.css +3 -3
- package/src/components/badge.css +5 -5
- package/src/components/breadcrumb.css +1 -1
- package/src/components/breakpoints.css +4 -4
- package/src/components/button.css +13 -13
- package/src/components/card.css +8 -8
- package/src/components/carousel.css +2 -2
- package/src/components/cascade.css +2 -2
- package/src/components/cfl.css +4 -4
- package/src/components/chart.css +3 -3
- package/src/components/chip.css +2 -2
- package/src/components/combo.css +3 -3
- package/src/components/composition.css +7 -7
- package/src/components/datepicker.css +6 -6
- package/src/components/datetimepicker.css +1 -1
- package/src/components/description-list.css +1 -1
- package/src/components/divider.css +1 -1
- package/src/components/drawer.css +1 -1
- package/src/components/file-upload.css +5 -5
- package/src/components/filterbar.css +7 -7
- package/src/components/form-grid.css +2 -2
- package/src/components/input-group.css +6 -6
- package/src/components/input.css +6 -6
- package/src/components/kbd.css +1 -1
- package/src/components/list.css +6 -6
- package/src/components/menu.css +3 -3
- package/src/components/modal.css +1 -1
- package/src/components/pagination.css +1 -1
- package/src/components/progress.css +1 -1
- package/src/components/rating.css +2 -2
- package/src/components/selection.css +4 -4
- package/src/components/skeleton.css +1 -1
- package/src/components/slider.css +1 -1
- package/src/components/spinner.css +1 -1
- package/src/components/states.css +1 -1
- package/src/components/stepper.css +2 -2
- package/src/components/table.css +15 -15
- package/src/components/tabs.css +3 -3
- package/src/components/timeline.css +1 -1
- package/src/components/timepicker.css +1 -1
- package/src/components/toast.css +3 -3
- package/src/components/tooltip.css +1 -1
- package/src/components/tree.css +2 -2
- package/tokens/breakpoints.d.ts +2 -2
- package/tokens/breakpoints.mjs +3 -3
- package/tokens/tokens.json +1 -1
package/README.id.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) · **Bahasa Indonesia**
|
|
4
4
|
|
|
5
|
-
> **Lebih banyak _free day_ buat dev
|
|
5
|
+
> **Lebih banyak _free day_ buat dev. UI kit-nya sudah siap pakai.**
|
|
6
6
|
|
|
7
7
|
[](https://cahyo-dimas.github.io/freeday-ui-kit/)
|
|
8
|
-
[](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v2.0.0)
|
|
9
9
|
|
|
10
|
-
UI KIT yang token-driven & framework-agnostic
|
|
10
|
+
UI KIT yang token-driven & framework-agnostic. Satu sumber kebenaran untuk warna, tipografi,
|
|
11
11
|
spasi, dan komponen. Blueprint: `docs/superpowers/specs/2026-07-21-freeday-ui-kit-design.md`.
|
|
12
|
-
**Referensi hidup:** **[cahyo-dimas.github.io/freeday-ui-kit](https://cahyo-dimas.github.io/freeday-ui-kit/)
|
|
12
|
+
**Referensi hidup:** **[cahyo-dimas.github.io/freeday-ui-kit](https://cahyo-dimas.github.io/freeday-ui-kit/)**, atau buka `docs/index.html` langsung di browser.
|
|
13
13
|
|
|
14
14
|
> 🚀 **Baru mau pakai di project?** Langkah demi langkah per stack (HTML · Vue · React · Blazor): **[`docs/getting-started.md`](docs/getting-started.md)**.
|
|
15
15
|
>
|
|
@@ -17,7 +17,7 @@ spasi, dan komponen. Blueprint: `docs/superpowers/specs/2026-07-21-freeday-ui-ki
|
|
|
17
17
|
> **[`COMPONENTS.md`](COMPONENTS.md)**. **Kapan pakai yang mana:** **[`USAGE.md`](USAGE.md)**.
|
|
18
18
|
> Satu layar utuh yang sudah dirakit: **[`docs/reference-screen.html`](docs/reference-screen.html)**.
|
|
19
19
|
>
|
|
20
|
-
> 🤖 **Ngoding pakai AI agent (atau vibe code)?** Tak ada model yang tahu Freeday dari training
|
|
20
|
+
> 🤖 **Ngoding pakai AI agent (atau vibe code)?** Tak ada model yang tahu Freeday dari training, jadi
|
|
21
21
|
> berikan **[`docs/agent-onboarding.md`](docs/agent-onboarding.md)** (blok instruksi siap-tempel +
|
|
22
22
|
> tabel mapping migrasi).
|
|
23
23
|
|
|
@@ -27,33 +27,33 @@ node tokens/build.mjs # tokens.json -> dist/freeday.tokens.css; bundel dist/fr
|
|
|
27
27
|
# dist/freeday.bundle.css (token+komponen); salin dist/*.js + dist/freeday.js
|
|
28
28
|
npm test # tes transformasi build + kontras WCAG (node:test)
|
|
29
29
|
```
|
|
30
|
-
`dist/` di-commit
|
|
30
|
+
`dist/` di-commit, jadi konsumen tak perlu build sendiri.
|
|
31
31
|
|
|
32
32
|
## Pakai di project
|
|
33
33
|
|
|
34
34
|
### Pertama: pintu masuk mana yang kamu pakai?
|
|
35
35
|
|
|
36
|
-
Sebagian besar Freeday itu markup + kelas `fdy-*` dan sama di mana pun. **
|
|
37
|
-
interaktif juga punya wrapper typed
|
|
36
|
+
Sebagian besar Freeday itu markup + kelas `fdy-*` dan sama di mana pun. **Sebelas komponen
|
|
37
|
+
interaktif juga punya wrapper typed.** Di stack berikut, pakai wrapper-nya, bukan markup mentah +
|
|
38
38
|
enhancer:
|
|
39
39
|
|
|
40
|
-
| Stack-mu | Impor
|
|
40
|
+
| Stack-mu | Impor kesebelasnya dari | Binding |
|
|
41
41
|
|---|---|---|
|
|
42
42
|
| **Vue 3** | `@cahyo-dimas/freeday/vue` | `v-model` |
|
|
43
43
|
| **React 18/19** | `@cahyo-dimas/freeday/react` | `value` + `onChange` |
|
|
44
44
|
| **Blazor (net8.0)** | RCL `Freeday.Blazor` | `@bind-Value` |
|
|
45
45
|
| HTML statis · Svelte · template server-rendered | *(tanpa wrapper)* markup mentah + enhancer, di bawah | event `fdy-*` |
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
`FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer`. Menulis markup mentah
|
|
49
|
-
|
|
50
|
-
rusak diam-diam: DOM yang di-render framework belakangan tak pernah ter-hydrate, dan state widget
|
|
47
|
+
Kesebelasnya: `FdyCombo` · `FdyDatepicker` · `FdyDateRange` · `FdyAutocomplete` · `FdyCascade` ·
|
|
48
|
+
`FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer` · `FdyAppShell`. Menulis markup mentah
|
|
49
|
+
untuk kesebelas ini di dalam Vue/React/Blazor *kelihatan* baik-baik saja pada mulanya, karena render
|
|
50
|
+
pertamanya memang benar. Setelah itu ia rusak diam-diam: DOM yang di-render framework belakangan tak pernah ter-hydrate, dan state widget
|
|
51
51
|
berakhir di DOM alih-alih di state framework-mu. Selebihnya (button, card, badge, alert, markup
|
|
52
|
-
tabel, layout, dan komponen interaktif yang tak punya wrapper) sama persis di semua stack
|
|
52
|
+
tabel, layout, dan komponen interaktif yang tak punya wrapper) sama persis di semua stack. Untuk
|
|
53
53
|
yang terakhir, hydrate dengan `useFreeday` (Vue/React) atau `FreedayBlazor.initAll` (Blazor).
|
|
54
54
|
Panduan lengkap per stack: [`docs/getting-started.md`](docs/getting-started.md).
|
|
55
55
|
|
|
56
|
-
**Sebagai paket (
|
|
56
|
+
**Sebagai paket (Vue/React/Blazor/Vite, atau project apa pun yang punya bundler):**
|
|
57
57
|
```bash
|
|
58
58
|
npm i @cahyo-dimas/freeday
|
|
59
59
|
```
|
|
@@ -77,27 +77,27 @@ ter-publish → install tanpa build step; minify diserahkan ke bundler konsumen.
|
|
|
77
77
|
<link rel="stylesheet" href="dist/freeday.css"> <!-- komponen fdy-* -->
|
|
78
78
|
```
|
|
79
79
|
Kelas komponen berprefix `fdy-` (mis. `fdy-btn`, `fdy-card`, `fdy-badge`). Pakai langsung di
|
|
80
|
-
markup framework apa pun
|
|
80
|
+
markup framework apa pun: Vue, React, Blazor, atau HTML polos.
|
|
81
81
|
|
|
82
|
-
> **⚠️ Muat font-nya sendiri
|
|
82
|
+
> **⚠️ Muat font-nya sendiri. Paket ini tidak.** Token tipe menamai **Sora** / **IBM Plex Sans** /
|
|
83
83
|
> **JetBrains Mono** tapi Freeday tak membundel file font. Muat (mis. `@import '@fontsource/sora/700.css'`
|
|
84
|
-
> …) atau override `--font-display`/`--font-body`/`--font-mono
|
|
84
|
+
> …) atau override `--font-display`/`--font-body`/`--font-mono`. Kalau tidak, kit jatuh ke fallback
|
|
85
85
|
> sistem dan terlihat "belum jadi". Detail: [`docs/getting-started.md`](docs/getting-started.md).
|
|
86
86
|
|
|
87
87
|
> **Token/role mana dipakai kapan → [`USAGE.md`](USAGE.md).** Freeday menjaga konsistensi *nilai*;
|
|
88
|
-
> `USAGE.md` = doktrin yang menjaga konsistensi *keputusan
|
|
88
|
+
> `USAGE.md` = doktrin yang menjaga konsistensi *keputusan*: role tipe (`.fdy-title-page/-section/-card`),
|
|
89
89
|
> ritme spasi, elevasi, satu-primary-per-layar, palet kategorikal `--tone-1…8`, dan primitif komposisi
|
|
90
90
|
> halaman (`.fdy-page`, `.fdy-page-section`, `.fdy-stats`). Tiap app mulai di `.fdy-app`.
|
|
91
91
|
|
|
92
92
|
> **Scope: komponen + token, bukan layout.** Freeday punya komponen & design token; helper layout
|
|
93
|
-
> cuma `.fdy-hidden` / `.fdy-visually-hidden` plus primitif komposisi di atas. Layout grid dari layer-mu sendiri
|
|
94
|
-
>
|
|
95
|
-
> (`base.css` Freeday = reset-nya). `base.css` itu reset *ringan* (tak me-reset margin `ul`/`ol`/`p
|
|
96
|
-
> pakai `.fdy-list-reset` atau komponen list Freeday), dan skala spacing/radius/durasi adalah custom
|
|
93
|
+
> cuma `.fdy-hidden` / `.fdy-visually-hidden` plus primitif komposisi di atas. Layout grid dari layer-mu sendiri.
|
|
94
|
+
> Pasangkan dengan utility framework (Tailwind, UnoCSS…) mode **utilities-only, preflight OFF**
|
|
95
|
+
> (`base.css` Freeday = reset-nya). `base.css` itu reset *ringan* (tak me-reset margin `ul`/`ol`/`p`,
|
|
96
|
+
> jadi pakai `.fdy-list-reset` atau komponen list Freeday), dan skala spacing/radius/durasi adalah custom
|
|
97
97
|
> property publik (`--space-0`…`--space-24`, …) yang bisa jadi dasar theme utility-mu. Detail:
|
|
98
98
|
> [`docs/getting-started.md` §Core concepts](docs/getting-started.md).
|
|
99
99
|
|
|
100
|
-
> `.fdy-btn` **sudah** tombol primary
|
|
100
|
+
> `.fdy-btn` **sudah** tombol primary. Tak ada modifier `.fdy-btn--primary` terpisah.
|
|
101
101
|
> Modifier untuk varian lain: `--ghost`, `--danger`, `--text`, `--sm`, `--lg`, `--icon`
|
|
102
102
|
> (lihat `docs/index.html`).
|
|
103
103
|
|
|
@@ -117,7 +117,8 @@ JS. Dua cara:
|
|
|
117
117
|
<script src="dist/freeday-upload.js" defer></script> <!-- [data-fdy-dropzone] -->
|
|
118
118
|
<script src="dist/freeday-toast.js" defer></script> <!-- Freeday.toast({...}) -->
|
|
119
119
|
```
|
|
120
|
-
Semua auto-init `[data-fdy-*]` saat `DOMContentLoaded
|
|
120
|
+
Semua auto-init `[data-fdy-*]` saat `DOMContentLoaded`. Semuanya idempotent, dan tetap jadi markup
|
|
121
|
+
biasa kalau script-nya tak pernah dimuat.
|
|
121
122
|
|
|
122
123
|
| Enhancer | Hook markup | Event / API |
|
|
123
124
|
|---|---|---|
|
|
@@ -138,47 +139,47 @@ Semua auto-init `[data-fdy-*]` saat `DOMContentLoaded` — idempotent, progressi
|
|
|
138
139
|
|
|
139
140
|
Tabel lebar (banyak kolom) butuh wrapper untuk scroll horizontal: bungkus `.fdy-table` dengan
|
|
140
141
|
`.fdy-table-wrap` (tabel biasa, sudah termasuk shell border + shadow) atau `.fdy-table-scroll`
|
|
141
|
-
(scroll polos tanpa shell
|
|
142
|
+
(scroll polos tanpa shell, jadi jalan standalone maupun di dalam `.fdy-datatable` yang shell
|
|
142
143
|
border/shadow-nya sudah ada sendiri). Tanpa salah satu wrapper ini, tabel lebar akan overflow
|
|
143
144
|
container-nya, bukan scroll sendiri.
|
|
144
145
|
|
|
145
|
-
### 3. Theming
|
|
146
|
-
- `data-theme="light|dark"`
|
|
146
|
+
### 3. Theming: 3 sumbu lewat `data-*` di root
|
|
147
|
+
- `data-theme="light|dark"` me-redefinisi token semantic (bind ke state tema app-mu).
|
|
147
148
|
Berlaku di **ancestor mana pun**, tak harus root: `<section data-theme="dark">` membalik region itu
|
|
148
149
|
dan semua komponen di dalamnya ikut (lihat [`USAGE.md`](USAGE.md) §5b).
|
|
149
|
-
- `data-density="comfortable|compact"`
|
|
150
|
+
- `data-density="comfortable|compact"` mengatur tinggi kontrol (`--control-h`) untuk layar padat data.
|
|
150
151
|
Ini auto-apply hanya ke kontrol bawaan Freeday (button, input, combo, dst); komponen
|
|
151
152
|
custom/hand-built harus baca `--control-h` sendiri (mis. `height: var(--control-h)`) supaya ikut
|
|
152
153
|
menyusut/melebar saat `data-density` berubah.
|
|
153
|
-
- (roadmap) `data-style`
|
|
154
|
+
- (roadmap) `data-style` untuk varian visual lain.
|
|
154
155
|
- Skala breakpoint (`sm`/`md`/`lg`/`xl` = 600/960/1280/1920px, sama dengan utilitas
|
|
155
156
|
`src/components/breakpoints.css`) juga tersedia di JS: `import { breakpoints } from
|
|
156
|
-
'@cahyo-dimas/freeday/breakpoints'
|
|
157
|
-
skala Freeday.
|
|
157
|
+
'@cahyo-dimas/freeday/breakpoints'`. Pakai itu untuk menyamakan `matchMedia`/`@media` app-mu
|
|
158
|
+
dengan skala Freeday.
|
|
158
159
|
|
|
159
160
|
## Integrasi framework (SPA)
|
|
160
|
-
> **Peta library lengkap:** [`docs/integrations.md`](docs/integrations.md)
|
|
161
|
+
> **Peta library lengkap:** [`docs/integrations.md`](docs/integrations.md). Tiap area
|
|
161
162
|
> (form/validasi, chart, tabel, tanggal, overlay, dst) dipetakan ke library ekosistem yang biasa
|
|
162
163
|
> dipasang (Zod/Yup, Chart.js, TanStack Table, date-fns, Floating UI, …), plus cara
|
|
163
164
|
> menjembataninya + binding Vue/React/Blazor. Buka saat mulai project baru.
|
|
164
165
|
|
|
165
|
-
**Adapter siap pakai
|
|
166
|
+
**Adapter siap pakai untuk Vue, React, dan Blazor.** Semua tipis: enhancer tetap sumber kebenaran,
|
|
166
167
|
adapter hanya hydrate + jembatani event. Tiap punya contoh layar **faktur** yang jalan:
|
|
167
168
|
|
|
168
169
|
```ts
|
|
169
|
-
// Vue 3
|
|
170
|
+
// Vue 3: @cahyo-dimas/freeday/vue
|
|
170
171
|
import { useFreeday } from '@cahyo-dimas/freeday/vue';
|
|
171
172
|
const root = ref<HTMLElement | null>(null);
|
|
172
173
|
useFreeday(root); // @fdy-cascade-change="…" (detail bertipe)
|
|
173
174
|
```
|
|
174
175
|
```tsx
|
|
175
|
-
// React
|
|
176
|
+
// React: @cahyo-dimas/freeday/react
|
|
176
177
|
import { useFreeday } from '@cahyo-dimas/freeday/react';
|
|
177
178
|
const root = useRef<HTMLDivElement>(null);
|
|
178
179
|
useFreeday(root); // event fdy-* bubbling → listen di root
|
|
179
180
|
```
|
|
180
181
|
```razor
|
|
181
|
-
@* Blazor
|
|
182
|
+
@* Blazor: RCL Freeday.Blazor (net8.0), komponen native typed <FdyX> dengan @bind, 11/11 parity *@
|
|
182
183
|
@using Freeday.Blazor
|
|
183
184
|
<FdyCombo TValue="string" @bind-Value="_status" Options="_statusOptions" AriaLabelledby="lbl" />
|
|
184
185
|
<FdyTable TRow="Invoice" Columns="_cols" Rows="_rows" RowKey="@(i => i.Code)" PageSize="10" />
|
|
@@ -195,18 +196,18 @@ Peta library & pola lengkap: [`docs/integrations.md`](docs/integrations.md).
|
|
|
195
196
|
|
|
196
197
|
Enhancer auto-init sekali saat load. Untuk DOM yang dirender dinamis (Vue/React/Blazor):
|
|
197
198
|
- **Reuse enhancer:** setelah mount/route change, panggil `window.FreedayTable.initAll(el)` (atau
|
|
198
|
-
`initAll()` global). Aman diulang
|
|
199
|
+
`initAll()` global). Aman diulang, karena tiap init dijaga flag idempotent. Jembatani ke state framework
|
|
199
200
|
lewat event yang dipancarkan (mis. dengarkan `fdy-cfl-select`, `fdy-datepicker-change`).
|
|
200
201
|
- **Atau re-implement:** tulis komponen framework sendiri, pertahankan **markup + kontrak ARIA +
|
|
201
202
|
kelas `fdy-*`** yang sama (lihat `docs/index.html`). Enhancer adalah implementasi rujukan, bukan
|
|
202
203
|
keharusan. Untuk choose-from-list, jadikan komponen terkontrol (`fetchPage` callback + server
|
|
203
204
|
cache), jangan mirror ke store global.
|
|
204
205
|
|
|
205
|
-
## Aturan token
|
|
206
|
+
## Aturan token: 3 lapis (jangan dilanggar)
|
|
206
207
|
```
|
|
207
|
-
Tier 1 PRIMITIVE ramp mentah (--azure-600…)
|
|
208
|
-
Tier 2 SEMANTIC peran (--color-primary, --color-surface…)
|
|
209
|
-
Tier 3 COMPONENT --fdy-<komponen>-<prop
|
|
208
|
+
Tier 1 PRIMITIVE ramp mentah (--azure-600…), TAK PERNAH dipakai di komponen
|
|
209
|
+
Tier 2 SEMANTIC peran (--color-primary, --color-surface…), berubah saat theme & re-brand
|
|
210
|
+
Tier 3 COMPONENT --fdy-<komponen>-<prop>, opsional, override lokal
|
|
210
211
|
```
|
|
211
212
|
Komponen hanya menyentuh Tier 2/3. Butuh nilai baru → compose → extend modifier → baru create.
|
|
212
213
|
|
|
@@ -252,10 +253,10 @@ terlihat, HTML native dulu sebelum ARIA, komponen interaktif ikut pola WAI-ARIA
|
|
|
252
253
|
## Dukungan browser
|
|
253
254
|
Butuh browser evergreen, kira-kira 2023+: **Chrome 111 · Safari 16.4 · Firefox 113** (floor
|
|
254
255
|
ditentukan `color-mix()`). Fitur lain: native `<dialog>`/`::backdrop`, `accent-color`, `100dvh`,
|
|
255
|
-
`conic-gradient`, `scroll-snap
|
|
256
|
+
`conic-gradient`, `scroll-snap`, semuanya ≥ Safari 15.4. Blur backdrop pakai
|
|
256
257
|
`-webkit-backdrop-filter` + `backdrop-filter` (Safari lama tetap jalan, hanya tanpa blur). Belum ada
|
|
257
|
-
CSS build/autoprefixer
|
|
258
|
+
CSS build/autoprefixer, jadi dukungan browser lama jadi tanggung jawab konsumen.
|
|
258
259
|
|
|
259
260
|
## Lisensi
|
|
260
|
-
[MIT](LICENSE) © 2026 Cahyo D. Kurnianto
|
|
261
|
+
[MIT](LICENSE) © 2026 Cahyo D. Kurnianto. Bebas dipakai, diubah, dan didistribusikan asal
|
|
261
262
|
menyertakan baris copyright + teks lisensi.
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
**English** · [Bahasa Indonesia](README.id.md)
|
|
4
4
|
|
|
5
|
-
> **More free days for devs
|
|
5
|
+
> **More free days for devs. The UI kit is ready to use.**
|
|
6
6
|
|
|
7
7
|
[](https://cahyo-dimas.github.io/freeday-ui-kit/)
|
|
8
|
-
[](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v2.0.0)
|
|
9
9
|
|
|
10
|
-
A token-driven, framework-agnostic UI kit
|
|
10
|
+
A token-driven, framework-agnostic UI kit. One source of truth for color, typography,
|
|
11
11
|
spacing, and components. Blueprint: `docs/superpowers/specs/2026-07-21-freeday-ui-kit-design.md`.
|
|
12
|
-
**Living reference:** **[cahyo-dimas.github.io/freeday-ui-kit](https://cahyo-dimas.github.io/freeday-ui-kit/)
|
|
12
|
+
**Living reference:** **[cahyo-dimas.github.io/freeday-ui-kit](https://cahyo-dimas.github.io/freeday-ui-kit/)**, or open `docs/index.html` directly in a browser.
|
|
13
13
|
|
|
14
14
|
> 🚀 **Starting a project?** Step-by-step per stack (HTML · Vue · React · Blazor): **[`docs/getting-started.md`](docs/getting-started.md)**.
|
|
15
15
|
>
|
|
@@ -17,7 +17,7 @@ spacing, and components. Blueprint: `docs/superpowers/specs/2026-07-21-freeday-u
|
|
|
17
17
|
> **[`COMPONENTS.md`](COMPONENTS.md)**. **Which one to reach for, and when:** **[`USAGE.md`](USAGE.md)**.
|
|
18
18
|
> A full screen assembled: **[`docs/reference-screen.html`](docs/reference-screen.html)**.
|
|
19
19
|
>
|
|
20
|
-
> 🤖 **Building with an AI agent (or vibe-coding)?** No model knows Freeday from training
|
|
20
|
+
> 🤖 **Building with an AI agent (or vibe-coding)?** No model knows Freeday from training, so give it
|
|
21
21
|
> **[`docs/agent-onboarding.md`](docs/agent-onboarding.md)** (paste-ready project instructions +
|
|
22
22
|
> a migration mapping table).
|
|
23
23
|
|
|
@@ -27,32 +27,34 @@ node tokens/build.mjs # tokens.json -> dist/freeday.tokens.css; bundles dist/f
|
|
|
27
27
|
# dist/freeday.bundle.css (tokens+components); copies dist/*.js + dist/freeday.js
|
|
28
28
|
npm test # build-transform tests + WCAG contrast (node:test)
|
|
29
29
|
```
|
|
30
|
-
`dist/` is committed
|
|
30
|
+
`dist/` is committed, so consumers don't have to build it themselves.
|
|
31
31
|
|
|
32
32
|
## Use in a project
|
|
33
33
|
|
|
34
34
|
### First: which entry point is yours?
|
|
35
35
|
|
|
36
|
-
Most of Freeday is markup + `fdy-*` classes and is identical everywhere. **
|
|
37
|
-
components also ship a typed wrapper
|
|
36
|
+
Most of Freeday is markup + `fdy-*` classes and is identical everywhere. **Eleven interactive
|
|
37
|
+
components also ship a typed wrapper.** In those stacks, use the wrapper rather than raw markup +
|
|
38
|
+
enhancer:
|
|
38
39
|
|
|
39
|
-
| Your stack | Import the
|
|
40
|
+
| Your stack | Import the eleven from | Binding |
|
|
40
41
|
|---|---|---|
|
|
41
42
|
| **Vue 3** | `@cahyo-dimas/freeday/vue` | `v-model` |
|
|
42
43
|
| **React 18/19** | `@cahyo-dimas/freeday/react` | `value` + `onChange` |
|
|
43
44
|
| **Blazor (net8.0)** | `Freeday.Blazor` RCL | `@bind-Value` |
|
|
44
45
|
| Static HTML · Svelte · server-rendered templates | *(no wrapper)* raw markup + enhancers, below | `fdy-*` events |
|
|
45
46
|
|
|
46
|
-
The
|
|
47
|
-
`FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer`. Hand-writing the raw
|
|
48
|
-
these inside Vue/React/Blazor *looks* fine
|
|
47
|
+
The eleven: `FdyCombo` · `FdyDatepicker` · `FdyDateRange` · `FdyAutocomplete` · `FdyCascade` ·
|
|
48
|
+
`FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer` · `FdyAppShell`. Hand-writing the raw
|
|
49
|
+
markup for these inside Vue/React/Blazor *looks* fine at first, because the first render is correct.
|
|
50
|
+
Then it breaks quietly:
|
|
49
51
|
DOM the framework renders later is never hydrated, and the widget's state ends up in the DOM instead
|
|
50
52
|
of your framework's. Everything else (button, card, badge, alert, table markup, layout, and the
|
|
51
|
-
interactive components with no wrapper) is the same plain markup in every stack
|
|
53
|
+
interactive components with no wrapper) is the same plain markup in every stack. Hydrate the latter
|
|
52
54
|
with `useFreeday` (Vue/React) or `FreedayBlazor.initAll` (Blazor). Full walkthrough per stack:
|
|
53
55
|
[`docs/getting-started.md`](docs/getting-started.md).
|
|
54
56
|
|
|
55
|
-
**As a package (
|
|
57
|
+
**As a package (Vue/React/Blazor/Vite, or any project with a bundler):**
|
|
56
58
|
```bash
|
|
57
59
|
npm i @cahyo-dimas/freeday
|
|
58
60
|
```
|
|
@@ -76,27 +78,27 @@ bundler. Because it's on **public npm**, `npm ci` runs in CI without auth or an
|
|
|
76
78
|
<link rel="stylesheet" href="dist/freeday.css"> <!-- fdy-* components -->
|
|
77
79
|
```
|
|
78
80
|
Component classes are prefixed `fdy-` (e.g. `fdy-btn`, `fdy-card`, `fdy-badge`). Use them directly
|
|
79
|
-
in any framework's markup
|
|
81
|
+
in any framework's markup: Vue, React, Blazor, or plain HTML.
|
|
80
82
|
|
|
81
|
-
> **⚠️ Load the fonts
|
|
83
|
+
> **⚠️ Load the fonts yourself. The package doesn't.** The type tokens name **Sora** / **IBM Plex Sans** /
|
|
82
84
|
> **JetBrains Mono** but Freeday bundles no font files. Load them (e.g. `@import '@fontsource/sora/700.css'`
|
|
83
|
-
> …) or override `--font-display`/`--font-body`/`--font-mono
|
|
85
|
+
> …) or override `--font-display`/`--font-body`/`--font-mono`. Otherwise the kit renders in the system
|
|
84
86
|
> fallback and looks unfinished. See [`docs/getting-started.md` §Core concepts](docs/getting-started.md).
|
|
85
87
|
|
|
86
88
|
> **Which token/role to use when → [`USAGE.md`](USAGE.md).** Freeday enforces consistent *values*;
|
|
87
|
-
> `USAGE.md` is the doctrine that also makes *decisions* consistent
|
|
89
|
+
> `USAGE.md` is the doctrine that also makes *decisions* consistent: type roles (`.fdy-title-page/-section/-card`),
|
|
88
90
|
> spacing rhythm, elevation, one-primary-per-screen, the `--tone-1…8` categorical palette, and the page-
|
|
89
91
|
> composition primitives (`.fdy-page`, `.fdy-page-section`, `.fdy-stats`). Every app starts in `.fdy-app`.
|
|
90
92
|
|
|
91
93
|
> **Scope: components + tokens, not layout.** Freeday owns components and design tokens; the only
|
|
92
94
|
> layout helpers are `.fdy-hidden` / `.fdy-visually-hidden` plus the page-composition primitives above.
|
|
93
|
-
> Bring your own grid layer
|
|
95
|
+
> Bring your own grid layer. Pair it with a utility framework (Tailwind, UnoCSS…) run **utilities-only
|
|
94
96
|
> with preflight OFF** (Freeday's `base.css` is the reset). `base.css` is a *light* reset (it doesn't
|
|
95
|
-
> strip `ul`/`ol`/`p` margins
|
|
97
|
+
> strip `ul`/`ol`/`p` margins, so use `.fdy-list-reset` or a Freeday list component), and the
|
|
96
98
|
> spacing/radius/duration scales are public custom properties (`--space-0`…`--space-24`, …) you can
|
|
97
99
|
> build your utility theme on. Full notes: [`docs/getting-started.md` §Core concepts](docs/getting-started.md).
|
|
98
100
|
|
|
99
|
-
> `.fdy-btn` is **already** the primary button
|
|
101
|
+
> `.fdy-btn` is **already** the primary button. There's no separate `.fdy-btn--primary` modifier.
|
|
100
102
|
> Modifiers for other variants: `--ghost`, `--danger`, `--text`, `--sm`, `--lg`, `--icon`
|
|
101
103
|
> (see `docs/index.html`).
|
|
102
104
|
|
|
@@ -116,7 +118,8 @@ JS. Two ways:
|
|
|
116
118
|
<script src="dist/freeday-upload.js" defer></script> <!-- [data-fdy-dropzone] -->
|
|
117
119
|
<script src="dist/freeday-toast.js" defer></script> <!-- Freeday.toast({...}) -->
|
|
118
120
|
```
|
|
119
|
-
Each one auto-inits `[data-fdy-*]` on `DOMContentLoaded
|
|
121
|
+
Each one auto-inits `[data-fdy-*]` on `DOMContentLoaded`. They're idempotent, and they degrade to
|
|
122
|
+
plain markup when the script never loads.
|
|
120
123
|
|
|
121
124
|
| Enhancer | Markup hook | Event / API |
|
|
122
125
|
|---|---|---|
|
|
@@ -137,47 +140,47 @@ Each one auto-inits `[data-fdy-*]` on `DOMContentLoaded` — idempotent, progres
|
|
|
137
140
|
|
|
138
141
|
Wide tables (many columns) need a wrapper for horizontal scroll: wrap `.fdy-table` in
|
|
139
142
|
`.fdy-table-wrap` (a standard table, includes the border + shadow shell) or `.fdy-table-scroll`
|
|
140
|
-
(plain scroll, no shell
|
|
143
|
+
(plain scroll, no shell, so it works standalone or inside `.fdy-datatable`, which already has its own
|
|
141
144
|
border/shadow shell). Without one of these wrappers, a wide table overflows its container instead
|
|
142
145
|
of scrolling.
|
|
143
146
|
|
|
144
|
-
### 3. Theming
|
|
145
|
-
- `data-theme="light|dark"`
|
|
147
|
+
### 3. Theming: 3 axes via `data-*` on the root
|
|
148
|
+
- `data-theme="light|dark"` redefines the semantic tokens (bind it to your app's theme state).
|
|
146
149
|
Works on **any ancestor**, not just the root: `<section data-theme="dark">` inverts that region
|
|
147
150
|
and every component inside it follows (see [`USAGE.md`](USAGE.md) §5b).
|
|
148
|
-
- `data-density="comfortable|compact"`
|
|
151
|
+
- `data-density="comfortable|compact"` sets control height (`--control-h`) for data-dense screens.
|
|
149
152
|
This auto-applies only to Freeday's built-in controls (button, input, combo, etc.);
|
|
150
153
|
custom/hand-built components must read `--control-h` themselves (e.g. `height: var(--control-h)`)
|
|
151
154
|
to shrink or grow when `data-density` changes.
|
|
152
|
-
- (roadmap) `data-style`
|
|
155
|
+
- (roadmap) `data-style` for alternative visual variants.
|
|
153
156
|
- The breakpoint scale (`sm`/`md`/`lg`/`xl` = 600/960/1280/1920px, matching the
|
|
154
157
|
`src/components/breakpoints.css` utilities) is also available in JS: `import { breakpoints } from
|
|
155
|
-
'@cahyo-dimas/freeday/breakpoints'
|
|
156
|
-
Freeday's
|
|
158
|
+
'@cahyo-dimas/freeday/breakpoints'`. Use it to keep your app's `matchMedia`/`@media` on the same
|
|
159
|
+
scale as Freeday's.
|
|
157
160
|
|
|
158
161
|
## Framework integration (SPA)
|
|
159
|
-
> **Full library map:** [`docs/integrations.md`](docs/integrations.md)
|
|
162
|
+
> **Full library map:** [`docs/integrations.md`](docs/integrations.md). Each area (forms/validation,
|
|
160
163
|
> charts, tables, dates, overlays, etc.) mapped to the ecosystem library you'd normally reach for
|
|
161
164
|
> (Zod/Yup, Chart.js, TanStack Table, date-fns, Floating UI, …), plus how to bridge it and the
|
|
162
165
|
> Vue/React/Blazor bindings. Read it when starting a new project.
|
|
163
166
|
|
|
164
|
-
**Ready-made adapters
|
|
167
|
+
**Ready-made adapters for Vue, React and Blazor.** All thin: the enhancer stays the source of truth;
|
|
165
168
|
the adapter only hydrates and bridges events. Each ships a working **invoice** screen:
|
|
166
169
|
|
|
167
170
|
```ts
|
|
168
|
-
// Vue 3
|
|
171
|
+
// Vue 3: @cahyo-dimas/freeday/vue
|
|
169
172
|
import { useFreeday } from '@cahyo-dimas/freeday/vue';
|
|
170
173
|
const root = ref<HTMLElement | null>(null);
|
|
171
174
|
useFreeday(root); // @fdy-cascade-change="…" (typed detail)
|
|
172
175
|
```
|
|
173
176
|
```tsx
|
|
174
|
-
// React
|
|
177
|
+
// React: @cahyo-dimas/freeday/react
|
|
175
178
|
import { useFreeday } from '@cahyo-dimas/freeday/react';
|
|
176
179
|
const root = useRef<HTMLDivElement>(null);
|
|
177
180
|
useFreeday(root); // fdy-* events bubble → listen at the root
|
|
178
181
|
```
|
|
179
182
|
```razor
|
|
180
|
-
@* Blazor
|
|
183
|
+
@* Blazor: Freeday.Blazor RCL (net8.0), native typed <FdyX> with @bind, 11/11 parity *@
|
|
181
184
|
@using Freeday.Blazor
|
|
182
185
|
<FdyCombo TValue="string" @bind-Value="_status" Options="_statusOptions" AriaLabelledby="lbl" />
|
|
183
186
|
<FdyTable TRow="Invoice" Columns="_cols" Rows="_rows" RowKey="@(i => i.Code)" PageSize="10" />
|
|
@@ -194,7 +197,7 @@ Full library map and patterns: [`docs/integrations.md`](docs/integrations.md).
|
|
|
194
197
|
|
|
195
198
|
Enhancers auto-init once on load. For DOM rendered dynamically (Vue/React/Blazor):
|
|
196
199
|
- **Reuse the enhancer:** after a mount or route change, call `window.FreedayTable.initAll(el)`
|
|
197
|
-
(or the global `initAll()`). Safe to repeat
|
|
200
|
+
(or the global `initAll()`). Safe to repeat, since each init is guarded by an idempotent flag. Bridge
|
|
198
201
|
to framework state through the events it emits (e.g. listen for `fdy-cfl-select`,
|
|
199
202
|
`fdy-datepicker-change`).
|
|
200
203
|
- **Or re-implement:** write your own framework component, keeping the same **markup + ARIA
|
|
@@ -202,11 +205,11 @@ Enhancers auto-init once on load. For DOM rendered dynamically (Vue/React/Blazor
|
|
|
202
205
|
implementation, not a requirement. For choose-from-list, make it a controlled component
|
|
203
206
|
(`fetchPage` callback + server cache) rather than mirroring into a global store.
|
|
204
207
|
|
|
205
|
-
## Token rules
|
|
208
|
+
## Token rules: 3 tiers (don't break them)
|
|
206
209
|
```
|
|
207
|
-
Tier 1 PRIMITIVE raw ramp (--azure-600…)
|
|
208
|
-
Tier 2 SEMANTIC roles (--color-primary, --color-surface…)
|
|
209
|
-
Tier 3 COMPONENT --fdy-<component>-<prop
|
|
210
|
+
Tier 1 PRIMITIVE raw ramp (--azure-600…), NEVER used in components
|
|
211
|
+
Tier 2 SEMANTIC roles (--color-primary, --color-surface…), change on theme & re-brand
|
|
212
|
+
Tier 3 COMPONENT --fdy-<component>-<prop>, optional local override
|
|
210
213
|
```
|
|
211
214
|
Components only touch Tier 2/3. Need a new value → compose → extend a modifier → only then create.
|
|
212
215
|
|
|
@@ -220,7 +223,7 @@ src/*.js optional JS enhancers (reference, vanilla)
|
|
|
220
223
|
dist/ build output (COMMITTED):
|
|
221
224
|
freeday.tokens.css semantic tokens (light/dark/compact)
|
|
222
225
|
freeday.css every component (NO tokens)
|
|
223
|
-
freeday.bundle.css tokens + components
|
|
226
|
+
freeday.bundle.css tokens + components, link this one
|
|
224
227
|
freeday.js bundle of every enhancer (single <script>)
|
|
225
228
|
freeday-*.js per-file enhancers
|
|
226
229
|
COMPONENTS.md every class + markup skeleton + a11y contract
|
|
@@ -259,11 +262,11 @@ the "Accessibility" section in `docs/index.html`.
|
|
|
259
262
|
## Browser support
|
|
260
263
|
Needs an evergreen browser, roughly 2023+: **Chrome 111 · Safari 16.4 · Firefox 113** (the floor is
|
|
261
264
|
set by `color-mix()`). Other features used: native `<dialog>`/`::backdrop`, `accent-color`,
|
|
262
|
-
`100dvh`, `conic-gradient`, `scroll-snap
|
|
265
|
+
`100dvh`, `conic-gradient`, `scroll-snap`, all of them ≥ Safari 15.4. Backdrop blur uses
|
|
263
266
|
`-webkit-backdrop-filter` + `backdrop-filter` (older Safari still works, just without the blur).
|
|
264
|
-
There's no CSS build or autoprefixer step
|
|
267
|
+
There's no CSS build or autoprefixer step, so supporting older browsers is the consumer's
|
|
265
268
|
responsibility.
|
|
266
269
|
|
|
267
270
|
## License
|
|
268
|
-
[MIT](LICENSE) © 2026 Cahyo D. Kurnianto
|
|
271
|
+
[MIT](LICENSE) © 2026 Cahyo D. Kurnianto. Free to use, modify, and distribute, as long as the
|
|
269
272
|
copyright line and license text are included.
|