Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="relative w-full h-[400px] bg-muted overflow-hidden">
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<UMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in 4"
:key="i"
Expand All @@ -10,8 +10,8 @@
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
<UPageMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
</UMarquee>
<UMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in [5, 6, 7, 8]"
:key="i"
Expand All @@ -21,8 +21,8 @@
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
</UMarquee>
<UMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in [9, 10, 11, 12]"
:key="i"
Expand All @@ -32,6 +32,6 @@
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
</UMarquee>
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const testimonials = [{

<template>
<div class="flex flex-col gap-4 w-full">
<UPageMarquee pause-on-hover :overlay="false" :ui="{ root: '[--gap:--spacing(4)]', content: 'w-auto py-1' }">
<UMarquee pause-on-hover :overlay="false" :ui="{ root: '[--gap:--spacing(4)]', content: 'w-auto py-1' }">
<UPageCard
v-for="(testimonial, index) in testimonials"
:key="index"
Expand All @@ -102,8 +102,8 @@ const testimonials = [{
<UUser v-bind="testimonial.user" size="xl" :ui="{ description: 'line-clamp-1' }" />
</template>
</UPageCard>
</UPageMarquee>
<UPageMarquee pause-on-hover reverse :overlay="false" :ui="{ root: '[--gap:--spacing(4)]', content: 'w-auto py-1' }">
</UMarquee>
<UMarquee pause-on-hover reverse :overlay="false" :ui="{ root: '[--gap:--spacing(4)]', content: 'w-auto py-1' }">
<UPageCard
v-for="(testimonial, index) in testimonials"
:key="index"
Expand All @@ -118,6 +118,6 @@ const testimonials = [{
<UUser v-bind="testimonial.user" size="xl" :ui="{ description: 'line-clamp-1' }" />
</template>
</UPageCard>
</UPageMarquee>
</UMarquee>
</div>
</template>
4 changes: 2 additions & 2 deletions docs/app/pages/figma.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ onMounted(async () => {
<UPageSection v-bind="page.features2" :ui="{ container: 'py-16 sm:py-16 lg:py-16', features: 'mt-0' }" class="border-y border-default" />

<UPageCTA v-if="page.customers" :title="page.customers.title" :ui="{ title: '!text-base font-medium', container: 'sm:py-12 sm:gap-8' }" variant="outline" class="rounded-none">
<UPageMarquee pause-on-hover :ui="{ root: '[--duration:40s]' }">
<UMarquee pause-on-hover :ui="{ root: '[--duration:40s]' }">
<img v-for="(logo, index) in page.customers.items" :key="index" v-bind="logo" class="h-6 shrink-0 max-w-[140px] filter invert dark:invert-0" loading="lazy">
</UPageMarquee>
</UMarquee>
</UPageCTA>
<UPageSection v-bind="page.faq" :ui="{ container: 'relative' }">
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
Expand Down
20 changes: 10 additions & 10 deletions docs/app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
<LazySkyBg is-index />

<div class="h-[344px] lg:h-full lg:relative w-full lg:min-h-[calc(100vh-var(--ui-header-height)-1px)] overflow-hidden">
<UPageMarquee
<UMarquee
pause-on-hover
:overlay="false"
:ui="{
Expand All @@ -106,9 +106,9 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
/>
<UBadge color="neutral" variant="outline" size="md" :label="component.title" class="hidden lg:block absolute mx-auto top-4 left-6 xl:left-4 group-hover/link:opacity-100 opacity-0 transition-all duration-300 pointer-events-none -translate-y-2 group-hover/link:translate-y-0" />
</ULink>
</UPageMarquee>
</UMarquee>

<UPageMarquee
<UMarquee
pause-on-hover
reverse
:overlay="false"
Expand All @@ -135,7 +135,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
/>
<UBadge color="neutral" variant="outline" size="md" :label="component.title" class="hidden lg:block absolute mx-auto top-4 left-6 xl:left-4 group-hover/link:opacity-100 opacity-0 transition-all duration-300 pointer-events-none -translate-y-2 group-hover/link:translate-y-0" />
</ULink>
</UPageMarquee>
</UMarquee>
</div>
</UPageHero>

Expand Down Expand Up @@ -271,7 +271,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {

<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
<div class="relative h-[400px] border border-default bg-muted overflow-hidden border-x-0 -mx-4 sm:-mx-6 lg:mx-0 lg:border-x w-screen lg:w-full">
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<UMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in 4"
:key="i"
Expand All @@ -282,8 +282,8 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
<UPageMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
</UMarquee>
<UMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in [5, 6, 7, 8]"
:key="i"
Expand All @@ -294,8 +294,8 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
</UMarquee>
<UMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
<img
v-for="i in [9, 10, 11, 12]"
:key="i"
Expand All @@ -306,7 +306,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
:alt="`Nuxt UI Screenshot ${i}`"
class="aspect-video border border-default rounded-lg bg-white"
>
</UPageMarquee>
</UMarquee>
</div>
</UPageSection>
</UMain>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
title: PageMarquee
title: Marquee
description: 'A component to create infinite scrolling content.'
category: page
category: data
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/v4/src/runtime/components/PageMarquee.vue
to: https://github.com/nuxt/ui/blob/v4/src/runtime/components/Marquee.vue
---

## Usage

The `PageMarquee` component allows you to create an infinite scrolling animation with your content. Perfect for showcasing logos, testimonials, or any repeating content in an engaging way.
The `Marquee` component allows you to create an infinite scrolling animation with your content. Perfect for showcasing logos, testimonials, or any repeating content in an engaging way.

::component-code
---
Expand Down Expand Up @@ -173,12 +173,12 @@ slots:

### Testimonials

Use the `PageMarquee` component to create an infinite scrolling animation for your testimonials.
Use the `Marquee` component to create an infinite scrolling animation for your testimonials.

::component-example{label="With Items"}
---
prettier: true
name: 'page-marquee-testimonials'
name: 'marquee-testimonials'
collapse: true
overflowHidden: true
class: 'px-0'
Expand All @@ -187,12 +187,12 @@ class: 'px-0'

### Screenshots

Use the `PageMarquee` component to create an infinite scrolling animation for your screenshots.
Use the `Marquee` component to create an infinite scrolling animation for your screenshots.

::component-example{label="With Screenshots"}
---
prettier: true
name: 'page-marquee-screenshots'
name: 'marquee-screenshots'
collapse: true
overflowHidden: true
class: '!p-0'
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/2.components/page-logos.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ props:
---
::

::note{to="/docs/components/page-marquee"}
When you use `marquee` mode, you can customize its behavior by passing props. For more info, check out the [PageMarquee](/docs/components/page-marquee) component.
::note{to="/docs/components/marquee"}
When you use `marquee` mode, you can customize its behavior by passing props. For more info, check out the [Marquee](/docs/components/marquee) component.
::

## API
Expand Down
1 change: 1 addition & 0 deletions docs/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export default defineNuxtConfig({
'/docs/getting-started/i18n': { redirect: '/docs/getting-started/i18n/nuxt', prerender: false },
// v4 redirects - renamed components
'/components/button-group': { redirect: { to: '/docs/components/field-group', statusCode: 301 }, prerender: false },
'/components/page-marquee': { redirect: { to: '/docs/components/marquee', statusCode: 301 }, prerender: false },
// v4 redirects - removed pro pages
'/pro': { redirect: { to: '/pro/activate', statusCode: 301 }, prerender: false },
'/pro/pricing': { redirect: { to: '/pro/activate', statusCode: 301 }, prerender: false },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
<script lang="ts">
import type { AppConfig } from '@nuxt/schema'
import theme from '#build/ui/page-marquee'
import theme from '#build/ui/marquee'
import type { ComponentConfig } from '../types/tv'

type PageMarquee = ComponentConfig<typeof theme, AppConfig, 'pageMarquee'>
type Marquee = ComponentConfig<typeof theme, AppConfig, 'marquee'>

export interface PageMarqueeProps {
export interface MarqueeProps {
/**
* The element or component this component should render as.
* @defaultValue 'div'
*/
as?: any
pauseOnHover?: boolean
reverse?: boolean
orientation?: PageMarquee['variants']['orientation']
orientation?: Marquee['variants']['orientation']
repeat?: number
overlay?: boolean
class?: any
ui?: PageMarquee['slots']
ui?: Marquee['slots']
}

export interface PageMarqueeSlots {
export interface MarqueeSlots {
default(props?: {}): any
}
</script>
Expand All @@ -31,16 +31,16 @@ import { Primitive } from 'reka-ui'
import { useAppConfig } from '#imports'
import { tv } from '../utils/tv'

const props = withDefaults(defineProps<PageMarqueeProps>(), {
const props = withDefaults(defineProps<MarqueeProps>(), {
orientation: 'horizontal',
repeat: 4,
overlay: true
})
defineSlots<PageMarqueeSlots>()
defineSlots<MarqueeSlots>()

const appConfig = useAppConfig() as PageMarquee['AppConfig']
const appConfig = useAppConfig() as Marquee['AppConfig']

const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.pageMarquee || {}) })({
const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.marquee || {}) })({
pauseOnHover: props.pauseOnHover,
orientation: props.orientation,
reverse: props.reverse,
Expand Down
10 changes: 5 additions & 5 deletions src/runtime/components/PageLogos.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import type { AppConfig } from '@nuxt/schema'
import theme from '#build/ui/page-logos'
import type { PageMarqueeProps } from '../types'
import type { MarqueeProps } from '../types'
import type { ComponentConfig } from '../types/tv'

type PageLogos = ComponentConfig<typeof theme, AppConfig, 'pageLogos'>
Expand All @@ -19,7 +19,7 @@ export interface PageLogosProps {
as?: any
title?: string
items?: PageLogosItem[]
marquee?: boolean | PageMarqueeProps
marquee?: boolean | MarqueeProps
class?: any
ui?: PageLogos['slots']
}
Expand All @@ -35,7 +35,7 @@ import { Primitive } from 'reka-ui'
import { createReusableTemplate } from '@vueuse/core'
import { useAppConfig } from '#imports'
import { tv } from '../utils/tv'
import UPageMarquee from './PageMarquee.vue'
import UMarquee from './Marquee.vue'
import UAvatar from './Avatar.vue'
import UIcon from './Icon.vue'

Expand Down Expand Up @@ -79,13 +79,13 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.pageLogos ||
{{ title }}
</h2>

<UPageMarquee
<UMarquee
v-if="marquee"
v-bind="typeof marquee === 'object' ? marquee : {}"
:class="ui.logos({ class: props.ui?.logos, marquee: true })"
>
<ReuseCreateItemTemplate :items="items" />
</UPageMarquee>
</UMarquee>
<div v-else :class="ui.logos({ class: props.ui?.logos })">
<ReuseCreateItemTemplate :items="items" />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export * from '../components/InputTags.vue'
export * from '../components/Kbd.vue'
export * from '../components/Link.vue'
export * from '../components/Main.vue'
export * from '../components/Marquee.vue'
export * from '../components/Modal.vue'
export * from '../components/NavigationMenu.vue'
export * from '../components/Page.vue'
Expand All @@ -73,7 +74,6 @@ export * from '../components/PageHero.vue'
export * from '../components/PageLinks.vue'
export * from '../components/PageList.vue'
export * from '../components/PageLogos.vue'
export * from '../components/PageMarquee.vue'
export * from '../components/PageSection.vue'
export * from '../components/Pagination.vue'
export * from '../components/PinInput.vue'
Expand Down
2 changes: 1 addition & 1 deletion src/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export { default as inputTags } from './input-tags'
export { default as kbd } from './kbd'
export { default as link } from './link'
export { default as main } from './main'
export { default as marquee } from './marquee'
export { default as modal } from './modal'
export { default as navigationMenu } from './navigation-menu'
export { default as page } from './page'
Expand All @@ -71,7 +72,6 @@ export { default as pageHero } from './page-hero'
export { default as pageLinks } from './page-links'
export { default as pageList } from './page-list'
export { default as pageLogos } from './page-logos'
export { default as pageMarquee } from './page-marquee'
export { default as pageSection } from './page-section'
export { default as pagination } from './pagination'
export { default as pinInput } from './pin-input'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { describe, it, expect } from 'vitest'
import PageMarquee from '../../src/runtime/components/PageMarquee.vue'
import type { PageMarqueeProps, PageMarqueeSlots } from '../../src/runtime/components/PageMarquee.vue'
import Marquee from '../../src/runtime/components/Marquee.vue'
import type { MarqueeProps, MarqueeSlots } from '../../src/runtime/components/Marquee.vue'
import ComponentRender from '../component-render'

describe('PageMarquee', () => {
describe('Marquee', () => {
it.each([
// Props
['with as', { props: { as: 'section' } }],
Expand All @@ -16,8 +16,8 @@ describe('PageMarquee', () => {
['with ui', { props: { ui: { content: 'gap-4' } } }],
// Slots
['with default slot', { slots: { default: () => 'Default slot' } }]
])('renders %s correctly', async (nameOrHtml: string, options: { props?: PageMarqueeProps, slots?: Partial<PageMarqueeSlots> }) => {
const html = await ComponentRender(nameOrHtml, options, PageMarquee)
])('renders %s correctly', async (nameOrHtml: string, options: { props?: MarqueeProps, slots?: Partial<MarqueeSlots> }) => {
const html = await ComponentRender(nameOrHtml, options, Marquee)
expect(html).toMatchSnapshot()
})
})
Loading