@cahyo-dimas/freeday 1.54.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +625 -545
- package/COMPONENTS.md +141 -138
- package/README.id.md +46 -45
- package/README.md +46 -43
- package/USAGE.md +34 -34
- package/adapters/blazor/FdyAppShell.razor +2 -2
- package/adapters/blazor/FdyAppShell.razor.cs +6 -6
- package/adapters/blazor/FdyCfl.razor.cs +1 -1
- package/adapters/blazor/FdyChart.razor +1 -1
- package/adapters/blazor/FdyChart.razor.cs +3 -3
- package/adapters/blazor/FdyChartSeries.cs +1 -1
- package/adapters/blazor/FdyCombo.razor.cs +2 -2
- package/adapters/blazor/FdyModal.razor +1 -1
- package/adapters/blazor/FdyTable.razor.cs +7 -7
- package/adapters/blazor/FdyTableFilter.razor +1 -1
- package/adapters/blazor/FdyTableFooter.razor +1 -1
- package/adapters/blazor/FdyTableFooter.razor.cs +4 -4
- package/adapters/blazor/Freeday.Blazor.csproj +1 -1
- package/adapters/blazor/FreedayComponentBase.cs +1 -1
- package/adapters/blazor/TableModel.cs +3 -3
- package/adapters/blazor/TableTypes.cs +3 -3
- package/adapters/blazor/freeday-blazor.js +5 -5
- package/adapters/core/app-shell.d.ts +1 -1
- package/adapters/core/app-shell.js +6 -6
- package/adapters/core/table-model.d.ts +2 -2
- package/adapters/core/table-model.js +8 -8
- package/adapters/react/components/FdyAppShell.tsx +5 -5
- package/adapters/react/components/FdyAutocomplete.tsx +1 -1
- package/adapters/react/components/FdyCascade.tsx +1 -1
- package/adapters/react/components/FdyCfl.tsx +11 -11
- package/adapters/react/components/FdyDateRange.tsx +2 -2
- package/adapters/react/components/FdyDatepicker.tsx +5 -5
- package/adapters/react/components/FdyDrawer.tsx +1 -1
- package/adapters/react/components/FdyModal.tsx +2 -2
- package/adapters/react/components/FdyTable.tsx +7 -7
- package/adapters/react/components/FdyTableFilter.tsx +1 -1
- package/adapters/react/components/FdyTableFooter.tsx +5 -5
- package/adapters/react/index.d.ts +1 -1
- package/adapters/react/useFreeday.js +3 -3
- package/adapters/vue/components/FdyAppShell.vue +5 -5
- package/adapters/vue/components/FdyAutocomplete.vue +1 -1
- package/adapters/vue/components/FdyCascade.vue +1 -1
- package/adapters/vue/components/FdyCfl.vue +8 -8
- package/adapters/vue/components/FdyChart.vue +2 -2
- package/adapters/vue/components/FdyCombo.vue +1 -1
- package/adapters/vue/components/FdyDateRange.vue +2 -2
- package/adapters/vue/components/FdyDatepicker.vue +5 -5
- package/adapters/vue/components/FdyDrawer.vue +3 -3
- package/adapters/vue/components/FdyModal.vue +3 -3
- package/adapters/vue/components/FdyTable.vue +7 -7
- package/adapters/vue/components/FdyTableFilter.vue +1 -1
- package/adapters/vue/components/FdyTableFooter.vue +5 -5
- package/adapters/vue/index.d.ts +2 -2
- package/adapters/vue/useFreeday.js +3 -3
- package/dist/asset.d.ts +3 -3
- package/dist/freeday-app-shell.js +9 -9
- package/dist/freeday-autocomplete.js +2 -2
- package/dist/freeday-breakpoint.js +1 -1
- package/dist/freeday-carousel.js +5 -5
- package/dist/freeday-cascade.js +7 -7
- package/dist/freeday-cfl.js +9 -9
- package/dist/freeday-chart.js +11 -11
- package/dist/freeday-chip.js +3 -3
- package/dist/freeday-datepicker.js +11 -7
- package/dist/freeday-datetime.js +5 -5
- package/dist/freeday-drawer.js +1 -1
- package/dist/freeday-form.js +14 -14
- package/dist/freeday-mask.js +6 -6
- package/dist/freeday-menu.js +1 -1
- package/dist/freeday-number.js +3 -3
- package/dist/freeday-popover.js +3 -3
- package/dist/freeday-rating.js +2 -2
- package/dist/freeday-select.js +5 -5
- package/dist/freeday-slider.js +2 -2
- package/dist/freeday-stepper.js +7 -7
- package/dist/freeday-table.js +15 -15
- package/dist/freeday-tabs.js +1 -1
- package/dist/freeday-timepicker.js +2 -2
- package/dist/freeday-toast.js +8 -8
- package/dist/freeday-tree.js +3 -3
- package/dist/freeday-upload.js +25 -25
- package/dist/freeday.bundle.css +176 -176
- package/dist/freeday.css +170 -170
- package/dist/freeday.d.ts +2 -2
- package/dist/freeday.js +162 -158
- package/dist/freeday.tokens.css +5 -5
- package/docs/agent-onboarding.md +41 -41
- package/docs/getting-started.md +35 -35
- package/docs/integrations.md +18 -18
- package/docs/reference-screen.html +14 -14
- package/package.json +4 -3
- package/src/base.css +6 -6
- package/src/components/accordion.css +4 -4
- package/src/components/alert.css +1 -1
- package/src/components/app-shell.css +10 -10
- package/src/components/appbar.css +3 -3
- package/src/components/autocomplete.css +1 -1
- package/src/components/avatar.css +3 -3
- package/src/components/badge.css +5 -5
- package/src/components/breadcrumb.css +1 -1
- package/src/components/breakpoints.css +4 -4
- package/src/components/button.css +13 -13
- package/src/components/card.css +8 -8
- package/src/components/carousel.css +2 -2
- package/src/components/cascade.css +2 -2
- package/src/components/cfl.css +4 -4
- package/src/components/chart.css +3 -3
- package/src/components/chip.css +2 -2
- package/src/components/combo.css +3 -3
- package/src/components/composition.css +7 -7
- package/src/components/datepicker.css +6 -6
- package/src/components/datetimepicker.css +1 -1
- package/src/components/description-list.css +1 -1
- package/src/components/divider.css +1 -1
- package/src/components/drawer.css +1 -1
- package/src/components/file-upload.css +5 -5
- package/src/components/filterbar.css +7 -7
- package/src/components/form-grid.css +2 -2
- package/src/components/input-group.css +6 -6
- package/src/components/input.css +6 -6
- package/src/components/kbd.css +1 -1
- package/src/components/list.css +6 -6
- package/src/components/menu.css +3 -3
- package/src/components/modal.css +1 -1
- package/src/components/pagination.css +1 -1
- package/src/components/progress.css +1 -1
- package/src/components/rating.css +2 -2
- package/src/components/selection.css +4 -4
- package/src/components/skeleton.css +1 -1
- package/src/components/slider.css +1 -1
- package/src/components/spinner.css +1 -1
- package/src/components/states.css +1 -1
- package/src/components/stepper.css +2 -2
- package/src/components/table.css +15 -15
- package/src/components/tabs.css +3 -3
- package/src/components/timeline.css +1 -1
- package/src/components/timepicker.css +1 -1
- package/src/components/toast.css +3 -3
- package/src/components/tooltip.css +1 -1
- package/src/components/tree.css +2 -2
- package/tokens/breakpoints.d.ts +2 -2
- package/tokens/breakpoints.mjs +3 -3
- package/tokens/tokens.json +1 -1
package/dist/freeday-chart.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, chart renderer (optional, zero-dependency, no external chart lib).
|
|
2
2
|
* Renders sparkline / bar / line / area / donut into an element from data attributes.
|
|
3
3
|
* Auto-inits [data-fdy-chart] once; call FreedayChart.update(el) to re-render after the
|
|
4
4
|
* data attributes change (used by the freeday/vue <FdyChart> wrapper for reactive data).
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
* Single-series colour (sparkline / simple bar / single line) via data-fdy-color references a
|
|
7
7
|
* semantic token by name (primary, accent, success, warning, danger, info). Multi-series
|
|
8
8
|
* defaults draw from the validated categorical --chart-1..8 palette in fixed order (never
|
|
9
|
-
* cycled, 8-series cap); pass data-fdy-colors to override
|
|
9
|
+
* cycled, 8-series cap); pass data-fdy-colors to override, a name is a semantic token
|
|
10
10
|
* (var(--color-<name>)) OR a slot "chart-1".."chart-8" (var(--chart-N)) to pin a series to the
|
|
11
11
|
* validated palette. Both data-fdy-color and data-fdy-colors accept the chart-N form.
|
|
12
12
|
* Cartesian charts (line/area, multi-series/stacked bar) draw themed axes from --chart-grid /
|
|
13
13
|
* --chart-tick and format ticks + tooltips via data-fdy-format (number|percent|currency). Their
|
|
14
14
|
* viewBox is sized to the measured plot (1 user unit = 1 CSS pixel) and repainted from a
|
|
15
15
|
* ResizeObserver, so axis type stays in real pixels and is set in CSS via --fdy-chart-tick-size.
|
|
16
|
-
* Charts are an enhancement
|
|
16
|
+
* Charts are an enhancement, put a table/text fallback inside the element and it will be
|
|
17
17
|
* replaced on render; give the element role="img" + aria-label.
|
|
18
18
|
*
|
|
19
19
|
* Sparkline: <span data-fdy-chart="sparkline" data-values="4,6,5,8,7,10" data-fdy-color="primary">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
return v ? v.split(',').map(function (s) { return s.trim(); }) : [];
|
|
51
51
|
}
|
|
52
52
|
// role="img" is Children Presentational per ARIA, so the docs used to say a chart's rendered
|
|
53
|
-
// legend, bar values and donut centre are not exposed. No browser actually prunes that subtree
|
|
53
|
+
// legend, bar values and donut centre are not exposed. No browser actually prunes that subtree,
|
|
54
54
|
// measured in Chrome's AX tree, every one of those nodes is live and unignored; what saves the
|
|
55
55
|
// advice is only that AT treats a NAMED role="img" as a leaf and does not descend. So the kit
|
|
56
56
|
// hides them itself, and the author's aria-label really is the whole text alternative.
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
// Lay the chrome out first so the plot can be measured, then size the viewBox to it in CSS
|
|
226
226
|
// pixels: one user unit is one pixel, so font-size / r / stroke-width mean what they say at
|
|
227
227
|
// every container width. (A fixed 320x180 viewBox stretched by CSS multiplied every declared
|
|
228
|
-
// size by plotWidth/320 instead
|
|
228
|
+
// size by plotWidth/320 instead, a 9px axis label rendered ~39px on a 1728px viewport.)
|
|
229
229
|
var legendMode = el.getAttribute('data-fdy-legend') || 'auto';
|
|
230
230
|
var showLegend = legendMode !== 'none' && (series.length >= 2 || legendMode === 'always');
|
|
231
231
|
el.classList.add('fdy-chart-xy');
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
el.appendChild(plot);
|
|
247
247
|
|
|
248
248
|
// Measured while empty: .fdy-chart-xy__plot carries its own width / aspect-ratio / min-height,
|
|
249
|
-
// so the box is already final. A detached or display:none chart measures 0
|
|
249
|
+
// so the box is already final. A detached or display:none chart measures 0, fall back to the
|
|
250
250
|
// legacy box and let the ResizeObserver repaint it once it is actually laid out.
|
|
251
251
|
var box = plot.getBoundingClientRect();
|
|
252
252
|
var W = Math.round(box.width) || 320, H = Math.round(box.height) || 180;
|
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
|
|
291
291
|
// x category labels with autoskip. Labels are author-supplied, so estimate the widest one instead
|
|
292
292
|
// of assuming a fixed 40px slot; keep every step-th plus the last, then drop any kept label that
|
|
293
|
-
// would collide with the one before it
|
|
293
|
+
// would collide with the one before it, including the forced last one (a fraction-of-a-slot
|
|
294
294
|
// overlap happens when n-1 lands next to the last kept multiple of step, e.g. n=24 at most widths).
|
|
295
295
|
var widest = 0;
|
|
296
296
|
for (var wi = 0; wi < n; wi++) widest = Math.max(widest, String(labels[wi] || ('#' + (wi + 1))).length * charW);
|
|
@@ -301,7 +301,7 @@
|
|
|
301
301
|
for (var xi = 0; xi < n; xi++) {
|
|
302
302
|
if (xi % step === 0 || xi === n - 1) kept.push(xi);
|
|
303
303
|
}
|
|
304
|
-
// The last label is worth forcing, but not on top of its neighbour
|
|
304
|
+
// The last label is worth forcing, but not on top of its neighbour, drop the penultimate one.
|
|
305
305
|
if (kept.length >= 2 && xPos(kept[kept.length - 1]) - xPos(kept[kept.length - 2]) < minGap) {
|
|
306
306
|
kept.splice(kept.length - 2, 1);
|
|
307
307
|
}
|
|
@@ -434,17 +434,17 @@
|
|
|
434
434
|
var li = document.createElement('li');
|
|
435
435
|
var sw = document.createElement('span'); sw.className = 'fdy-chart__swatch'; sw.style.background = colorAt(i);
|
|
436
436
|
li.appendChild(sw);
|
|
437
|
-
li.appendChild(document.createTextNode((labels[i] || ('#' + (i + 1))) + '
|
|
437
|
+
li.appendChild(document.createTextNode((labels[i] || ('#' + (i + 1))) + ' · ' + Math.round((v / total) * 100) + '%'));
|
|
438
438
|
legend.appendChild(li);
|
|
439
439
|
});
|
|
440
440
|
el.appendChild(ring);
|
|
441
|
-
// Honour data-fdy-legend for the donut too
|
|
441
|
+
// Honour data-fdy-legend for the donut too, a caller may supply its own richer legend. 'auto'
|
|
442
442
|
// keeps today's behaviour (a donut is unreadable without labels, so it shows); 'none' suppresses it.
|
|
443
443
|
if ((el.getAttribute('data-fdy-legend') || 'auto') !== 'none') el.appendChild(legend);
|
|
444
444
|
ensureImg(el);
|
|
445
445
|
}
|
|
446
446
|
|
|
447
|
-
// Full (re-)render from current data attributes. Idempotent
|
|
447
|
+
// Full (re-)render from current data attributes. Idempotent, safe to call repeatedly.
|
|
448
448
|
function renderChart(el) {
|
|
449
449
|
var type = el.getAttribute('data-fdy-chart');
|
|
450
450
|
if (type === 'sparkline') renderSparkline(el);
|
package/dist/freeday-chip.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, chip enhancer (optional, zero-dependency).
|
|
2
2
|
* Two behaviours, both progressive enhancement:
|
|
3
3
|
*
|
|
4
|
-
* 1. Removable chips
|
|
4
|
+
* 1. Removable chips, any .fdy-chip__remove button removes its chip and emits a
|
|
5
5
|
* bubbling "fdy-chip-remove" (detail {value}).
|
|
6
|
-
* 2. Choice / filter groups
|
|
6
|
+
* 2. Choice / filter groups, a [data-fdy-chips] container of interactive chips
|
|
7
7
|
* (.fdy-chip--choice / .fdy-chip--filter, each a <button>) toggles aria-pressed
|
|
8
8
|
* on click. Add data-single for one-at-a-time (radio-like) selection; filter
|
|
9
9
|
* chips get a leading check when pressed. Emits "fdy-chip-change" on the group
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, date picker enhancer (optional, zero-dependency).
|
|
2
2
|
* Builds an input-styled trigger + calendar popover from an empty wrapper.
|
|
3
|
-
* Locale comes from <html lang> (via Intl)
|
|
3
|
+
* Locale comes from <html lang> (via Intl), month/weekday/value formatting is not hardcoded.
|
|
4
4
|
*
|
|
5
5
|
* Markup contract:
|
|
6
6
|
* - Single: <div data-fdy-datepicker data-value="2026-07-21" data-label="Tanggal unggah"
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
(function () {
|
|
20
20
|
'use strict';
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
/* The page's own `lang` wins, which is the better escape hatch than any attribute the kit
|
|
23
|
+
could invent: an Indonesian app writes <html lang="id"> and gets Indonesian month and
|
|
24
|
+
weekday names back automatically. The FALLBACK follows the kit's default language, or a
|
|
25
|
+
page without `lang` would read English labels around Indonesian month names. */
|
|
26
|
+
var LOCALE = document.documentElement.getAttribute('lang') || 'en';
|
|
23
27
|
var uidSeq = 0;
|
|
24
28
|
function uid(p) { uidSeq += 1; return p + '-' + uidSeq; }
|
|
25
29
|
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
|
@@ -66,10 +70,10 @@
|
|
|
66
70
|
var view = startOfDay(selected || new Date());
|
|
67
71
|
view = new Date(view.getFullYear(), view.getMonth(), 1);
|
|
68
72
|
var focusDate = null;
|
|
69
|
-
/* 'days' | 'months'
|
|
73
|
+
/* 'days' | 'months', the calendar drills one level up rather than growing furniture beside the
|
|
70
74
|
title. Before this, the only pointer route to another month was one click per month: from
|
|
71
75
|
August 2026 to March 2022 is fifty-three of them. Shift+PageUp already jumped a year, but a
|
|
72
|
-
shortcut nobody can see is not an affordance
|
|
76
|
+
shortcut nobody can see is not an affordance, the repo's own test helper clicked "previous
|
|
73
77
|
month" twenty-four times to reach a date two years back. */
|
|
74
78
|
var mode = 'days';
|
|
75
79
|
var focusMonth = null;
|
|
@@ -268,7 +272,7 @@
|
|
|
268
272
|
var YEARS_PER_PAGE = 12;
|
|
269
273
|
function yearPageStart(y) { return Math.floor(y / YEARS_PER_PAGE) * YEARS_PER_PAGE; }
|
|
270
274
|
|
|
271
|
-
/* A year is only unreachable when EVERY month in it falls outside min/max
|
|
275
|
+
/* A year is only unreachable when EVERY month in it falls outside min/max, the same rule
|
|
272
276
|
monthDisabled applies one level down, for the same reason: a bound that sits inside the year
|
|
273
277
|
disables neither end. */
|
|
274
278
|
function yearDisabled(y) {
|
|
@@ -513,7 +517,7 @@
|
|
|
513
517
|
var f = fromApi.getValue();
|
|
514
518
|
var t = toApi.getValue();
|
|
515
519
|
toApi.setMin(f || null); // end can't precede start (one-directional, per Foundation)
|
|
516
|
-
fromApi.setRange(f, t); // start stays free
|
|
520
|
+
fromApi.setRange(f, t); // start stays free, picking a later start clears the end below
|
|
517
521
|
toApi.setRange(f, t);
|
|
518
522
|
}
|
|
519
523
|
fromEl.addEventListener('fdy-datepicker-change', function () {
|
package/dist/freeday-datetime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, datetime picker composer (optional, zero-dependency).
|
|
2
2
|
* Combines a child date picker and time picker into one value. It does not build
|
|
3
|
-
* anything itself
|
|
3
|
+
* anything itself, freeday-datepicker.js and freeday-timepicker.js enhance the
|
|
4
4
|
* children; this only listens for their change events and emits a single combined
|
|
5
5
|
* "fdy-datetime-change" (detail {date, time, value}). value is "YYYY-MM-DDTHH:MM"
|
|
6
6
|
* when both parts are set, else "". Icon variants are controlled per child picker
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* <div data-fdy-datepicker data-value="2026-07-21"></div>
|
|
11
11
|
* <div data-fdy-timepicker data-value="14:30"></div></div>
|
|
12
12
|
* State: add data-fdy-disabled or data-fdy-invalid on the wrapper to reflect it onto both
|
|
13
|
-
* child triggers as one control (read-only is adapter-only
|
|
13
|
+
* child triggers as one control (read-only is adapter-only, a vanilla datetime is interactive).
|
|
14
14
|
*/
|
|
15
15
|
(function () {
|
|
16
16
|
'use strict';
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
if (!dp || !tp) return;
|
|
26
26
|
|
|
27
27
|
// Reflect one wrapper-level state onto BOTH child triggers so a datetime reads as a single
|
|
28
|
-
// disabled/invalid control. Deferred with setTimeout(0)
|
|
28
|
+
// disabled/invalid control. Deferred with setTimeout(0). NOT a microtask: the timepicker
|
|
29
29
|
// enhancer registers its DOMContentLoaded init AFTER this composer, and microtasks drain
|
|
30
30
|
// *between* listeners (so a microtask would run before the timepicker trigger exists). A
|
|
31
31
|
// macrotask waits until the whole init pass is done and both triggers are built. (readonly is
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
// Listen for the children's bubbling change events (order-independent
|
|
59
|
+
// Listen for the children's bubbling change events (order-independent, no need
|
|
60
60
|
// for the child enhancers to have run before this composer).
|
|
61
61
|
wrap.addEventListener('fdy-datepicker-change', function (e) { date = e.detail.value; emit(); });
|
|
62
62
|
wrap.addEventListener('fdy-time-select', function (e) { time = e.detail.value; emit(); });
|
package/dist/freeday-drawer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, drawer enhancer (optional, zero-dependency).
|
|
2
2
|
* A trigger [data-fdy-drawer="drawerId"] opens the <dialog class="fdy-drawer" id="drawerId">
|
|
3
3
|
* as a modal side panel (native showModal gives focus-trap, Esc, and return-focus). Clicking
|
|
4
4
|
* the backdrop or any [data-close] inside closes it.
|
package/dist/freeday-form.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, form validation enhancer (optional, zero-dependency).
|
|
2
2
|
* Wires the native Constraint Validation API to accessible inline errors on any
|
|
3
3
|
* [data-fdy-validate] <form>. Native-first: constraints come from the standard
|
|
4
4
|
* markup attributes (required, type, pattern, min/max, minlength/maxlength, step);
|
|
@@ -38,24 +38,24 @@
|
|
|
38
38
|
badInput: 'type',
|
|
39
39
|
customError: 'mismatch'
|
|
40
40
|
};
|
|
41
|
-
/* User-facing strings. Indonesian by default
|
|
42
|
-
* path
|
|
41
|
+
/* User-facing strings. Indonesian by default, documented and deliberate for the raw enhancer
|
|
42
|
+
* path, and overridable at three levels, narrowest first: `data-fdy-msg-<alias>` on the field,
|
|
43
43
|
* `data-fdy-msg` on the field, then `data-fdy-text-<alias>` on the FORM. The form level is what
|
|
44
44
|
* a host in another language needs: it sets nine messages once instead of on every input.
|
|
45
45
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
46
46
|
var TEXT = {
|
|
47
|
-
required: '
|
|
48
|
-
type: '
|
|
49
|
-
pattern: '
|
|
50
|
-
minlength: '
|
|
51
|
-
maxlength: '
|
|
52
|
-
min: '
|
|
53
|
-
max: '
|
|
54
|
-
step: '
|
|
55
|
-
mismatch: '
|
|
56
|
-
invalid: '
|
|
47
|
+
required: 'Required.',
|
|
48
|
+
type: 'Invalid format.',
|
|
49
|
+
pattern: 'Doesn’t match the required format.',
|
|
50
|
+
minlength: 'Too short.',
|
|
51
|
+
maxlength: 'Too long.',
|
|
52
|
+
min: 'Too small.',
|
|
53
|
+
max: 'Too large.',
|
|
54
|
+
step: 'Not a valid step.',
|
|
55
|
+
mismatch: 'Values don’t match.',
|
|
56
|
+
invalid: 'Invalid.'
|
|
57
57
|
};
|
|
58
|
-
/* Kebab-cased for the lookup
|
|
58
|
+
/* Kebab-cased for the lookup, see the note in the other enhancers: HTML lowercases attribute
|
|
59
59
|
names, so `data-fdy-text-filter-text` and `data-fdy-text-filtertext` are different attributes
|
|
60
60
|
and only one of them is what an author would write. */
|
|
61
61
|
function textOf(root, key) {
|
package/dist/freeday-mask.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, input mask + password reveal enhancer (optional, zero-dependency).
|
|
2
2
|
*
|
|
3
3
|
* [data-fdy-mask]="pattern" formats a text input as you type. Placeholders:
|
|
4
4
|
* # a digit (0-9) A a letter (a-z/A-Z) * a letter or digit
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
/* User-facing strings. Indonesian by default
|
|
55
|
-
* path
|
|
54
|
+
/* User-facing strings. Indonesian by default, documented and deliberate for the raw enhancer
|
|
55
|
+
* path, and every one overridable per element, so a host that speaks another language (the
|
|
56
56
|
* Blazor adapters, an English app on the raw path) supplies its own without forking this file.
|
|
57
57
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
58
58
|
var TEXT = {
|
|
59
|
-
show: '
|
|
60
|
-
hide: '
|
|
59
|
+
show: 'Show password',
|
|
60
|
+
hide: 'Hide password'
|
|
61
61
|
};
|
|
62
62
|
/* HTML lowercases attribute names, so a camelCase key like `filterText` can only ever be written
|
|
63
|
-
as `data-fdy-text-filtertext
|
|
63
|
+
as `data-fdy-text-filtertext`, while the kebab form anybody would reach for,
|
|
64
64
|
`data-fdy-text-filter-text`, becomes a DIFFERENT attribute the enhancer never reads, and the
|
|
65
65
|
override fails silently. So the key is kebab-cased for the lookup; the run-together spelling
|
|
66
66
|
still resolves, for markup written against 1.39.0. */
|
package/dist/freeday-menu.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, menu enhancer (optional, zero-dependency).
|
|
2
2
|
* Menu-button pattern (WAI-ARIA APG): a trigger with aria-haspopup="menu" toggles a
|
|
3
3
|
* role="menu" popup of role="menuitem" buttons. Also powers the split button
|
|
4
4
|
* (main action + attached caret toggle). Auto-inits [data-fdy-menu].
|
package/dist/freeday-number.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, number field enhancer (optional, zero-dependency).
|
|
2
2
|
* Gives a native <input type="number"> its increment/decrement affordance back, on the kit's terms:
|
|
3
3
|
* .fdy-input hides the user agent's own spin buttons (unthemeable OS widgets), so this puts two real
|
|
4
|
-
* buttons in an .fdy-input-group instead. No new block
|
|
4
|
+
* buttons in an .fdy-input-group instead. No new block, the group already owns the shared border,
|
|
5
5
|
* :focus-within ring and error promotion.
|
|
6
6
|
*
|
|
7
7
|
* Markup contract:
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
if (frozen()) return;
|
|
68
68
|
if (Number(btn.getAttribute('data-fdy-number-step')) < 0) input.stepDown();
|
|
69
69
|
else input.stepUp();
|
|
70
|
-
/* The value changed without the user typing, so say so the way the platform does
|
|
70
|
+
/* The value changed without the user typing, so say so the way the platform does, frameworks
|
|
71
71
|
listen to these, not to a kit-specific event. */
|
|
72
72
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
73
73
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
package/dist/freeday-popover.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, popover positioning helper (optional, zero-dependency).
|
|
2
2
|
* Lifts a dropdown panel into the top layer via the native Popover API so it escapes ANY
|
|
3
3
|
* ancestor overflow clip (a .fdy-card with overflow:hidden, an app-shell main with
|
|
4
|
-
* overflow:auto, …), then positions it `fixed` against its trigger
|
|
4
|
+
* overflow:auto, …), then positions it `fixed` against its trigger, flipping above when
|
|
5
5
|
* there is no room below, and matching the trigger width. The panel stays a DOM child of its
|
|
6
6
|
* component, so focus, outside-click (.closest), and ARIA relationships keep working unchanged.
|
|
7
7
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
&& typeof HTMLElement.prototype.showPopover === 'function';
|
|
22
22
|
|
|
23
23
|
// Position `panel` (already shown, so it has a measurable box) against `trigger`'s rect.
|
|
24
|
-
// matchWidth (default true) floors the panel to the trigger width
|
|
24
|
+
// matchWidth (default true) floors the panel to the trigger width, right for input-shaped
|
|
25
25
|
// dropdowns (combo/cascade/date/time), skipped for menus that keep their own min-width.
|
|
26
26
|
function place(panel, trigger, matchWidth) {
|
|
27
27
|
var r = trigger.getBoundingClientRect();
|
package/dist/freeday-rating.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, rating enhancer (optional, zero-dependency).
|
|
2
2
|
* Fills stars up to the checked radio (and previews on hover) for an interactive
|
|
3
3
|
* [data-fdy-rating] radio group; for [data-fdy-readonly] it fills from data-value.
|
|
4
|
-
* The radios are native
|
|
4
|
+
* The radios are native, arrow-key selection and form association come for free.
|
|
5
5
|
*/
|
|
6
6
|
(function () {
|
|
7
7
|
'use strict';
|
package/dist/freeday-select.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, combobox enhancer (optional, zero-dependency).
|
|
2
2
|
* Implements the WAI-ARIA APG "select-only combobox" pattern for every
|
|
3
3
|
* [data-fdy-combo] on the page. Progressive enhancement: the markup is the
|
|
4
4
|
* component, this script wires behavior. In a Vue/React/Blazor app you would
|
|
5
|
-
* bind your own state instead
|
|
5
|
+
* bind your own state instead, this is the framework-agnostic reference.
|
|
6
6
|
*
|
|
7
7
|
* Expected markup:
|
|
8
8
|
* <div class="fdy-combo" data-fdy-combo data-value="x">
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
var seq = 0;
|
|
26
26
|
var openClose = null; // close() of the currently-open combo, or null
|
|
27
27
|
|
|
28
|
-
/* The tick lives in CSS now, so the option's text IS its label
|
|
28
|
+
/* The tick lives in CSS now, so the option's text IS its label, no sibling walk to skip a glyph. */
|
|
29
29
|
function optionLabel(opt) {
|
|
30
30
|
return (opt.textContent || '').trim();
|
|
31
31
|
}
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
if (openClose === close) openClose = null;
|
|
92
92
|
}
|
|
93
93
|
// Mark an option selected + reflect it in the button. `silent` skips the change
|
|
94
|
-
// event, close, and focus
|
|
94
|
+
// event, close, and focus, used by the programmatic setValue() below so a host
|
|
95
95
|
// (e.g. a Blazor/framework wrapper) can push a value in without echoing an event
|
|
96
96
|
// back to itself or stealing focus. User-driven picks go through choose() (loud).
|
|
97
97
|
function select(opt, silent) {
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
isOpen() ? close() : open();
|
|
127
127
|
});
|
|
128
128
|
// Pressing an option must not blur the button: a blur fires the focusout
|
|
129
|
-
// handler below, which closes the listbox before the option's click lands
|
|
129
|
+
// handler below, which closes the listbox before the option's click lands,
|
|
130
130
|
// so the pick is lost (real mouse only; synthetic .click() never blurs).
|
|
131
131
|
// preventDefault on mousedown keeps focus on the button without blocking click.
|
|
132
132
|
listbox.addEventListener('mousedown', function (e) { e.preventDefault(); });
|
package/dist/freeday-slider.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, slider value binding (optional, zero-dependency).
|
|
2
2
|
* Mirrors a [data-fdy-slider] range input's value into <output for="inputId">, with an
|
|
3
3
|
* optional prefix/suffix on the output (data-fdy-prefix / data-fdy-suffix). The range itself
|
|
4
|
-
* is a native input
|
|
4
|
+
* is a native input, keyboard and ARIA are built in; this only updates the visible readout.
|
|
5
5
|
*/
|
|
6
6
|
(function () {
|
|
7
7
|
'use strict';
|
package/dist/freeday-stepper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, stepper/wizard enhancer (optional, zero-dependency).
|
|
2
2
|
* Drives a step header + panels: prev/next navigation, completed/active state, and
|
|
3
|
-
* clicking a reached step to revisit it (linear
|
|
3
|
+
* clicking a reached step to revisit it (linear, can't skip ahead). Auto-inits
|
|
4
4
|
* [data-fdy-stepper].
|
|
5
5
|
*
|
|
6
6
|
* Markup: <div data-fdy-stepper>
|
|
@@ -19,16 +19,16 @@
|
|
|
19
19
|
var CHECK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg>';
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
/* User-facing strings. Indonesian by default
|
|
23
|
-
* path
|
|
22
|
+
/* User-facing strings. Indonesian by default, documented and deliberate for the raw enhancer
|
|
23
|
+
* path, and every one overridable per element, so a host that speaks another language (the
|
|
24
24
|
* Blazor adapters, an English app on the raw path) supplies its own without forking this file.
|
|
25
25
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
26
26
|
var TEXT = {
|
|
27
|
-
done: '
|
|
28
|
-
next: '
|
|
27
|
+
done: 'Done',
|
|
28
|
+
next: 'Next'
|
|
29
29
|
};
|
|
30
30
|
/* HTML lowercases attribute names, so a camelCase key like `filterText` can only ever be written
|
|
31
|
-
as `data-fdy-text-filtertext
|
|
31
|
+
as `data-fdy-text-filtertext`, while the kebab form anybody would reach for,
|
|
32
32
|
`data-fdy-text-filter-text`, becomes a DIFFERENT attribute the enhancer never reads, and the
|
|
33
33
|
override fails silently. So the key is kebab-cased for the lookup; the run-together spelling
|
|
34
34
|
still resolves, for markup written against 1.39.0. */
|
package/dist/freeday-table.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, data-table enhancer (optional, zero-dependency).
|
|
2
2
|
* Adds client-side search, column sort, pagination and row selection to any
|
|
3
3
|
* [data-fdy-table]. Progressive enhancement over a plain semantic <table>;
|
|
4
4
|
* in a framework app, do this server- or store-side instead.
|
|
@@ -34,26 +34,26 @@
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
/* User-facing strings. Indonesian by default
|
|
38
|
-
* path
|
|
37
|
+
/* User-facing strings. Indonesian by default, documented and deliberate for the raw enhancer
|
|
38
|
+
* path, and every one overridable per element, so a host that speaks another language (the
|
|
39
39
|
* Blazor adapters, an English app on the raw path) supplies its own without forking this file.
|
|
40
40
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
41
41
|
var TEXT = {
|
|
42
|
-
prev: '
|
|
43
|
-
next: '
|
|
44
|
-
selected: '{n}
|
|
45
|
-
filter: 'Filter
|
|
46
|
-
filterText: '
|
|
47
|
-
filterTextPlaceholder: '
|
|
48
|
-
filterEnum: '
|
|
49
|
-
filterRange: '
|
|
42
|
+
prev: 'Previous',
|
|
43
|
+
next: 'Next',
|
|
44
|
+
selected: '{n} selected',
|
|
45
|
+
filter: 'Filter column',
|
|
46
|
+
filterText: 'Contains text',
|
|
47
|
+
filterTextPlaceholder: 'Contains…',
|
|
48
|
+
filterEnum: 'Show values',
|
|
49
|
+
filterRange: 'Value range',
|
|
50
50
|
reset: 'Reset',
|
|
51
|
-
close: '
|
|
52
|
-
rows: '{n}
|
|
53
|
-
info: '
|
|
51
|
+
close: 'Close',
|
|
52
|
+
rows: '{n} rows',
|
|
53
|
+
info: 'Showing {from}–{to} of {total}'
|
|
54
54
|
};
|
|
55
55
|
/* HTML lowercases attribute names, so a camelCase key like `filterText` can only ever be written
|
|
56
|
-
as `data-fdy-text-filtertext
|
|
56
|
+
as `data-fdy-text-filtertext`, while the kebab form anybody would reach for,
|
|
57
57
|
`data-fdy-text-filter-text`, becomes a DIFFERENT attribute the enhancer never reads, and the
|
|
58
58
|
override fails silently. So the key is kebab-cased for the lookup; the run-together spelling
|
|
59
59
|
still resolves, for markup written against 1.39.0. */
|
package/dist/freeday-tabs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, tabs enhancer (optional, zero-dependency, WAI-ARIA APG tabs).
|
|
2
2
|
* Auto-inits every [data-fdy-tabs]. Roving tabindex + arrow/Home/End nav.
|
|
3
3
|
*
|
|
4
4
|
* Markup: a [data-fdy-tabs] with a [role="tablist"] of
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, time picker enhancer (optional, zero-dependency).
|
|
2
2
|
* Builds an input-styled trigger + scrollable time-list popover (WAI-ARIA listbox)
|
|
3
3
|
* from an empty [data-fdy-timepicker] wrapper. 24h HH:MM. Options run from
|
|
4
4
|
* data-min (default 00:00) to data-max (default 23:59) every data-step minutes
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
wrap.dataset.fdyTpReady = '1';
|
|
29
29
|
wrap.classList.add('fdy-timepicker');
|
|
30
30
|
|
|
31
|
-
var label = wrap.getAttribute('data-label') || '
|
|
31
|
+
var label = wrap.getAttribute('data-label') || 'Choose a time';
|
|
32
32
|
var placeholder = wrap.getAttribute('data-placeholder') || '--:--';
|
|
33
33
|
var step = Math.max(1, parseInt(wrap.getAttribute('data-step') || '30', 10));
|
|
34
34
|
var minM = valid(wrap.getAttribute('data-min')) ? toMin(wrap.getAttribute('data-min')) : 0;
|
package/dist/freeday-toast.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, toast API (optional, zero-dependency).
|
|
2
2
|
* Freeday.toast({ variant, title, message, timeout, key }) shows a transient
|
|
3
3
|
* notification in a live region (created on first use). Returns the element.
|
|
4
4
|
* variant: 'success' | 'warning' | 'danger' | 'info' (default: neutral)
|
|
5
5
|
* timeout: ms before auto-dismiss (default 4000; 0 = sticky)
|
|
6
|
-
* key: optional stable id
|
|
6
|
+
* key: optional stable id, a new toast with the same key REPLACES the
|
|
7
7
|
* existing one in place instead of stacking a duplicate (e.g. a burst
|
|
8
8
|
* of identical failures shows one toast, refreshed).
|
|
9
9
|
* Freeday.dismiss(nodeOrKey) closes a toast early (pass the returned element or its key).
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
|
|
40
40
|
/* Put the region in the TOP LAYER, above any open <dialog>.
|
|
41
41
|
*
|
|
42
|
-
* A modal dialog lives in the top layer, where z-index does not reach
|
|
42
|
+
* A modal dialog lives in the top layer, where z-index does not reach, so a toast raised by an
|
|
43
43
|
* action taken inside a modal was painted behind that modal's backdrop, which is where an error
|
|
44
44
|
* message is least useful. showPopover() joins the same layer, and membership there is ordered by
|
|
45
45
|
* when you joined: hide-then-show re-joins at the top, so a toast shown while a dialog is open
|
|
46
46
|
* lands above it rather than under the dialog that was opened after the last toast.
|
|
47
47
|
*
|
|
48
48
|
* Guarded twice on purpose. `showPopover` is absent before Chrome 114 / Safari 17 / Firefox 125,
|
|
49
|
-
* and the call throws if the element is disconnected or already open
|
|
49
|
+
* and the call throws if the element is disconnected or already open, in every one of those
|
|
50
50
|
* cases the region stays an ordinary fixed block at z-index 200, which is what it has always
|
|
51
51
|
* been. A notification must never be the thing that throws.
|
|
52
52
|
*/
|
|
@@ -77,15 +77,15 @@
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
/* User-facing strings. Indonesian by default
|
|
81
|
-
* path
|
|
80
|
+
/* User-facing strings. Indonesian by default, documented and deliberate for the raw enhancer
|
|
81
|
+
* path, and every one overridable per element, so a host that speaks another language (the
|
|
82
82
|
* Blazor adapters, an English app on the raw path) supplies its own without forking this file.
|
|
83
83
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
84
84
|
var TEXT = {
|
|
85
|
-
close: '
|
|
85
|
+
close: 'Close'
|
|
86
86
|
};
|
|
87
87
|
/* HTML lowercases attribute names, so a camelCase key like `filterText` can only ever be written
|
|
88
|
-
as `data-fdy-text-filtertext
|
|
88
|
+
as `data-fdy-text-filtertext`, while the kebab form anybody would reach for,
|
|
89
89
|
`data-fdy-text-filter-text`, becomes a DIFFERENT attribute the enhancer never reads, and the
|
|
90
90
|
override fails silently. So the key is kebab-cased for the lookup; the run-together spelling
|
|
91
91
|
still resolves, for markup written against 1.39.0. */
|
package/dist/freeday-tree.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Freeday
|
|
1
|
+
/* Freeday, tree checkbox cascade (optional, zero-dependency).
|
|
2
2
|
* Turns a [data-fdy-tree] checkbox tree into a selectable one: checking a branch checks
|
|
3
3
|
* every descendant; a partially-selected branch shows the native :indeterminate state.
|
|
4
|
-
* Rows are native <input class="fdy-checkbox">, labelled via aria-label
|
|
4
|
+
* Rows are native <input class="fdy-checkbox">, labelled via aria-label. Space toggles.
|
|
5
5
|
* Selection never toggles the <details> (the checkbox stops click propagation).
|
|
6
6
|
*
|
|
7
7
|
* Markup contract:
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
return Array.prototype.filter.call(ul.children, function (n) { return n.tagName === 'LI'; });
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// The checkbox belonging to a row's own <li
|
|
28
|
+
// The checkbox belonging to a row's own <li>, branch summary or leaf, never a child's.
|
|
29
29
|
function ownBox(li) {
|
|
30
30
|
return li.querySelector(':scope > details > summary input[type="checkbox"]')
|
|
31
31
|
|| li.querySelector(':scope > input[type="checkbox"]');
|