@cahyo-dimas/freeday 1.39.0 → 1.41.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 CHANGED
@@ -3,6 +3,53 @@
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.41.0] — 2026-08-19
7
+ One note from the account app (IDU_EMATE_ACCT_WEB, #018) — the first raised from that repo.
8
+ ### Fixed
9
+ - **`.fdy-input-group` rendered 1px shorter than every control beside it** (#018). The group
10
+ declares a `1.5px` border and its inner input subtracted `3px` to compensate, so the border box
11
+ should land on `--control-h`. **At `devicePixelRatio: 1` the engine resolves each 1.5px border to
12
+ 1px**, the compensation over-subtracts, and a search field beside a button measured 39px against
13
+ 40px. At dpr 2 the halves survive and the arithmetic is right — which is why it shipped: it is
14
+ invisible on a retina display and visible on every 1× monitor.
15
+ The group now states `height: var(--control-h)` (it is already `border-box`) and the input
16
+ `height: auto; align-self: stretch`. The group is `align-items: stretch` already, so the input and
17
+ the addons fill whatever the border leaves — at any border width, any rounding, and under
18
+ `data-density="compact"` without a second `calc` to keep in step. The defect was not the number;
19
+ it was compensating in one rule for a value declared in another.
20
+ ### Added — guards
21
+ - **Control heights are measured in a real browser** (#018). No stylesheet assertion could have
22
+ caught this: the CSS reads as correct arithmetic, and the value it is correct about is one the
23
+ engine rounds. `browser/control-heights.mjs` measures `.fdy-input-group` against `.fdy-btn`,
24
+ `.fdy-input` and `.fdy-combo` with `getBoundingClientRect`, at both densities. Written **failing
25
+ first** against 1.40.0 — it reproduced 39 vs 40 before the fix landed.
26
+ - The note's own sweep is recorded: `calc(var(--control-h)` has five uses in `src/`, and the four in
27
+ `button.css` step a control deliberately by a spacing token. This was the last compensation of its
28
+ kind.
29
+
30
+ ## [1.40.0] — 2026-08-19
31
+ One note from the back-office app (IDU_EMATE_APPL_WEB, #017).
32
+ ### Fixed
33
+ - **A picker inside a `.fdy-field` now fills it.** `.fdy-field`, `.fdy-combo` and
34
+ `.fdy-input-group` all cap at 22rem; `.fdy-datepicker` capped at 14rem and `.fdy-timepicker`
35
+ at 11rem. In a two-column form grid that left a **224px** date box beside a **319px** combo —
36
+ measured, not eyeballed — and the row read as ragged with no fix available to the consuming
37
+ app, because the cap sits on the component. `.fdy-field > .fdy-datepicker` / `> .fdy-timepicker`
38
+ / `> .fdy-daterange` drop the cap; a picker standing on its own keeps its narrower width, which
39
+ is right for a short value.
40
+
41
+ ### Added — guards
42
+ - **The enhancer string contract is asserted in a real browser** (#016). 1.39.0 moved every
43
+ user-facing string in **nine** enhancers into a `TEXT` table read through `textOf()`, and only
44
+ **one of the nine** — upload — had any browser coverage at all. The node guard proves the
45
+ literals *sit* in the table; it reads the source as text and cannot prove the wiring *runs*, so a
46
+ `zone` out of scope or a `getAttribute` on a non-element would have thrown at init with all 51
47
+ node tests still green. `browser/text-override.mjs` initialises table, stepper, mask, carousel,
48
+ cascade, form and toast on real markup and asserts **both halves**: the documented Indonesian
49
+ default still renders, and `data-fdy-text-*` wins. The default is a contract too — an enhancer
50
+ that quietly turned English would be a breaking change wearing a bugfix's clothes.
51
+ Mutation-tested: making `textOf()` ignore the attribute fails it by name and value.
52
+
6
53
  ## [1.39.0] — 2026-08-19
7
54
  The sweep #013 §2 filed and #015 restated: the vanilla enhancers' strings are reachable now.
8
55
  ### Added
@@ -1112,6 +1112,12 @@ a { color: var(--color-primary); }
1112
1112
  /* Freeday — Date picker (input-styled trigger + calendar popover).
1113
1113
  * Built by freeday-datepicker.js from an empty [data-fdy-datepicker] wrapper. */
1114
1114
  .fdy-datepicker{position:relative;display:inline-block;width:100%;max-width:14rem;}
1115
+ /* Inside a labelled field, a picker fills the field like every other control.
1116
+ The 14rem/11rem caps above suit a picker standing on its own; in a form grid
1117
+ they leave the date box visibly short of the combo beside it — 224px against
1118
+ 319px in a two-column layout — and the row reads as ragged. The field's own
1119
+ max-width is what should govern there. */
1120
+ .fdy-field>.fdy-datepicker,.fdy-field>.fdy-timepicker,.fdy-field>.fdy-daterange{max-width:none;}
1115
1121
  .fdy-datepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1116
1122
  .fdy-datepicker__trigger:hover{border-color:var(--color-text-muted);}
1117
1123
  .fdy-datepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
@@ -1326,10 +1332,15 @@ a { color: var(--color-primary); }
1326
1332
  .fdy-form-grid>.fdy-field--full{grid-column:1/-1;}
1327
1333
 
1328
1334
  /* Freeday — Input group (prefix/suffix addons, e.g. Rp / % / icon) */
1329
- .fdy-input-group{display:flex;align-items:stretch;max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1335
+ .fdy-input-group{display:flex;align-items:stretch;height:var(--control-h);max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
1330
1336
  .fdy-input-group:hover{border-color:var(--color-text-muted);}
1331
1337
  .fdy-input-group:focus-within{border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
1332
- .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:calc(var(--control-h) - 3px);}
1338
+ /* The group owns the height; the input fills whatever the border leaves. It used to subtract 3px
1339
+ for two 1.5px borders, which is arithmetic the engine is free to round: at dpr 1 each border
1340
+ resolves to 1px, so the group rendered 1px short of every control beside it (#018). Stretching
1341
+ is right at any border width, any rounding, and under compact without a second calc to keep in
1342
+ step with --control-h. */
1343
+ .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:auto;align-self:stretch;}
1333
1344
  .fdy-input-group .fdy-input:focus{box-shadow:none;}
1334
1345
  .fdy-input-group__addon{display:inline-flex;align-items:center;padding:0 var(--space-3);background:var(--color-surface-2);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;border-right:var(--bw) solid var(--color-border);}
1335
1346
  .fdy-input-group__addon:last-child{border-right:0;border-left:var(--bw) solid var(--color-border);}
package/dist/freeday.css CHANGED
@@ -729,6 +729,12 @@ a { color: var(--color-primary); }
729
729
  /* Freeday — Date picker (input-styled trigger + calendar popover).
730
730
  * Built by freeday-datepicker.js from an empty [data-fdy-datepicker] wrapper. */
731
731
  .fdy-datepicker{position:relative;display:inline-block;width:100%;max-width:14rem;}
732
+ /* Inside a labelled field, a picker fills the field like every other control.
733
+ The 14rem/11rem caps above suit a picker standing on its own; in a form grid
734
+ they leave the date box visibly short of the combo beside it — 224px against
735
+ 319px in a two-column layout — and the row reads as ragged. The field's own
736
+ max-width is what should govern there. */
737
+ .fdy-field>.fdy-datepicker,.fdy-field>.fdy-timepicker,.fdy-field>.fdy-daterange{max-width:none;}
732
738
  .fdy-datepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
733
739
  .fdy-datepicker__trigger:hover{border-color:var(--color-text-muted);}
734
740
  .fdy-datepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
@@ -943,10 +949,15 @@ a { color: var(--color-primary); }
943
949
  .fdy-form-grid>.fdy-field--full{grid-column:1/-1;}
944
950
 
945
951
  /* Freeday — Input group (prefix/suffix addons, e.g. Rp / % / icon) */
946
- .fdy-input-group{display:flex;align-items:stretch;max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
952
+ .fdy-input-group{display:flex;align-items:stretch;height:var(--control-h);max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
947
953
  .fdy-input-group:hover{border-color:var(--color-text-muted);}
948
954
  .fdy-input-group:focus-within{border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
949
- .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:calc(var(--control-h) - 3px);}
955
+ /* The group owns the height; the input fills whatever the border leaves. It used to subtract 3px
956
+ for two 1.5px borders, which is arithmetic the engine is free to round: at dpr 1 each border
957
+ resolves to 1px, so the group rendered 1px short of every control beside it (#018). Stretching
958
+ is right at any border width, any rounding, and under compact without a second calc to keep in
959
+ step with --control-h. */
960
+ .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:auto;align-self:stretch;}
950
961
  .fdy-input-group .fdy-input:focus{box-shadow:none;}
951
962
  .fdy-input-group__addon{display:inline-flex;align-items:center;padding:0 var(--space-3);background:var(--color-surface-2);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;border-right:var(--bw) solid var(--color-border);}
952
963
  .fdy-input-group__addon:last-child{border-right:0;border-left:var(--bw) solid var(--color-border);}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cahyo-dimas/freeday",
3
- "version": "1.39.0",
3
+ "version": "1.41.0",
4
4
  "description": "Freeday — token-driven, framework-agnostic UI KIT (design source-of-truth).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -92,7 +92,7 @@
92
92
  "scripts": {
93
93
  "build": "node tokens/build.mjs",
94
94
  "test": "node --test",
95
- "test:browser": "node --test browser/vanilla.mjs browser/adapter.mjs browser/layout.mjs browser/theme.mjs browser/state.mjs browser/root-init.mjs browser/upload-states.mjs browser/number.mjs browser/card-stretch.mjs",
95
+ "test:browser": "node --test browser/vanilla.mjs browser/adapter.mjs browser/layout.mjs browser/theme.mjs browser/state.mjs browser/root-init.mjs browser/upload-states.mjs browser/number.mjs browser/card-stretch.mjs browser/text-override.mjs browser/control-heights.mjs",
96
96
  "prepack": "node tokens/build.mjs",
97
97
  "version": "node tokens/build.mjs && git add dist",
98
98
  "typecheck:react": "tsc -p adapters/react/tsconfig.json --noEmit"
@@ -1,6 +1,12 @@
1
1
  /* Freeday — Date picker (input-styled trigger + calendar popover).
2
2
  * Built by freeday-datepicker.js from an empty [data-fdy-datepicker] wrapper. */
3
3
  .fdy-datepicker{position:relative;display:inline-block;width:100%;max-width:14rem;}
4
+ /* Inside a labelled field, a picker fills the field like every other control.
5
+ The 14rem/11rem caps above suit a picker standing on its own; in a form grid
6
+ they leave the date box visibly short of the combo beside it — 224px against
7
+ 319px in a two-column layout — and the row reads as ragged. The field's own
8
+ max-width is what should govern there. */
9
+ .fdy-field>.fdy-datepicker,.fdy-field>.fdy-timepicker,.fdy-field>.fdy-daterange{max-width:none;}
4
10
  .fdy-datepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
5
11
  .fdy-datepicker__trigger:hover{border-color:var(--color-text-muted);}
6
12
  .fdy-datepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
@@ -1,8 +1,13 @@
1
1
  /* Freeday — Input group (prefix/suffix addons, e.g. Rp / % / icon) */
2
- .fdy-input-group{display:flex;align-items:stretch;max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
2
+ .fdy-input-group{display:flex;align-items:stretch;height:var(--control-h);max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
3
3
  .fdy-input-group:hover{border-color:var(--color-text-muted);}
4
4
  .fdy-input-group:focus-within{border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
5
- .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:calc(var(--control-h) - 3px);}
5
+ /* The group owns the height; the input fills whatever the border leaves. It used to subtract 3px
6
+ for two 1.5px borders, which is arithmetic the engine is free to round: at dpr 1 each border
7
+ resolves to 1px, so the group rendered 1px short of every control beside it (#018). Stretching
8
+ is right at any border width, any rounding, and under compact without a second calc to keep in
9
+ step with --control-h. */
10
+ .fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:auto;align-self:stretch;}
6
11
  .fdy-input-group .fdy-input:focus{box-shadow:none;}
7
12
  .fdy-input-group__addon{display:inline-flex;align-items:center;padding:0 var(--space-3);background:var(--color-surface-2);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;border-right:var(--bw) solid var(--color-border);}
8
13
  .fdy-input-group__addon:last-child{border-right:0;border-left:var(--bw) solid var(--color-border);}