Skip to content

Add support for Tailwind CSS #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2025
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
24 changes: 22 additions & 2 deletions packages/create-vue-lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type Config = {
includeGithubCi: boolean
includeAtAliases: boolean
includeTestVariable: boolean
includeTailwind: boolean
includeVpRaw: boolean
}

type Args = {
Expand Down Expand Up @@ -263,10 +265,12 @@ async function init() {
process.exit(1)
}

const includeTailwind = await togglePrompt('Include Tailwind CSS?')
const includeEsLint = await togglePrompt('Include ESLint?', true)
const includeEsLintStylistic = await togglePromptIf(includeEsLint, 'Include ESLint Stylistic for formatting?', includeEsLint)
const includeVitest = await togglePromptIf(extended, 'Include Vitest for testing?', true)
const includeDocs = await togglePrompt('Include VitePress for documentation?', true)
const includeVpRaw = includeDocs && await togglePromptIf(extended, 'Include support for vp-raw in VitePress?', includeTailwind)
const includeGithubPages = includeDocs && await togglePrompt('Include GitHub Pages config for documentation?')
const includePlayground = await togglePrompt('Include playground application for development?', true)
const includeGithubCi = await togglePrompt('Include GitHub CI configuration?', !!githubPath)
Expand Down Expand Up @@ -338,7 +342,9 @@ async function init() {
includeVitest,
includeGithubCi,
includeAtAliases,
includeTestVariable
includeTestVariable,
includeTailwind,
includeVpRaw
}

copyTemplate('base', config)
Expand Down Expand Up @@ -367,6 +373,14 @@ async function init() {
copyTemplate('ci', config)
}

if (config.includeTailwind) {
copyTemplate('tailwind', config)
}

if (config.includeVpRaw) {
copyTemplate('vp-raw', config)
}

console.log()
console.log(`${bgGreen(bold(black('DONE')))} Project created`)
console.log()
Expand Down Expand Up @@ -441,7 +455,10 @@ function copyFiles(templateFile: string, config: Config) {
const target = targetPath.replace(/\.ejs$/, '')
let content = ejs.render(template, { config })

if (/\.(json|m?[jt]s)$/.test(target)) {
if (/\.(json|m?[jt]s|vue)$/.test(target)) {
// Ensure there are no blank lines at the start and a single blank line at the end
content = content.trim() + '\n'

// Trim spaces from the ends of lines
content = content.replace(/ +\n/g, '\n')

Expand All @@ -450,6 +467,9 @@ function copyFiles(templateFile: string, config: Config) {

// Remove trailing commas and any blank newlines that follow them
content = content.replace(/, *(?:\n+(\n\s*)|(\s*))([}\])])/g, '$1$2$3')

// Trim blank lines after {, [ or (
content = content.replace(/([{[(]\n)\n+/g, '$1')
}

fs.writeFileSync(target, content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
},
"devDependencies": {
"@rollup/plugin-replace": "^6.0.2",
<%_ if (config.includeTailwind) { _%>
"@tailwindcss/vite": "^4.1.5",
<%_ } _%>
"@tsconfig/node22": "^22.0.1",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.13.14",
Expand All @@ -53,6 +56,9 @@
"npm-run-all2": "^7.0.2",
"publint": "^0.3.9",
"rimraf": "^5.0.1",
<%_ if (config.includeTailwind) { _%>
"tailwindcss": "^4.1.5",
<%_ } _%>
"typescript": "~5.8.0",
"vite": "^6.2.4",
"vite-plugin-dts": "^4.5.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { defineConfig, type UserConfig } from 'vite'
import replace from '@rollup/plugin-replace'
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'
<%_ if (config.includeTailwind) { _%>
import tailwindcss from '@tailwindcss/vite'
<%_ } _%>

export default defineConfig(({ mode }): UserConfig => {
if (mode !== 'production' && mode !== 'development' && mode !== 'neutral' && mode !== 'test') {
Expand Down Expand Up @@ -38,6 +41,9 @@ export default defineConfig(({ mode }): UserConfig => {
prodDevtools: mode === 'development'
}
}),
<%_ if (config.includeTailwind) { _%>
tailwindcss(),
<%_ } _%>
dtsPlugin
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ const msg = ref('Hello world!')
</script>

<template>
<div class="outer">
<input v-model="msg">
<div class="outer<%- config.includeTailwind ? ' border-1 border-solid border-green-700 p-5' : '' %>">
<input v-model="msg"<%- config.includeTailwind ? ' class="border-1 border-solid border-neutral-500 px-1 py-0.5"' : '' %>>
<p>{{ msg }}</p>
</div>
</template>

<%_ if (!config.includeTailwind) { _%>
<style scoped>
.outer {
border: 1px solid green;
Expand All @@ -26,3 +27,4 @@ const msg = ref('Hello world!')
padding: 2px 4px;
}
</style>
<%_ } _%>
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,22 @@ if (__DEV__) {
</script>

<template>
<div class="panel">
<div class="panel<%- config.includeTailwind ? ' border-1 border-solid border-[#34495e] rounded-[5px] flex flex-col font-sans overflow-hidden [&>*+*]:border-t-1 [&>*+*]:border-t-solid [&>*+*]:border-t-[#34495e] [&>.panel-section:first-child]:rounded-t-[5px] [&>.panel-section:last-child]:rounded-b-[5px]' : '' %>">
<slot name="header">
<MyPanelSection v-if="title" class="panel-header">{{ title }}</MyPanelSection>
<MyPanelSection v-if="title" class="panel-header<%- config.includeTailwind ? ' bg-[#34495e] inset-ring inset-ring-white text-white tracking-wide text-shadow-sm' : '' %>">{{ title }}</MyPanelSection>
</slot>
<slot name="body">
<MyPanelSection class="panel-body">
<MyPanelSection class="panel-body<%- config.includeTailwind ? ' flex-auto overflow-auto' : '' %>">
<slot />
</MyPanelSection>
</slot>
<slot name="footer">
<MyPanelSection v-if="footer" class="panel-footer">{{ footer }}</MyPanelSection>
<MyPanelSection v-if="footer" class="panel-footer<%- config.includeTailwind ? ' bg-[#34495e] inset-ring inset-ring-white text-white tracking-wide text-shadow-sm' : '' %>">{{ footer }}</MyPanelSection>
</slot>
</div>
</template>

<%_ if (!config.includeTailwind) { _%>
<style scoped>
.panel {
border: 1px solid #34495e;
Expand Down Expand Up @@ -65,3 +66,4 @@ if (__DEV__) {
overflow: auto;
}
</style>
<%_ } _%>
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ if (__DEV__) {
</script>

<template>
<div class="panel-section">
<div class="panel-section<%- config.includeTailwind ? ' p-2' : '' %>">
<slot />
</div>
</template>

<%_ if (!config.includeTailwind) { _%>
<style scoped>
.panel-section {
padding: 10px;
}
</style>
<%_ } _%>
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<%_ if (config.includeTailwind) { _%>
import './index.css'

<%_ } _%>
export { default as ExampleComponent } from './components/ExampleComponent.vue'
export { default as MyPanel } from './components/MyPanel.vue'
export { default as MyPanelSection } from './components/MyPanelSection.vue'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
"vue": "^3.5.13"
},
"devDependencies": {
<%_ if (config.includeTailwind) { _%>
"@tailwindcss/vite": "^4.1.5",
<%_ } _%>
"@tsconfig/node22": "^22.0.1",
"@types/node": "^22.13.14",
"@vitejs/plugin-vue": "^5.2.3",
"@vue/tsconfig": "^0.7.0",
"npm-run-all2": "^7.0.2",
"rimraf": "^5.0.1",
<%_ if (config.includeTailwind) { _%>
"tailwindcss": "^4.1.5",
<%_ } _%>
"typescript": "~5.8.0",
"vite": "^6.2.4",
"vite-plugin-vue-devtools": "^7.7.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig, type UserConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
<%_ if (config.includeTailwind) { _%>
import tailwindcss from '@tailwindcss/vite'
<%_ } _%>

<%_ if (config.includeAtAliases) { _%>
const librarySrc = fileURLToPath(new URL('../<%- config.mainPackageDirName %>/src/', import.meta.url))
Expand All @@ -12,6 +15,9 @@ const playgroundSrc = fileURLToPath(new URL('./src/', import.meta.url))
export default defineConfig(({ mode }): UserConfig => ({
plugins: [
vue(),
<%_ if (config.includeTailwind) { _%>
tailwindcss(),
<%_ } _%>
vueDevTools()
],

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { ExampleComponent, MyPanel } from '@scopedPackageName@'
import { ExampleComponent, MyPanel } from '<%- config.scopedPackageName %>'
</script>

<template>
<div class="main">
<div class="main<%- config.includeTailwind ? ' flex flex-col max-w-75 gap-2.5 m-2.5' : '' %>">
<ExampleComponent />
<MyPanel title="Panel title" footer="Panel footer">
Header and footer
Expand All @@ -20,6 +20,7 @@ import { ExampleComponent, MyPanel } from '@scopedPackageName@'
</div>
</template>

<%_ if (!config.includeTailwind) { _%>
<style scoped>
.main {
max-width: 300px;
Expand All @@ -29,3 +30,4 @@ import { ExampleComponent, MyPanel } from '@scopedPackageName@'
margin-top: 10px;
}
</style>
<%_ } _%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import "tailwindcss";

@source ".";
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { fileURLToPath, URL } from 'node:url'

import { defineConfigWithTheme } from 'vitepress'
<%_ if (config.includeTailwind) { _%>
import tailwindcss from '@tailwindcss/vite'
<%_ } _%>

<%_ if (config.includeAtAliases) { _%>
const librarySrc = fileURLToPath(new URL('../../<%- config.mainPackageDirName %>/src/', import.meta.url))
Expand Down Expand Up @@ -34,6 +37,12 @@ export default ({ mode }: { mode: string }) => defineConfigWithTheme({
<%_ } _%>

vite: {
<%_ if (config.includeTailwind) { _%>
plugins: [
tailwindcss()
],
<%_ } _%>

resolve: {
<%_ if (config.includeAtAliases) { _%>
alias: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
"vue": "^3.5.13"
},
"devDependencies": {
<%_ if (config.includeTailwind) { _%>
"@tailwindcss/vite": "^4.1.5",
<%_ } _%>
"@tsconfig/node22": "^22.0.1",
"@types/node": "^22.13.14",
"@vue/tsconfig": "^0.7.0",
"npm-run-all2": "^7.0.2",
<%_ if (config.includeVpRaw) { _%>
"postcss": "^8.5.3",
<%_ } _%>
"rimraf": "^5.0.1",
<%_ if (config.includeTailwind) { _%>
"tailwindcss": "^4.1.5",
<%_ } _%>
"typescript": "~5.8.0",
"vitepress": "^1.6.3",
"vue-tsc": "^2.2.8"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ExampleComponent, MyPanel } from '@scopedPackageName@'
import { ExampleComponent, MyPanel } from '<%- config.scopedPackageName %>'
</script>

<style scoped>
Expand All @@ -10,6 +10,9 @@ import { ExampleComponent, MyPanel } from '@scopedPackageName@'

# Introduction

<%_ if (config.includeVpRaw) { _%>
::: raw
<%_ } _%>
<ExampleComponent />

<MyPanel title="Panel title" footer="Panel footer">
Expand All @@ -27,3 +30,6 @@ import { ExampleComponent, MyPanel } from '@scopedPackageName@'
<MyPanel>
No header or footer
</MyPanel>
<%_ if (config.includeVpRaw) { _%>
:::
<%_ } _%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { postcssIsolateStyles } from 'vitepress'

export default {
plugins: [
// See https://vitepress.dev/guide/markdown#raw
postcssIsolateStyles({
includeFiles: [/base\.css/, /vp-doc\.css/]
})
]
}
28 changes: 27 additions & 1 deletion packages/docs/src/questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@
<span class="check">✔</span> <a href="#main-package-directory">Main package directory … test-project</a>
<span class="check">✔</span> <a href="#global-variable-name">Global variable name … TestProject</a>
<span class="check">✔</span> <a href="#github-path">GitHub path (optional) … skirtles-code/test-project</a>
<span class="check">✔</span> <a href="#include-tailwind-css">Include Tailwind CSS? … No / Yes</a>
<span class="check">✔</span> <a href="#include-eslint">Include ESLint? … No / Yes</a>
<span class="check">✔</span> <a href="#include-eslint-stylistic">Include ESLint Stylistic for formatting? … No / Yes</a>
<span class="check">✔</span> <a href="#include-vitest">Include Vitest for testing? … No / Yes</a>
<span class="check">✔</span> <a href="#include-vitepress">Include VitePress for documentation? … No / Yes</a>
<span class="check">✔</span> <a href="#include-vp-raw">Include support for vp-raw in VitePress? … No / Yes</a>
<span class="check">✔</span> <a href="#include-github-pages">Include GitHub Pages config for documentation? … No / Yes</a>
<span class="check">✔</span> <a href="#include-playground">Include playground application for development? … No / Yes</a>
<span class="check">✔</span> <a href="#include-github-ci">Include GitHub CI configuration? … No / Yes</a>
Expand Down Expand Up @@ -140,6 +142,12 @@ For example, this project has its repository at `https://github.com/skirtles-cod

While answering this question is optional, it can be especially useful if you intend to use GitHub Pages to host your documentation, as the generated configuration files will be much closer to their final form.

## Include Tailwind CSS?{#include-tailwind-css}

[Tailwind CSS](https://tailwindcss.com/) is a popular CSS framework.

Selecting this option will add version 4 of Tailwind CSS to the project. This will include Vite configuration for all packages, as well as using Tailwind in the example code.

## Include ESLint?

Include configuration for ESLint. This will be very similar to the default configuration generated by the official [`create-vue`](https://github.com/vuejs/create-vue) tool.
Expand Down Expand Up @@ -172,9 +180,27 @@ Very small libraries might prefer to just use a GitHub `README.md` instead. Larg

VitePress will be configured with an `alias` to allow you to access your library within the documentation. This will use the library source code directly, without needing a build or release of the library.

## Include support for vp-raw in VitePress?{#include-vp-raw}

:::info NOTE
You'll only see this question if you chose to include VitePress *and* you're using the `--extended` flag.
:::

The default theme for VitePress can potentially clash with the CSS for components in your library. This is especially problematic when using Tailwind.

To mitigate this, VitePress supports the use of a `vp-raw` CSS class (or a `raw` custom container) to isolate component examples from the default VitePress styling:

- <https://vitepress.dev/guide/markdown#raw>

Isolating the styles will increase the size and complexity of the documentation CSS, so VitePress doesn't enable it by default. Instead, it must be enabled via a PostCSS plugin.

If you choose to include support for `vp-raw` then PostCSS will be added to the documentation package, along with the relevant configuration to enable style isolation.

This option will default to **Yes** if the project is using Tailwind.

## Include GitHub Pages config for documentation?{#include-github-pages}

You'll only see this question if you chose to include VitePress in the previous question.
You'll only see this question if you chose to include VitePress.

Selecting this option will generate configuration files for deploying your documentation to GitHub Pages via a GitHub Action. The workflow is configured to deploy from the `main` branch.

Expand Down