Skip to content

Commit

Permalink
feat(module): auto inject lib/utils & refresh the playground (#528)
Browse files Browse the repository at this point in the history
* chore: add dev:nuxt script

* chore(module): add `.npmrc` to playground

* chore: bump 'nuxtjs/tailwindcss' and add it to modules

* chore: add schema to components.json

* chore: bump playground deps

* fix: add missing tailwind.css by the cli

* chore: bump tailwind config

* chore(playground): bump Button component

* chore: add comments

* refactor: simplify components registration

* chore(module): bump deps

* chore(module): remove `oxc-parser`

* chore: dedupe

* feat(module): auto generate `lib/utils`

* feat(module): refresh playground style and dark mode

* chore: revert components registration and link the comment

* chore: readd oxc-parser

* chore: bump vitest
  • Loading branch information
MuhammadM1998 authored May 7, 2024
1 parent 3dd2fbd commit 631ffb8
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 506 deletions.
11 changes: 5 additions & 6 deletions packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@
"@oxc-parser/wasm": "^0.1.0"
},
"devDependencies": {
"@nuxt/devtools": "latest",
"@nuxt/eslint-config": "^0.3.6",
"@nuxt/module-builder": "^0.5.5",
"@nuxt/eslint-config": "^0.3.10",
"@nuxt/module-builder": "^0.6.0",
"@nuxt/schema": "^3.11.2",
"@nuxt/test-utils": "^3.12.0",
"@types/node": "^20.12.7",
"@nuxt/test-utils": "^3.12.1",
"@types/node": "^20.12.8",
"nuxt": "^3.11.2",
"vitest": "^0.33.0"
"vitest": "^1.6.0"
}
}
1 change: 1 addition & 0 deletions packages/module/playground/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
41 changes: 34 additions & 7 deletions packages/module/playground/app.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
<script setup>
<script setup lang="ts">
import { MoonIcon, SunIcon } from '@radix-icons/vue'
const isDark = ref(true)
useHead({ htmlAttrs: { class: () => isDark.value ? 'dark' : '' } })
</script>

<template>
<div>
<UiButton :variant="'destructive'">
hi
</UiButton>
Nuxt module playground!
</div>
<main class="flex flex-col min-h-dvh">
<header class="border-b py-1 ">
<div class="container flex justify-between items-center ">
<h1 class="font-medium">
shadcn-vue Playground
</h1>

<ClientOnly>
<button
class="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors rounded-md"
aria-label="Toggle dark mode"
@click="isDark = !isDark"
>
<component
:is="isDark ? SunIcon : MoonIcon"
class="size-5"
/>
</button>
</ClientOnly>
</div>
</header>

<!-- Try your components here -->
<section class="container grow my-4 p-4 rounded-md border grid place-content-center">
<UiButton variant="destructive">
Hi
</UiButton>
</section>
</main>
</template>
78 changes: 78 additions & 0 deletions packages/module/playground/assets/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
1 change: 1 addition & 0 deletions packages/module/playground/components.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "https://shadcn-vue.com/schema.json",
"style": "default",
"typescript": true,
"tailwind": {
Expand Down
23 changes: 13 additions & 10 deletions packages/module/playground/components/ui/button/Button.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<script setup lang="ts">
import { buttonVariants } from '.'
import type { HTMLAttributes } from 'vue'
import { Primitive, type PrimitiveProps } from 'radix-vue'
import { type ButtonVariants, buttonVariants } from '.'
import { cn } from '@/lib/utils'
interface Props {
variant?: NonNullable<Parameters<typeof buttonVariants>[0]>['variant']
size?: NonNullable<Parameters<typeof buttonVariants>[0]>['size']
as?: string
interface Props extends PrimitiveProps {
variant?: ButtonVariants['variant']
size?: ButtonVariants['size']
class?: HTMLAttributes['class']
}
withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<Props>(), {
as: 'button',
})
</script>

<template>
<component
:is="as"
:class="cn(buttonVariants({ variant, size }), $attrs.class ?? '')"
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</component>
</Primitive>
</template>
7 changes: 5 additions & 2 deletions packages/module/playground/components/ui/button/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { cva } from 'class-variance-authority'
import { type VariantProps, cva } from 'class-variance-authority'

export { default as Button } from './Button.vue'

export const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
Expand All @@ -19,6 +19,7 @@ export const buttonVariants = cva(
},
size: {
default: 'h-10 px-4 py-2',
xs: 'h-7 rounded px-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
Expand All @@ -30,3 +31,5 @@ export const buttonVariants = cva(
},
},
)

