@cahyo-dimas/freeday 1.33.0 → 1.35.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/COMPONENTS.md +46 -2
  3. package/README.id.md +1 -1
  4. package/README.md +1 -1
  5. package/adapters/blazor/FdyTable.razor +2 -35
  6. package/adapters/blazor/FdyTable.razor.cs +56 -9
  7. package/adapters/blazor/FdyTableFooter.razor +60 -0
  8. package/adapters/blazor/FdyTableFooter.razor.cs +59 -0
  9. package/adapters/blazor/TableModel.cs +12 -0
  10. package/adapters/core/table-model.d.ts +2 -0
  11. package/adapters/core/table-model.js +21 -0
  12. package/adapters/react/components/FdyAutocomplete.tsx +1 -1
  13. package/adapters/react/components/FdyCascade.tsx +2 -2
  14. package/adapters/react/components/FdyCfl.tsx +25 -11
  15. package/adapters/react/components/FdyTable.tsx +49 -33
  16. package/adapters/react/components/FdyTableFooter.tsx +102 -0
  17. package/adapters/react/index.d.ts +3 -0
  18. package/adapters/react/index.js +1 -0
  19. package/adapters/vue/components/FdyAutocomplete.vue +1 -1
  20. package/adapters/vue/components/FdyCascade.vue +2 -2
  21. package/adapters/vue/components/FdyCfl.vue +25 -11
  22. package/adapters/vue/components/FdyTable.vue +51 -46
  23. package/adapters/vue/components/FdyTableFooter.vue +121 -0
  24. package/adapters/vue/index.d.ts +3 -0
  25. package/adapters/vue/index.js +1 -0
  26. package/dist/freeday-table.js +24 -1
  27. package/dist/freeday.bundle.css +53 -13
  28. package/dist/freeday.css +53 -13
  29. package/dist/freeday.js +24 -1
  30. package/docs/agent-onboarding.md +2 -0
  31. package/docs/getting-started.md +1 -1
  32. package/package.json +29 -8
  33. package/src/components/alert.css +1 -1
  34. package/src/components/app-shell.css +2 -2
  35. package/src/components/cfl.css +1 -1
  36. package/src/components/composition.css +1 -1
  37. package/src/components/datepicker.css +8 -4
  38. package/src/components/file-upload.css +1 -1
  39. package/src/components/list.css +1 -1
  40. package/src/components/states.css +1 -1
  41. package/src/components/table.css +36 -0
  42. package/src/components/toast.css +1 -1
@@ -21,8 +21,8 @@
21
21
  .fdy-app__brand-mark{flex:none;width:1.5rem;height:1.5rem;}
22
22
  .fdy-app__brand-mark svg{display:block;width:100%;height:100%;}
23
23
  .fdy-app__brand-text{display:flex;flex-direction:column;min-width:0;}
24
- .fdy-app__brand-title{display:block;font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
25
- .fdy-app__brand-subtitle{display:block;font-size:var(--text-xs);font-weight:var(--weight-regular);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
24
+ .fdy-app__brand-title{display:block;font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
25
+ .fdy-app__brand-subtitle{display:block;font-size:var(--text-xs);font-weight:var(--weight-regular);color:var(--color-text-muted);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
26
26
  .fdy-nav{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:2px;padding:var(--space-3) var(--space-3) var(--space-6);}
27
27
  /* Horizontal variant — the SAME nav links laid out as a row, for a top-nav application (one that
28
28
  * puts its primary navigation in `.fdy-appbar` / `.fdy-app__topbar` and has no sidebar). Deliberately
@@ -19,7 +19,7 @@
19
19
  .fdy-cfl__check input{pointer-events:none;}
20
20
 
21
21
  /* Empty result state. */
22
- .fdy-cfl__empty{padding:var(--space-8) var(--space-5);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm);}
22
+ .fdy-cfl__empty{padding:var(--space-8) var(--space-5);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm);margin:0;}
23
23
  .fdy-cfl__empty[hidden]{display:none;}
24
24
 
25
25
  /* Footer — selection count (multi) sits left, actions right. */
@@ -13,7 +13,7 @@
13
13
  prose. -subtle is gated at 3.0 on purpose (placeholders, separators, decorative glyphs) and
14
14
  measures 4.41 on the page ground — axe reports it as a serious color-contrast failure. Same
15
15
  argument, same ink, same 4.41 as .fdy-stat__label in 1.30.0. */
16
- .fdy-eyebrow{font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--color-text-muted);}
16
+ .fdy-eyebrow{font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--color-text-muted);margin:0;}
17
17
  .fdy-title-page{font-family:var(--font-display);font-size:var(--text-3xl);font-weight:var(--weight-bold);letter-spacing:var(--tracking-tighter);line-height:var(--leading-tight);color:var(--color-text);margin:0;text-wrap:balance;}
