Skip to content

Commit

Permalink
feat(VSpeedDial): port to v3 (#19308)
Browse files Browse the repository at this point in the history
Co-authored-by: Kael <kaelwd@gmail.com>
  • Loading branch information
johnleider and KaelWD committed Mar 5, 2024
1 parent a98a4ca commit 736d688
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/api-generator/src/locale/en/VMenu.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"props": {
"attach": "Specifies which DOM element the overlay content should teleport to. Can be a direct element reference, querySelector string, or `true` to disable teleporting. Uses `body` by default. Generally not recommended except as a last resort: the default positioning algorithm should handle most scenarios better than is possible without teleporting, and you may have unexpected behavior if the menu ends up as child of its activator.",
"id": "The unique identifier of the component.",
"closeOnClick": "Designates if menu should close on outside-activator click.",
"closeOnContentClick": "Designates if menu should close when its content is clicked.",
"closeDelay": "Milliseconds to wait before closing component. Only works with the **open-on-hover** prop.",
Expand Down
4 changes: 4 additions & 0 deletions packages/docs/src/data/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@
{
"title": "sparklines",
"subfolder": "components"
},
{
"title": "speed-dials",
"subfolder": "components"
}
]
},
Expand Down
70 changes: 70 additions & 0 deletions packages/docs/src/examples/v-speed-dial/usage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<ExamplesUsageExample
v-model="model"
:code="code"
:name="name"
:options="options"
>
<v-sheet class="text-center" height="420">
<v-fab icon="$vuetify" size="large">
<v-icon></v-icon>

<v-speed-dial
v-bind="props"
>
<v-btn key="1" icon="$success"></v-btn>
<v-btn key="2" icon="$info"></v-btn>
<v-btn key="3" icon="$warning"></v-btn>
<v-btn key="4" icon="$error"></v-btn>
</v-speed-dial>
</v-fab>
</v-sheet>

<template v-slot:configuration>
<v-select v-model="location1" :items="locations1" label="Location 1"></v-select>
<v-select v-model="location2" :items="locations2" label="Location 2"></v-select>
<v-select v-model="transition" :items="transitions" label="Transition"></v-select>
</template>
</ExamplesUsageExample>
</template>

