@domicile-desktop/component-library 0.0.0-alpha-7a29c8f7f7ea → 0.0.0-alpha-63728a988cfd
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 +14 -3
- package/src/AnimatedCaretIcon/AnimatedCaretIcon.tsx +74 -0
- package/src/AnimatedCloseIcon/AnimatedCloseIcon.tsx +49 -0
- package/src/AnimatedDownloadIcon/AnimatedDownloadIcon.tsx +50 -0
- package/src/AnimatedFloatIcon/AnimatedFloatIcon.tsx +171 -0
- package/src/AnimatedLayoutIcon/AnimatedLayoutIcon.tsx +142 -0
- package/src/AnimatedLockIcon/AnimatedLockIcon.tsx +51 -0
- package/src/AnimatedMaximizeIcon/AnimatedMaximizeIcon.tsx +97 -0
- package/src/AnimatedMinusIcon/AnimatedMinusIcon.tsx +34 -0
- package/src/AnimatedPlusIcon/AnimatedPlusIcon.tsx +49 -0
- package/src/AnimatedReloadIcon/AnimatedReloadIcon.tsx +93 -0
- package/src/AnimatedSlidersIcon/AnimatedSlidersIcon.tsx +78 -0
- package/src/AnimatedSquaresIcon/AnimatedSquaresIcon.tsx +13 -31
- package/src/_icon/IconPart.tsx +8 -0
- package/src/_icon/diagonals.ts +11 -0
- package/src/_icon/icon-keyframes.ts +53 -3
- package/src/_icon/phosphor-parts.ts +46 -0
- package/src/_icon/redrawn-parts.ts +128 -0
- package/styled-system/types/prop-type.d.ts +1 -1
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-63728a988cfd",
|
|
6
|
+
"@domicile-desktop/system-apps": "0.0.0-alpha-63728a988cfd",
|
|
7
7
|
"@pandacss/dev": "^1.12.1",
|
|
8
8
|
"@phosphor-icons/react": "^2.1.10"
|
|
9
9
|
},
|
|
@@ -36,13 +36,24 @@
|
|
|
36
36
|
"./Accordion": "./src/Accordion/Accordion.tsx",
|
|
37
37
|
"./AnimatedBellIcon": "./src/AnimatedBellIcon/AnimatedBellIcon.tsx",
|
|
38
38
|
"./AnimatedBluetoothIcon": "./src/AnimatedBluetoothIcon/AnimatedBluetoothIcon.tsx",
|
|
39
|
+
"./AnimatedCaretIcon": "./src/AnimatedCaretIcon/AnimatedCaretIcon.tsx",
|
|
39
40
|
"./AnimatedChatIcon": "./src/AnimatedChatIcon/AnimatedChatIcon.tsx",
|
|
40
41
|
"./AnimatedCheckIcon": "./src/AnimatedCheckIcon/AnimatedCheckIcon.tsx",
|
|
42
|
+
"./AnimatedCloseIcon": "./src/AnimatedCloseIcon/AnimatedCloseIcon.tsx",
|
|
43
|
+
"./AnimatedDownloadIcon": "./src/AnimatedDownloadIcon/AnimatedDownloadIcon.tsx",
|
|
41
44
|
"./AnimatedEyeIcon": "./src/AnimatedEyeIcon/AnimatedEyeIcon.tsx",
|
|
45
|
+
"./AnimatedFloatIcon": "./src/AnimatedFloatIcon/AnimatedFloatIcon.tsx",
|
|
42
46
|
"./AnimatedGearIcon": "./src/AnimatedGearIcon/AnimatedGearIcon.tsx",
|
|
43
47
|
"./AnimatedKeyboardIcon": "./src/AnimatedKeyboardIcon/AnimatedKeyboardIcon.tsx",
|
|
48
|
+
"./AnimatedLayoutIcon": "./src/AnimatedLayoutIcon/AnimatedLayoutIcon.tsx",
|
|
44
49
|
"./AnimatedLightningIcon": "./src/AnimatedLightningIcon/AnimatedLightningIcon.tsx",
|
|
50
|
+
"./AnimatedLockIcon": "./src/AnimatedLockIcon/AnimatedLockIcon.tsx",
|
|
51
|
+
"./AnimatedMaximizeIcon": "./src/AnimatedMaximizeIcon/AnimatedMaximizeIcon.tsx",
|
|
45
52
|
"./AnimatedMicrophoneIcon": "./src/AnimatedMicrophoneIcon/AnimatedMicrophoneIcon.tsx",
|
|
53
|
+
"./AnimatedMinusIcon": "./src/AnimatedMinusIcon/AnimatedMinusIcon.tsx",
|
|
54
|
+
"./AnimatedPlusIcon": "./src/AnimatedPlusIcon/AnimatedPlusIcon.tsx",
|
|
55
|
+
"./AnimatedReloadIcon": "./src/AnimatedReloadIcon/AnimatedReloadIcon.tsx",
|
|
56
|
+
"./AnimatedSlidersIcon": "./src/AnimatedSlidersIcon/AnimatedSlidersIcon.tsx",
|
|
46
57
|
"./AnimatedSpeakerIcon": "./src/AnimatedSpeakerIcon/AnimatedSpeakerIcon.tsx",
|
|
47
58
|
"./AnimatedSquaresIcon": "./src/AnimatedSquaresIcon/AnimatedSquaresIcon.tsx",
|
|
48
59
|
"./AnimatedThemeIcon": "./src/AnimatedThemeIcon/AnimatedThemeIcon.tsx",
|
|
@@ -146,5 +157,5 @@
|
|
|
146
157
|
"test:unit": "bun test"
|
|
147
158
|
},
|
|
148
159
|
"type": "module",
|
|
149
|
-
"version": "0.0.0-alpha-
|
|
160
|
+
"version": "0.0.0-alpha-63728a988cfd"
|
|
150
161
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
import { css } from "../../styled-system/css";
|
|
4
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
5
|
+
import { IconPart } from "../_icon/IconPart";
|
|
6
|
+
import { CARET_REGULAR } from "../_icon/redrawn-parts";
|
|
7
|
+
|
|
8
|
+
/** Which way the caret points. */
|
|
9
|
+
export type CaretPointing = keyof typeof CARET_REGULAR;
|
|
10
|
+
|
|
11
|
+
/** The way each pointing darts. Physical, since the icon does not mirror. */
|
|
12
|
+
const DARTS: Record<CaretPointing, readonly [number, number]> = {
|
|
13
|
+
down: [0, 1],
|
|
14
|
+
left: [-1, 0],
|
|
15
|
+
right: [1, 0],
|
|
16
|
+
up: [0, -1],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** Each arm turns toward the other, sharpening the point. */
|
|
20
|
+
const SWINGS = [
|
|
21
|
+
[1, 0],
|
|
22
|
+
[-1, 0],
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
type Props = {
|
|
26
|
+
/** Names the icon; without one it is decorative. */
|
|
27
|
+
label?: string | undefined;
|
|
28
|
+
pointing: CaretPointing;
|
|
29
|
+
size: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Phosphor's regular carets. While the control it is in is pointed at, its
|
|
34
|
+
* point sharpens and darts the way it points.
|
|
35
|
+
*/
|
|
36
|
+
export const AnimatedCaretIcon = ({ label, pointing, size }: Props) => {
|
|
37
|
+
const { arms, tip } = CARET_REGULAR[pointing];
|
|
38
|
+
const [x, y] = DARTS[pointing];
|
|
39
|
+
return (
|
|
40
|
+
<IconFrame label={label} size={size}>
|
|
41
|
+
<g
|
|
42
|
+
className={dartStyles}
|
|
43
|
+
style={{ "--part-x": x, "--part-y": y } as CSSProperties}
|
|
44
|
+
>
|
|
45
|
+
{arms.map((d, index) => (
|
|
46
|
+
<IconPart
|
|
47
|
+
d={d}
|
|
48
|
+
direction={SWINGS[index]}
|
|
49
|
+
hoverStyles={sharpenStyles}
|
|
50
|
+
key={d}
|
|
51
|
+
name="arm"
|
|
52
|
+
order={index}
|
|
53
|
+
origin={tip}
|
|
54
|
+
/>
|
|
55
|
+
))}
|
|
56
|
+
</g>
|
|
57
|
+
</IconFrame>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const dartStyles = css({
|
|
62
|
+
_controlHover: {
|
|
63
|
+
animation: "iconPartSpread {durations.slower} {easings.in-out}",
|
|
64
|
+
},
|
|
65
|
+
"--spread": "10px",
|
|
66
|
+
"[data-reduced-motion] &": { animationName: "none !important" },
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const sharpenStyles = css({
|
|
70
|
+
_controlHover: {
|
|
71
|
+
animation: "iconArmSwing {durations.slower} {easings.in-out}",
|
|
72
|
+
},
|
|
73
|
+
"--swing": "9deg",
|
|
74
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { X_BOLD, X_REGULAR } from "../_icon/redrawn-parts";
|
|
5
|
+
|
|
6
|
+
/** Which way each stroke swings as the X snips. */
|
|
7
|
+
const SWINGS = [
|
|
8
|
+
[-1, 0],
|
|
9
|
+
[1, 0],
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
const ARMS = { bold: X_BOLD.arms, regular: X_REGULAR.arms };
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
/** Names the icon; without one it is decorative. */
|
|
16
|
+
label?: string | undefined;
|
|
17
|
+
size: number;
|
|
18
|
+
weight?: keyof typeof ARMS | undefined;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Phosphor's `X`. Its two strokes snip, like scissors, while the control it
|
|
23
|
+
* is in is pointed at.
|
|
24
|
+
*/
|
|
25
|
+
export const AnimatedCloseIcon = ({
|
|
26
|
+
label,
|
|
27
|
+
size,
|
|
28
|
+
weight = "regular",
|
|
29
|
+
}: Props) => (
|
|
30
|
+
<IconFrame label={label} size={size}>
|
|
31
|
+
{ARMS[weight].map((d, index) => (
|
|
32
|
+
<IconPart
|
|
33
|
+
d={d}
|
|
34
|
+
direction={SWINGS[index]}
|
|
35
|
+
hoverStyles={snipStyles}
|
|
36
|
+
key={d}
|
|
37
|
+
name="arm"
|
|
38
|
+
order={index}
|
|
39
|
+
/>
|
|
40
|
+
))}
|
|
41
|
+
</IconFrame>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const snipStyles = css({
|
|
45
|
+
_controlHover: {
|
|
46
|
+
animation: "iconArmSwing {durations.slower} {easings.in-out}",
|
|
47
|
+
},
|
|
48
|
+
"--swing": "14deg",
|
|
49
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { DOWNLOAD_REGULAR } from "../_icon/phosphor-parts";
|
|
5
|
+
import { useCue } from "../_icon/useCue";
|
|
6
|
+
|
|
7
|
+
/** The tray's floor, which it gives toward. */
|
|
8
|
+
const FLOOR = [128, 216] as const;
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
/** Drops the arrow again each time it changes, such as for a new download. */
|
|
12
|
+
cue?: unknown;
|
|
13
|
+
/** Names the icon; without one it is decorative. */
|
|
14
|
+
label?: string | undefined;
|
|
15
|
+
size: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Phosphor's regular `DownloadSimple`. Its arrow drops into the tray when it
|
|
20
|
+
* appears and on each cue, and the tray gives under it.
|
|
21
|
+
*/
|
|
22
|
+
export const AnimatedDownloadIcon = ({ cue, label, size }: Props) => {
|
|
23
|
+
const cued = useCue(cue);
|
|
24
|
+
return (
|
|
25
|
+
<IconFrame label={label} size={size}>
|
|
26
|
+
<IconPart
|
|
27
|
+
cue={cued}
|
|
28
|
+
cueStyles={giveStyles}
|
|
29
|
+
d={DOWNLOAD_REGULAR.tray}
|
|
30
|
+
name="tray"
|
|
31
|
+
origin={FLOOR}
|
|
32
|
+
/>
|
|
33
|
+
<IconPart
|
|
34
|
+
cue={cued}
|
|
35
|
+
cueStyles={dropStyles}
|
|
36
|
+
d={DOWNLOAD_REGULAR.arrow}
|
|
37
|
+
name="arrow"
|
|
38
|
+
/>
|
|
39
|
+
</IconFrame>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Not keyed on `data-cued`: the drop also plays when the icon appears.
|
|
44
|
+
const dropStyles = css({
|
|
45
|
+
animation: "iconDownloadDrop {durations.slowest} {easings.out}",
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const giveStyles = css({
|
|
49
|
+
animation: "iconTrayGive {durations.slowest} {easings.out}",
|
|
50
|
+
});
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { useId } from "react";
|
|
2
|
+
|
|
3
|
+
import { css } from "../../styled-system/css";
|
|
4
|
+
import { DIAGONALS } from "../_icon/diagonals";
|
|
5
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
6
|
+
import { IconPart } from "../_icon/IconPart";
|
|
7
|
+
import { SQUARES_REGULAR } from "../_icon/phosphor-parts";
|
|
8
|
+
import { BROWSERS_REGULAR } from "../_icon/redrawn-parts";
|
|
9
|
+
|
|
10
|
+
/** The centers of the squares, which they shrink about. */
|
|
11
|
+
const SQUARE_CENTERS = [
|
|
12
|
+
[80, 80],
|
|
13
|
+
[176, 80],
|
|
14
|
+
[80, 176],
|
|
15
|
+
[176, 176],
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
/** The center of the window in front. */
|
|
19
|
+
const FRONT_CENTER = [112, 144] as const;
|
|
20
|
+
|
|
21
|
+
/** The way the window in front lifts, and the one behind the other way. */
|
|
22
|
+
const FRONT_LIFT = [-1, 1] as const;
|
|
23
|
+
const BACK_LIFT = [1, -1] as const;
|
|
24
|
+
|
|
25
|
+
type Props = {
|
|
26
|
+
/** Whether the window floats: the icon then offers to tile it. */
|
|
27
|
+
floating: boolean;
|
|
28
|
+
/** Names the icon; without one it is decorative. */
|
|
29
|
+
label?: string | undefined;
|
|
30
|
+
size: number;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Phosphor's regular `Browsers` while a window is tiled, to float it, and
|
|
35
|
+
* its `SquaresFour` while it floats, to tile it. Pointed at, the windows
|
|
36
|
+
* lift apart or the squares part. On a change the windows gather into the
|
|
37
|
+
* squares, or the window behind slides out from the one in front.
|
|
38
|
+
*/
|
|
39
|
+
export const AnimatedFloatIcon = ({ floating, label, size }: Props) => {
|
|
40
|
+
const maskId = useId();
|
|
41
|
+
const windows = floating ? "hidden" : "shown";
|
|
42
|
+
const squares = floating ? "shown" : "hidden";
|
|
43
|
+
return (
|
|
44
|
+
<IconFrame label={label} size={size}>
|
|
45
|
+
<defs>
|
|
46
|
+
{/* Hides the window behind where the one in front covers it. */}
|
|
47
|
+
<mask
|
|
48
|
+
height="320"
|
|
49
|
+
id={maskId}
|
|
50
|
+
maskUnits="userSpaceOnUse"
|
|
51
|
+
width="320"
|
|
52
|
+
x="-32"
|
|
53
|
+
y="-32"
|
|
54
|
+
>
|
|
55
|
+
<rect fill="white" height="320" width="320" x="-32" y="-32" />
|
|
56
|
+
<g fill="black">
|
|
57
|
+
<IconPart
|
|
58
|
+
d={BROWSERS_REGULAR.frontOutline}
|
|
59
|
+
direction={FRONT_LIFT}
|
|
60
|
+
hoverStyles={floating ? undefined : frontLiftStyles}
|
|
61
|
+
name="front-outline"
|
|
62
|
+
/>
|
|
63
|
+
</g>
|
|
64
|
+
</mask>
|
|
65
|
+
</defs>
|
|
66
|
+
<g mask={`url(#${maskId})`}>
|
|
67
|
+
<IconPart
|
|
68
|
+
d={BROWSERS_REGULAR.back}
|
|
69
|
+
direction={BACK_LIFT}
|
|
70
|
+
hoverStyles={floating ? undefined : backLiftStyles}
|
|
71
|
+
name="back"
|
|
72
|
+
state={windows}
|
|
73
|
+
stateStyles={backStyles}
|
|
74
|
+
/>
|
|
75
|
+
</g>
|
|
76
|
+
<IconPart
|
|
77
|
+
d={BROWSERS_REGULAR.front}
|
|
78
|
+
direction={FRONT_LIFT}
|
|
79
|
+
hoverStyles={floating ? undefined : frontLiftStyles}
|
|
80
|
+
name="front"
|
|
81
|
+
origin={FRONT_CENTER}
|
|
82
|
+
state={windows}
|
|
83
|
+
stateStyles={frontStyles}
|
|
84
|
+
/>
|
|
85
|
+
{SQUARES_REGULAR.squares.map((d, index) => (
|
|
86
|
+
<IconPart
|
|
87
|
+
d={d}
|
|
88
|
+
direction={DIAGONALS[index]}
|
|
89
|
+
hoverStyles={floating ? squareSpreadStyles : undefined}
|
|
90
|
+
key={d}
|
|
91
|
+
name="square"
|
|
92
|
+
order={index}
|
|
93
|
+
origin={SQUARE_CENTERS[index]}
|
|
94
|
+
state={squares}
|
|
95
|
+
stateStyles={squareStyles}
|
|
96
|
+
/>
|
|
97
|
+
))}
|
|
98
|
+
</IconFrame>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// The window behind tucks under the one in front before either goes, and
|
|
103
|
+
// slides back out once the one in front is back.
|
|
104
|
+
const backStyles = css({
|
|
105
|
+
"&[data-state=hidden]": {
|
|
106
|
+
opacity: 0,
|
|
107
|
+
transform: "translate(-32px, 32px)",
|
|
108
|
+
transition:
|
|
109
|
+
"opacity {durations.fastest} {easings.linear} {durations.normal}, transform {durations.normal} {easings.in}",
|
|
110
|
+
},
|
|
111
|
+
"&[data-state=shown]": {
|
|
112
|
+
opacity: 1,
|
|
113
|
+
transform: "none",
|
|
114
|
+
transition:
|
|
115
|
+
"opacity {durations.fastest} {easings.linear} {durations.slow}, transform {durations.slower} {easings.outBack} {durations.slow}",
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const frontStyles = css({
|
|
120
|
+
"&[data-state=hidden]": {
|
|
121
|
+
opacity: 0,
|
|
122
|
+
transform: "scale(0.8)",
|
|
123
|
+
transition:
|
|
124
|
+
"opacity {durations.normal} {easings.in} {durations.fast}, transform {durations.normal} {easings.in} {durations.fast}",
|
|
125
|
+
},
|
|
126
|
+
"&[data-state=shown]": {
|
|
127
|
+
opacity: 1,
|
|
128
|
+
transform: "none",
|
|
129
|
+
transition:
|
|
130
|
+
"opacity {durations.normal} {easings.out} {durations.fast}, transform {durations.slow} {easings.out} {durations.fast}",
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// The squares gather into the middle as they go, and come out of it.
|
|
135
|
+
const squareStyles = css({
|
|
136
|
+
"&[data-state=hidden]": {
|
|
137
|
+
opacity: 0,
|
|
138
|
+
transform:
|
|
139
|
+
"translate(calc(var(--part-x) * -30px), calc(var(--part-y) * -30px)) scale(0.6)",
|
|
140
|
+
transition:
|
|
141
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
142
|
+
},
|
|
143
|
+
"&[data-state=shown]": {
|
|
144
|
+
opacity: 1,
|
|
145
|
+
transform: "none",
|
|
146
|
+
transition:
|
|
147
|
+
"opacity {durations.normal} {easings.out} calc({durations.fast} + var(--part-order) * {durations.fastest}), transform {durations.slower} {easings.outBack} calc({durations.fast} + var(--part-order) * {durations.fastest})",
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const backLiftStyles = css({
|
|
152
|
+
_controlHover: {
|
|
153
|
+
animation: "iconPartSpread {durations.slowest} {easings.in-out}",
|
|
154
|
+
},
|
|
155
|
+
"--spread": "12px",
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const frontLiftStyles = css({
|
|
159
|
+
_controlHover: {
|
|
160
|
+
animation: "iconPartSpread {durations.slowest} {easings.in-out}",
|
|
161
|
+
},
|
|
162
|
+
"--spread": "8px",
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const squareSpreadStyles = css({
|
|
166
|
+
_controlHover: {
|
|
167
|
+
animation:
|
|
168
|
+
"iconPartSpread {durations.slowest} {easings.in-out} calc(var(--part-order) * {durations.fastest} / 2)",
|
|
169
|
+
},
|
|
170
|
+
"--spread": "9px",
|
|
171
|
+
});
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { ROWS_REGULAR, TABS_REGULAR } from "../_icon/phosphor-parts";
|
|
5
|
+
import { SQUARE_SPLIT_REGULAR } from "../_icon/redrawn-parts";
|
|
6
|
+
|
|
7
|
+
/** How a group lays out its windows. */
|
|
8
|
+
export type GroupLayout = "column" | "row" | "stack" | "tabs";
|
|
9
|
+
|
|
10
|
+
/** Where the tabs stand, which they rise from. */
|
|
11
|
+
const TABS_BASE = [128, 176] as const;
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
/** Names the icon; without one it is decorative. */
|
|
15
|
+
label?: string | undefined;
|
|
16
|
+
layout: GroupLayout;
|
|
17
|
+
size: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const shownIf = (shown: boolean) => (shown ? "shown" : "hidden");
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A group's layout, in Phosphor's regular icons: `SquareSplitHorizontal`
|
|
24
|
+
* for a row, `SquareSplitVertical` for a column, `Rows` for a stack and
|
|
25
|
+
* `Tabs` for tabs. When the layout changes the new one builds in: the divider draws
|
|
26
|
+
* across, the rows drop in, the tabs rise.
|
|
27
|
+
*/
|
|
28
|
+
export const AnimatedLayoutIcon = ({ label, layout, size }: Props) => {
|
|
29
|
+
const split = layout === "row" || layout === "column";
|
|
30
|
+
return (
|
|
31
|
+
<IconFrame label={label} size={size}>
|
|
32
|
+
<IconPart
|
|
33
|
+
d={SQUARE_SPLIT_REGULAR.frame}
|
|
34
|
+
name="frame"
|
|
35
|
+
state={shownIf(split)}
|
|
36
|
+
stateStyles={fadeStyles}
|
|
37
|
+
/>
|
|
38
|
+
<IconPart
|
|
39
|
+
d={SQUARE_SPLIT_REGULAR.horizontal}
|
|
40
|
+
name="divider"
|
|
41
|
+
state={shownIf(layout === "row")}
|
|
42
|
+
stateStyles={columnDividerStyles}
|
|
43
|
+
/>
|
|
44
|
+
<IconPart
|
|
45
|
+
d={SQUARE_SPLIT_REGULAR.vertical}
|
|
46
|
+
name="divider"
|
|
47
|
+
state={shownIf(layout === "column")}
|
|
48
|
+
stateStyles={rowDividerStyles}
|
|
49
|
+
/>
|
|
50
|
+
{ROWS_REGULAR.rows.map((d, index) => (
|
|
51
|
+
<IconPart
|
|
52
|
+
d={d}
|
|
53
|
+
key={d}
|
|
54
|
+
name="row"
|
|
55
|
+
order={index}
|
|
56
|
+
state={shownIf(layout === "stack")}
|
|
57
|
+
stateStyles={rowStyles}
|
|
58
|
+
/>
|
|
59
|
+
))}
|
|
60
|
+
<IconPart
|
|
61
|
+
d={TABS_REGULAR.tabs}
|
|
62
|
+
name="tabs"
|
|
63
|
+
origin={TABS_BASE}
|
|
64
|
+
state={shownIf(layout === "tabs")}
|
|
65
|
+
stateStyles={tabsStyles}
|
|
66
|
+
/>
|
|
67
|
+
</IconFrame>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const fadeStyles = css({
|
|
72
|
+
"&[data-state=hidden]": {
|
|
73
|
+
opacity: 0,
|
|
74
|
+
transition: "opacity {durations.fast} {easings.in}",
|
|
75
|
+
},
|
|
76
|
+
"&[data-state=shown]": {
|
|
77
|
+
opacity: 1,
|
|
78
|
+
transition: "opacity {durations.normal} {easings.out}",
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Draws down from the middle, across the frame.
|
|
83
|
+
const columnDividerStyles = css({
|
|
84
|
+
"&[data-state=hidden]": {
|
|
85
|
+
opacity: 0,
|
|
86
|
+
transform: "scaleY(0)",
|
|
87
|
+
transition:
|
|
88
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
89
|
+
},
|
|
90
|
+
"&[data-state=shown]": {
|
|
91
|
+
opacity: 1,
|
|
92
|
+
transform: "none",
|
|
93
|
+
transition:
|
|
94
|
+
"opacity {durations.fast} {easings.out} {durations.faster}, transform {durations.slow} {easings.out} {durations.faster}",
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const rowDividerStyles = css({
|
|
99
|
+
"&[data-state=hidden]": {
|
|
100
|
+
opacity: 0,
|
|
101
|
+
transform: "scaleX(0)",
|
|
102
|
+
transition:
|
|
103
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
104
|
+
},
|
|
105
|
+
"&[data-state=shown]": {
|
|
106
|
+
opacity: 1,
|
|
107
|
+
transform: "none",
|
|
108
|
+
transition:
|
|
109
|
+
"opacity {durations.fast} {easings.out} {durations.faster}, transform {durations.slow} {easings.out} {durations.faster}",
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Each row drops in after the one above it.
|
|
114
|
+
const rowStyles = css({
|
|
115
|
+
"&[data-state=hidden]": {
|
|
116
|
+
opacity: 0,
|
|
117
|
+
transform: "translateY(-28px)",
|
|
118
|
+
transition:
|
|
119
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
120
|
+
},
|
|
121
|
+
"&[data-state=shown]": {
|
|
122
|
+
opacity: 1,
|
|
123
|
+
transform: "none",
|
|
124
|
+
transition:
|
|
125
|
+
"opacity {durations.normal} {easings.out} calc({durations.faster} + var(--part-order) * {durations.faster}), transform {durations.slower} {easings.outBack} calc({durations.faster} + var(--part-order) * {durations.faster})",
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const tabsStyles = css({
|
|
130
|
+
"&[data-state=hidden]": {
|
|
131
|
+
opacity: 0,
|
|
132
|
+
transform: "scaleY(0.4)",
|
|
133
|
+
transition:
|
|
134
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
135
|
+
},
|
|
136
|
+
"&[data-state=shown]": {
|
|
137
|
+
opacity: 1,
|
|
138
|
+
transform: "none",
|
|
139
|
+
transition:
|
|
140
|
+
"opacity {durations.normal} {easings.out} {durations.faster}, transform {durations.slow} {easings.outBack} {durations.faster}",
|
|
141
|
+
},
|
|
142
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { LOCK_REGULAR } from "../_icon/redrawn-parts";
|
|
5
|
+
|
|
6
|
+
/** The keyhole's middle, which it swells about. */
|
|
7
|
+
const KEYHOLE = [128, 152] as const;
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
/** Names the icon; without one it is decorative. */
|
|
11
|
+
label?: string | undefined;
|
|
12
|
+
size: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Phosphor's regular `Lock`. Its shackle snaps shut when it appears, such as
|
|
17
|
+
* when a page turns out to be secure, and lifts a little while the control
|
|
18
|
+
* it is in is pointed at.
|
|
19
|
+
*/
|
|
20
|
+
export const AnimatedLockIcon = ({ label, size }: Props) => (
|
|
21
|
+
<IconFrame label={label} size={size}>
|
|
22
|
+
<IconPart d={LOCK_REGULAR.body} name="body" />
|
|
23
|
+
<IconPart
|
|
24
|
+
d={LOCK_REGULAR.shackle}
|
|
25
|
+
hoverStyles={liftStyles}
|
|
26
|
+
name="shackle"
|
|
27
|
+
stateStyles={shutStyles}
|
|
28
|
+
/>
|
|
29
|
+
<IconPart
|
|
30
|
+
d={LOCK_REGULAR.keyhole}
|
|
31
|
+
name="keyhole"
|
|
32
|
+
origin={KEYHOLE}
|
|
33
|
+
stateStyles={pulseStyles}
|
|
34
|
+
/>
|
|
35
|
+
</IconFrame>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const shutStyles = css({
|
|
39
|
+
animation: "iconShackleShut {durations.slower} {easings.out}",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const pulseStyles = css({
|
|
43
|
+
animation:
|
|
44
|
+
"iconKeyholePulse {durations.slow} {easings.in-out} {durations.normal} both",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const liftStyles = css({
|
|
48
|
+
_controlHover: {
|
|
49
|
+
animation: "iconShackleLift {durations.slowest} {easings.in-out}",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { DIAGONALS } from "../_icon/diagonals";
|
|
3
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
4
|
+
import { IconPart } from "../_icon/IconPart";
|
|
5
|
+
import {
|
|
6
|
+
CORNERS_IN_REGULAR,
|
|
7
|
+
CORNERS_OUT_REGULAR,
|
|
8
|
+
} from "../_icon/phosphor-parts";
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
/** Names the icon; without one it is decorative. */
|
|
12
|
+
label?: string | undefined;
|
|
13
|
+
/** Whether the window is maximized: the icon then offers to restore it. */
|
|
14
|
+
maximized: boolean;
|
|
15
|
+
size: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Phosphor's regular `CornersOut` while a window is not maximized, and its
|
|
20
|
+
* `CornersIn` while it is. Pointed at, the corners push out or pull in. On a
|
|
21
|
+
* change they travel that way into the other icon: out to maximize, in to
|
|
22
|
+
* restore.
|
|
23
|
+
*/
|
|
24
|
+
export const AnimatedMaximizeIcon = ({ label, maximized, size }: Props) => (
|
|
25
|
+
<IconFrame label={label} size={size}>
|
|
26
|
+
{CORNERS_OUT_REGULAR.corners.map((d, index) => (
|
|
27
|
+
<IconPart
|
|
28
|
+
d={d}
|
|
29
|
+
direction={DIAGONALS[index]}
|
|
30
|
+
hoverStyles={maximized ? undefined : pushStyles}
|
|
31
|
+
key={d}
|
|
32
|
+
name="corner-out"
|
|
33
|
+
state={maximized ? "hidden" : "shown"}
|
|
34
|
+
stateStyles={outStyles}
|
|
35
|
+
/>
|
|
36
|
+
))}
|
|
37
|
+
{CORNERS_IN_REGULAR.corners.map((d, index) => (
|
|
38
|
+
<IconPart
|
|
39
|
+
d={d}
|
|
40
|
+
direction={DIAGONALS[index]}
|
|
41
|
+
hoverStyles={maximized ? pullStyles : undefined}
|
|
42
|
+
key={d}
|
|
43
|
+
name="corner-in"
|
|
44
|
+
state={maximized ? "shown" : "hidden"}
|
|
45
|
+
stateStyles={inStyles}
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
</IconFrame>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Pointing out, they sit further out while hidden.
|
|
52
|
+
const outStyles = css({
|
|
53
|
+
"&[data-state=hidden]": {
|
|
54
|
+
opacity: 0,
|
|
55
|
+
transform:
|
|
56
|
+
"translate(calc(var(--part-x) * 28px), calc(var(--part-y) * 28px))",
|
|
57
|
+
transition:
|
|
58
|
+
"opacity {durations.normal} {easings.in}, transform {durations.normal} {easings.in}",
|
|
59
|
+
},
|
|
60
|
+
"&[data-state=shown]": {
|
|
61
|
+
opacity: 1,
|
|
62
|
+
transform: "none",
|
|
63
|
+
transition:
|
|
64
|
+
"opacity {durations.normal} {easings.out} {durations.faster}, transform {durations.slower} {easings.outBack} {durations.faster}",
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Pointing in, they sit further in while hidden.
|
|
69
|
+
const inStyles = css({
|
|
70
|
+
"&[data-state=hidden]": {
|
|
71
|
+
opacity: 0,
|
|
72
|
+
transform:
|
|
73
|
+
"translate(calc(var(--part-x) * -28px), calc(var(--part-y) * -28px))",
|
|
74
|
+
transition:
|
|
75
|
+
"opacity {durations.normal} {easings.in}, transform {durations.normal} {easings.in}",
|
|
76
|
+
},
|
|
77
|
+
"&[data-state=shown]": {
|
|
78
|
+
opacity: 1,
|
|
79
|
+
transform: "none",
|
|
80
|
+
transition:
|
|
81
|
+
"opacity {durations.normal} {easings.out} {durations.faster}, transform {durations.slower} {easings.outBack} {durations.faster}",
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const pushStyles = css({
|
|
86
|
+
_controlHover: {
|
|
87
|
+
animation: "iconPartSpread {durations.slowest} {easings.in-out}",
|
|
88
|
+
},
|
|
89
|
+
"--spread": "14px",
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const pullStyles = css({
|
|
93
|
+
_controlHover: {
|
|
94
|
+
animation: "iconPartSpread {durations.slowest} {easings.in-out}",
|
|
95
|
+
},
|
|
96
|
+
"--spread": "-10px",
|
|
97
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { MINUS_BOLD } from "../_icon/redrawn-parts";
|
|
5
|
+
|
|
6
|
+
/** The bar draws in across, the opposite of the plus's arms reaching. */
|
|
7
|
+
const DRAWS_IN = [-1, 0] as const;
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
/** Names the icon; without one it is decorative. */
|
|
11
|
+
label?: string | undefined;
|
|
12
|
+
size: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Phosphor's bold `Minus`. Its bar draws in while the control it is in is
|
|
17
|
+
* pointed at.
|
|
18
|
+
*/
|
|
19
|
+
export const AnimatedMinusIcon = ({ label, size }: Props) => (
|
|
20
|
+
<IconFrame label={label} size={size}>
|
|
21
|
+
<IconPart
|
|
22
|
+
d={MINUS_BOLD.bar}
|
|
23
|
+
direction={DRAWS_IN}
|
|
24
|
+
hoverStyles={drawInStyles}
|
|
25
|
+
name="bar"
|
|
26
|
+
/>
|
|
27
|
+
</IconFrame>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const drawInStyles = css({
|
|
31
|
+
_controlHover: {
|
|
32
|
+
animation: "iconArmReach {durations.slower} {easings.in-out}",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { PLUS_BOLD, PLUS_REGULAR } from "../_icon/redrawn-parts";
|
|
5
|
+
|
|
6
|
+
/** The way each arm reaches: across, then down. */
|
|
7
|
+
const REACHES = [
|
|
8
|
+
[1, 0],
|
|
9
|
+
[0, 1],
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
const ARMS = { bold: PLUS_BOLD.arms, regular: PLUS_REGULAR.arms };
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
/** Names the icon; without one it is decorative. */
|
|
16
|
+
label?: string | undefined;
|
|
17
|
+
size: number;
|
|
18
|
+
weight?: keyof typeof ARMS | undefined;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Phosphor's `Plus`. Its arms reach out, one after the other, while
|
|
23
|
+
* the control it is in is pointed at.
|
|
24
|
+
*/
|
|
25
|
+
export const AnimatedPlusIcon = ({
|
|
26
|
+
label,
|
|
27
|
+
size,
|
|
28
|
+
weight = "regular",
|
|
29
|
+
}: Props) => (
|
|
30
|
+
<IconFrame label={label} size={size}>
|
|
31
|
+
{ARMS[weight].map((d, index) => (
|
|
32
|
+
<IconPart
|
|
33
|
+
d={d}
|
|
34
|
+
direction={REACHES[index]}
|
|
35
|
+
hoverStyles={reachStyles}
|
|
36
|
+
key={d}
|
|
37
|
+
name="arm"
|
|
38
|
+
order={index}
|
|
39
|
+
/>
|
|
40
|
+
))}
|
|
41
|
+
</IconFrame>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const reachStyles = css({
|
|
45
|
+
_controlHover: {
|
|
46
|
+
animation:
|
|
47
|
+
"iconArmReach {durations.slower} {easings.in-out} calc(var(--part-order) * {durations.faster}) both",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { css } from "../../styled-system/css";
|
|
2
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
3
|
+
import { IconPart } from "../_icon/IconPart";
|
|
4
|
+
import { ARROW_CLOCKWISE_REGULAR } from "../_icon/phosphor-parts";
|
|
5
|
+
import { X_REGULAR } from "../_icon/redrawn-parts";
|
|
6
|
+
|
|
7
|
+
/** Which way each of the X's strokes swings. */
|
|
8
|
+
const SWINGS = [
|
|
9
|
+
[-1, 0],
|
|
10
|
+
[1, 0],
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
/** Names the icon; without one it is decorative. */
|
|
15
|
+
label?: string | undefined;
|
|
16
|
+
/** Whether the page is loading: the icon then offers to stop it. */
|
|
17
|
+
loading: boolean;
|
|
18
|
+
size: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Phosphor's regular `ArrowClockwise`, to reload, and its `X` while the page
|
|
23
|
+
* loads, to stop. Pointed at, the arrow winds forward or the X snips. When
|
|
24
|
+
* loading starts the arrow spins away into the X, and it spins back once
|
|
25
|
+
* the page has loaded.
|
|
26
|
+
*/
|
|
27
|
+
export const AnimatedReloadIcon = ({ label, loading, size }: Props) => (
|
|
28
|
+
<IconFrame label={label} size={size}>
|
|
29
|
+
<IconPart
|
|
30
|
+
d={ARROW_CLOCKWISE_REGULAR.arrow}
|
|
31
|
+
hoverStyles={loading ? undefined : windStyles}
|
|
32
|
+
name="arrow"
|
|
33
|
+
state={loading ? "hidden" : "shown"}
|
|
34
|
+
stateStyles={arrowStyles}
|
|
35
|
+
/>
|
|
36
|
+
{X_REGULAR.arms.map((d, index) => (
|
|
37
|
+
<IconPart
|
|
38
|
+
d={d}
|
|
39
|
+
direction={SWINGS[index]}
|
|
40
|
+
hoverStyles={loading ? snipStyles : undefined}
|
|
41
|
+
key={d}
|
|
42
|
+
name="arm"
|
|
43
|
+
order={index}
|
|
44
|
+
state={loading ? "shown" : "hidden"}
|
|
45
|
+
stateStyles={armStyles}
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
</IconFrame>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const arrowStyles = css({
|
|
52
|
+
"&[data-state=hidden]": {
|
|
53
|
+
opacity: 0,
|
|
54
|
+
transform: "rotate(180deg) scale(0.6)",
|
|
55
|
+
transition:
|
|
56
|
+
"opacity {durations.normal} {easings.in}, transform {durations.slow} {easings.in}",
|
|
57
|
+
},
|
|
58
|
+
"&[data-state=shown]": {
|
|
59
|
+
opacity: 1,
|
|
60
|
+
transform: "none",
|
|
61
|
+
transition:
|
|
62
|
+
"opacity {durations.normal} {easings.out} {durations.faster}, transform {durations.slowest} {easings.outBack} {durations.faster}",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Each stroke turns in from its own side.
|
|
67
|
+
const armStyles = css({
|
|
68
|
+
"&[data-state=hidden]": {
|
|
69
|
+
opacity: 0,
|
|
70
|
+
transform: "rotate(calc(var(--part-x) * 45deg)) scale(0.5)",
|
|
71
|
+
transition:
|
|
72
|
+
"opacity {durations.fast} {easings.in}, transform {durations.fast} {easings.in}",
|
|
73
|
+
},
|
|
74
|
+
"&[data-state=shown]": {
|
|
75
|
+
opacity: 1,
|
|
76
|
+
transform: "none",
|
|
77
|
+
transition:
|
|
78
|
+
"opacity {durations.normal} {easings.out} {durations.fast}, transform {durations.slower} {easings.outBack} {durations.fast}",
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const windStyles = css({
|
|
83
|
+
_controlHover: {
|
|
84
|
+
animation: "iconArrowWind {durations.slowest} {easings.in-out}",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const snipStyles = css({
|
|
89
|
+
_controlHover: {
|
|
90
|
+
animation: "iconArmSwing {durations.slower} {easings.in-out}",
|
|
91
|
+
},
|
|
92
|
+
"--swing": "14deg",
|
|
93
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useId } from "react";
|
|
2
|
+
|
|
3
|
+
import { css } from "../../styled-system/css";
|
|
4
|
+
import { IconFrame } from "../_icon/IconFrame";
|
|
5
|
+
import { IconPart } from "../_icon/IconPart";
|
|
6
|
+
import { SLIDERS_REGULAR } from "../_icon/redrawn-parts";
|
|
7
|
+
|
|
8
|
+
/** The way each knob slides: the top one along, the bottom one back. */
|
|
9
|
+
const SLIDES = [
|
|
10
|
+
[1, 0],
|
|
11
|
+
[-1, 0],
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
/** Names the icon; without one it is decorative. */
|
|
16
|
+
label?: string | undefined;
|
|
17
|
+
size: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Phosphor's regular `SlidersHorizontal`. Its knobs slide opposite ways and
|
|
22
|
+
* back while the control it is in is pointed at.
|
|
23
|
+
*/
|
|
24
|
+
export const AnimatedSlidersIcon = ({ label, size }: Props) => {
|
|
25
|
+
const maskId = useId();
|
|
26
|
+
return (
|
|
27
|
+
<IconFrame label={label} size={size}>
|
|
28
|
+
<defs>
|
|
29
|
+
{/* Hide each track where its knob sits, and move with the knob. */}
|
|
30
|
+
{SLIDERS_REGULAR.knobDisks.map((d, index) => (
|
|
31
|
+
<mask
|
|
32
|
+
height="320"
|
|
33
|
+
id={`${maskId}-${index.toString()}`}
|
|
34
|
+
key={d}
|
|
35
|
+
maskUnits="userSpaceOnUse"
|
|
36
|
+
width="320"
|
|
37
|
+
x="-32"
|
|
38
|
+
y="-32"
|
|
39
|
+
>
|
|
40
|
+
<rect fill="white" height="320" width="320" x="-32" y="-32" />
|
|
41
|
+
<g fill="black">
|
|
42
|
+
<IconPart
|
|
43
|
+
d={d}
|
|
44
|
+
direction={SLIDES[index]}
|
|
45
|
+
hoverStyles={slideStyles}
|
|
46
|
+
name="knob-disk"
|
|
47
|
+
order={index}
|
|
48
|
+
/>
|
|
49
|
+
</g>
|
|
50
|
+
</mask>
|
|
51
|
+
))}
|
|
52
|
+
</defs>
|
|
53
|
+
{SLIDERS_REGULAR.tracks.map((d, index) => (
|
|
54
|
+
<g key={d} mask={`url(#${maskId}-${index.toString()})`}>
|
|
55
|
+
<IconPart d={d} name="track" />
|
|
56
|
+
</g>
|
|
57
|
+
))}
|
|
58
|
+
{SLIDERS_REGULAR.knobs.map((d, index) => (
|
|
59
|
+
<IconPart
|
|
60
|
+
d={d}
|
|
61
|
+
direction={SLIDES[index]}
|
|
62
|
+
hoverStyles={slideStyles}
|
|
63
|
+
key={d}
|
|
64
|
+
name="knob"
|
|
65
|
+
order={index}
|
|
66
|
+
/>
|
|
67
|
+
))}
|
|
68
|
+
</IconFrame>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const slideStyles = css({
|
|
73
|
+
_controlHover: {
|
|
74
|
+
animation:
|
|
75
|
+
"iconPartSpread {durations.slowest} {easings.in-out} calc(var(--part-order) * {durations.fastest}) both",
|
|
76
|
+
},
|
|
77
|
+
"--spread": "24px",
|
|
78
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { css } from "../../styled-system/css";
|
|
2
|
+
import { DIAGONALS } from "../_icon/diagonals";
|
|
2
3
|
import { IconFrame } from "../_icon/IconFrame";
|
|
3
4
|
import { IconPart } from "../_icon/IconPart";
|
|
4
5
|
import { SQUARES_REGULAR } from "../_icon/phosphor-parts";
|
|
@@ -18,11 +19,12 @@ export const AnimatedSquaresIcon = ({ label, size }: Props) => (
|
|
|
18
19
|
{SQUARES_REGULAR.squares.map((d, index) => (
|
|
19
20
|
<IconPart
|
|
20
21
|
d={d}
|
|
22
|
+
direction={DIAGONALS[index]}
|
|
21
23
|
hoverStyles={squareSpreadStyles}
|
|
22
24
|
key={d}
|
|
23
25
|
name="square"
|
|
24
26
|
order={index}
|
|
25
|
-
stateStyles={
|
|
27
|
+
stateStyles={squarePressStyles}
|
|
26
28
|
/>
|
|
27
29
|
))}
|
|
28
30
|
</IconFrame>
|
|
@@ -31,36 +33,16 @@ export const AnimatedSquaresIcon = ({ label, size }: Props) => (
|
|
|
31
33
|
const squareSpreadStyles = css({
|
|
32
34
|
_controlHover: {
|
|
33
35
|
animation:
|
|
34
|
-
"
|
|
36
|
+
"iconPartSpread {durations.slowest} {easings.in-out} calc(var(--part-order) * {durations.fastest} / 2)",
|
|
35
37
|
},
|
|
38
|
+
"--spread": "9px",
|
|
36
39
|
});
|
|
37
40
|
|
|
38
|
-
// Each square moves along its
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
transition: "transform {durations.fast} {easings.out}",
|
|
47
|
-
}),
|
|
48
|
-
css({
|
|
49
|
-
_controlActive: { transform: "translate(-5px, 5px)" },
|
|
50
|
-
"--spread-x": "9px",
|
|
51
|
-
"--spread-y": "-9px",
|
|
52
|
-
transition: "transform {durations.fast} {easings.out}",
|
|
53
|
-
}),
|
|
54
|
-
css({
|
|
55
|
-
_controlActive: { transform: "translate(5px, -5px)" },
|
|
56
|
-
"--spread-x": "-9px",
|
|
57
|
-
"--spread-y": "9px",
|
|
58
|
-
transition: "transform {durations.fast} {easings.out}",
|
|
59
|
-
}),
|
|
60
|
-
css({
|
|
61
|
-
_controlActive: { transform: "translate(-5px, -5px)" },
|
|
62
|
-
"--spread-x": "9px",
|
|
63
|
-
"--spread-y": "9px",
|
|
64
|
-
transition: "transform {durations.fast} {easings.out}",
|
|
65
|
-
}),
|
|
66
|
-
];
|
|
41
|
+
// Each square moves in along its diagonal while pressed.
|
|
42
|
+
const squarePressStyles = css({
|
|
43
|
+
_controlActive: {
|
|
44
|
+
transform:
|
|
45
|
+
"translate(calc(var(--part-x) * -5px), calc(var(--part-y) * -5px))",
|
|
46
|
+
},
|
|
47
|
+
transition: "transform {durations.fast} {easings.out}",
|
|
48
|
+
});
|
package/src/_icon/IconPart.tsx
CHANGED
|
@@ -8,6 +8,11 @@ type Props = {
|
|
|
8
8
|
/** The animation each cue plays. */
|
|
9
9
|
cueStyles?: string | undefined;
|
|
10
10
|
d: string;
|
|
11
|
+
/**
|
|
12
|
+
* The way it moves in motions that move parts apart, from -1 to 1 on each
|
|
13
|
+
* axis, as `--part-x` and `--part-y`.
|
|
14
|
+
*/
|
|
15
|
+
direction?: readonly [number, number] | undefined;
|
|
11
16
|
/** The animation played while the control the icon is in is pointed at. */
|
|
12
17
|
hoverStyles?: string | undefined;
|
|
13
18
|
/** What the part is, for styles and tests: "clapper", "arc". */
|
|
@@ -31,6 +36,7 @@ export const IconPart = ({
|
|
|
31
36
|
cue = 0,
|
|
32
37
|
cueStyles,
|
|
33
38
|
d,
|
|
39
|
+
direction = [0, 0],
|
|
34
40
|
hoverStyles,
|
|
35
41
|
name,
|
|
36
42
|
order = 0,
|
|
@@ -46,6 +52,8 @@ export const IconPart = ({
|
|
|
46
52
|
{
|
|
47
53
|
"--part-order": order,
|
|
48
54
|
"--part-origin": `${origin[0].toString()}px ${origin[1].toString()}px`,
|
|
55
|
+
"--part-x": direction[0],
|
|
56
|
+
"--part-y": direction[1],
|
|
49
57
|
} as CSSProperties
|
|
50
58
|
}
|
|
51
59
|
>
|
|
@@ -13,6 +13,25 @@ export const iconKeyframes = {
|
|
|
13
13
|
"0%, 100%": { opacity: "0.25" },
|
|
14
14
|
"50%": { opacity: "1" },
|
|
15
15
|
},
|
|
16
|
+
// A plus's arm reaches out along its direction, and back.
|
|
17
|
+
iconArmReach: {
|
|
18
|
+
"0%, 100%": { transform: "none" },
|
|
19
|
+
"50%": {
|
|
20
|
+
transform:
|
|
21
|
+
"scale(calc(1 + var(--part-x) * 0.18), calc(1 + var(--part-y) * 0.18))",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
// An arm swings `--swing` the way its direction says, and back: an X
|
|
25
|
+
// snipping, a caret's point sharpening.
|
|
26
|
+
iconArmSwing: {
|
|
27
|
+
"0%, 100%": { transform: "none" },
|
|
28
|
+
"50%": { transform: "rotate(calc(var(--part-x) * var(--swing)))" },
|
|
29
|
+
},
|
|
30
|
+
// A reload arrow winds forward, and back.
|
|
31
|
+
iconArrowWind: {
|
|
32
|
+
"0%, 100%": { transform: "none" },
|
|
33
|
+
"50%": { transform: "rotate(40deg)" },
|
|
34
|
+
},
|
|
16
35
|
// The bell's clapper, lagging the swing.
|
|
17
36
|
iconBellClapper: {
|
|
18
37
|
"0%, 100%": { transform: "none" },
|
|
@@ -73,11 +92,22 @@ export const iconKeyframes = {
|
|
|
73
92
|
"0%, 100%": { opacity: "1" },
|
|
74
93
|
"50%": { opacity: "0.25" },
|
|
75
94
|
},
|
|
95
|
+
// A download's arrow drops into its tray.
|
|
96
|
+
iconDownloadDrop: {
|
|
97
|
+
"0%": { opacity: "0", transform: "translateY(-60px)" },
|
|
98
|
+
"70%": { opacity: "1", transform: "translateY(10px)" },
|
|
99
|
+
"100%": { opacity: "1", transform: "none" },
|
|
100
|
+
},
|
|
76
101
|
// The gear turns one tooth. Its six teeth make the end look like the start.
|
|
77
102
|
iconGearTurn: {
|
|
78
103
|
"0%": { transform: "none" },
|
|
79
104
|
"100%": { transform: "rotate(60deg)" },
|
|
80
105
|
},
|
|
106
|
+
// A lock's keyhole swells as its shackle shuts.
|
|
107
|
+
iconKeyholePulse: {
|
|
108
|
+
"0%, 100%": { transform: "none" },
|
|
109
|
+
"50%": { transform: "scale(1.35)" },
|
|
110
|
+
},
|
|
81
111
|
// A key presses down.
|
|
82
112
|
iconKeyPress: {
|
|
83
113
|
"0%, 100%": { transform: "none" },
|
|
@@ -103,6 +133,15 @@ export const iconKeyframes = {
|
|
|
103
133
|
"35%": { transform: "rotate(-12deg)" },
|
|
104
134
|
"70%": { transform: "rotate(5deg)" },
|
|
105
135
|
},
|
|
136
|
+
// A part moves `--spread` out along its direction (see `IconPart`), and
|
|
137
|
+
// back.
|
|
138
|
+
iconPartSpread: {
|
|
139
|
+
"0%, 100%": { transform: "none" },
|
|
140
|
+
"50%": {
|
|
141
|
+
transform:
|
|
142
|
+
"translate(calc(var(--part-x) * var(--spread)), calc(var(--part-y) * var(--spread)))",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
106
145
|
// The eye's pupil looks one way, then the other.
|
|
107
146
|
iconPupilGlance: {
|
|
108
147
|
"0%, 100%": { transform: "none" },
|
|
@@ -123,10 +162,21 @@ export const iconKeyframes = {
|
|
|
123
162
|
"0%, 100%": { transform: "none" },
|
|
124
163
|
"50%": { transform: "scale(0.88)" },
|
|
125
164
|
},
|
|
126
|
-
// A
|
|
127
|
-
|
|
165
|
+
// A lock's shackle lifts a little, and back.
|
|
166
|
+
iconShackleLift: {
|
|
167
|
+
"0%, 100%": { transform: "none" },
|
|
168
|
+
"50%": { transform: "translateY(-14px)" },
|
|
169
|
+
},
|
|
170
|
+
// A lock's shackle snaps shut from open.
|
|
171
|
+
iconShackleShut: {
|
|
172
|
+
"0%": { transform: "translateY(-30px)" },
|
|
173
|
+
"70%": { transform: "translateY(4px)" },
|
|
174
|
+
"100%": { transform: "none" },
|
|
175
|
+
},
|
|
176
|
+
// A download's tray gives under the arrow landing in it.
|
|
177
|
+
iconTrayGive: {
|
|
128
178
|
"0%, 100%": { transform: "none" },
|
|
129
|
-
"
|
|
179
|
+
"70%": { transform: "scaleY(0.86)" },
|
|
130
180
|
},
|
|
131
181
|
// A speaker wave pulls in, for quieter.
|
|
132
182
|
iconWavePull: {
|
|
@@ -168,3 +168,49 @@ export const CHECK_BOLD = {
|
|
|
168
168
|
check:
|
|
169
169
|
"M232.49 80.49L104.49 208.49A12 12 0 0 1 87.49 208.49L31.49 152.49A12 12 0 1 1 48.49 135.49L96 183 215.51 63.51A12 12 0 0 1 232.51 80.51Z",
|
|
170
170
|
} as const;
|
|
171
|
+
|
|
172
|
+
/** CornersOut regular; top start, top end, bottom start, bottom end. */
|
|
173
|
+
export const CORNERS_OUT_REGULAR = {
|
|
174
|
+
corners: [
|
|
175
|
+
"M88 40H48A8 8 0 0 0 40 48V88A8 8 0 0 0 56 88V56H88A8 8 0 0 0 88 40Z",
|
|
176
|
+
"M216 48V88A8 8 0 0 1 200 88V56H168A8 8 0 0 1 168 40H208A8 8 0 0 1 216 48Z",
|
|
177
|
+
"M88 200H56V168A8 8 0 0 0 40 168V208A8 8 0 0 0 48 216H88A8 8 0 0 0 88 200Z",
|
|
178
|
+
"M208 160A8 8 0 0 0 200 168V200H168A8 8 0 0 0 168 216H208A8 8 0 0 0 216 208V168A8 8 0 0 0 208 160Z",
|
|
179
|
+
],
|
|
180
|
+
} as const;
|
|
181
|
+
|
|
182
|
+
/** CornersIn regular; top start, top end, bottom start, bottom end. */
|
|
183
|
+
export const CORNERS_IN_REGULAR = {
|
|
184
|
+
corners: [
|
|
185
|
+
"M96 40A8 8 0 0 0 88 48V88H48A8 8 0 0 0 48 104H96A8 8 0 0 0 104 96V48A8 8 0 0 0 96 40Z",
|
|
186
|
+
"M152 96V48A8 8 0 0 1 168 48V88H208A8 8 0 0 1 208 104H160A8 8 0 0 1 152 96Z",
|
|
187
|
+
"M96 152H48A8 8 0 0 0 48 168H88V208A8 8 0 0 0 104 208V160A8 8 0 0 0 96 152Z",
|
|
188
|
+
"M208 152H160A8 8 0 0 0 152 160V208A8 8 0 0 0 168 208V168H208A8 8 0 0 0 208 152Z",
|
|
189
|
+
],
|
|
190
|
+
} as const;
|
|
191
|
+
|
|
192
|
+
/** Rows regular; top first. */
|
|
193
|
+
export const ROWS_REGULAR = {
|
|
194
|
+
rows: [
|
|
195
|
+
"M208 48H48A16 16 0 0 0 32 64V104A16 16 0 0 0 48 120H208A16 16 0 0 0 224 104V64A16 16 0 0 0 208 48ZM208 104H48V64H208V104Z",
|
|
196
|
+
"M208 136H48A16 16 0 0 0 32 152V192A16 16 0 0 0 48 208H208A16 16 0 0 0 224 192V152A16 16 0 0 0 208 136ZM208 192H48V152H208V192Z",
|
|
197
|
+
],
|
|
198
|
+
} as const;
|
|
199
|
+
|
|
200
|
+
/** Tabs regular. */
|
|
201
|
+
export const TABS_REGULAR = {
|
|
202
|
+
tabs: "M255.66 165.7H255.66V165.7A0.24 0.24 0 0 0 255.66 165.62L233.37 91.4A15.89 15.89 0 0 0 218.05 80H208A8 8 0 0 0 208 96H218.05L237.25 160H206L185.37 91.4A15.89 15.89 0 0 0 170.05 80H160A8 8 0 0 0 160 96H170.05L189.25 160H158L137.37 91.4A15.89 15.89 0 0 0 122.05 80H38A15.89 15.89 0 0 0 22.63 91.4L0.37 165.6 0.37 165.65V165.65S0.37 165.7 0.37 165.73A8.1 8.1 0 0 0 0 168 8 8 0 0 0 8 176H248A8 8 0 0 0 255.66 165.7ZM38 96H122.1L141.3 160H18.75Z",
|
|
203
|
+
} as const;
|
|
204
|
+
|
|
205
|
+
/** ArrowClockwise regular. */
|
|
206
|
+
export const ARROW_CLOCKWISE_REGULAR = {
|
|
207
|
+
arrow:
|
|
208
|
+
"M240 56V104A8 8 0 0 1 232 112H184A8 8 0 0 1 184 96H211.4L184.81 71.64 184.56 71.4A80 80 0 1 0 182.89 186.18 8 8 0 0 1 193.89 197.81 95.44 95.44 0 0 1 128 224H126.68A96 96 0 1 1 195.75 60L224 85.8V56A8 8 0 1 1 240 56Z",
|
|
209
|
+
} as const;
|
|
210
|
+
|
|
211
|
+
/** DownloadSimple regular. */
|
|
212
|
+
export const DOWNLOAD_REGULAR = {
|
|
213
|
+
arrow:
|
|
214
|
+
"M122.34 149.66A8 8 0 0 0 133.66 149.66L173.66 109.66A8 8 0 0 0 162.34 98.34L136 124.69V32A8 8 0 0 0 120 32V124.69L93.66 98.34A8 8 0 0 0 82.34 109.66Z",
|
|
215
|
+
tray: "M224 144V208A8 8 0 0 1 216 216H40A8 8 0 0 1 32 208V144A8 8 0 0 1 48 144V200H208V144A8 8 0 0 1 224 144Z",
|
|
216
|
+
} as const;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phosphor icons whose moving parts Phosphor merges into one outline, drawn
|
|
3
|
+
* again as separate parts that cover the same ground at rest: each is the
|
|
4
|
+
* same strokes and boxes, so the outline the parts join into is Phosphor's.
|
|
5
|
+
* As in Phosphor's paths, outlines run counterclockwise and holes clockwise.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** X regular: its two 16-wide strokes, top start first. */
|
|
9
|
+
export const X_REGULAR = {
|
|
10
|
+
arms: [
|
|
11
|
+
"M61.66 50.34L205.66 194.34A8 8 0 0 1 194.34 205.66L50.34 61.66A8 8 0 0 1 61.66 50.34Z",
|
|
12
|
+
"M194.34 50.34A8 8 0 0 1 205.66 61.66L61.66 205.66A8 8 0 0 1 50.34 194.34Z",
|
|
13
|
+
],
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
/** Plus regular: its two 16-wide strokes, across first. */
|
|
17
|
+
export const PLUS_REGULAR = {
|
|
18
|
+
arms: [
|
|
19
|
+
"M40 120H216A8 8 0 0 1 216 136H40A8 8 0 0 1 40 120Z",
|
|
20
|
+
"M120 40A8 8 0 0 1 136 40V216A8 8 0 0 1 120 216Z",
|
|
21
|
+
],
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Browsers regular: the window behind, whole, the window in front, and the
|
|
26
|
+
* front window's outline, which masks the one behind where it overlaps.
|
|
27
|
+
*/
|
|
28
|
+
export const BROWSERS_REGULAR = {
|
|
29
|
+
back: "M216 40H72A16 16 0 0 0 56 56V168A16 16 0 0 0 72 184H216A16 16 0 0 0 232 168V56A16 16 0 0 0 216 40ZM72 56H216V168H72Z",
|
|
30
|
+
front:
|
|
31
|
+
"M184 72H40A16 16 0 0 0 24 88V200A16 16 0 0 0 40 216H184A16 16 0 0 0 200 200V88A16 16 0 0 0 184 72ZM184 88V104H40V88ZM184 200H40V120H184V200Z",
|
|
32
|
+
frontOutline:
|
|
33
|
+
"M184 72H40A16 16 0 0 0 24 88V200A16 16 0 0 0 40 216H184A16 16 0 0 0 200 200V88A16 16 0 0 0 184 72Z",
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* SquareSplitHorizontal and SquareSplitVertical regular: their shared frame,
|
|
38
|
+
* and the divider each draws inside it.
|
|
39
|
+
*/
|
|
40
|
+
export const SQUARE_SPLIT_REGULAR = {
|
|
41
|
+
frame:
|
|
42
|
+
"M200 40H56A16 16 0 0 0 40 56V200A16 16 0 0 0 56 216H200A16 16 0 0 0 216 200V56A16 16 0 0 0 200 40ZM56 56H200V200H56Z",
|
|
43
|
+
horizontal: "M120 56H136V200H120Z",
|
|
44
|
+
vertical: "M56 120H200V136H56Z",
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* CaretLeft, CaretUp, CaretRight and CaretDown regular: their two 16-wide
|
|
49
|
+
* strokes, the one that turns clockwise to meet the other first, and the tip
|
|
50
|
+
* they meet at.
|
|
51
|
+
*/
|
|
52
|
+
export const CARET_REGULAR = {
|
|
53
|
+
down: {
|
|
54
|
+
arms: [
|
|
55
|
+
"M42.34 101.66L122.34 181.66A8 8 0 0 0 133.66 170.34L53.66 90.34A8 8 0 0 0 42.34 101.66Z",
|
|
56
|
+
"M133.66 181.66L213.66 101.66A8 8 0 0 0 202.34 90.34L122.34 170.34A8 8 0 0 0 133.66 181.66Z",
|
|
57
|
+
],
|
|
58
|
+
tip: [128, 176],
|
|
59
|
+
},
|
|
60
|
+
left: {
|
|
61
|
+
arms: [
|
|
62
|
+
"M154.34 42.34L74.34 122.34A8 8 0 0 0 85.66 133.66L165.66 53.66A8 8 0 0 0 154.34 42.34Z",
|
|
63
|
+
"M74.34 133.66L154.34 213.66A8 8 0 0 0 165.66 202.34L85.66 122.34A8 8 0 0 0 74.34 133.66Z",
|
|
64
|
+
],
|
|
65
|
+
tip: [80, 128],
|
|
66
|
+
},
|
|
67
|
+
right: {
|
|
68
|
+
arms: [
|
|
69
|
+
"M101.66 213.66L181.66 133.66A8 8 0 0 0 170.34 122.34L90.34 202.34A8 8 0 0 0 101.66 213.66Z",
|
|
70
|
+
"M181.66 122.34L101.66 42.34A8 8 0 0 0 90.34 53.66L170.34 133.66A8 8 0 0 0 181.66 122.34Z",
|
|
71
|
+
],
|
|
72
|
+
tip: [176, 128],
|
|
73
|
+
},
|
|
74
|
+
up: {
|
|
75
|
+
arms: [
|
|
76
|
+
"M213.66 154.34L133.66 74.34A8 8 0 0 0 122.34 85.66L202.34 165.66A8 8 0 0 0 213.66 154.34Z",
|
|
77
|
+
"M122.34 74.34L42.34 154.34A8 8 0 0 0 53.66 165.66L133.66 85.66A8 8 0 0 0 122.34 74.34Z",
|
|
78
|
+
],
|
|
79
|
+
tip: [128, 80],
|
|
80
|
+
},
|
|
81
|
+
} as const;
|
|
82
|
+
|
|
83
|
+
/** X bold: its two 24-wide strokes, top start first. */
|
|
84
|
+
export const X_BOLD = {
|
|
85
|
+
arms: [
|
|
86
|
+
"M47.51 64.49L191.51 208.49A12 12 0 0 0 208.49 191.51L64.49 47.51A12 12 0 0 0 47.51 64.49Z",
|
|
87
|
+
"M191.51 47.51L47.51 191.51A12 12 0 0 0 64.49 208.49L208.49 64.49A12 12 0 0 0 191.51 47.51Z",
|
|
88
|
+
],
|
|
89
|
+
} as const;
|
|
90
|
+
|
|
91
|
+
/** Plus bold: its two 24-wide strokes, across first. */
|
|
92
|
+
export const PLUS_BOLD = {
|
|
93
|
+
arms: [
|
|
94
|
+
"M40 140L216 140A12 12 0 0 0 216 116L40 116A12 12 0 0 0 40 140Z",
|
|
95
|
+
"M116 40L116 216A12 12 0 0 0 140 216L140 40A12 12 0 0 0 116 40Z",
|
|
96
|
+
],
|
|
97
|
+
} as const;
|
|
98
|
+
|
|
99
|
+
/** Minus bold: its one 24-wide stroke. */
|
|
100
|
+
export const MINUS_BOLD = {
|
|
101
|
+
bar: "M40 140L216 140A12 12 0 0 0 216 116L40 116A12 12 0 0 0 40 140Z",
|
|
102
|
+
} as const;
|
|
103
|
+
|
|
104
|
+
/** Lock regular: its body, its shackle and its keyhole. */
|
|
105
|
+
export const LOCK_REGULAR = {
|
|
106
|
+
body: "M208 80H48A16 16 0 0 0 32 96V208A16 16 0 0 0 48 224H208A16 16 0 0 0 224 208V96A16 16 0 0 0 208 80ZM208 208H48V96H208V208Z",
|
|
107
|
+
keyhole: "M140 152A12 12 0 1 1 128 140 12 12 0 0 1 140 152Z",
|
|
108
|
+
shackle: "M80 80V56A48 48 0 0 1 176 56V80H160V56A32 32 0 0 0 96 56V80Z",
|
|
109
|
+
} as const;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* SlidersHorizontal regular: its tracks and knobs, top first, and each
|
|
113
|
+
* knob's disk, which masks its track where the knob sits.
|
|
114
|
+
*/
|
|
115
|
+
export const SLIDERS_REGULAR = {
|
|
116
|
+
knobDisks: [
|
|
117
|
+
"M136 80A32 32 0 1 0 72 80A32 32 0 1 0 136 80Z",
|
|
118
|
+
"M200 176A32 32 0 1 0 136 176A32 32 0 1 0 200 176Z",
|
|
119
|
+
],
|
|
120
|
+
knobs: [
|
|
121
|
+
"M136 80A32 32 0 1 0 72 80A32 32 0 1 0 136 80ZM120 80A16 16 0 1 1 88 80A16 16 0 1 1 120 80Z",
|
|
122
|
+
"M200 176A32 32 0 1 0 136 176A32 32 0 1 0 200 176ZM184 176A16 16 0 1 1 152 176A16 16 0 1 1 184 176Z",
|
|
123
|
+
],
|
|
124
|
+
tracks: [
|
|
125
|
+
"M40 88L216 88A8 8 0 0 0 216 72L40 72A8 8 0 0 0 40 88Z",
|
|
126
|
+
"M40 184L216 184A8 8 0 0 0 216 168L40 168A8 8 0 0 0 40 184Z",
|
|
127
|
+
],
|
|
128
|
+
} as const;
|
|
@@ -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" | "iconArcRipple" | "iconArcSearch" | "iconBellClapper" | "iconBellNudge" | "iconBellSwing" | "iconBoltStrike" | "iconBubbleTip" | "iconCapsuleBob" | "iconCheckDraw" | "iconCoreIn" | "iconCoreOut" | "iconDotBlink" | "iconGearTurn" | "iconKeyPress" | "iconLineWrite" | "iconMoonIn" | "iconMoonOut" | "iconMoonRock" | "iconPupilGlance" | "iconRayIn" | "iconRayOut" | "iconRayPulse" | "
|
|
172
|
+
animationName: "ping" | "bounce" | "iconArcRipple" | "iconArcSearch" | "iconArmReach" | "iconArmSwing" | "iconArrowWind" | "iconBellClapper" | "iconBellNudge" | "iconBellSwing" | "iconBoltStrike" | "iconBubbleTip" | "iconCapsuleBob" | "iconCheckDraw" | "iconCoreIn" | "iconCoreOut" | "iconDotBlink" | "iconDownloadDrop" | "iconGearTurn" | "iconKeyholePulse" | "iconKeyPress" | "iconLineWrite" | "iconMoonIn" | "iconMoonOut" | "iconMoonRock" | "iconPartSpread" | "iconPupilGlance" | "iconRayIn" | "iconRayOut" | "iconRayPulse" | "iconShackleLift" | "iconShackleShut" | "iconTrayGive" | "iconWavePull" | "iconWavePush" | "levelToastEnter" | "levelToastHold" | "levelToastHoldAgain" | "noticeShown" | "pulse" | "spin" | "themeSwipeFromBottom" | "themeSwipeFromTop" | "toastCountdown";
|
|
173
173
|
animationTimingFunction: Tokens["easings"];
|
|
174
174
|
animationDuration: Tokens["durations"];
|
|
175
175
|
animationDelay: Tokens["durations"];
|