18
18
  .fdy-title-section{font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);line-height:var(--leading-snug);color:var(--color-text);margin:0;text-wrap:balance;}
19
19
  .fdy-title-card{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);color:var(--color-text);margin:0;}
@@ -31,12 +31,9 @@
31
31
  .fdy-cal__head{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-2);}
32
32
  /* The title is a CONTROL now (#004 §1): it drills to the month grid, so it needs the UA button box
33
33
  reset and the same hover/focus treatment as the arrows beside it. */
34
- .fdy-cal__title{flex:1;appearance:none;border:0;background:transparent;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);text-align:center;font-family:inherit;font-weight:var(--weight-semibold);font-size:var(--text-sm);color:var(--color-text);text-transform:capitalize;cursor:pointer;}
34
+ .fdy-cal__title{flex:1;appearance:none;border:0;background:transparent;margin:0;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);text-align:center;font-family:inherit;font-weight:var(--weight-semibold);font-size:var(--text-sm);color:var(--color-text);text-transform:capitalize;cursor:pointer;}
35
35
  .fdy-cal__title:hover{background:var(--color-surface-2);}
36
36
  .fdy-cal__title:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
37
- /* Month grid — 3×4 over the same track width as the 7-column day grid, so the panel does not resize
38
- when you drill and the pointer does not have to travel. */
39
- .fdy-cal__grid--months{grid-template-columns:repeat(3,1fr);gap:var(--space-1);}
40
37
  .fdy-cal__month{display:inline-flex;align-items:center;justify-content:center;height:2.25rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:inherit;font-size:var(--text-sm);text-transform:capitalize;cursor:pointer;}
41
38
  .fdy-cal__month:hover{background:var(--color-surface-2);}
42
39
  .fdy-cal__month:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
@@ -47,6 +44,13 @@
47
44
  .fdy-cal__nav:hover{background:var(--color-surface-2);color:var(--color-text);}
48
45
  .fdy-cal__nav:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
49
46
  .fdy-cal__grid{display:grid;grid-template-columns:repeat(7,2rem);gap:2px;}
47
+ /* Month grid — 3×4 over the same track width as the 7-column day grid, so the panel does not resize
48
+ when you drill and the pointer does not have to travel.
49
+
50
+ AFTER `.fdy-cal__grid`, and that is the whole rule: the element carries both classes, they weigh
51
+ the same, so source order decides. Declared earlier, the modifier lost to the base it modifies and
52
+ twelve months rendered seven across — the layout the comment above described, never once applied. */
53
+ .fdy-cal__grid--months{grid-template-columns:repeat(3,1fr);gap:var(--space-1);}
50
54
  .fdy-cal__dow{display:flex;align-items:center;justify-content:center;height:1.75rem;font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);text-transform:capitalize;}
51
55
  .fdy-cal__day{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-size:var(--text-sm);font-variant-numeric:tabular-nums;cursor:pointer;}
52
56
  .fdy-cal__day:hover{background:var(--color-surface-2);}
