Skip to content

Commit 50a447f

Browse files
committed
fix: updated deps, removed licenses req and added missing component
1 parent 8974d9b commit 50a447f

File tree

10 files changed

+923
-879
lines changed

10 files changed

+923
-879
lines changed

.env.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
GITHUB_TOKEN="" # GitHub token
22

3-
NUXT_UI_PRO_LICENSE="" # Production license for @nuxt/ui-pro, get one at https://ui.nuxt.com/pro/purchase
43
NUXT_PUBLIC_SITE_URL="https://projectm-visualizer.org" # Public URL, used for OG Image when running nuxt generate
54
NUXT_PUBLIC_ASSET_KEY="" # Asset encryption key for the public assets
65

.github/workflows/release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ jobs:
5454
- name: Build
5555
run: bun run generate
5656
env:
57-
NUXT_UI_PRO_LICENSE: ${{ secrets.NUXT_UI_PRO_LICENSE }}
5857
NUXT_PUBLIC_SITE_URL: ${{ secrets.NUXT_PUBLIC_SITE_URL }}
5958
NUXT_PUBLIC_ASSET_KEY: ${{ secrets.NUXT_PUBLIC_ASSET_KEY }}
6059

app/assets/css/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@import "tailwindcss";
2-
@import "@nuxt/ui-pro";
2+
@import "@nuxt/ui";
33

