@domicile-desktop/component-library 0.0.0-alpha-3e5b976f2009 → 0.0.0-alpha-db2937ff6ccf
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
CHANGED
|
@@ -30,6 +30,7 @@ Each export is `@domicile-desktop/component-library/<name>`.
|
|
|
30
30
|
| `Kbd` | Keyboard key cap. |
|
|
31
31
|
| `list-walk` | Arrow-key movement of a highlight through a list while focus stays in an input. |
|
|
32
32
|
| `ModalDialog` | Modal dialog with `title`, `footer` and `trigger` props. |
|
|
33
|
+
| `Notice` | Pill that briefly shows a change, such as a zoom level or volume, with an optional level meter. Key it per change. |
|
|
33
34
|
| `ContextMenu` | Menu opened at a point, such as a right click's. Parts: `Item`, `CheckboxItem`, `RadioGroup` and `RadioItem`, `Submenu`, `Separator`. Items take an `icon` and a `mnemonic`, whose letter chooses them. |
|
|
34
35
|
| `PortalDialogs` | Every dialog applications ask for through the desktop portal. Mount one per shell with `host={domicile}`; it refuses kinds it cannot draw. `omitScreenCasts` leaves screen casts out of its indicator. See [PORTALS.md](/docs/PORTALS.md). |
|
|
35
36
|
| `source-name` | `sourceName`: how a screen cast's source is named. |
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@base-ui/react": "^1.8.0",
|
|
4
4
|
"@cprussin/option-result": "^2.0.1",
|
|
5
|
-
"@domicile-desktop/sdk": "0.0.0-alpha-
|
|
6
|
-
"@domicile-desktop/system-apps": "0.0.0-alpha-
|
|
5
|
+
"@domicile-desktop/sdk": "0.0.0-alpha-db2937ff6ccf",
|
|
6
|
+
"@domicile-desktop/system-apps": "0.0.0-alpha-db2937ff6ccf",
|
|
7
7
|
"@pandacss/dev": "^1.12.1",
|
|
8
8
|
"@phosphor-icons/react": "^2.1.10"
|
|
9
9
|
},
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"./list-walk": "./src/list-walk.ts",
|
|
56
56
|
"./ModalDialog": "./src/ModalDialog/ModalDialog.tsx",
|
|
57
57
|
"./media-theme-source": "./src/ThemeSwitch/media-theme-source.ts",
|
|
58
|
+
"./Notice": "./src/Notice/Notice.tsx",
|
|
58
59
|
"./Popover": "./src/Popover/Popover.tsx",
|
|
59
60
|
"./PortalDialogs": "./src/PortalDialogs/PortalDialogs.tsx",
|
|
60
61
|
"./Provider": "./src/Provider/Provider.tsx",
|
|
@@ -114,5 +115,5 @@
|
|
|
114
115
|
"test:unit": "bun test"
|
|
115
116
|
},
|
|
116
117
|
"type": "module",
|
|
117
|
-
"version": "0.0.0-alpha-
|
|
118
|
+
"version": "0.0.0-alpha-db2937ff6ccf"
|
|
118
119
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { css } from "../../styled-system/css";
|
|
4
|
+
import { hstack } from "../../styled-system/patterns";
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
/** What the notice is about, such as the label's new value. */
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
/** Drawn before the label. */
|
|
10
|
+
icon: ReactNode;
|
|
11
|
+
/** A level from 0 to 1, drawn as a meter after the label. */
|
|
12
|
+
level?: number | undefined;
|
|
13
|
+
/** Grays the meter, such as for muted audio. */
|
|
14
|
+
muted?: boolean | undefined;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A pill that briefly shows a change, such as a new zoom level or volume, then
|
|
19
|
+
* fades out.
|
|
20
|
+
*
|
|
21
|
+
* It hides on `animationend`, not a timer, so the duration lives only in the
|
|
22
|
+
* stylesheet. Key it per change to show it again. The caller positions it; it
|
|
23
|
+
* ignores the pointer so it never blocks what is under it.
|
|
24
|
+
*/
|
|
25
|
+
export const Notice = ({ children, icon, level, muted }: Props) => {
|
|
26
|
+
const [showing, setShowing] = useState(true);
|
|
27
|
+
|
|
28
|
+
return showing ? (
|
|
29
|
+
<output
|
|
30
|
+
className={noticeStyles}
|
|
31
|
+
onAnimationEnd={() => {
|
|
32
|
+
setShowing(false);
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{icon}
|
|
36
|
+
{children}
|
|
37
|
+
{level === undefined ? undefined : (
|
|
38
|
+
<span
|
|
39
|
+
aria-valuemax={100}
|
|
40
|
+
aria-valuemin={0}
|
|
41
|
+
aria-valuenow={Math.round(level * 100)}
|
|
42
|
+
className={meterStyles}
|
|
43
|
+
data-muted={muted === true ? "" : undefined}
|
|
44
|
+
role="meter"
|
|
45
|
+
// Inline because the level is a runtime value Panda cannot extract.
|
|
46
|
+
style={{ "--notice-level": level } as CSSProperties}
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
</output>
|
|
50
|
+
) : undefined;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Appears quickly, holds long enough to read, then fades out.
|
|
54
|
+
const noticeStyles = hstack({
|
|
55
|
+
animation: "noticeShown {durations.notice} {easings.out} forwards",
|
|
56
|
+
backgroundColor: "card",
|
|
57
|
+
border: "1px solid {colors.border}",
|
|
58
|
+
borderRadius: "full",
|
|
59
|
+
boxShadow: "lifted",
|
|
60
|
+
color: "foreground",
|
|
61
|
+
fontSize: "sm",
|
|
62
|
+
fontVariantNumeric: "tabular-nums",
|
|
63
|
+
gap: 2,
|
|
64
|
+
paddingBlock: 1.5,
|
|
65
|
+
paddingInline: 3,
|
|
66
|
+
pointerEvents: "none",
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// A track with the level filled from the start edge. The fill is a scaled
|
|
70
|
+
// pseudo-element so the level can change without layout.
|
|
71
|
+
const meterStyles = css({
|
|
72
|
+
"&::after": {
|
|
73
|
+
backgroundColor: "accent",
|
|
74
|
+
borderRadius: "full",
|
|
75
|
+
content: '""',
|
|
76
|
+
inset: 0,
|
|
77
|
+
position: "absolute",
|
|
78
|
+
transform: "scaleX(var(--notice-level))",
|
|
79
|
+
transformOrigin: "left",
|
|
80
|
+
},
|
|
81
|
+
"&[data-muted]::after": {
|
|
82
|
+
backgroundColor: "muted",
|
|
83
|
+
},
|
|
84
|
+
backgroundColor: "border",
|
|
85
|
+
blockSize: 1,
|
|
86
|
+
borderRadius: "full",
|
|
87
|
+
inlineSize: 24,
|
|
88
|
+
overflow: "hidden",
|
|
89
|
+
position: "relative",
|
|
90
|
+
});
|
package/src/pandacss-preset.ts
CHANGED
|
@@ -145,6 +145,17 @@ export const domicilePreset = definePreset({
|
|
|
145
145
|
theme: {
|
|
146
146
|
extend: {
|
|
147
147
|
keyframes: {
|
|
148
|
+
// `Notice`: appears quickly, holds long enough to read, then fades
|
|
149
|
+
// out on its own.
|
|
150
|
+
noticeShown: {
|
|
151
|
+
"0%": {
|
|
152
|
+
opacity: "0",
|
|
153
|
+
transform: "translateY(calc(-1 * {spacing.1}))",
|
|
154
|
+
},
|
|
155
|
+
"10%": { opacity: "1", transform: "translateY(0)" },
|
|
156
|
+
"75%": { opacity: "1" },
|
|
157
|
+
"100%": { opacity: "0" },
|
|
158
|
+
},
|
|
148
159
|
pulse: {
|
|
149
160
|
"0%": { opacity: "0.3" },
|
|
150
161
|
"50%": { opacity: "0.7" },
|
|
@@ -384,6 +395,9 @@ export const domicilePreset = definePreset({
|
|
|
384
395
|
durations: {
|
|
385
396
|
// Wallpaper crossfade. Long because nothing waits on it.
|
|
386
397
|
crossfade: { value: "2s" },
|
|
398
|
+
// How long a `Notice` stays up. Longer than the scale above, which
|
|
399
|
+
// is for control feedback, not reading.
|
|
400
|
+
notice: { value: "1.5s" },
|
|
387
401
|
pulse: { value: "1.5s" },
|
|
388
402
|
// One turn of `spin`. A slower spinner looks stuck.
|
|
389
403
|
spin: { value: "1s" },
|
|
@@ -1307,6 +1307,10 @@ const tokens = {
|
|
|
1307
1307
|
"value": "2s",
|
|
1308
1308
|
"variable": "var(--gXQUBH)"
|
|
1309
1309
|
},
|
|
1310
|
+
"durations.notice": {
|
|
1311
|
+
"value": "1.5s",
|
|
1312
|
+
"variable": "var(--infmmp)"
|
|
1313
|
+
},
|
|
1310
1314
|
"durations.pulse": {
|
|
1311
1315
|
"value": "1.5s",
|
|
1312
1316
|
"variable": "var(--YdYTw)"
|
|
@@ -27,7 +27,7 @@ export type AnimationToken = "spin" | "ping" | "pulse" | "bounce"
|
|
|
27
27
|
|
|
28
28
|
export type BorderWidthToken = "fauxBold"
|
|
29
29
|
|
|
30
|
-
export type DurationToken = "fastest" | "faster" | "fast" | "normal" | "slow" | "slower" | "slowest" | "crossfade" | "pulse" | "spin" | "wipe"
|
|
30
|
+
export type DurationToken = "fastest" | "faster" | "fast" | "normal" | "slow" | "slower" | "slowest" | "crossfade" | "notice" | "pulse" | "spin" | "wipe"
|
|
31
31
|
|
|
32
32
|
export type EasingToken = "default" | "linear" | "in" | "out" | "in-out" | "emphasized" | "outBack" | "outQuart"
|
|
33
33
|
|
|
@@ -169,7 +169,7 @@ export interface UtilityValues {
|
|
|
169
169
|
transitionProperty: "common" | "colors" | "size" | "position" | "background";
|
|
170
170
|
transition: "all" | "common" | "size" | "position" | "background" | "colors" | "opacity" | "shadow" | "transform";
|
|
171
171
|
animation: Tokens["animations"];
|
|
172
|
-
animationName: "ping" | "bounce" | "pulse" | "spin" | "themeSwipeFromBottom" | "themeSwipeFromTop" | "toastCountdown";
|
|
172
|
+
animationName: "ping" | "bounce" | "noticeShown" | "pulse" | "spin" | "themeSwipeFromBottom" | "themeSwipeFromTop" | "toastCountdown";
|
|
173
173
|
animationTimingFunction: Tokens["easings"];
|
|
174
174
|
animationDuration: Tokens["durations"];
|
|
175
175
|
animationDelay: Tokens["durations"];
|