@leavepulse/ui 0.74.1 → 0.74.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.
@@ -1,9 +1,9 @@
1
1
 
2
- .lp-dropzone__frame rect[data-v-46c9a55a] {
2
+ .lp-dropzone__frame rect[data-v-afb08dd3] {
3
3
  stroke: var(--color-line);
4
4
  transition: stroke var(--duration-fast) linear;
5
5
  }
6
- .lp-dropzone:hover .lp-dropzone__frame rect[data-v-46c9a55a] {
6
+ .lp-dropzone:hover .lp-dropzone__frame rect[data-v-afb08dd3] {
7
7
  stroke: var(--color-line-strong);
8
8
  }
9
9
 
@@ -12,28 +12,28 @@
12
12
  with every other thing on it; under a drag it is the answer to "can I let go
13
13
  here". One dash period per cycle, so the travel is continuous rather than
14
14
  jumping back at the seam. */
15
- .lp-dropzone--over .lp-dropzone__frame rect[data-v-46c9a55a] {
15
+ .lp-dropzone--over .lp-dropzone__frame rect[data-v-afb08dd3] {
16
16
  stroke: var(--color-brand);
17
- animation: lp-dropzone-ants-46c9a55a 500ms linear infinite;
17
+ animation: lp-dropzone-ants-afb08dd3 500ms linear infinite;
18
18
  }
19
- @keyframes lp-dropzone-ants-46c9a55a {
19
+ @keyframes lp-dropzone-ants-afb08dd3 {
20
20
  to {
21
21
  stroke-dashoffset: -11;
22
22
  }
23
23
  }
24
24
 
25
25
  /* The dashes fade in and the block settles up a few pixels. */
26
- .lp-dropzone[data-v-46c9a55a] {
26
+ .lp-dropzone[data-v-afb08dd3] {
27
27
  --rise: 6px;
28
28
  animation: rise-in var(--duration-slow) var(--ease-settle) both;
29
29
  }
30
- .lp-dropzone--waiting[data-v-46c9a55a] {
30
+ .lp-dropzone--waiting[data-v-afb08dd3] {
31
31
  opacity: 0;
32
32
  animation: none;
33
33
  }
34
34
  @media (prefers-reduced-motion: reduce) {
35
- .lp-dropzone[data-v-46c9a55a],
36
- .lp-dropzone--waiting[data-v-46c9a55a] {
35
+ .lp-dropzone[data-v-afb08dd3],
36
+ .lp-dropzone--waiting[data-v-afb08dd3] {
37
37
  opacity: 1;
38
38
  transform: none;
39
39
  animation: none;
@@ -41,7 +41,7 @@ to {
41
41
 
42
42
  /* The ants stop, the colour stays: the brand stroke is what says "drop
43
43
  here", and it says it standing still. */
44
- .lp-dropzone--over .lp-dropzone__frame rect[data-v-46c9a55a] {
44
+ .lp-dropzone--over .lp-dropzone__frame rect[data-v-afb08dd3] {
45
45
  animation: none;
46
46
  }
47
47
  }
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, computed, useModel, watch, useId, onMounted, onBeforeUnmount, openBlock, createElementBlock, withModifiers, normalizeStyle, normalizeClass, unref, createElementVNode, mergeProps, createVNode, Transition, withCtx, renderSlot, toDisplayString, createCommentVNode, createTextVNode, Fragment, mergeModels, nextTick } from "vue";
1
+ import { defineComponent, ref, computed, useModel, watch, useId, onMounted, onBeforeUnmount, nextTick, openBlock, createElementBlock, withModifiers, normalizeStyle, normalizeClass, unref, createElementVNode, mergeProps, createVNode, Transition, withCtx, renderSlot, toDisplayString, createCommentVNode, createTextVNode, Fragment, mergeModels } from "vue";
2
2
  import { HINT_SIGNALS, noteDropzone } from "../composables/useHintSystem.js";
3
3
  import { hints } from "../composables/useHints.js";
4
4
  import { useLabels } from "../composables/useLpConfig.js";
@@ -10,19 +10,24 @@ import { POPOVER_PANEL } from "./dropdown.js";
10
10
  import { _ as _sfc_main$2 } from "../chunks/LpIcon--5WSb3jJ.js";
11
11
  import { usePortalTarget, useOutsideGuard } from "../composables/useView.js";
12
12
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
13
- import '../assets/LpDropzone-Bb1vBTeU.css';const _hoisted_1 = ["aria-disabled"];
13
+ import '../assets/LpDropzone-B_qRq1-R.css';const _hoisted_1 = ["aria-disabled"];
14
14
  const _hoisted_2 = ["disabled", "aria-labelledby"];
15
- const _hoisted_3 = ["id"];
16
- const _hoisted_4 = {
15
+ const _hoisted_3 = {
16
+ "aria-hidden": "true",
17
+ class: "lp-dropzone__frame pointer-events-none absolute inset-0 size-full"
18
+ };
19
+ const _hoisted_4 = ["rx"];
20
+ const _hoisted_5 = ["id"];
21
+ const _hoisted_6 = {
17
22
  key: 0,
18
23
  class: "text-sm font-medium text-ink"
19
24
  };
20
- const _hoisted_5 = {
25
+ const _hoisted_7 = {
21
26
  key: 1,
22
27
  class: "text-xs text-muted"
23
28
  };
24
- const _hoisted_6 = ["disabled"];
25
- const _hoisted_7 = ["accept", "multiple", "disabled"];
29
+ const _hoisted_8 = ["disabled"];
30
+ const _hoisted_9 = ["accept", "multiple", "disabled"];
26
31
  const __default__ = { inheritAttrs: false };
27
32
  const _sfc_main = /* @__PURE__ */ defineComponent({
28
33
  ...__default__,
@@ -260,6 +265,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
260
265
  onMounted(() => {
261
266
  mounted = true;
262
267
  listen(props.pasteTarget);
268
+ measureRadius();
263
269
  });
264
270
  watch(
265
271
  () => props.pasteTarget,
@@ -277,6 +283,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
277
283
  over.value ? "lp-dropzone--over" : "",
278
284
  props.animate && !revealed.value ? "lp-dropzone--waiting" : ""
279
285
  ].join(" "));
286
+ const measuredRadius = ref("");
287
+ const frameRadius = computed(
288
+ () => rootClass.value.split(/\s+/).includes("rounded-card") || !measuredRadius.value ? "var(--radius-card)" : measuredRadius.value
289
+ );
290
+ function measureRadius() {
291
+ const zone = revealAnchor.value;
292
+ if (zone) measuredRadius.value = getComputedStyle(zone).borderTopLeftRadius;
293
+ }
294
+ watch(rootClass, () => nextTick(measureRadius));
280
295
  const portalTo = usePortalTarget();
281
296
  const guardOutside = useOutsideGuard();
282
297
  return (_ctx, _cache) => {
@@ -302,21 +317,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
302
317
  onClick: press,
303
318
  onPaste
304
319
  }), null, 16, _hoisted_2),
305
- _cache[5] || (_cache[5] = createElementVNode("svg", {
306
- "aria-hidden": "true",
307
- class: "lp-dropzone__frame pointer-events-none absolute inset-0 size-full"
308
- }, [
320
+ (openBlock(), createElementBlock("svg", _hoisted_3, [
309
321
  createElementVNode("rect", {
310
322
  x: "0.5",
311
323
  y: "0.5",
312
324
  width: "calc(100% - 1px)",
313
325
  height: "calc(100% - 1px)",
314
- rx: "var(--radius-card)",
326
+ rx: frameRadius.value,
315
327
  fill: "none",
316
328
  "stroke-width": "1",
317
329
  "stroke-dasharray": "6 5"
318
- })
319
- ], -1)),
330
+ }, null, 8, _hoisted_4)
331
+ ])),
320
332
  createVNode(Transition, {
321
333
  mode: "out-in",
322
334
  "enter-active-class": "transition-[opacity,translate] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] motion-reduce:transition-none",
@@ -355,8 +367,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
355
367
  size: 22,
356
368
  class: normalizeClass(["text-muted transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] motion-reduce:transition-none", over.value ? "scale-110 text-brand" : ""])
357
369
  }, null, 8, ["name", "class"]),
358
- __props.title ? (openBlock(), createElementBlock("span", _hoisted_4, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
359
- __props.hint || __props.links ? (openBlock(), createElementBlock("span", _hoisted_5, [
370
+ __props.title ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
371
+ __props.hint || __props.links ? (openBlock(), createElementBlock("span", _hoisted_7, [
360
372
  createTextVNode(toDisplayString(__props.hint), 1),
361
373
  __props.hint && __props.links ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
362
374
  createTextVNode(" · ")
@@ -367,10 +379,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
367
379
  class: "pointer-events-auto rounded-inner font-medium text-brand underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none",
368
380
  disabled: __props.disabled,
369
381
  onClick: withModifiers(startLink, ["stop"])
370
- }, toDisplayString(unref(labels).orLink), 9, _hoisted_6)) : createCommentVNode("", true)
382
+ }, toDisplayString(unref(labels).orLink), 9, _hoisted_8)) : createCommentVNode("", true)
371
383
  ])) : createCommentVNode("", true)
372
384
  ], true)
373
- ], 8, _hoisted_3))
385
+ ], 8, _hoisted_5))
374
386
  ]),
