@cahyo-dimas/freeday 1.21.0 → 1.23.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 +111 -0
- package/COMPONENTS.md +83 -3
- package/README.id.md +23 -1
- package/README.md +22 -1
- package/USAGE.md +21 -0
- package/adapters/react/useFreeday.js +5 -0
- package/adapters/vue/useFreeday.js +5 -0
- package/dist/freeday-autocomplete.js +4 -1
- package/dist/freeday-carousel.js +4 -1
- package/dist/freeday-cascade.js +4 -1
- package/dist/freeday-cfl.js +25 -20
- package/dist/freeday-chart.js +4 -1
- package/dist/freeday-chip.js +3 -0
- package/dist/freeday-datepicker.js +6 -3
- package/dist/freeday-datetime.js +4 -1
- package/dist/freeday-drawer.js +16 -11
- package/dist/freeday-form.js +4 -1
- package/dist/freeday-mask.js +3 -0
- package/dist/freeday-menu.js +4 -1
- package/dist/freeday-rating.js +4 -1
- package/dist/freeday-select.js +4 -5
- package/dist/freeday-slider.js +4 -1
- package/dist/freeday-stepper.js +4 -1
- package/dist/freeday-table.js +4 -4
- package/dist/freeday-tabs.js +4 -4
- package/dist/freeday-timepicker.js +4 -1
- package/dist/freeday-tree.js +4 -1
- package/dist/freeday-upload.js +4 -1
- package/dist/freeday.bundle.css +50 -2
- package/dist/freeday.css +50 -2
- package/dist/freeday.js +117 -60
- package/docs/agent-onboarding.md +35 -4
- package/docs/getting-started.md +10 -5
- package/package.json +2 -2
- package/src/components/app-shell.css +9 -0
- package/src/components/appbar.css +9 -0
- package/src/components/avatar.css +5 -0
- package/src/components/button.css +14 -0
- package/src/components/stepper.css +6 -1
- package/src/components/tabs.css +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,112 @@
|
|
|
3
3
|
Semua perubahan penting dicatat di sini. Format longgar mengikuti
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/); tiap versi = git tag.
|
|
5
5
|
|
|
6
|
+
## [1.23.0] — 2026-08-13
|
|
7
|
+
Consumption round 6 (`improvement-notes/006`). The reporter filed two of the three as **their own**
|
|
8
|
+
bugs rather than the kit's — and they were right about the code, but in both cases the kit had a way
|
|
9
|
+
to make the mistake impossible and had not taken it. Those are the two most valuable findings here.
|
|
10
|
+
### Fixed
|
|
11
|
+
- **`initAll(ctx)` now enhances `ctx` itself, not just its descendants.** `querySelectorAll` never
|
|
12
|
+
matches its own root, so a framework ref placed **on** the widget — `<div ref="menu" data-fdy-menu>`,
|
|
13
|
+
which is the ordinary shape when a component's root element *is* the widget — meant the one element
|
|
14
|
+
that needed enhancing was the only one that could not be found. It failed with **no error, no
|
|
15
|
+
warning, and a UI that looked finished**: the markup rendered and simply never opened. Measured
|
|
16
|
+
before the fix: `data-fdy-menu-ready` stayed `null` and `aria-expanded` stayed `"false"` while
|
|
17
|
+
`initAll` was present and callable the whole time; `initAll(parent)` worked. One `matches()` line
|
|
18
|
+
per selector, in **all 21 enhancers** (`drawer` and `cfl` needed their inline trigger callbacks
|
|
19
|
+
hoisted first). Init was already idempotent via each widget's `-ready` flag, so a root that is also
|
|
20
|
+
matched by the descendant query costs nothing. `useFreeday` (Vue/React) and `FreedayBlazor.initAll`
|
|
21
|
+
delegate to these, so they inherit the fix with no change of their own.
|
|
22
|
+
- **The stepper connector no longer draws through the markers when `__btn` is omitted.** The lift now
|
|
23
|
+
lives on `.fdy-step__marker` — the part that must always exist — instead of only on
|
|
24
|
+
`.fdy-step__btn`. The connector is `position:absolute; z-index:0`, and a positioned box paints
|
|
25
|
+
*after* in-flow inline content in the same stacking context, so a marker that was merely inline got
|
|
26
|
+
painted over: not for lack of a z-index, but for lack of being positioned at all. An
|
|
27
|
+
indicator-only stepper (no navigation, so no button) is a reasonable thing to write and it produced
|
|
28
|
+
a visible defect in shipped UI. Measured: hit-testing the marker's centre returned the connector's
|
|
29
|
+
own `.fdy-step` before, the marker after. `__btn` keeps its z-index for the navigable case.
|
|
30
|
+
### Added
|
|
31
|
+
- **`.fdy-avatar--xs`** (1.5rem, `--text-xs`) — an avatar inside a control had nothing to reach for:
|
|
32
|
+
`.fdy-btn--sm` is `calc(var(--control-h) - var(--space-2))` = **2rem**, exactly `--avatar--sm`'s
|
|
33
|
+
size, so the monogram filled a small button edge to edge and the ghost border crossed the circle
|
|
34
|
+
(measured: trigger 32px tall, avatar 32×32). 1.5rem inside 2rem leaves the ~4px the kit's other
|
|
35
|
+
controls give their icons. The report suggested `--text-2xs`; that token does not exist — `--text-xs`
|
|
36
|
+
is the smallest the kit has, and inventing a type step for one avatar size is not worth it.
|
|
37
|
+
### Added — guards
|
|
38
|
+
- **`browser/root-init.mjs`** — mounts a widget *after* load, initialises it through its own root, and
|
|
39
|
+
drives a **real click** to prove it opens; repeated for a second enhancer so the fix reads as the
|
|
40
|
+
shared pattern rather than a one-off. Mutation-checked on both. Being marked `-ready` is explicitly
|
|
41
|
+
not accepted as passing: an early version of this check reported success against markup the enhancer
|
|
42
|
+
had actually bailed on.
|
|
43
|
+
### Docs
|
|
44
|
+
- `COMPONENTS.md`: `initAll(root)` documents that the root may be the widget itself; the stepper
|
|
45
|
+
section states that `__btn` is **optional** and shows the read-only indicator markup (the parts list
|
|
46
|
+
never said which parts were optional); avatar gains its size table with the in-control guidance.
|
|
47
|
+
- Both `useFreeday` docstrings now show the ref-on-the-widget shape alongside the wrapping one.
|
|
48
|
+
|
|
49
|
+
## [1.22.0] — 2026-08-12
|
|
50
|
+
Two bodies of work. **(a)** three more findings from consumption round 5 — the report grew §5-§7
|
|
51
|
+
after 1.21.0 was cut; **(b)** a **routing** failure found in the same adopted project, which had been
|
|
52
|
+
built on raw markup + enhancers inside a framework that has typed wrappers because nothing in the
|
|
53
|
+
package ever told it otherwise. (b) was prepared as 1.21.1 and folded in here rather than shipped as
|
|
54
|
+
a separate patch minutes earlier.
|
|
55
|
+
### Added — from consumption round 5 (§5, §6)
|
|
56
|
+
- **`.fdy-nav--horizontal`** — the same navigation links laid out as a **row**, for a top-nav
|
|
57
|
+
application that puts its primary nav in `.fdy-appbar` / `.fdy-app__topbar` and has no sidebar.
|
|
58
|
+
Deliberately a modifier, not a new block: the item, its states and `aria-current="page"` are
|
|
59
|
+
unchanged. On `.fdy-appbar--primary` the links go on-colour automatically (full on-colour ink in
|
|
60
|
+
every state; the current page is carried by the background wash plus the semibold weight the base
|
|
61
|
+
rule already applies, so no dimmed variant trades away the bar's guaranteed contrast).
|
|
62
|
+
Reported as "there is no horizontal navigation component": `.fdy-nav` was the sidebar's vertical
|
|
63
|
+
menu and `.fdy-appbar` had `__brand`/`__spacer`/`__actions` but nothing to put *links* in — so a
|
|
64
|
+
top-nav app had a component for the bar and none for what the bar is mostly made of.
|
|
65
|
+
- **`.fdy-tabs__tab` also honours `aria-current="page"`**, so the tab *look* legitimately serves
|
|
66
|
+
**routed** sub-navigation (`/settings/profile` · `/settings/billing`) built from real links. A link
|
|
67
|
+
cannot be `aria-selected` — that is invalid ARIA on an anchor — so the app that borrowed the class
|
|
68
|
+
had to restate the active style for a second attribute. Keep `role="tab"` + `freeday-tabs.js` for
|
|
69
|
+
**in-page** tabs, where the roving-tabindex / one-panel-per-tab contract is real.
|
|
70
|
+
- **Pressed state for toggle buttons** — `aria-pressed="true"` now styles: soft primary fill + strong
|
|
71
|
+
ink on `--ghost`/`--text`, an inverted-gradient sunken look on the solid button, and the same
|
|
72
|
+
treatment in the danger hue. No new class or markup contract, since `aria-pressed` is already the
|
|
73
|
+
correct attribute — and it is what turns `.fdy-btn-group` from a joined row into a **complete**
|
|
74
|
+
segmented control. Previously "which one am I on" was left to each app to hand-tint, which is a
|
|
75
|
+
colour decision the kit should own.
|
|
76
|
+
*Found while building it:* one shared `.fdy-btn[aria-pressed="true"]` rule **cannot** work. A
|
|
77
|
+
gradient is a background-**image**, so the `background` shorthand resets `background-color` to
|
|
78
|
+
transparent — at equal specificity the later rule won and the ghost segment lost its fill entirely.
|
|
79
|
+
Each fill variant now defines its own pressed look. The CSS read correctly in the file; only a real
|
|
80
|
+
engine showed it, which is why the new guard lives in `browser/`.
|
|
81
|
+
### Fixed — from consumption round 5 (§7)
|
|
82
|
+
- **Hard rule 1 in `COMPONENTS.md` now records its one exception.** The rule says a modifier is
|
|
83
|
+
always written beside its block class, but `.fdy-input-group__addon--icon` is standalone by design
|
|
84
|
+
— adding the base `__addon` gives a search glyph the grey fill and divider of a `Rp` / `%` prefix.
|
|
85
|
+
An agent following the rule literally produced the wrong control; one following the CSS comment
|
|
86
|
+
broke the stated rule. The exception is now written down, and it is the only one.
|
|
87
|
+
### Fixed — the package now routes by stack
|
|
88
|
+
- **The paste-block in `docs/agent-onboarding.md` never mentioned the adapters.** That block is the
|
|
89
|
+
only text that lands in a consuming project's agent instructions, so it is the only text an agent
|
|
90
|
+
re-reads on every task — and it opened with "a CSS kit + enhancers, **not a component framework**",
|
|
91
|
+
which actively steers a Vue/React project away from the typed components. It now opens with a
|
|
92
|
+
**step 0 routing table** (Vue → `/vue` · React → `/react` · Blazor → RCL · everything else → raw
|
|
93
|
+
markup), names the ten wrapped components, and states the failure mode: the raw path renders
|
|
94
|
+
correctly the first time and then silently stops hydrating.
|
|
95
|
+
- **`COMPONENTS.md` flags the wrapper at each of the ten sections**, so the choice is visible at the
|
|
96
|
+
point of use rather than only on an onboarding page read once — with each component's *real*
|
|
97
|
+
binding (`v-model` / `value`+`onChange` / `@bind-Value` for the six value-bound ones; `open`+`close`
|
|
98
|
+
for modal and drawer; data props for chart; `columns`+`rows`+events for table). Hard rule 7 states
|
|
99
|
+
it up front.
|
|
100
|
+
- **Both READMEs lead with the routing table**, above the first import block. Previously the first
|
|
101
|
+
runnable snippet was the vanilla one and the adapter table sat ~130 lines below it.
|
|
102
|
+
- **`docs/getting-started.md`** core concept 2 ("the enhancer is the source of truth") is now scoped
|
|
103
|
+
to the raw path, and notes that Vue/React re-implement the ten natively while Blazor wraps the
|
|
104
|
+
enhancer over interop.
|
|
105
|
+
### Notes
|
|
106
|
+
- Root cause was structural, not editorial: at **v1.18.0** `docs/getting-started.md` — the only
|
|
107
|
+
per-stack router the kit had — was **not in `files`**, so `npm i` delivered a README whose
|
|
108
|
+
"Starting a project? per stack" link pointed at a path that does not exist inside `node_modules`.
|
|
109
|
+
`adapters/` *was* shipped, so the wrappers sat in the install, unused, with nothing pointing at
|
|
110
|
+
them. v1.20.0 started shipping the docs; this release makes them route.
|
|
111
|
+
|
|
6
112
|
## [1.21.0] — 2026-08-12
|
|
7
113
|
Fifth round of real-app consumption feedback, written while that app adopted 1.20.0. Two findings —
|
|
8
114
|
and a **withdrawal**: the reporter retracted 1.20's rejected §A themselves after isolating the real
|
|
@@ -57,6 +163,11 @@ reproduce here, so the rejection stands and the withdrawal is recorded rather th
|
|
|
57
163
|
hidden labels in a wide table, asserting the page cannot scroll horizontally *and* that the scroller
|
|
58
164
|
still scrolls. A static test cannot see this failure; only a layout engine can. Both guards
|
|
59
165
|
mutation-checked — reverting any single `position:relative` fails them.
|
|
166
|
+
- **`browser/state.mjs`** — pressed toggles and nav orientation in a real engine: the pressed ghost
|
|
167
|
+
segment must keep a flat background-colour (the mutation that reproduces the shorthand bug fails
|
|
168
|
+
it), the solid toggle must read as inset, `--horizontal` must actually be a row with the current
|
|
169
|
+
link marked, on-colour nav ink must stay on-colour in both states, and a routed tab must take its
|
|
170
|
+
underline from `aria-current`. Mutation-checked against all three fixes.
|
|
60
171
|
- **`browser/theme.mjs`** — subtree theming end-to-end: a `.fdy-title-page` and a `.fdy-card` inside
|
|
61
172
|
`<section data-theme="dark">` take the dark tokens, a nested light island goes back, and
|
|
62
173
|
`data-theme` on `<html>` still themes everything. `test/build.test.mjs` guards the selector shape
|
package/COMPONENTS.md
CHANGED
|
@@ -15,6 +15,10 @@ live docs.
|
|
|
15
15
|
1. **Prefix is `fdy-`, pattern is compact BEM**: block `fdy-card`, element `fdy-card__title`,
|
|
16
16
|
modifier `fdy-card--elevated`. A modifier is **always** written alongside its block class:
|
|
17
17
|
`class="fdy-btn fdy-btn--ghost"`, never `fdy-btn--ghost` alone.
|
|
18
|
+
**One documented exception:** `.fdy-input-group__addon--icon` is **standalone** — it is a
|
|
19
|
+
borderless leading glyph, and adding the base `.fdy-input-group__addon` would give it the grey
|
|
20
|
+
fill and divider of a `Rp` / `%` prefix, which is not what a search icon is. Written
|
|
21
|
+
`class="fdy-input-group__addon--icon"`, alone. It is the only one; everywhere else the rule holds.
|
|
18
22
|
2. **Never invent a class.** If it is not in this file, it does not exist. Freeday has no
|
|
19
23
|
`fdy-grid`, no `fdy-flex`, no `fdy-mt-4`, no `fdy-primary`.
|
|
20
24
|
3. **Never write a raw hex or px value** in app CSS. Use the tokens — `var(--color-primary)`,
|
|
@@ -30,6 +34,14 @@ live docs.
|
|
|
30
34
|
invalid state does not belong to the control itself.
|
|
31
35
|
6. **Interactive components need their enhancer script.** Static ones (button, card, badge, table,
|
|
32
36
|
alert, breadcrumb, timeline, accordion, tree-without-cascade…) are CSS-only.
|
|
37
|
+
7. **On Vue, React or Blazor, ten components have a typed wrapper — use it.** `FdyCombo` ·
|
|
38
|
+
`FdyDatepicker` · `FdyDateRange` · `FdyAutocomplete` · `FdyCascade` · `FdyCfl` · `FdyChart` ·
|
|
39
|
+
`FdyTable` · `FdyModal` · `FdyDrawer`, from `@cahyo-dimas/freeday/vue`, `/react`, or the
|
|
40
|
+
`Freeday.Blazor` RCL. Each is flagged at its own section below. Hand-writing their raw markup in
|
|
41
|
+
those stacks *looks* right — the enhancer initialises once and the first render is correct — then
|
|
42
|
+
breaks quietly: later-rendered DOM is never hydrated and the widget's state sits in the DOM
|
|
43
|
+
instead of your framework's. Everything else is the same markup everywhere; hydrate the other
|
|
44
|
+
interactive components with `useFreeday` (Vue/React) or `FreedayBlazor.initAll` (Blazor).
|
|
33
45
|
|
|
34
46
|
### Containment — why the kit's containers are `position:relative`
|
|
35
47
|
|
|
@@ -53,7 +65,9 @@ Two consequences for you:
|
|
|
53
65
|
## Enhancers — hook, script, global, events
|
|
54
66
|
|
|
55
67
|
Every enhancer is zero-dependency, auto-initialises once on `DOMContentLoaded`, and is idempotent:
|
|
56
|
-
re-hydrate SPA-rendered DOM with `window.Freeday<X>.initAll(root)`.
|
|
68
|
+
re-hydrate SPA-rendered DOM with `window.Freeday<X>.initAll(root)`. **`root` may be the widget
|
|
69
|
+
itself or an ancestor of it** — both work, so a framework ref placed directly on the enhanced
|
|
70
|
+
element is fine. Events are bubbling
|
|
57
71
|
`CustomEvent`s; the payload is in `event.detail`.
|
|
58
72
|
|
|
59
73
|
| Markup hook | Script | Global | Emits |
|
|
@@ -227,6 +241,10 @@ rest of the app is not.
|
|
|
227
241
|
- Modifiers: `--ghost` `--danger` `--text` `--icon` (square, icon-only) `--sm` `--lg`
|
|
228
242
|
- Parts: `.fdy-btn__icon` (wraps the `<svg>`) · `.fdy-btn-group` (segmented row, `role="group"` +
|
|
229
243
|
`aria-label`)
|
|
244
|
+
- **Toggle / segmented:** `aria-pressed="true"` gives a real pressed state (soft primary fill on
|
|
245
|
+
`--ghost`/`--text`, an inset-sunk gradient on the solid button). No extra class — `aria-pressed`
|
|
246
|
+
is already the right attribute, and it is what turns `.fdy-btn-group` from a joined row into a
|
|
247
|
+
complete segmented control.
|
|
230
248
|
- A11y: `--icon` **requires** `aria-label`. Use `<button type="button">` unless it submits.
|
|
231
249
|
|
|
232
250
|
```html
|
|
@@ -312,6 +330,8 @@ Native inputs, styled. `.fdy-check` · `.fdy-radio` · `.fdy-switch` on the wrap
|
|
|
312
330
|
```
|
|
313
331
|
|
|
314
332
|
## Select / combobox — `.fdy-combo`
|
|
333
|
+
> **Typed wrapper: `<FdyCombo>`** — Vue (`v-model`) · React (`value`/`onChange`) · Blazor (`@bind-Value`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
334
|
+
|
|
315
335
|
Fully styleable dropdown, APG combobox+listbox. Needs `freeday-select.js`.
|
|
316
336
|
|
|
317
337
|
- `.fdy-combo` (+`--error`, `--no-icon`) · `__button` `__value` (+`--placeholder`) `__listbox`
|
|
@@ -334,6 +354,8 @@ Fully styleable dropdown, APG combobox+listbox. Needs `freeday-select.js`.
|
|
|
334
354
|
```
|
|
335
355
|
|
|
336
356
|
## Autocomplete — `.fdy-autocomplete`
|
|
357
|
+
> **Typed wrapper: `<FdyAutocomplete>`** — Vue (`v-model`) · React (`value`/`onChange`) · Blazor (`@bind-Value`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
358
|
+
|
|
337
359
|
Editable combobox that filters as you type. Needs `freeday-autocomplete.js`.
|
|
338
360
|
|
|
339
361
|
- `.fdy-autocomplete` · `__listbox` `__option` `__empty`
|
|
@@ -341,6 +363,8 @@ Editable combobox that filters as you type. Needs `freeday-autocomplete.js`.
|
|
|
341
363
|
`aria-controls` → the listbox `id`, `autocomplete="off"`.
|
|
342
364
|
|
|
343
365
|
## Cascade select — `.fdy-cascade`
|
|
366
|
+
> **Typed wrapper: `<FdyCascade>`** — Vue (`v-model`) · React (`value`/`onChange`) · Blazor (`@bind-Value`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
367
|
+
|
|
344
368
|
Hierarchical drill-down. The data model is a **nested `<ul>`** inside the wrapper: an `<li>` with a
|
|
345
369
|
child `<ul>` is a branch, one without is a leaf. Needs `freeday-cascade.js`.
|
|
346
370
|
|
|
@@ -360,6 +384,8 @@ child `<ul>` is a branch, one without is a leaf. Needs `freeday-cascade.js`.
|
|
|
360
384
|
```
|
|
361
385
|
|
|
362
386
|
## Choose-from-list (CFL) — `data-fdy-cfl`
|
|
387
|
+
> **Typed wrapper: `<FdyCfl>`** — Vue (`v-model`) · React (`value`/`onChange`) · Blazor (`@bind-Value`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
388
|
+
|
|
363
389
|
A read-only field backed by master data: the button opens a searchable dialog, the picked row fills
|
|
364
390
|
the field. The value is always **chosen, never typed**. Needs `freeday-cfl.js`.
|
|
365
391
|
|
|
@@ -410,6 +436,8 @@ the field. The value is always **chosen, never typed**. Needs `freeday-cfl.js`.
|
|
|
410
436
|
```
|
|
411
437
|
|
|
412
438
|
## Date picker — `data-fdy-datepicker`
|
|
439
|
+
> **Typed wrapper: `<FdyDatepicker>`** — Vue (`v-model`) · React (`value`/`onChange`) · Blazor (`@bind-Value`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
440
|
+
|
|
413
441
|
Input-styled trigger + calendar popover. Needs `freeday-datepicker.js`. **Author an empty `<div>`**
|
|
414
442
|
— the enhancer builds everything.
|
|
415
443
|
|
|
@@ -417,6 +445,7 @@ Input-styled trigger + calendar popover. Needs `freeday-datepicker.js`. **Author
|
|
|
417
445
|
`__panel`; calendar internals `.fdy-cal__head` `__nav` `__title` `__grid` `__dow` `__day`
|
|
418
446
|
- Range: wrap two pickers in `.fdy-daterange` + `data-fdy-daterange` (`role="group"`), children
|
|
419
447
|
get `data-role="from"` / `"to"`; separator `.fdy-daterange__sep`. The end can't precede the start.
|
|
448
|
+
**Typed wrapper: `<FdyDateRange>`** (Vue/React/Blazor) — use it in those stacks.
|
|
420
449
|
- Attributes: `data-value="YYYY-MM-DD"`, `data-placeholder`, `data-label`, `data-fdy-no-icon`
|
|
421
450
|
|
|
422
451
|
```html
|
|
@@ -499,6 +528,18 @@ Linear multi-step flow: marker → check, one panel at a time, back/next. Needs
|
|
|
499
528
|
|
|
500
529
|
# Data
|
|
501
530
|
|
|
531
|
+
**`__btn` is optional.** For a **read-only indicator** put `__marker` + `__label` straight in the
|
|
532
|
+
`<li>`; for a **navigable** stepper wrap them in `<button class="fdy-step__btn">` (add `disabled`
|
|
533
|
+
for a step that is not reachable yet). Both render identically — the marker carries its own lift
|
|
534
|
+
over the connector line, so omitting `__btn` cannot make the connector draw through the numbers.
|
|
535
|
+
|
|
536
|
+
```html
|
|
537
|
+
<ol class="fdy-stepper">
|
|
538
|
+
<li class="fdy-step is-complete"><span class="fdy-step__marker">1</span><span class="fdy-step__label">Email</span></li>
|
|
539
|
+
<li class="fdy-step is-active"><span class="fdy-step__marker">2</span><span class="fdy-step__label">Verify</span></li>
|
|
540
|
+
</ol>
|
|
541
|
+
```
|
|
542
|
+
|
|
502
543
|
## Table — `.fdy-table`
|
|
503
544
|
Semantic static table. Wrap in `.fdy-table-wrap` (bordered surface) or `.fdy-table-scroll`
|
|
504
545
|
(horizontal scroll). Always a `<caption>` (use `.fdy-visually-hidden` if it shouldn't show) and
|
|
@@ -517,6 +558,8 @@ Semantic static table. Wrap in `.fdy-table-wrap` (bordered surface) or `.fdy-tab
|
|
|
517
558
|
```
|
|
518
559
|
|
|
519
560
|
## Data table — `.fdy-datatable`
|
|
561
|
+
> **Typed wrapper: `<FdyTable>`** — controlled: `columns` + `rows`, with sort/filter/page events (`update:pageIndex` · `onPageIndexChange` · `PageIndexChanged`) and `process` for driving a card list off the same processed set. The markup below is the raw enhancer path.
|
|
562
|
+
|
|
520
563
|
The interactive table: global search, sort, per-column filters, row selection + bulk bar,
|
|
521
564
|
pagination. Needs `freeday-table.js`. Wrap the whole thing in `.fdy-datatable` + `data-fdy-table`
|
|
522
565
|
(`data-page-size="N"`).
|
|
@@ -556,6 +599,8 @@ Empty / error placeholder for a data area. `--danger` for failures. Parts: `__ic
|
|
|
556
599
|
replaces.
|
|
557
600
|
|
|
558
601
|
## Charts — `data-fdy-chart`
|
|
602
|
+
> **Typed wrapper: `<FdyChart>`** — data props in all three (`type` + `values` / `series`); it repaints on data change, so `FreedayChart.update(el)` is only for the raw path below.
|
|
603
|
+
|
|
559
604
|
Pure SVG/CSS, no dependency, re-colours with the theme. Needs `freeday-chart.js`; call
|
|
560
605
|
`FreedayChart.update(el)` after changing data (or use `FdyChart` in Vue/React/Blazor).
|
|
561
606
|
|
|
@@ -662,18 +707,43 @@ Size-matched placeholders so nothing shifts when data lands: `--title` `--text`
|
|
|
662
707
|
|
|
663
708
|
# Navigation
|
|
664
709
|
|
|
665
|
-
## Nav (
|
|
666
|
-
|
|
710
|
+
## Nav (menu) — `.fdy-nav`
|
|
711
|
+
Navigation links — **vertical by default** (the app shell sidebar), horizontal with `--horizontal`. Items are `<a class="fdy-nav__item">` with
|
|
667
712
|
`__icon` / `__label` / `__badge`; the current one gets `aria-current="page"`.
|
|
668
713
|
`--flat` drops the surface. Nested groups are native `<details>`:
|
|
669
714
|
|
|
670
715
|
- `.fdy-nav__tree` + `<summary class="fdy-nav__item">` + `.fdy-nav__caret` → children in
|
|
671
716
|
`.fdy-nav__sub`
|
|
672
717
|
- `.fdy-nav__group` + `<summary class="fdy-nav__grouplabel">` → a collapsible section
|
|
718
|
+
- **`--horizontal`** lays the same links out as a row, for a **top-nav application** (primary
|
|
719
|
+
navigation in `.fdy-appbar` or `.fdy-app__topbar`, no sidebar). Same item, same states, same
|
|
720
|
+
`aria-current="page"`; the row scrolls if it runs out of width. On `.fdy-appbar--primary` the
|
|
721
|
+
links go on-colour automatically.
|
|
722
|
+
|
|
723
|
+
```html
|
|
724
|
+
<header class="fdy-appbar">
|
|
725
|
+
<a class="fdy-appbar__brand" href="/">Acme</a>
|
|
726
|
+
<nav class="fdy-nav fdy-nav--horizontal" aria-label="Main">
|
|
727
|
+
<a class="fdy-nav__item" href="/invoices" aria-current="page">Invoices</a>
|
|
728
|
+
<a class="fdy-nav__item" href="/customers">Customers</a>
|
|
729
|
+
</nav>
|
|
730
|
+
<span class="fdy-appbar__spacer"></span>
|
|
731
|
+
<div class="fdy-appbar__actions"><!-- buttons --></div>
|
|
732
|
+
</header>
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
> **Which one for navigation?** A nav link is a link marked `aria-current="page"` — never
|
|
736
|
+
> `aria-selected` (invalid ARIA on an anchor) and never `role="tab"`. Use `.fdy-nav--horizontal`
|
|
737
|
+
> for an application's **primary** navigation. For **routed sub-navigation** that should look like
|
|
738
|
+
> tabs (`/settings/profile` · `/settings/billing`), put `.fdy-tabs__list` / `.fdy-tabs__tab` on
|
|
739
|
+
> plain `<a>`s — those classes honour `aria-current="page"` too — and do **not** add the tab roles
|
|
740
|
+
> or `freeday-tabs.js`, which promise a keyboard contract routes do not have.
|
|
673
741
|
|
|
674
742
|
## App bar — `.fdy-appbar`
|
|
675
743
|
Standalone top bar (distinct from the shell's `.fdy-app__topbar`). Modifiers `--sticky`
|
|
676
744
|
`--elevated` `--dense` `--primary` (on-colour controls). Parts `__brand` `__spacer` `__actions`.
|
|
745
|
+
It ships **no link class of its own** — put `<nav class="fdy-nav fdy-nav--horizontal">` in it
|
|
746
|
+
for primary navigation (see Nav above).
|
|
677
747
|
|
|
678
748
|
## Breadcrumb — `.fdy-breadcrumb`
|
|
679
749
|
`<nav class="fdy-breadcrumb" aria-label="Breadcrumb">` → `<ol class="fdy-breadcrumb__list">` with
|
|
@@ -682,6 +752,8 @@ Standalone top bar (distinct from the shell's `.fdy-app__topbar`). Modifiers `--
|
|
|
682
752
|
|
|
683
753
|
## Tabs — `.fdy-tabs`
|
|
684
754
|
APG tabs: ←/→, Home/End, roving tabindex. Needs `freeday-tabs.js`.
|
|
755
|
+
`.fdy-tabs__tab` marks its active state from **`aria-selected="true"` or `aria-current="page"`**,
|
|
756
|
+
so the same look serves routed sub-navigation built from plain links — see the note under Nav.
|
|
685
757
|
|
|
686
758
|
```html
|
|
687
759
|
<div class="fdy-tabs" data-fdy-tabs>
|
|
@@ -699,12 +771,16 @@ APG tabs: ←/→, Home/End, roving tabindex. Needs `freeday-tabs.js`.
|
|
|
699
771
|
# Overlays
|
|
700
772
|
|
|
701
773
|
## Modal — `.fdy-modal`
|
|
774
|
+
> **Typed wrapper: `<FdyModal>`** — Vue (`:open` + `@close`) · React (`open` + `onClose`) · Blazor (`@bind-Open`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
775
|
+
|
|
702
776
|
Native `<dialog>`: focus trap, Esc and backdrop come from the browser. Sizes `--sm` `--md` `--lg`
|
|
703
777
|
`--wide`; `--cfl` for the choose-from-list dialog. Parts `__header` `__title` `__body` `__footer`
|
|
704
778
|
`__close`. The body scrolls; the footer never clips. `aria-labelledby` → the title's `id`;
|
|
705
779
|
`data-close` on any button that should close it.
|
|
706
780
|
|
|
707
781
|
## Drawer — `.fdy-drawer`
|
|
782
|
+
> **Typed wrapper: `<FdyDrawer>`** — Vue (`:open` + `@close`) · React (`open` + `onClose`) · Blazor (`@bind-Open`). In those stacks use the wrapper; the markup below is for stacks without an adapter (and is what the wrapper renders).
|
|
783
|
+
|
|
708
784
|
Temporary side panel on native `<dialog>` — left by default, `--right` to flip. Parts `__header`
|
|
709
785
|
`__title` `__body` `__footer` `__close`. Open it from any
|
|
710
786
|
`<button data-fdy-drawer="<dialog id>">`. Needs `freeday-drawer.js`.
|
|
@@ -751,6 +827,10 @@ Initials or image. Sizes `--sm` / default / `--lg`; `.fdy-avatar-group` stacks t
|
|
|
751
827
|
group). `--tone-1`…`--tone-8` are decorative tints (WCAG AA in both themes) to distinguish
|
|
752
828
|
same-initial avatars — hash the index off the **full** name, not the initials.
|
|
753
829
|
|
|
830
|
+
Sizes: `--xs` 1.5rem · *(base)* 2.5rem · `--sm` 2rem · `--lg` 3.5rem. Use **`--xs` inside a control**
|
|
831
|
+
— `.fdy-btn--sm` is itself 2rem tall, so an `--sm` avatar fills a small button edge to edge and the
|
|
832
|
+
ghost border cuts across the circle.
|
|
833
|
+
|
|
754
834
|
## Chip — `.fdy-chip`
|
|
755
835
|
Three roles inside a `.fdy-chips` row:
|
|
756
836
|
|
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/v1.23.0)
|
|
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`.
|
|
@@ -31,6 +31,28 @@ npm test # tes transformasi build + kontras WCAG (node:test)
|
|
|
31
31
|
|
|
32
32
|
## Pakai di project
|
|
33
33
|
|
|
34
|
+
### Pertama: pintu masuk mana yang kamu pakai?
|
|
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 +
|
|
38
|
+
enhancer:
|
|
39
|
+
|
|
40
|
+
| Stack-mu | Impor kesepuluhnya dari | Binding |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| **Vue 3** | `@cahyo-dimas/freeday/vue` | `v-model` |
|
|
43
|
+
| **React 18/19** | `@cahyo-dimas/freeday/react` | `value` + `onChange` |
|
|
44
|
+
| **Blazor (net8.0)** | RCL `Freeday.Blazor` | `@bind-Value` |
|
|
45
|
+
| HTML statis · Svelte · template server-rendered | *(tanpa wrapper)* markup mentah + enhancer, di bawah | event `fdy-*` |
|
|
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
|
|
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
|
|
53
|
+
yang terakhir, hydrate dengan `useFreeday` (Vue/React) atau `FreedayBlazor.initAll` (Blazor).
|
|
54
|
+
Panduan lengkap per stack: [`docs/getting-started.md`](docs/getting-started.md).
|
|
55
|
+
|
|
34
56
|
**Sebagai paket (project dengan bundler — Vue/React/Blazor/Vite):**
|
|
35
57
|
```bash
|
|
36
58
|
npm i @cahyo-dimas/freeday
|
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/v1.23.0)
|
|
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`.
|
|
@@ -31,6 +31,27 @@ npm test # build-transform tests + WCAG contrast (node:test)
|
|
|
31
31
|
|
|
32
32
|
## Use in a project
|
|
33
33
|
|
|
34
|
+
### First: which entry point is yours?
|
|
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:
|
|
38
|
+
|
|
39
|
+
| Your stack | Import the ten from | Binding |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **Vue 3** | `@cahyo-dimas/freeday/vue` | `v-model` |
|
|
42
|
+
| **React 18/19** | `@cahyo-dimas/freeday/react` | `value` + `onChange` |
|
|
43
|
+
| **Blazor (net8.0)** | `Freeday.Blazor` RCL | `@bind-Value` |
|
|
44
|
+
| Static HTML · Svelte · server-rendered templates | *(no wrapper)* raw markup + enhancers, below | `fdy-*` events |
|
|
45
|
+
|
|
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:
|
|
49
|
+
DOM the framework renders later is never hydrated, and the widget's state ends up in the DOM instead
|
|
50
|
+
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
|
|
52
|
+
with `useFreeday` (Vue/React) or `FreedayBlazor.initAll` (Blazor). Full walkthrough per stack:
|
|
53
|
+
[`docs/getting-started.md`](docs/getting-started.md).
|
|
54
|
+
|
|
34
55
|
**As a package (projects with a bundler — Vue/React/Blazor/Vite):**
|
|
35
56
|
```bash
|
|
36
57
|
npm i @cahyo-dimas/freeday
|
package/USAGE.md
CHANGED
|
@@ -115,6 +115,27 @@ container, a single `<section>`. An app whose two list screens are dense and who
|
|
|
115
115
|
are not should scope it per screen rather than densifying everything. Set it at one level per screen,
|
|
116
116
|
never per component.
|
|
117
117
|
|
|
118
|
+
## 6b. Navigation: one component, two orientations — and never a tab role
|
|
119
|
+
|
|
120
|
+
A navigation link is an `<a class="fdy-nav__item">` marked **`aria-current="page"`**. That does not
|
|
121
|
+
change with the layout:
|
|
122
|
+
|
|
123
|
+
- **Sidebar app** — `.fdy-nav` inside `.fdy-app__sidebar` (the default).
|
|
124
|
+
- **Top-nav app** — `.fdy-nav.fdy-nav--horizontal` inside `.fdy-appbar` or `.fdy-app__topbar`, with
|
|
125
|
+
no sidebar. Same items, same states; on `.fdy-appbar--primary` the links go on-colour for you.
|
|
126
|
+
- **Routed sub-navigation that should look like tabs** (`/settings/profile` · `/settings/billing`) —
|
|
127
|
+
put `.fdy-tabs__list` / `.fdy-tabs__tab` on plain `<a>`s. Those classes honour `aria-current="page"`
|
|
128
|
+
as well as `aria-selected="true"` precisely for this. Do **not** add `role="tab"`/`role="tablist"`
|
|
129
|
+
or `freeday-tabs.js`: those promise a roving-tabindex, arrow-key, one-panel-per-tab contract that
|
|
130
|
+
route links do not honour, and `aria-selected` is invalid ARIA on an anchor in the first place.
|
|
131
|
+
|
|
132
|
+
Reserve the full `.fdy-tabs` component (with its roles and its enhancer) for **in-page** tabs, where
|
|
133
|
+
nothing navigates.
|
|
134
|
+
|
|
135
|
+
**Toggles:** a button that is on/off carries `aria-pressed`, and the kit styles it — soft primary
|
|
136
|
+
fill on `--ghost`/`--text`, a sunken gradient on the solid button. A `.fdy-btn-group` of `--ghost`
|
|
137
|
+
buttons with exactly one `aria-pressed="true"` **is** the segmented control; don't hand-tint it.
|
|
138
|
+
|
|
118
139
|
## 7. Assemble the page from the frame down
|
|
119
140
|
|
|
120
141
|
1. **Shell:** every application starts inside **`.fdy-app`** — a flex row of `__sidebar` (with
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* useFreeday(root); // scopes init to this component's subtree
|
|
10
10
|
* // <div ref={root}> ...[data-fdy-*] markup... </div>
|
|
11
11
|
*
|
|
12
|
+
* The ref may also sit ON the widget itself — <div ref={root} data-fdy-menu> — which is what you
|
|
13
|
+
* write when the component's root element IS the widget. initAll() matches its own root as
|
|
14
|
+
* well as descendants, so both shapes work. (Before 1.23.0 only the wrapping shape did, and
|
|
15
|
+
* the other failed silently: querySelectorAll never matches its root.)
|
|
16
|
+
*
|
|
12
17
|
* Events are native bubbling CustomEvents — add listeners on the root (they
|
|
13
18
|
* bubble) and read event.detail. See index.d.ts for the detail types.
|
|
14
19
|
*/
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* useFreeday(root); // scopes init to this component's subtree
|
|
11
11
|
* // <div ref="root"> ...[data-fdy-*] markup... </div>
|
|
12
12
|
*
|
|
13
|
+
* The ref may also sit ON the widget itself — <div ref="root" data-fdy-menu> — which is what you
|
|
14
|
+
* write when the component's root element IS the widget. initAll() matches its own root as
|
|
15
|
+
* well as descendants, so both shapes work. (Before 1.23.0 only the wrapping shape did, and
|
|
16
|
+
* the other failed silently: querySelectorAll never matches its root.)
|
|
17
|
+
*
|
|
13
18
|
* Events come straight through as native bubbling CustomEvents — bind them with
|
|
14
19
|
* plain v-on (e.g. @fdy-cascade-change) and read event.detail. See index.d.ts
|
|
15
20
|
* for the detail types.
|
|
@@ -122,7 +122,10 @@
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
function initAll(context) {
|
|
125
|
-
|
|
125
|
+
var root = context || document;
|
|
126
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
127
|
+
if (root.matches && root.matches('[data-fdy-autocomplete]')) initAutocomplete(root);
|
|
128
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-autocomplete]'), initAutocomplete);
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
if (document.readyState === 'loading') {
|
package/dist/freeday-carousel.js
CHANGED
|
@@ -98,7 +98,10 @@
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
function initAll(context) {
|
|
101
|
-
|
|
101
|
+
var root = context || document;
|
|
102
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
103
|
+
if (root.matches && root.matches('[data-fdy-carousel]')) initCarousel(root);
|
|
104
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-carousel]'), initCarousel);
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
if (document.readyState === 'loading') {
|
package/dist/freeday-cascade.js
CHANGED
|
@@ -243,7 +243,10 @@
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
function initAll(context) {
|
|
246
|
-
|
|
246
|
+
var root = context || document;
|
|
247
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
248
|
+
if (root.matches && root.matches('[data-fdy-cascade]')) initCascade(root);
|
|
249
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-cascade]'), initCascade);
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
if (document.readyState === 'loading') {
|
package/dist/freeday-cfl.js
CHANGED
|
@@ -179,28 +179,33 @@
|
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
function
|
|
183
|
-
|
|
182
|
+
function bindGroup(group) {
|
|
183
|
+
if (group.dataset.fdyCflBound === '1') return;
|
|
184
|
+
var dialog = document.getElementById(group.getAttribute('data-fdy-cfl'));
|
|
185
|
+
if (!dialog) return;
|
|
186
|
+
initDialog(dialog);
|
|
187
|
+
var opener = group.querySelector('[data-fdy-cfl-trigger], .fdy-input-group__btn');
|
|
188
|
+
if (!opener) return;
|
|
189
|
+
group.dataset.fdyCflBound = '1';
|
|
190
|
+
opener.addEventListener('click', function () { dialog.fdyCflOpen(group, opener); });
|
|
191
|
+
}
|
|
184
192
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
opener.addEventListener('click', function () { dialog.fdyCflOpen(group, opener); });
|
|
194
|
-
});
|
|
193
|
+
function bindOpener(opener) {
|
|
194
|
+
if (opener.dataset.fdyCflBound === '1') return;
|
|
195
|
+
var dialog = document.getElementById(opener.getAttribute('data-fdy-cfl-open'));
|
|
196
|
+
if (!dialog) return;
|
|
197
|
+
initDialog(dialog);
|
|
198
|
+
opener.dataset.fdyCflBound = '1';
|
|
199
|
+
opener.addEventListener('click', function () { dialog.fdyCflOpen(null, opener); });
|
|
200
|
+
}
|
|
195
201
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
});
|
|
202
|
+
function initTriggers(context) {
|
|
203
|
+
var ctx = context || document;
|
|
204
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
205
|
+
if (ctx.matches && ctx.matches('[data-fdy-cfl]')) bindGroup(ctx);
|
|
206
|
+
if (ctx.matches && ctx.matches('[data-fdy-cfl-open]')) bindOpener(ctx);
|
|
207
|
+
Array.prototype.forEach.call(ctx.querySelectorAll('[data-fdy-cfl]'), bindGroup);
|
|
208
|
+
Array.prototype.forEach.call(ctx.querySelectorAll('[data-fdy-cfl-open]'), bindOpener);
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
if (document.readyState === 'loading') {
|
package/dist/freeday-chart.js
CHANGED
|
@@ -416,7 +416,10 @@
|
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
function initAll(context) {
|
|
419
|
-
|
|
419
|
+
var root = context || document;
|
|
420
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
421
|
+
if (root.matches && root.matches('[data-fdy-chart]')) initChart(root);
|
|
422
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-chart]'), initChart);
|
|
420
423
|
}
|
|
421
424
|
|
|
422
425
|
if (document.readyState === 'loading') {
|
package/dist/freeday-chip.js
CHANGED
|
@@ -69,6 +69,9 @@
|
|
|
69
69
|
|
|
70
70
|
function initAll(context) {
|
|
71
71
|
var root = context || document;
|
|
72
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
73
|
+
if (root.matches && root.matches('[data-fdy-chips]')) initGroup(root);
|
|
74
|
+
if (root.matches && root.matches('.fdy-chip__remove')) initRemove(root);
|
|
72
75
|
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-chips]'), initGroup);
|
|
73
76
|
Array.prototype.forEach.call(root.querySelectorAll('.fdy-chip__remove'), initRemove);
|
|
74
77
|
}
|
|
@@ -306,9 +306,12 @@
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
function initAll(context) {
|
|
309
|
-
var
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
var root = context || document;
|
|
310
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
311
|
+
if (root.matches && root.matches('[data-fdy-daterange]')) initRange(root);
|
|
312
|
+
if (root.matches && root.matches('[data-fdy-datepicker]')) initPicker(root);
|
|
313
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-daterange]'), initRange);
|
|
314
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-datepicker]'), initPicker);
|
|
312
315
|
}
|
|
313
316
|
|
|
314
317
|
if (document.readyState === 'loading') {
|
package/dist/freeday-datetime.js
CHANGED
|
@@ -70,7 +70,10 @@
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function initAll(context) {
|
|
73
|
-
|
|
73
|
+
var root = context || document;
|
|
74
|
+
/* root included: querySelectorAll never matches its own root, and a framework ref often sits ON the widget. */
|
|
75
|
+
if (root.matches && root.matches('[data-fdy-datetimepicker]')) initDatetime(root);
|
|
76
|
+
Array.prototype.forEach.call(root.querySelectorAll('[data-fdy-datetimepicker]'), initDatetime);
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
if (document.readyState === 'loading') {
|