@cahyo-dimas/freeday 3.6.0 → 3.8.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 +139 -0
- package/COMPONENTS.md +119 -6
- package/README.id.md +19 -6
- package/README.md +17 -5
- package/USAGE.md +42 -0
- package/adapters/blazor/FdyDatepicker.razor +3 -1
- package/adapters/blazor/FdyDatepicker.razor.cs +22 -1
- package/adapters/blazor/FdyTableFooter.razor +6 -6
- package/adapters/blazor/FdyTableFooter.razor.cs +36 -0
- package/adapters/react/components/FdyDatepicker.tsx +122 -42
- package/adapters/react/components/FdyTableFooter.tsx +37 -6
- package/adapters/react/index.d.ts +1 -1
- package/adapters/vue/components/FdyDatepicker.vue +119 -34
- package/adapters/vue/components/FdyTableFooter.vue +39 -6
- package/dist/freeday-datepicker.js +68 -14
- package/dist/freeday-menu.js +15 -1
- package/dist/freeday-popover.js +33 -11
- package/dist/freeday-tabs.js +21 -2
- package/dist/freeday.bundle.css +493 -117
- package/dist/freeday.css +190 -113
- package/dist/freeday.js +137 -28
- package/dist/freeday.tokens.css +303 -4
- package/docs/getting-started.md +1 -1
- package/package.json +2 -2
- package/src/base.css +1 -1
- package/src/components/accordion.css +1 -1
- package/src/components/alert.css +5 -5
- package/src/components/app-shell.css +2 -2
- package/src/components/appbar.css +3 -3
- package/src/components/avatar.css +15 -9
- package/src/components/badge.css +18 -14
- package/src/components/breadcrumb.css +1 -1
- package/src/components/button.css +21 -13
- package/src/components/carousel.css +3 -3
- package/src/components/cascade.css +4 -4
- package/src/components/chip.css +33 -15
- package/src/components/combo.css +5 -5
- package/src/components/datepicker.css +8 -8
- package/src/components/file-upload.css +9 -4
- package/src/components/input-group.css +2 -2
- package/src/components/input.css +2 -2
- package/src/components/menu.css +3 -3
- package/src/components/pagination.css +1 -1
- package/src/components/selection.css +2 -2
- package/src/components/skeleton.css +1 -1
- package/src/components/stepper.css +1 -1
- package/src/components/table.css +12 -7
- package/src/components/tabs.css +32 -1
- package/src/components/timepicker.css +3 -3
- package/src/components/toast.css +1 -1
- package/src/components/tree.css +1 -1
- package/tokens/tokens.json +57 -4
package/dist/freeday-popover.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* Used by the select/combo, datepicker, timepicker, cascade, autocomplete and menu enhancers;
|
|
9
9
|
* the freeday/vue adapter ships an equivalent `usePopover` composable.
|
|
10
10
|
*
|
|
11
|
-
* attach(panel, trigger) -> { show(), hide() }
|
|
11
|
+
* attach(panel, trigger, opts) -> { show(), hide() }, where opts is { matchWidth, align } and
|
|
12
|
+
* both are described on place() below. show()/hide() also toggle the panel's [hidden]
|
|
12
13
|
* attribute so callers keep using `!panel.hidden` for open-state and the `:not([hidden])`
|
|
13
14
|
* entrance animation still fires. On browsers without the Popover API it degrades to that
|
|
14
15
|
* [hidden] toggle over the panel's existing absolute-positioned CSS (clipped, but functional).
|
|
@@ -21,35 +22,56 @@
|
|
|
21
22
|
&& typeof HTMLElement.prototype.showPopover === 'function';
|
|
22
23
|
|
|
23
24
|
// Position `panel` (already shown, so it has a measurable box) against `trigger`'s rect.
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
// opts is the object attach() takes, and both keys are optional:
|
|
26
|
+
// matchWidth (default true) floors the panel to the trigger width, right for input-shaped
|
|
27
|
+
// dropdowns (combo/cascade/date/time), skipped for menus that keep their own min-width.
|
|
28
|
+
// align 'start' (default) lines the panel's LEFT edge up with the trigger's left edge;
|
|
29
|
+
// 'end' lines its RIGHT edge up with the trigger's right edge, which is what a
|
|
30
|
+
// control parked in a right-hand gutter needs. The panel is kept inside the
|
|
31
|
+
// viewport either way, so 'end' near the left edge slides right instead of
|
|
32
|
+
// hanging off it. freeday-menu.js reads it off `.fdy-menu--end`.
|
|
33
|
+
function place(panel, trigger, opts) {
|
|
34
|
+
var o = opts || {};
|
|
35
|
+
/* Take the panel out of the flow BEFORE measuring anything, because until this runs the panel
|
|
36
|
+
* is still `position:absolute` with `top:calc(100% + …)` from its component's stylesheet. An
|
|
37
|
+
* author rule outranks the popover UA style, and in the top layer that `100%` resolves against
|
|
38
|
+
* the viewport, so a panel that has just been shown sits one viewport height down the page and
|
|
39
|
+
* drags the document's scrollable overflow with it. Where scrollbars take layout space (every
|
|
40
|
+
* Windows and Linux browser; macOS overlay scrollbars hide it completely) the document gains a
|
|
41
|
+
* classic scrollbar for the duration, documentElement.clientWidth drops by its width, and the
|
|
42
|
+
* page relays out 15px narrower. A trigger rect read in that instant is a rect from a layout
|
|
43
|
+
* that is about to be undone by the next three lines: measured 961 instead of 976 for an avatar
|
|
44
|
+
* in a 24px gutter, so the menu landed a scrollbar's width to the left of it. */
|
|
28
45
|
panel.style.position = 'fixed';
|
|
29
46
|
panel.style.margin = '0';
|
|
30
47
|
panel.style.inset = 'auto'; // clear the UA popover centering
|
|
31
|
-
|
|
48
|
+
var r = trigger.getBoundingClientRect();
|
|
49
|
+
if (o.matchWidth !== false) panel.style.minWidth = r.width + 'px'; // at least as wide as the trigger
|
|
32
50
|
var ph = panel.offsetHeight, pw = panel.offsetWidth;
|
|
33
51
|
var vw = document.documentElement.clientWidth, vh = document.documentElement.clientHeight;
|
|
34
52
|
var below = vh - r.bottom - GAP, above = r.top - GAP;
|
|
35
53
|
// Prefer below; flip above only when it doesn't fit below and above has more room.
|
|
36
54
|
var top = (ph <= below || below >= above) ? (r.bottom + GAP) : Math.max(GAP, r.top - GAP - ph);
|
|
37
|
-
var left = r.left;
|
|
38
|
-
|
|
55
|
+
var left = (o.align === 'end') ? (r.right - pw) : r.left;
|
|
56
|
+
/* Clamped on BOTH sides, and that is not belt-and-braces: the first line is what keeps a
|
|
57
|
+
start-aligned panel on screen, the second is what keeps an end-aligned one on screen when
|
|
58
|
+
the panel is wider than the room to the left of its trigger. Keeping only one of them
|
|
59
|
+
trades an overflow on one edge for an overflow on the other. */
|
|
60
|
+
if (left + pw > vw - GAP) left = vw - GAP - pw;
|
|
61
|
+
if (left < GAP) left = GAP;
|
|
39
62
|
panel.style.top = Math.round(top) + 'px';
|
|
40
63
|
panel.style.left = Math.round(left) + 'px';
|
|
41
64
|
}
|
|
42
65
|
|
|
43
66
|
function attach(panel, trigger, opts) {
|
|
44
|
-
var matchWidth = !(opts && opts.matchWidth === false);
|
|
45
67
|
if (supported) panel.setAttribute('popover', 'manual');
|
|
46
|
-
function reposition() { if (supported && panel.matches(':popover-open')) place(panel, trigger,
|
|
68
|
+
function reposition() { if (supported && panel.matches(':popover-open')) place(panel, trigger, opts); }
|
|
47
69
|
return {
|
|
48
70
|
show: function () {
|
|
49
71
|
panel.hidden = false;
|
|
50
72
|
if (supported) {
|
|
51
73
|
if (!panel.matches(':popover-open')) panel.showPopover();
|
|
52
|
-
place(panel, trigger,
|
|
74
|
+
place(panel, trigger, opts);
|
|
53
75
|
window.addEventListener('scroll', reposition, true); // capture: any scrolling ancestor
|
|
54
76
|
window.addEventListener('resize', reposition);
|
|
55
77
|
}
|
package/dist/freeday-tabs.js
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* Markup: a [data-fdy-tabs] with a [role="tablist"] of
|
|
5
5
|
* <button role="tab" aria-controls="PANEL" aria-selected> and matching
|
|
6
6
|
* <div role="tabpanel" id="PANEL" aria-labelledby="TAB" [hidden]>.
|
|
7
|
+
*
|
|
8
|
+
* The arrow AXIS comes from the tablist's `aria-orientation`: `vertical` answers to Up and
|
|
9
|
+
* Down, anything else to Left and Right. One axis per tablist, which is what APG maps, and the
|
|
10
|
+
* other pair is left entirely alone rather than bound as a second axis: Left and Right over a
|
|
11
|
+
* column of tabs belong to whatever else is on the page, and a widget that preventDefaults a key
|
|
12
|
+
* it has no meaning for has taken it from the page silently. Home/End answer on both.
|
|
7
13
|
*/
|
|
8
14
|
(function () {
|
|
9
15
|
'use strict';
|
|
@@ -14,6 +20,19 @@
|
|
|
14
20
|
if (tabs.length === 0) return;
|
|
15
21
|
root.dataset.fdyTabsReady = '1';
|
|
16
22
|
|
|
23
|
+
/* The look follows `.fdy-tabs--vertical`, the behaviour follows `aria-orientation`, and this
|
|
24
|
+
makes the second agree with the first so an app states the axis once. The attribute always
|
|
25
|
+
wins when it is there: it is what an assistive technology announces, so nothing here may
|
|
26
|
+
overwrite one an author wrote. */
|
|
27
|
+
var list = root.querySelector('[role="tablist"]');
|
|
28
|
+
if (list !== null && list.getAttribute('aria-orientation') === null
|
|
29
|
+
&& root.classList.contains('fdy-tabs--vertical')) {
|
|
30
|
+
list.setAttribute('aria-orientation', 'vertical');
|
|
31
|
+
}
|
|
32
|
+
var vertical = list !== null && list.getAttribute('aria-orientation') === 'vertical';
|
|
33
|
+
var NEXT_KEY = vertical ? 'ArrowDown' : 'ArrowRight';
|
|
34
|
+
var PREV_KEY = vertical ? 'ArrowUp' : 'ArrowLeft';
|
|
35
|
+
|
|
17
36
|
function panelFor(tab) {
|
|
18
37
|
var id = tab.getAttribute('aria-controls');
|
|
19
38
|
return id ? document.getElementById(id) : null;
|
|
@@ -33,9 +52,9 @@
|
|
|
33
52
|
tab.addEventListener('click', function () { select(tab, false); });
|
|
34
53
|
tab.addEventListener('keydown', function (e) {
|
|
35
54
|
switch (e.key) {
|
|
36
|
-
case
|
|
55
|
+
case NEXT_KEY:
|
|
37
56
|
e.preventDefault(); select(tabs[(i + 1) % tabs.length], true); break;
|
|
38
|
-
case
|
|
57
|
+
case PREV_KEY:
|
|
39
58
|
e.preventDefault(); select(tabs[(i - 1 + tabs.length) % tabs.length], true); break;
|
|
40
59
|
case 'Home':
|
|
41
60
|
e.preventDefault(); select(tabs[0], true); break;
|