mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 07:21:46 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5af9da4d3c | ||
|
|
1d995136a5 | ||
|
|
ba15add4db | ||
|
|
0aca478c57 | ||
|
|
0ee4f2b75b | ||
|
|
6e53cb6281 | ||
|
|
de715304dc | ||
|
|
81854112e3 | ||
|
|
87526b9ec5 | ||
|
|
f79187825f | ||
|
|
0443ac2c9d | ||
|
|
d2c51e3667 | ||
|
|
d15d7fa01d |
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"git": {
|
"git": {
|
||||||
"commitMessage": "chore(release): ${version}"
|
"commitMessage": "chore(release): ${version}",
|
||||||
|
"tagName": "v${version}"
|
||||||
},
|
},
|
||||||
"npm": {
|
"npm": {
|
||||||
"publish": false
|
"publish": false
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
"web": true
|
"web": true
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"before:init": ["pnpm lint"]
|
"before:init": ["pnpm lint", "pnpm typecheck"]
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"@release-it/conventional-changelog": {
|
"@release-it/conventional-changelog": {
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.14.1](https://github.com/nuxt/ui/compare/v2.14.0...v2.14.1) (2024-02-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **module:** revert tailwind config from [#1272](https://github.com/nuxt/ui/issues/1272) ([#1404](https://github.com/nuxt/ui/issues/1404)) ([ba15add](https://github.com/nuxt/ui/commit/ba15add4db5d2f84e987819628cbbf88edcbad57))
|
||||||
|
|
||||||
## [2.14.0](https://github.com/nuxt/ui/compare/v2.13.0...v2.14.0) (2024-02-22)
|
## [2.14.0](https://github.com/nuxt/ui/compare/v2.13.0...v2.14.0) (2024-02-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
|
|
||||||
|
<Banner />
|
||||||
|
|
||||||
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />
|
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />
|
||||||
|
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
@@ -12,7 +14,7 @@
|
|||||||
<Footer v-if="!$route.path.startsWith('/examples')" />
|
<Footer v-if="!$route.path.startsWith('/examples')" />
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<LazyUDocsSearch ref="searchRef" :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 1000 }" />
|
<LazyUContentSearch ref="searchRef" :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 1000 }" />
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
|
||||||
<UNotifications>
|
<UNotifications>
|
||||||
|
|||||||
76
docs/components/Banner.vue
Normal file
76
docs/components/Banner.vue
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { isAfter } from 'date-fns'
|
||||||
|
|
||||||
|
const id = 'nuxt-ui-banner-1'
|
||||||
|
const to = '/pro/pricing'
|
||||||
|
const date = new Date('2024-02-25T20:00:00Z')
|
||||||
|
|
||||||
|
const timeAgo = useTimeAgo(date)
|
||||||
|
|
||||||
|
const hideBanner = () => {
|
||||||
|
localStorage.setItem(id, 'true')
|
||||||
|
|
||||||
|
document.querySelector('html')?.classList.add('hide-banner')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.server) {
|
||||||
|
useHead({
|
||||||
|
script: [{
|
||||||
|
key: 'prehydrate-template-banner',
|
||||||
|
innerHTML: `
|
||||||
|
if (localStorage.getItem('${id}') === 'true') {
|
||||||
|
document.querySelector('html').classList.add('hide-banner')
|
||||||
|
}`.replace(/\s+/g, ' '),
|
||||||
|
type: 'text/javascript'
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (isAfter(new Date(), date)) {
|
||||||
|
hideBanner()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (isAfter(new Date(), date)) {
|
||||||
|
hideBanner()
|
||||||
|
clearInterval(interval)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="relative bg-primary hover:bg-primary/90 transition-[background] backdrop-blur z-50 app-banner">
|
||||||
|
<UContainer class="py-2">
|
||||||
|
<NuxtLink v-if="to" :to="to" class="focus:outline-none" tabindex="-1">
|
||||||
|
<span class="absolute inset-0 " aria-hidden="true" />
|
||||||
|
</NuxtLink>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between gap-2">
|
||||||
|
<div class="lg:flex-1 hidden lg:flex items-center" />
|
||||||
|
|
||||||
|
<p class="text-sm font-medium text-white dark:text-gray-900">
|
||||||
|
<UIcon name="i-heroicons-gift" class="w-5 h-5 align-top flex-shrink-0 pointer-events-none mr-2" />
|
||||||
|
<span class="font-semibold">Nuxt UI Pro v1.0</span> is out with dashboard components! Discount ends <span class="font-semibold">{{ timeAgo }}</span>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-end lg:flex-1">
|
||||||
|
<button
|
||||||
|
class="p-1.5 rounded-md inline-flex hover:bg-primary/90"
|
||||||
|
@click.prevent="hideBanner"
|
||||||
|
>
|
||||||
|
<UIcon name="i-heroicons-x-mark-20-solid" class="w-5 h-5 text-white dark:text-gray-900" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</UContainer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hide-banner .app-banner {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
<template #right>
|
<template #right>
|
||||||
<ColorPicker />
|
<ColorPicker />
|
||||||
|
|
||||||
<UTooltip text="Search" :shortcuts="[metaSymbol, 'K']">
|
<UTooltip text="Search" :shortcuts="[metaSymbol, 'K']" :popper="{ strategy: 'absolute' }">
|
||||||
<UDocsSearchButton :label="null" />
|
<UContentSearchButton :label="null" />
|
||||||
</UTooltip>
|
</UTooltip>
|
||||||
|
|
||||||
<UColorModeButton />
|
<UColorModeButton />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<UPopover mode="hover">
|
<UPopover mode="hover" :popper="{ strategy: 'absolute' }" :ui="{ width: 'w-[156px]' }">
|
||||||
<template #default="{ open }">
|
<template #default="{ open }">
|
||||||
<UButton color="gray" variant="ghost" square :class="[open && 'bg-gray-50 dark:bg-gray-800']" aria-label="Color picker">
|
<UButton color="gray" variant="ghost" square :class="[open && 'bg-gray-50 dark:bg-gray-800']" aria-label="Color picker">
|
||||||
<UIcon name="i-heroicons-swatch-20-solid" class="w-5 h-5 text-primary-500 dark:text-primary-400" />
|
<UIcon name="i-heroicons-swatch-20-solid" class="w-5 h-5 text-primary-500 dark:text-primary-400" />
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ pro:
|
|||||||
title: Upgrade to <span class="text-primary">Nuxt UI Pro</span>
|
title: Upgrade to <span class="text-primary">Nuxt UI Pro</span>
|
||||||
description: 'Nuxt UI Pro is a collection of premium Vue components built on top of Nuxt UI to create beautiful & responsive Nuxt applications in minutes.<br>It includes all primitives to build landing pages, documentations, blogs, dashboards or entire SaaS products.'
|
description: 'Nuxt UI Pro is a collection of premium Vue components built on top of Nuxt UI to create beautiful & responsive Nuxt applications in minutes.<br>It includes all primitives to build landing pages, documentations, blogs, dashboards or entire SaaS products.'
|
||||||
links:
|
links:
|
||||||
- label: View plans
|
- label: Buy now
|
||||||
to: /pro/pricing
|
to: /pro/pricing
|
||||||
color: gray
|
color: black
|
||||||
icon: i-heroicons-credit-card
|
trailingIcon: i-heroicons-arrow-right-20-solid
|
||||||
size: lg
|
size: lg
|
||||||
- label: Explore templates
|
- label: Explore templates
|
||||||
to: /pro/templates
|
to: /pro/templates
|
||||||
@@ -178,7 +178,7 @@ pro:
|
|||||||
</UPageBody>
|
</UPageBody>
|
||||||
|
|
||||||
<template #right>
|
<template #right>
|
||||||
<UDocsToc :links="page.body.toc.links" />
|
<UContentToc :links="page.body.toc.links" />
|
||||||
</template>
|
</template>
|
||||||
</UPage>
|
</UPage>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<LazyUDocsSearch :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 1000 }" />
|
<LazyUContentSearch :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 1000 }" />
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
|
||||||
<UNotifications>
|
<UNotifications>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createResolver } from '@nuxt/kit'
|
import { createResolver } from '@nuxt/kit'
|
||||||
import colors from 'tailwindcss/colors'
|
import colors from 'tailwindcss/colors'
|
||||||
import module from '../src/module'
|
import module from '../src/module'
|
||||||
import { excludeColors } from '../src/runtime/utils/colors'
|
import { excludeColors } from '../src/colors'
|
||||||
import pkg from '../package.json'
|
import pkg from '../package.json'
|
||||||
|
|
||||||
const { resolve } = createResolver(import.meta.url)
|
const { resolve } = createResolver(import.meta.url)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"@nuxt/devtools": "^1.0.8",
|
"@nuxt/devtools": "^1.0.8",
|
||||||
"@nuxt/eslint-config": "^0.2.0",
|
"@nuxt/eslint-config": "^0.2.0",
|
||||||
"@nuxt/image": "^1.3.0",
|
"@nuxt/image": "^1.3.0",
|
||||||
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@0.7.5-28475621.09eb8fa",
|
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@1.0.0-28476869.809f447",
|
||||||
"@nuxtjs/fontaine": "^0.4.1",
|
"@nuxtjs/fontaine": "^0.4.1",
|
||||||
"@nuxtjs/google-fonts": "^3.1.3",
|
"@nuxtjs/google-fonts": "^3.1.3",
|
||||||
"@nuxtjs/plausible": "^0.2.4",
|
"@nuxtjs/plausible": "^0.2.4",
|
||||||
@@ -20,8 +20,8 @@
|
|||||||
"@vueuse/nuxt": "^10.8.0",
|
"@vueuse/nuxt": "^10.8.0",
|
||||||
"date-fns": "^3.3.1",
|
"date-fns": "^3.3.1",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"joi": "^17.12.1",
|
"joi": "^17.12.2",
|
||||||
"nuxt": "^3.10.2",
|
"nuxt": "^3.10.3",
|
||||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||||
"nuxt-component-meta": "^0.6.3",
|
"nuxt-component-meta": "^0.6.3",
|
||||||
"nuxt-og-image": "^2.2.4",
|
"nuxt-og-image": "^2.2.4",
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
<hr v-if="surround?.length">
|
<hr v-if="surround?.length">
|
||||||
|
|
||||||
<UDocsSurround :surround="surround" />
|
<UContentSurround :surround="surround" />
|
||||||
</UPageBody>
|
</UPageBody>
|
||||||
|
|
||||||
<template v-if="page?.body?.toc?.links?.length" #right>
|
<template v-if="page?.body?.toc?.links?.length" #right>
|
||||||
<UDocsToc :links="page.body.toc.links">
|
<UContentToc :links="page.body.toc.links">
|
||||||
<template #bottom>
|
<template #bottom>
|
||||||
<div class="hidden lg:block space-y-6 !mt-6">
|
<div class="hidden lg:block space-y-6 !mt-6">
|
||||||
<UDivider v-if="page.body?.toc?.links?.length" type="dashed" />
|
<UDivider v-if="page.body?.toc?.links?.length" type="dashed" />
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UDocsToc>
|
</UContentToc>
|
||||||
</template>
|
</template>
|
||||||
</UPage>
|
</UPage>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -164,7 +164,13 @@
|
|||||||
</ULandingSection>
|
</ULandingSection>
|
||||||
|
|
||||||
<template v-if="navigation.find(item => item._path === '/pro')">
|
<template v-if="navigation.find(item => item._path === '/pro')">
|
||||||
<ULandingHero id="pro" :links="page.pro.links" :ui="{ title: 'sm:text-6xl' }">
|
<div class="relative">
|
||||||
|
<UDivider class="absolute inset-x-0" />
|
||||||
|
|
||||||
|
<div class="w-full relative overflow-hidden h-px bg-gradient-to-r from-gray-800 via-primary-400 to-gray-800 max-w-5xl mx-auto" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ULandingHero id="pro" :links="page.pro.links" :ui="{ title: 'sm:text-6xl' }" class="bg-gradient-to-b from-gray-50 dark:from-gray-950/50 to-white dark:to-gray-900 relative">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span v-html="page.pro.title" />
|
<span v-html="page.pro.title" />
|
||||||
</template>
|
</template>
|
||||||
@@ -173,11 +179,13 @@
|
|||||||
<span v-html="page.pro.description" />
|
<span v-html="page.pro.description" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<video poster="https://res.cloudinary.com/nuxt/video/upload/so_14.8/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.jpg" controls class="rounded-lg">
|
<div class="bg-gray-900/5 dark:bg-white/5 ring-1 ring-inset ring-gray-900/10 dark:ring-white/10 rounded-xl lg:-m-4 p-4">
|
||||||
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.webm" type="video/webm">
|
<video poster="https://res.cloudinary.com/nuxt/video/upload/so_3.3/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.jpg" controls class="rounded-lg">
|
||||||
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.mp4" type="video/mp4">
|
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.webm" type="video/webm">
|
||||||
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.ogg" type="video/ogg">
|
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.mp4" type="video/mp4">
|
||||||
</video>
|
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.ogg" type="video/ogg">
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
</ULandingHero>
|
</ULandingHero>
|
||||||
|
|
||||||
<ULandingSection v-for="(section, index) in page.pro.sections" :key="index" v-bind="section" class="!pt-0">
|
<ULandingSection v-for="(section, index) in page.pro.sections" :key="index" v-bind="section" class="!pt-0">
|
||||||
@@ -246,7 +254,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #aside-top>
|
<template #aside-top>
|
||||||
<UDocsSearchButton size="md" class="w-full" />
|
<UContentSearchButton size="md" class="w-full" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #aside-default>
|
<template #aside-default>
|
||||||
@@ -275,7 +283,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #docs-surround>
|
<template #docs-surround>
|
||||||
<UDocsSurround
|
<UContentSurround
|
||||||
:surround="(surround as unknown as ParsedContent[])"
|
:surround="(surround as unknown as ParsedContent[])"
|
||||||
class="w-full gap-4"
|
class="w-full gap-4"
|
||||||
:ui="{
|
:ui="{
|
||||||
@@ -294,7 +302,7 @@
|
|||||||
|
|
||||||
<template #docs-toc>
|
<template #docs-toc>
|
||||||
<div class="absolute top-0 left-0 right-0 space-y-3">
|
<div class="absolute top-0 left-0 right-0 space-y-3">
|
||||||
<UDocsToc :links="toc" class="bg-transparent relative max-h-full overflow-hidden top-0" :ui="({ container: { base: '!pt-0 !pb-4' } } as any)" />
|
<UContentToc :links="toc" class="bg-transparent relative max-h-full overflow-hidden top-0" :ui="({ container: { base: '!pt-0 !pb-4' } } as any)" />
|
||||||
|
|
||||||
<UDivider type="dashed" :ui="{ border: { base: 'border-gray-800/10 dark:border-gray-200/10' } }" />
|
<UDivider type="dashed" :ui="{ border: { base: 'border-gray-800/10 dark:border-gray-200/10' } }" />
|
||||||
|
|
||||||
@@ -612,8 +620,8 @@ const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
|||||||
slot: 'docs-surround',
|
slot: 'docs-surround',
|
||||||
class: 'bottom-4 inset-x-4 h-28'
|
class: 'bottom-4 inset-x-4 h-28'
|
||||||
} : {
|
} : {
|
||||||
name: 'UDocsSurround',
|
name: 'UContentSurround',
|
||||||
to: '/pro/components/docs-surround',
|
to: '/pro/components/content-surround',
|
||||||
class: 'bottom-4 inset-x-4 h-28',
|
class: 'bottom-4 inset-x-4 h-28',
|
||||||
inactive: false
|
inactive: false
|
||||||
}]
|
}]
|
||||||
@@ -621,8 +629,8 @@ const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
|||||||
name: '#default',
|
name: '#default',
|
||||||
class: 'left-4 right-72 inset-y-4'
|
class: 'left-4 right-72 inset-y-4'
|
||||||
}]), isAfterStep(steps.docs + 13) ? {
|
}]), isAfterStep(steps.docs + 13) ? {
|
||||||
name: 'UDocsToc',
|
name: 'UContentToc',
|
||||||
to: '/pro/components/docs-toc',
|
to: '/pro/components/content-toc',
|
||||||
class: 'right-4 inset-y-4 w-64',
|
class: 'right-4 inset-y-4 w-64',
|
||||||
inactive: isAfterStep(steps.docs + 14),
|
inactive: isAfterStep(steps.docs + 14),
|
||||||
children: [{
|
children: [{
|
||||||
|
|||||||
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/ui",
|
"name": "@nuxt/ui",
|
||||||
"version": "2.14.0",
|
"version": "2.14.1",
|
||||||
"repository": "nuxt/ui",
|
"repository": "nuxt/ui",
|
||||||
"homepage": "https://ui.nuxt.com",
|
"homepage": "https://ui.nuxt.com",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"@headlessui/tailwindcss": "^0.2.0",
|
"@headlessui/tailwindcss": "^0.2.0",
|
||||||
"@headlessui/vue": "^1.7.19",
|
"@headlessui/vue": "^1.7.19",
|
||||||
"@iconify-json/heroicons": "^1.1.20",
|
"@iconify-json/heroicons": "^1.1.20",
|
||||||
"@nuxt/kit": "^3.10.2",
|
"@nuxt/kit": "^3.10.3",
|
||||||
"@nuxtjs/color-mode": "^3.3.2",
|
"@nuxtjs/color-mode": "^3.3.2",
|
||||||
"@nuxtjs/tailwindcss": "^6.11.4",
|
"@nuxtjs/tailwindcss": "^6.11.4",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
@@ -64,9 +64,9 @@
|
|||||||
"@release-it/conventional-changelog": "^8.0.1",
|
"@release-it/conventional-changelog": "^8.0.1",
|
||||||
"@vue/test-utils": "^2.4.4",
|
"@vue/test-utils": "^2.4.4",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"happy-dom": "^13.3.8",
|
"happy-dom": "^13.4.1",
|
||||||
"joi": "^17.12.1",
|
"joi": "^17.12.2",
|
||||||
"nuxt": "^3.10.2",
|
"nuxt": "^3.10.3",
|
||||||
"release-it": "^17.1.1",
|
"release-it": "^17.1.1",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"unbuild": "^2.0.0",
|
"unbuild": "^2.0.0",
|
||||||
@@ -78,10 +78,10 @@
|
|||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@nuxt/kit": "^3.10.2",
|
"@nuxt/kit": "3.10.3",
|
||||||
"@nuxt/schema": "3.10.2",
|
"@nuxt/schema": "3.10.3",
|
||||||
"tailwindcss": "3.4.1",
|
"tailwindcss": "3.4.1",
|
||||||
"@headlessui/vue": "^1.7.19",
|
"@headlessui/vue": "1.7.19",
|
||||||
"vue": "3.4.19"
|
"vue": "3.4.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
795
pnpm-lock.yaml
generated
795
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
import { omit } from './lodash'
|
import { omit } from './runtime/utils/lodash'
|
||||||
import { kebabCase, camelCase, upperFirst } from 'scule'
|
import { kebabCase, camelCase, upperFirst } from 'scule'
|
||||||
|
|
||||||
const colorsToExclude = [
|
const colorsToExclude = [
|
||||||
112
src/module.ts
112
src/module.ts
@@ -1,10 +1,22 @@
|
|||||||
|
import { createRequire } from 'node:module'
|
||||||
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
|
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
|
||||||
import type { CollectionNames, IconsPluginOptions } from '@egoist/tailwindcss-icons'
|
import { defaultExtractor as createDefaultExtractor } from 'tailwindcss/lib/lib/defaultExtractor.js'
|
||||||
|
import { iconsPlugin, getIconCollections, type CollectionNames, type IconsPluginOptions } from '@egoist/tailwindcss-icons'
|
||||||
import { name, version } from '../package.json'
|
import { name, version } from '../package.json'
|
||||||
import createTemplates from './templates'
|
import createTemplates from './templates'
|
||||||
|
import { generateSafelist, excludeColors, customSafelistExtractor } from './colors'
|
||||||
import * as config from './runtime/ui.config'
|
import * as config from './runtime/ui.config'
|
||||||
import type { DeepPartial, Strategy } from './runtime/types/utils'
|
import type { DeepPartial, Strategy } from './runtime/types/utils'
|
||||||
import installTailwind from './tailwind'
|
|
||||||
|
const defaultExtractor = createDefaultExtractor({ tailwindConfig: { separator: ':' } })
|
||||||
|
const _require = createRequire(import.meta.url)
|
||||||
|
const defaultColors = _require('tailwindcss/colors.js')
|
||||||
|
|
||||||
|
delete defaultColors.lightBlue
|
||||||
|
delete defaultColors.warmGray
|
||||||
|
delete defaultColors.trueGray
|
||||||
|
delete defaultColors.coolGray
|
||||||
|
delete defaultColors.blueGray
|
||||||
|
|
||||||
type UI = {
|
type UI = {
|
||||||
primary?: string
|
primary?: string
|
||||||
@@ -76,13 +88,107 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
nuxt.options.css.push(resolve(runtimeDir, 'ui.css'))
|
nuxt.options.css.push(resolve(runtimeDir, 'ui.css'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
nuxt.hook('tailwindcss:config', function (tailwindConfig) {
|
||||||
|
tailwindConfig.theme = tailwindConfig.theme || {}
|
||||||
|
tailwindConfig.theme.extend = tailwindConfig.theme.extend || {}
|
||||||
|
tailwindConfig.theme.extend.colors = tailwindConfig.theme.extend.colors || {}
|
||||||
|
|
||||||
|
const globalColors: any = {
|
||||||
|
...(tailwindConfig.theme.colors || defaultColors),
|
||||||
|
...tailwindConfig.theme.extend?.colors
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
globalColors.primary = tailwindConfig.theme.extend.colors.primary = {
|
||||||
|
50: 'rgb(var(--color-primary-50) / <alpha-value>)',
|
||||||
|
100: 'rgb(var(--color-primary-100) / <alpha-value>)',
|
||||||
|
200: 'rgb(var(--color-primary-200) / <alpha-value>)',
|
||||||
|
300: 'rgb(var(--color-primary-300) / <alpha-value>)',
|
||||||
|
400: 'rgb(var(--color-primary-400) / <alpha-value>)',
|
||||||
|
500: 'rgb(var(--color-primary-500) / <alpha-value>)',
|
||||||
|
600: 'rgb(var(--color-primary-600) / <alpha-value>)',
|
||||||
|
700: 'rgb(var(--color-primary-700) / <alpha-value>)',
|
||||||
|
800: 'rgb(var(--color-primary-800) / <alpha-value>)',
|
||||||
|
900: 'rgb(var(--color-primary-900) / <alpha-value>)',
|
||||||
|
950: 'rgb(var(--color-primary-950) / <alpha-value>)',
|
||||||
|
DEFAULT: 'rgb(var(--color-primary-DEFAULT) / <alpha-value>)'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalColors.gray) {
|
||||||
|
// @ts-ignore
|
||||||
|
globalColors.cool = tailwindConfig.theme.extend.colors.cool = defaultColors.gray
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
globalColors.gray = tailwindConfig.theme.extend.colors.gray = {
|
||||||
|
50: 'rgb(var(--color-gray-50) / <alpha-value>)',
|
||||||
|
100: 'rgb(var(--color-gray-100) / <alpha-value>)',
|
||||||
|
200: 'rgb(var(--color-gray-200) / <alpha-value>)',
|
||||||
|
300: 'rgb(var(--color-gray-300) / <alpha-value>)',
|
||||||
|
400: 'rgb(var(--color-gray-400) / <alpha-value>)',
|
||||||
|
500: 'rgb(var(--color-gray-500) / <alpha-value>)',
|
||||||
|
600: 'rgb(var(--color-gray-600) / <alpha-value>)',
|
||||||
|
700: 'rgb(var(--color-gray-700) / <alpha-value>)',
|
||||||
|
800: 'rgb(var(--color-gray-800) / <alpha-value>)',
|
||||||
|
900: 'rgb(var(--color-gray-900) / <alpha-value>)',
|
||||||
|
950: 'rgb(var(--color-gray-950) / <alpha-value>)'
|
||||||
|
}
|
||||||
|
|
||||||
|
const colors = excludeColors(globalColors)
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
nuxt.options.appConfig.ui = {
|
||||||
|
primary: 'green',
|
||||||
|
gray: 'cool',
|
||||||
|
colors,
|
||||||
|
strategy: 'merge'
|
||||||
|
}
|
||||||
|
|
||||||
|
tailwindConfig.safelist = tailwindConfig.safelist || []
|
||||||
|
tailwindConfig.safelist.push(...generateSafelist(options.safelistColors || [], colors))
|
||||||
|
})
|
||||||
|
|
||||||
createTemplates(nuxt)
|
createTemplates(nuxt)
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
|
|
||||||
await installModule('nuxt-icon')
|
await installModule('nuxt-icon')
|
||||||
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
||||||
await installTailwind(options, nuxt, { resolve, runtimeDir })
|
await installModule('@nuxtjs/tailwindcss', {
|
||||||
|
exposeConfig: true,
|
||||||
|
config: {
|
||||||
|
darkMode: 'class',
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/forms')({ strategy: 'class' }),
|
||||||
|
require('@tailwindcss/aspect-ratio'),
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
require('@tailwindcss/container-queries'),
|
||||||
|
require('@headlessui/tailwindcss'),
|
||||||
|
iconsPlugin(Array.isArray(options.icons) || options.icons === 'all' ? { collections: getIconCollections(options.icons) } : typeof options.icons === 'object' ? options.icons as IconsPluginOptions : {})
|
||||||
|
],
|
||||||
|
content: {
|
||||||
|
files: [
|
||||||
|
resolve(runtimeDir, 'components/**/*.{vue,mjs,ts}'),
|
||||||
|
resolve(runtimeDir, 'ui.config/**/*.{mjs,js,ts}')
|
||||||
|
],
|
||||||
|
transform: {
|
||||||
|
vue: (content) => {
|
||||||
|
return content.replaceAll(/(?:\r\n|\r|\n)/g, ' ')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extract: {
|
||||||
|
vue: (content) => {
|
||||||
|
return [
|
||||||
|
...defaultExtractor(content),
|
||||||
|
// @ts-ignore
|
||||||
|
...customSafelistExtractor(options.prefix, content, nuxt.options.appConfig.ui.colors, options.safelistColors)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
|
|
||||||
|
|||||||
135
src/tailwind.ts
135
src/tailwind.ts
@@ -1,135 +0,0 @@
|
|||||||
import { createRequire } from 'node:module'
|
|
||||||
import { join } from 'pathe'
|
|
||||||
import { addTemplate, installModule, useNuxt } from '@nuxt/kit'
|
|
||||||
import { excludeColors, generateSafelist } from './runtime/utils/colors'
|
|
||||||
import type { ModuleOptions } from './module'
|
|
||||||
|
|
||||||
const _require = createRequire(import.meta.url)
|
|
||||||
const defaultColors = _require('tailwindcss/colors.js')
|
|
||||||
|
|
||||||
delete defaultColors.lightBlue
|
|
||||||
delete defaultColors.warmGray
|
|
||||||
delete defaultColors.trueGray
|
|
||||||
delete defaultColors.coolGray
|
|
||||||
delete defaultColors.blueGray
|
|
||||||
|
|
||||||
export default async function installTailwind (moduleOptions: ModuleOptions, nuxt = useNuxt(), { resolve, runtimeDir }) {
|
|
||||||
// 1. register hook
|
|
||||||
// @ts-ignore
|
|
||||||
nuxt.hook('tailwindcss:config', function (tailwindConfig) {
|
|
||||||
tailwindConfig.theme = tailwindConfig.theme || {}
|
|
||||||
tailwindConfig.theme.extend = tailwindConfig.theme.extend || {}
|
|
||||||
tailwindConfig.theme.extend.colors =
|
|
||||||
tailwindConfig.theme.extend.colors || {}
|
|
||||||
|
|
||||||
const globalColors: any = {
|
|
||||||
...(tailwindConfig.theme.colors || defaultColors),
|
|
||||||
...tailwindConfig.theme.extend?.colors
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
globalColors.primary = tailwindConfig.theme.extend.colors.primary = {
|
|
||||||
50: 'rgb(var(--color-primary-50) / <alpha-value>)',
|
|
||||||
100: 'rgb(var(--color-primary-100) / <alpha-value>)',
|
|
||||||
200: 'rgb(var(--color-primary-200) / <alpha-value>)',
|
|
||||||
300: 'rgb(var(--color-primary-300) / <alpha-value>)',
|
|
||||||
400: 'rgb(var(--color-primary-400) / <alpha-value>)',
|
|
||||||
500: 'rgb(var(--color-primary-500) / <alpha-value>)',
|
|
||||||
600: 'rgb(var(--color-primary-600) / <alpha-value>)',
|
|
||||||
700: 'rgb(var(--color-primary-700) / <alpha-value>)',
|
|
||||||
800: 'rgb(var(--color-primary-800) / <alpha-value>)',
|
|
||||||
900: 'rgb(var(--color-primary-900) / <alpha-value>)',
|
|
||||||
950: 'rgb(var(--color-primary-950) / <alpha-value>)',
|
|
||||||
DEFAULT: 'rgb(var(--color-primary-DEFAULT) / <alpha-value>)'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globalColors.gray) {
|
|
||||||
// @ts-ignore
|
|
||||||
globalColors.cool = tailwindConfig.theme.extend.colors.cool =
|
|
||||||
defaultColors.gray
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
globalColors.gray = tailwindConfig.theme.extend.colors.gray = {
|
|
||||||
50: 'rgb(var(--color-gray-50) / <alpha-value>)',
|
|
||||||
100: 'rgb(var(--color-gray-100) / <alpha-value>)',
|
|
||||||
200: 'rgb(var(--color-gray-200) / <alpha-value>)',
|
|
||||||
300: 'rgb(var(--color-gray-300) / <alpha-value>)',
|
|
||||||
400: 'rgb(var(--color-gray-400) / <alpha-value>)',
|
|
||||||
500: 'rgb(var(--color-gray-500) / <alpha-value>)',
|
|
||||||
600: 'rgb(var(--color-gray-600) / <alpha-value>)',
|
|
||||||
700: 'rgb(var(--color-gray-700) / <alpha-value>)',
|
|
||||||
800: 'rgb(var(--color-gray-800) / <alpha-value>)',
|
|
||||||
900: 'rgb(var(--color-gray-900) / <alpha-value>)',
|
|
||||||
950: 'rgb(var(--color-gray-950) / <alpha-value>)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const colors = excludeColors(globalColors)
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
nuxt.options.appConfig.ui = {
|
|
||||||
primary: 'green',
|
|
||||||
gray: 'cool',
|
|
||||||
colors,
|
|
||||||
strategy: 'merge'
|
|
||||||
}
|
|
||||||
|
|
||||||
tailwindConfig.safelist = tailwindConfig.safelist || []
|
|
||||||
tailwindConfig.safelist.push(
|
|
||||||
...generateSafelist(moduleOptions.safelistColors || [], colors)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 2. add config template
|
|
||||||
const configTemplate = addTemplate({
|
|
||||||
filename: 'nuxtui-tailwind.config.cjs',
|
|
||||||
write: true,
|
|
||||||
getContents: () => `
|
|
||||||
const { defaultExtractor: createDefaultExtractor } = require('tailwindcss/lib/lib/defaultExtractor.js')
|
|
||||||
const { customSafelistExtractor } = require(${JSON.stringify(resolve(runtimeDir, 'utils', 'colors'))})
|
|
||||||
const { iconsPlugin, getIconCollections } = require('@egoist/tailwindcss-icons')
|
|
||||||
|
|
||||||
const defaultExtractor = createDefaultExtractor({ tailwindConfig: { separator: ':' } })
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
darkMode: 'class',
|
|
||||||
plugins: [
|
|
||||||
require('@tailwindcss/forms')({ strategy: 'class' }),
|
|
||||||
require('@tailwindcss/aspect-ratio'),
|
|
||||||
require('@tailwindcss/typography'),
|
|
||||||
require('@tailwindcss/container-queries'),
|
|
||||||
require('@headlessui/tailwindcss'),
|
|
||||||
iconsPlugin(${Array.isArray(moduleOptions.icons) || moduleOptions.icons === 'all' ? `{ collections: getIconCollections(${JSON.stringify(moduleOptions.icons)}) }` : typeof moduleOptions.icons === 'object' ? JSON.stringify(moduleOptions.icons) : '{}'})
|
|
||||||
],
|
|
||||||
content: {
|
|
||||||
files: [
|
|
||||||
${JSON.stringify(resolve(runtimeDir, 'components/**/*.{vue,mjs,ts}'))},
|
|
||||||
${JSON.stringify(resolve(runtimeDir, 'ui.config/**/*.{mjs,js,ts}'))}
|
|
||||||
],
|
|
||||||
transform: {
|
|
||||||
vue: (content) => {
|
|
||||||
return content.replaceAll(/(?:\\r\\n|\\r|\\n)/g, ' ')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
extract: {
|
|
||||||
vue: (content) => {
|
|
||||||
return [
|
|
||||||
...defaultExtractor(content),
|
|
||||||
...customSafelistExtractor(${JSON.stringify(moduleOptions.prefix)}, content, ${JSON.stringify(nuxt.options.appConfig.ui.colors)}, ${JSON.stringify(moduleOptions.safelistColors)})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
})
|
|
||||||
|
|
||||||
// 3. install module
|
|
||||||
await installModule('@nuxtjs/tailwindcss', {
|
|
||||||
exposeConfig: true,
|
|
||||||
configPath: [
|
|
||||||
configTemplate.dst,
|
|
||||||
join(nuxt.options.rootDir, 'tailwind.config')
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user