BlogPost

GitLab
Um artigo personalizável para exibir em uma página de blog.

Uso

O componente BlogPost oferece uma maneira flexível de exibir um elemento <article> com conteúdo personalizável, incluindo título, descrição, imagem, etc.

Apresentando o Nuxt Icon v1

Apresentando o Nuxt Icon v1

Conheça o Nuxt Icon v1 - uma solução de ícones moderna, versátil e personalizável para os seus projetos Nuxt.
Anthony Fu

Anthony Fu

antfu7

Use o componente BlogPosts para exibir vários posts de blog em um layout de grade responsivo.

Título

Use a prop title para exibir o título do BlogPost.

Introducing Nuxt Icon v1

<template>
  <NBlogPost title="Introducing Nuxt Icon v1" />
</template>

Descrição

Use a prop description para exibir a descrição do BlogPost.

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
  />
</template>

Dados

Use a prop date para exibir a data do BlogPost.

A data é formatada automaticamente para o locale atual. Você pode passar um objeto Date ou uma string.

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    date="2024-11-25"
  />
</template>

Badge

Use a prop badge para exibir um Badge no BlogPost.

Release

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    badge="Release"
  />
</template>

Você pode passar qualquer propriedade do componente Badge para personalizá-lo.

Release

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    :badge="{
      label: 'Release',
      color: 'primary',
      variant: 'solid'
    }"
  />
</template>

Imagem

Use a prop image para exibir uma imagem no BlogPost.

Se o @nuxt/image estiver instalado, o componente <NuxtImg> será usado no lugar da tag img nativa.
Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
  />
</template>

Autores

Use a prop authors para exibir uma lista de User no BlogPost como um array de objetos com as seguintes propriedades:

  • name?: string
  • description?: string
  • avatar?: Omit<AvatarProps, 'size'>
  • chip?: boolean | Omit<ChipProps, 'size' | 'inset'>
  • size?: UserProps['size']
  • orientation?: UserProps['orientation']

Você pode passar qualquer propriedade do componente Link, como to, target, etc.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
Anthony Fu

Anthony Fu

antfu7

<script setup lang="ts">
import type { UserProps } from '@nitro/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  }
])
</script>

<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { UserProps } from '@nitro/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  }
])
</script>

<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

Quando a prop authors tem mais de um item, o componente AvatarGroup é usado.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<script setup lang="ts">
import type { UserProps } from '@nitro/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png',
      loading: 'lazy'
    },
    to: 'https://github.com/benjamincanac',
    target: '_blank'
  }
])
</script>

<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { UserProps } from '@nitro/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png',
      loading: 'lazy'
    },
    to: 'https://github.com/benjamincanac',
    target: '_blank'
  }
])
</script>

<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

Você pode passar qualquer propriedade do componente <NuxtLink>, como to, target, rel, etc.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
  />
</template>

Variante

Use a prop variant para alterar o estilo do BlogPost.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
    variant="naked"
  />
</template>
A estilização será diferente conforme você forneça uma prop to ou uma image.

Orientação

Use a prop orientation para alterar a orientação do BlogPost. O padrão é vertical.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <NBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
    orientation="horizontal"
    variant="outline"
  />
</template>

API

Props

Prop Default Type
as'article'any

The element or component this component should render as.

title string
description string
date string | Date

The date of the blog post. Can be a string or a Date object.

badge string | BadgeProps

Display a badge on the blog post. Can be a string or an object. { color: 'neutral', variant: 'subtle' }

authors UserProps[]

The authors of the blog post.

image string | Partial<ImgHTMLAttributes> & { [key: string]: any; }

The image of the blog post. Can be a string or an object.

orientation'vertical' "vertical" | "horizontal"

The orientation of the blog post.

variant'outline' "outline" | "soft" | "subtle" | "ghost" | "naked"
to string | it | et
target null | "_blank" | "_parent" | "_self" | "_top" | string & {}
ui { root?: SlotClass; header?: SlotClass; body?: SlotClass; footer?: SlotClass; image?: SlotClass; title?: SlotClass; description?: SlotClass; authors?: SlotClass; avatar?: SlotClass; meta?: SlotClass; date?: SlotClass; badge?: SlotClass; }

Slots

Slot Type
date{}
badge{}
title{}
description{}
authors{ ui: object; }
header{ ui: object; }
body{}
footer{}

Tema