44
@source "../../../content/**/*";
55

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!-- eslint-disable @typescript-eslint/no-explicit-any -->
2+
<script lang="ts">
3+
import type { AppConfig } from '@nuxt/schema'
4+
import theme from './theme'
5+
import type { ComponentConfig } from './tv'
6+
7+
type PageMarquee = ComponentConfig<typeof theme, AppConfig, 'pageMarquee'>
8+
9+
export interface PageMarqueeProps {
10+
/**
11+
* The element or component this component should render as.
12+
* @defaultValue 'div'
13+
*/
14+
as?: any
15+
pauseOnHover?: boolean
16+
reverse?: boolean
17+
orientation?: PageMarquee['variants']['orientation']
18+
repeat?: number
19+
overlay?: boolean
20+
class?: any
21+
ui?: PageMarquee['slots']
22+
}
23+
24+
export interface PageMarqueeSlots {
25+
default(props?: object): any
26+
}
27+
</script>
28+
29+
<!-- eslint-disable import/first -->
30+
<script setup lang="ts">
31+
import { computed } from 'vue'
32+
import { Primitive } from 'reka-ui'
33+
import { tv } from './tv'
34+
35+
const props = withDefaults(defineProps<PageMarqueeProps>(), {
36+
orientation: 'horizontal',
37+
repeat: 4,
38+
overlay: true
39+
})
40+
defineSlots<PageMarqueeSlots>()
41+
42+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
43+
// @ts-ignore
44+
const ui = computed(() => tv({ extend: tv(theme) })({
45+
pauseOnHover: props.pauseOnHover,
46+
orientation: props.orientation,
47+
reverse: props.reverse,
48+
overlay: props.overlay
49+
}))
50+
</script>
51+
52+
<template>
53+
<Primitive
54+
:as="as"
55+
:class="ui.root({ class: [props.ui?.root, props.class] })"
56+
>
57+
<div
58+
v-for="i in repeat"
59+
:key="i"
60+
:class="ui.content({ class: [props.ui?.content] })"
61+
>
62+
<slot />
63+
</div>
64+
</Primitive>
65+
</template>
66+
67+
<style>
68+
@keyframes marquee {
69+
from { transform: translate3d(0, 0, 0); will-change: transform; }
70+
to { transform: translate3d(calc(-100% - var(--gap)), 0, 0); will-change: transform; }
71+
}
72+
73+
@keyframes marquee-rtl {
74+
from { transform: translate3d(calc(100%), 0, 0); will-change: transform; }
75+
to { transform: translate3d(calc(-100% * var(--repeat) - var(--gap) * var(--repeat)), 0, 0); will-change: transform; }
76+
}
77+
78+
@keyframes marquee-vertical {
79+
from { transform: translate3d(0, 0, 0); will-change: transform; }
80+
to { transform: translate3d(0, calc(-100% - var(--gap)), 0); will-change: transform; }
81+
}
82+
83+
@keyframes marquee-vertical-rtl {
84+
from { transform: translate3d(0, calc(100%), 0); will-change: transform; }
85+
to { transform: translate3d(0, calc(-100% * var(--repeat) - var(--gap) * var(--repeat)), 0); will-change: transform; }
86+
}
87+
</style>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { TVConfig } from './tv'
2+
3+
const theme = {
4+
slots: {
5+
root: 'group relative flex items-center overflow-hidden gap-(--gap) [--gap:--spacing(16)] [--duration:20s]',
6+
content: 'flex items-center shrink-0 justify-around gap-(--gap) min-w-max'
7+
},
8+
variants: {
9+
orientation: {
10+
horizontal: {
11+
content: 'w-full'
12+
},
13+
vertical: {
14+
content: 'h-full'
15+
}
16+
},
17+
pauseOnHover: {
18+
true: {
19+
content: 'group-hover:[animation-play-state:paused]'
20+
}
21+
},
22+
reverse: {
23+
true: {
24+
content: '[animation-direction:reverse]'
25+
}
26+
},
27+
overlay: {
28+
true: {
29+
root: 'before:absolute before:pointer-events-none before:content-[""] before:z-2 before:from-default before:to-transparent after:absolute after:pointer-events-none after:content-[""] after:z-2 after:from-default after:to-transparent'
30+
}
31+
}
32+
},
33+
compoundVariants: [{
34+
orientation: 'horizontal',
35+
class: {
36+
root: 'flex-row',
37+
content: 'flex-row animate-[marquee_var(--duration)_linear_infinite] rtl:animate-[marquee-rtl_var(--duration)_linear_infinite] backface-hidden'
38+
}
39+
}, {
40+
orientation: 'horizontal',
41+
overlay: true,
42+
class: {
43+
root: 'before:inset-y-0 before:left-0 before:h-full before:w-1/3 before:bg-gradient-to-r after:inset-y-0 after:right-0 after:h-full after:w-1/3 after:bg-gradient-to-l backface-hidden'
44+
}
45+
}, {
46+
orientation: 'vertical',
47+
class: {
48+
root: 'flex-col',
49+
content: 'flex-col animate-[marquee-vertical_var(--duration)_linear_infinite] rtl:animate-[marquee-vertical-rtl_var(--duration)_linear_infinite] h-[fit-content] backface-hidden'
50+
}
51+
}, {
52+
orientation: 'vertical',
53+
overlay: true,
54+
class: {
55+
root: 'before:inset-x-0 before:top-0 before:w-full before:h-1/3 before:bg-gradient-to-b after:inset-x-0 after:bottom-0 after:w-full after:h-1/3 after:bg-gradient-to-t backface-hidden'
56+
}
57+
}]
58+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
59+
} satisfies TVConfig<any>
60+
61+
export default theme

