@eifi1/ui-kit 0.24.1 → 0.25.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.
Files changed (148) hide show
  1. package/README.md +6 -6
  2. package/dist/chart.d.ts +2 -2
  3. package/dist/components/account-chips.d.ts +1 -1
  4. package/dist/components/amount-input.d.ts +2 -2
  5. package/dist/components/button-group.d.ts +2 -2
  6. package/dist/components/calculator.d.ts +2 -2
  7. package/dist/components/column-mapper.d.ts +28 -9
  8. package/dist/components/column-mapper.js +63 -77
  9. package/dist/components/column-mapper.js.map +1 -1
  10. package/dist/components/confirm-dialog.d.ts +2 -2
  11. package/dist/components/copy-button.d.ts +2 -2
  12. package/dist/components/danger-confirm.d.ts +2 -2
  13. package/dist/components/data-table-cells.d.ts +1 -1
  14. package/dist/components/data-table-filter-popover.d.ts +1 -1
  15. package/dist/components/data-table-filters.d.ts +1 -1
  16. package/dist/components/data-table-labels.d.ts +1 -1
  17. package/dist/components/data-table-pagination.d.ts +1 -1
  18. package/dist/components/data-table-pagination.js +6 -1
  19. package/dist/components/data-table-pagination.js.map +1 -1
  20. package/dist/components/data-table.d.ts +1 -1
  21. package/dist/components/data-table.js +7 -1
  22. package/dist/components/data-table.js.map +1 -1
  23. package/dist/components/facing-pair.d.ts +2 -2
  24. package/dist/components/file-button.d.ts +2 -2
  25. package/dist/components/file-dropzone.d.ts +2 -2
  26. package/dist/components/form-actions.d.ts +2 -2
  27. package/dist/components/iban-input.d.ts +2 -2
  28. package/dist/components/language-select.d.ts +2 -2
  29. package/dist/components/money-field.d.ts +2 -2
  30. package/dist/components/number-field.d.ts +2 -2
  31. package/dist/components/number-input.d.ts +2 -2
  32. package/dist/components/numpad-sheet.d.ts +2 -2
  33. package/dist/components/phone-input.d.ts +2 -2
  34. package/dist/components/series-chart.d.ts +2 -2
  35. package/dist/components/settings-fields.d.ts +2 -2
  36. package/dist/components/share-card.d.ts +2 -2
  37. package/dist/components/swipeable-row.js +1 -1
  38. package/dist/components/swipeable-row.js.map +1 -1
  39. package/dist/components/table.d.ts +35 -1
  40. package/dist/components/table.js +4 -0
  41. package/dist/components/table.js.map +1 -1
  42. package/dist/components/text-link.d.ts +2 -2
  43. package/dist/components/time-input.d.ts +2 -2
  44. package/dist/components/tooltip.d.ts +103 -14
  45. package/dist/components/tooltip.js +194 -57
  46. package/dist/components/tooltip.js.map +1 -1
  47. package/dist/components/translation-review-editor.d.ts +9 -1
  48. package/dist/components/translation-review-editor.js +11 -1
  49. package/dist/components/translation-review-editor.js.map +1 -1
  50. package/dist/components/translation-review-labels.d.ts +10 -0
  51. package/dist/components/translation-review-labels.js +5 -1
  52. package/dist/components/translation-review-labels.js.map +1 -1
  53. package/dist/components/translation-review.d.ts +145 -8
  54. package/dist/components/translation-review.js +372 -91
  55. package/dist/components/translation-review.js.map +1 -1
  56. package/dist/components/ui.d.ts +2 -2
  57. package/dist/components/ui.js +55 -18
  58. package/dist/components/ui.js.map +1 -1
  59. package/dist/components/use-table-state.d.ts +1 -1
  60. package/dist/{data-table-labels-B7OdnM0S.d.ts → data-table-labels-Cdn1QS2k.d.ts} +21 -1
  61. package/dist/data-table.d.ts +1 -1
  62. package/dist/feedback/feedback-attachment.d.ts +2 -2
  63. package/dist/feedback/feedback-dialog.d.ts +2 -2
  64. package/dist/feedback/feedback-dialog.js +6 -1
  65. package/dist/feedback/feedback-dialog.js.map +1 -1
  66. package/dist/feedback/feedback-inbox.d.ts +2 -2
  67. package/dist/feedback/feedback-inbox.js +2 -0
  68. package/dist/feedback/feedback-inbox.js.map +1 -1
  69. package/dist/feedback/feedback-thread.d.ts +2 -2
  70. package/dist/{feedback-DOwPu-Il.d.ts → feedback-BXKH-ToU.d.ts} +32 -3
  71. package/dist/feedback.d.ts +2 -2
  72. package/dist/hooks/use-body-scroll-lock.js +16 -0
  73. package/dist/hooks/use-body-scroll-lock.js.map +1 -1
  74. package/dist/hooks/use-file-drop.d.ts +2 -2
  75. package/dist/hooks/use-search-param-state.d.ts +58 -3
  76. package/dist/hooks/use-search-param-state.js +107 -35
  77. package/dist/hooks/use-search-param-state.js.map +1 -1
  78. package/dist/i18n/defaults.d.ts +2 -2
  79. package/dist/i18n/german.d.ts +2 -2
  80. package/dist/i18n/german.js +8 -1
  81. package/dist/i18n/german.js.map +1 -1
  82. package/dist/i18n/kit-labels.d.ts +2 -2
  83. package/dist/i18n/languages.d.ts +2 -2
  84. package/dist/i18n/locales/de-CH.d.ts +2 -2
  85. package/dist/i18n/locales/en.d.ts +2 -2
  86. package/dist/i18n/locales/en.js +5 -1
  87. package/dist/i18n/locales/en.js.map +1 -1
  88. package/dist/i18n/locales/es.d.ts +2 -2
  89. package/dist/i18n/locales/es.js +7 -1
  90. package/dist/i18n/locales/es.js.map +1 -1
  91. package/dist/i18n/locales/fr.d.ts +2 -2
  92. package/dist/i18n/locales/fr.js +6 -1
  93. package/dist/i18n/locales/fr.js.map +1 -1
  94. package/dist/i18n/locales/hu.d.ts +2 -2
  95. package/dist/i18n/locales/hu.js +9 -1
  96. package/dist/i18n/locales/hu.js.map +1 -1
  97. package/dist/i18n/locales/it.d.ts +2 -2
  98. package/dist/i18n/locales/it.js +6 -1
  99. package/dist/i18n/locales/it.js.map +1 -1
  100. package/dist/i18n/locales/zh.d.ts +2 -2
  101. package/dist/i18n/locales/zh.js +6 -1
  102. package/dist/i18n/locales/zh.js.map +1 -1
  103. package/dist/i18n/review.d.ts +2 -2
  104. package/dist/i18n/review.js +11 -0
  105. package/dist/i18n/review.js.map +1 -1
  106. package/dist/index.d.ts +6 -6
  107. package/dist/index.js +9 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/lib/strip-fade.d.ts +84 -5
  110. package/dist/lib/strip-fade.js +109 -11
  111. package/dist/lib/strip-fade.js.map +1 -1
  112. package/dist/lib/translation-review.d.ts +45 -1
  113. package/dist/lib/translation-review.js +38 -1
  114. package/dist/lib/translation-review.js.map +1 -1
  115. package/dist/rhf/fields.d.ts +2 -2
  116. package/dist/rhf/form.d.ts +2 -2
  117. package/dist/rhf.d.ts +2 -2
  118. package/dist/shell/app-shell.d.ts +2 -2
  119. package/dist/shell/top-bar-brand.d.ts +2 -2
  120. package/dist/shell.d.ts +2 -2
  121. package/dist/wizard/stepper-nav.d.ts +2 -2
  122. package/dist/wizard.d.ts +2 -2
  123. package/package.json +1 -1
  124. package/src/components/column-mapper.tsx +120 -113
  125. package/src/components/data-table-pagination.tsx +10 -1
  126. package/src/components/data-table.tsx +34 -1
  127. package/src/components/swipeable-row.tsx +1 -1
  128. package/src/components/table.tsx +39 -0
  129. package/src/components/tooltip.tsx +487 -104
  130. package/src/components/translation-review-editor.tsx +21 -1
  131. package/src/components/translation-review-labels.ts +17 -0
  132. package/src/components/translation-review.tsx +657 -109
  133. package/src/components/ui.tsx +104 -4
  134. package/src/feedback/feedback-dialog.tsx +21 -0
  135. package/src/feedback/feedback-inbox.tsx +19 -2
  136. package/src/hooks/use-body-scroll-lock.ts +25 -0
  137. package/src/hooks/use-search-param-state.ts +283 -41
  138. package/src/i18n/german.ts +10 -0
  139. package/src/i18n/locales/en.ts +7 -0
  140. package/src/i18n/locales/es.ts +9 -0
  141. package/src/i18n/locales/fr.ts +9 -0
  142. package/src/i18n/locales/hu.ts +11 -0
  143. package/src/i18n/locales/it.ts +9 -0
  144. package/src/i18n/locales/zh.ts +8 -0
  145. package/src/i18n/review.ts +11 -0
  146. package/src/index.ts +12 -0
  147. package/src/lib/strip-fade.ts +220 -15
  148. package/src/lib/translation-review.ts +85 -0
