Skip to content

Commit

Permalink
feat: draggable element (#1402)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
KermanX and antfu committed Apr 10, 2024
1 parent 1abcd35 commit 65a1cda
Show file tree
Hide file tree
Showing 26 changed files with 1,084 additions and 91 deletions.
4 changes: 2 additions & 2 deletions cypress/e2e/examples/basic.spec.ts
Expand Up @@ -48,15 +48,15 @@ context('Basic', () => {
cy.contains('Global Footer')
.should('not.exist')

cy.get('#page-root > #slide-container > #slide-content > #slideshow .slidev-page-2 > p')
cy.get('#page-root > #slide-container > #slide-content > #slideshow .slidev-page-2 > div > p')
.should('have.css', 'border-color', 'rgb(0, 128, 0)')
.should('not.have.css', 'color', 'rgb(128, 0, 0)')

goPage(5)

cy.get('#page-root > #slide-container > #slide-content > #slideshow .slidev-page-5 .slidev-code')
.should('have.text', '<div>{{$slidev.nav.currentPage}}</div>')
.get('#page-root > #slide-container > #slide-content > #slideshow .slidev-page-5 > p')
.get('#page-root > #slide-container > #slide-content > #slideshow .slidev-page-5 > div > p')
.should('have.text', 'Current Page: 5')
})

Expand Down
37 changes: 37 additions & 0 deletions demo/starter/slides.md
Expand Up @@ -559,6 +559,43 @@ database "MySql" {

[Learn More](https://sli.dev/guide/syntax.html#diagrams)

---
foo: bar
dragPos:
square: 691,33,167,_,-16
---

# Draggable Elements

Double-click on the draggable elements to edit their positions.

<br>

###### Directive Usage

```md
<img v-drag="'square'" src="https://sli.dev/logo.png">
```

<br>

###### Component Usage

```md
<v-drag text-3xl>
<carbon:arrow-up />
Use the `v-drag` component to have a draggable container!
</v-drag>
```

<v-drag pos="671,205,253,_,-15">
<div text-center text-3xl border border-main rounded>
Double-click me!
</div>
</v-drag>

<img v-drag="'square'" src="https://sli.dev/logo.png">

---
src: ./pages/multiple-entries.md
hide: false
Expand Down
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Expand Up @@ -28,6 +28,10 @@ const Guide: DefaultTheme.NavItemWithLink[] = [
text: 'Animations',
link: '/guide/animations',
},
{
text: 'Draggable Elements',
link: '/guide/draggable',
},
{
text: 'Presenter Mode',
link: '/guide/presenter-mode',
Expand Down
4 changes: 4 additions & 0 deletions docs/builtin/components.md
Expand Up @@ -272,6 +272,10 @@ Parameters:

See https://sli.dev/guide/animations.html

### `VDrag`

See https://sli.dev/guide/draggable.html

### `SlidevVideo`

Embed a video.
Expand Down
1 change: 1 addition & 0 deletions docs/custom/index.md
Expand Up @@ -118,6 +118,7 @@ In addition, every slide accepts the following configuration in the Frontmatter
- `title` (`string`): Override the title for the `<TitleRenderer>` and `<Toc>` components (learn more [here](/builtin/components.html#titlerenderer)).
- `transition` (`string | TransitionProps`): Defines the transition between the slide and the next one (learn more [here](/guide/animations.html#slide-transitions)).
- `zoom` (`number`): Custom zoom scale. Useful for slides with a lot of content.
- `dragPos` (`Record<string,string>`): Used as positions of draggable elements (learn more [here](/guide/draggable.html).

## Directory Structure

Expand Down
66 changes: 66 additions & 0 deletions docs/guide/draggable.md
@@ -0,0 +1,66 @@
# Draggable Elements

Draggable elements give you the ability to move, resize and rotate elements by dragging them with the mouse. This is useful for creating floating elements in your slides.

## Directive Usage

### Data from the frontmatter

```md
---
dragPos:
square: Left,Top,Width,Height,Rotate
---

<img v-drag="'square'" src="https://sli.dev/logo.png">
```

### Data from the directive value

::: warning
Slidev use regex to update the position value in the slide content. If you meet problems, please use the frontmatter to define the values instead.
:::

```md
<img v-drag="[Left,Top,Width,Height,Rotate]" src="https://sli.dev/logo.png">
```

## Component Usage

### Data from the frontmatter

```md
---
dragPos:
foo: Left,Top,Width,Height,Rotate
---

<v-drag pos="foo" text-3xl>
<carbon:arrow-up />
Use the `v-drag` component to have a draggable container!
</v-drag>
```

### Data from props

```md
<v-drag pos="Left,Top,Width,Height,Rotate" text-3xl>
<carbon:arrow-up />
Use the `v-drag` component to have a draggable container!
</v-drag>
```

## Automatic Height

You can set `Height` to `NaN` (if you use the directive) or `_` (if you use the component) to make the height of the draggable element automatically adjust to its content.

## Create a Draggable Element

When you first create a draggable element, you don't need to specify the position value (but you need to specify the position name if you want to use the frontmatter). Slidev will automatically generate the initial position value for you.

## Controls

- Double click the draggable element to start dragging it.
- You can also use the arrow keys to move the element.
- Hold `Shift` while dragging to preserve its aspect ratio.
- Click outside the draggable element to stop dragging it.
27 changes: 27 additions & 0 deletions packages/client/builtin/VDrag.vue
@@ -0,0 +1,27 @@
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
import type { DragElementMarkdownSource } from '../composables/useDragElements'
import { useDragElement } from '../composables/useDragElements'
const props = defineProps<{
pos?: string
markdownSource?: DragElementMarkdownSource
}>()
const { id, container, containerStyle, mounted, unmounted, startDragging } = useDragElement(null, props.pos, props.markdownSource)
onMounted(mounted)
onUnmounted(unmounted)
</script>

<template>
<div
ref="container"
:data-drag-id="id"
:style="containerStyle"
class="p-1"
@dblclick="startDragging"
>
<slot />
</div>
</template>

0 comments on commit 65a1cda

Please sign in to comment.