@cahyo-dimas/freeday 1.10.0 → 1.11.1
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 +35 -0
- package/README.id.md +1 -1
- package/README.md +1 -1
- package/dist/freeday-chart.js +4 -1
- package/dist/freeday.bundle.css +14 -7
- package/dist/freeday.css +14 -7
- package/dist/freeday.js +4 -1
- package/package.json +1 -1
- package/src/components/badge.css +1 -1
- package/src/components/filterbar.css +8 -1
- package/src/components/modal.css +5 -5
- package/src/freeday-chart.js +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
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.11.1] — 2026-07-28
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Tall modals now scroll their body instead of clipping the footer (#34).** `.fdy-modal` had a
|
|
9
|
+
`max-height` + `overflow:hidden` but never established a flex context, so its three children laid out
|
|
10
|
+
as blocks: the body's height was its own content height (nothing for `overflow:auto` to scroll), and
|
|
11
|
+
the dialog's cap clipped whatever stuck out — including `.fdy-modal__footer` and its submit button, on
|
|
12
|
+
a short viewport (a form you could fill but not save). Gave the modal the column-flex treatment the
|
|
13
|
+
sibling `.fdy-drawer` already uses: `display:flex` on `.fdy-modal[open]`, `flex-direction:column` on
|
|
14
|
+
the base, `flex:none` on header/footer, and `flex:1;min-height:0` on the body. Modals that already fit
|
|
15
|
+
are unchanged. Verified in-browser (body scrolls, footer stays inside) including the `.fdy-modal--cfl`
|
|
16
|
+
picker — no regression.
|
|
17
|
+
|
|
18
|
+
## [1.11.0] — 2026-07-28
|
|
19
|
+
Follow-ups from the doc-ai-automation migration (improvement notes #31–#33). Additive / corrective.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **Badges no longer wrap and break the pill (#31).** `.fdy-badge` had `line-height:1` but no
|
|
23
|
+
`white-space`, so a two-word label (e.g. "Needs review") wrapped and collided with the pill padding,
|
|
24
|
+
turning the capsule into a cramped lozenge. Added `white-space:nowrap` — matching the sibling
|
|
25
|
+
`.fdy-badge-ov`, which already had it. A too-narrow badge now overflows its column (which
|
|
26
|
+
`.fdy-table-scroll` already handles) instead of wrapping.
|
|
27
|
+
- **Donut chart honours `legend="none"` (#33).** `freeday-chart.js` read `data-fdy-legend` only in the
|
|
28
|
+
cartesian renderer; the donut appended its legend unconditionally, so `<FdyChart type="donut"
|
|
29
|
+
legend="none">` still printed the built-in legend even when the caller supplied its own. Gated the
|
|
30
|
+
donut legend on the same attribute (`auto` still shows it — a donut is unreadable without labels).
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- **`.fdy-filterbar--actions-inline` modifier (#32).** Opt-in: sits the trailing actions inline after
|
|
34
|
+
the last field instead of at the far edge, so a wrapped bar reads as attached to its filters. Also
|
|
35
|
+
**documented** the filterbar's wrap behaviour: a wrapped bar breaks flex lines on each item's
|
|
36
|
+
*flex-basis* (the grow field's `flex:1 1 16rem` reserves 16rem), not its rendered width — so the
|
|
37
|
+
grow basis decides the wrap point; to avoid stranded actions, tune the `--w-grow` basis or drop a
|
|
38
|
+
field. (The note's margin-swap proposal to un-strand the actions was **tested in-browser and does not
|
|
39
|
+
work** — margins don't change flex line-breaking — so only the modifier + docs were taken.)
|
|
40
|
+
|
|
6
41
|
## [1.10.0] — 2026-07-28
|
|
7
42
|
Follow-ups from the doc-ai-automation migration (improvement notes #27–#30). Additive / corrective;
|
|
8
43
|
no breaking changes.
|
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.11.1)
|
|
9
9
|
|
|
10
10
|
UI KIT yang token-driven & framework-agnostic — satu sumber kebenaran untuk warna, tipografi,
|
|
11
11
|
spasi, dan komponen. Blueprint: `docs/superpowers/specs/2026-07-21-freeday-ui-kit-design.md`.
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> **More free days for devs — the UI kit is ready to use.**
|
|
6
6
|
|
|
7
7
|
[](https://cahyo-dimas.github.io/freeday-ui-kit/)
|
|
8
|
-
[](https://github.com/cahyo-dimas/freeday-ui-kit/tree/v1.11.1)
|
|
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`.
|
package/dist/freeday-chart.js
CHANGED
|
@@ -380,7 +380,10 @@
|
|
|
380
380
|
li.appendChild(document.createTextNode((labels[i] || ('#' + (i + 1))) + ' — ' + Math.round((v / total) * 100) + '%'));
|
|
381
381
|
legend.appendChild(li);
|
|
382
382
|
});
|
|
383
|
-
el.appendChild(ring);
|
|
383
|
+
el.appendChild(ring);
|
|
384
|
+
// Honour data-fdy-legend for the donut too — a caller may supply its own richer legend. 'auto'
|
|
385
|
+
// keeps today's behaviour (a donut is unreadable without labels, so it shows); 'none' suppresses it.
|
|
386
|
+
if ((el.getAttribute('data-fdy-legend') || 'auto') !== 'none') el.appendChild(legend);
|
|
384
387
|
ensureImg(el);
|
|
385
388
|
}
|
|
386
389
|
|
package/dist/freeday.bundle.css
CHANGED
|
@@ -526,7 +526,7 @@ a { color: var(--color-primary); }
|
|
|
526
526
|
.fdy-avatar-group .fdy-avatar:first-child{margin-left:0;}
|
|
527
527
|
|
|
528
528
|
/* Freeday — Badge */
|
|
529
|
-
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
529
|
+
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
530
530
|
.fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
|
|
531
531
|
.fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
|
|
532
532
|
.fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
|
|
@@ -984,8 +984,15 @@ a { color: var(--color-primary); }
|
|
|
984
984
|
.fdy-filterbar>.fdy-field--w-2xl{width:25rem;}
|
|
985
985
|
/* One growing field (usually the search) absorbs the remaining width. */
|
|
986
986
|
.fdy-filterbar>.fdy-field--w-grow{flex:1 1 16rem;width:auto;min-width:12rem;}
|
|
987
|
-
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
987
|
+
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
988
|
+
* Wrap note: a wrapped bar breaks flex lines on each item's *flex-basis* (the grow field's
|
|
989
|
+
* `flex:1 1 16rem` reserves 16rem for line-breaking), NOT its rendered width — so the grow basis,
|
|
990
|
+
* not the visible width, decides the wrap point. Margins can't keep the actions off a lonely wrapped
|
|
991
|
+
* row; to avoid stranded actions, tune the --w-grow basis or drop a field so the bar fits one row. */
|
|
988
992
|
.fdy-filterbar__actions{display:flex;align-items:center;gap:var(--space-2);margin-left:auto;}
|
|
993
|
+
/* Opt-in: sit the actions inline right after the last field instead of at the far edge — so when the
|
|
994
|
+
* bar wraps they read as attached to the filters rather than shoved to the right of a lonely row. */
|
|
995
|
+
.fdy-filterbar--actions-inline .fdy-filterbar__actions{margin-left:0;}
|
|
989
996
|
/* Stack on narrow screens so nothing overflows the row. */
|
|
990
997
|
@media (max-width:640px){
|
|
991
998
|
.fdy-filterbar>.fdy-field,.fdy-filterbar>.fdy-field--w-sm,.fdy-filterbar>.fdy-field--w-lg,.fdy-filterbar>.fdy-field--w-xl,.fdy-filterbar>.fdy-field--w-2xl,.fdy-filterbar>.fdy-field--w-grow{width:100%;flex:1 1 100%;}
|
|
@@ -1076,22 +1083,22 @@ fieldset.fdy-field>legend{padding:0;float:none;}
|
|
|
1076
1083
|
.fdy-btn-split__toggle svg{display:block;width:1rem;height:1rem;}
|
|
1077
1084
|
|
|
1078
1085
|
/* Freeday — Modal (native <dialog>) */
|
|
1079
|
-
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
1086
|
+
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;flex-direction:column;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
1080
1087
|
.fdy-modal--sm{width:min(24rem,calc(100vw - var(--space-8)));}
|
|
1081
1088
|
.fdy-modal--md{width:min(32rem,calc(100vw - var(--space-8)));}
|
|
1082
1089
|
.fdy-modal--lg{width:min(48rem,calc(100vw - var(--space-8)));}
|
|
1083
1090
|
.fdy-modal--wide{width:min(60rem,calc(100vw - var(--space-8)));}
|
|
1084
1091
|
.fdy-modal::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-base) var(--ease-standard),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
1085
|
-
.fdy-modal__header{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
1092
|
+
.fdy-modal__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
1086
1093
|
.fdy-modal__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;}
|
|
1087
1094
|
.fdy-modal__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
|
|
1088
1095
|
.fdy-modal__close:hover{background:var(--color-surface-2);color:var(--color-text);}
|
|
1089
|
-
.fdy-modal__body{padding:var(--space-5);overflow:auto;}
|
|
1090
|
-
.fdy-modal__footer{display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
1096
|
+
.fdy-modal__body{flex:1;min-height:0;padding:var(--space-5);overflow:auto;}
|
|
1097
|
+
.fdy-modal__footer{flex:none;display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
1091
1098
|
/* Symmetric enter AND exit (fade + rise + subtle scale) on the native <dialog>. @starting-style
|
|
1092
1099
|
* animates the entry; overlay/display allow-discrete keep it painted through the exit so it
|
|
1093
1100
|
* animates out on close too. Reduced motion honored by the global duration reset in base.css. */
|
|
1094
|
-
.fdy-modal[open]{opacity:1;transform:none;}
|
|
1101
|
+
.fdy-modal[open]{display:flex;opacity:1;transform:none;}
|
|
1095
1102
|
.fdy-modal[open]::backdrop{opacity:1;}
|
|
1096
1103
|
@starting-style{
|
|
1097
1104
|
.fdy-modal[open]{opacity:0;transform:translateY(8px) scale(.98);}
|
package/dist/freeday.css
CHANGED
|
@@ -181,7 +181,7 @@ a { color: var(--color-primary); }
|
|
|
181
181
|
.fdy-avatar-group .fdy-avatar:first-child{margin-left:0;}
|
|
182
182
|
|
|
183
183
|
/* Freeday — Badge */
|
|
184
|
-
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
184
|
+
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
185
185
|
.fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
|
|
186
186
|
.fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
|
|
187
187
|
.fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
|
|
@@ -639,8 +639,15 @@ a { color: var(--color-primary); }
|
|
|
639
639
|
.fdy-filterbar>.fdy-field--w-2xl{width:25rem;}
|
|
640
640
|
/* One growing field (usually the search) absorbs the remaining width. */
|
|
641
641
|
.fdy-filterbar>.fdy-field--w-grow{flex:1 1 16rem;width:auto;min-width:12rem;}
|
|
642
|
-
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
642
|
+
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
643
|
+
* Wrap note: a wrapped bar breaks flex lines on each item's *flex-basis* (the grow field's
|
|
644
|
+
* `flex:1 1 16rem` reserves 16rem for line-breaking), NOT its rendered width — so the grow basis,
|
|
645
|
+
* not the visible width, decides the wrap point. Margins can't keep the actions off a lonely wrapped
|
|
646
|
+
* row; to avoid stranded actions, tune the --w-grow basis or drop a field so the bar fits one row. */
|
|
643
647
|
.fdy-filterbar__actions{display:flex;align-items:center;gap:var(--space-2);margin-left:auto;}
|
|
648
|
+
/* Opt-in: sit the actions inline right after the last field instead of at the far edge — so when the
|
|
649
|
+
* bar wraps they read as attached to the filters rather than shoved to the right of a lonely row. */
|
|
650
|
+
.fdy-filterbar--actions-inline .fdy-filterbar__actions{margin-left:0;}
|
|
644
651
|
/* Stack on narrow screens so nothing overflows the row. */
|
|
645
652
|
@media (max-width:640px){
|
|
646
653
|
.fdy-filterbar>.fdy-field,.fdy-filterbar>.fdy-field--w-sm,.fdy-filterbar>.fdy-field--w-lg,.fdy-filterbar>.fdy-field--w-xl,.fdy-filterbar>.fdy-field--w-2xl,.fdy-filterbar>.fdy-field--w-grow{width:100%;flex:1 1 100%;}
|
|
@@ -731,22 +738,22 @@ fieldset.fdy-field>legend{padding:0;float:none;}
|
|
|
731
738
|
.fdy-btn-split__toggle svg{display:block;width:1rem;height:1rem;}
|
|
732
739
|
|
|
733
740
|
/* Freeday — Modal (native <dialog>) */
|
|
734
|
-
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
741
|
+
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;flex-direction:column;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
735
742
|
.fdy-modal--sm{width:min(24rem,calc(100vw - var(--space-8)));}
|
|
736
743
|
.fdy-modal--md{width:min(32rem,calc(100vw - var(--space-8)));}
|
|
737
744
|
.fdy-modal--lg{width:min(48rem,calc(100vw - var(--space-8)));}
|
|
738
745
|
.fdy-modal--wide{width:min(60rem,calc(100vw - var(--space-8)));}
|
|
739
746
|
.fdy-modal::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-base) var(--ease-standard),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
740
|
-
.fdy-modal__header{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
747
|
+
.fdy-modal__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
741
748
|
.fdy-modal__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;}
|
|
742
749
|
.fdy-modal__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
|
|
743
750
|
.fdy-modal__close:hover{background:var(--color-surface-2);color:var(--color-text);}
|
|
744
|
-
.fdy-modal__body{padding:var(--space-5);overflow:auto;}
|
|
745
|
-
.fdy-modal__footer{display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
751
|
+
.fdy-modal__body{flex:1;min-height:0;padding:var(--space-5);overflow:auto;}
|
|
752
|
+
.fdy-modal__footer{flex:none;display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
746
753
|
/* Symmetric enter AND exit (fade + rise + subtle scale) on the native <dialog>. @starting-style
|
|
747
754
|
* animates the entry; overlay/display allow-discrete keep it painted through the exit so it
|
|
748
755
|
* animates out on close too. Reduced motion honored by the global duration reset in base.css. */
|
|
749
|
-
.fdy-modal[open]{opacity:1;transform:none;}
|
|
756
|
+
.fdy-modal[open]{display:flex;opacity:1;transform:none;}
|
|
750
757
|
.fdy-modal[open]::backdrop{opacity:1;}
|
|
751
758
|
@starting-style{
|
|
752
759
|
.fdy-modal[open]{opacity:0;transform:translateY(8px) scale(.98);}
|
package/dist/freeday.js
CHANGED
|
@@ -1153,7 +1153,10 @@
|
|
|
1153
1153
|
li.appendChild(document.createTextNode((labels[i] || ('#' + (i + 1))) + ' — ' + Math.round((v / total) * 100) + '%'));
|
|
1154
1154
|
legend.appendChild(li);
|
|
1155
1155
|
});
|
|
1156
|
-
el.appendChild(ring);
|
|
1156
|
+
el.appendChild(ring);
|
|
1157
|
+
// Honour data-fdy-legend for the donut too — a caller may supply its own richer legend. 'auto'
|
|
1158
|
+
// keeps today's behaviour (a donut is unreadable without labels, so it shows); 'none' suppresses it.
|
|
1159
|
+
if ((el.getAttribute('data-fdy-legend') || 'auto') !== 'none') el.appendChild(legend);
|
|
1157
1160
|
ensureImg(el);
|
|
1158
1161
|
}
|
|
1159
1162
|
|
package/package.json
CHANGED
package/src/components/badge.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Freeday — Badge */
|
|
2
|
-
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
2
|
+
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
|
|
3
3
|
.fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
|
|
4
4
|
.fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
|
|
5
5
|
.fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
|
|
@@ -18,8 +18,15 @@
|
|
|
18
18
|
.fdy-filterbar>.fdy-field--w-2xl{width:25rem;}
|
|
19
19
|
/* One growing field (usually the search) absorbs the remaining width. */
|
|
20
20
|
.fdy-filterbar>.fdy-field--w-grow{flex:1 1 16rem;width:auto;min-width:12rem;}
|
|
21
|
-
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
21
|
+
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
|
|
22
|
+
* Wrap note: a wrapped bar breaks flex lines on each item's *flex-basis* (the grow field's
|
|
23
|
+
* `flex:1 1 16rem` reserves 16rem for line-breaking), NOT its rendered width — so the grow basis,
|
|
24
|
+
* not the visible width, decides the wrap point. Margins can't keep the actions off a lonely wrapped
|
|
25
|
+
* row; to avoid stranded actions, tune the --w-grow basis or drop a field so the bar fits one row. */
|
|
22
26
|
.fdy-filterbar__actions{display:flex;align-items:center;gap:var(--space-2);margin-left:auto;}
|
|
27
|
+
/* Opt-in: sit the actions inline right after the last field instead of at the far edge — so when the
|
|
28
|
+
* bar wraps they read as attached to the filters rather than shoved to the right of a lonely row. */
|
|
29
|
+
.fdy-filterbar--actions-inline .fdy-filterbar__actions{margin-left:0;}
|
|
23
30
|
/* Stack on narrow screens so nothing overflows the row. */
|
|
24
31
|
@media (max-width:640px){
|
|
25
32
|
.fdy-filterbar>.fdy-field,.fdy-filterbar>.fdy-field--w-sm,.fdy-filterbar>.fdy-field--w-lg,.fdy-filterbar>.fdy-field--w-xl,.fdy-filterbar>.fdy-field--w-2xl,.fdy-filterbar>.fdy-field--w-grow{width:100%;flex:1 1 100%;}
|
package/src/components/modal.css
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/* Freeday — Modal (native <dialog>) */
|
|
2
|
-
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
2
|
+
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;flex-direction:column;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
3
3
|
.fdy-modal--sm{width:min(24rem,calc(100vw - var(--space-8)));}
|
|
4
4
|
.fdy-modal--md{width:min(32rem,calc(100vw - var(--space-8)));}
|
|
5
5
|
.fdy-modal--lg{width:min(48rem,calc(100vw - var(--space-8)));}
|
|
6
6
|
.fdy-modal--wide{width:min(60rem,calc(100vw - var(--space-8)));}
|
|
7
7
|
.fdy-modal::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-base) var(--ease-standard),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
|
|
8
|
-
.fdy-modal__header{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
8
|
+
.fdy-modal__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
|
|
9
9
|
.fdy-modal__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;}
|
|
10
10
|
.fdy-modal__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
|
|
11
11
|
.fdy-modal__close:hover{background:var(--color-surface-2);color:var(--color-text);}
|
|
12
|
-
.fdy-modal__body{padding:var(--space-5);overflow:auto;}
|
|
13
|
-
.fdy-modal__footer{display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
12
|
+
.fdy-modal__body{flex:1;min-height:0;padding:var(--space-5);overflow:auto;}
|
|
13
|
+
.fdy-modal__footer{flex:none;display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
|
|
14
14
|
/* Symmetric enter AND exit (fade + rise + subtle scale) on the native <dialog>. @starting-style
|
|
15
15
|
* animates the entry; overlay/display allow-discrete keep it painted through the exit so it
|
|
16
16
|
* animates out on close too. Reduced motion honored by the global duration reset in base.css. */
|
|
17
|
-
.fdy-modal[open]{opacity:1;transform:none;}
|
|
17
|
+
.fdy-modal[open]{display:flex;opacity:1;transform:none;}
|
|
18
18
|
.fdy-modal[open]::backdrop{opacity:1;}
|
|
19
19
|
@starting-style{
|
|
20
20
|
.fdy-modal[open]{opacity:0;transform:translateY(8px) scale(.98);}
|
package/src/freeday-chart.js
CHANGED
|
@@ -380,7 +380,10 @@
|
|
|
380
380
|
li.appendChild(document.createTextNode((labels[i] || ('#' + (i + 1))) + ' — ' + Math.round((v / total) * 100) + '%'));
|
|
381
381
|
legend.appendChild(li);
|
|
382
382
|
});
|
|
383
|
-
el.appendChild(ring);
|
|
383
|
+
el.appendChild(ring);
|
|
384
|
+
// Honour data-fdy-legend for the donut too — a caller may supply its own richer legend. 'auto'
|
|
385
|
+
// keeps today's behaviour (a donut is unreadable without labels, so it shows); 'none' suppresses it.
|
|
386
|
+
if ((el.getAttribute('data-fdy-legend') || 'auto') !== 'none') el.appendChild(legend);
|
|
384
387
|
ensureImg(el);
|
|
385
388
|
}
|
|
386
389
|
|