@parallelworks/ui 0.65.2 → 0.66.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.
- package/README.md +14 -10
- package/dist/brandIcons.js +1 -1
- package/dist/components/Avatar.js +4 -1
- package/dist/components/Toast.d.ts +2 -2
- package/dist/components/Toast.js +2 -2
- package/dist/components/floating.d.ts +1 -1
- package/dist/components/floating.js +1 -1
- package/dist/graph/StepSummaries.js +16 -1
- package/dist/icons.d.ts +4 -3
- package/dist/icons.js +268 -277
- package/dist/styles/base.css +9 -5
- package/dist/styles.css +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -647,8 +647,8 @@ such as `z-index: 100` for a top bar, rather than a z-index chosen to win:
|
|
|
647
647
|
| `--layer-overlay` | 1000 | a panel over the page, such as a full-screen log |
|
|
648
648
|
| `--layer-drawer` | 1100 | drawers |
|
|
649
649
|
| `--layer-modal` | 1200 | modals |
|
|
650
|
-
| `--layer-
|
|
651
|
-
| `--layer-
|
|
650
|
+
| `--layer-toast` | 1300 | toasts, so one stays usable while a modal is open |
|
|
651
|
+
| `--layer-popover` | 1400 | menus, selects, popovers, hover cards and tooltips, so one opens over the dialog it belongs to and over a toast |
|
|
652
652
|
|
|
653
653
|
In Tailwind, `z-(--layer-modal)` reads one. Override a value on `:root` to move
|
|
654
654
|
a layer; the defaults sit in a cascade layer, so the host's own rule wins.
|
|
@@ -663,10 +663,11 @@ import { AddIcon, TrashIcon } from '@parallelworks/ui/icons'
|
|
|
663
663
|
```
|
|
664
664
|
|
|
665
665
|
`@parallelworks/ui/icons` is the one import point for interface icons. Each
|
|
666
|
-
name is a meaning, such as `RetryIcon` or `WarningIcon
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
666
|
+
name is a meaning, such as `RetryIcon` or `WarningIcon`. Every icon is drawn
|
|
667
|
+
for this module by one hand: one path on a 16px grid with a 1.5px stroke, in
|
|
668
|
+
fewer and simpler shapes than a 24px set so it stays crisp at the 16px it's
|
|
669
|
+
mostly shown at. Don't bring in another icon library: a name here keeps one
|
|
670
|
+
glyph per meaning across the apps.
|
|
670
671
|
|
|
671
672
|
- **Size and color:** an icon is `1em` square in `currentColor`, so it follows
|
|
672
673
|
the text around it. A class such as `size-4` or `h-3 w-3` sets another size,
|
|
@@ -690,10 +691,13 @@ meaning across the apps.
|
|
|
690
691
|
write-up to read, such as a case study, and `NotebookIcon` one notebook.
|
|
691
692
|
`PendingIcon` is a requirement not met yet and `NotRunningIcon` a run not
|
|
692
693
|
started; they share the empty circle, so keep them out of the same list.
|
|
693
|
-
- **Adding an icon:**
|
|
694
|
-
`export const NameIcon = /* @__PURE__ */
|
|
695
|
-
named for what it means rather than what it shows. Reuse
|
|
696
|
-
|
|
694
|
+
- **Adding an icon:** draw it as one path on the 16px grid and add
|
|
695
|
+
`export const NameIcon = /* @__PURE__ */ drawn('M…')` to `src/icons.tsx`,
|
|
696
|
+
named for what it means rather than what it shows. Reuse the existing parts
|
|
697
|
+
(the status circle, the person, the file and folder outlines, the
|
|
698
|
+
bottom-right corner for a plus, minus, check or X) so families match, and
|
|
699
|
+
check it at 16px beside its neighbours in the `UI/Icons` story. Reuse an
|
|
700
|
+
existing name when the meaning is the same.
|
|
697
701
|
|
|
698
702
|
Logos of other companies' products, such as `GitHubIcon` or `UbuntuIcon`, are
|
|
699
703
|
in `@parallelworks/ui/brand-icons`. They take the same props, are filled in the
|
package/dist/brandIcons.js
CHANGED
|
@@ -27,7 +27,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
27
27
|
*/
|
|
28
28
|
/** A one-color logo in the text's color, at the text's size. */
|
|
29
29
|
function brand(viewBox, ...paths) {
|
|
30
|
-
function Icon({ title, size = "1em", color = "currentColor", strokeWidth: _strokeWidth,
|
|
30
|
+
function Icon({ title, size = "1em", color = "currentColor", strokeWidth: _strokeWidth, children, ...props }) {
|
|
31
31
|
const named = Boolean(title || props["aria-label"] || props["aria-labelledby"]);
|
|
32
32
|
return /* @__PURE__ */ jsxs("svg", {
|
|
33
33
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -54,7 +54,10 @@ function Avatar$1({ src, name, colorKey, size = "md", status, className }) {
|
|
|
54
54
|
}, src), /* @__PURE__ */ jsx(Avatar.Fallback, {
|
|
55
55
|
"aria-hidden": "true",
|
|
56
56
|
className: cx("flex size-full items-center justify-center", colorBy ? categoryClasses(colorBy) : "bg-gradient-to-br from-[var(--gradient-start,var(--theme-accent))] to-[var(--gradient-mid,var(--theme-link))] text-(--theme-accent-text)"),
|
|
57
|
-
children:
|
|
57
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
58
|
+
className: "leading-none [text-box:trim-both_cap_alphabetic]",
|
|
59
|
+
children: size === "xs" ? firstCharacter(avatarInitials(name)) : avatarInitials(name)
|
|
60
|
+
})
|
|
58
61
|
})]
|
|
59
62
|
}), status && /* @__PURE__ */ jsx("span", {
|
|
60
63
|
"data-testid": "online-indicator",
|
|
@@ -54,8 +54,8 @@ export interface Toaster {
|
|
|
54
54
|
}) => Promise<T>;
|
|
55
55
|
}
|
|
56
56
|
/** Shows toasts from anywhere, a component or not. They render in the
|
|
57
|
-
* `UIProvider`'s viewport, over dialogs and
|
|
58
|
-
* modal is open. */
|
|
57
|
+
* `UIProvider`'s viewport, over dialogs and under an open popup such as a menu,
|
|
58
|
+
* and stay usable while a modal is open. */
|
|
59
59
|
export declare const toast: Toaster;
|
|
60
60
|
/** Whether a dialog's close request came from a press on a toast, which the
|
|
61
61
|
* dialog ignores: a toast floats over it, so pressing one isn't leaving it. */
|
package/dist/components/Toast.js
CHANGED
|
@@ -56,8 +56,8 @@ function show(kind) {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
/** Shows toasts from anywhere, a component or not. They render in the
|
|
59
|
-
* `UIProvider`'s viewport, over dialogs and
|
|
60
|
-
* modal is open. */
|
|
59
|
+
* `UIProvider`'s viewport, over dialogs and under an open popup such as a menu,
|
|
60
|
+
* and stay usable while a modal is open. */
|
|
61
61
|
var toast = {
|
|
62
62
|
info: show("info"),
|
|
63
63
|
success: show("success"),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Above dialogs and sticky chrome; hidden while its anchor is scrolled out of view. */
|
|
1
|
+
/** Above dialogs, toasts and sticky chrome; hidden while its anchor is scrolled out of view. */
|
|
2
2
|
export declare const positionerClassName = "z-(--layer-popover) outline-none data-anchor-hidden:invisible";
|
|
3
3
|
/** A panel of choices: a menu, a select's list, a combobox's list. */
|
|
4
4
|
export declare const panelClassName = "rounded-lg border border-(--theme-border) bg-(--theme-app-bg) text-sm text-(--theme-app) shadow-(--theme-shadow-lg) outline-none origin-(--transform-origin) transition-[transform,opacity] duration-100 data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/floating.ts
|
|
2
|
-
/** Above dialogs and sticky chrome; hidden while its anchor is scrolled out of view. */
|
|
2
|
+
/** Above dialogs, toasts and sticky chrome; hidden while its anchor is scrolled out of view. */
|
|
3
3
|
var positionerClassName = "z-(--layer-popover) outline-none data-anchor-hidden:invisible";
|
|
4
4
|
var enterExit = "origin-(--transform-origin) transition-[transform,opacity] duration-100 data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100";
|
|
5
5
|
/** A panel of choices: a menu, a select's list, a combobox's list. */
|
|
@@ -138,6 +138,18 @@ function SummaryBody({ runSlug, path }) {
|
|
|
138
138
|
children: data
|
|
139
139
|
}) });
|
|
140
140
|
}
|
|
141
|
+
function scroller(el) {
|
|
142
|
+
const { body, documentElement } = el.ownerDocument;
|
|
143
|
+
let position = getComputedStyle(el).position;
|
|
144
|
+
for (let node = el.parentElement; node && node !== body; node = node.parentElement) {
|
|
145
|
+
if (position === "fixed") return null;
|
|
146
|
+
const style = getComputedStyle(node);
|
|
147
|
+
if (position === "absolute" && style.position === "static") continue;
|
|
148
|
+
if (node !== documentElement && /auto|scroll|overlay/.test(style.overflowY) && node.scrollHeight > node.clientHeight) return node;
|
|
149
|
+
position = style.position;
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
141
153
|
function useNearViewport(ref) {
|
|
142
154
|
const [near, setNear] = useState(typeof IntersectionObserver === "undefined");
|
|
143
155
|
useEffect(() => {
|
|
@@ -145,7 +157,10 @@ function useNearViewport(ref) {
|
|
|
145
157
|
if (near || !el) return;
|
|
146
158
|
const observer = new IntersectionObserver((entries) => {
|
|
147
159
|
if (entries.some((entry) => entry.isIntersecting)) setNear(true);
|
|
148
|
-
}, {
|
|
160
|
+
}, {
|
|
161
|
+
root: scroller(el),
|
|
162
|
+
rootMargin: "200% 0px"
|
|
163
|
+
});
|
|
149
164
|
observer.observe(el);
|
|
150
165
|
return () => observer.disconnect();
|
|
151
166
|
}, [ref, near]);
|
package/dist/icons.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { ReactNode, SVGProps } from 'react';
|
|
2
|
+
export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
|
|
3
|
+
/** Width and height; the text's size by default. */
|
|
4
|
+
size?: string | number | undefined;
|
|
4
5
|
/** Names the icon for assistive technology. Without it, or an `aria-label`,
|
|
5
6
|
* the icon is decoration and hidden from assistive technology. */
|
|
6
7
|
title?: string | undefined;
|