app.config.ts
export default defineAppConfig({
  ui: {
    blogPost: {
      slots: {
        root: 'relative group/blog-post flex flex-col rounded-lg overflow-hidden',
        header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
        body: 'min-w-0 flex-1 flex flex-col',
        footer: '',
        image: 'object-cover object-top w-full h-full',
        title: 'text-xl text-pretty font-semibold text-highlighted',
        description: 'mt-1 text-base text-pretty',
        authors: 'pt-4 mt-auto flex flex-wrap gap-x-3 gap-y-1.5',
        avatar: '',
        meta: 'flex items-center gap-2 mb-2',
        date: 'text-sm',
        badge: ''
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
            body: 'justify-center p-4 sm:p-6 lg:px-0'
          },
          vertical: {
            root: 'flex flex-col',
            body: 'p-4 sm:p-6'
          }
        },
        variant: {
          outline: {
            root: 'bg-default ring ring-default',
            date: 'text-toned',
            description: 'text-muted'
          },
          soft: {
            root: 'bg-elevated/50',
            date: 'text-muted',
            description: 'text-toned'
          },
          subtle: {
            root: 'bg-elevated/50 ring ring-default',
            date: 'text-muted',
            description: 'text-toned'
          },
          ghost: {
            date: 'text-toned',
            description: 'text-muted',
            header: 'shadow-lg rounded-lg'
          },
          naked: {
            root: 'p-0 sm:p-0',
            date: 'text-toned',
            description: 'text-muted',
            header: 'shadow-lg rounded-lg'
          }
        },
        to: {
          true: {
            root: [
              'outline-primary/25 has-[>a:focus-visible]:outline-3',
              'transition'
            ],
            image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
            avatar: 'inline-flex transform transition-transform duration-200 hover:scale-115 rounded-full outline-primary/25 focus-visible:outline-3'
          }
        },
        image: {
          true: ''
        }
      },
      compoundVariants: [
        {
          variant: 'outline',
          to: true,
          class: {
            root: 'hover:bg-elevated/50'
          }
        },
        {
          variant: 'soft',
          to: true,
          class: {
            root: 'hover:bg-elevated'
          }
        },
        {
          variant: 'subtle',
          to: true,
          class: {
            root: 'hover:bg-elevated hover:ring-accented'
          }
        },
        {
          variant: [
            'outline',
            'subtle'
          ],
          to: true,
          class: {
            root: 'has-[>a:focus-visible]:ring-primary'
          }
        },
        {
          variant: 'ghost',
          to: true,
          class: {
            root: 'hover:bg-elevated/50',
            header: [
              'group-hover/blog-post:shadow-none',
              'transition-all'
            ]
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'vertical',
          class: {
            header: 'group-hover/blog-post:rounded-b-none'
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'horizontal',
          class: {
            header: 'group-hover/blog-post:rounded-r-none'
          }
        },
        {
          orientation: 'vertical',
          image: false,
          variant: 'naked',
          class: {
            body: 'p-0 sm:p-0'
          }
        }
      ],
      defaultVariants: {
        variant: 'outline'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        blogPost: {
          slots: {
            root: 'relative group/blog-post flex flex-col rounded-lg overflow-hidden',
            header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
            body: 'min-w-0 flex-1 flex flex-col',
            footer: '',
            image: 'object-cover object-top w-full h-full',
            title: 'text-xl text-pretty font-semibold text-highlighted',
            description: 'mt-1 text-base text-pretty',
            authors: 'pt-4 mt-auto flex flex-wrap gap-x-3 gap-y-1.5',
            avatar: '',
            meta: 'flex items-center gap-2 mb-2',
            date: 'text-sm',
            badge: ''
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
                body: 'justify-center p-4 sm:p-6 lg:px-0'
              },
              vertical: {
                root: 'flex flex-col',
                body: 'p-4 sm:p-6'
              }
            },
            variant: {
              outline: {
                root: 'bg-default ring ring-default',
                date: 'text-toned',
                description: 'text-muted'
              },
              soft: {
                root: 'bg-elevated/50',
                date: 'text-muted',
                description: 'text-toned'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default',
                date: 'text-muted',
                description: 'text-toned'
              },
              ghost: {
                date: 'text-toned',
                description: 'text-muted',
                header: 'shadow-lg rounded-lg'
              },
              naked: {
                root: 'p-0 sm:p-0',
                date: 'text-toned',
                description: 'text-muted',
                header: 'shadow-lg rounded-lg'
              }
            },
            to: {
              true: {
                root: [
                  'outline-primary/25 has-[>a:focus-visible]:outline-3',
                  'transition'
                ],
                image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
                avatar: 'inline-flex transform transition-transform duration-200 hover:scale-115 rounded-full outline-primary/25 focus-visible:outline-3'
              }
            },
            image: {
              true: ''
            }
          },
          compoundVariants: [
            {
              variant: 'outline',
              to: true,
              class: {
                root: 'hover:bg-elevated/50'
              }
            },
            {
              variant: 'soft',
              to: true,
              class: {
                root: 'hover:bg-elevated'
              }
            },
            {
              variant: 'subtle',
              to: true,
              class: {
                root: 'hover:bg-elevated hover:ring-accented'
              }
            },
            {
              variant: [
                'outline',
                'subtle'
              ],
              to: true,
              class: {
                root: 'has-[>a:focus-visible]:ring-primary'
              }
            },
            {
              variant: 'ghost',
              to: true,
              class: {
                root: 'hover:bg-elevated/50',
                header: [
                  'group-hover/blog-post:shadow-none',
                  'transition-all'
                ]
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'vertical',
              class: {
                header: 'group-hover/blog-post:rounded-b-none'
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'horizontal',
              class: {
                header: 'group-hover/blog-post:rounded-r-none'
              }
            },
            {
              orientation: 'vertical',
              image: false,
              variant: 'naked',
              class: {
                body: 'p-0 sm:p-0'
              }
            }
          ],
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})

Changelog

No recent changes