export type ButtonVariants = VariantProps<typeof buttonVariants>
2 changes: 1 addition & 1 deletion packages/module/playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default defineNuxtConfig({
modules: ['../src/module'],
modules: ['@nuxtjs/tailwindcss', '../src/module'],
shadcn: {
prefix: 'Ui',
},
Expand Down
8 changes: 4 additions & 4 deletions packages/module/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
"generate": "nuxi generate"
},
"dependencies": {
"@nuxtjs/tailwindcss": "^6.10.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"clsx": "^2.1.1",
"embla-carousel": "8.0.0-rc19",
"embla-carousel-vue": "8.0.0-rc19",
"lucide-vue-next": "^0.276.0",
"radix-vue": "^1.4.8",
"tailwind-merge": "^2.0.0",
"radix-vue": "^1.7.2",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.12.0",
"nuxt": "latest"
}
}
13 changes: 13 additions & 0 deletions packages/module/playground/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const animate = require('tailwindcss-animate')
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class'],
safelist: ['dark'],
prefix: '',

theme: {
container: {
Expand Down Expand Up @@ -49,6 +51,7 @@ module.exports = {
},
},
borderRadius: {
xl: 'calc(var(--radius) + 4px)',
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)',
Expand All @@ -62,10 +65,20 @@ module.exports = {
from: { height: 'var(--radix-accordion-content-height)' },
to: { height: 0 },
},
'collapsible-down': {
from: { height: 0 },
to: { height: 'var(--radix-collapsible-content-height)' },
},
'collapsible-up': {
from: { height: 'var(--radix-collapsible-content-height)' },
to: { height: 0 },
},
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
'collapsible-down': 'collapsible-down 0.2s ease-in-out',
'collapsible-up': 'collapsible-up 0.2s ease-in-out',
},
},
},
Expand Down
26 changes: 24 additions & 2 deletions packages/module/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { readFileSync, readdirSync } from 'node:fs'
import { join } from 'node:path'
import { addComponent, createResolver, defineNuxtModule } from '@nuxt/kit'
import { parseSync } from '@oxc-parser/wasm'
import { addComponent, addTemplate, createResolver, defineNuxtModule, findPath, useLogger } from '@nuxt/kit'
import { UTILS } from '../../cli/src/utils/templates'

// TODO: add test to make sure all registry is being parse correctly
// Module options TypeScript interface definition
Expand Down Expand Up @@ -29,15 +30,36 @@ export default defineNuxtModule<ModuleOptions>({
async setup({ prefix, componentDir }, nuxt) {
const COMPONENT_DIR_PATH = componentDir!
const ROOT_DIR_PATH = nuxt.options.rootDir
const UTILS_ALIAS = '@/lib/utils' // Use the same path from the cli for backward compatibility
const { resolve, resolvePath } = createResolver(ROOT_DIR_PATH)
const logger = useLogger('shadcn-nuxt')

// `lib/utils`
const utilsTemplate = addTemplate({
filename: 'shadcn-nuxt/utils.ts',
getContents: () => UTILS,
write: true,
})
nuxt.options.alias = { [UTILS_ALIAS]: utilsTemplate.dst, ...nuxt.options.alias } // We add our alias to the top to avoid conflicts with nuxt built in `@` alias

// Recommend to remove the root `lib/utils` if exists
const isRootUtilsExists = await findPath('./lib/utils.ts', { cwd: ROOT_DIR_PATH })
if (isRootUtilsExists)
logger.warn('[shadcn-nuxt] `lib/utils.ts` is auto generated by the module and can be safely removed.')

// Components Auto Imports
const componentsPath = resolve(COMPONENT_DIR_PATH)

// Tell Nuxt to not scan `componentsDir` for auto imports as we will do it manually
// See https://github.com/radix-vue/shadcn-vue/pull/528#discussion_r1590206268
nuxt.hook('components:dirs', (dirs) => {
dirs.unshift({
path: resolve(COMPONENT_DIR_PATH),
path: componentsPath,
extensions: [],
})
})

// Manually scan `componentsDir` for components and register them for auto imports
try {
readdirSync(resolve(COMPONENT_DIR_PATH))
.forEach(async (dir) => {
Expand Down
Loading

0 comments on commit 631ffb8

Please sign in to comment.