app/components/app/Marquee/tv.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import type { defaultConfig, ClassValue, TVVariants, TVCompoundVariants, TVDefaultVariants } from 'tailwind-variants'
3+
import { createTV } from 'tailwind-variants'
4+
import type { AppConfig } from '@nuxt/schema'
5+
import appConfig from '#build/app.config'
6+
7+
/**
8+
* Defines the AppConfig object based on the tailwind-variants configuration.
9+
*/
10+
export type TVConfig<T extends Record<string, any>> = {
11+
[P in keyof T]?: {
12+
[K in keyof T[P]as K extends 'base' | 'slots' | 'variants' | 'compoundVariants' | 'defaultVariants' ? K : never]?: K extends 'base' ? ClassValue
13+
: K extends 'slots' ? {
14+
[S in keyof T[P]['slots']]?: ClassValue
15+
}
16+
: K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, T[P]['variants']>
17+
: K extends 'compoundVariants' ? TVCompoundVariants<T[P]['variants'], T[P]['slots'], ClassValue, object, undefined>
18+
: K extends 'defaultVariants' ? TVDefaultVariants<T[P]['variants'], T[P]['slots'], object, undefined>
19+
: never
20+
}
21+
}
22+
23+
/**
24+
* Utility type to flatten intersection types for better IDE hover information.
25+
* @template T The type to flatten.
26+
*/
27+
type Id<T> = {} & { [P in keyof T]: T[P] }
28+
29+
type ComponentVariants<T extends { variants?: Record<string, Record<string, any>> }> = {
30+
[K in keyof T['variants']]: keyof T['variants'][K]
31+
}
32+
33+
type ComponentSlots<T extends { slots?: Record<string, any> }> = Id<{
34+
[K in keyof T['slots']]?: ClassValue
35+
}>
36+
37+
type GetComponentAppConfig<A, U extends string, K extends string>
38+
= A extends Record<U, Record<K, any>> ? A[U][K] : object
39+
40+
type ComponentAppConfig<
41+
T,
42+
A extends Record<string, any>,
43+
K extends string,
44+
U extends string = 'ui' | 'ui.prose'
45+
> = A & (
46+
U extends 'ui.prose'
47+
? { ui?: { prose?: { [k in K]?: Partial<T> } } }
48+
: { [key in Exclude<U, 'ui.prose'>]?: { [k in K]?: Partial<T> } }
49+
)
50+
51+
/**
52+
* Defines the configuration shape expected for a component.
53+
* @template T The component's theme imported from `#build/ui/*`.
54+
* @template A The base AppConfig type from `@nuxt/schema`.
55+
* @template K The key identifying the component (e.g., 'badge').
56+
* @template U The top-level key in AppConfig ('ui' or 'uiPro').
57+
*/
58+
export type ComponentConfig<
59+
T extends Record<string, any>,
60+
A extends Record<string, any>,
61+
K extends string,
62+
U extends 'ui' | 'ui.prose' = 'ui'
63+
> = {
64+
AppConfig: ComponentAppConfig<T, A, K, U>
65+
variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>
66+
slots: ComponentSlots<T>
67+
}
68+
69+
// -------------------------------
70+
71+
const appConfigTv = appConfig as AppConfig & { ui: { tv: typeof defaultConfig } }
72+
73+
export const tv = /* @__PURE__ */ createTV(appConfigTv.ui?.tv)

app/pages/index.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import Marquee from '~/components/app/Marquee/Marquee.vue'
23
import { VideoPlayer } from '@videojs-player/vue'
34
import 'video.js/dist/video-js.css'
45
@@ -129,7 +130,7 @@ onMounted(async () => {
129130
v-if="page.contributors"
130131
class="flex flex-col gap-6 sm:gap-8 pb-16 sm:pb-24 lg:pb-32"
131132
>
132-
<UPageMarquee
133+
<Marquee
133134
v-if="loadingContributors || batchOne.length"
134135
v-bind="page.contributors"
135136
:ui="{
@@ -163,9 +164,9 @@ onMounted(async () => {
163164
<USkeleton class="h-6 w-24 rounded-full" />
164165
</div>
165166
</template>
166-
</UPageMarquee>
167+
</Marquee>
167168

168-
<UPageMarquee
169+
<Marquee
169170
v-if="loadingContributors || batchTwo.length"
170171
v-bind="page.contributors"
171172
:reverse="true"
@@ -200,7 +201,7 @@ onMounted(async () => {
200201
<USkeleton class="h-6 w-24 rounded-full" />
201202
</div>
202203
</template>
203-
</UPageMarquee>
204+
</Marquee>
204205
</UContainer>
205206

206207
<UPageSection

0 commit comments

Comments
 (0)