diff --git a/playground/app.vue b/playground/app.vue index 3b056780..63182f3a 100644 --- a/playground/app.vue +++ b/playground/app.vue @@ -14,6 +14,7 @@ const components = [ 'alert', 'avatar', 'badge', + 'breadcrumb', 'button', 'card', 'checkbox', diff --git a/playground/pages/breadcrumb.vue b/playground/pages/breadcrumb.vue new file mode 100644 index 00000000..ff6ace16 --- /dev/null +++ b/playground/pages/breadcrumb.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/runtime/components/Breadcrumb.vue b/src/runtime/components/Breadcrumb.vue new file mode 100644 index 00000000..070808fe --- /dev/null +++ b/src/runtime/components/Breadcrumb.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/runtime/types/index.d.ts b/src/runtime/types/index.d.ts index d216ce9f..74487d08 100644 --- a/src/runtime/types/index.d.ts +++ b/src/runtime/types/index.d.ts @@ -3,6 +3,7 @@ export * from '../components/Accordion.vue' export * from '../components/Alert.vue' export * from '../components/Avatar.vue' export * from '../components/Badge.vue' +export * from '../components/Breadcrumb.vue' export * from '../components/Button.vue' export * from '../components/Card.vue' export * from '../components/Checkbox.vue' diff --git a/src/theme/breadcrumb.ts b/src/theme/breadcrumb.ts new file mode 100644 index 00000000..9fa2983c --- /dev/null +++ b/src/theme/breadcrumb.ts @@ -0,0 +1,28 @@ +export default { + slots: { + root: 'relative min-w-0', + list: 'flex items-center gap-1.5', + item: 'flex min-w-0', + link: 'group relative flex items-center gap-1.5 font-medium text-sm min-w-0', + linkLeadingIcon: 'shrink-0 size-5', + linkLeadingAvatar: 'shrink-0', + linkLabel: 'truncate', + separator: 'flex', + separatorIcon: 'shrink-0 size-5 text-gray-500 dark:text-gray-400' + }, + variants: { + active: { + true: { + link: 'text-primary-500 dark:text-primary-400' + }, + false: { + link: 'text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white' + } + }, + disabled: { + true: { + link: 'cursor-not-allowed opacity-75' + } + } + } +} diff --git a/src/theme/index.ts b/src/theme/index.ts index 8a7281a1..0b6bc07f 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -2,6 +2,7 @@ export { default as accordion } from './accordion' export { default as alert } from './alert' export { default as avatar } from './avatar' export { default as badge } from './badge' +export { default as breadcrumb } from './breadcrumb' export { default as button } from './button' export { default as card } from './card' export { default as checkbox } from './checkbox' diff --git a/test/components/Breadcrumb.spec.ts b/test/components/Breadcrumb.spec.ts new file mode 100644 index 00000000..59079135 --- /dev/null +++ b/test/components/Breadcrumb.spec.ts @@ -0,0 +1,36 @@ +import { describe, it, expect } from 'vitest' +import Breadcrumb, { type BreadcrumbProps } from '../../src/runtime/components/Breadcrumb.vue' +import ComponentRender from '../component-render' + +describe('Breadcrumb', () => { + const links = [{ + label: 'Home', + avatar: { + src: 'https://avatars.githubusercontent.com/u/739984?v=4' + }, + to: '/' + }, { + label: 'Navigation', + icon: 'i-heroicons-square-3-stack-3d', + disabled: true + }, { + label: 'Breadcrumb', + icon: 'i-heroicons-link' + }] + + it.each([ + // Props + ['with links', { props: { links } }], + ['with separatorIcon', { props: { links, separatorIcon: 'i-heroicons-minus' } }], + ['with class', { props: { class: 'w-48' } }], + ['with ui', { props: { ui: { link: 'font-bold' } } }], + // Slots + ['with default slot', { slots: { default: () => 'Default slot' } }], + ['with leading slot', { slots: { leading: () => 'Leading slot' } }], + ['with trailing slot', { slots: { trailing: () => 'Trailing slot' } }], + ['with separator slot', { slots: { separator: () => '/' } }] + ])('renders %s correctly', async (nameOrHtml: string, options: { props?: BreadcrumbProps, slots?: any }) => { + const html = await ComponentRender(nameOrHtml, options, Breadcrumb) + expect(html).toMatchSnapshot() + }) +}) diff --git a/test/components/__snapshots__/Breadcrumb.spec.ts.snap b/test/components/__snapshots__/Breadcrumb.spec.ts.snap new file mode 100644 index 00000000..6dea25f1 --- /dev/null +++ b/test/components/__snapshots__/Breadcrumb.spec.ts.snap @@ -0,0 +1,71 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Breadcrumb > renders with class correctly 1`] = ` +"
+
    +
    " +`; + +exports[`Breadcrumb > renders with default slot correctly 1`] = ` +"
    +
      +
      " +`; + +exports[`Breadcrumb > renders with leading slot correctly 1`] = ` +"
      +
        +
        " +`; + +exports[`Breadcrumb > renders with links correctly 1`] = ` +"
        +
          +
        1. Home
        2. + +
        3. Navigation
        4. + +
        5. Breadcrumb
        6. + +
        +
        " +`; + +exports[`Breadcrumb > renders with separator slot correctly 1`] = ` +"
        +
          +
          " +`; + +exports[`Breadcrumb > renders with separatorIcon correctly 1`] = ` +"
          +
            +
          1. Home
          2. + +
          3. Navigation
          4. + +
          5. Breadcrumb
          6. + +
          +
          " +`; + +exports[`Breadcrumb > renders with trailing slot correctly 1`] = ` +"
          +
            +
            " +`; + +exports[`Breadcrumb > renders with ui correctly 1`] = ` +"
            +
              +
              " +`;