From b5ca0d96f1de049dde698e57a340fc8ee54dd2e7 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Thu, 31 Oct 2024 11:27:52 +0100 Subject: [PATCH] feat(NavigationMenu): add `item-content` slot --- .../NavigationMenuContentSlotExample.vue | 88 +++++++++++++++++++ docs/content/3.components/navigation-menu.md | 17 +++- src/runtime/components/NavigationMenu.vue | 54 ++++++------ src/theme/navigation-menu.ts | 5 +- .../__snapshots__/NavigationMenu.spec.ts.snap | 42 ++++----- 5 files changed, 156 insertions(+), 50 deletions(-) create mode 100644 docs/app/components/content/examples/navigation-menu/NavigationMenuContentSlotExample.vue diff --git a/docs/app/components/content/examples/navigation-menu/NavigationMenuContentSlotExample.vue b/docs/app/components/content/examples/navigation-menu/NavigationMenuContentSlotExample.vue new file mode 100644 index 00000000..1466d97c --- /dev/null +++ b/docs/app/components/content/examples/navigation-menu/NavigationMenuContentSlotExample.vue @@ -0,0 +1,88 @@ + + + diff --git a/docs/content/3.components/navigation-menu.md b/docs/content/3.components/navigation-menu.md index bc8d8df8..6f42215f 100644 --- a/docs/content/3.components/navigation-menu.md +++ b/docs/content/3.components/navigation-menu.md @@ -560,6 +560,7 @@ You will have access to the following slots: - `#{{ item.slot }}-leading`{lang="ts-type"} - `#{{ item.slot }}-label`{lang="ts-type"} - `#{{ item.slot }}-trailing`{lang="ts-type"} +- `#{{ item.slot }}-content`{lang="ts-type"} ::component-example --- @@ -568,7 +569,21 @@ name: 'navigation-menu-custom-slot-example' :: ::tip{to="#slots"} -You can also use the `#item`, `#item-leading`, `#item-label` and `#item-trailing` slots to customize all items. +You can also use the `#item`, `#item-leading`, `#item-label`, `#item-trailing` and `#item-content` slots to customize all items. +:: + +### With content slot + +Use the `#item-content` slot or the `slot` property (`#{{ item.slot }}-content`) to customize the content of a specific item. + +::component-example +--- +name: 'navigation-menu-content-slot-example' +--- +:: + +::note +In this example, we add the `sm:w-[var(--radix-navigation-menu-viewport-width)]` class on the `viewport` to have a dynamic width. This requires to set a width on the content's first child. :: ## API diff --git a/src/runtime/components/NavigationMenu.vue b/src/runtime/components/NavigationMenu.vue index b145ee6e..cb60d7db 100644 --- a/src/runtime/components/NavigationMenu.vue +++ b/src/runtime/components/NavigationMenu.vue @@ -78,6 +78,7 @@ export type NavigationMenuSlots = { 'item-leading': SlotProps 'item-label': SlotProps 'item-trailing': SlotProps + 'item-content': SlotProps } & DynamicSlots> @@ -153,7 +154,8 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0] v-bind="(typeof item.badge === 'string' || typeof item.badge === 'number') ? { label: item.badge } : item.badge" :class="ui.linkTrailingBadge({ class: props.ui?.linkTrailingBadge })" /> - + + @@ -172,10 +174,10 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0] > @@ -183,33 +185,35 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0] - -
    -
  • - - - - + + +
      +
    • + + + + -
      -

      - {{ get(childItem, props.labelKey as string) }} +

      +

      + {{ get(childItem, props.labelKey as string) }} - -

      -

      - {{ childItem.description }} -

      -
      - - - -
    • -
    + +

    +

    + {{ childItem.description }} +

    + +
    +
    +
    +
  • +
+
-