@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.
Files changed (145) hide show
  1. package/CHANGELOG.md +657 -535
  2. package/COMPONENTS.md +153 -135
  3. package/README.id.md +46 -45
  4. package/README.md +46 -43
  5. package/USAGE.md +39 -35
  6. package/adapters/blazor/FdyAppShell.razor +50 -0
  7. package/adapters/blazor/FdyAppShell.razor.cs +114 -0
  8. package/adapters/blazor/FdyCfl.razor.cs +1 -1
  9. package/adapters/blazor/FdyChart.razor +1 -1
  10. package/adapters/blazor/FdyChart.razor.cs +3 -3
  11. package/adapters/blazor/FdyChartSeries.cs +1 -1
  12. package/adapters/blazor/FdyCombo.razor.cs +2 -2
  13. package/adapters/blazor/FdyModal.razor +1 -1
  14. package/adapters/blazor/FdyTable.razor.cs +7 -7
  15. package/adapters/blazor/FdyTableFilter.razor +1 -1
  16. package/adapters/blazor/FdyTableFooter.razor +1 -1
  17. package/adapters/blazor/FdyTableFooter.razor.cs +4 -4
  18. package/adapters/blazor/Freeday.Blazor.csproj +1 -1
  19. package/adapters/blazor/FreedayComponentBase.cs +1 -1
  20. package/adapters/blazor/TableModel.cs +3 -3
  21. package/adapters/blazor/TableTypes.cs +3 -3
  22. package/adapters/blazor/freeday-blazor.js +5 -5
  23. package/adapters/core/app-shell.d.ts +30 -0
  24. package/adapters/core/app-shell.js +134 -0
  25. package/adapters/core/table-model.d.ts +2 -2
  26. package/adapters/core/table-model.js +8 -8
  27. package/adapters/react/components/FdyAppShell.tsx +159 -0
  28. package/adapters/react/components/FdyAutocomplete.tsx +1 -1
  29. package/adapters/react/components/FdyCascade.tsx +1 -1
  30. package/adapters/react/components/FdyCfl.tsx +11 -11
  31. package/adapters/react/components/FdyDateRange.tsx +2 -2
  32. package/adapters/react/components/FdyDatepicker.tsx +5 -5
  33. package/adapters/react/components/FdyDrawer.tsx +1 -1
  34. package/adapters/react/components/FdyModal.tsx +2 -2
  35. package/adapters/react/components/FdyTable.tsx +7 -7
  36. package/adapters/react/components/FdyTableFilter.tsx +1 -1
  37. package/adapters/react/components/FdyTableFooter.tsx +5 -5
  38. package/adapters/react/index.d.ts +2 -1
  39. package/adapters/react/index.js +1 -0
  40. package/adapters/react/useFreeday.js +3 -3
  41. package/adapters/vue/components/FdyAppShell.vue +160 -0
  42. package/adapters/vue/components/FdyAutocomplete.vue +1 -1
  43. package/adapters/vue/components/FdyCascade.vue +1 -1
  44. package/adapters/vue/components/FdyCfl.vue +8 -8
  45. package/adapters/vue/components/FdyChart.vue +2 -2
  46. package/adapters/vue/components/FdyCombo.vue +1 -1
  47. package/adapters/vue/components/FdyDateRange.vue +2 -2
  48. package/adapters/vue/components/FdyDatepicker.vue +5 -5
  49. package/adapters/vue/components/FdyDrawer.vue +3 -3
  50. package/adapters/vue/components/FdyModal.vue +3 -3
  51. package/adapters/vue/components/FdyTable.vue +7 -7
  52. package/adapters/vue/components/FdyTableFilter.vue +1 -1
  53. package/adapters/vue/components/FdyTableFooter.vue +5 -5
  54. package/adapters/vue/index.d.ts +3 -2
  55. package/adapters/vue/index.js +1 -0
  56. package/adapters/vue/useFreeday.js +3 -3
  57. package/dist/asset.d.ts +3 -3
  58. package/dist/freeday-app-shell.js +49 -9
  59. package/dist/freeday-autocomplete.js +2 -2
  60. package/dist/freeday-breakpoint.js +1 -1
  61. package/dist/freeday-carousel.js +5 -5
  62. package/dist/freeday-cascade.js +7 -7
  63. package/dist/freeday-cfl.js +9 -9
  64. package/dist/freeday-chart.js +11 -11
  65. package/dist/freeday-chip.js +3 -3
  66. package/dist/freeday-datepicker.js +11 -7
  67. package/dist/freeday-datetime.js +5 -5
  68. package/dist/freeday-drawer.js +1 -1
  69. package/dist/freeday-form.js +14 -14
  70. package/dist/freeday-mask.js +6 -6
  71. package/dist/freeday-menu.js +1 -1
  72. package/dist/freeday-number.js +3 -3
  73. package/dist/freeday-popover.js +3 -3
  74. package/dist/freeday-rating.js +2 -2
  75. package/dist/freeday-select.js +5 -5
  76. package/dist/freeday-slider.js +2 -2
  77. package/dist/freeday-stepper.js +7 -7
  78. package/dist/freeday-table.js +15 -15
  79. package/dist/freeday-tabs.js +1 -1
  80. package/dist/freeday-timepicker.js +2 -2
  81. package/dist/freeday-toast.js +8 -8
  82. package/dist/freeday-tree.js +3 -3
  83. package/dist/freeday-upload.js +25 -25
  84. package/dist/freeday.bundle.css +176 -176
  85. package/dist/freeday.css +170 -170
  86. package/dist/freeday.d.ts +2 -2
  87. package/dist/freeday.js +202 -158
  88. package/dist/freeday.tokens.css +5 -5
  89. package/docs/agent-onboarding.md +42 -42
  90. package/docs/getting-started.md +35 -35
  91. package/docs/integrations.md +18 -18
  92. package/docs/reference-screen.html +14 -14
  93. package/package.json +5 -4
  94. package/src/base.css +6 -6
  95. package/src/components/accordion.css +4 -4
  96. package/src/components/alert.css +1 -1
  97. package/src/components/app-shell.css +10 -10
  98. package/src/components/appbar.css +3 -3
  99. package/src/components/autocomplete.css +1 -1
  100. package/src/components/avatar.css +3 -3
  101. package/src/components/badge.css +5 -5
  102. package/src/components/breadcrumb.css +1 -1
  103. package/src/components/breakpoints.css +4 -4
  104. package/src/components/button.css +13 -13
  105. package/src/components/card.css +8 -8
  106. package/src/components/carousel.css +2 -2
  107. package/src/components/cascade.css +2 -2
  108. package/src/components/cfl.css +4 -4
  109. package/src/components/chart.css +3 -3
  110. package/src/components/chip.css +2 -2
  111. package/src/components/combo.css +3 -3
  112. package/src/components/composition.css +7 -7
  113. package/src/components/datepicker.css +6 -6
  114. package/src/components/datetimepicker.css +1 -1
  115. package/src/components/description-list.css +1 -1
  116. package/src/components/divider.css +1 -1
  117. package/src/components/drawer.css +1 -1
  118. package/src/components/file-upload.css +5 -5
  119. package/src/components/filterbar.css +7 -7
  120. package/src/components/form-grid.css +2 -2
  121. package/src/components/input-group.css +6 -6
  122. package/src/components/input.css +6 -6
  123. package/src/components/kbd.css +1 -1
  124. package/src/components/list.css +6 -6
  125. package/src/components/menu.css +3 -3
  126. package/src/components/modal.css +1 -1
  127. package/src/components/pagination.css +1 -1
  128. package/src/components/progress.css +1 -1
  129. package/src/components/rating.css +2 -2
  130. package/src/components/selection.css +4 -4
  131. package/src/components/skeleton.css +1 -1
  132. package/src/components/slider.css +1 -1
  133. package/src/components/spinner.css +1 -1
  134. package/src/components/states.css +1 -1
  135. package/src/components/stepper.css +2 -2
  136. package/src/components/table.css +15 -15
  137. package/src/components/tabs.css +3 -3
  138. package/src/components/timeline.css +1 -1
  139. package/src/components/timepicker.css +1 -1
  140. package/src/components/toast.css +3 -3
  141. package/src/components/tooltip.css +1 -1
  142. package/src/components/tree.css +2 -2
  143. package/tokens/breakpoints.d.ts +2 -2
  144. package/tokens/breakpoints.mjs +3 -3
  145. 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 UI kit-nya sudah siap pakai.**
