Initial commit
This commit is contained in:
41
skills/tailwind-setup/README.md
Normal file
41
skills/tailwind-setup/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Tailwind Setup Skill (Vite + shadcn/ui)
|
||||
|
||||
Add Tailwind CSS, shadcn/ui, dark-mode theme tokens, and aliases to a React/Vite frontend that talks to a Django backend.
|
||||
|
||||
## What This Skill Does
|
||||
- Installs Tailwind (+ Vite plugin) and core shadcn/ui deps (`class-variance-authority`, `clsx`, `tailwind-merge`, `lucide-react`).
|
||||
- Updates `vite.config.js` to run `tailwindcss()` alongside React and adds `@` alias → `./src`.
|
||||
- Replaces `src/index.css` with Tailwind entry, then appends theme tokens via `scripts/apply-theme.sh` (uses `assets/tailwind-theme.css`) for dark/light palettes.
|
||||
- Sets up shadcn/ui scaffolding: `components.json`, `jsconfig.json` aliases, and utility `src/lib/utils.js`.
|
||||
- Enables class-based dark mode in `tailwind.config.js`.
|
||||
- Adds `ThemeContext` & `ThemeToggle` components and wraps `App` with `ThemeProvider`.
|
||||
- Installs shadcn/ui components (card, field, input, button, table, navigation-menu, label, separator, alert) via CLI.
|
||||
- Verifies build with `npm --prefix ./frontend run build`.
|
||||
|
||||
## Prerequisites
|
||||
- React + Vite frontend in `frontend/`.
|
||||
- Django backend already set up (used only for proxy alignment).
|
||||
- Node.js 18+ and npm; mkcert HTTPS recommended.
|
||||
|
||||
## Setup Summary (see SKILL.md for exact edits)
|
||||
1) **Deps**: `npm --prefix ./frontend install tailwindcss @tailwindcss/vite class-variance-authority clsx tailwind-merge lucide-react`.
|
||||
2) **Vite config**: import `path`, `tailwindcss`; add plugin; add `resolve.alias` `{ '@': path.resolve(__dirname, './src') }`.
|
||||
3) **CSS entry**: set `src/index.css` to `@import "tailwindcss";`.
|
||||
4) **Theme tokens**: run `bash .claude/skills/tailwind-setup/scripts/apply-theme.sh frontend` (appends tokens to `src/index.css`).
|
||||
5) **shadcn scaffolding**: create `components.json`, `jsconfig.json`, `src/lib/utils.js`.
|
||||
6) **Tailwind config**: `darkMode: 'class'`, content globs for `./index.html` and `./src/**/*.{js,jsx}`.
|
||||
7) **ThemeProvider + toggle**: add `src/contexts/ThemeContext.jsx`, `src/components/ThemeToggle.jsx`; wrap `<Router />` in `App.jsx`; drop toggle into navbar.
|
||||
8) **shadcn components**: run `npx --prefix ./frontend shadcn@latest add ...` for card/field/input/button/table/navigation-menu/label/separator/alert.
|
||||
9) **Build check**: `npm --prefix ./frontend run build`.
|
||||
|
||||
## Outputs/Artifacts
|
||||
- Tailwind + shadcn tokens in `src/index.css`.
|
||||
- `tailwind.config.js`, `components.json`, `jsconfig.json`, `src/lib/utils.js`.
|
||||
- Theme context/toggle components added and App wrapped.
|
||||
- Installed shadcn/ui primitives ready for use.
|
||||
|
||||
## Notes & Gotchas
|
||||
- Run theme script from project root and pass `frontend` path arg.
|
||||
- Ensure Vite aliases in `vite.config.js` and `jsconfig.json` match.
|
||||
- If you already have CSS content, back it up before replacing with Tailwind import (tokens are appended by the script).
|
||||
- Add additional content globs to `tailwind.config.js` if you place components elsewhere.
|
||||
352
skills/tailwind-setup/SKILL.md
Normal file
352
skills/tailwind-setup/SKILL.md
Normal file
@@ -0,0 +1,352 @@
|
||||
---
|
||||
name: tailwind-setup
|
||||
description: Configure Tailwind CSS and shadcn/ui for React frontends with Django backends, including dark mode support and theme tokens. This skill should be used when setting up a new React project or adding Tailwind to an existing one.
|
||||
allowed-tools: Bash, Write, Edit, Read, Glob, Grep, TodoWrite, mcp__shadcn__get_project_registries, mcp__shadcn__search_items_in_registries, mcp__shadcn__view_items_in_registries, mcp__shadcn__get_item_examples_from_registries, mcp__shadcn__get_add_command_for_items, mcp__shadcn__get_audit_checklist
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Configure Tailwind CSS with shadcn/ui for React frontends connecting to Django backends. This setup includes dark mode support, theme tokens, and shadcn/ui component integration. The configuration enables automatic dark mode switching and provides a foundation for building consistent, themeable user interfaces.
|
||||
|
||||
## Setup Process Overview
|
||||
|
||||
Follow these steps in order:
|
||||
1. Install Dependencies
|
||||
2. Configure Vite for Django Backend
|
||||
3. Setup Tailwind in CSS
|
||||
4. Apply Base Theme (Required for dark mode support)
|
||||
5. Setup shadcn/ui
|
||||
6. Implement Dark Mode with Toggle
|
||||
7. Verify Setup and Check for Errors
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Install Dependencies
|
||||
|
||||
Install Tailwind CSS and the Vite plugin:
|
||||
|
||||
```bash
|
||||
npm --prefix ./frontend tailwindcss @tailwindcss/vite
|
||||
```
|
||||
|
||||
## Step 2: Configure Vite for Django Backend
|
||||
|
||||
Configure `vite.config.js` to enable Tailwind and path aliases:
|
||||
|
||||
1. Read existing `vite.config.js`
|
||||
2. Add the required imports at the top (keep the existing React import):
|
||||
```javascript
|
||||
import path from 'node:path'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
```
|
||||
3. Update the plugins array so Tailwind runs alongside React:
|
||||
```javascript
|
||||
plugins: [
|
||||
react(),
|
||||
tailwindcss(),
|
||||
]
|
||||
```
|
||||
4. Define the alias block in the same file so `@/` resolves to `src` (this relies on the `path` import above):
|
||||
```javascript
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Step 3: Setup Tailwind in CSS
|
||||
|
||||
Configure the main CSS file to import Tailwind:
|
||||
|
||||
1. Read existing `src/index.css`
|
||||
2. Replace the entire contents with the Tailwind import:
|
||||
```css
|
||||
@import "tailwindcss";
|
||||
```
|
||||
|
||||
## Step 4: Apply Base Theme
|
||||
|
||||
Apply the base theme by running the bundled script from the project root directory at: `scripts/apply-theme.sh`
|
||||
|
||||
Apply the base theme by running the script from the skill's bundled resources at:`scripts/apply-theme.sh` within this skill's directory.
|
||||
|
||||
The script requires requires the frontend directory path (relative to project
|
||||
root) as an argument.
|
||||
|
||||
3. **Run the theme script from project root**:
|
||||
```bash
|
||||
bash <path-to-skill>/scripts/apply-theme.sh frontend
|
||||
```
|
||||
|
||||
The script appends shadcn/ui's design tokens (from `assets/tailwind-theme.css`, in the skill's bundled resources) to `src/index.css`, adding support for typography, colors, and automatic dark mode.
|
||||
|
||||
|
||||
## Step 5: Setup shadcn/ui
|
||||
|
||||
### 5a. Install shadcn/ui Dependencies
|
||||
|
||||
Install the required packages for shadcn/ui component functionality:
|
||||
|
||||
```bash
|
||||
npm --prefix ./frontend install class-variance-authority clsx tailwind-merge lucide-react
|
||||
```
|
||||
|
||||
### 5b. Create jsconfig.json for Path Aliases
|
||||
|
||||
Create `jsconfig.json` in the frontend root directory:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5c. Create Utility Helper Function
|
||||
|
||||
Create `src/lib/utils.js`:
|
||||
|
||||
```javascript
|
||||
import { clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
```
|
||||
|
||||
### 5d. Create components.json Configuration
|
||||
|
||||
Create `components.json` in the frontend root directory:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": false,
|
||||
"tsx": false,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "src/index.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5e. Install shadcn/ui Components
|
||||
|
||||
**PREREQUISITE:** Before installing components, verify their availability and review usage patterns using the shadcn MCP server. This ensures compatibility with the current registry and helps understand proper implementation patterns.
|
||||
|
||||
**MCP Verification:**
|
||||
|
||||
Use the shadcn MCP tools to search for each component and confirm it exists in the registry:
|
||||
|
||||
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="card"`
|
||||
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="button"`
|
||||
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="navigation-menu"`
|
||||
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="alert"`
|
||||
|
||||
**Install Required Components:**
|
||||
|
||||
Once verified, install the components using the shadcn CLI:
|
||||
|
||||
```bash
|
||||
npx --prefix ./frontend shadcn@latest add card
|
||||
npx --prefix ./frontend shadcn@latest add field
|
||||
npx --prefix ./frontend shadcn@latest add input
|
||||
npx --prefix ./frontend shadcn@latest add button
|
||||
npx --prefix ./frontend shadcn@latest add table
|
||||
npx --prefix ./frontend shadcn@latest add navigation-menu
|
||||
npx --prefix ./frontend shadcn@latest add label
|
||||
npx --prefix ./frontend shadcn@latest add separator
|
||||
npx --prefix ./frontend shadcn@latest add alert
|
||||
```
|
||||
|
||||
## Step 6: Implement Dark Mode with Toggle
|
||||
|
||||
### 6a. Configure Tailwind for Class-based Dark Mode
|
||||
|
||||
Create or update `tailwind.config.js` in the frontend root directory, to enable class-based dark mode:
|
||||
|
||||
```js
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{js,jsx}",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### 6b. Create Theme Context
|
||||
|
||||
Create `src/contexts/ThemeContext.jsx`:
|
||||
|
||||
```js
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
|
||||
const ThemeContext = createContext({
|
||||
theme: "system",
|
||||
setTheme: () => null,
|
||||
});
|
||||
|
||||
export function ThemeProvider({ children, defaultTheme = "system", storageKey = "theme" }) {
|
||||
const [theme, setTheme] = useState(() => {
|
||||
return localStorage.getItem(storageKey) || defaultTheme;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
|
||||
root.classList.remove("dark");
|
||||
|
||||
if (theme === "system") {
|
||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
if (systemTheme) {
|
||||
root.classList.add("dark");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme === "dark") {
|
||||
root.classList.add("dark");
|
||||
}
|
||||
}, [theme]);
|
||||
|
||||
const value = {
|
||||
theme,
|
||||
setTheme: (newTheme) => {
|
||||
localStorage.setItem(storageKey, newTheme);
|
||||
setTheme(newTheme);
|
||||
},
|
||||
};
|
||||
|
||||
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
||||
}
|
||||
|
||||
export function useTheme() {
|
||||
const context = useContext(ThemeContext);
|
||||
|
||||
if (context === undefined) {
|
||||
throw new Error("useTheme must be used within a ThemeProvider");
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
```
|
||||
|
||||
### 6c. Create Theme Toggle Button Component
|
||||
|
||||
Create `src/components/ThemeToggle.jsx`:
|
||||
|
||||
```js
|
||||
import { Moon, Sun } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useTheme } from "@/contexts/ThemeContext";
|
||||
|
||||
export default function ThemeToggle() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const toggleTheme = () => {
|
||||
// If currently system or light, switch to dark
|
||||
// If currently dark, switch to light
|
||||
if (theme === "dark") {
|
||||
setTheme("light");
|
||||
} else {
|
||||
setTheme("dark");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={toggleTheme}
|
||||
aria-label="Toggle theme"
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 6d. Wrap App with ThemeProvider
|
||||
|
||||
Update `src/App.jsx` to include the ThemeProvider:
|
||||
|
||||
```js
|
||||
import Router from "./router";
|
||||
import { ThemeProvider } from "@/contexts/ThemeContext";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThemeProvider defaultTheme="system" storageKey="theme">
|
||||
<Router />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
### 6e. Add Theme Toggle to Navbar
|
||||
|
||||
Integrate the ThemeToggle component into the navigation bar:
|
||||
|
||||
1. **Locate the navbar component**: Find the main navigation component (commonly in `src/components/Navbar.jsx` or similar)
|
||||
2. **Import the ThemeToggle component**:
|
||||
```js
|
||||
import ThemeToggle from "@/components/ThemeToggle";
|
||||
```
|
||||
3. **Add the toggle to the navbar**: Place the `<ThemeToggle />` component in an appropriate location within the navbar, typically in the right section alongside other navigation items:
|
||||
```jsx
|
||||
<nav className="flex items-center justify-between p-4">
|
||||
<div>{/* Logo and left-side nav items */}</div>
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Other right-side nav items */}
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</nav>
|
||||
```
|
||||
|
||||
|
||||
## Step 7: Run Build to Check for Compilation Errors
|
||||
|
||||
Build the project to verify there are no compilation errors:
|
||||
|
||||
```bash
|
||||
npm --prefix ./frontend run build
|
||||
```
|
||||
|
||||
If the build succeeds, the setup is complete. If there are errors:
|
||||
- Check for missing imports or incorrect file paths
|
||||
- Verify all components were installed correctly
|
||||
- Ensure `jsconfig.json` path aliases match `vite.config.js` aliases
|
||||
- Confirm `tailwind.config.js` content paths include all component files
|
||||
|
||||
## Setup Complete
|
||||
|
||||
The Tailwind CSS and shadcn/ui setup is now complete. The project includes:
|
||||
- Tailwind CSS with Vite integration
|
||||
- shadcn/ui design tokens and theme variables
|
||||
- Dark mode support with class-based switching
|
||||
- Path aliases configured for clean imports (`@/components`, `@/lib`, etc.)
|
||||
- Core shadcn/ui components installed and ready to use
|
||||
|
||||
97
skills/tailwind-setup/assets/tailwind-theme.css
Normal file
97
skills/tailwind-setup/assets/tailwind-theme.css
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Base Theme Configuration */
|
||||
@layer base {
|
||||
:root {
|
||||
--background: oklch(1.0000 0 0);
|
||||
--foreground: oklch(0.2686 0 0);
|
||||
--card: oklch(1.0000 0 0);
|
||||
--card-foreground: oklch(0.2686 0 0);
|
||||
--popover: oklch(1.0000 0 0);
|
||||
--popover-foreground: oklch(0.2686 0 0);
|
||||
--primary: oklch(0.7686 0.1647 70.0804);
|
||||
--primary-foreground: oklch(0 0 0);
|
||||
--secondary: oklch(0.9670 0.0029 264.5419);
|
||||
--secondary-foreground: oklch(0.4461 0.0263 256.8018);
|
||||
--muted: oklch(0.9846 0.0017 247.8389);
|
||||
--muted-foreground: oklch(0.5510 0.0234 264.3637);
|
||||
--accent: oklch(0.9869 0.0214 95.2774);
|
||||
--accent-foreground: oklch(0.4732 0.1247 46.2007);
|
||||
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||
--destructive-foreground: oklch(1.0000 0 0);
|
||||
--border: oklch(0.9276 0.0058 264.5313);
|
||||
--input: oklch(0.9276 0.0058 264.5313);
|
||||
--ring: oklch(0.7686 0.1647 70.0804);
|
||||
--chart-1: oklch(0.7686 0.1647 70.0804);
|
||||
--chart-2: oklch(0.6658 0.1574 58.3183);
|
||||
--chart-3: oklch(0.5553 0.1455 48.9975);
|
||||
--chart-4: oklch(0.4732 0.1247 46.2007);
|
||||
--chart-5: oklch(0.4137 0.1054 45.9038);
|
||||
--radius: 0.375rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.2046 0 0);
|
||||
--foreground: oklch(0.9219 0 0);
|
||||
--card: oklch(0.2686 0 0);
|
||||
--card-foreground: oklch(0.9219 0 0);
|
||||
--popover: oklch(0.2686 0 0);
|
||||
--popover-foreground: oklch(0.9219 0 0);
|
||||
--primary: oklch(0.7686 0.1647 70.0804);
|
||||
--primary-foreground: oklch(0 0 0);
|
||||
--secondary: oklch(0.2686 0 0);
|
||||
--secondary-foreground: oklch(0.9219 0 0);
|
||||
--muted: oklch(0.2393 0 0);
|
||||
--muted-foreground: oklch(0.7155 0 0);
|
||||
--accent: oklch(0.4732 0.1247 46.2007);
|
||||
--accent-foreground: oklch(0.9243 0.1151 95.7459);
|
||||
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||
--destructive-foreground: oklch(1.0000 0 0);
|
||||
--border: oklch(0.3715 0 0);
|
||||
--input: oklch(0.3715 0 0);
|
||||
--ring: oklch(0.7686 0.1647 70.0804);
|
||||
--chart-1: oklch(0.8369 0.1644 84.4286);
|
||||
--chart-2: oklch(0.6658 0.1574 58.3183);
|
||||
--chart-3: oklch(0.4732 0.1247 46.2007);
|
||||
--chart-4: oklch(0.5553 0.1455 48.9975);
|
||||
--chart-5: oklch(0.4732 0.1247 46.2007);
|
||||
}
|
||||
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
}
|
||||
45
skills/tailwind-setup/scripts/apply-theme.sh
Executable file
45
skills/tailwind-setup/scripts/apply-theme.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to apply Tailwind theme to index.css
|
||||
# Usage: bash apply-theme.sh <frontend-directory>
|
||||
# Example: bash apply-theme.sh frontend
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
THEME_FILE="$SCRIPT_DIR/../assets/tailwind-theme.css"
|
||||
|
||||
# Check if frontend directory argument provided
|
||||
if [ -z "$1" ]; then
|
||||
echo "Error: Please provide the frontend directory path"
|
||||
echo "Usage: bash apply-theme.sh <frontend-directory>"
|
||||
echo "Example: bash apply-theme.sh frontend"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_DIR="$1"
|
||||
TARGET_FILE="$TARGET_DIR/src/index.css"
|
||||
|
||||
# Check if target file exists
|
||||
if [ ! -f "$TARGET_FILE" ]; then
|
||||
echo "Error: $TARGET_FILE not found."
|
||||
echo "Make sure '$TARGET_DIR' is the correct frontend directory path."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if theme file exists
|
||||
if [ ! -f "$THEME_FILE" ]; then
|
||||
echo "Error: Theme file not found at $THEME_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if theme already applied
|
||||
if grep -q "Base Theme Configuration" "$TARGET_FILE"; then
|
||||
echo "Theme already appears to be applied to $TARGET_FILE"
|
||||
echo "Skipping to avoid duplication."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Append theme to index.css
|
||||
echo "" >> "$TARGET_FILE"
|
||||
cat "$THEME_FILE" >> "$TARGET_FILE"
|
||||
|
||||
echo "✓ Tailwind theme successfully applied to $TARGET_FILE"
|
||||
Reference in New Issue
Block a user