@dumiflex/wp-kit 0.3.0 → 0.4.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 +77 -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 +119 -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 +292 -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 +125 -125
- package/src/InlineEdit.vue +183 -183
- package/src/Input.vue +99 -99
- package/src/Kbd.vue +56 -56
- package/src/Lightbox.vue +173 -173
- package/src/ListFilter.vue +85 -85
- package/src/ListRow.vue +204 -204
- package/src/LoadingMark.vue +175 -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 +82 -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/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/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/IconPicker.vue
CHANGED
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* IconPicker — pick one PrimeIcons glyph, or none.
|
|
4
|
-
*
|
|
5
|
-
* The `icon` column has existed on categories end-to-end (engine column,
|
|
6
|
-
* `wp_api/categories.py` `_UPDATABLE_FIELDS`, `CategoryRow.icon`) with no UI
|
|
7
|
-
* to set it, so every category rendered with the same generic bookmark.
|
|
8
|
-
*
|
|
9
|
-
* The offered glyphs live in `./icon-catalog`, which is verified against the
|
|
10
|
-
* installed `primeicons.css` by a test — an unknown name renders as an empty
|
|
11
|
-
* cell rather than failing, so nothing else would catch a typo.
|
|
12
|
-
*
|
|
13
|
-
* The glyph name is stored WITHOUT the `pi pi-` prefix (e.g. `"user"`), which
|
|
14
|
-
* is what the engine column already holds and what `Icon.vue` expects.
|
|
15
|
-
*/
|
|
16
|
-
import { computed, ref } from "vue";
|
|
17
|
-
import Popover from "./Popover.vue";
|
|
18
|
-
import { ICON_GROUPS } from "./icon-catalog";
|
|
19
|
-
|
|
20
|
-
const props = withDefaults(
|
|
21
|
-
defineProps<{
|
|
22
|
-
/** Current glyph name, unprefixed (`"user"`). Empty / null = none. */
|
|
23
|
-
modelValue: string | null;
|
|
24
|
-
ariaLabel?: string | undefined;
|
|
25
|
-
dataTest?: string | undefined;
|
|
26
|
-
/** Icon only, no name beside it, for a tight table cell. */
|
|
27
|
-
compact?: boolean | undefined;
|
|
28
|
-
}>(),
|
|
29
|
-
{ ariaLabel: "Pick an icon", dataTest: undefined, compact: false },
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const emit = defineEmits<{ "update:modelValue": [v: string | null] }>();
|
|
33
|
-
|
|
34
|
-
const open = ref(false);
|
|
35
|
-
const current = computed<string | null>(() => props.modelValue || null);
|
|
36
|
-
|
|
37
|
-
/** "arrow-right" → "Arrow right": the closed picker says which icon it holds. */
|
|
38
|
-
const currentName = computed(() => {
|
|
39
|
-
const n = current.value;
|
|
40
|
-
if (!n) return "Choose icon";
|
|
41
|
-
const words = n.replace(/-/g, " ");
|
|
42
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
function pick(name: string | null): void {
|
|
46
|
-
emit("update:modelValue", name);
|
|
47
|
-
open.value = false;
|
|
48
|
-
}
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<template>
|
|
52
|
-
<!-- On the kit Popover: it follows the trigger on scroll, flips to stay on
|
|
53
|
-
screen, and closes on Escape or a click outside with focus back on
|
|
54
|
-
the trigger. -->
|
|
55
|
-
<Popover v-model:open="open" :label="ariaLabel" role="listbox">
|
|
56
|
-
<template #trigger="{ props: triggerProps }">
|
|
57
|
-
<button
|
|
58
|
-
v-bind="triggerProps"
|
|
59
|
-
type="button"
|
|
60
|
-
class="wp-iconpick__trigger"
|
|
61
|
-
:class="{ 'wp-iconpick__trigger--compact': compact }"
|
|
62
|
-
:aria-label="`${ariaLabel}: ${current ? currentName : 'none'}`"
|
|
63
|
-
:data-test="dataTest"
|
|
64
|
-
>
|
|
65
|
-
<!-- Both states share one fixed-size slot: an em-dash and a glyph have
|
|
66
|
-
different intrinsic widths and baselines, so without it the trigger
|
|
67
|
-
resized and the mark shifted the moment an icon was picked. -->
|
|
68
|
-
<span class="wp-iconpick__slot" aria-hidden="true">
|
|
69
|
-
<i v-if="current" :class="`pi pi-${current}`" />
|
|
70
|
-
<span v-else class="wp-iconpick__none">—</span>
|
|
71
|
-
</span>
|
|
72
|
-
<span
|
|
73
|
-
v-if="!compact"
|
|
74
|
-
class="wp-iconpick__name"
|
|
75
|
-
:class="{ 'wp-iconpick__name--empty': !current }"
|
|
76
|
-
aria-hidden="true"
|
|
77
|
-
>{{ currentName }}</span>
|
|
78
|
-
<i class="pi pi-chevron-down wp-iconpick__caret" aria-hidden="true" />
|
|
79
|
-
</button>
|
|
80
|
-
</template>
|
|
81
|
-
<div class="wp-iconpick__panel" :data-test="dataTest ? `${dataTest}-panel` : undefined">
|
|
82
|
-
<button
|
|
83
|
-
type="button"
|
|
84
|
-
class="wp-iconpick__clear"
|
|
85
|
-
data-test="icon-picker-none"
|
|
86
|
-
@click="pick(null)"
|
|
87
|
-
>No icon</button>
|
|
88
|
-
<div v-for="group in ICON_GROUPS" :key="group.label" class="wp-iconpick__group">
|
|
89
|
-
<div class="wp-iconpick__group-label">{{ group.label }}</div>
|
|
90
|
-
<div class="wp-iconpick__grid">
|
|
91
|
-
<button
|
|
92
|
-
v-for="name in group.icons"
|
|
93
|
-
:key="name"
|
|
94
|
-
type="button"
|
|
95
|
-
class="wp-iconpick__cell"
|
|
96
|
-
:class="{ 'wp-iconpick__cell--on': name === current }"
|
|
97
|
-
role="option"
|
|
98
|
-
:aria-selected="name === current"
|
|
99
|
-
:title="name"
|
|
100
|
-
:aria-label="name"
|
|
101
|
-
:data-test="`icon-picker-${name}`"
|
|
102
|
-
@click="pick(name)"
|
|
103
|
-
><i :class="`pi pi-${name}`" aria-hidden="true" /></button>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
</Popover>
|
|
108
|
-
</template>
|
|
109
|
-
|
|
110
|
-
<style scoped>
|
|
111
|
-
.wp-iconpick__trigger {
|
|
112
|
-
display: inline-flex;
|
|
113
|
-
align-items: center;
|
|
114
|
-
gap: var(--wp-space-2);
|
|
115
|
-
height: var(--wp-control-h-md, 32px);
|
|
116
|
-
min-width: 140px;
|
|
117
|
-
max-width: 220px;
|
|
118
|
-
padding: 0 var(--wp-space-4) 0 var(--wp-space-3);
|
|
119
|
-
background: var(--wp-bg-2);
|
|
120
|
-
border: 1px solid var(--wp-border);
|
|
121
|
-
border-radius: var(--wp-radius-sm);
|
|
122
|
-
font: inherit;
|
|
123
|
-
font-size: 12.5px;
|
|
124
|
-
color: var(--wp-text);
|
|
125
|
-
cursor: pointer;
|
|
126
|
-
}
|
|
127
|
-
.wp-iconpick__trigger:hover { border-color: var(--wp-border-strong); }
|
|
128
|
-
.wp-iconpick__trigger:focus-visible { outline: none; border-color: var(--wp-accent-500); box-shadow: var(--wp-focus-ring); }
|
|
129
|
-
.wp-iconpick__trigger--compact { min-width: 0; padding: 0 var(--wp-space-3); }
|
|
130
|
-
.wp-iconpick__name {
|
|
131
|
-
flex: 1; min-width: 0; text-align: left;
|
|
132
|
-
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
133
|
-
}
|
|
134
|
-
.wp-iconpick__name--empty { color: var(--wp-text-dim); }
|
|
135
|
-
/* Fixed square so the glyph is centred in it regardless of the glyph's own
|
|
136
|
-
* advance width, and so swapping "no icon" for an icon doesn't reflow. */
|
|
137
|
-
.wp-iconpick__slot {
|
|
138
|
-
display: inline-flex;
|
|
139
|
-
align-items: center;
|
|
140
|
-
justify-content: center;
|
|
141
|
-
width: 16px;
|
|
142
|
-
height: 16px;
|
|
143
|
-
font-size: 14px;
|
|
144
|
-
line-height: 1;
|
|
145
|
-
}
|
|
146
|
-
.wp-iconpick__none { color: var(--wp-text-dim); line-height: 1; }
|
|
147
|
-
.wp-iconpick__caret { font-size: 9px; color: var(--wp-text-dim); line-height: 1; }
|
|
148
|
-
</style>
|
|
149
|
-
|
|
150
|
-
<style>
|
|
151
|
-
/* Unscoped: the panel is teleported to <body> by Popover, so a scoped selector's
|
|
152
|
-
`[data-v-…]` attribute would never match it. Class names are
|
|
153
|
-
component-specific (`wp-iconpick*`), so global is safe. */
|
|
154
|
-
/* Lives inside the kit Popover's panel, which gives the frame and shadow. */
|
|
155
|
-
.wp-iconpick__panel {
|
|
156
|
-
width: 212px;
|
|
157
|
-
max-height: 276px;
|
|
158
|
-
overflow-y: auto;
|
|
159
|
-
}
|
|
160
|
-
.wp-iconpick__clear {
|
|
161
|
-
width: 100%;
|
|
162
|
-
margin-bottom: var(--wp-space-3);
|
|
163
|
-
padding: var(--wp-space-2);
|
|
164
|
-
background: transparent;
|
|
165
|
-
border: 1px dashed var(--wp-border);
|
|
166
|
-
border-radius: var(--wp-radius-sm);
|
|
167
|
-
color: var(--wp-text-muted);
|
|
168
|
-
font-size: var(--wp-text-xs);
|
|
169
|
-
cursor: pointer;
|
|
170
|
-
}
|
|
171
|
-
.wp-iconpick__clear:hover { color: var(--wp-text); border-color: var(--wp-accent); }
|
|
172
|
-
.wp-iconpick__group + .wp-iconpick__group { margin-top: var(--wp-space-3); }
|
|
173
|
-
.wp-iconpick__group-label {
|
|
174
|
-
font-size: 9.5px;
|
|
175
|
-
font-weight: 700;
|
|
176
|
-
letter-spacing: 0.08em;
|
|
177
|
-
text-transform: uppercase;
|
|
178
|
-
color: var(--wp-text-dim);
|
|
179
|
-
margin-bottom: var(--wp-space-2);
|
|
180
|
-
}
|
|
181
|
-
.wp-iconpick__grid {
|
|
182
|
-
display: grid;
|
|
183
|
-
grid-template-columns: repeat(8, 1fr);
|
|
184
|
-
gap: 2px;
|
|
185
|
-
}
|
|
186
|
-
.wp-iconpick__cell {
|
|
187
|
-
display: flex;
|
|
188
|
-
align-items: center;
|
|
189
|
-
justify-content: center;
|
|
190
|
-
aspect-ratio: 1;
|
|
191
|
-
background: transparent;
|
|
192
|
-
border: 1px solid transparent;
|
|
193
|
-
border-radius: var(--wp-radius-sm);
|
|
194
|
-
color: var(--wp-text-muted);
|
|
195
|
-
cursor: pointer;
|
|
196
|
-
font-size: 13px;
|
|
197
|
-
}
|
|
198
|
-
/* Kill the icon font's own line box — it otherwise pushes the glyph off the
|
|
199
|
-
* cell's vertical centre even though the cell is a centred flex container. */
|
|
200
|
-
.wp-iconpick__cell i { line-height: 1; }
|
|
201
|
-
.wp-iconpick__cell:hover {
|
|
202
|
-
background: color-mix(in oklab, var(--wp-accent) 18%, transparent);
|
|
203
|
-
color: var(--wp-text);
|
|
204
|
-
}
|
|
205
|
-
.wp-iconpick__cell--on {
|
|
206
|
-
border-color: var(--wp-accent);
|
|
207
|
-
color: var(--wp-accent);
|
|
208
|
-
}
|
|
209
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* IconPicker — pick one PrimeIcons glyph, or none.
|
|
4
|
+
*
|
|
5
|
+
* The `icon` column has existed on categories end-to-end (engine column,
|
|
6
|
+
* `wp_api/categories.py` `_UPDATABLE_FIELDS`, `CategoryRow.icon`) with no UI
|
|
7
|
+
* to set it, so every category rendered with the same generic bookmark.
|
|
8
|
+
*
|
|
9
|
+
* The offered glyphs live in `./icon-catalog`, which is verified against the
|
|
10
|
+
* installed `primeicons.css` by a test — an unknown name renders as an empty
|
|
11
|
+
* cell rather than failing, so nothing else would catch a typo.
|
|
12
|
+
*
|
|
13
|
+
* The glyph name is stored WITHOUT the `pi pi-` prefix (e.g. `"user"`), which
|
|
14
|
+
* is what the engine column already holds and what `Icon.vue` expects.
|
|
15
|
+
*/
|
|
16
|
+
import { computed, ref } from "vue";
|
|
17
|
+
import Popover from "./Popover.vue";
|
|
18
|
+
import { ICON_GROUPS } from "./icon-catalog";
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(
|
|
21
|
+
defineProps<{
|
|
22
|
+
/** Current glyph name, unprefixed (`"user"`). Empty / null = none. */
|
|
23
|
+
modelValue: string | null;
|
|
24
|
+
ariaLabel?: string | undefined;
|
|
25
|
+
dataTest?: string | undefined;
|
|
26
|
+
/** Icon only, no name beside it, for a tight table cell. */
|
|
27
|
+
compact?: boolean | undefined;
|
|
28
|
+
}>(),
|
|
29
|
+
{ ariaLabel: "Pick an icon", dataTest: undefined, compact: false },
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits<{ "update:modelValue": [v: string | null] }>();
|
|
33
|
+
|
|
34
|
+
const open = ref(false);
|
|
35
|
+
const current = computed<string | null>(() => props.modelValue || null);
|
|
36
|
+
|
|
37
|
+
/** "arrow-right" → "Arrow right": the closed picker says which icon it holds. */
|
|
38
|
+
const currentName = computed(() => {
|
|
39
|
+
const n = current.value;
|
|
40
|
+
if (!n) return "Choose icon";
|
|
41
|
+
const words = n.replace(/-/g, " ");
|
|
42
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
function pick(name: string | null): void {
|
|
46
|
+
emit("update:modelValue", name);
|
|
47
|
+
open.value = false;
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template>
|
|
52
|
+
<!-- On the kit Popover: it follows the trigger on scroll, flips to stay on
|
|
53
|
+
screen, and closes on Escape or a click outside with focus back on
|
|
54
|
+
the trigger. -->
|
|
55
|
+
<Popover v-model:open="open" :label="ariaLabel" role="listbox">
|
|
56
|
+
<template #trigger="{ props: triggerProps }">
|
|
57
|
+
<button
|
|
58
|
+
v-bind="triggerProps"
|
|
59
|
+
type="button"
|
|
60
|
+
class="wp-iconpick__trigger"
|
|
61
|
+
:class="{ 'wp-iconpick__trigger--compact': compact }"
|
|
62
|
+
:aria-label="`${ariaLabel}: ${current ? currentName : 'none'}`"
|
|
63
|
+
:data-test="dataTest"
|
|
64
|
+
>
|
|
65
|
+
<!-- Both states share one fixed-size slot: an em-dash and a glyph have
|
|
66
|
+
different intrinsic widths and baselines, so without it the trigger
|
|
67
|
+
resized and the mark shifted the moment an icon was picked. -->
|
|
68
|
+
<span class="wp-iconpick__slot" aria-hidden="true">
|
|
69
|
+
<i v-if="current" :class="`pi pi-${current}`" />
|
|
70
|
+
<span v-else class="wp-iconpick__none">—</span>
|
|
71
|
+
</span>
|
|
72
|
+
<span
|
|
73
|
+
v-if="!compact"
|
|
74
|
+
class="wp-iconpick__name"
|
|
75
|
+
:class="{ 'wp-iconpick__name--empty': !current }"
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
>{{ currentName }}</span>
|
|
78
|
+
<i class="pi pi-chevron-down wp-iconpick__caret" aria-hidden="true" />
|
|
79
|
+
</button>
|
|
80
|
+
</template>
|
|
81
|
+
<div class="wp-iconpick__panel" :data-test="dataTest ? `${dataTest}-panel` : undefined">
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
class="wp-iconpick__clear"
|
|
85
|
+
data-test="icon-picker-none"
|
|
86
|
+
@click="pick(null)"
|
|
87
|
+
>No icon</button>
|
|
88
|
+
<div v-for="group in ICON_GROUPS" :key="group.label" class="wp-iconpick__group">
|
|
89
|
+
<div class="wp-iconpick__group-label">{{ group.label }}</div>
|
|
90
|
+
<div class="wp-iconpick__grid">
|
|
91
|
+
<button
|
|
92
|
+
v-for="name in group.icons"
|
|
93
|
+
:key="name"
|
|
94
|
+
type="button"
|
|
95
|
+
class="wp-iconpick__cell"
|
|
96
|
+
:class="{ 'wp-iconpick__cell--on': name === current }"
|
|
97
|
+
role="option"
|
|
98
|
+
:aria-selected="name === current"
|
|
99
|
+
:title="name"
|
|
100
|
+
:aria-label="name"
|
|
101
|
+
:data-test="`icon-picker-${name}`"
|
|
102
|
+
@click="pick(name)"
|
|
103
|
+
><i :class="`pi pi-${name}`" aria-hidden="true" /></button>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</Popover>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<style scoped>
|
|
111
|
+
.wp-iconpick__trigger {
|
|
112
|
+
display: inline-flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
gap: var(--wp-space-2);
|
|
115
|
+
height: var(--wp-control-h-md, 32px);
|
|
116
|
+
min-width: 140px;
|
|
117
|
+
max-width: 220px;
|
|
118
|
+
padding: 0 var(--wp-space-4) 0 var(--wp-space-3);
|
|
119
|
+
background: var(--wp-bg-2);
|
|
120
|
+
border: 1px solid var(--wp-border);
|
|
121
|
+
border-radius: var(--wp-radius-sm);
|
|
122
|
+
font: inherit;
|
|
123
|
+
font-size: 12.5px;
|
|
124
|
+
color: var(--wp-text);
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
}
|
|
127
|
+
.wp-iconpick__trigger:hover { border-color: var(--wp-border-strong); }
|
|
128
|
+
.wp-iconpick__trigger:focus-visible { outline: none; border-color: var(--wp-accent-500); box-shadow: var(--wp-focus-ring); }
|
|
129
|
+
.wp-iconpick__trigger--compact { min-width: 0; padding: 0 var(--wp-space-3); }
|
|
130
|
+
.wp-iconpick__name {
|
|
131
|
+
flex: 1; min-width: 0; text-align: left;
|
|
132
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
133
|
+
}
|
|
134
|
+
.wp-iconpick__name--empty { color: var(--wp-text-dim); }
|
|
135
|
+
/* Fixed square so the glyph is centred in it regardless of the glyph's own
|
|
136
|
+
* advance width, and so swapping "no icon" for an icon doesn't reflow. */
|
|
137
|
+
.wp-iconpick__slot {
|
|
138
|
+
display: inline-flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
width: 16px;
|
|
142
|
+
height: 16px;
|
|
143
|
+
font-size: 14px;
|
|
144
|
+
line-height: 1;
|
|
145
|
+
}
|
|
146
|
+
.wp-iconpick__none { color: var(--wp-text-dim); line-height: 1; }
|
|
147
|
+
.wp-iconpick__caret { font-size: 9px; color: var(--wp-text-dim); line-height: 1; }
|
|
148
|
+
</style>
|
|
149
|
+
|
|
150
|
+
<style>
|
|
151
|
+
/* Unscoped: the panel is teleported to <body> by Popover, so a scoped selector's
|
|
152
|
+
`[data-v-…]` attribute would never match it. Class names are
|
|
153
|
+
component-specific (`wp-iconpick*`), so global is safe. */
|
|
154
|
+
/* Lives inside the kit Popover's panel, which gives the frame and shadow. */
|
|
155
|
+
.wp-iconpick__panel {
|
|
156
|
+
width: 212px;
|
|
157
|
+
max-height: 276px;
|
|
158
|
+
overflow-y: auto;
|
|
159
|
+
}
|
|
160
|
+
.wp-iconpick__clear {
|
|
161
|
+
width: 100%;
|
|
162
|
+
margin-bottom: var(--wp-space-3);
|
|
163
|
+
padding: var(--wp-space-2);
|
|
164
|
+
background: transparent;
|
|
165
|
+
border: 1px dashed var(--wp-border);
|
|
166
|
+
border-radius: var(--wp-radius-sm);
|
|
167
|
+
color: var(--wp-text-muted);
|
|
168
|
+
font-size: var(--wp-text-xs);
|
|
169
|
+
cursor: pointer;
|
|
170
|
+
}
|
|
171
|
+
.wp-iconpick__clear:hover { color: var(--wp-text); border-color: var(--wp-accent); }
|
|
172
|
+
.wp-iconpick__group + .wp-iconpick__group { margin-top: var(--wp-space-3); }
|
|
173
|
+
.wp-iconpick__group-label {
|
|
174
|
+
font-size: 9.5px;
|
|
175
|
+
font-weight: 700;
|
|
176
|
+
letter-spacing: 0.08em;
|
|
177
|
+
text-transform: uppercase;
|
|
178
|
+
color: var(--wp-text-dim);
|
|
179
|
+
margin-bottom: var(--wp-space-2);
|
|
180
|
+
}
|
|
181
|
+
.wp-iconpick__grid {
|
|
182
|
+
display: grid;
|
|
183
|
+
grid-template-columns: repeat(8, 1fr);
|
|
184
|
+
gap: 2px;
|
|
185
|
+
}
|
|
186
|
+
.wp-iconpick__cell {
|
|
187
|
+
display: flex;
|
|
188
|
+
align-items: center;
|
|
189
|
+
justify-content: center;
|
|
190
|
+
aspect-ratio: 1;
|
|
191
|
+
background: transparent;
|
|
192
|
+
border: 1px solid transparent;
|
|
193
|
+
border-radius: var(--wp-radius-sm);
|
|
194
|
+
color: var(--wp-text-muted);
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
font-size: 13px;
|
|
197
|
+
}
|
|
198
|
+
/* Kill the icon font's own line box — it otherwise pushes the glyph off the
|
|
199
|
+
* cell's vertical centre even though the cell is a centred flex container. */
|
|
200
|
+
.wp-iconpick__cell i { line-height: 1; }
|
|
201
|
+
.wp-iconpick__cell:hover {
|
|
202
|
+
background: color-mix(in oklab, var(--wp-accent) 18%, transparent);
|
|
203
|
+
color: var(--wp-text);
|
|
204
|
+
}
|
|
205
|
+
.wp-iconpick__cell--on {
|
|
206
|
+
border-color: var(--wp-accent);
|
|
207
|
+
color: var(--wp-accent);
|
|
208
|
+
}
|
|
209
|
+
</style>
|