@adecore/ui 0.54.7 → 0.54.9

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/dist/Banner.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { LucideIcon } from 'lucide-react';
2
2
  import type { ReactNode, Ref } from 'react';
3
- export type BannerTone = 'attention' | 'error' | 'neutral';
3
+ export type BannerTone = 'attention' | 'error' | 'positive' | 'neutral';
4
4
  export interface BannerProps {
5
5
  icon: LucideIcon;
6
6
  tone: BannerTone;
package/dist/Banner.js CHANGED
@@ -6,6 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  const TONE = {
7
7
  attention: 'text-status-needs-you',
8
8
  error: 'text-status-error',
9
+ positive: 'text-positive',
9
10
  neutral: 'text-text-muted'
10
11
  };
11
12
  const OVERLAY = 'absolute inset-x-0 top-3 z-20';
package/dist/Toasts.js CHANGED
@@ -19,7 +19,7 @@ const ICON = {
19
19
  };
20
20
  const TONE = {
21
21
  progress: 'text-text-muted',
22
- success: 'text-status-idle',
22
+ success: 'text-positive',
23
23
  error: 'text-status-error',
24
24
  deleted: 'text-text-muted'
25
25
  };
package/dist/theme.css CHANGED
@@ -1103,10 +1103,14 @@
1103
1103
  [data-overlay-scrollbars][data-scrollbar-dragging], .ade-scrollbar { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
1104
1104
  .ade-scroll-area { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
1105
1105
  /* Its own stacking layer, so a sticky header with a z-index inside never covers the bars. */
1106
- /* `contain` lets the box bounce at its own end; the page's `overscroll-behavior: none` would take the bounce of a scroll chained up to it. */
1107
- .ade-scroll-viewport { flex: 1 1 auto; min-height: 0; overflow: auto; isolation: isolate; overscroll-behavior: contain; }
1108
- .ade-scroll-viewport[data-axis="y"] { overflow-x: hidden; }
1109
- .ade-scroll-viewport[data-axis="x"] { overflow-y: hidden; }
1106
+ /* It scrolls only along an axis whose bar has something to scroll (`useOverlayScrollbars`): Chromium composites every box
1107
+ that can scroll, so a canvas of idle areas would cost a layer each on every frame. Hidden, it still scrolls from code. */
1108
+ /* `contain` lets the box bounce at its own end; the page's `overscroll-behavior: none` would take the bounce of a scroll chained up to it.
1109
+ Only on the axes it scrolls: Chromium stops a chain at `contain` even on an axis that cannot scroll, so a wheel down over a
1110
+ table that scrolls sideways would never reach the thread around it. */
1111
+ .ade-scroll-viewport { flex: 1 1 auto; min-height: 0; overflow: hidden; isolation: isolate; }
1112
+ .ade-scroll-viewport[data-overflow-y] { overflow-y: auto; overscroll-behavior-y: contain; }
1113
+ .ade-scroll-viewport[data-overflow-x] { overflow-x: auto; overscroll-behavior-x: contain; }
1110
1114
  .ade-scrollbar {
1111
1115
  --scrollbar-size: 12px;
1112
1116
  position: absolute;
@@ -6,6 +6,16 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
6
6
  export const SCROLLBAR_LINGER_MS = 600;
7
7
  /* The theme hides the native bar of a scroller that carries this attribute. */
8
8
  const OVERLAY_ATTRIBUTE = 'data-overlay-scrollbars';
9
+ /*
10
+ * Set on the scroller for each axis of a bar that has something to scroll. A `ScrollArea` scrolls
11
+ * only along those: Chromium composites every box that can scroll, so a canvas full of idle areas
12
+ * would cost a layer each on every frame.
13
+ */
14
+ const OVERFLOW_X_ATTRIBUTE = 'data-overflow-x';
15
+ const OVERFLOW_Y_ATTRIBUTE = 'data-overflow-y';
16
+ function overflowAttributeOf(bar) {
17
+ return bar.vertical ? OVERFLOW_Y_ATTRIBUTE : OVERFLOW_X_ATTRIBUTE;
18
+ }
9
19
  /*
10
20
  * Draws thin bars over `viewport`, a scroller that stays native, so wheel, keys, `scrollIntoView` and
11
21
  * a virtualizer keep working on it. Put the returned element in a positioned ancestor whose box is
@@ -65,6 +75,7 @@ export function useOverlayScrollbars(viewport, t0) {
65
75
  bars.forEach((bar_3, index) => {
66
76
  bar_3.element.toggleAttribute("data-overflow", overflowing[index]);
67
77
  bar_3.element.toggleAttribute("data-corner", corner);
78
+ viewport.toggleAttribute(overflowAttributeOf(bar_3), overflowing[index]);
68
79
  });
69
80
  bars.forEach((bar_4, index_0) => {
70
81
  if (!overflowing[index_0]) {
@@ -184,15 +195,23 @@ export function useOverlayScrollbars(viewport, t0) {
184
195
  });
185
196
  const sizes = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(layout);
186
197
  sizes?.observe(viewport);
187
- const observeContent = () => {
188
- for (const child of viewport.children) {
189
- sizes?.observe(child);
190
- }
191
- };
192
198
  const content = typeof MutationObserver === "undefined" ? null : new MutationObserver(() => {
193
199
  observeContent();
194
200
  layout();
195
201
  });
202
+ const observeContent = () => {
203
+ for (const child of viewport.childNodes) {
204
+ if (child.nodeType === child.ELEMENT_NODE) {
205
+ sizes?.observe(child);
206
+ } else {
207
+ if (child.nodeType === child.TEXT_NODE) {
208
+ content?.observe(child, {
209
+ characterData: true
210
+ });
211
+ }
212
+ }
213
+ }
214
+ };
196
215
  content?.observe(viewport, {
197
216
  childList: true
198
217
  });
@@ -210,6 +229,8 @@ export function useOverlayScrollbars(viewport, t0) {
210
229
  content?.disconnect();
211
230
  window.clearTimeout(lingerTimer);
212
231
  viewport.removeAttribute(OVERLAY_ATTRIBUTE);
232
+ viewport.removeAttribute(OVERFLOW_X_ATTRIBUTE);
233
+ viewport.removeAttribute(OVERFLOW_Y_ATTRIBUTE);
213
234
  viewport.removeAttribute("data-scrollbar-dragging");
214
235
  viewport.removeEventListener("scroll", onScroll);
215
236
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/ui",
3
- "version": "0.54.7",
3
+ "version": "0.54.9",
4
4
  "description": "React components, a theme, formatters and a settings dialog for desktop-grade apps on React 19, Base UI and Tailwind 4.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
package/src/Banner.tsx CHANGED
@@ -4,12 +4,13 @@ import type { ReactNode, Ref } from 'react';
4
4
  import { Icon } from './Icon.tsx';
5
5
  import { Surface } from './Surface.tsx';
6
6
 
7
- /* The mark in front of the line: a decision to make, a failure to read, or something that happened. */
8
- export type BannerTone = 'attention' | 'error' | 'neutral';
7
+ /* The mark in front of the line: a decision to make, a failure to read, something that succeeded, or something that happened. */
8
+ export type BannerTone = 'attention' | 'error' | 'positive' | 'neutral';
9
9
 
10
10
  const TONE: Record<BannerTone, string> = {
11
11
  attention: 'text-status-needs-you',
12
12
  error: 'text-status-error',
13
+ positive: 'text-positive',
13
14
  neutral: 'text-text-muted'
14
15
  };
15
16
 
package/src/Toasts.tsx CHANGED
@@ -19,7 +19,7 @@ const ICON = {
19
19
 
20
20
  const TONE = {
21
21
  progress: 'text-text-muted',
22
- success: 'text-status-idle',
22
+ success: 'text-positive',
23
23
  error: 'text-status-error',
24
24
  deleted: 'text-text-muted'
25
25
  } as const;
package/src/theme.css CHANGED
@@ -1103,10 +1103,14 @@
1103
1103
  [data-overlay-scrollbars][data-scrollbar-dragging], .ade-scrollbar { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
1104
1104
  .ade-scroll-area { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
1105
1105
  /* Its own stacking layer, so a sticky header with a z-index inside never covers the bars. */
1106
- /* `contain` lets the box bounce at its own end; the page's `overscroll-behavior: none` would take the bounce of a scroll chained up to it. */
1107
- .ade-scroll-viewport { flex: 1 1 auto; min-height: 0; overflow: auto; isolation: isolate; overscroll-behavior: contain; }
1108
- .ade-scroll-viewport[data-axis="y"] { overflow-x: hidden; }
1109
- .ade-scroll-viewport[data-axis="x"] { overflow-y: hidden; }
1106
+ /* It scrolls only along an axis whose bar has something to scroll (`useOverlayScrollbars`): Chromium composites every box
1107
+ that can scroll, so a canvas of idle areas would cost a layer each on every frame. Hidden, it still scrolls from code. */
1108
+ /* `contain` lets the box bounce at its own end; the page's `overscroll-behavior: none` would take the bounce of a scroll chained up to it.
1109
+ Only on the axes it scrolls: Chromium stops a chain at `contain` even on an axis that cannot scroll, so a wheel down over a
1110
+ table that scrolls sideways would never reach the thread around it. */
1111
+ .ade-scroll-viewport { flex: 1 1 auto; min-height: 0; overflow: hidden; isolation: isolate; }
1112
+ .ade-scroll-viewport[data-overflow-y] { overflow-y: auto; overscroll-behavior-y: contain; }
1113
+ .ade-scroll-viewport[data-overflow-x] { overflow-x: auto; overscroll-behavior-x: contain; }
1110
1114
  .ade-scrollbar {
1111
1115
  --scrollbar-size: 12px;
1112
1116
  position: absolute;
@@ -14,12 +14,24 @@ export const SCROLLBAR_LINGER_MS = 600;
14
14
  /* The theme hides the native bar of a scroller that carries this attribute. */
15
15
  const OVERLAY_ATTRIBUTE = 'data-overlay-scrollbars';
16
16
 
17
+ /*
18
+ * Set on the scroller for each axis of a bar that has something to scroll. A `ScrollArea` scrolls
19
+ * only along those: Chromium composites every box that can scroll, so a canvas full of idle areas
20
+ * would cost a layer each on every frame.
21
+ */
22
+ const OVERFLOW_X_ATTRIBUTE = 'data-overflow-x';
23
+ const OVERFLOW_Y_ATTRIBUTE = 'data-overflow-y';
24
+
17
25
  interface Bar {
18
26
  readonly element: HTMLElement;
19
27
  readonly thumb: HTMLElement;
20
28
  readonly vertical: boolean;
21
29
  }
22
30
 
31
+ function overflowAttributeOf(bar: Bar): string {
32
+ return bar.vertical ? OVERFLOW_Y_ATTRIBUTE : OVERFLOW_X_ATTRIBUTE;
33
+ }
34
+
23
35
  /*
24
36
  * Draws thin bars over `viewport`, a scroller that stays native, so wheel, keys, `scrollIntoView` and
25
37
  * a virtualizer keep working on it. Put the returned element in a positioned ancestor whose box is
@@ -68,6 +80,7 @@ export function useOverlayScrollbars(viewport: HTMLElement | null, { axis = 'y'
68
80
  bars.forEach((bar, index) => {
69
81
  bar.element.toggleAttribute('data-overflow', overflowing[index]);
70
82
  bar.element.toggleAttribute('data-corner', corner);
83
+ viewport.toggleAttribute(overflowAttributeOf(bar), overflowing[index]);
71
84
  });
72
85
 
73
86
  bars.forEach((bar, index) => {
@@ -211,12 +224,6 @@ export function useOverlayScrollbars(viewport: HTMLElement | null, { axis = 'y'
211
224
  const sizes = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(layout);
212
225
  sizes?.observe(viewport);
213
226
 
214
- const observeContent = (): void => {
215
- for (const child of viewport.children) {
216
- sizes?.observe(child);
217
- }
218
- };
219
-
220
227
  // A row added to the content changes what scrolls without resizing the rows already observed.
221
228
  const content =
222
229
  typeof MutationObserver === 'undefined'
@@ -226,6 +233,18 @@ export function useOverlayScrollbars(viewport: HTMLElement | null, { axis = 'y'
226
233
  layout();
227
234
  });
228
235
 
236
+ // Text right in the scroller, as in a `<pre>`, grows without resizing anything an observer sees.
237
+ // The node's own constants, not the `Element` or `Node` globals: a document from a test's own window has none.
238
+ const observeContent = (): void => {
239
+ for (const child of viewport.childNodes) {
240
+ if (child.nodeType === child.ELEMENT_NODE) {
241
+ sizes?.observe(child as Element);
242
+ } else if (child.nodeType === child.TEXT_NODE) {
243
+ content?.observe(child, { characterData: true });
244
+ }
245
+ }
246
+ };
247
+
229
248
  content?.observe(viewport, { childList: true });
230
249
  observeContent();
231
250
  viewport.setAttribute(OVERLAY_ATTRIBUTE, '');
@@ -241,6 +260,8 @@ export function useOverlayScrollbars(viewport: HTMLElement | null, { axis = 'y'
241
260
  content?.disconnect();
242
261
  window.clearTimeout(lingerTimer);
243
262
  viewport.removeAttribute(OVERLAY_ATTRIBUTE);
263
+ viewport.removeAttribute(OVERFLOW_X_ATTRIBUTE);
264
+ viewport.removeAttribute(OVERFLOW_Y_ATTRIBUTE);
244
265
  viewport.removeAttribute('data-scrollbar-dragging');
245
266
  viewport.removeEventListener('scroll', onScroll);
246
267
  };