5
+ > **Lebih banyak _free day_ buat dev. UI kit-nya sudah siap pakai.**
6
6
 
7
7
  [![Live docs](https://img.shields.io/badge/docs-live-2050d8?style=flat-square)](https://cahyo-dimas.github.io/freeday-ui-kit/)
8
- [![Release](https://img.shields.io/badge/release-v1.53.0-0078d4?style=flat-square)](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v1.53.0)
8
+ [![Release](https://img.shields.io/badge/release-v2.0.0-0078d4?style=flat-square)](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v2.0.0)
9
9
 
10
- UI KIT yang token-driven & framework-agnostic satu sumber kebenaran untuk warna, tipografi,
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/)** atau buka `docs/index.html` langsung di browser.
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 konsumen tak perlu build sendiri.
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. **Sepuluh komponen
37
- interaktif juga punya wrapper typed** di stack berikut, pakai wrapper-nya, bukan markup mentah +
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 kesepuluhnya dari | Binding |
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
- Kesepuluhnya: `FdyCombo` · `FdyDatepicker` · `FdyDateRange` · `FdyAutocomplete` · `FdyCascade` ·
48
- `FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer`. Menulis markup mentah untuk
49
- kesepuluh ini di dalam Vue/React/Blazor *kelihatan* baik-baik saja render pertama benar — lalu
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 — untuk
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 (project dengan bundler — Vue/React/Blazor/Vite):**
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 Vue, React, Blazor, atau HTML polos.
80
+ markup framework apa pun: Vue, React, Blazor, atau HTML polos.
81
81
 
82
- > **⚠️ Muat font-nya sendiri paket ini tidak.** Token tipe menamai **Sora** / **IBM Plex Sans** /
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` kalau tidak, kit jatuh ke fallback
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* role tipe (`.fdy-title-page/-section/-card`),
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
- > 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
- > 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 tak ada modifier `.fdy-btn--primary` terpisah.
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` idempotent, progressive enhancement.
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 jalan standalone maupun di dalam `.fdy-datatable` yang 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 3 sumbu lewat `data-*` di root
146
- - `data-theme="light|dark"` redefinisi token semantic (bind ke state tema app-mu).
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"` tinggi kontrol (`--control-h`) untuk layar padat data.
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` varian visual lain.
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'` dipakai untuk menyamakan `matchMedia`/`@media` app-mu ke
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) tiap area
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 Vue · React · Blazor.** Semua tipis: enhancer tetap sumber kebenaran,
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 @cahyo-dimas/freeday/vue
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 @cahyo-dimas/freeday/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 RCL Freeday.Blazor (net8.0): komponen native typed <FdyX> dengan @bind, 10/10 parity *@
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 tiap init dijaga flag idempotent. Jembatani ke state framework
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 3 lapis (jangan dilanggar)
206
+ ## Aturan token: 3 lapis (jangan dilanggar)
206
207
  ```
207
- Tier 1 PRIMITIVE ramp mentah (--azure-600…) TAK PERNAH dipakai di komponen
208
- Tier 2 SEMANTIC peran (--color-primary, --color-surface…) berubah saat theme & re-brand
209
- Tier 3 COMPONENT --fdy-<komponen>-<prop> opsional, override lokal
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` semua ≥ Safari 15.4. Blur backdrop pakai
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 dukungan browser lama = tanggung jawab konsumen.
258
+ CSS build/autoprefixer, jadi dukungan browser lama jadi tanggung jawab konsumen.
258
259
 
259
260
  ## Lisensi
260
- [MIT](LICENSE) © 2026 Cahyo D. Kurnianto bebas dipakai, diubah, dan didistribusikan asal
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 the UI kit is ready to use.**
5
+ > **More free days for devs. The UI kit is ready to use.**
6
6
 
7
7
  [![Live docs](https://img.shields.io/badge/docs-live-2050d8?style=flat-square)](https://cahyo-dimas.github.io/freeday-ui-kit/)
8
- [![Release](https://img.shields.io/badge/release-v1.53.0-0078d4?style=flat-square)](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v1.53.0)
8
+ [![Release](https://img.shields.io/badge/release-v2.0.0-0078d4?style=flat-square)](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v2.0.0)
9
9
 
10
- A token-driven, framework-agnostic UI kit one source of truth for color, typography,
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/)** or open `docs/index.html` directly in a browser.
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 give it
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 consumers don't have to build it themselves.
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. **Ten interactive
37
- components also ship a typed wrapper** in these stacks, use the wrapper, not raw markup + enhancer:
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 ten from | Binding |
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 ten: `FdyCombo` · `FdyDatepicker` · `FdyDateRange` · `FdyAutocomplete` · `FdyCascade` ·
47
- `FdyCfl` · `FdyChart` · `FdyTable` · `FdyModal` · `FdyDrawer`. Hand-writing the raw markup for
48
- these inside Vue/React/Blazor *looks* fine the first render is correct — and then breaks quietly:
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 hydrate the latter
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 (projects with a bundler — Vue/React/Blazor/Vite):**
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 Vue, React, Blazor, or plain HTML.
81
+ in any framework's markup: Vue, React, Blazor, or plain HTML.
80
82
 
81
- > **⚠️ Load the fonts the package doesn't.** The type tokens name **Sora** / **IBM Plex Sans** /
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` otherwise the kit renders in the system
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 type roles (`.fdy-title-page/-section/-card`),
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 pair it with a utility framework (Tailwind, UnoCSS…) run **utilities-only
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 use `.fdy-list-reset` or a Freeday list component), and the
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 — there's no separate `.fdy-btn--primary` modifier.
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` idempotent, progressive enhancement.
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 works standalone or inside `.fdy-datatable`, which already has its own
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 3 axes via `data-*` on the root
145
- - `data-theme="light|dark"` redefines the semantic tokens (bind it to your app's theme state).
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"` control height (`--control-h`) for data-dense screens.
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` alternative visual variants.
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'` use it to align your app's `matchMedia`/`@media` with
156
- Freeday's scale.
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) each area (forms/validation,
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 Vue · React · Blazor.** All thin: the enhancer stays the source of truth;
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 @cahyo-dimas/freeday/vue
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 @cahyo-dimas/freeday/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 Freeday.Blazor RCL (net8.0): native typed <FdyX> with @bind, 10/10 parity *@
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 each init is guarded by an idempotent flag. Bridge
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 3 tiers (don't break them)
208
+ ## Token rules: 3 tiers (don't break them)
206
209
  ```
207
- Tier 1 PRIMITIVE raw ramp (--azure-600…) NEVER used in components
208
- Tier 2 SEMANTIC roles (--color-primary, --color-surface…) change on theme & re-brand
209
- Tier 3 COMPONENT --fdy-<component>-<prop> optional, local override
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 link this one
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` all ≥ Safari 15.4. Backdrop blur uses
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 supporting older browsers is the consumer's
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 free to use, modify, and distribute, as long as the
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.