@@ -8,7 +8,7 @@
8
8
  .fdy-dropzone__icon{color:var(--color-text-subtle);}
9
9
  .fdy-dropzone.is-dragover .fdy-dropzone__icon{color:var(--color-primary);}
10
10
  .fdy-dropzone__icon svg{display:block;width:2rem;height:2rem;}
11
- .fdy-dropzone__title{font-weight:var(--weight-medium);color:var(--color-text);}
11
+ .fdy-dropzone__title{font-size:inherit;font-weight:var(--weight-medium);color:var(--color-text);margin:0;}
12
12
  .fdy-dropzone__hint{font-size:var(--text-xs);}
13
13
  /* Wide (horizontal) layout — icon beside the copy instead of stacked, for full-width
14
14
  * sections. Wrap the title + hint in .fdy-dropzone__text. */
@@ -37,7 +37,7 @@
37
37
  .fdy-list__row--button:disabled:hover,.fdy-list__row--button[aria-disabled="true"]:hover,.fdy-list__row--interactive[aria-disabled="true"]:hover{background:none;}
38
38
  /* Row internals: a title/meta stack that truncates, and a trailing slot pinned right. */
39
39
  .fdy-list__main{display:flex;flex-direction:column;gap:var(--space-1);min-width:0;flex:1;}
40
- .fdy-list__title{font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
40
+ .fdy-list__title{font-family:var(--font-body);font-size:var(--text-base);font-weight:var(--weight-medium);letter-spacing:normal;color:var(--color-text);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
41
41
  .fdy-list__meta{font-size:var(--text-sm);color:var(--color-text-muted);display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;}
42
42
  .fdy-list__aside{flex:none;display:flex;align-items:center;gap:var(--space-2);}
43
43
  /* Density: rows tighten with the rest of the kit (--space-* mid-range steps under compact). */
@@ -2,7 +2,7 @@
2
2
  .fdy-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-2);padding:var(--space-10) var(--space-6);}
3
3
  .fdy-state__icon{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;color:var(--color-text-subtle);}
4
4
  .fdy-state__icon svg{width:100%;height:100%;}
5
- .fdy-state__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);}
5
+ .fdy-state__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0;}
6
6
  .fdy-state__text{font-size:var(--text-sm);color:var(--color-text-muted);max-width:24rem;line-height:var(--leading-normal);}
7
7
  .fdy-state__actions{margin-top:var(--space-2);display:flex;gap:var(--space-2);flex-wrap:wrap;justify-content:center;}
8
8
  .fdy-state--danger .fdy-state__icon{color:var(--color-danger-strong);}
@@ -37,6 +37,30 @@
37
37
  .fdy-table__selcol{width:1px;white-space:nowrap;}
38
38
  .fdy-table tbody tr[aria-selected="true"],.fdy-table tbody tr[aria-selected="true"]:hover{background:var(--color-primary-soft);}
39
39
 
