@elasticias/ui 1.0.50 → 1.0.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elasticias/ui",
3
- "version": "1.0.50",
3
+ "version": "1.0.51",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -2073,16 +2073,27 @@
2073
2073
  }
2074
2074
 
2075
2075
  .dp__panel {
2076
- position: absolute;
2077
- top: calc(100% + 8px);
2078
- inset-inline-start: 0;
2079
- min-width: 320px;
2076
+ /* Portaled to <body> and fixed to the viewport; the component writes all
2077
+ four physical sides and max-height from the trigger's rect
2078
+ (placeDpPanel). No logical inset here: in RTL it would fight the
2079
+ computed left. The z-index is a fallback; PrimeNG's ZIndexUtils sets
2080
+ the live layer. */
2081
+ position: fixed;
2082
+ box-sizing: border-box;
2083
+ /* The preset list sizes to its rows; the calendar view (.wide) has a set
2084
+ width. It used to take the date inputs' intrinsic width (about 450px),
2085
+ which is what pushed it past the card and the viewport. */
2086
+ inline-size: max-content;
2087
+ min-inline-size: 320px;
2088
+ max-inline-size: calc(100vw - 16px);
2089
+ overflow-y: auto;
2090
+ overscroll-behavior: contain;
2080
2091
  background: var(--paper-alt);
2081
2092
  border: 1px solid var(--rule);
2082
2093
  border-radius: var(--r-xl);
2083
2094
  box-shadow: var(--shadow-3);
2084
2095
  padding: 6px;
2085
- z-index: 40;
2096
+ z-index: 1000;
2086
2097
  display: none;
2087
2098
  animation: row-actions-menu-in var(--t-base) var(--ease-spring);
2088
2099
  }
@@ -2092,7 +2103,7 @@
2092
2103
  gap: 2px;
2093
2104
  }
2094
2105
  .dp__panel.wide {
2095
- min-width: 340px;
2106
+ inline-size: 340px;
2096
2107
  }
2097
2108
 