375
387
  _: 3
376
388
  }),
@@ -380,7 +392,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
380
392
  }, {
381
393
  default: withCtx(() => [
382
394
  createVNode(unref(PopoverAnchor), {
383
- reference: unref(revealAnchor) ?? void 0
395
+ reference: unref(revealAnchor) ?? void 0,
396
+ class: "hidden"
384
397
  }, null, 8, ["reference"]),
385
398
  createVNode(unref(PopoverPortal), { to: unref(portalTo) }, {
386
399
  default: withCtx(() => [
@@ -426,12 +439,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
426
439
  onChange: onPicked,
427
440
  onClick: _cache[4] || (_cache[4] = withModifiers(() => {
428
441
  }, ["stop"]))
429
- }, null, 40, _hoisted_7)
442
+ }, null, 40, _hoisted_9)
430
443
  ], 46, _hoisted_1);
431
444
  };
432
445
  }
433
446
  });
434
- const LpDropzone = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-46c9a55a"]]);
447
+ const LpDropzone = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-afb08dd3"]]);
435
448
  export {
436
449
  LpDropzone as default
437
450
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.74.1",
3
+ "version": "0.74.2",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -406,6 +406,7 @@ let mounted = false
406
406
  onMounted(() => {
407
407
  mounted = true
408
408
  listen(props.pasteTarget)
409
+ measureRadius()
409
410
  })
410
411
  watch(
411
412
  () => props.pasteTarget,
@@ -430,6 +431,22 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(() => [
430
431
  props.animate && !revealed.value ? "lp-dropzone--waiting" : "",
431
432
  ].join(" "))
432
433
 
434
+ // The dashed frame is an SVG rect, which cannot inherit the box's
435
+ // border-radius: a zone rounded by the consumer (`rounded-control`) kept the
436
+ // card's curve on its dashes while the background clipped tighter. The kit's
437
+ // own rounding stays a live token, so a theme that changes it still applies.
438
+ const measuredRadius = ref("")
439
+ const frameRadius = computed(() =>
440
+ rootClass.value.split(/\s+/).includes("rounded-card") || !measuredRadius.value
441
+ ? "var(--radius-card)"
442
+ : measuredRadius.value,
443
+ )
444
+ function measureRadius() {
445
+ const zone = revealAnchor.value as HTMLElement | null
446
+ if (zone) measuredRadius.value = getComputedStyle(zone).borderTopLeftRadius
447
+ }
448
+ watch(rootClass, () => nextTick(measureRadius))
449
+
433
450
  // Overlays open in the window this component renders in (an LpFrame's, inside one).
434
451
  const portalTo = usePortalTarget()
435
452
  // What happens in another document (the page around a frame, or a frame in
@@ -473,7 +490,7 @@ const guardOutside = useOutsideGuard()
473
490
  y="0.5"
474
491
  width="calc(100% - 1px)"
475
492
  height="calc(100% - 1px)"
476
- rx="var(--radius-card)"
493
+ :rx="frameRadius"
477
494
  fill="none"
478
495
  stroke-width="1"
479
496
  stroke-dasharray="6 5"
@@ -526,7 +543,9 @@ const guardOutside = useOutsideGuard()
526
543
  <!-- A zone too narrow for the field (a thumbnail beside its controls)
527
544
  keeps its picture and opens the field under itself instead. -->
528
545
  <PopoverRoot :open="linking && floating" @update:open="(open: boolean) => !open && stopLink(false)">
529
- <PopoverAnchor :reference="revealAnchor ?? undefined" />
546
+ <!-- Positioned by `reference`; its own empty element must not be a flex
547
+ item, or the zone's gap adds a strip under the content. -->
548
+ <PopoverAnchor :reference="revealAnchor ?? undefined" class="hidden" />
530
549
  <PopoverPortal :to="portalTo">
531
550
  <PopoverContent
532
551
  @interact-outside="guardOutside"