@cahyo-dimas/freeday 2.0.0 → 2.2.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 +155 -0
- package/COMPONENTS.md +298 -2
- package/README.id.md +1 -1
- package/README.md +1 -1
- package/adapters/blazor/FdyAutocomplete.razor +4 -1
- package/adapters/blazor/FdyAutocomplete.razor.cs +26 -0
- package/adapters/blazor/FdyCascade.razor +6 -1
- package/adapters/blazor/FdyCascade.razor.cs +24 -0
- package/adapters/blazor/FdyCombo.razor +1 -0
- package/adapters/blazor/FdyCombo.razor.cs +13 -0
- package/adapters/blazor/FdyDatepicker.razor +15 -1
- package/adapters/blazor/FdyDatepicker.razor.cs +46 -0
- package/adapters/core/cfl-value.d.ts +11 -0
- package/adapters/core/cfl-value.js +31 -0
- package/adapters/react/components/FdyDrawer.tsx +3 -1
- package/adapters/react/components/FdyModal.tsx +3 -1
- package/adapters/react/index.d.ts +3 -0
- package/adapters/react/index.js +1 -0
- package/adapters/vue/components/FdyDrawer.vue +4 -1
- package/adapters/vue/components/FdyModal.vue +4 -1
- package/adapters/vue/index.d.ts +3 -0
- package/adapters/vue/index.js +1 -0
- package/dist/freeday-autocomplete.js +17 -1
- package/dist/freeday-carousel.js +5 -4
- package/dist/freeday-cascade.js +58 -7
- package/dist/freeday-cfl.js +5 -4
- package/dist/freeday-chart.js +33 -3
- package/dist/freeday-datepicker.js +109 -17
- package/dist/freeday-form.js +5 -4
- package/dist/freeday-mask.js +5 -4
- package/dist/freeday-select.js +18 -1
- package/dist/freeday-stepper.js +5 -4
- package/dist/freeday-table.js +9 -6
- package/dist/freeday-timepicker.js +19 -1
- package/dist/freeday-toast.js +5 -4
- package/dist/freeday-upload.js +5 -4
- package/dist/freeday.js +298 -64
- package/docs/agent-onboarding.md +9 -6
- package/docs/getting-started.md +15 -6
- package/docs/integrations.md +2 -2
- package/package.json +2 -2
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Locale comes from <html lang> (via Intl), month/weekday/value formatting is not hardcoded.
|
|
4
4
|
*
|
|
5
5
|
* Markup contract:
|
|
6
|
-
* - Single: <div data-fdy-datepicker data-value="2026-07-21" data-label="
|
|
7
|
-
* data-placeholder="
|
|
8
|
-
* - Range: <div data-fdy-daterange role="group" aria-label="
|
|
9
|
-
* <div data-fdy-datepicker data-role="from" data-placeholder="
|
|
6
|
+
* - Single: <div data-fdy-datepicker data-value="2026-07-21" data-label="Upload date"
|
|
7
|
+
* data-placeholder="Choose a date" data-min="2026-01-01" data-max="2026-12-31"></div>
|
|
8
|
+
* - Range: <div data-fdy-daterange role="group" aria-label="Date range">
|
|
9
|
+
* <div data-fdy-datepicker data-role="from" data-placeholder="From"></div>
|
|
10
10
|
* <span class="fdy-daterange__sep">–</span>
|
|
11
|
-
* <div data-fdy-datepicker data-role="to" data-placeholder="
|
|
11
|
+
* <div data-fdy-datepicker data-role="to" data-placeholder="To"></div>
|
|
12
12
|
* </div>
|
|
13
13
|
* The range links the two: the end can never precede the start (out-of-range days disable).
|
|
14
14
|
*
|
|
@@ -24,6 +24,47 @@
|
|
|
24
24
|
weekday names back automatically. The FALLBACK follows the kit's default language, or a
|
|
25
25
|
page without `lang` would read English labels around Indonesian month names. */
|
|
26
26
|
var LOCALE = document.documentElement.getAttribute('lang') || 'en';
|
|
27
|
+
|
|
28
|
+
/* User-facing strings. English by default, and every one overridable per element with
|
|
29
|
+
* `data-fdy-text-<key>`, so a host that speaks another language (an Indonesian app on the raw
|
|
30
|
+
* path, and every Blazor app, whose picker IS this enhancer) supplies its own without forking
|
|
31
|
+
* this file.
|
|
32
|
+
*
|
|
33
|
+
* This table arrived late, in 2.2.0: the ten labels below were written as literals passed to
|
|
34
|
+
* `navButton()` / `titleButton()`, so the guard that proves no enhancer string is hard-coded
|
|
35
|
+
* never saw them — it looks for the line that writes to the DOM, and here that line only ever
|
|
36
|
+
* sees a variable. Month and weekday names are NOT here on purpose: they come from `Intl`
|
|
37
|
+
* through the page's `lang`, which is a better hatch than anything the kit could invent.
|
|
38
|
+
* The `{label}` in the three title strings is the period the button drills into. */
|
|
39
|
+
var TEXT = {
|
|
40
|
+
label: 'Date',
|
|
41
|
+
placeholder: 'Choose a date',
|
|
42
|
+
prevMonth: 'Previous month',
|
|
43
|
+
nextMonth: 'Next month',
|
|
44
|
+
prevYear: 'Previous year',
|
|
45
|
+
nextYear: 'Next year',
|
|
46
|
+
prevYears: 'Previous years',
|
|
47
|
+
nextYears: 'Next years',
|
|
48
|
+
chooseMonth: '{label}, choose month',
|
|
49
|
+
chooseYear: '{label}, choose year',
|
|
50
|
+
backToMonths: '{start} to {end}, back to months'
|
|
51
|
+
};
|
|
52
|
+
/* HTML lowercases attribute names, so a camelCase key like `prevMonth` can only ever be written
|
|
53
|
+
as `data-fdy-text-prevmonth`, while the kebab form anybody would reach for,
|
|
54
|
+
`data-fdy-text-prev-month`, becomes a DIFFERENT attribute the enhancer never reads, and the
|
|
55
|
+
override fails silently. So the key is kebab-cased for the lookup; the run-together spelling
|
|
56
|
+
still resolves. */
|
|
57
|
+
function textAttr(root, key) {
|
|
58
|
+
if (!root || !root.getAttribute) return null;
|
|
59
|
+
var kebab = root.getAttribute('data-fdy-text-' + key.replace(/[A-Z]/g, function (c) { return '-' + c.toLowerCase(); }));
|
|
60
|
+
return kebab != null && kebab !== '' ? kebab : root.getAttribute('data-fdy-text-' + key);
|
|
61
|
+
}
|
|
62
|
+
function textOf(root, key, vars) {
|
|
63
|
+
var custom = textAttr(root, key);
|
|
64
|
+
var s = custom != null && custom !== '' ? custom : TEXT[key];
|
|
65
|
+
if (vars) for (var k in vars) if (Object.prototype.hasOwnProperty.call(vars, k)) s = s.split('{' + k + '}').join(vars[k]);
|
|
66
|
+
return s;
|
|
67
|
+
}
|
|
27
68
|
var uidSeq = 0;
|
|
28
69
|
function uid(p) { uidSeq += 1; return p + '-' + uidSeq; }
|
|
29
70
|
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
|
@@ -61,8 +102,8 @@
|
|
|
61
102
|
wrap.dataset.fdyDpReady = '1';
|
|
62
103
|
wrap.classList.add('fdy-datepicker');
|
|
63
104
|
|
|
64
|
-
var placeholder = wrap.getAttribute('data-placeholder') ||
|
|
65
|
-
var label = wrap.getAttribute('data-label') || '
|
|
105
|
+
var placeholder = wrap.getAttribute('data-placeholder') || textOf(wrap, 'placeholder');
|
|
106
|
+
var label = wrap.getAttribute('data-label') || textOf(wrap, 'label');
|
|
66
107
|
var selected = parseISO(wrap.getAttribute('data-value'));
|
|
67
108
|
var minDate = parseISO(wrap.getAttribute('data-min'));
|
|
68
109
|
var maxDate = parseISO(wrap.getAttribute('data-max'));
|
|
@@ -160,16 +201,16 @@
|
|
|
160
201
|
panel.innerHTML = '';
|
|
161
202
|
var head = document.createElement('div');
|
|
162
203
|
head.className = 'fdy-cal__head';
|
|
163
|
-
var title = titleButton(monthFmt.format(view), monthFmt.format(view)
|
|
204
|
+
var title = titleButton(monthFmt.format(view), textOf(wrap, 'chooseMonth', { label: monthFmt.format(view) }), function () {
|
|
164
205
|
mode = 'months';
|
|
165
206
|
focusMonth = view.getMonth();
|
|
166
207
|
render();
|
|
167
208
|
focusMonthCell();
|
|
168
209
|
});
|
|
169
210
|
panel.setAttribute('aria-labelledby', title.id);
|
|
170
|
-
head.appendChild(navButton('‹',
|
|
211
|
+
head.appendChild(navButton('‹', textOf(wrap, 'prevMonth'), function () { view = addMonths(view, -1); render(); }));
|
|
171
212
|
head.appendChild(title);
|
|
172
|
-
head.appendChild(navButton('›',
|
|
213
|
+
head.appendChild(navButton('›', textOf(wrap, 'nextMonth'), function () { view = addMonths(view, 1); render(); }));
|
|
173
214
|
panel.appendChild(head);
|
|
174
215
|
|
|
175
216
|
var grid = document.createElement('div');
|
|
@@ -226,16 +267,16 @@
|
|
|
226
267
|
var year = view.getFullYear();
|
|
227
268
|
var head = document.createElement('div');
|
|
228
269
|
head.className = 'fdy-cal__head';
|
|
229
|
-
var title = titleButton(String(year),
|
|
270
|
+
var title = titleButton(String(year), textOf(wrap, 'chooseYear', { label: year }), function () {
|
|
230
271
|
mode = 'years';
|
|
231
272
|
focusYear = year;
|
|
232
273
|
render();
|
|
233
274
|
focusYearCell();
|
|
234
275
|
});
|
|
235
276
|
panel.setAttribute('aria-labelledby', title.id);
|
|
236
|
-
head.appendChild(navButton('‹',
|
|
277
|
+
head.appendChild(navButton('‹', textOf(wrap, 'prevYear'), function () { view = addMonths(view, -12); render(); focusMonthCell(); }));
|
|
237
278
|
head.appendChild(title);
|
|
238
|
-
head.appendChild(navButton('›',
|
|
279
|
+
head.appendChild(navButton('›', textOf(wrap, 'nextYear'), function () { view = addMonths(view, 12); render(); focusMonthCell(); }));
|
|
239
280
|
panel.appendChild(head);
|
|
240
281
|
|
|
241
282
|
var grid = document.createElement('div');
|
|
@@ -287,16 +328,16 @@
|
|
|
287
328
|
var end = start + YEARS_PER_PAGE - 1;
|
|
288
329
|
var head = document.createElement('div');
|
|
289
330
|
head.className = 'fdy-cal__head';
|
|
290
|
-
var title = titleButton(start + ' – ' + end,
|
|
331
|
+
var title = titleButton(start + ' – ' + end, textOf(wrap, 'backToMonths', { start: start, end: end }), function () {
|
|
291
332
|
mode = 'months';
|
|
292
333
|
focusMonth = view.getMonth();
|
|
293
334
|
render();
|
|
294
335
|
focusMonthCell();
|
|
295
336
|
});
|
|
296
337
|
panel.setAttribute('aria-labelledby', title.id);
|
|
297
|
-
head.appendChild(navButton('‹',
|
|
338
|
+
head.appendChild(navButton('‹', textOf(wrap, 'prevYears'), function () { moveYearFocus(focusYear - YEARS_PER_PAGE); }));
|
|
298
339
|
head.appendChild(title);
|
|
299
|
-
head.appendChild(navButton('›',
|
|
340
|
+
head.appendChild(navButton('›', textOf(wrap, 'nextYears'), function () { moveYearFocus(focusYear + YEARS_PER_PAGE); }));
|
|
300
341
|
panel.appendChild(head);
|
|
301
342
|
|
|
302
343
|
var grid = document.createElement('div');
|
|
@@ -457,7 +498,46 @@
|
|
|
457
498
|
|
|
458
499
|
var _pop = null;
|
|
459
500
|
function popCtl() { if (_pop === null && window.FreedayPopover) _pop = window.FreedayPopover.attach(panel, trigger); return _pop; }
|
|
501
|
+
|
|
502
|
+
/* The three field states the CSS has always styled (`:disabled`, `[aria-readonly="true"]`,
|
|
503
|
+
`[aria-invalid="true"]`) and this enhancer never set, so only the stacks that re-implement
|
|
504
|
+
the control natively had them. Read from the seed at init and settable afterwards, because
|
|
505
|
+
a host that renders once — every Blazor wrapper does, `ShouldRender => false` — cannot
|
|
506
|
+
express a later change any other way. */
|
|
507
|
+
function flagOf(name) {
|
|
508
|
+
var v = wrap.getAttribute('data-' + name);
|
|
509
|
+
return v != null && v !== 'false';
|
|
510
|
+
}
|
|
511
|
+
/* Named `state*`, not `is*`: this file already has an `isDisabled(date)` deciding whether a
|
|
512
|
+
DAY falls outside min/max, and shadowing it with a boolean made the day grid throw on every
|
|
513
|
+
render — silently, since the panel still opened and only its cells went missing. */
|
|
514
|
+
var stateDisabled = flagOf('disabled');
|
|
515
|
+
var stateReadonly = flagOf('readonly');
|
|
516
|
+
var stateInvalid = flagOf('invalid');
|
|
517
|
+
/* `data-id` and `data-describedby`: the trigger this enhancer BUILDS is the element a form
|
|
518
|
+
has to point its label and its error text at, and the raw path had no way to say so. */
|
|
519
|
+
if (wrap.getAttribute('data-id')) trigger.id = wrap.getAttribute('data-id');
|
|
520
|
+
if (wrap.getAttribute('data-describedby')) trigger.setAttribute('aria-describedby', wrap.getAttribute('data-describedby'));
|
|
521
|
+
|
|
522
|
+
function applyState() {
|
|
523
|
+
trigger.disabled = stateDisabled;
|
|
524
|
+
if (stateReadonly) trigger.setAttribute('aria-readonly', 'true');
|
|
525
|
+
else trigger.removeAttribute('aria-readonly');
|
|
526
|
+
if (stateInvalid) trigger.setAttribute('aria-invalid', 'true');
|
|
527
|
+
else trigger.removeAttribute('aria-invalid');
|
|
528
|
+
wrap.classList.toggle('fdy-datepicker--error', stateInvalid);
|
|
529
|
+
if ((stateDisabled || stateReadonly) && !panel.hidden) close(false);
|
|
530
|
+
}
|
|
531
|
+
function setState(next) {
|
|
532
|
+
if (!next) return;
|
|
533
|
+
if (next.disabled != null) stateDisabled = !!next.disabled;
|
|
534
|
+
if (next.readonly != null) stateReadonly = !!next.readonly;
|
|
535
|
+
if (next.invalid != null) stateInvalid = !!next.invalid;
|
|
536
|
+
applyState();
|
|
537
|
+
}
|
|
538
|
+
|
|
460
539
|
function open() {
|
|
540
|
+
if (stateDisabled || stateReadonly) return;
|
|
461
541
|
if (!panel.hidden) return;
|
|
462
542
|
mode = 'days';
|
|
463
543
|
focusDate = selected || focusDate || new Date();
|
|
@@ -487,8 +567,11 @@
|
|
|
487
567
|
|
|
488
568
|
updateDisplay();
|
|
489
569
|
|
|
570
|
+
applyState();
|
|
571
|
+
|
|
490
572
|
var api = {
|
|
491
573
|
wrap: wrap,
|
|
574
|
+
setState: setState,
|
|
492
575
|
getValue: function () { return selected ? toISO(selected) : ''; },
|
|
493
576
|
clear: function () { selected = null; updateDisplay(); if (!panel.hidden) render(); },
|
|
494
577
|
setMin: function (iso) { minDate = parseISO(iso); if (!panel.hidden) render(); },
|
|
@@ -548,5 +631,14 @@
|
|
|
548
631
|
initAll();
|
|
549
632
|
}
|
|
550
633
|
|
|
551
|
-
window.FreedayDatepicker = {
|
|
634
|
+
window.FreedayDatepicker = {
|
|
635
|
+
init: initPicker,
|
|
636
|
+
initAll: initAll,
|
|
637
|
+
/* A host that rendered its seed once and cannot re-render it (Blazor) still has to be able to
|
|
638
|
+
disable, lock or invalidate the field later. */
|
|
639
|
+
setState: function (root, state) {
|
|
640
|
+
var api = root && root._fdyDp ? root._fdyDp : null;
|
|
641
|
+
if (api && api.setState) api.setState(state);
|
|
642
|
+
}
|
|
643
|
+
};
|
|
552
644
|
})();
|
package/dist/freeday-form.js
CHANGED
|
@@ -38,10 +38,11 @@
|
|
|
38
38
|
badInput: 'type',
|
|
39
39
|
customError: 'mismatch'
|
|
40
40
|
};
|
|
41
|
-
/* User-facing strings.
|
|
42
|
-
* path, and overridable at three levels, narrowest first: `data-fdy-msg-<alias>` on
|
|
43
|
-
* `data-fdy-msg` on the field, then `data-fdy-text-<alias>` on the FORM. The form
|
|
44
|
-
* a host in another language needs: it sets nine messages once instead of on
|
|
41
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
42
|
+
* enhancer path, and overridable at three levels, narrowest first: `data-fdy-msg-<alias>` on
|
|
43
|
+
* the field, `data-fdy-msg` on the field, then `data-fdy-text-<alias>` on the FORM. The form
|
|
44
|
+
* level is what a host in another language needs: it sets nine messages once instead of on
|
|
45
|
+
* every input.
|
|
45
46
|
* Keeping them in ONE table is also what lets a guard prove none is hard-coded further down. */
|
|
46
47
|
var TEXT = {
|
|
47
48
|
required: 'Required.',
|
package/dist/freeday-mask.js
CHANGED
|
@@ -51,10 +51,11 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
/* User-facing strings.
|
|
55
|
-
* path, and every one overridable per element
|
|
56
|
-
*
|
|
57
|
-
* Keeping them in ONE table is also what lets a guard prove none is
|
|
54
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
55
|
+
* enhancer path, and every one overridable per element with `data-fdy-text-<key>`, so a host
|
|
56
|
+
* that speaks another language (an Indonesian app on the raw path) supplies its own without
|
|
57
|
+
* forking this file. Keeping them in ONE table is also what lets a guard prove none is
|
|
58
|
+
* hard-coded further down. */
|
|
58
59
|
var TEXT = {
|
|
59
60
|
show: 'Show password',
|
|
60
61
|
hide: 'Hide password'
|
package/dist/freeday-select.js
CHANGED
|
@@ -210,5 +210,22 @@
|
|
|
210
210
|
if (root && root._fdyCombo) root._fdyCombo.setValue(value);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
/* Beside setValue for the same reason it exists: a host that renders its markup once (every
|
|
214
|
+
Blazor wrapper, `ShouldRender => false`) cannot express a later state change any other way,
|
|
215
|
+
and a parameter that silently stops working after the first render is worse than none. */
|
|
216
|
+
function setState(root, state) {
|
|
217
|
+
var button = root ? root.querySelector('.fdy-combo__button') : null;
|
|
218
|
+
if (!button || !state) return;
|
|
219
|
+
if (state.disabled != null) button.disabled = !!state.disabled;
|
|
220
|
+
if (state.readonly != null) {
|
|
221
|
+
if (state.readonly) button.setAttribute('aria-readonly', 'true');
|
|
222
|
+
else button.removeAttribute('aria-readonly');
|
|
223
|
+
}
|
|
224
|
+
if (state.invalid != null) {
|
|
225
|
+
if (state.invalid) button.setAttribute('aria-invalid', 'true');
|
|
226
|
+
else button.removeAttribute('aria-invalid');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
window.FreedayCombo = { init: initCombo, initAll: initAll, setValue: setValue, setState: setState };
|
|
214
231
|
})();
|
package/dist/freeday-stepper.js
CHANGED
|
@@ -19,10 +19,11 @@
|
|
|
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.
|
|
23
|
-
* path, and every one overridable per element
|
|
24
|
-
*
|
|
25
|
-
* Keeping them in ONE table is also what lets a guard prove none is
|
|
22
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
23
|
+
* enhancer path, and every one overridable per element with `data-fdy-text-<key>`, so a host
|
|
24
|
+
* that speaks another language (an Indonesian app on the raw path) supplies its own without
|
|
25
|
+
* forking this file. Keeping them in ONE table is also what lets a guard prove none is
|
|
26
|
+
* hard-coded further down. */
|
|
26
27
|
var TEXT = {
|
|
27
28
|
done: 'Done',
|
|
28
29
|
next: 'Next'
|
package/dist/freeday-table.js
CHANGED
|
@@ -34,10 +34,11 @@
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
/* User-facing strings.
|
|
38
|
-
* path, and every one overridable per element
|
|
39
|
-
*
|
|
40
|
-
* Keeping them in ONE table is also what lets a guard prove none is
|
|
37
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
38
|
+
* enhancer path, and every one overridable per element with `data-fdy-text-<key>`, so a host
|
|
39
|
+
* that speaks another language (an Indonesian app on the raw path) supplies its own without
|
|
40
|
+
* forking this file. Keeping them in ONE table is also what lets a guard prove none is
|
|
41
|
+
* hard-coded further down. */
|
|
41
42
|
var TEXT = {
|
|
42
43
|
prev: 'Previous',
|
|
43
44
|
next: 'Next',
|
|
@@ -46,6 +47,8 @@
|
|
|
46
47
|
filterText: 'Contains text',
|
|
47
48
|
filterTextPlaceholder: 'Contains…',
|
|
48
49
|
filterEnum: 'Show values',
|
|
50
|
+
filterMin: 'Min',
|
|
51
|
+
filterMax: 'Max',
|
|
49
52
|
filterRange: 'Value range',
|
|
50
53
|
reset: 'Reset',
|
|
51
54
|
close: 'Close',
|
|
@@ -318,8 +321,8 @@
|
|
|
318
321
|
pop.appendChild(filterTitle(textOf(root, 'filterRange')));
|
|
319
322
|
var range = document.createElement('div');
|
|
320
323
|
range.className = 'fdy-filter__range';
|
|
321
|
-
var minI = numberInput('
|
|
322
|
-
var maxI = numberInput('
|
|
324
|
+
var minI = numberInput(textOf(root, 'filterMin'), f.min);
|
|
325
|
+
var maxI = numberInput(textOf(root, 'filterMax'), f.max);
|
|
323
326
|
var applyRange = function () {
|
|
324
327
|
f.min = minI.value !== '' ? parseNum(minI.value) : null;
|
|
325
328
|
f.max = maxI.value !== '' ? parseNum(maxI.value) : null;
|
|
@@ -14,6 +14,24 @@
|
|
|
14
14
|
(function () {
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
/* User-facing strings, overridable per element with `data-fdy-text-<key>`. One entry, and it
|
|
18
|
+
* still needed the table: it reached the DOM as an argument to a helper, which is how it sat
|
|
19
|
+
* outside every string guard until 2.2.0. */
|
|
20
|
+
var TEXT = {
|
|
21
|
+
label: 'Choose a time'
|
|
22
|
+
};
|
|
23
|
+
function textAttr(root, key) {
|
|
24
|
+
if (!root || !root.getAttribute) return null;
|
|
25
|
+
var kebab = root.getAttribute('data-fdy-text-' + key.replace(/[A-Z]/g, function (c) { return '-' + c.toLowerCase(); }));
|
|
26
|
+
return kebab != null && kebab !== '' ? kebab : root.getAttribute('data-fdy-text-' + key);
|
|
27
|
+
}
|
|
28
|
+
function textOf(root, key, vars) {
|
|
29
|
+
var custom = textAttr(root, key);
|
|
30
|
+
var s = custom != null && custom !== '' ? custom : TEXT[key];
|
|
31
|
+
if (vars) for (var k in vars) if (Object.prototype.hasOwnProperty.call(vars, k)) s = s.split('{' + k + '}').join(vars[k]);
|
|
32
|
+
return s;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
var seq = 0;
|
|
18
36
|
var CLOCK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 2"></path></svg>';
|
|
19
37
|
|
|
@@ -28,7 +46,7 @@
|
|
|
28
46
|
wrap.dataset.fdyTpReady = '1';
|
|
29
47
|
wrap.classList.add('fdy-timepicker');
|
|
30
48
|
|
|
31
|
-
var label = wrap.getAttribute('data-label') ||
|
|
49
|
+
var label = wrap.getAttribute('data-label') || textOf(wrap, 'label');
|
|
32
50
|
var placeholder = wrap.getAttribute('data-placeholder') || '--:--';
|
|
33
51
|
var step = Math.max(1, parseInt(wrap.getAttribute('data-step') || '30', 10));
|
|
34
52
|
var minM = valid(wrap.getAttribute('data-min')) ? toMin(wrap.getAttribute('data-min')) : 0;
|
package/dist/freeday-toast.js
CHANGED
|
@@ -77,10 +77,11 @@
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
/* User-facing strings.
|
|
81
|
-
* path, and every one overridable per element
|
|
82
|
-
*
|
|
83
|
-
* Keeping them in ONE table is also what lets a guard prove none is
|
|
80
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
81
|
+
* enhancer path, and every one overridable per element with `data-fdy-text-<key>`, so a host
|
|
82
|
+
* that speaks another language (an Indonesian app on the raw path) supplies its own without
|
|
83
|
+
* forking this file. Keeping them in ONE table is also what lets a guard prove none is
|
|
84
|
+
* hard-coded further down. */
|
|
84
85
|
var TEXT = {
|
|
85
86
|
close: 'Close'
|
|
86
87
|
};
|
package/dist/freeday-upload.js
CHANGED
|
@@ -51,10 +51,11 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
/* User-facing strings.
|
|
55
|
-
* path, and every one overridable per element
|
|
56
|
-
*
|
|
57
|
-
* Keeping them in ONE table is also what lets a guard prove none is
|
|
54
|
+
/* User-facing strings. English by default since 2.0.0, documented and deliberate for the raw
|
|
55
|
+
* enhancer path, and every one overridable per element with `data-fdy-text-<key>`, so a host
|
|
56
|
+
* that speaks another language (an Indonesian app on the raw path) supplies its own without
|
|
57
|
+
* forking this file. Keeping them in ONE table is also what lets a guard prove none is
|
|
58
|
+
* hard-coded further down. */
|
|
58
59
|
var TEXT = {
|
|
59
60
|
remove: 'Remove {name}',
|
|
60
61
|
progress: 'Upload progress for {name}',
|