@dumiflex/wp-kit 0.3.0 → 0.5.0
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/CHANGELOG.md +92 -51
- package/LICENSE +674 -674
- package/README.md +73 -76
- package/package.json +78 -77
- package/src/Avatar.vue +83 -83
- package/src/Badge.vue +97 -97
- package/src/Banner.vue +118 -118
- package/src/BookmarkButton.vue +27 -27
- package/src/BundleMeta.vue +51 -51
- package/src/Button.vue +103 -103
- package/src/Card.vue +68 -68
- package/src/Checkbox.vue +109 -107
- package/src/Chip.vue +163 -97
- package/src/ChoiceCards.vue +133 -133
- package/src/CloseButton.vue +69 -69
- package/src/CodeBlock.vue +146 -119
- package/src/ColorField.vue +188 -206
- package/src/ColorPicker.vue +201 -201
- package/src/Combobox.vue +331 -334
- package/src/ConfirmDialog.vue +165 -163
- package/src/ConfirmModal.vue +147 -147
- package/src/ConstraintMatrixPreview.vue +708 -708
- package/src/ContextMenu.vue +386 -379
- package/src/CopyButton.vue +156 -156
- package/src/DataTable.vue +293 -292
- package/src/DatePicker.vue +234 -234
- package/src/DescriptionList.vue +73 -73
- package/src/DiffView.vue +68 -68
- package/src/Disclosure.vue +166 -166
- package/src/DragHandle.vue +49 -49
- package/src/Drawer.vue +131 -131
- package/src/DropZone.vue +196 -196
- package/src/DropdownMenu.vue +72 -72
- package/src/EmptyState.vue +111 -111
- package/src/Field.vue +28 -28
- package/src/HsvPicker.vue +208 -208
- package/src/Icon.vue +39 -39
- package/src/IconPicker.vue +209 -209
- package/src/ImageGrid.vue +127 -125
- package/src/InlineEdit.vue +183 -183
- package/src/Input.vue +99 -99
- package/src/Kbd.vue +56 -56
- package/src/Lightbox.vue +176 -173
- package/src/ListFilter.vue +85 -85
- package/src/ListRow.vue +204 -204
- package/src/LoadingMark.vue +217 -161
- package/src/Logo.vue +60 -60
- package/src/Modal.vue +78 -76
- package/src/ModalShell.vue +109 -107
- package/src/Pagination.vue +106 -106
- package/src/Popover.vue +180 -171
- package/src/PostCard.vue +210 -211
- package/src/ProgressBar.vue +90 -90
- package/src/RadioGroup.vue +177 -177
- package/src/RangeSlider.vue +183 -183
- package/src/RelativeDate.vue +35 -35
- package/src/ResizeHandle.vue +143 -143
- package/src/SearchInput.vue +192 -199
- package/src/Select.vue +644 -641
- package/src/Separator.vue +54 -54
- package/src/Skeleton.vue +98 -82
- package/src/Slider.vue +198 -198
- package/src/SortableList.vue +260 -260
- package/src/SplitPane.vue +68 -68
- package/src/StarButton.vue +40 -40
- package/src/Stepper.vue +141 -141
- package/src/SupportLinks.vue +93 -93
- package/src/TagInput.vue +297 -300
- package/src/Textarea.vue +57 -57
- package/src/Timeline.vue +92 -92
- package/src/ToastCard.vue +119 -119
- package/src/ToastHost.vue +40 -40
- package/src/Toggle.vue +36 -36
- package/src/TokenizedValue.vue +310 -310
- package/src/Toolbar.vue +110 -110
- package/src/VirtualList.vue +87 -87
- package/src/VisuallyHidden.vue +29 -29
- package/src/WpButton.vue +75 -75
- package/src/WpCheck.vue +104 -102
- package/src/WpIconButton.vue +107 -107
- package/src/WpImageZoom.vue +544 -544
- package/src/WpNumber.vue +178 -183
- package/src/WpSegmented.vue +175 -175
- package/src/WpSelect.vue +93 -89
- package/src/WpSwitch.vue +163 -163
- package/src/WpTabs.vue +188 -188
- package/src/_modal-motion.css +33 -33
- package/src/_skeleton.css +50 -50
- package/src/axis-color.ts +42 -42
- package/src/button.css +169 -169
- package/src/calendar.ts +59 -59
- package/src/clipboard.ts +50 -50
- package/src/colour-presets.ts +12 -12
- package/src/diff.ts +51 -51
- package/src/drop-zone.ts +41 -41
- package/src/field.css +50 -0
- package/src/flip.ts +237 -237
- package/src/floating-layer.ts +48 -0
- package/src/floating.ts +99 -99
- package/src/highlight.ts +199 -0
- package/src/hsv.ts +100 -100
- package/src/icon-catalog.ts +52 -52
- package/src/image-zoom.ts +93 -93
- package/src/kind-colour.ts +28 -0
- package/src/loading-mark-motion.ts +249 -0
- package/src/logo-paths.ts +21 -21
- package/src/matrix-axis.ts +91 -91
- package/src/pagination.ts +27 -27
- package/src/platform-keys.ts +29 -29
- package/src/rich-tokenize.ts +357 -357
- package/src/select-types.ts +32 -32
- package/src/slider-math.ts +45 -45
- package/src/sortable.ts +22 -22
- package/src/theme/fonts/OFL-Fraunces.txt +93 -93
- package/src/theme/fonts/OFL-JetBrainsMono.txt +93 -93
- package/src/theme/fonts/OFL-Manrope.txt +93 -93
- package/src/theme/looks.css +428 -428
- package/src/theme/palettes.css +254 -254
- package/src/theme/tokens.css +2896 -2894
- package/src/tokens.ts +56 -56
- package/src/tooltip.css +43 -43
- package/src/tooltip.ts +146 -146
- package/src/useDialogFocus.ts +73 -73
- package/src/useGrowableField.ts +357 -357
- package/src/useModalKeyShield.ts +116 -116
- package/src/useToast.ts +48 -48
- package/src/wp-logo.svg +14 -14
- package/src/ChipToggle.vue +0 -92
- package/src/KindChip.vue +0 -53
- package/src/RatingBadge.vue +0 -42
package/src/LoadingMark.vue
CHANGED
|
@@ -1,161 +1,217 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/** Gradient ids must be unique on the page. `useId` restarts per Vue app and
|
|
3
|
-
* the extension mounts many small apps, so count across all of them. */
|
|
4
|
-
let nextId = 0;
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
/**
|
|
9
|
-
* The loading mark. Two drawings, one per kind of place:
|
|
10
|
-
*
|
|
11
|
-
* - `logo` (pages and panels): the full logo. Its two rings slide apart and
|
|
12
|
-
* back while the big star dips and turns and the small stars twinkle. A
|
|
13
|
-
* `block` mark, or one 24 px or bigger, gets it by default.
|
|
14
|
-
* - `sparkle` (tight inline spots: a text row, a button, a list item): the
|
|
15
|
-
* logo's three stars without the rings, the big one dipping while the small
|
|
16
|
-
* ones swap places, like the AI working line. Small marks get it by
|
|
17
|
-
* default, so an inline "Loading bundle…" is not a big colourful logo.
|
|
18
|
-
*
|
|
19
|
-
* Alone it is an icon (`size`, 14 inline and 40 as a block). With slot text it
|
|
20
|
-
* becomes a row ("[mark] Loading bundle…"); with `block` it is centred in its
|
|
21
|
-
* box, for a panel or page that is loading. `mono` draws it in the text
|
|
22
|
-
* colour, for a host with its own colours (a busy button).
|
|
23
|
-
*/
|
|
24
|
-
import { computed, useSlots } from "vue";
|
|
25
|
-
import { BRAND_COLOURS, RING_A, RING_B, STAR_A, STAR_B, STAR_BIG, type LogoBrand } from "./logo-paths";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
</
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/** Gradient ids must be unique on the page. `useId` restarts per Vue app and
|
|
3
|
+
* the extension mounts many small apps, so count across all of them. */
|
|
4
|
+
let nextId = 0;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
/**
|
|
9
|
+
* The loading mark. Two drawings, one per kind of place:
|
|
10
|
+
*
|
|
11
|
+
* - `logo` (pages and panels): the full logo. Its two rings slide apart and
|
|
12
|
+
* back while the big star dips and turns and the small stars twinkle. A
|
|
13
|
+
* `block` mark, or one 24 px or bigger, gets it by default.
|
|
14
|
+
* - `sparkle` (tight inline spots: a text row, a button, a list item): the
|
|
15
|
+
* logo's three stars without the rings, the big one dipping while the small
|
|
16
|
+
* ones swap places, like the AI working line. Small marks get it by
|
|
17
|
+
* default, so an inline "Loading bundle…" is not a big colourful logo.
|
|
18
|
+
*
|
|
19
|
+
* Alone it is an icon (`size`, 14 inline and 40 as a block). With slot text it
|
|
20
|
+
* becomes a row ("[mark] Loading bundle…"); with `block` it is centred in its
|
|
21
|
+
* box, for a panel or page that is loading. `mono` draws it in the text
|
|
22
|
+
* colour, for a host with its own colours (a busy button).
|
|
23
|
+
*/
|
|
24
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref, useSlots } from "vue";
|
|
25
|
+
import { BRAND_COLOURS, RING_A, RING_B, STAR_A, STAR_B, STAR_BIG, type LogoBrand } from "./logo-paths";
|
|
26
|
+
import { BOX, PAD, animate, drawNow, type Animated, type Look } from "./loading-mark-motion";
|
|
27
|
+
|
|
28
|
+
const props = withDefaults(defineProps<{
|
|
29
|
+
/** Width and height in px. Default 14, or 40 with `block`. */
|
|
30
|
+
size?: number | undefined;
|
|
31
|
+
/** Accessible name when there is no slot text. */
|
|
32
|
+
label?: string | undefined;
|
|
33
|
+
/** Centre it (and its text, below) in the space it is given. */
|
|
34
|
+
block?: boolean | undefined;
|
|
35
|
+
/** Which drawing; default `logo` for a block or a 24 px+ mark, else `sparkle`. */
|
|
36
|
+
variant?: "logo" | "sparkle" | undefined;
|
|
37
|
+
/** Draw in the current text colour instead of the logo colours. */
|
|
38
|
+
mono?: boolean | undefined;
|
|
39
|
+
/** Hidden from screen readers, for a host that says it is busy itself
|
|
40
|
+
* (a button with `aria-busy`). */
|
|
41
|
+
decorative?: boolean | undefined;
|
|
42
|
+
/** Whose colours: the extension's (default) or the community site's. */
|
|
43
|
+
brand?: LogoBrand | undefined;
|
|
44
|
+
}>(), { size: undefined, label: "Loading", block: false, variant: undefined, mono: false, decorative: false, brand: "extension" });
|
|
45
|
+
|
|
46
|
+
const slots = useSlots();
|
|
47
|
+
const id = `wp-lm-${nextId++}`;
|
|
48
|
+
const px = computed(() => props.size ?? (props.block ? 40 : 14));
|
|
49
|
+
const drawing = computed(() => props.variant ?? (props.block || px.value >= 24 ? "logo" : "sparkle"));
|
|
50
|
+
/** The logo's own colours (brand, not theme tokens: the mark looks the same
|
|
51
|
+
* in light and dark). */
|
|
52
|
+
const VIOLET = computed(() => BRAND_COLOURS[props.brand][0]);
|
|
53
|
+
const INDIGO = computed(() => BRAND_COLOURS[props.brand][1]);
|
|
54
|
+
const TEAL = computed(() => BRAND_COLOURS[props.brand][2]);
|
|
55
|
+
const fill = (colour: string): string => (props.mono ? "currentColor" : colour);
|
|
56
|
+
|
|
57
|
+
/* The SVG is the still mark (first paint, reduced motion, a page with no
|
|
58
|
+
* canvas). Once mounted, a canvas over it draws the motion: see
|
|
59
|
+
* `loading-mark-motion.ts` for why it is not CSS. */
|
|
60
|
+
const root = ref<HTMLElement | null>(null);
|
|
61
|
+
const canvas = ref<HTMLCanvasElement | null>(null);
|
|
62
|
+
const live = ref(false);
|
|
63
|
+
const drawn = ref(false);
|
|
64
|
+
const canvasStyle = computed(() => {
|
|
65
|
+
const side = (px.value * BOX) / 1024;
|
|
66
|
+
const off = (px.value * PAD) / 1024;
|
|
67
|
+
return { width: `${side}px`, height: `${side}px`, top: `${-off}px`, left: `${-off}px` };
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let textColour = "";
|
|
71
|
+
let textColourAt = -Infinity;
|
|
72
|
+
function look(): Look {
|
|
73
|
+
if (props.mono) {
|
|
74
|
+
const now = performance.now();
|
|
75
|
+
if (now - textColourAt > 500 && root.value) {
|
|
76
|
+
textColour = getComputedStyle(root.value).color || "currentColor";
|
|
77
|
+
textColourAt = now;
|
|
78
|
+
}
|
|
79
|
+
return { variant: drawing.value, colours: [textColour, textColour, textColour], flat: true };
|
|
80
|
+
}
|
|
81
|
+
return { variant: drawing.value, colours: [VIOLET.value, INDIGO.value, TEAL.value], flat: false };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let stop: (() => void) | null = null;
|
|
85
|
+
let observer: IntersectionObserver | null = null;
|
|
86
|
+
let motion: MediaQueryList | null = null;
|
|
87
|
+
|
|
88
|
+
async function start(): Promise<void> {
|
|
89
|
+
if (stop) return;
|
|
90
|
+
live.value = true;
|
|
91
|
+
await nextTick();
|
|
92
|
+
const el = canvas.value;
|
|
93
|
+
if (!el || !live.value) return;
|
|
94
|
+
const mark: Animated = { canvas: el, look, clock: 0, visible: true };
|
|
95
|
+
if (!drawNow(mark)) {
|
|
96
|
+
live.value = false;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
drawn.value = true;
|
|
100
|
+
stop = animate(mark);
|
|
101
|
+
if (typeof IntersectionObserver === "function") {
|
|
102
|
+
observer = new IntersectionObserver((entries) => {
|
|
103
|
+
for (const e of entries) mark.visible = e.isIntersecting;
|
|
104
|
+
});
|
|
105
|
+
observer.observe(el);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function halt(): void {
|
|
109
|
+
stop?.();
|
|
110
|
+
stop = null;
|
|
111
|
+
observer?.disconnect();
|
|
112
|
+
observer = null;
|
|
113
|
+
live.value = false;
|
|
114
|
+
drawn.value = false;
|
|
115
|
+
}
|
|
116
|
+
function onMotionChange(): void {
|
|
117
|
+
if (motion?.matches) halt();
|
|
118
|
+
else void start();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
onMounted(() => {
|
|
122
|
+
// No matchMedia means no way to honour reduced motion, and a test DOM
|
|
123
|
+
// (jsdom) has no canvas and logs an error for every attempt: keep the
|
|
124
|
+
// still SVG in both.
|
|
125
|
+
if (typeof window.matchMedia !== "function" || typeof requestAnimationFrame !== "function") return;
|
|
126
|
+
if (navigator.userAgent.includes("jsdom")) return;
|
|
127
|
+
motion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
128
|
+
motion.addEventListener?.("change", onMotionChange);
|
|
129
|
+
if (!motion.matches) void start();
|
|
130
|
+
});
|
|
131
|
+
onBeforeUnmount(() => {
|
|
132
|
+
motion?.removeEventListener?.("change", onMotionChange);
|
|
133
|
+
halt();
|
|
134
|
+
});
|
|
135
|
+
</script>
|
|
136
|
+
|
|
137
|
+
<template>
|
|
138
|
+
<span
|
|
139
|
+
ref="root"
|
|
140
|
+
class="wp-lm"
|
|
141
|
+
:class="{ 'wp-lm--block': block, 'wp-lm--drawn': drawn }"
|
|
142
|
+
:role="decorative ? undefined : 'status'"
|
|
143
|
+
:aria-label="decorative || slots.default ? undefined : label"
|
|
144
|
+
:aria-hidden="decorative || undefined"
|
|
145
|
+
data-test="loading-mark"
|
|
146
|
+
>
|
|
147
|
+
<span class="wp-lm__art" :style="{ width: `${px}px`, height: `${px}px` }">
|
|
148
|
+
<svg
|
|
149
|
+
class="wp-lm__svg"
|
|
150
|
+
:data-variant="drawing"
|
|
151
|
+
viewBox="0 0 1024 1024"
|
|
152
|
+
:width="px"
|
|
153
|
+
:height="px"
|
|
154
|
+
aria-hidden="true"
|
|
155
|
+
>
|
|
156
|
+
<template v-if="drawing === 'logo'">
|
|
157
|
+
<defs v-if="!mono">
|
|
158
|
+
<linearGradient :id="`${id}a`" x1="312.56" y1="897.19" x2="312.56" y2="2" gradientUnits="userSpaceOnUse">
|
|
159
|
+
<stop offset="0" :stop-color="VIOLET" />
|
|
160
|
+
<stop offset="1" :stop-color="INDIGO" />
|
|
161
|
+
</linearGradient>
|
|
162
|
+
<linearGradient :id="`${id}b`" x1="711.44" y1="126.81" x2="711.44" y2="1022" gradientUnits="userSpaceOnUse">
|
|
163
|
+
<stop offset="0" :stop-color="INDIGO" />
|
|
164
|
+
<stop offset="1" :stop-color="TEAL" />
|
|
165
|
+
</linearGradient>
|
|
166
|
+
</defs>
|
|
167
|
+
<path class="wp-lm__ring wp-lm__ring--a" :fill="fill(`url(#${id}a)`)" :d="RING_A" />
|
|
168
|
+
<path class="wp-lm__ring wp-lm__ring--b" :fill="fill(`url(#${id}b)`)" :d="RING_B" />
|
|
169
|
+
<path class="wp-lm__star wp-lm__star--big" :fill="fill(VIOLET)" :d="STAR_BIG" />
|
|
170
|
+
<path class="wp-lm__star wp-lm__star--tw" :fill="fill(INDIGO)" :d="STAR_A" />
|
|
171
|
+
<path class="wp-lm__star wp-lm__star--tw" :fill="fill(TEAL)" :d="STAR_B" />
|
|
172
|
+
</template>
|
|
173
|
+
<g v-else transform="translate(512 512) scale(1.45) translate(-512 -512)">
|
|
174
|
+
<path class="wp-lm__star wp-lm__star--big" :fill="fill(VIOLET)" :d="STAR_BIG" />
|
|
175
|
+
<g class="wp-lm__swap">
|
|
176
|
+
<path class="wp-lm__star" :fill="fill(INDIGO)" :d="STAR_A" />
|
|
177
|
+
<path class="wp-lm__star" :fill="fill(TEAL)" :d="STAR_B" />
|
|
178
|
+
</g>
|
|
179
|
+
</g>
|
|
180
|
+
</svg>
|
|
181
|
+
<canvas v-if="live" ref="canvas" class="wp-lm__canvas" :style="canvasStyle" aria-hidden="true" />
|
|
182
|
+
</span>
|
|
183
|
+
<span v-if="slots.default" class="wp-lm__text"><slot /></span>
|
|
184
|
+
</span>
|
|
185
|
+
</template>
|
|
186
|
+
|
|
187
|
+
<style scoped>
|
|
188
|
+
.wp-lm {
|
|
189
|
+
display: inline-flex;
|
|
190
|
+
align-items: center;
|
|
191
|
+
gap: 8px;
|
|
192
|
+
vertical-align: middle;
|
|
193
|
+
}
|
|
194
|
+
.wp-lm--block {
|
|
195
|
+
display: flex;
|
|
196
|
+
flex-direction: column;
|
|
197
|
+
justify-content: center;
|
|
198
|
+
gap: 12px;
|
|
199
|
+
width: 100%;
|
|
200
|
+
padding: 48px 16px;
|
|
201
|
+
color: var(--wp-text-muted);
|
|
202
|
+
text-align: center;
|
|
203
|
+
}
|
|
204
|
+
.wp-lm__art { position: relative; display: inline-block; flex-shrink: 0; line-height: 0; }
|
|
205
|
+
.wp-lm__svg { display: block; overflow: visible; }
|
|
206
|
+
.wp-lm__canvas { position: absolute; pointer-events: none; }
|
|
207
|
+
.wp-lm--drawn .wp-lm__svg { visibility: hidden; }
|
|
208
|
+
|
|
209
|
+
/* Reduced motion: no canvas, the still mark breathes. A registered custom
|
|
210
|
+
* property, not `opacity` itself, so the fade stays off the compositor (a
|
|
211
|
+
* composited fade turns the mark soft). */
|
|
212
|
+
@property --wp-lm-o { syntax: "<number>"; inherits: false; initial-value: 1; }
|
|
213
|
+
@media (prefers-reduced-motion: reduce) {
|
|
214
|
+
.wp-lm__svg { opacity: var(--wp-lm-o); animation: wp-lm-fade 2.4s ease-in-out infinite; }
|
|
215
|
+
@keyframes wp-lm-fade { 0%, 100% { --wp-lm-o: 1; } 50% { --wp-lm-o: 0.55; } }
|
|
216
|
+
}
|
|
217
|
+
</style>
|
package/src/Logo.vue
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/** Gradient ids must be unique on the page, and two logos may wear different
|
|
3
|
-
* brands, so count across every app on it. */
|
|
4
|
-
let nextId = 0;
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
/**
|
|
9
|
-
* The Wildcard Pipeline logo, drawn inline so it needs no file. It names
|
|
10
|
-
* itself to screen readers; `decorative` hides it when the name is written
|
|
11
|
-
* beside it (the top bar's brand). `brand="community"` draws it in the
|
|
12
|
-
* community site's colours.
|
|
13
|
-
*
|
|
14
|
-
* <Logo :size="22" decorative />
|
|
15
|
-
*/
|
|
16
|
-
import { computed } from "vue";
|
|
17
|
-
import { BRAND_COLOURS, type LogoBrand } from "./logo-paths";
|
|
18
|
-
|
|
19
|
-
const props = withDefaults(defineProps<{
|
|
20
|
-
size?: number | undefined;
|
|
21
|
-
decorative?: boolean | undefined;
|
|
22
|
-
brand?: LogoBrand | undefined;
|
|
23
|
-
}>(), { size: 28, brand: "extension" });
|
|
24
|
-
|
|
25
|
-
const id = `wp-logo-${nextId++}`;
|
|
26
|
-
const c = computed(() => BRAND_COLOURS[props.brand]);
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<template>
|
|
30
|
-
<svg
|
|
31
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
-
viewBox="0 0 1024 1024"
|
|
33
|
-
:width="size"
|
|
34
|
-
:height="size"
|
|
35
|
-
:role="decorative ? undefined : 'img'"
|
|
36
|
-
:aria-label="decorative ? undefined : 'Wildcard Pipeline'"
|
|
37
|
-
:aria-hidden="decorative || undefined"
|
|
38
|
-
class="wp-logo"
|
|
39
|
-
>
|
|
40
|
-
<defs>
|
|
41
|
-
<linearGradient :id="`${id}a`" x1="312.56" y1="897.19" x2="312.56" y2="2" gradientUnits="userSpaceOnUse">
|
|
42
|
-
<stop offset="0" :stop-color="c[0]" />
|
|
43
|
-
<stop offset="1" :stop-color="c[1]" />
|
|
44
|
-
</linearGradient>
|
|
45
|
-
<linearGradient :id="`${id}b`" x1="711.44" y1="126.81" x2="711.44" y2="1022" gradientUnits="userSpaceOnUse">
|
|
46
|
-
<stop offset="0" :stop-color="c[1]" />
|
|
47
|
-
<stop offset="1" :stop-color="c[2]" />
|
|
48
|
-
</linearGradient>
|
|
49
|
-
</defs>
|
|
50
|
-
<path :fill="`url(#${id}a)`" d="m512,2c-53.6,0-98.47,38.16-108.84,88.73-75.07,19.29-143.32,58.26-198.74,113.68-55.42,55.42-94.39,123.68-113.68,198.74-50.58,10.38-88.73,55.24-88.73,108.84s38.16,98.47,88.73,108.84c13.62,53.14,37.03,102.64,69.77,147.47,37.14,50.86,85.83,93.86,140.81,124.33,5.54,3.08,11.56,4.54,17.48,4.54,12.7,0,25.02-6.72,31.61-18.61,9.68-17.44,3.38-39.42-14.07-49.09-85.32-47.32-147.22-125.71-173.38-218.21,36.3-18.29,61.27-55.92,61.27-99.28s-24.94-80.97-61.23-99.27c34.22-119.96,129.79-215.52,249.74-249.74,18.3,36.29,55.92,61.23,99.27,61.23,61.27,0,111.11-49.84,111.11-111.11S573.27,2,512,2ZM113.11,473.11c21.44,0,38.89,17.44,38.89,38.89,0,20.1-15.32,36.69-34.91,38.69h-.01c-.18.02-.36.03-.53.04-1.13.1-2.28.16-3.43.16-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89Zm398.89-321.11c-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89,38.89,17.44,38.89,38.89-17.44,38.89-38.89,38.89Z" />
|
|
51
|
-
<path :fill="`url(#${id}b)`" d="m933.27,403.16c-13.62-53.14-37.03-102.64-69.77-147.47-37.14-50.86-85.83-93.86-140.81-124.33-17.44-9.68-39.42-3.38-49.09,14.07-9.68,17.44-3.38,39.42,14.07,49.09,85.32,47.32,147.22,125.71,173.38,218.21-36.3,18.29-61.27,55.92-61.27,99.28s24.94,80.97,61.23,99.27c-34.22,119.96-129.79,215.52-249.74,249.74-18.3-36.29-55.92-61.23-99.27-61.23-61.27,0-111.11,49.84-111.11,111.11s49.84,111.11,111.11,111.11c53.6,0,98.47-38.16,108.84-88.73,75.07-19.29,143.32-58.26,198.74-113.68,55.42-55.42,94.39-123.68,113.68-198.74,50.58-10.38,88.73-55.24,88.73-108.84s-38.16-98.47-88.73-108.84Zm-421.27,546.62c-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89,38.89,17.44,38.89,38.89-17.44,38.89-38.89,38.89Zm398.89-398.89c-21.44,0-38.89-17.44-38.89-38.89,0-20.03,15.22-36.58,34.72-38.67.38-.04.77-.08,1.16-.11h.02c.99-.08,1.99-.11,2.99-.11,21.44,0,38.89,17.44,38.89,38.89s-17.44,38.89-38.89,38.89Z" />
|
|
52
|
-
<path :fill="c[0]" d="m735.02,517.56c-153.82,30.87-186.59,63.64-217.46,217.46-1.22,6.08-9.9,6.08-11.12,0-30.87-153.82-63.64-186.59-217.46-217.46-6.08-1.22-6.08-9.9,0-11.12,153.82-30.87,186.59-63.64,217.46-217.46,1.22-6.08,9.9-6.08,11.12,0,30.87,153.82,63.64,186.59,217.46,217.46,6.08,1.22,6.08,9.9,0,11.12Z" />
|
|
53
|
-
<path :fill="c[1]" d="m434.06,665.85c-51.08,10.25-61.96,21.13-72.22,72.22-.41,2.02-3.29,2.02-3.69,0-10.25-51.08-21.13-61.96-72.22-72.22-2.02-.41-2.02-3.29,0-3.69,51.08-10.25,61.96-21.13,72.22-72.22.41-2.02,3.29-2.02,3.69,0,10.25,51.08,21.13,61.96,72.22,72.22,2.02.41,2.02,3.29,0,3.69Z" />
|
|
54
|
-
<path :fill="c[2]" d="m738.07,361.84c-51.08,10.25-61.96,21.13-72.22,72.22-.41,2.02-3.29,2.02-3.69,0-10.25-51.08-21.13-61.96-72.22-72.22-2.02-.41-2.02-3.29,0-3.69,51.08-10.25,61.96-21.13,72.22-72.22.41-2.02,3.29-2.02,3.69,0,10.25,51.08,21.13,61.96,72.22,72.22,2.02.41,2.02,3.29,0,3.69Z" />
|
|
55
|
-
</svg>
|
|
56
|
-
</template>
|
|
57
|
-
|
|
58
|
-
<style scoped>
|
|
59
|
-
.wp-logo { display: block; flex-shrink: 0; }
|
|
60
|
-
</style>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/** Gradient ids must be unique on the page, and two logos may wear different
|
|
3
|
+
* brands, so count across every app on it. */
|
|
4
|
+
let nextId = 0;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
/**
|
|
9
|
+
* The Wildcard Pipeline logo, drawn inline so it needs no file. It names
|
|
10
|
+
* itself to screen readers; `decorative` hides it when the name is written
|
|
11
|
+
* beside it (the top bar's brand). `brand="community"` draws it in the
|
|
12
|
+
* community site's colours.
|
|
13
|
+
*
|
|
14
|
+
* <Logo :size="22" decorative />
|
|
15
|
+
*/
|
|
16
|
+
import { computed } from "vue";
|
|
17
|
+
import { BRAND_COLOURS, type LogoBrand } from "./logo-paths";
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<{
|
|
20
|
+
size?: number | undefined;
|
|
21
|
+
decorative?: boolean | undefined;
|
|
22
|
+
brand?: LogoBrand | undefined;
|
|
23
|
+
}>(), { size: 28, brand: "extension" });
|
|
24
|
+
|
|
25
|
+
const id = `wp-logo-${nextId++}`;
|
|
26
|
+
const c = computed(() => BRAND_COLOURS[props.brand]);
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<svg
|
|
31
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
+
viewBox="0 0 1024 1024"
|
|
33
|
+
:width="size"
|
|
34
|
+
:height="size"
|
|
35
|
+
:role="decorative ? undefined : 'img'"
|
|
36
|
+
:aria-label="decorative ? undefined : 'Wildcard Pipeline'"
|
|
37
|
+
:aria-hidden="decorative || undefined"
|
|
38
|
+
class="wp-logo"
|
|
39
|
+
>
|
|
40
|
+
<defs>
|
|
41
|
+
<linearGradient :id="`${id}a`" x1="312.56" y1="897.19" x2="312.56" y2="2" gradientUnits="userSpaceOnUse">
|
|
42
|
+
<stop offset="0" :stop-color="c[0]" />
|
|
43
|
+
<stop offset="1" :stop-color="c[1]" />
|
|
44
|
+
</linearGradient>
|
|
45
|
+
<linearGradient :id="`${id}b`" x1="711.44" y1="126.81" x2="711.44" y2="1022" gradientUnits="userSpaceOnUse">
|
|
46
|
+
<stop offset="0" :stop-color="c[1]" />
|
|
47
|
+
<stop offset="1" :stop-color="c[2]" />
|
|
48
|
+
</linearGradient>
|
|
49
|
+
</defs>
|
|
50
|
+
<path :fill="`url(#${id}a)`" d="m512,2c-53.6,0-98.47,38.16-108.84,88.73-75.07,19.29-143.32,58.26-198.74,113.68-55.42,55.42-94.39,123.68-113.68,198.74-50.58,10.38-88.73,55.24-88.73,108.84s38.16,98.47,88.73,108.84c13.62,53.14,37.03,102.64,69.77,147.47,37.14,50.86,85.83,93.86,140.81,124.33,5.54,3.08,11.56,4.54,17.48,4.54,12.7,0,25.02-6.72,31.61-18.61,9.68-17.44,3.38-39.42-14.07-49.09-85.32-47.32-147.22-125.71-173.38-218.21,36.3-18.29,61.27-55.92,61.27-99.28s-24.94-80.97-61.23-99.27c34.22-119.96,129.79-215.52,249.74-249.74,18.3,36.29,55.92,61.23,99.27,61.23,61.27,0,111.11-49.84,111.11-111.11S573.27,2,512,2ZM113.11,473.11c21.44,0,38.89,17.44,38.89,38.89,0,20.1-15.32,36.69-34.91,38.69h-.01c-.18.02-.36.03-.53.04-1.13.1-2.28.16-3.43.16-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89Zm398.89-321.11c-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89,38.89,17.44,38.89,38.89-17.44,38.89-38.89,38.89Z" />
|
|
51
|
+
<path :fill="`url(#${id}b)`" d="m933.27,403.16c-13.62-53.14-37.03-102.64-69.77-147.47-37.14-50.86-85.83-93.86-140.81-124.33-17.44-9.68-39.42-3.38-49.09,14.07-9.68,17.44-3.38,39.42,14.07,49.09,85.32,47.32,147.22,125.71,173.38,218.21-36.3,18.29-61.27,55.92-61.27,99.28s24.94,80.97,61.23,99.27c-34.22,119.96-129.79,215.52-249.74,249.74-18.3-36.29-55.92-61.23-99.27-61.23-61.27,0-111.11,49.84-111.11,111.11s49.84,111.11,111.11,111.11c53.6,0,98.47-38.16,108.84-88.73,75.07-19.29,143.32-58.26,198.74-113.68,55.42-55.42,94.39-123.68,113.68-198.74,50.58-10.38,88.73-55.24,88.73-108.84s-38.16-98.47-88.73-108.84Zm-421.27,546.62c-21.44,0-38.89-17.44-38.89-38.89s17.44-38.89,38.89-38.89,38.89,17.44,38.89,38.89-17.44,38.89-38.89,38.89Zm398.89-398.89c-21.44,0-38.89-17.44-38.89-38.89,0-20.03,15.22-36.58,34.72-38.67.38-.04.77-.08,1.16-.11h.02c.99-.08,1.99-.11,2.99-.11,21.44,0,38.89,17.44,38.89,38.89s-17.44,38.89-38.89,38.89Z" />
|
|
52
|
+
<path :fill="c[0]" d="m735.02,517.56c-153.82,30.87-186.59,63.64-217.46,217.46-1.22,6.08-9.9,6.08-11.12,0-30.87-153.82-63.64-186.59-217.46-217.46-6.08-1.22-6.08-9.9,0-11.12,153.82-30.87,186.59-63.64,217.46-217.46,1.22-6.08,9.9-6.08,11.12,0,30.87,153.82,63.64,186.59,217.46,217.46,6.08,1.22,6.08,9.9,0,11.12Z" />
|
|
53
|
+
<path :fill="c[1]" d="m434.06,665.85c-51.08,10.25-61.96,21.13-72.22,72.22-.41,2.02-3.29,2.02-3.69,0-10.25-51.08-21.13-61.96-72.22-72.22-2.02-.41-2.02-3.29,0-3.69,51.08-10.25,61.96-21.13,72.22-72.22.41-2.02,3.29-2.02,3.69,0,10.25,51.08,21.13,61.96,72.22,72.22,2.02.41,2.02,3.29,0,3.69Z" />
|
|
54
|
+
<path :fill="c[2]" d="m738.07,361.84c-51.08,10.25-61.96,21.13-72.22,72.22-.41,2.02-3.29,2.02-3.69,0-10.25-51.08-21.13-61.96-72.22-72.22-2.02-.41-2.02-3.29,0-3.69,51.08-10.25,61.96-21.13,72.22-72.22.41-2.02,3.29-2.02,3.69,0,10.25,51.08,21.13,61.96,72.22,72.22,2.02.41,2.02,3.29,0,3.69Z" />
|
|
55
|
+
</svg>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<style scoped>
|
|
59
|
+
.wp-logo { display: block; flex-shrink: 0; }
|
|
60
|
+
</style>
|