@cahyo-dimas/freeday 3.14.1 → 3.14.2
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 +25 -0
- package/COMPONENTS.md +5 -0
- package/README.id.md +1 -1
- package/README.md +1 -1
- package/adapters/react/index.d.ts +2 -1
- package/adapters/react/useFreeday.js +20 -2
- package/adapters/vue/index.d.ts +2 -1
- package/adapters/vue/useFreeday.js +15 -1
- package/docs/getting-started.md +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,31 @@ benar. Perubahan seperti itu ditulis di bawah `### Changed: BREAKING (types)`
|
|
|
9
9
|
lama → tipe baru, dan cara menyempitkannya — bukan di bawah `### Added`, betapapun aditifnya dari
|
|
10
10
|
sisi kit.
|
|
11
11
|
|
|
12
|
+
## [3.14.2] - 2026-10-30
|
|
13
|
+
|
|
14
|
+
**`useFreeday(ref)` dengan ref yang masih kosong kini bersuara.** Ref yang lupa dipasang di template
|
|
15
|
+
membuat adapter memindai seluruh dokumen tanpa tanda apa pun. Hasilnya bekerja, hanya lebih luas
|
|
16
|
+
dari yang diminta, dan markup lain di halaman diam-diam ikut bergantung padanya sampai hari ref itu
|
|
17
|
+
dipasang (`CATATAN-FREEDAY.md` §17). Kebalikan dari cakupan yang terlalu sempit di 3.13.0 `#099`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **Vue dan React: satu `console.warn` per komponen ketika ref yang diberikan ke `useFreeday` masih
|
|
21
|
+
`null` saat mount** (`#105`). Di Vue diperiksa di `onMounted`, di React sesudah commit pertama;
|
|
22
|
+
pembaruan sesudahnya tidak mengulangnya. Pesannya menyebut dua penyebab (ref tak terpasang, atau
|
|
23
|
+
terpasang di elemen di balik `v-if`/kondisi) dan dua jalan keluarnya (pasang di elemen yang selalu
|
|
24
|
+
dirender, atau `useFreeday()` tanpa argumen bila seluruh dokumen memang yang dimaksud).
|
|
25
|
+
|
|
26
|
+
### Catatan
|
|
27
|
+
- **Yang dipindai tidak berubah.** Ref kosong tetap jatuh ke seluruh dokumen. Adapter tidak dapat
|
|
28
|
+
membedakan ref yang lupa dari ref yang sekadar terlambat, dan mempersempitnya sekarang akan
|
|
29
|
+
mematikan dengan diam markup yang hari ini hanya hidup karena pemindaian itu, persis kelas cacat
|
|
30
|
+
`#099`. Peringatan ini memberi aplikasi waktu untuk membereskannya lebih dulu.
|
|
31
|
+
- Peringatan dinyalakan di setiap build, bukan hanya mode dev, sama seperti
|
|
32
|
+
`freeday-unhydrated.js`: kit tidak punya bendera build, dan peringatan ini hanya muncul pada kode
|
|
33
|
+
yang memang keliru.
|
|
34
|
+
- Blazor tidak dicakup: `ElementReference` adalah struct, bukan ref yang dapat `null`, dan apa yang
|
|
35
|
+
sampai ke `FreedayBlazor.initAll` dari `@ref` yang lupa ditangkap belum diukur.
|
|
36
|
+
|
|
12
37
|
## [3.14.1] - 2026-10-30
|
|
13
38
|
|
|
14
39
|
**Badan `FdyModal` kembali setinggi isinya di iPhone.** Di iPhone 7 sungguhan (iOS 15), setiap modal
|
package/COMPONENTS.md
CHANGED
|
@@ -52,6 +52,11 @@ live docs.
|
|
|
52
52
|
never enhanced logs one `console.warn` naming it, with the element attached. The usual cause is
|
|
53
53
|
a `useFreeday()` ref on a wrapper that does not contain it. `freeday-unhydrated.js` does this,
|
|
54
54
|
and it ships in the root import.
|
|
55
|
+
**A `useFreeday(ref)` whose ref is still null at mount says so too.** That is a ref left off the
|
|
56
|
+
template, or one on an element behind `v-if` / a condition, and the call falls back to the whole
|
|
57
|
+
document: everything works, wider than asked, and other markup on the page can come to rely on
|
|
58
|
+
that scan unnoticed. It logs one `console.warn` per component. Put the ref on an element that is
|
|
59
|
+
always rendered, or write `useFreeday()` with no argument when the document is what you mean.
|
|
55
60
|
**`data-fdy-ignore` says "not yours".** On an element or any ancestor, every enhancer skips that
|
|
56
61
|
subtree, even under an explicit `initAll(document)`, and the warning above stays quiet. Use it
|
|
57
62
|
where the app drives kit-styled markup itself, such as a chip matrix with its own removal flow.
|
package/README.id.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
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/v3.14.2)
|
|
9
9
|
|
|
10
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`.
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
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/v3.14.2)
|
|
9
9
|
|
|
10
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`.
|
|
@@ -8,7 +8,8 @@ export interface UseFreedayReturn {
|
|
|
8
8
|
/**
|
|
9
9
|
* Auto-initialise Freeday enhancers over a component's subtree on mount and
|
|
10
10
|
* after every commit. Pass a ref to scope the work; omit it to scan the whole
|
|
11
|
-
* document.
|
|
11
|
+
* document. A ref that is still null after the first commit also scans the
|
|
12
|
+
* whole document, and warns once: bind it to an always-rendered element, or omit it.
|
|
12
13
|
*/
|
|
13
14
|
export declare function useFreeday(rootRef?: RefObject<HTMLElement | null>): UseFreedayReturn;
|
|
14
15
|
|
|
@@ -14,10 +14,16 @@
|
|
|
14
14
|
* well as descendants, so both shapes work. (Before 1.23.0 only the wrapping shape did, and
|
|
15
15
|
* the other failed silently: querySelectorAll never matches its root.)
|
|
16
16
|
*
|
|
17
|
+
* A ref that is still null after the first commit is a mistake, and an unusually quiet one: the
|
|
18
|
+
* call falls back to the whole document, so everything works, only wider than asked, and other code
|
|
19
|
+
* on the page can come to depend on that scan without knowing it. It warns once, after the first
|
|
20
|
+
* commit. Pass no argument, useFreeday(), when the whole document is what you mean; and put the ref
|
|
21
|
+
* on an element that is always rendered, not one behind a condition.
|
|
22
|
+
*
|
|
17
23
|
* Events are native bubbling CustomEvents, add listeners on the root (they
|
|
18
24
|
* bubble) and read event.detail. See index.d.ts for the detail types.
|
|
19
25
|
*/
|
|
20
|
-
import { useEffect, useCallback } from 'react';
|
|
26
|
+
import { useEffect, useCallback, useRef } from 'react';
|
|
21
27
|
|
|
22
28
|
// Discover Freeday enhancer namespaces once (all registered by the time an app
|
|
23
29
|
// mounts, since `import 'freeday'` runs first). Each exposes initAll(el?).
|
|
@@ -36,7 +42,13 @@ function freedayApis() {
|
|
|
36
42
|
return _apis;
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
var EMPTY_REF = 'Freeday: useFreeday(ref) got a ref that is still null after the first commit, so it hydrated '
|
|
46
|
+
+ 'the whole document instead of one subtree. Either ref={...} is missing from the JSX, or it sits on an '
|
|
47
|
+
+ 'element that is not rendered yet (a condition). Put the ref on an element that is always rendered, or '
|
|
48
|
+
+ 'call useFreeday() with no argument if the whole document is what you mean.';
|
|
49
|
+
|
|
39
50
|
export function useFreeday(rootRef) {
|
|
51
|
+
var checked = useRef(false);
|
|
40
52
|
var rehydrate = useCallback(function () {
|
|
41
53
|
var el = rootRef && rootRef.current ? rootRef.current : undefined;
|
|
42
54
|
var apis = freedayApis();
|
|
@@ -44,6 +56,12 @@ export function useFreeday(rootRef) {
|
|
|
44
56
|
}, [rootRef]);
|
|
45
57
|
// No dependency array: runs after every commit (mount + updates), mirroring
|
|
46
58
|
// the Vue adapter's onMounted + onUpdated.
|
|
47
|
-
useEffect(
|
|
59
|
+
useEffect(function () {
|
|
60
|
+
if (!checked.current) {
|
|
61
|
+
checked.current = true;
|
|
62
|
+
if (rootRef && !rootRef.current) console.warn(EMPTY_REF);
|
|
63
|
+
}
|
|
64
|
+
rehydrate();
|
|
65
|
+
});
|
|
48
66
|
return { rehydrate: rehydrate };
|
|
49
67
|
}
|
package/adapters/vue/index.d.ts
CHANGED
|
@@ -8,7 +8,8 @@ export interface UseFreedayReturn {
|
|
|
8
8
|
/**
|
|
9
9
|
* Auto-initialise Freeday enhancers over a component's subtree on mount and
|
|
10
10
|
* after every update. Pass a template ref to scope the work; omit it to scan
|
|
11
|
-
* the whole document.
|
|
11
|
+
* the whole document. A ref that is still null at mount also scans the whole
|
|
12
|
+
* document, and warns once: bind it to an always-rendered element, or omit it.
|
|
12
13
|
*/
|
|
13
14
|
export declare function useFreeday(rootRef?: Ref<HTMLElement | null>): UseFreedayReturn;
|
|
14
15
|
|
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
* well as descendants, so both shapes work. (Before 1.23.0 only the wrapping shape did, and
|
|
16
16
|
* the other failed silently: querySelectorAll never matches its root.)
|
|
17
17
|
*
|
|
18
|
+
* A ref that is still null once the component has mounted is a mistake, and an unusually quiet
|
|
19
|
+
* one: the call falls back to the whole document, so everything works, only wider than asked, and
|
|
20
|
+
* other code on the page can come to depend on that scan without knowing it. It warns once, at
|
|
21
|
+
* mount. Pass no argument, useFreeday(), when the whole document is what you mean; and put the ref
|
|
22
|
+
* on an element that is always rendered, not one behind v-if.
|
|
23
|
+
*
|
|
18
24
|
* Events come straight through as native bubbling CustomEvents, bind them with
|
|
19
25
|
* plain v-on (e.g. @fdy-cascade-change) and read event.detail. See index.d.ts
|
|
20
26
|
* for the detail types.
|
|
@@ -36,6 +42,11 @@ function freedayApis() {
|
|
|
36
42
|
return apis;
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
var EMPTY_REF = 'Freeday: useFreeday(ref) got a ref that is still null after mount, so it hydrated the whole '
|
|
46
|
+
+ 'document instead of one subtree. Either ref="..." is missing from the template, or it sits on an element '
|
|
47
|
+
+ 'that is not rendered yet (v-if). Put the ref on an element that is always rendered, or call useFreeday() '
|
|
48
|
+
+ 'with no argument if the whole document is what you mean.';
|
|
49
|
+
|
|
39
50
|
export function useFreeday(rootRef) {
|
|
40
51
|
var apis = null;
|
|
41
52
|
function rehydrate() {
|
|
@@ -43,7 +54,10 @@ export function useFreeday(rootRef) {
|
|
|
43
54
|
var el = rootRef && 'value' in rootRef ? (rootRef.value || undefined) : undefined;
|
|
44
55
|
for (var i = 0; i < apis.length; i++) apis[i].initAll(el);
|
|
45
56
|
}
|
|
46
|
-
onMounted(
|
|
57
|
+
onMounted(function () {
|
|
58
|
+
if (rootRef && 'value' in rootRef && !rootRef.value) console.warn(EMPTY_REF);
|
|
59
|
+
rehydrate();
|
|
60
|
+
});
|
|
47
61
|
onUpdated(function () { nextTick(rehydrate); });
|
|
48
62
|
return { rehydrate: rehydrate };
|
|
49
63
|
}
|
package/docs/getting-started.md
CHANGED
|
@@ -198,7 +198,7 @@ live docs also have a copy button per component.
|
|
|
198
198
|
```bash
|
|
199
199
|
npm i @cahyo-dimas/freeday
|
|
200
200
|
```
|
|
201
|
-
Lands in `package.json` as `"@cahyo-dimas/freeday": "^3.14.
|
|
201
|
+
Lands in `package.json` as `"@cahyo-dimas/freeday": "^3.14.2"` (public npm package). `dist/` is
|
|
202
202
|
committed and published → no build step; `npm ci` runs without auth.
|
|
203
203
|
|
|
204
204
|
### 2. Import the CSS + enhancers **once** in your entry (`src/main.ts`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cahyo-dimas/freeday",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.2",
|
|
4
4
|
"description": "Freeday: token-driven, framework-agnostic UI KIT (design source-of-truth).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"scripts": {
|
|
97
97
|
"build": "node tokens/build.mjs",
|
|
98
98
|
"test": "node --test",
|
|
99
|
-
"test:browser": "node --test --test-concurrency=3 browser/color-mix.mjs browser/vanilla.mjs browser/adapter.mjs browser/layout.mjs browser/theme.mjs browser/state.mjs browser/root-init.mjs browser/upload-states.mjs browser/number.mjs browser/card-stretch.mjs browser/text-override.mjs browser/control-heights.mjs browser/field-width.mjs browser/cfl-multi.mjs browser/cfl-dialog-only.mjs browser/crowding.mjs browser/over-dialog.mjs browser/chart-scale.mjs browser/overlay-stack.mjs browser/chart-a11y.mjs browser/app-shell.mjs browser/bottom-nav.mjs browser/picker-states.mjs browser/tabs-strip.mjs browser/tabs-vertical.mjs browser/menu-align.mjs browser/cfl-narrow.mjs browser/form-reveal.mjs browser/confirm-search-copy.mjs browser/daterange-settled.mjs browser/display-parts.mjs browser/table-empty.mjs browser/table-footer-text.mjs browser/month-mode.mjs browser/monthpicker.mjs browser/page-columns.mjs browser/table-hover.mjs browser/typed-popover.mjs browser/filter-parity.mjs browser/filter-wrap.mjs browser/filter-stack.mjs browser/timepicker.mjs browser/form-kit-required.mjs browser/picker-in-modal.mjs browser/harness-contract.mjs browser/app-owned.mjs browser/sortable.mjs browser/modal-phone.mjs",
|
|
99
|
+
"test:browser": "node --test --test-concurrency=3 browser/color-mix.mjs browser/vanilla.mjs browser/adapter.mjs browser/layout.mjs browser/theme.mjs browser/state.mjs browser/root-init.mjs browser/upload-states.mjs browser/number.mjs browser/card-stretch.mjs browser/text-override.mjs browser/control-heights.mjs browser/field-width.mjs browser/cfl-multi.mjs browser/cfl-dialog-only.mjs browser/crowding.mjs browser/over-dialog.mjs browser/chart-scale.mjs browser/overlay-stack.mjs browser/chart-a11y.mjs browser/app-shell.mjs browser/bottom-nav.mjs browser/picker-states.mjs browser/tabs-strip.mjs browser/tabs-vertical.mjs browser/menu-align.mjs browser/cfl-narrow.mjs browser/form-reveal.mjs browser/confirm-search-copy.mjs browser/daterange-settled.mjs browser/display-parts.mjs browser/table-empty.mjs browser/table-footer-text.mjs browser/month-mode.mjs browser/monthpicker.mjs browser/page-columns.mjs browser/table-hover.mjs browser/typed-popover.mjs browser/filter-parity.mjs browser/filter-wrap.mjs browser/filter-stack.mjs browser/timepicker.mjs browser/form-kit-required.mjs browser/picker-in-modal.mjs browser/harness-contract.mjs browser/app-owned.mjs browser/sortable.mjs browser/modal-phone.mjs browser/empty-ref.mjs",
|
|
100
100
|
"prepack": "node tokens/build.mjs",
|
|
101
101
|
"version": "node tokens/build.mjs && git add dist",
|
|
102
102
|
"typecheck:react": "tsc -p adapters/react/tsconfig.json --noEmit",
|