diff --git a/docs/app/components/content/examples/context-menu/ContextMenuCheckboxItemsExample.vue b/docs/app/components/content/examples/context-menu/ContextMenuCheckboxItemsExample.vue
index ea6c558c..1859d4af 100644
--- a/docs/app/components/content/examples/context-menu/ContextMenuCheckboxItemsExample.vue
+++ b/docs/app/components/content/examples/context-menu/ContextMenuCheckboxItemsExample.vue
@@ -14,8 +14,8 @@ const items = computed(() => [{
onUpdateChecked(checked: boolean) {
showSidebar.value = checked
},
- onSelect(e?: Event) {
- e?.preventDefault()
+ onSelect(e: Event) {
+ e.preventDefault()
}
}, {
label: 'Show Toolbar',
diff --git a/docs/app/components/content/examples/dropdown-menu/DropdownMenuCheckboxItemsExample.vue b/docs/app/components/content/examples/dropdown-menu/DropdownMenuCheckboxItemsExample.vue
index fe9b2f40..4e427694 100644
--- a/docs/app/components/content/examples/dropdown-menu/DropdownMenuCheckboxItemsExample.vue
+++ b/docs/app/components/content/examples/dropdown-menu/DropdownMenuCheckboxItemsExample.vue
@@ -17,8 +17,8 @@ const items = computed(() => [{
onUpdateChecked(checked: boolean) {
showBookmarks.value = checked
},
- onSelect(e?: Event) {
- e?.preventDefault()
+ onSelect(e: Event) {
+ e.preventDefault()
}
}, {
label: 'Show History',
diff --git a/playground/app/pages/components/command-palette.vue b/playground/app/pages/components/command-palette.vue
index ab350dd7..37bc9031 100644
--- a/playground/app/pages/components/command-palette.vue
+++ b/playground/app/pages/components/command-palette.vue
@@ -33,7 +33,8 @@ const groups = computed(() => [{
icon: 'i-heroicons-document-plus',
loading: loading.value,
onSelect(e: Event) {
- e?.preventDefault()
+ e.preventDefault()
+
toast.add({ title: 'New file added!' })
loading.value = true
@@ -48,7 +49,8 @@ const groups = computed(() => [{
suffix: 'Create a new folder in the current directory or workspace.',
icon: 'i-heroicons-folder-plus',
onSelect(e: Event) {
- e?.preventDefault()
+ e.preventDefault()
+
toast.add({ title: 'New folder added!' })
},
kbds: ['meta', 'F']
@@ -57,7 +59,8 @@ const groups = computed(() => [{
suffix: 'Add a hashtag to the current item.',
icon: 'i-heroicons-hashtag',
onSelect(e: Event) {
- e?.preventDefault()
+ e.preventDefault()
+
toast.add({ title: 'Hashtag added!' })
},
kbds: ['meta', 'H']
@@ -66,7 +69,8 @@ const groups = computed(() => [{
suffix: 'Add a label to the current item.',
icon: 'i-heroicons-tag',
onSelect(e: Event) {
- e?.preventDefault()
+ e.preventDefault()
+
toast.add({ title: 'Label added!' })
},
kbds: ['meta', 'L']
diff --git a/playground/app/pages/components/context-menu.vue b/playground/app/pages/components/context-menu.vue
index 6deed524..3afa2ed1 100644
--- a/playground/app/pages/components/context-menu.vue
+++ b/playground/app/pages/components/context-menu.vue
@@ -1,9 +1,12 @@
diff --git a/playground/app/pages/components/dropdown-menu.vue b/playground/app/pages/components/dropdown-menu.vue
index 295f3cda..20f5a924 100644
--- a/playground/app/pages/components/dropdown-menu.vue
+++ b/playground/app/pages/components/dropdown-menu.vue
@@ -1,7 +1,9 @@
diff --git a/src/runtime/components/ContextMenu.vue b/src/runtime/components/ContextMenu.vue
index e60b0aae..fa74aa64 100644
--- a/src/runtime/components/ContextMenu.vue
+++ b/src/runtime/components/ContextMenu.vue
@@ -24,6 +24,7 @@ export interface ContextMenuItem extends Omit extends Omit {
* @defaultValue appConfig.ui.icons.check
*/
checkedIcon?: string
+ /**
+ * The icon displayed when an item is loading.
+ * @defaultValue appConfig.ui.icons.loading
+ */
+ loadingIcon?: string
/** The content of the menu. */
content?: Omit
/**
@@ -113,6 +119,7 @@ const ui = computed(() => contextMenu({
:portal="portal"
:label-key="labelKey"
:checked-icon="checkedIcon"
+ :loading-icon="loadingIcon"
>
diff --git a/src/runtime/components/ContextMenuContent.vue b/src/runtime/components/ContextMenuContent.vue
index a8535811..f9efb73b 100644
--- a/src/runtime/components/ContextMenuContent.vue
+++ b/src/runtime/components/ContextMenuContent.vue
@@ -12,6 +12,7 @@ interface ContextMenuContentProps extends Omit props.items?.length ? (Array.isArray(props.items[0
-
+
+
@@ -106,6 +108,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
:items="item.children"
:align-offset="-4"
:label-key="labelKey"
+ :checked-icon="checkedIcon"
+ :loading-icon="loadingIcon"
v-bind="item.content"
>
diff --git a/src/runtime/components/DropdownMenu.vue b/src/runtime/components/DropdownMenu.vue
index cb65deaa..9e669564 100644
--- a/src/runtime/components/DropdownMenu.vue
+++ b/src/runtime/components/DropdownMenu.vue
@@ -24,6 +24,7 @@ export interface DropdownMenuItem extends Omit extends Omit
* @defaultValue appConfig.ui.icons.check
*/
checkedIcon?: string
+ /**
+ * The icon displayed when an item is loading.
+ * @defaultValue appConfig.ui.icons.loading
+ */
+ loadingIcon?: string
/**
* The content of the menu.
* @defaultValue { side: 'bottom', sideOffset: 8 }
@@ -123,6 +129,7 @@ const ui = computed(() => dropdownMenu({
:portal="portal"
:label-key="labelKey"
:checked-icon="checkedIcon"
+ :loading-icon="loadingIcon"
>
diff --git a/src/runtime/components/DropdownMenuContent.vue b/src/runtime/components/DropdownMenuContent.vue
index ddd20060..6ed7d2e5 100644
--- a/src/runtime/components/DropdownMenuContent.vue
+++ b/src/runtime/components/DropdownMenuContent.vue
@@ -13,6 +13,7 @@ interface DropdownMenuContentProps extends Omit props.items?.length ? (Array.isArray(props.items[0
-
+
+
@@ -115,6 +117,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
:align-offset="-4"
:side-offset="3"
:label-key="labelKey"
+ :checked-icon="checkedIcon"
+ :loading-icon="loadingIcon"
v-bind="item.content"
>
diff --git a/src/theme/context-menu.ts b/src/theme/context-menu.ts
index 4c806645..1656a1e7 100644
--- a/src/theme/context-menu.ts
+++ b/src/theme/context-menu.ts
@@ -28,6 +28,11 @@ export default (options: Required) => ({
itemLeadingIcon: ['text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] group-data-[state=open]:text-[var(--ui-text)]', options.theme.transitions && 'transition-colors']
}
},
+ loading: {
+ true: {
+ itemLeadingIcon: 'animate-spin'
+ }
+ },
size: {
xs: {
label: 'p-1 text-xs gap-1',
diff --git a/src/theme/dropdown-menu.ts b/src/theme/dropdown-menu.ts
index fd0bc707..04f8bb8d 100644
--- a/src/theme/dropdown-menu.ts
+++ b/src/theme/dropdown-menu.ts
@@ -29,6 +29,11 @@ export default (options: Required) => ({
itemLeadingIcon: ['text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] group-data-[state=open]:text-[var(--ui-text)]', options.theme.transitions && 'transition-colors']
}
},
+ loading: {
+ true: {
+ itemLeadingIcon: 'animate-spin'
+ }
+ },
size: {
xs: {
label: 'p-1 text-xs gap-1',