Skip to content

Commit 834fce2

Browse files
authored
Feature/auto snap (#137)
* Auto-snap to prev/next element * Add changeset
1 parent d19f17d commit 834fce2

File tree

5 files changed

+66
-5
lines changed

5 files changed

+66
-5
lines changed

.changeset/common-shrimps-tan.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"slidev-addon-fancy-arrow": minor
3+
---
4+
5+
Auto-snap to prev/next element if no snap target or absolute position is specified

components/FancyArrow.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,19 @@ const point1: Ref<AbsolutePosition | undefined> = useEndpointResolution(
6262
slideContainer,
6363
svgContainer,
6464
endpoint1,
65+
{
66+
self: root,
67+
direction: "prev",
68+
},
6569
);
6670
const point2: Ref<AbsolutePosition | undefined> = useEndpointResolution(
6771
slideContainer,
6872
svgContainer,
6973
endpoint2,
74+
{
75+
self: root,
76+
direction: "next",
77+
},
7078
);
7179
7280
const { arcSvg, textPosition } = useRoughArrow({

components/parse-option.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,12 @@ export function compileArrowEndpointProps(
7373
};
7474
}
7575

76-
return {
77-
x: Number(props.x ?? 0),
78-
y: Number(props.y ?? 0),
79-
};
76+
if (props.x != undefined || props.y != undefined) {
77+
return {
78+
x: Number(props.x ?? 0),
79+
y: Number(props.y ?? 0),
80+
};
81+
}
82+
83+
return undefined;
8084
}

components/use-element-position.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,35 @@ export function useEndpointResolution(
2424
slideContainerRef: Ref<Element | undefined>,
2525
rootElementRef: Ref<SVGSVGElement | undefined>,
2626
endpointRef: Ref<AbsolutePosition | SnapTarget | undefined>,
27+
fallbackOption: {
28+
self: Ref<HTMLElement | undefined>;
29+
direction: "next" | "prev";
30+
},
2731
): Ref<AbsolutePosition | undefined> {
2832
const { $scale } = useSlideContext();
2933
const isSlideActive = useIsSlideActive();
3034

3135
const snappedElementInfo = computed(() => {
3236
const endpoint = endpointRef.value;
33-
if (endpoint == null || !("query" in endpoint)) {
37+
if (endpoint == null) {
38+
// If endpoint is undefined, we try to use the next or previous element
39+
// as fallback snap target.
40+
const selfElem = fallbackOption.self.value;
41+
if (!selfElem) {
42+
return undefined;
43+
}
44+
const element =
45+
fallbackOption.direction === "next"
46+
? selfElem.nextElementSibling
47+
: selfElem.previousElementSibling;
48+
return {
49+
element,
50+
snapPosition: undefined,
51+
};
52+
}
53+
if (!("query" in endpoint)) {
54+
// endpoint is AbsolutePosition
55+
// so we don't need to resolve the element.
3456
return undefined;
3557
}
3658
const element =

slides.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ Use `pos1` and `pos2` to specify the anchor point on the snapped elements.
295295

296296
---
297297

298+
# Auto-snap
299+
300+
<div>
301+
If no snap target or absolute position is specified, the arrow will automatically snap to the next or previous element in the slide.
302+
</div>
303+
304+
<div p-8 flex justify-center>Prev</div>
305+
306+
<FancyArrow />
307+
308+
<div p-8 flex justify-center>Next</div>
309+
310+
```html
311+
<div p-8 flex justify-center>Prev</div>
312+
313+
<FancyArrow />
314+
315+
<div p-8 flex justify-center>Next</div>
316+
```
317+
318+
---
319+
298320
# Appearance
299321

300322
<div grid="~ cols-3 gap-4" mt-6 h-100>

0 commit comments

Comments
 (0)