@dumiflex/wp-kit 0.15.0 → 0.15.2
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 +14 -0
- package/package.json +1 -1
- package/src/ColorField.vue +3 -0
- package/src/HsvPicker.vue +27 -7
- package/src/PostCard.vue +17 -18
- package/src/WpSegmented.vue +3 -1
- package/src/useGrowableField.ts +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.2](https://github.com/DumiFlex/wp-kit/compare/v0.15.1...v0.15.2) (2026-11-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* colour picker edges and thumb drift, uncut Segmented descenders, no false more-below hint ([#119](https://github.com/DumiFlex/wp-kit/issues/119)) ([d4728bb](https://github.com/DumiFlex/wp-kit/commit/d4728bb70ae90bedc68fc61a662cc848788b41a0))
|
|
9
|
+
|
|
10
|
+
## [0.15.1](https://github.com/DumiFlex/wp-kit/compare/v0.15.0...v0.15.1) (2026-11-09)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **PostCard:** show sample values as one line of text ([#115](https://github.com/DumiFlex/wp-kit/issues/115)) ([ced88a1](https://github.com/DumiFlex/wp-kit/commit/ced88a1e4c54ac6c20859b9d858f30f79a4e9edf))
|
|
16
|
+
|
|
3
17
|
## [0.15.0](https://github.com/DumiFlex/wp-kit/compare/v0.14.0...v0.15.0) (2026-11-09)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
package/src/ColorField.vue
CHANGED
|
@@ -199,6 +199,9 @@ function pickNone(): void {
|
|
|
199
199
|
border-radius: min(3px, var(--wp-radius-cap, 999px));
|
|
200
200
|
/* Checks show through a see-through colour. */
|
|
201
201
|
background: repeating-conic-gradient(var(--wp-bg-4) 0 25%, var(--wp-bg-1) 0 50%) 0 0 / 8px 8px;
|
|
202
|
+
/* Not under the see-through border, or the checks show round the colour
|
|
203
|
+
as a jagged edge. */
|
|
204
|
+
background-clip: padding-box;
|
|
202
205
|
}
|
|
203
206
|
.wp-color-field--md .wp-color-field__chip { width: 20px; height: 20px; border-radius: min(4px, var(--wp-radius-cap, 999px)); }
|
|
204
207
|
.wp-color-field--compact { padding: 0 3px; }
|
package/src/HsvPicker.vue
CHANGED
|
@@ -38,6 +38,10 @@ const emit = defineEmits<{
|
|
|
38
38
|
const hsv = ref<Hsv>({ h: 0, s: 1, v: 1 });
|
|
39
39
|
|
|
40
40
|
function syncFromProp(hex: string) {
|
|
41
|
+
// Our own emit coming back: keep the exact position. A hex has only 256
|
|
42
|
+
// steps per channel, so near black (or grey) reading it back moves the
|
|
43
|
+
// thumb away from the pointer, and the hue jumps.
|
|
44
|
+
if (hex.toLowerCase() === hsvToHex(hsv.value).toLowerCase()) return;
|
|
41
45
|
const parsed = hexToHsv(hex);
|
|
42
46
|
if (!parsed) return;
|
|
43
47
|
// Preserve the local hue when incoming RGB is pure black/white —
|
|
@@ -58,6 +62,18 @@ const hueBg = computed(() => `hsl(${hsv.value.h}, 100%, 50%)`);
|
|
|
58
62
|
const svEl = ref<HTMLDivElement | null>(null);
|
|
59
63
|
const hueEl = ref<HTMLDivElement | null>(null);
|
|
60
64
|
|
|
65
|
+
/** Where `evt` sits inside `el`'s padding box (what the gradient and the
|
|
66
|
+
* thumb are drawn in), as 0..1 fractions; the border is not part of it. */
|
|
67
|
+
function fraction(el: HTMLElement, evt: PointerEvent): { x: number; y: number } {
|
|
68
|
+
const rect = el.getBoundingClientRect();
|
|
69
|
+
const left = rect.left + el.clientLeft;
|
|
70
|
+
const top = rect.top + el.clientTop;
|
|
71
|
+
const w = el.clientWidth || rect.width;
|
|
72
|
+
const h = el.clientHeight || rect.height;
|
|
73
|
+
const clamp = (n: number) => Math.max(0, Math.min(1, n));
|
|
74
|
+
return { x: w ? clamp((evt.clientX - left) / w) : 0, y: h ? clamp((evt.clientY - top) / h) : 0 };
|
|
75
|
+
}
|
|
76
|
+
|
|
61
77
|
/** Document-level drag state. Only one drag can be active at a time
|
|
62
78
|
* (one mouse / one finger), so a single `activeDrag` ref tracking
|
|
63
79
|
* which surface owns the current pointer is sufficient. */
|
|
@@ -66,19 +82,16 @@ let activeDrag: "sv" | "hue" | null = null;
|
|
|
66
82
|
function handleSvMove(evt: PointerEvent) {
|
|
67
83
|
const el = svEl.value;
|
|
68
84
|
if (!el) return;
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
const y = Math.max(0, Math.min(rect.height, evt.clientY - rect.top));
|
|
72
|
-
hsv.value = { h: hsv.value.h, s: x / rect.width, v: 1 - (y / rect.height) };
|
|
85
|
+
const { x, y } = fraction(el, evt);
|
|
86
|
+
hsv.value = { h: hsv.value.h, s: x, v: 1 - y };
|
|
73
87
|
emitHex();
|
|
74
88
|
}
|
|
75
89
|
|
|
76
90
|
function handleHueMove(evt: PointerEvent) {
|
|
77
91
|
const el = hueEl.value;
|
|
78
92
|
if (!el) return;
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
hsv.value = { h: (x / rect.width) * 360, s: hsv.value.s, v: hsv.value.v };
|
|
93
|
+
const { x } = fraction(el, evt);
|
|
94
|
+
hsv.value = { h: x * 360, s: hsv.value.s, v: hsv.value.v };
|
|
82
95
|
emitHex();
|
|
83
96
|
}
|
|
84
97
|
|
|
@@ -162,6 +175,11 @@ const hueCursorStyle = computed(() => ({
|
|
|
162
175
|
linear-gradient(to top, #000, transparent),
|
|
163
176
|
linear-gradient(to right, #fff, transparent),
|
|
164
177
|
var(--wp-hsv-hue, hsl(0, 100%, 50%));
|
|
178
|
+
/* The gradients are sized to the padding box; without these they repeat
|
|
179
|
+
under the see-through border: a white line down the right edge, the
|
|
180
|
+
hue along the bottom. */
|
|
181
|
+
background-repeat: no-repeat;
|
|
182
|
+
background-clip: padding-box;
|
|
165
183
|
}
|
|
166
184
|
.wp-hsv-picker__sv-cursor {
|
|
167
185
|
position: absolute;
|
|
@@ -192,6 +210,8 @@ const hueCursorStyle = computed(() => ({
|
|
|
192
210
|
hsl(300, 100%, 50%),
|
|
193
211
|
hsl(360, 100%, 50%)
|
|
194
212
|
);
|
|
213
|
+
background-repeat: no-repeat;
|
|
214
|
+
background-clip: padding-box;
|
|
195
215
|
}
|
|
196
216
|
.wp-hsv-picker__hue-cursor {
|
|
197
217
|
position: absolute;
|
package/src/PostCard.vue
CHANGED
|
@@ -86,9 +86,13 @@ const samples = computed(() => (props.post.samples ?? []).filter((v) => v.trim()
|
|
|
86
86
|
:names="post.bundleModules.names"
|
|
87
87
|
/>
|
|
88
88
|
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
|
|
89
|
+
<p v-if="samples.length" class="wp-post-card__samples" :title="samples.join(' · ')">
|
|
90
|
+
<span class="wp-post-card__samples-k">Rolls</span>
|
|
91
|
+
<template v-for="(v, i) in samples" :key="i">
|
|
92
|
+
<span v-if="i" class="wp-post-card__samples-sep" aria-hidden="true"> · </span>
|
|
93
|
+
<span class="wp-post-card__sample">{{ v }}</span>
|
|
94
|
+
</template>
|
|
95
|
+
</p>
|
|
92
96
|
|
|
93
97
|
<p v-if="post.description" class="wp-post-card__desc">{{ post.description }}</p>
|
|
94
98
|
|
|
@@ -193,27 +197,22 @@ const samples = computed(() => (props.post.samples ?? []).filter((v) => v.trim()
|
|
|
193
197
|
-webkit-box-orient: vertical;
|
|
194
198
|
}
|
|
195
199
|
.wp-post-card__samples {
|
|
196
|
-
display: flex;
|
|
197
|
-
flex-wrap: wrap;
|
|
198
|
-
gap: 5px;
|
|
199
200
|
margin: 0;
|
|
200
|
-
padding: 0;
|
|
201
|
-
list-style: none;
|
|
202
|
-
}
|
|
203
|
-
.wp-post-card__sample {
|
|
204
|
-
max-width: 100%;
|
|
205
201
|
overflow: hidden;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
font-size: 12px;
|
|
209
|
-
line-height: 1.4;
|
|
202
|
+
font-size: 13px;
|
|
203
|
+
line-height: 1.5;
|
|
210
204
|
color: var(--wp-text);
|
|
211
205
|
white-space: nowrap;
|
|
212
206
|
text-overflow: ellipsis;
|
|
213
|
-
background: color-mix(in oklab, var(--post-card-c) 12%, var(--wp-bg-2));
|
|
214
|
-
border: 1px solid color-mix(in oklab, var(--post-card-c) 28%, var(--wp-border));
|
|
215
|
-
border-radius: min(6px, var(--wp-radius-cap, 999px));
|
|
216
207
|
}
|
|
208
|
+
.wp-post-card__samples-k {
|
|
209
|
+
margin-right: 8px;
|
|
210
|
+
font-size: 11px;
|
|
211
|
+
letter-spacing: 0.04em;
|
|
212
|
+
text-transform: uppercase;
|
|
213
|
+
color: var(--wp-text-muted);
|
|
214
|
+
}
|
|
215
|
+
.wp-post-card__samples-sep { color: var(--wp-text-muted); }
|
|
217
216
|
.wp-post-card__tags { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
218
217
|
.wp-post-card__tags .wp-chip { padding: 2px 8px; font-size: 11px; }
|
|
219
218
|
.wp-post-card__foot {
|
package/src/WpSegmented.vue
CHANGED
|
@@ -158,7 +158,9 @@ function onKeydown(ev: KeyboardEvent): void {
|
|
|
158
158
|
.wp-segmented[data-size="lg"] .wp-segmented__opt { padding: 0 var(--wp-space-6); font-size: var(--wp-text-base); }
|
|
159
159
|
.wp-segmented[data-block] { display: flex; width: 100%; align-self: stretch; }
|
|
160
160
|
.wp-segmented[data-block] .wp-segmented__opt { flex: 1 1 0; }
|
|
161
|
-
|
|
161
|
+
/* The option sets line-height 1; the label clips (for the ellipsis), so it
|
|
162
|
+
needs a taller line or it cuts g, p, q and y. */
|
|
163
|
+
.wp-segmented__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.3; }
|
|
162
164
|
.wp-segmented[data-icon-only] .wp-segmented__opt { aspect-ratio: 1; padding: 0; }
|
|
163
165
|
.wp-segmented__opt:hover:not(:disabled) { color: var(--wp-text); background: var(--wp-bg-3); }
|
|
164
166
|
.wp-segmented__opt[data-active="true"] {
|
package/src/useGrowableField.ts
CHANGED
|
@@ -74,8 +74,12 @@ export function useGrowableField(
|
|
|
74
74
|
function updateOverflowHint(): void {
|
|
75
75
|
const el = getEl();
|
|
76
76
|
if (!el) return;
|
|
77
|
-
//
|
|
78
|
-
|
|
77
|
+
// Only text counts: the bottom padding scrolling out of view hides
|
|
78
|
+
// nothing, so it is allowed for (a box a few px short of its padding
|
|
79
|
+
// showed the hint under a fully visible last line). 2px slack absorbs
|
|
80
|
+
// sub-pixel rounding at the exact bottom.
|
|
81
|
+
const pad = parseFloat(getComputedStyle(el).paddingBottom) || 0;
|
|
82
|
+
hasMoreBelow.value = el.scrollHeight - el.scrollTop - el.clientHeight > pad + 2;
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
function scheduleOverflowHint(): void {
|