diff --git a/docs/app/components/content/examples/breadcrumb/BreadcrumbCustomSlotExample.vue b/docs/app/components/content/examples/breadcrumb/BreadcrumbCustomSlotExample.vue
index b5adde51..128ef6a2 100644
--- a/docs/app/components/content/examples/breadcrumb/BreadcrumbCustomSlotExample.vue
+++ b/docs/app/components/content/examples/breadcrumb/BreadcrumbCustomSlotExample.vue
@@ -3,7 +3,7 @@ const items = [{
label: 'Home',
to: '/'
}, {
- slot: 'dropdown' as const,
+ slot: 'dropdown',
icon: 'i-heroicons-ellipsis-horizontal',
children: [{
label: 'Documentation'
diff --git a/docs/app/components/content/examples/dropdown-menu/DropdownMenuCustomSlotExample.vue b/docs/app/components/content/examples/dropdown-menu/DropdownMenuCustomSlotExample.vue
new file mode 100644
index 00000000..0be51bfb
--- /dev/null
+++ b/docs/app/components/content/examples/dropdown-menu/DropdownMenuCustomSlotExample.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/app/components/content/examples/dropdown-menu/DropdownMenuOpenExample.vue b/docs/app/components/content/examples/dropdown-menu/DropdownMenuOpenExample.vue
new file mode 100644
index 00000000..51a35736
--- /dev/null
+++ b/docs/app/components/content/examples/dropdown-menu/DropdownMenuOpenExample.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/docs/content/3.components/accordion.md b/docs/content/3.components/accordion.md
index a79d1282..0a41063b 100644
--- a/docs/content/3.components/accordion.md
+++ b/docs/content/3.components/accordion.md
@@ -11,15 +11,17 @@ links:
## Usage
+### Items
+
Use the `items` prop as an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- `icon?: string`{lang="ts-type"}
- `trailingIcon?: string`{lang="ts-type"}
-- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
- `content?: string`{lang="ts-type"}
- `value?: string`{lang="ts-type"}
- `disabled?: boolean`{lang="ts-type"}
+- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
::component-code
---
@@ -200,7 +202,7 @@ props:
### With custom slot
-Use the `slot` property to customize a specific item.
+Use the `slot` property instead of the `#content` slot to customize a specific item.
::component-example
---
diff --git a/docs/content/3.components/breadcrumb.md b/docs/content/3.components/breadcrumb.md
index c3e50779..66dd6e05 100644
--- a/docs/content/3.components/breadcrumb.md
+++ b/docs/content/3.components/breadcrumb.md
@@ -8,11 +8,14 @@ links:
## Usage
+### Items
+
Use the `items` prop as an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- `icon?: string`{lang="ts-type"}
- `avatar?: AvatarProps`{lang="ts-type"}
+- `class?: any`{lang="ts-type"}
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
You can also pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
@@ -70,23 +73,57 @@ You can customize this icon globally in your `app.config.ts` under `ui.icons.che
## Examples
-### With custom slot
-
-Use the `slot` property to customize a specific item with a dropdown menu for example.
-
-:component-example{name="breadcrumb-custom-slot-example"}
-
### With separator slot
Use the `#separator` slot to customize the separator between each item.
:component-example{name="breadcrumb-separator-slot-example"}
+### With custom slot
+
+Use the `slot` property to customize a specific item.
+
+You will have access to the following slots:
+
+- `{{ item.slot }}`{lang="ts-type"}
+- `{{ item.slot }}-leading`{lang="ts-type"}
+- `{{ item.slot }}-label`{lang="ts-type"}
+- `{{ item.slot }}-trailing`{lang="ts-type"}
+
+:component-example{name="breadcrumb-custom-slot-example"}
+
+::tip{to="#slots"}
+You can also use the `item`, `item-leading`, `item-label` and `item-trailing` slots to customize all items.
+::
+
## API
### Props
-:component-props
+::component-props
+---
+ignore:
+ - as
+ - to
+ - target
+ - active
+ - activeClass
+ - inactiveClass
+ - exactActiveClass
+ - ariaCurrentValue
+ - href
+ - rel
+ - noRel
+ - prefetch
+ - noPrefetch
+ - prefetchedClass
+ - replace
+ - exact
+ - exactQuery
+ - exactHash
+ - external
+---
+::
### Slots
diff --git a/docs/content/3.components/dropdown-menu.md b/docs/content/3.components/dropdown-menu.md
index 65b440fe..47538d76 100644
--- a/docs/content/3.components/dropdown-menu.md
+++ b/docs/content/3.components/dropdown-menu.md
@@ -8,20 +8,361 @@ links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/benjamincanac/ui3/tree/dev/src/runtime/components/Dropdown.vue
-navigation:
- badge:
- label: Todo
---
## Usage
+Use a [Button](/components/button) or any other component in the default slot of the DropdownMenu.
+
+### Items
+
+Use the `items` prop as an array of objects with the following properties:
+
+- `label?: string`{lang="ts-type"}
+- `icon?: string`{lang="ts-type"}
+- `avatar?: AvatarProps`{lang="ts-type"}
+- `kbds?: string[] | KbdProps[]`{lang="ts-type"}
+- `type?: "link" | "label" | "separator"`{lang="ts-type"}
+- `disabled?: boolean`{lang="ts-type"}
+- `class?: any`{lang="ts-type"}
+- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
+- `select?(e: Event): void`{lang="ts-type"}
+
+You can also pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
+
+::component-code
+---
+prettier: true
+ignore:
+ - items
+ - class
+external:
+ - items
+class: 'justify-center'
+props:
+ items:
+ - - label: Benjamin
+ avatar:
+ src: 'https://avatars.githubusercontent.com/u/739984?v=4'
+ type: label
+ - - label: Profile
+ icon: i-heroicons-user
+ - label: Billing
+ icon: i-heroicons-credit-card
+ - label: Settings
+ icon: i-heroicons-cog
+ kbds:
+ - ','
+ - label: Keyboard shortcuts
+ icon: i-heroicons-computer-desktop
+ - - label: Team
+ icon: i-heroicons-users
+ - label: Invite users
+ icon: i-heroicons-user-plus
+ children:
+ - - label: Email
+ icon: i-heroicons-envelope
+ - label: Message
+ icon: i-heroicons-chat-bubble-left
+ - - label: More
+ icon: i-heroicons-plus-circle
+ - label: New team
+ icon: i-heroicons-plus
+ kbds:
+ - meta
+ - n
+ - - label: GitHub
+ icon: i-simple-icons-github
+ to: 'https://github.com/nuxt/ui'
+ target: _blank
+ - label: Support
+ icon: i-heroicons-lifebuoy
+ to: '/components/dropdown-menu'
+ - label: API
+ icon: i-heroicons-cloud
+ disabled: true
+ - - label: Logout
+ icon: i-heroicons-arrow-right-on-rectangle
+ kbds:
+ - shift
+ - meta
+ - q
+ class: 'w-48'
+slots:
+ default: |
+
+
+---
+
+:u-button{icon="i-heroicons-bars-3" color="gray" variant="outline"}
+::
+
+::tip
+Each item can take a `children` array to create a nested menu which can be controlled using the `open`, `defaultOpen` and `content` properties.
+::
+
+### Content
+
+Use the `content` prop to control how the DropdownMenu content is rendered, like its `align` or `side` for example.
+
+::component-code
+---
+prettier: true
+ignore:
+ - items
+ - class
+external:
+ - items
+items:
+ content.align:
+ - start
+ - center
+ - end
+ content.side:
+ - right
+ - left
+ - top
+ - bottom
+class: 'justify-center'
+props:
+ items:
+ - label: Profile
+ icon: i-heroicons-user
+ - label: Billing
+ icon: i-heroicons-credit-card
+ - label: Settings
+ icon: i-heroicons-cog
+ content:
+ align: start
+ side: bottom
+ sideOffset: 8
+ class: 'w-48'
+slots:
+ default: |
+
+
+---
+
+:u-button{label="Open" icon="i-heroicons-bars-3" color="gray" variant="outline"}
+::
+
+### Arrow
+
+Use the `arrow` prop to display an arrow on the DropdownMenu.
+
+::component-code
+---
+prettier: true
+ignore:
+ - arrow
+ - items
+ - class
+external:
+ - items
+class: 'justify-center'
+props:
+ arrow: true
+ items:
+ - label: Profile
+ icon: i-heroicons-user
+ - label: Billing
+ icon: i-heroicons-credit-card
+ - label: Settings
+ icon: i-heroicons-cog
+ class: 'w-48'
+slots:
+ default: |
+
+
+---
+
+:u-button{label="Open" icon="i-heroicons-bars-3" color="gray" variant="outline"}
+::
+
+### Size
+
+Use the `size` prop to control the size of the DropdownMenu.
+
+::component-code
+---
+prettier: true
+ignore:
+ - items
+ - class
+ - content.align
+external:
+ - items
+class: 'justify-center'
+props:
+ size: xl
+ items:
+ - label: Profile
+ icon: i-heroicons-user
+ - label: Billing
+ icon: i-heroicons-credit-card
+ - label: Settings
+ icon: i-heroicons-cog
+ content:
+ align: start
+ class: 'w-48'
+slots:
+ default: |
+
+
+---
+
+:u-button{size="xl" label="Open" icon="i-heroicons-bars-3" color="gray" variant="outline"}
+::
+
+::important
+The `size` prop will not be proxied to the Button, you need to set it yourself.
+::
+
+::note
+When using the same size, the DropdownMenu items will be perfectly aligned with the Button.
+::
+
+### Disabled
+
+Use the `disabled` prop to disable the DropdownMenu.
+
+::component-code
+---
+prettier: true
+ignore:
+ - items
+ - class
+external:
+ - items
+class: 'justify-center'
+props:
+ disabled: true
+ items:
+ - label: Profile
+ icon: i-heroicons-user
+ - label: Billing
+ icon: i-heroicons-credit-card
+ - label: Settings
+ icon: i-heroicons-cog
+ class: 'w-48'
+slots:
+ default: |
+
+
+---
+
+:u-button{label="Open" icon="i-heroicons-bars-3" color="gray" variant="outline"}
+::
+
## Examples
+### Control open state
+
+You can control the open state by using the `default-open` prop or the `v-model:open` directive.
+
+::component-example
+---
+name: 'dropdown-menu-open-example'
+class: 'justify-center'
+---
+::
+
+::note
+In this example, press :kbd{value="O"} to toggle the DropdownMenu.
+::
+
+### With custom slot
+
+Use the `slot` property to customize a specific item.
+
+You will have access to the following slots:
+
+- `{{ item.slot }}`{lang="ts-type"}
+- `{{ item.slot }}-leading`{lang="ts-type"}
+- `{{ item.slot }}-label`{lang="ts-type"}
+- `{{ item.slot }}-trailing`{lang="ts-type"}
+
+::component-example
+---
+name: 'dropdown-menu-custom-slot-example'
+class: 'justify-center'
+---
+::
+
+::tip{to="#slots"}
+You can also use the `item`, `item-leading`, `item-label` and `item-trailing` slots to customize all items.
+::
+
+### Extract shortcuts
+
+When you have some items with `kbds` property (displaying some [Kbd](/components/kbd)), you can easily make them work with the [defineShortcuts](/composables/define-shortcuts) composable.
+
+Inside the `defineShortcuts` composable, there is an `extractShortcuts` utility that will extract the shortcuts recursively from the items and return an object that you can pass to `defineShortcuts`. It will automatically call the `select` function of the item when the shortcut is pressed.
+
+```vue
+
+```
+
+::note
+In this example, :kbd{value="meta"} :kbd{value="E"}, :kbd{value="meta"} :kbd{value="I"} and :kbd{value="meta"} :kbd{value="N"} would trigger the `select` function of the corresponding item.
+::
+
## API
### Props
-:component-props
+::component-props
+---
+ignore:
+ - as
+ - to
+ - target
+ - activeClass
+ - inactiveClass
+ - exactActiveClass
+ - ariaCurrentValue
+ - href
+ - rel
+ - noRel
+ - prefetch
+ - noPrefetch
+ - prefetchedClass
+ - replace
+ - exact
+ - exactQuery
+ - exactHash
+ - external
+---
+::
### Slots
diff --git a/docs/content/3.components/radio-group.md b/docs/content/3.components/radio-group.md
index e2f8de35..68867314 100644
--- a/docs/content/3.components/radio-group.md
+++ b/docs/content/3.components/radio-group.md
@@ -12,6 +12,10 @@ links:
## Usage
+Use the `v-model` directive to control the value of the RadioGroup.
+
+### Items
+
Use the `items` prop as an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
@@ -19,8 +23,6 @@ Use the `items` prop as an array of objects with the following properties:
- `value?: string`{lang="ts-type"}
- `disabled?: boolean`{lang="ts-type"}
-Use the `v-model` directive to control the value of the RadioGroup.
-
::component-code
---
ignore:
diff --git a/docs/content/3.components/tabs.md b/docs/content/3.components/tabs.md
index 024a7c63..c912f5b8 100644
--- a/docs/content/3.components/tabs.md
+++ b/docs/content/3.components/tabs.md
@@ -11,15 +11,17 @@ links:
## Usage
+### Items
+
Use the `items` prop as an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- `icon?: string`{lang="ts-type"}
- `avatar?: AvatarProps`{lang="ts-type"}
-- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
- `content?: string`{lang="ts-type"}
- `value?: string | number`{lang="ts-type"}
- `disabled?: boolean`{lang="ts-type"}
+- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
::component-code
---
@@ -207,7 +209,7 @@ Use the `#content` slot to customize the content of each item.
### With custom slot
-Use the `slot` property to customize a specific item.
+Use the `slot` property instead of the `#content` slot to customize a specific item.
:component-example{name="tabs-custom-slot-example"}
diff --git a/docs/content/3.components/tooltip.md b/docs/content/3.components/tooltip.md
index 9dd0a0be..244d25c0 100644
--- a/docs/content/3.components/tooltip.md
+++ b/docs/content/3.components/tooltip.md
@@ -88,6 +88,40 @@ slots:
This can be configured globally through the `tooltip.delayDuration` option in the [`App`](/components/app) component.
::
+### Content
+
+Use the `content` prop to control how the Tooltip content is rendered, like its `align` or `side` for example.
+
+::component-code
+---
+prettier: true
+ignore:
+ - text
+items:
+ content.align:
+ - start
+ - center
+ - end
+ content.side:
+ - right
+ - left
+ - top
+ - bottom
+props:
+ content:
+ align: center
+ side: bottom
+ sideOffset: 8
+ text: 'Open on GitHub'
+slots:
+ default: |
+
+
+---
+
+:u-button{icon="i-simple-icons-github"}
+::
+
### Arrow
Use the `arrow` prop to display an arrow on the Tooltip.
@@ -110,35 +144,6 @@ slots:
:u-button{icon="i-simple-icons-github"}
::
-### Content
-
-Use the `content` prop to control how the Tooltip content is rendered, like its side for example.
-
-::component-code
----
-prettier: true
-ignore:
- - text
-items:
- content.side:
- - right
- - left
- - top
- - bottom
-props:
- content:
- side: right
- sideOffset: 8
- text: 'Open on GitHub'
-slots:
- default: |
-
-
----
-
-:u-button{icon="i-simple-icons-github"}
-::
-
### Disabled
Use the `disabled` prop to disable the Tooltip.
diff --git a/docs/nuxt.config.ts b/docs/nuxt.config.ts
index 0c75214b..435ea7ba 100644
--- a/docs/nuxt.config.ts
+++ b/docs/nuxt.config.ts
@@ -128,6 +128,7 @@ export default defineNuxtConfig({
'UCheckbox',
'UChip',
'UCollapsible',
+ 'UDropdownMenu',
'UFormField',
'UIcon',
'UInput',
diff --git a/playground/app/pages/components/dropdown-menu.vue b/playground/app/pages/components/dropdown-menu.vue
index f939e1c2..fd6609d4 100644
--- a/playground/app/pages/components/dropdown-menu.vue
+++ b/playground/app/pages/components/dropdown-menu.vue
@@ -127,7 +127,7 @@ defineShortcuts(extractShortcuts(items))
-
+