40
+ /* Frozen header row and/or first column — a rate matrix, a timetable, any grid read
41
+ against two axes at once.
42
+
43
+ This modifier exists because `position:sticky` alone is NOT enough. With
44
+ `border-collapse:collapse` the shared border belongs to the TABLE, not to either
45
+ cell, so a frozen cell scrolls out from under its own rule and the frozen column
46
+ loses the line that separates it from the data. Separate borders put each border
47
+ back on the cell that sticks. */
48
+ .fdy-table--sticky{border-collapse:separate;border-spacing:0;}
49
+ .fdy-table--sticky th,.fdy-table--sticky td{border-bottom:var(--bw) solid var(--color-border-muted);}
50
+ .fdy-table--sticky thead th{position:sticky;top:0;z-index:2;border-bottom:var(--bw) solid var(--color-border);}
51
+ /* The row header freezes sideways over the data cells, so it needs an opaque
52
+ background of its own — and it takes the BODY surface, not the header one, so a
53
+ hovered row stays one continuous band across the freeze line. Losing that is
54
+ losing the only way to track a row across a wide grid. */
55
+ .fdy-table--sticky tbody th{position:sticky;left:0;z-index:1;background:var(--color-surface);border-right:var(--bw) solid var(--color-border);}
56
+ .fdy-table--sticky tbody tr:hover th{background:var(--color-surface-2);}
57
+ /* The corner cell is frozen on both axes, so it has to outrank both. */
58
+ .fdy-table--sticky thead th:first-child{left:0;z-index:3;border-right:var(--bw) solid var(--color-border);}
59
+
60
+ /* The scrollport a sticky cell sticks to. Both axes scroll here, and the height is a
61
+ custom property so a page can size it without out-specifying this rule. */
62
+ .fdy-table-scroll--frozen{position:relative;overflow:auto;max-height:var(--fdy-table-frozen-h,30rem);}
63
+
40
64
  /* Data-table shell (toolbar + scroll + footer stay put while the table scrolls) */
41
65
  .fdy-datatable{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);background:var(--color-surface);overflow:hidden;}
42
66
  .fdy-table-scroll{position:relative;overflow-x:auto;}
@@ -46,6 +70,18 @@
46
70
  .fdy-table-toolbar__count{font-size:var(--text-sm);color:var(--color-text-muted);white-space:nowrap;}
47
71
  .fdy-table-footer{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-4);border-top:var(--bw) solid var(--color-border);}
48
72
  .fdy-table-footer__info{font-size:var(--text-sm);color:var(--color-text-muted);}
73
+ /* Rows per page. `margin-left:auto` eats the free space, so the size control and the pager travel
74
+ together on the right while the range stays left — no wrapper element, which is what keeps the
75
+ footer's DOM byte-identical for the tables that don't offer one (#008). The control is the kit's
76
+ own `.fdy-combo`, never a native <select>: an OS menu is unthemeable, and on macOS it drops a
77
+ dark panel into a light page — which is the reason FdyCombo exists at all. Sized to its content:
78
+ `.fdy-combo` is display:block at max-width 22rem, which in a footer is a bar-wide box for two
79
+ digits. Its HEIGHT is left alone on purpose — `--control-h`, the same as every other control on
80
+ the page. It briefly carried 2.25rem to match the pager links beside it, which made the one
81
+ combobox in a compact app 4px taller than all the others; a pager link is a nav button, and the
82
+ thing this must agree with is the form controls. */
83
+ .fdy-table-footer__size{display:inline-flex;align-items:center;gap:var(--space-2);margin-left:auto;font-size:var(--text-sm);color:var(--color-text-muted);}
84
+ .fdy-table-footer__size .fdy-combo{width:5.5rem;}
49
85
 
50
86
  /* Column filter — funnel button injected (enhancer) or rendered (FdyTable) into a filterable <th> */
51
87
  .fdy-table__filterwrap{display:inline-flex;align-items:center;vertical-align:middle;}
@@ -7,7 +7,7 @@
7
7
  .fdy-toast--danger .fdy-toast__accent{background:var(--color-danger);}
8
8
  .fdy-toast--info .fdy-toast__accent{background:var(--color-info);}
9
9
  .fdy-toast__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);font-size:var(--text-sm);}
10
- .fdy-toast__title{font-weight:var(--weight-semibold);}
10
+ .fdy-toast__title{font-size:inherit;font-weight:var(--weight-semibold);margin:0;}
11
11
  .fdy-toast__text{opacity:.88;line-height:var(--leading-normal);}
12
12
  .fdy-toast__close{flex:none;border:0;background:transparent;color:var(--color-inverse-text);opacity:.7;cursor:pointer;font-size:var(--text-lg);line-height:1;padding:0 var(--space-1);border-radius:var(--radius-sm);}
13
13
  .fdy-toast__close:hover{opacity:1;}