2098
2109
  .dp__view {
@@ -2367,7 +2378,7 @@
2367
2378
 
2368
2379
  .dp__cal-grid {
2369
2380
  display: grid;
2370
- grid-template-columns: repeat(7, 1fr);
2381
+ grid-template-columns: repeat(7, minmax(0, 1fr));
2371
2382
  gap: 2px 0;
2372
2383
  padding: 0 2px;
2373
2384
  }
@@ -2462,20 +2473,24 @@
2462
2473
 
2463
2474
  .dp__inputs {
2464
2475
  display: grid;
2465
- grid-template-columns: 1fr 1fr;
2476
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
2477
+ /* A label that wraps (the panel has a set width now) must not push its
2478
+ input below its neighbour's. */
2479
+ align-items: end;
2466
2480
  gap: var(--s-2);
2467
2481
  padding: var(--s-2) var(--s-3) 0;
2468
2482
  }
2469
2483
 
2470
2484
  /* Single-date field mode — one full-width input instead of Du / Au. */
2471
2485
  .dp__inputs--single {
2472
- grid-template-columns: 1fr;
2486
+ grid-template-columns: minmax(0, 1fr);
2473
2487
  padding-bottom: var(--s-3);
2474
2488
  }
2475
2489
 
2476
2490
  .dp__field {
2477
2491
  display: grid;
2478
2492
  gap: 4px;
2493
+ min-width: 0;
2479
2494
  }
2480
2495
 
2481
2496
  .dp__field label {
@@ -2488,6 +2503,9 @@
2488
2503
  }
2489
2504
 
2490
2505
  .dp__field input {
2506
+ /* Border-box here, not left to an app's reset: with content-box the
2507
+ 100% width plus padding pushed the time input past its column. */
2508
+ box-sizing: border-box;
2491
2509
  font: inherit;
2492
2510
  font-family: var(--font-mono);
2493
2511
  font-size: 12.5px;
@@ -3859,6 +3877,22 @@ input.ef-input[type='number'] {
3859
3877
  transform: translateY(-50%);
3860
3878
  }
3861
3879
 
3880
+ /* The clear sits at the wrapper's trailing edge, but the input can carry its
3881
+ own direction (`dir` on ef-input-text: an LTR phone or IBAN on an Arabic
3882
+ screen), and `padding-inline-end` follows the input, so the room it reserved
3883
+ landed on the opposite side and the value ran under the ✕. Reserve the room
3884
+ by the wrapper's direction instead. Physical sides on purpose: the two
3885
+ directions are named so the side tracks the clear, not the input. */
3886
+ .ef-input-wrap:dir(ltr) .ef-input.has-clear {
3887
+ padding-left: 12px;
3888
+ padding-right: 36px;
3889
+ }
3890
+
3891
+ .ef-input-wrap:dir(rtl) .ef-input.has-clear {
3892
+ padding-left: 36px;
3893
+ padding-right: 12px;
3894
+ }
3895
+
3862
3896
  /* The same centring, for the clear that PrimeNG owns rather than we do.
3863
3897
  PrimeNG centres both password icons with `top: 50%; margin-top: -8px`, which
3864
3898
  is exact for the 16px mask toggle it draws itself and wrong for anything
@@ -4726,6 +4760,74 @@ input.ef-input[type='number'] {
4726
4760
  }
4727
4761
  }
4728
4762
 
4763
+ /* The date picker's phone layout: a full-width bottom sheet over a backdrop.
4764
+ EfViewportService's mobile (<= 767px) toggles the class, so there is no
4765
+ media query here and no band where the two disagree. Every target is
4766
+ --hit-touch (48px). Declared after the base .dp__* rules so it wins. */
4767
+ .dp__backdrop {
4768
+ position: fixed;
4769
+ inset: 0;
4770
+ z-index: 1000;
4771
+ background: color-mix(in oklab, var(--ink-950) 35%, transparent);
4772
+ }
4773
+
4774
+ .dp__panel.dp__panel--sheet {
4775
+ inset: auto 0 0 0;
4776
+ inline-size: 100%;
4777
+ max-inline-size: none;
4778
+ min-inline-size: 0;
4779
+ max-height: 85vh;
4780
+ max-height: 85dvh;
4781
+ border-radius: var(--r-xl) var(--r-xl) 0 0;
4782
+ border-bottom: 0;
4783
+ padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
4784
+ animation: dp-sheet-in var(--t-base) var(--ease-spring);
4785
+ }
4786
+
4787
+ @keyframes dp-sheet-in {
4788
+ from {
4789
+ transform: translateY(100%);
4790
+ }
4791
+ to {
4792
+ transform: translateY(0);
4793
+ }
4794
+ }
4795
+
4796
+ .dp__panel--sheet .dp__cal-day {
4797
+ height: var(--hit-touch);
4798
+ }
4799
+
4800
+ .dp__panel--sheet .dp__cal-day .day-num {
4801
+ width: 40px;
4802
+ height: 40px;
4803
+ font-size: 15px;
4804
+ }
4805
+
4806
+ .dp__panel--sheet .dp__cal-nav,
4807
+ .dp__panel--sheet .dp__back {
4808
+ width: var(--hit-touch);
4809
+ height: var(--hit-touch);
4810
+ }
4811
+
4812
+ .dp__panel--sheet .dp__cal-pick,
4813
+ .dp__panel--sheet .dp__cal-cell,
4814
+ .dp__panel--sheet .dp__preset,
4815
+ .dp__panel--sheet .dp__actions .btn {
4816
+ min-height: var(--hit-touch);
4817
+ }
4818
+
4819
+ /* 16px stops iOS Safari zooming the page when the input takes focus. */
4820
+ .dp__panel--sheet .dp__field input {
4821
+ min-height: var(--hit-touch);
4822
+ font-size: 16px;
4823
+ }
4824
+
4825
+ @media (prefers-reduced-motion: reduce) {
4826
+ .dp__panel.dp__panel--sheet {
4827
+ animation: none;
4828
+ }
4829
+ }
4830
+
4729
4831
  /* ── TOUCH TARGET TIER ──────────────────────────────────────────────
4730
4832
  The design system documents three tiers: --hit-base 40px for forms,
4731
4833
  --hit-touch 48px for touch, --hit-pos 64px for the till. Until now
@@ -5034,3 +5136,133 @@ input.ef-input[type='number'] {
5034
5136
  min-height: var(--hit-touch);
5035
5137
  }
5036
5138
  }
5139
+
5140
+ /* ── Touch tier, wave 2 (QA D2, D4, D7) ──────────────────────────────
5141
+ A thumb needs 48px; these four controls were left at their desktop
5142
+ height. By pointer, like the rules above, so a mouse keeps the dense
5143
+ layout. Last in the file so the base rules do not win. */
5144
+ @media (pointer: coarse) {
5145
+ /* The ⋮ overflow menu and the shared row-actions menu: 36px items. */
5146
+ .row-actions__item,
5147
+ .ef-menu__item {
5148
+ min-height: var(--hit-touch);
5149
+ }
5150
+
5151
+ /* Confirm dialog actions ("Annuler" / "Recharger"): 40px. */
5152
+ .es-confirm .p-confirmdialog-accept-button,
5153
+ .es-confirm .p-confirmdialog-reject-button {
5154
+ min-height: var(--hit-touch);
5155
+ }
5156
+
5157
+ /* Dialog header close: a 32px ghost circle. */
5158
+ .es-dialog .p-dialog-header-icon,
5159
+ .es-dialog .p-dialog-close-button,
5160
+ .es-dialog .es-dialog__close {
5161
+ width: var(--hit-touch);
5162
+ height: var(--hit-touch);
5163
+ }
5164
+ }
5165
+
5166
+ /* ef-pdf-preview footer on a phone: five actions in one row clipped every
5167
+ label. Let them wrap to two rows of equal-width buttons; Close, which
5168
+ pushed itself to the leading edge on a wide footer, joins the grid.
5169
+ Breakpoint is the shell's 767px (EfViewportService). */
5170
+ @media (max-width: 767px) {
5171
+ .es-dialog.ef-pdf-preview-dialog .p-dialog-footer {
5172
+ flex-wrap: wrap;
5173
+ }
5174
+
5175
+ .es-dialog.ef-pdf-preview-dialog .p-dialog-footer .btn {
5176
+ flex: 1 1 calc(50% - var(--s-2));
5177
+ min-width: 0;
5178
+ justify-content: center;
5179
+ }
5180
+
5181
+ .es-dialog.ef-pdf-preview-dialog .p-dialog-footer .btn-dialog-leading {
5182
+ margin-inline-end: 0;
5183
+ }
5184
+ }
5185
+
5186
+ /* A Latin code (order reference, SKU) inside RTL text keeps its own
5187
+ left-to-right order and is not reordered by its neighbours. Without it
5188
+ the card's reference clipped at the wrong end in Arabic. The isolate is
5189
+ a no-op in LTR. */
5190
+ .tbl .ref,
5191
+ .mrow__primary .ref {
5192
+ direction: ltr;
5193
+ unicode-bidi: isolate;
5194
+ }
5195
+
5196
+ .mrow__primary .ref {
5197
+ display: inline-block;
5198
+ max-width: 100%;
5199
+ overflow: hidden;
5200
+ text-overflow: ellipsis;
5201
+ vertical-align: bottom;
5202
+ }
5203
+
5204
+ /* ──────────── EF-PASSWORD — COMPTOIR VARIANT ────────────────────────
5205
+ `<ef-password variant="comptoir">` puts `.ef-password--comptoir` on the
5206
+ p-password root. Same box as `.ef-input` (--hit-field: 40px, 48px on a
5207
+ coarse pointer), and the show/hide toggle is a --hit-field square. */
5208
+ .ef-password--comptoir.p-password {
5209
+ position: relative;
5210
+ display: block;
5211
+ width: 100%;
5212
+ }
5213
+
5214
+ .ef-password--comptoir.p-password .p-password-input {
5215
+ font: inherit;
5216
+ font-size: 14px;
5217
+ line-height: 1.2;
5218
+ box-sizing: border-box;
5219
+ width: 100%;
5220
+ height: var(--hit-field);
5221
+ padding-block: 0;
5222
+ padding-inline: 12px;
5223
+ background: var(--paper-alt);
5224
+ border: 1px solid var(--rule);
5225
+ border-radius: var(--r-md);
5226
+ color: var(--text);
5227
+ box-shadow: none;
5228
+ outline: 0;
5229
+ transition:
5230
+ border-color var(--t-fast) var(--ease-out),
5231
+ box-shadow var(--t-fast) var(--ease-out);
5232
+ }
5233
+
5234
+ .ef-password--comptoir.p-password .p-password-input:focus {
5235
+ border-color: var(--tenant-400);
5236
+ box-shadow: 0 0 0 4px var(--tenant-100);
5237
+ }
5238
+
5239
+ .ef-password--comptoir.p-password .p-password-input:disabled {
5240
+ background: var(--paper);
5241
+ color: var(--text-mute);
5242
+ cursor: not-allowed;
5243
+ }
5244
+
5245
+ .ef-password--comptoir.p-password.ng-invalid.ng-touched .p-password-input {
5246
+ border-color: var(--st-cancelled-fg);
5247
+ box-shadow: 0 0 0 3px var(--st-cancelled-bg);
5248
+ }
5249
+
5250
+ /* Room for the toggle, on whichever side the text ends. */
5251
+ .ef-password--comptoir.p-password:has(.p-password-toggle-mask-icon) .p-password-input {
5252
+ padding-inline-end: var(--hit-field);
5253
+ }
5254
+
5255
+ /* The 16px glyph sits in a --hit-field square (padding grows the target,
5256
+ not the glyph) pinned to the input's end edge. */
5257
+ .ef-password--comptoir.p-password .p-password-toggle-mask-icon {
5258
+ position: absolute;
5259
+ inset-block-start: 0;
5260
+ inset-inline-end: 0;
5261
+ margin: 0;
5262
+ box-sizing: border-box;
5263
+ width: var(--hit-field);
5264
+ height: var(--hit-field);
5265
+ padding: calc((var(--hit-field) - 16px) / 2);
5266
+ color: var(--text-mute);
5267
+ cursor: pointer;
5268
+ }