<script setup>
const name = 'v-speed-dial'
const model = shallowRef('default')
const options = []
const location1 = shallowRef('Bottom')
const locations1 = ['Top', 'Bottom', 'Left', 'Right']
const location2 = shallowRef('Center')
const locations2 = ['Top', 'Bottom', 'Center', 'Left', 'Right']
const location = computed(() => `${location1.value.toLowerCase()} ${location2.value.toLowerCase()}`)
const transition = shallowRef('fade-transition')
const transitions = ['scale-transition', 'slide-x-transition', 'slide-y-transition', 'slide-x-reverse-transition', 'slide-y-reverse-transition']
const props = computed(() => {
return {
activator: 'parent',
location: location.value,
transition: transition.value,
}
})
const slots = computed(() => {
return `
<template v-slot:activator="{ props: activatorProps }">
<v-fab
v-bind="activatorProps"
size="large"
icon="$vuetify"
></v-fab>
</template>
<v-btn key="1" icon="$success"></v-btn>
<v-btn key="2" icon="$info"></v-btn>
<v-btn key="3" icon="$warning"></v-btn>
<v-btn key="4" icon="$error"></v-btn>
`
})
const code = computed(() => {
return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`
})
</script>
6 changes: 6 additions & 0 deletions packages/docs/src/pages/en/components/all.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ Navigation components are used to navigate between different views or pages.

</ComponentsListItem>

<ComponentsListItem name="Speed dials" src="speed-dials" labs>

The speed dial component is a floating action button that can reveal additional actions when clicked

</ComponentsListItem>

<ComponentsListItem name="System bar" src="system-bars">

The system bar component shows application information with iconography, time, and more
Expand Down
60 changes: 60 additions & 0 deletions packages/docs/src/pages/en/components/speed-dials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
emphasized: true
meta:
nav: Speed Dials
title: Speed Dial component
description: The speed dial component is a floating action button that can reveal additional actions when clicked.
keywords: speed dial, fab, vuetify speed dial component, vue speed dial component
related:
- /components/buttons/
- /components/icons/
- /styles/transitions/
features:
report: true
---

# Speed Dials

The `v-speed-dial` component can be used as a floating action button that can reveal additional actions when clicked.

<PageFeatures />

::: warning

This feature requires [v3.5.8](/getting-started/release-notes/?version=v3.5.8)

:::

## Installation

Labs components require a manual import and installation of the component.

```js { resource="src/plugins/vuetify.js" }
import { VSpeedDial } from 'vuetify/labs/VSpeedDial'

export default createVuetify({
components: {
VSpeedDial,
},
})
```

## Usage

Speed dials can be attached to material to signify a promoted action in your application. The default size will be used in most cases, whereas the `small` variant can be used to maintain continuity with similar sized elements.

<ExamplesUsage name="v-speed-dial" />

<PromotedEntry />

## API

| Component | Description |
| - | - |
| [v-speed-dial](/api/v-speed-dial/) | Primary Component |

<ApiInline hide-links />

### Guide

Coming soon.
1 change: 1 addition & 0 deletions packages/docs/src/pages/en/labs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ The following is a list of available and up-and-coming components for use with L
| - | - | - |
| [v-calendar](/components/calendars/) | A calendar component | [v3.4.9](/getting-started/release-notes/?version=v3.4.9) |
| [v-empty-state](/components/empty-states/) | A component for displaying empty states | [v3.5.7](/getting-started/release-notes/?version=v3.5.7) |
| [v-speed-dial](/components/speed-dials/) | A component for display actions | [v3.5.8](/getting-started/release-notes/?version=v3.5.8) |
| [v-sparkline](/components/sparklines/) | A basic data display component | [v3.5.5](/getting-started/release-notes/?version=v3.5.5) |

::: warning
Expand Down
24 changes: 16 additions & 8 deletions packages/vuetify/src/composables/transition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Utilities
import { h, mergeProps, Transition } from 'vue'
import { h, mergeProps, Transition, TransitionGroup } from 'vue'
import { propsFactory } from '@/util'

// Types
Expand All @@ -16,20 +16,28 @@ export const makeTransitionProps = propsFactory({
interface MaybeTransitionProps extends TransitionProps {
transition?: string | boolean | TransitionProps & { component?: any }
disabled?: boolean
group?: boolean
}

export const MaybeTransition: FunctionalComponent<MaybeTransitionProps> = (props, { slots }) => {
const { transition, disabled, ...rest } = props
const { transition, disabled, group, ...rest } = props

const { component = Transition, ...customProps } = typeof transition === 'object' ? transition : {}
const {
component = group ? TransitionGroup : Transition,
...customProps
} = typeof transition === 'object' ? transition : {}

return h(
component,
mergeProps(typeof transition === 'string'
? { name: disabled ? '' : transition }
: customProps as any,
rest as any,
{ disabled }),
mergeProps(
typeof transition === 'string'
? { name: disabled ? '' : transition }
: customProps as any,
typeof transition === 'string'
? {}
: { disabled, group },
rest as any,
),
slots
)
}
2 changes: 1 addition & 1 deletion packages/vuetify/src/labs/VFab/VFab.sass
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
vertical-align: middle

.v-fab--app &
margin: 4px
margin: 12px

.v-fab--absolute &
position: absolute
Expand Down
2 changes: 2 additions & 0 deletions packages/vuetify/src/labs/VSpeedDial/VSpeedDial.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.v-speed-dial__content
gap: 8px
60 changes: 60 additions & 0 deletions packages/vuetify/src/labs/VSpeedDial/VSpeedDial.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Styles
import './VSpeedDial.sass'

// Components
import { VDefaultsProvider } from '@/components/VDefaultsProvider'
import { makeVMenuProps, VMenu } from '@/components/VMenu/VMenu'

// Composables
import { makeComponentProps } from '@/composables/component'
import { makeTransitionProps, MaybeTransition } from '@/composables/transition'

// Utilities
import { genericComponent, propsFactory, useRender } from '@/util'

export const makeVSpeedDialProps = propsFactory({
...makeComponentProps(),
...makeVMenuProps({ offset: 8, minWidth: 0, location: 'top center' as const }),
...makeTransitionProps({ transition: 'fade-transition' }),
}, 'VSpeedDial')

export const VSpeedDial = genericComponent()({
name: 'VSpeedDial',

props: makeVSpeedDialProps(),

setup (props, { slots }) {
useRender(() => {
const menuProps = VMenu.filterProps(props)

return (
<VMenu
{ ...menuProps }
class={ props.class }
style={ props.style }
contentClass="v-speed-dial__content"
>
<VDefaultsProvider
defaults={{
VBtn: {
size: 'small',
},
}}
>
<MaybeTransition
appear
group
transition={ props.transition }
>
{ slots.default?.() }
</MaybeTransition>
</VDefaultsProvider>
</VMenu>
)
})

return {}
},
})

export type VSpeedDial = InstanceType<typeof VSpeedDial>
1 change: 1 addition & 0 deletions packages/vuetify/src/labs/VSpeedDial/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { VSpeedDial } from './VSpeedDial'
1 change: 1 addition & 0 deletions packages/vuetify/src/labs/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './VCalendar'
export * from './VFab'
export * from './VPicker'
export * from './VSparkline'
export * from './VSpeedDial'
export * from './VEmptyState'

0 comments on commit 736d688

Please sign in to comment.