@@ -38,6 +38,7 @@ import { useAnnounce } from "../hooks/use-announce";
38
38
  import { DEFAULT_DATA_TABLE_LABELS, resolveDataTableLabels, type DataTableLabels } from "./data-table-labels";
39
39
  import { useKitLabelOverrides, useKitLocale } from "../i18n/kit-labels";
40
40
  import { Tooltip } from "./tooltip";
41
+ import { useEdgeFade } from "../lib/strip-fade";
41
42
  import { dirOf, isRtl, type Direction } from "../lib/direction";
42
43
 
43
44
  // ---------- Types ----------
@@ -494,6 +495,26 @@ export interface DataTableProps<T> {
494
495
  * Default true.
495
496
  */
496
497
  frame?: boolean;
498
+ /**
499
+ * Fade out an edge of the desktop table's scroller while columns are hidden behind
500
+ * it (0.25) — the kit {@link Table}'s `edgeFade`, on the scroller this table draws
501
+ * itself (DataTable renders its own `<table>`, not through Table, so the prop is
502
+ * its own too). Measured: nothing is drawn while every column fits; the end with
503
+ * columns behind it fades, both ends once scrolled into the middle, the reading
504
+ * direction's ends in RTL. A `mask-image`, so no layout moves and no colour is
505
+ * assumed; never animated. The scroller's own scrollbars stay out of it — its
506
+ * vertical one sits at the inline end, in the very band that fades. Focus landing
507
+ * in a cell behind the fade (a row action, a link, the selection box) is scrolled
508
+ * clear of it. The scroller carries `data-overflow` (`"start"`, `"end"`, `"both"`).
509
+ *
510
+ * The phone layout is a card list that never scrolls sideways; it is unaffected.
511
+ *
512
+ * Off by default. It is visual only, but not neutral: on the bump it would change
513
+ * how every overflowing desktop table in an app looks, and the mask covers
514
+ * everything the scroller paints — the sticky header and totals rows, an app's own
515
+ * marks at the scroller's edges. Opt in per table, or app-wide from your own wrapper.
516
+ */
517
+ edgeFade?: boolean;
497
518
  /** Extra classes for the table's root element (the card, or with `frame={false}`
498
519
  * the plain wrapper). Merged last, so a caller's margin or width wins. */
499
520
  className?: string;
@@ -1002,6 +1023,7 @@ export function DataTable<T>({
1002
1023
  resizable: resizableProp,
1003
1024
  multiSort: multiSortProp,
1004
1025
  frame = true,
1026
+ edgeFade = false,
1005
1027
  className,
1006
1028
  rowActions,
1007
1029
  toolbar,
@@ -1545,6 +1567,9 @@ export function DataTable<T>({
1545
1567
  // list — never both — so we don't double up DOM nodes that screen readers and
1546
1568
  // integration tests would have to disambiguate.
1547
1569
  const isMdUp = useMediaQuery("(min-width: 768px)", true);
1570
+ // `edgeFade` (0.25) on the desktop scroller; the phone list never scrolls sideways.
1571
+ const desktopScroller = useRef<HTMLDivElement | null>(null);
1572
+ const edgeFadeProps = useEdgeFade(desktopScroller, edgeFade && isMdUp);
1548
1573
 
1549
1574
  // ---- Mobile card list (md:hidden) ----
1550
1575
  // Renders the same paged/filtered/sorted slice but as stacked cards instead
@@ -2060,10 +2085,18 @@ export function DataTable<T>({
2060
2085
  other half of the `w-0 min-w-full` fix on the expansion cell below
2061
2086
  (feedback #104: "expanding an item resizes the columns"). */}
2062
2087
  <div
2088
+ ref={desktopScroller}
2063
2089
  // The scroller: marked for the Tooltip's auto-portal (see the root above).
2064
2090
  data-clips=""
2065
2091
  className={cn("overflow-auto [scrollbar-gutter:stable]", fillHeight && "flex-1 min-h-0")}
2066
- style={fillHeight ? undefined : { maxHeight: maxBodyHeight }}
2092
+ // `edgeFade`: the mask, `data-overflow` and the focus handling; nothing
2093
+ // while off. The height bound is merged over the mask, not replaced by it.
2094
+ {...edgeFadeProps}
2095
+ style={
2096
+ fillHeight
2097
+ ? edgeFadeProps.style
2098
+ : { ...edgeFadeProps.style, maxHeight: maxBodyHeight }
2099
+ }
2067
2100
  >
2068
2101
  {/* A table with no name is "table" in a screen reader's list of tables, and
2069
2102
  an app renders several. `labels.table` is how a call site says which. */}
@@ -227,7 +227,7 @@ export function SwipeableRow({
227
227
  // text also SELECTS that text — so committing an action left the row
228
228
  // highlighted blue. Suppressed only while dragging, so text in a row at
229
229
  // rest stays selectable.
230
- swipe.dragging ? "select-none" : "transition-transform duration-150",
230
+ swipe.dragging ? "select-none" : "transition-transform duration-150 motion-reduce:transition-none",
231
231
  )}
232
232
  style={{
233
233
  transform: dx !== 0 ? `translate3d(${dx}px,0,0)` : undefined,
@@ -1,6 +1,7 @@
1
1
  import { Children, createContext, useCallback, useContext, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
2
2
  import type { ComponentPropsWithRef, ReactNode, Ref } from "react";
3
3
  import { cn } from "../lib/cn";
4
+ import { useEdgeFade } from "../lib/strip-fade";
4
5
  import { assignRef } from "./choice-parts";
5
6
  import { THIN_SCROLLBAR_CLASS, useScrollOverflow } from "./scroll-area";
6
7
 
@@ -194,6 +195,40 @@ export interface TableProps extends ComponentPropsWithRef<"table"> {
194
195
  * columns gets none.
195
196
  */
196
197
  stack?: "phone";
198
+ /**
199
+ * Fade out an edge of the scroll wrapper while columns are hidden behind it (0.25).
200
+ *
201
+ * A table wider than its box scrolls sideways inside the wrapper, and on a phone —
202
+ * whose scrollbars are overlays that show only while you drag — nothing said there
203
+ * was more: the last visible column simply ended at the edge, often mid-word. 0.24
204
+ * drew a fade for ColumnRoleTable's preview (Kurvenschmiede: the fourth column's
205
+ * role select sat off-screen with no hint) by wrapping this Table and reaching its
206
+ * wrapper as the `<table>`'s `parentElement`; this is that fade as the Table's own,
207
+ * so a table needs neither the reach-around nor a box of its own round it.
208
+ *
209
+ * It is the kit Tabs strip's fade, MEASURED rather than assumed: nothing is drawn
210
+ * while the table fits, so a table that fits paints exactly as without the prop;
211
+ * the end with columns behind it fades, and both ends once scrolled into the
212
+ * middle; the ends are the reading direction's, so in RTL the hidden columns fade
213
+ * on the left. It is a `mask-image` — no layout change, no background colour to
214
+ * fade to, so it works on any surface in either theme — and never animated, so
215
+ * there is nothing for reduced motion to turn off. The wrapper's own scrollbars
216
+ * stay out of it (a fade on a classic scrollbar hid the very thing that says the
217
+ * box scrolls).
218
+ *
219
+ * Focus that lands in a cell behind the fade — a link, a select, a checkbox — is
220
+ * scrolled clear of it, cell and all where the cell fits; the browser's own scroll
221
+ * stops at the edge, under the fade. And while the overflowing wrapper ITSELF holds
222
+ * keyboard focus (it is a tab stop then, for arrow-key scrolling) the fade lifts, so
223
+ * the focus outline round the box is drawn whole rather than faded out at its sides.
224
+ *
225
+ * The wrapper carries `data-overflow` — `"start"`, `"end"` or `"both"`, in
226
+ * reading-direction terms, absent while it fits — for a caller's own affordance
227
+ * (a scroll button) and for tests, which cannot read a mask.
228
+ *
229
+ * Off by default: it changes how every overflowing table looks.
230
+ */
231
+ edgeFade?: boolean;
197
232
  }
198
233
 
199
234
  /**
@@ -236,6 +271,7 @@ export function Table({
236
271
  framed = false,
237
272
  rowDividers = true,
238
273
  stack,
274
+ edgeFade = false,
239
275
  className,
240
276
  "aria-label": ariaLabel,
241
277
  ref,
@@ -245,6 +281,7 @@ export function Table({
245
281
  const [captions, setCaptions] = useState(0);
246
282
  const wrapper = useRef<HTMLDivElement | null>(null);
247
283
  const overflowing = useScrollOverflow(wrapper);
284
+ const fade = useEdgeFade(wrapper, edgeFade);
248
285
  const tableRef = useRef<HTMLTableElement | null>(null);
249
286
  const setTableRef = useMergedRef(tableRef, ref);
250
287
 
@@ -307,6 +344,8 @@ export function Table({
307
344
  data-overflowing={overflowing || undefined}
308
345
  data-clips=""
309
346
  data-framed={framed || undefined}
347
+ // `edgeFade`: the mask, `data-overflow` and the focus handling; nothing while off.
348
+ {...fade}
310
349
  className={cn(
311
350
  // `relative`: the containing block for an `sr-only` caption.
312
351
  "relative w-full overflow-x-auto",