Skip to content

Commit 4416967

Browse files
feat(components): [Toolbar] implements
1 parent 6fae5e4 commit 4416967

21 files changed

+470
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Enter the component you want most in the components, leave the emojis and follow
5858
| Toast | 🚧 |
5959
| [ToggleGroup](https://vue-primitives.netlify.app/?path=/story/components-togglegroup--single) ||
6060
| [Toggle](https://vue-primitives.netlify.app/?path=/story/components-toggle--styled) ||
61-
| Toolbar | 🚧 |
61+
| [Toolbar](https://vue-primitives.netlify.app/?path=/story/components-toolbar--styled) | |
6262
| Tooltip | 🚧 |
6363

6464
## Utilites
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Ref } from 'vue'
2+
import { createContext } from '../hooks/index.ts'
3+
import type { PrimitiveProps } from '../primitive/index.ts'
4+
import type { RovingFocusGroupProps } from '../roving-focus/RovingFocusGroup.ts'
5+
6+
export interface ToolbarProps extends PrimitiveProps {
7+
orientation?: RovingFocusGroupProps['orientation']
8+
loop?: RovingFocusGroupProps['loop']
9+
dir?: RovingFocusGroupProps['dir']
10+
}
11+
12+
interface ToolbarContextValue {
13+
orientation: () => Required<RovingFocusGroupProps>['orientation']
14+
dir: Ref<Required<RovingFocusGroupProps>['dir']>
15+
}
16+
export const [provideToolbarContext, useToolbarContext] = createContext<ToolbarContextValue>('Toolbar')
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script setup lang="ts">
2+
import { useDirection } from '../direction/index.ts'
3+
import { Primitive } from '../primitive/index.ts'
4+
import { RovingFocusGroup } from '../roving-focus/index.ts'
5+
import { type ToolbarProps, provideToolbarContext } from './Toolbar.ts'
6+
7+
defineOptions({
8+
name: 'Toolbar',
9+
inheritAttrs: false,
10+
})
11+
12+
const props = withDefaults(defineProps<ToolbarProps>(), {
13+
orientation: 'horizontal',
14+
loop: true,
15+
})
16+
17+
const direction = useDirection(() => props.dir)
18+
19+
provideToolbarContext({
20+
orientation() {
21+
return props.orientation
22+
},
23+
dir: direction,
24+
})
25+
</script>
26+
27+
<template>
28+
<RovingFocusGroup
29+
as-child
30+
:orientation="orientation"
31+
:dir="direction"
32+
:loop="loop"
33+
>
34+
<Primitive
35+
:as="as"
36+
:as-child="asChild"
37+
role="toolbar"
38+
:aria-orientation="orientation"
39+
:dir="direction"
40+
v-bind="$attrs"
41+
>
42+
<slot />
43+
</Primitive>
44+
</RovingFocusGroup>
45+
</template>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import type { PrimitiveProps } from '../primitive/index.ts'
2+
3+
export interface ToolbarButtonProps extends PrimitiveProps {
4+
disabled?: boolean
5+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script setup lang="ts">
2+
import { Primitive } from '../primitive/index.ts'
3+
import { RovingFocusGroupItem } from '../roving-focus/index.ts'
4+
import type { ToolbarButtonProps } from './ToolbarButton.ts'
5+
6+
defineOptions({
7+
name: 'ToolbarButton',
8+
inheritAttrs: false,
9+
})
10+
11+
withDefaults(defineProps<ToolbarButtonProps>(), {
12+
as: 'button',
13+
})
14+
</script>
15+
16+
<template>
17+
<RovingFocusGroupItem
18+
as-child
19+
:focusable="!disabled"
20+
>
21+
<Primitive
22+
:as="as"
23+
:as-child="asChild"
24+
type="button"
25+
v-bind="$attrs"
26+
>
27+
<slot />
28+
</Primitive>
29+
</RovingFocusGroupItem>
30+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { PrimitiveProps } from '../primitive/index.ts'
2+
3+
export interface ToolbarLinkProps extends PrimitiveProps {}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script setup lang="ts">
2+
import { useAttrs } from 'vue'
3+
import { Primitive } from '../primitive/index.ts'
4+
import { RovingFocusGroupItem } from '../roving-focus/index.ts'
5+
import { composeEventHandlers } from '../utils/vue.ts'
6+
import { isFunction } from '../utils/is.ts'
7+
import type { ToolbarLinkProps } from './ToolbarLink.ts'
8+
9+
defineOptions({
10+
name: 'ToolbarLink',
11+
inheritAttrs: false,
12+
})
13+
14+
withDefaults(defineProps<ToolbarLinkProps>(), {
15+
as: 'a',
16+
})
17+
const attrs = useAttrs()
18+
19+
const onKeydown = composeEventHandlers((event) => {
20+
isFunction(attrs.onKeydown) && attrs.onKeydown(event)
21+
}, (event: KeyboardEvent) => {
22+
if (event.key === ' ') {
23+
(event.currentTarget as HTMLElement).click()
24+
}
25+
})
26+
</script>
27+
28+
<template>
29+
<RovingFocusGroupItem
30+
as-child
31+
focusable
32+
>
33+
<Primitive
34+
:as="as"
35+
:as-child="asChild"
36+
type="button"
37+
v-bind="{
38+
...attrs,
39+
onKeydown,
40+
}"
41+
>
42+
<slot />
43+
</Primitive>
44+
</RovingFocusGroupItem>
45+
</template>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { PrimitiveProps } from '../primitive/Primitive.ts'
2+
import type { SeparatorProps } from '../separator/index.ts'
3+
4+
export interface ToolbarSeparatorProps extends PrimitiveProps {
5+
decorative?: SeparatorProps['decorative']
6+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script setup lang="ts">
2+
import { Separator } from '../separator/index.ts'
3+
import { useToolbarContext } from './Toolbar.ts'
4+
import type { ToolbarSeparatorProps } from './ToolbarSeparator.ts'
5+
6+
defineOptions({
7+
name: 'ToolbarSeparator',
8+
})
9+
10+
withDefaults(defineProps<ToolbarSeparatorProps>(), {
11+
decorative: undefined,
12+
})
13+
14+
const context = useToolbarContext('ToolbarSeparator')
15+
</script>
16+
17+
<template>
18+
<Separator
19+
:as="as"
20+
:as-child="asChild"
21+
:orientation="context.orientation()"
22+
:decorative="decorative"
23+
>
24+
<slot />
25+
</Separator>
26+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { ToggleGroupProps, ToggleGroupType } from '../toggle-group/index.ts'
2+
3+
export interface ToolbarToggleGroupProps<T extends ToggleGroupType> extends Omit<ToggleGroupProps<T>, 'rovingFocus' | 'orientation' | 'dir'> {}

0 commit comments

Comments
 (0)