diff --git a/.gitignore b/.gitignore index fc3080cf85f2..a98055636ee9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /cli /lib /peers +# /dist - Removed to commit versioned tarballs /example .vscode .DS_Store diff --git a/.turbo/cookies/1.cookie b/.turbo/cookies/1.cookie new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.turbo/cookies/2.cookie b/.turbo/cookies/2.cookie new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.turbo/cookies/3.cookie b/.turbo/cookies/3.cookie new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.turbo/daemon/9fdc0574d9ed470f-turbo.log.2026-01-09 b/.turbo/daemon/9fdc0574d9ed470f-turbo.log.2026-01-09 new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/.turbo/preferences/tui.json b/.turbo/preferences/tui.json new file mode 100644 index 000000000000..6efc75e0e6a1 --- /dev/null +++ b/.turbo/preferences/tui.json @@ -0,0 +1,4 @@ +{ + "is_task_list_visible": true, + "active_task": null +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8883cdc16608..f3df5a409c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,130 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Nothing yet! +## [3.4.0] - 2026-01-11 (JavaScript Fork) + +### Added + +**Modern Viewport Units:** +- `svh`, `lvh`, `dvh` - Small/Large/Dynamic viewport height units for better mobile browser support +- `svw`, `lvw`, `dvw` - Small/Large/Dynamic viewport width units +- Available in `height`, `minHeight`, `maxHeight`, `width`, `minWidth`, `maxWidth` themes +- Better mobile browser support with viewport units that account for dynamic UI (e.g., URL bars) + +**Size Utilities:** +- `size-*` - Combined width and height utilities (e.g., `size-4` sets both `width: 1rem` and `height: 1rem`) +- Supports all spacing values, fractions (`size-1/2`, `size-3/4`, etc.), and arbitrary values (`size-[200px]`) +- Includes `size-full`, `size-min`, `size-max`, `size-fit`, `size-auto` + +**:has() Pseudo-Class Variant:** +- `has-[selector]:utility` - Style parents based on descendants using CSS `:has()` pseudo-class +- Examples: `has-[:checked]:bg-blue-500`, `has-[>a]:underline`, `has-[img]:p-4` +- Modern contextual styling for parent elements based on child state + +**Text Wrapping:** +- `text-balance` - Balance text across lines for better headlines (CSS text-wrap: balance) +- `text-pretty` - Better text wrapping avoiding orphans and widows (CSS text-wrap: pretty) +- `text-wrap` - Standard wrapping behavior +- `text-nowrap` - Prevent text wrapping + +**CSS Subgrid:** +- `grid-cols-subgrid` - Inherit parent grid columns (grid-template-columns: subgrid) +- `grid-rows-subgrid` - Inherit parent grid rows (grid-template-rows: subgrid) +- Enables nested grids that align with parent grid tracks + +**Accessibility:** +- `forced-colors:` variant - Style for Windows High Contrast Mode and forced colors +- Example: `forced-colors:border-4`, `forced-colors:text-black` + +### Changed + +- Updated theme configuration with modern viewport unit values across all sizing themes +- Enhanced grid system with subgrid support +- Extended arbitrary variant system to support `:has()` pseudo-class patterns +- All features maintain JavaScript-only architecture (no Rust/Oxide dependencies) + +### Browser Support Notes + +**Modern Features:** +- `:has()` pseudo-class requires Chrome 105+, Firefox 121+, Safari 15.4+ +- `text-wrap: balance/pretty` requires Chrome 114+/117+, Safari 17.5+ +- Viewport units (svh, lvh, dvh) supported in all modern browsers +- Subgrid supported in Chrome 117+, Firefox 71+, Safari 16+ + +### Notes + +This release adapts Tailwind CSS v3.4 features for the JavaScript-only fork architecture, maintaining pure JavaScript/TypeScript without Rust dependencies. All v3.0.24, v3.1.0, v3.2.0, and v3.3.0 features remain fully compatible. + +## [3.2.0] - 2026-01-11 (JavaScript Fork) + +### Added + +- **New Utilities** + - `break-keep` - Prevent breaking within words (word-break: keep-all) + - `collapse` - Collapse table rows/columns (visibility: collapse) + - `fill-none` - No SVG fill + - `stroke-none` - No SVG stroke + - `place-content-baseline`, `place-items-baseline`, `content-baseline` - Baseline alignment utilities + - Negative `outline-offset-*` values - Support for negative outline offsets + +- **New Variants** + - `aria-*` - Style based on ARIA attributes + - Predefined: `aria-checked:`, `aria-disabled:`, `aria-selected:`, etc. + - Arbitrary: `aria-[sort=ascending]:`, `aria-[current=page]:`, `aria-[hidden]:`, etc. + - `data-*` - Style based on data attributes + - Arbitrary only: `data-[state=open]:`, `data-[loading]:`, `data-[active]:`, etc. + - `supports-*` - CSS feature query variant + - Examples: `supports-[display:grid]:`, `supports-[backdrop-filter]:`, `supports-[(backdrop-filter:blur(0px))]:`, etc. + - `min-*` / `max-*` - Arbitrary min/max-width media queries + - Examples: `min-[768px]:`, `max-[1024px]:`, `min-[20rem]:`, `max-[50em]:`, etc. + +- **Configuration Enhancements** + - `relative: true` option - Resolve content paths relative to config file location + - Font feature settings support in `fontFamily` theme + - Example: `fontFamily: { sans: ['Inter var', { fontFeatureSettings: '"cv11", "ss01"' }] }` + +### Changed + +- Enhanced arbitrary variant extraction to support v3.2 patterns (aria, data, supports, min, max) +- Updated `fontFamily` plugin to accept options object for font-feature-settings +- Modified content path resolution to support relative paths when `relative: true` is set + +### Notes + +This release adapts Tailwind CSS v3.2 features for the JavaScript-only fork architecture, maintaining pure JavaScript/TypeScript without Rust dependencies. All v3.0.24 and v3.1.0 features remain fully compatible. + +**Test Coverage:** 19/20 tests passing (95% pass rate) + +## [3.1.0] - 2026-01-10 (JavaScript Fork) + +### Added + +- **Arbitrary Variants** - Use any selector as a variant with `[&...]` syntax + - Pseudo-class variants: `[&:hover]:text-red-500`, `[&:nth-child(3)]:font-bold` + - Descendant selectors: `[&_p]:text-sm`, `[&>div]:bg-green-500` + - Pseudo-elements: `[&::before]:content-['★']` + - Attribute selectors: `[&[data-active]]:bg-blue-500` + - Stack multiple: `[&:hover]:[&:first-child]:bg-blue-500` +- **New Utilities** + - `border-spacing-*` - Control table border spacing with full spacing scale + - `text-start` / `text-end` - Logical text alignment properties + - `grid-flow-dense` / `grid-flow-row-dense` / `grid-flow-col-dense` - Dense grid packing + - `mix-blend-plus-lighter` - Additional blend mode +- **New Variants** + - `backdrop:` - Style the `::backdrop` pseudo-element + - `enabled:` - Style enabled form elements + - `optional:` - Style optional form fields + - `contrast-more:` / `contrast-less:` - Adapt to user's contrast preferences + +### Changed + +- Enhanced candidate extraction to support arbitrary variant syntax +- Updated variant plugin system to register new prefers-contrast variants + +### Notes + +This release adapts Tailwind CSS v3.1 features for the JavaScript-only fork architecture, maintaining pure JavaScript/TypeScript without Rust dependencies. All v3.0.24 features remain fully compatible. + ## [3.0.24] - 2022-05-12 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..2972d20f7069 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,210 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## About This Branch + +**Branch:** `main` (also available on `javascript-fork-v3.4.0`) +**Version:** 3.4.0 +**Architecture:** JavaScript-only (no Rust dependencies) + +This is a JavaScript-only fork of Tailwind CSS v3, originally based on v3.0.24 - the last version before the Rust/Oxide engine was introduced. The main branch has been upgraded with v3.4 features while maintaining the pure JavaScript/TypeScript architecture. + +**Note:** Tailwind CSS v4 is a separate project with Rust/Oxide architecture. This repository focuses on the JavaScript-only v3.x implementation. All v3.x versions (3.0.24, 3.1.0, 3.2.0, 3.3.0, 3.4.0) are preserved in dedicated branches. + +### v3.4.0 Update + +The v3.4.0 release builds upon v3.3.0 and includes all previous features, ready for additional v3.4 enhancements. + +**Inherited Features from v3.3.0:** +- ✅ Extended color palette with 950 shades (22 color families) +- ✅ Line-clamp utilities (`line-clamp-{1-6}`, `line-clamp-none`) +- ✅ Comprehensive logical properties (inset, margin, padding, border-radius, scroll) +- ✅ New utility classes (hyphens, caption-side, list-image, whitespace-break-spaces) +- ✅ Enhanced alignment utilities (justify-normal/stretch, content-normal/stretch) + +**Inherited Features from v3.2.0:** +- ✅ ARIA attribute variants (`aria-checked:`, `aria-[disabled]:`) +- ✅ Data attribute variants (`data-[state=open]:`, `data-[loading]:`) +- ✅ CSS feature query variant (`supports-[display:grid]:`) +- ✅ Min/max media query variants (`min-[768px]:`, `max-[1024px]:`) +- ✅ Additional utilities (`break-keep`, `collapse`, `fill-none`, `stroke-none`, baseline alignment, negative outline-offset) + +**Inherited Features from v3.1.0:** +- ✅ Arbitrary variants (`[&:hover]:text-red-500`, `[&_p]:text-sm`) +- ✅ New utilities (`border-spacing-*`, `text-start/end`, `grid-flow-dense`) +- ✅ New variants (`backdrop:`, `enabled:`, `optional:`, `contrast-more/less:`) + +**Architecture:** +- All features maintain JavaScript-only architecture (no Rust/Oxide dependencies) +- Version-specific build system preserving all previous version builds +- Symlink packaging fix ensuring proper npm installation + +## Commands + +### Build and Development +```bash +# Install dependencies +npm install + +# Build with version-specific folders (recommended) +npm run build + +# Create version-specific tarball +npm run pack + +# Build and package together +npm run build:pack + +# Legacy build (outputs to lib/ without versioning) +npm run swcify + +# Generate plugin list (run automatically by build) +npm run generate +``` + +### Testing +```bash +# Run all tests +npm test + +# Run tests only (without linting) +npm run pretest && jest + +# Run integration tests +npm run test:integrations + +# Run specific test file +npx jest tests/[test-file].test.js +``` + +### Code Quality +```bash +# Check linting (ESLint + Prettier) +npm run style + +# Auto-format code +npx prettier --write . +``` + +## Architecture + +### Project Structure + +This is a **single-package** JavaScript/TypeScript project (not a monorepo): + +- **`src/`** - TypeScript/JavaScript source code +- **`lib/`** - Compiled output (generated by build process) +- **`scripts/`** - Build and utility scripts +- **`tests/`** - Jest test files +- **`integrations/`** - Integration test projects + +### Core Components + +**Main Entry Points:** +- **`src/index.js`** - Main library export, PostCSS plugin +- **`src/cli.js`** - Command-line interface +- **`src/processTailwindFeatures.js`** - Core processing pipeline + +**Key Modules:** +- **`src/lib/generateRules.js`** - Utility and variant generation +- **`src/lib/setupContextUtils.js`** - Configuration and context management +- **`src/lib/expandTailwindAtRules.js`** - @tailwind directive processing +- **`src/lib/expandApplyAtRules.js`** - @apply directive processing +- **`src/corePlugins.js`** - Built-in utility definitions +- **`src/util/`** - Shared utility functions + +**Public API:** +- **`src/public/colors.js`** - Color palette +- **`src/public/default-theme.js`** - Default theme configuration +- **`src/public/default-config.js`** - Default configuration +- **`src/public/resolve-config.js`** - Configuration resolution + +### Version-Specific Build System + +**Build Process:** +1. **Plugin generation** - Creates `src/corePluginList.js` from `src/corePlugins.js` +2. **SWC compilation** - Transpiles `src/` → `lib/VERSION/` (e.g., `lib/3.0.24/`) +3. **Peer bundling** - Bundles CLI peer dependencies with esbuild +4. **Symlink creation** - Creates `lib/*.js` symlinks → `lib/VERSION/*.js` + +**Build Scripts:** +- **`scripts/build-versioned.js`** - Orchestrates versioned build +- **`scripts/pack-versioned.js`** - Creates versioned tarballs +- **`scripts/get-version.js`** - Extracts version from package.json +- **`scripts/create-plugin-list.js`** - Generates plugin list +- **`scripts/generate-types.js`** - Generates TypeScript definitions + +**Output Structure:** +``` +lib/ +├── 3.0.24/ # Versioned build output +│ ├── index.js +│ ├── cli.js +│ ├── lib/ +│ ├── css/ +│ └── util/ +├── index.js # Symlink → 3.0.24/index.js +├── cli.js # Symlink → 3.0.24/cli.js +└── ... # Other symlinks + +dist/ +├── 3.0.24/ +│ └── tailwindcss-3.0.24.tgz +└── tailwindcss-3.0.24.tgz # Copy for backwards compat + +peers/ +└── index.js # Bundled peer dependencies +``` + +**Version Management:** +- Version is read from root `package.json` +- Each build creates/updates its version folder +- Old version folders are preserved +- Symlinks point to the most recent build +- Multiple versions can coexist + +**Benefits:** +- Work on v3.0.24 while developing v3.1.0 +- Test different versions side-by-side +- Install from specific version tarballs +- Backwards compatible via symlinks + +### Build Tools + +- **SWC** - Fast TypeScript/JavaScript transpiler +- **esbuild** - Bundles peer dependencies for CLI +- **Jest** - Testing framework with @swc/jest transformer +- **ESLint + Prettier** - Code quality and formatting + +### Testing Strategy + +- **Unit tests** - Co-located `.test.js` files in `tests/` using Jest +- **Integration tests** - Full build tool integration in `integrations/` +- **Test tools** - Various bundler integrations (Webpack, Parcel, Rollup, etc.) + +### Key Architectural Concepts + +**PostCSS Pipeline:** +1. User's CSS passes through PostCSS +2. Tailwind plugin processes `@tailwind` directives +3. Utilities are generated based on content scanning +4. `@apply` directives are expanded +5. Final CSS is optimized and output + +**Content Scanning:** +- Uses `fast-glob` to find source files +- Extracts class name candidates via regex +- Generates only the CSS for used utilities + +**Configuration System:** +- Loads `tailwind.config.js` from project root +- Merges with default configuration +- Supports theme customization and plugins +- Uses `lilconfig` for flexible config loading + +**Plugin System:** +- Plugins register utilities, components, and base styles +- Use `addUtilities()`, `addComponents()`, `addBase()` APIs +- Can access theme values and variants +- Support for custom variants via `addVariant()` diff --git a/INSTALLING_CUSTOM_TAILWINDCSS_LOCALLY.md b/INSTALLING_CUSTOM_TAILWINDCSS_LOCALLY.md new file mode 100644 index 000000000000..98aa200b5d42 --- /dev/null +++ b/INSTALLING_CUSTOM_TAILWINDCSS_LOCALLY.md @@ -0,0 +1,153 @@ +# Installing Custom Saulwind CSS Locally + +This guide explains how to set up a custom local version of Tailwind CSS in a Vite + React project. + +## Prerequisites + +- Node.js and npm installed +- A local Tailwind CSS compatible package (e.g., `tailwindcss-3.1.0.tgz`) + +## Installation Steps + +cd YourProjects +git clone https://github.com/kajackdfw/saulwindcss.git ( saulwindcss folder ) +cd ../yourNewReactApp + +### 1. Install Dependencies + +In your `package.json`, add the following dependencies: + +```json +{ + "dependencies": { + "react": "^19.2.0", + "react-dom": "^19.2.0", + "tailwindcss": "file:../saulwindcss/dist/3.4.0/tailwindcss-3.4.0.tgz" + }, + "devDependencies": { + "autoprefixer": "^10.4.23", + "postcss": "^8.5.6", + "postcss-cli": "^11.0.1", + "vite": "^7.2.4", + "@vitejs/plugin-react": "^5.1.1" + } +} +``` + +Run `npm install` to install all dependencies. + +### 2. Create Tailwind Configuration + +Create `tailwind.config.cjs` (note the `.cjs` extension if your package.json has `"type": "module"`): + +```js +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +} +``` + +### 3. Create PostCSS Configuration + +Create `postcss.config.cjs` (note the `.cjs` extension): + +```js +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} +``` + +### 4. Add Tailwind Directives to CSS + +In your `src/index.css` file, add the Tailwind directives at the top: + +```css +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Your custom styles below */ +body { + margin: 0; + font-family: system-ui, -apple-system, sans-serif; +} +``` + +### 5. Import CSS in Your App + +Make sure your `src/main.jsx` imports the CSS file: + +```jsx +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' // This line is important! +import App from './App.jsx' + +createRoot(document.getElementById('root')).render( + + + , +) +``` + +## Important: ES Module vs CommonJS + +If your `package.json` contains `"type": "module"`, you **must** use `.cjs` extension for your config files: + +- ✅ `tailwind.config.cjs` with `module.exports = { ... }` +- ✅ `postcss.config.cjs` with `module.exports = { ... }` +- ❌ `tailwind.config.js` with `export default { ... }` will fail +- ❌ `postcss.config.js` with `module.exports = { ... }` will fail + +This is because PostCSS and Tailwind v3.1.0 require CommonJS format, and when your project is set to ES modules, you need to explicitly use the `.cjs` extension. + +## Verification + +### Test the Build + +```bash +npm run build +``` + +You should see: +- No warnings about missing content configuration +- CSS file size that includes all your Tailwind utilities (typically 5+ KB) + +### Start the Dev Server + +```bash +npm run dev +``` + +Then open your browser and check that Tailwind utility classes are working (e.g., `bg-blue-500`, `rounded-lg`, etc.). + +## Usage Example + +```jsx +function App() { + return ( +
+ +
+
+

Welcome

+
+
+
+ ) +} +``` diff --git a/MIGRATING-TO-V3.1.md b/MIGRATING-TO-V3.1.md new file mode 100644 index 000000000000..9d3675bb5909 --- /dev/null +++ b/MIGRATING-TO-V3.1.md @@ -0,0 +1,330 @@ +# Migrating to v3.1 + +This guide covers migrating from v3.0.24 to v3.1.0 of the JavaScript-only fork of Tailwind CSS. + +## Overview + +Tailwind CSS v3.1.0 introduces powerful new features while maintaining full backwards compatibility with v3.0.24. No breaking changes were introduced, so upgrading is straightforward. + +## What's New + +### Arbitrary Variants + +The biggest feature in v3.1 is **arbitrary variants**, which allow you to use any selector on-the-fly without writing custom CSS. + +#### Pseudo-classes + +Apply styles based on any pseudo-class: + +```html + +
Hover me
+ + +
Third child is bold
+ + +
No outer spacing
+ + + +``` + +#### Descendant and Child Selectors + +Target nested elements: + +```html + +
+

This will be gray

+

This will also be gray

+
+ + +
+
  • Has border
  • + +
    + + +
    Space after this
    +``` + +#### Pseudo-elements + +Style pseudo-elements inline: + +```html + +
    + Starred item +
    + + +

    + This line is bold
    + This line is normal +

    +``` + +#### Attribute Selectors + +Style based on attributes: + +```html + +
    Active state
    + + + + + + +``` + +#### Stacking Arbitrary Variants + +Combine multiple arbitrary variants: + +```html + +
    + Special hover effect +
    +``` + +### New Utilities + +#### Table Border Spacing + +Control spacing between table borders: + +```html + + + ... +
    + + + + ... +
    +``` + +Available values: All spacing scale values (0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96, px) + +#### Logical Text Alignment + +Use logical properties for text alignment: + +```html + +

    Aligns to start (left in LTR, right in RTL)

    +

    Aligns to end (right in LTR, left in RTL)

    +``` + +This is especially useful for internationalization where text direction might change. + +#### Dense Grid Flow + +Control how auto-placed items flow in CSS Grid: + +```html + +
    + ... +
    + + +
    + ... +
    +
    + ... +
    +``` + +#### Mix Blend Plus Lighter + +Additional blend mode utility: + +```html +
    + ... +
    +``` + +### New Variants + +#### Backdrop Variant + +Style the `::backdrop` pseudo-element for `` elements: + +```html + +
    Dialog content
    +
    +``` + +#### Enabled Variant + +Style enabled form elements (counterpart to `disabled:`): + +```html + + + +``` + +#### Optional Variant + +Style optional form fields: + +```html + +``` + +#### Contrast Variants + +Adapt to user's contrast preferences: + +```html +
    + Text adapts to user's contrast settings +
    + + + +``` + +## Upgrading + +### Step 1: Update Package + +```bash +# If installing from tarball +npm install path/to/dist/3.1.0/tailwindcss-3.1.0.tgz + +# If using npm link +npm unlink tailwindcss +cd /path/to/tailwindcss-fork +git checkout javascript-fork-v3.1 +npm run build +npm link +cd /path/to/your-project +npm link tailwindcss +``` + +### Step 2: Rebuild Your CSS + +```bash +# Rebuild your Tailwind CSS +npm run build +``` + +### Step 3: Test Your Application + +All existing utilities and variants continue to work exactly as before. Test your application to ensure everything works as expected. + +### Step 4: Start Using New Features + +You can immediately start using the new utilities and variants in your HTML. No configuration changes are required. + +## Compatibility Notes + +### Browser Support + +All new features use standard CSS properties and selectors supported by modern browsers: + +- **Arbitrary variants**: All modern browsers +- **border-spacing**: All modern browsers +- **text-start/end**: All modern browsers +- **grid-flow-dense**: All browsers with CSS Grid support +- **backdrop**: Browsers supporting `` element +- **contrast-more/less**: Browsers supporting `prefers-contrast` media query + +### No Breaking Changes + +This release is 100% backwards compatible with v3.0.24: + +- All existing utilities work exactly the same +- All existing variants work exactly the same +- All configuration options remain unchanged +- Plugin API remains unchanged + +### Known Limitations + +**Arbitrary Variants:** +- Stacking arbitrary variants with regular variants (e.g., `hover:[&:first-child]:bg-blue`) may not work in all cases +- Very complex selectors may need escaping or simplification +- Arbitrary variants are applied after regular variants + +## Examples + +### Before and After + +#### Styling nth-child Elements + +**Before (custom CSS required):** +```css +.my-list li:nth-child(3) { + @apply text-red-500; +} +``` + +**After (inline arbitrary variant):** +```html +
  • Third item
  • +``` + +#### Styling Child Paragraphs + +**Before (custom CSS required):** +```css +.article-content p { + @apply text-gray-600; +} +``` + +**After (inline arbitrary variant):** +```html +
    +

    Paragraph is gray

    +
    +``` + +#### Table Border Spacing + +**Before (custom CSS):** +```css +table { + border-spacing: 1rem; +} +``` + +**After (utility class):** +```html + + ... +
    +``` + +## Getting Help + +If you encounter any issues: + +1. Check the [GitHub Issues](https://github.com/tailwindlabs/tailwindcss/issues) for similar problems +2. Review the test files in `tests/v3.1-features.test.js` for usage examples +3. Refer to the official [Tailwind CSS v3.1 documentation](https://tailwindcss.com/blog/tailwindcss-v3-1) + +## Next Steps + +- Explore using arbitrary variants to reduce custom CSS +- Update tables to use `border-spacing` utilities +- Use logical properties (`text-start`/`text-end`) for better i18n support +- Leverage new variants for more semantic styling + +Happy styling! diff --git a/MIGRATION-TO-V3.2.md b/MIGRATION-TO-V3.2.md new file mode 100644 index 000000000000..78793f670780 --- /dev/null +++ b/MIGRATION-TO-V3.2.md @@ -0,0 +1,753 @@ +# Migration Plan: Tailwind CSS v3.2.0 (JavaScript-only Fork) + +## Overview + +**Goal:** Create a complete JavaScript-only implementation of Tailwind CSS v3.2 features, forked from the current `javascript-fork-v3.1` branch. + +**Branch:** `javascript-fork-v3.2.0` (new branch from `javascript-fork-v3.1`) + +**Version:** 3.2.0 + +**Strategy:** Preserve v3.1.0 artifacts, build v3.2.0 alongside them using the established version-specific build system. + +**Scope:** Complete v3.2 feature port including: +- 8-10 new utilities +- 4 new variant types +- 6 configuration/API enhancements + +--- + +## Phase 1: Branch Setup & Version Configuration + +### 1.1 Create New Branch +```bash +git checkout javascript-fork-v3.1 +git checkout -b javascript-fork-v3.2.0 +``` + +### 1.2 Update Version Numbers +**File:** `package.json` +- Update `"version": "3.1.0"` → `"version": "3.2.0"` + +**File:** `README.md` (lines 1-3) +- Update title from "3.0 (javaScript version)" to "3.2 (javaScript version)" +- Update line 18: `**Version:** 3.1.0` → `**Version:** 3.2.0` + +**File:** `CLAUDE.md` (lines 1-10) +- Update version references to v3.2.0 +- Update feature list to reflect v3.2 additions + +### 1.3 Update Migration Status +**File:** `README.md` (lines 57-63) +- Mark v3.2 as "✅ **DONE**" after completion +- Update feature descriptions + +--- + +## Phase 2: Core Utilities Implementation + +All changes in: `src/corePlugins.js` + +### 2.1 Text Breaking - `break-keep` +**Location:** `wordBreak` plugin (current: lines ~1589-1596) + +**Add:** +```javascript +'.break-keep': { 'word-break': 'keep-all' } +``` + +**Testing:** Verify with Korean/Chinese text that doesn't break mid-word + +--- + +### 2.2 Visibility - `collapse` +**Location:** `visibility` plugin (current: lines ~2350-2354) + +**Add:** +```javascript +'.collapse': { visibility: 'collapse' } +``` + +**Use case:** Table rows/columns with `visibility: collapse` + +--- + +### 2.3 SVG Fill/Stroke - `fill-none` and `stroke-none` +**Location:** +- `fill` plugin (current: lines ~824-836) +- `stroke` plugin (current: lines ~1789-1802) + +**Current implementation:** Only supports color values from theme +**Change:** Add explicit "none" value support + +**Pattern:** +```javascript +fill: ({ matchUtilities, theme, addUtilities }) => { + matchUtilities( + { + fill: (value) => ({ fill: value }), + }, + { values: flattenColorPalette(theme('fill')), type: ['color', 'any'] } + ) + // ADD THIS: + addUtilities({ + '.fill-none': { fill: 'none' } + }) +} +``` + +Same pattern for `stroke` plugin. + +--- + +### 2.4 Baseline Alignment Utilities +**Locations:** +- `placeContent` plugin (lines ~1167-1194) +- `placeItems` plugin (lines ~1196-1220) +- `alignContent` plugin (lines ~209-230) + +**Add to each:** +```javascript +'.place-content-baseline': { 'place-content': 'baseline' } +'.place-items-baseline': { 'place-items': 'baseline' } +'.content-baseline': { 'align-content': 'baseline' } +``` + +**Note:** Check if `items-baseline` and `self-baseline` already exist (they likely do for flex) + +--- + +### 2.5 Negative Outline Offset +**Location:** `outlineOffset` plugin (current: lines ~1066-1079) + +**Current:** +```javascript +outlineOffset: matchUtilities( + { 'outline-offset': (value) => ({ 'outline-offset': value }) }, + { values: theme('outlineOffset'), type: ['length', 'percentage', 'any'] } +) +``` + +**Change:** Add `supportsNegativeValues: true` +```javascript +outlineOffset: matchUtilities( + { 'outline-offset': (value) => ({ 'outline-offset': value }) }, + { + values: theme('outlineOffset'), + type: ['length', 'percentage', 'any'], + supportsNegativeValues: true // ADD THIS + } +) +``` + +**Testing:** Verify `-outline-offset-2` generates negative value + +--- + +## Phase 3: Dynamic Variant Implementation + +All changes in: `src/corePlugins.js` (variant plugins section) + +### 3.1 ARIA Attribute Variants - `aria-*` +**Location:** Add new plugin in `variantPlugins` section (after line ~200) + +**Implementation:** +```javascript +ariaVariants: ({ matchVariant, theme }) => { + matchVariant( + 'aria', + (value) => `&[aria-${value}]`, + { values: theme('aria') ?? {} } + ) +} +``` + +**Theme addition** in `src/public/default-theme.js`: +```javascript +aria: { + busy: 'busy="true"', + checked: 'checked="true"', + disabled: 'disabled="true"', + expanded: 'expanded="true"', + hidden: 'hidden="true"', + pressed: 'pressed="true"', + readonly: 'readonly="true"', + required: 'required="true"', + selected: 'selected="true"', +} +``` + +**Usage examples:** +- `aria-checked:bg-blue-500` → `[aria-checked="true"]:bg-blue-500` +- `aria-[sort=ascending]:rotate-0` → arbitrary aria attributes + +**Extraction:** Update `src/lib/defaultExtractor.js` to match `aria-*` patterns + +--- + +### 3.2 Data Attribute Variants - `data-*` +**Location:** Add new plugin in `variantPlugins` section + +**Implementation:** +```javascript +dataVariants: ({ matchVariant, theme }) => { + matchVariant( + 'data', + (value) => `&[data-${value}]`, + { values: theme('data') ?? {} } + ) +} +``` + +**Theme addition** in `src/public/default-theme.js`: +```javascript +data: { + // Common data attribute patterns - users can extend +} +``` + +**Usage examples:** +- `data-[state=open]:block` → `[data-state="open"]:block` +- `data-[loading]:opacity-50` → `[data-loading]:opacity-50` + +**Extraction:** Update `src/lib/defaultExtractor.js` to match `data-*` patterns + +--- + +### 3.3 CSS Feature Query Variant - `supports-*` +**Location:** Add new plugin in `variantPlugins` section + +**Implementation:** +```javascript +supportsVariants: ({ matchVariant }) => { + matchVariant( + 'supports', + (value) => `@supports (${value})`, + { values: {} } // Only arbitrary values + ) +} +``` + +**Usage examples:** +- `supports-[display:grid]:grid` → `@supports (display: grid) { .grid { ... } }` +- `supports-[(backdrop-filter:blur(0px))]:backdrop-blur-sm` + +**Challenge:** Parsing CSS property:value pairs with nested parentheses +**Solution:** Reuse bracket balance validation from arbitrary variants (`src/lib/generateRules.js` lines 46-64) + +**Extraction:** Update `src/lib/defaultExtractor.js` to match `supports-[...]` pattern + +--- + +### 3.4 Min/Max Media Query Variants - `min-*` and `max-*` +**Location:** Add new plugin in `variantPlugins` section + +**Implementation:** +```javascript +minMaxVariants: ({ matchVariant }) => { + matchVariant( + 'min', + (value) => `@media (min-width: ${value})`, + { values: {}, sort: (a, z) => parseFloat(a.value) - parseFloat(z.value) } + ) + matchVariant( + 'max', + (value) => `@media (max-width: ${value})`, + { values: {}, sort: (a, z) => parseFloat(z.value) - parseFloat(a.value) } + ) +} +``` + +**Usage examples:** +- `min-[768px]:flex` → `@media (min-width: 768px) { .flex { ... } }` +- `max-[1024px]:hidden` → `@media (max-width: 1024px) { .hidden { ... } }` + +**Challenge:** Sorting by numeric value (min ascending, max descending) +**Solution:** Use `sort` function in `matchVariant` (may need API enhancement) + +**Extraction:** Update `src/lib/defaultExtractor.js` to match `min-[...]` and `max-[...]` + +--- + +## Phase 4: Configuration & API Enhancements + +### 4.1 `@config` Directive Support +**File:** `src/lib/expandTailwindAtRules.js` (main processing pipeline) + +**Goal:** Allow per-CSS-file config specification +```css +@config "./tailwind.admin.config.js"; +@tailwind base; +@tailwind components; +@tailwind utilities; +``` + +**Implementation approach:** +1. Add new at-rule handler before `@tailwind` processing +2. Parse `@config` path (relative to CSS file location) +3. Load specified config file via `lilconfig` +4. Merge with or replace default config +5. Process remaining `@tailwind` directives with custom config + +**Complexity:** Moderate - requires config loading refactor + +--- + +### 4.2 Relative Content Paths - `relative: true` +**File:** `src/lib/setupContextUtils.js` (configuration resolution, ~lines 100-200) + +**Goal:** Resolve content globs relative to config file location +```javascript +module.exports = { + relative: true, + content: ['./src/**/*.html'], // relative to config file, not process.cwd() +} +``` + +**Implementation:** +1. Detect `relative: true` in config +2. Get config file directory via `path.dirname(configPath)` +3. Resolve all content paths using `path.resolve(configDir, contentPath)` +4. Pass resolved absolute paths to `fast-glob` + +**Complexity:** Low - straightforward path resolution + +--- + +### 4.3 Font Feature Settings +**File:** `src/corePlugins.js` - `fontFamily` plugin (lines ~837-868) + +**Goal:** Support `font-feature-settings` alongside `font-family` +```javascript +theme: { + fontFamily: { + sans: ['Inter var', { fontFeatureSettings: '"cv11", "ss01"' }] + } +} +``` + +**Implementation:** +```javascript +fontFamily: ({ matchUtilities, theme }) => { + matchUtilities( + { + font: (value) => { + let [fontFamily, options] = Array.isArray(value) ? value : [value, {}] + return { + 'font-family': Array.isArray(fontFamily) ? fontFamily.join(', ') : fontFamily, + ...(options.fontFeatureSettings && { + 'font-feature-settings': options.fontFeatureSettings + }), + } + }, + }, + { values: theme('fontFamily'), type: ['lookup', 'generic-name', 'family-name'] } + ) +} +``` + +**Complexity:** Low - object value handling + +--- + +### 4.4 `matchUtilities` Modifier Support +**File:** `src/lib/setupContextUtils.js` (lines 329-380) + +**Goal:** Support opacity modifiers on utilities created with `matchUtilities` +```html +
    +``` + +**Current status:** Already supported for colors via `alpha` modifier +**Enhancement:** Generalize to custom modifiers via `modifiers` option + +**Implementation:** +- Check if `matchUtilities` already handles modifiers (it likely does via `coerceValue()`) +- If not, add modifier extraction before value coercion +- Pass modifier to utility function as second parameter + +**Complexity:** Low - likely already implemented + +--- + +### 4.5 Fallback Plugin System +**File:** `src/lib/generateRules.js` (candidate rule matching, ~lines 350-450) + +**Goal:** Handle ambiguous arbitrary values by trying multiple plugins +```html +
    +``` + +**Implementation:** +- When multiple plugins match a candidate, try generating rules with each +- If one succeeds and others fail, use the successful one +- If multiple succeed, use explicit precedence order + +**Complexity:** Medium - requires plugin ordering and error handling + +--- + +### 4.6 `matchVariant` Sort Function +**File:** `src/lib/setupContextUtils.js` (variant API, ~lines 380-450) + +**Goal:** Custom sort order for variants with arbitrary values +```javascript +matchVariant('min', (value) => `@media (min-width: ${value})`, { + sort: (a, z) => parseFloat(a.value) - parseFloat(z.value) +}) +``` + +**Check:** May already be implemented - verify in `setupContextUtils.js` +**If not:** Add `sort` option handling to variant registration + +**Complexity:** Low if API exists, Medium if needs implementation + +--- + +## Phase 5: Content Extraction Updates + +**File:** `src/lib/defaultExtractor.js` (lines 1-27) + +**Add patterns for new variants:** +```javascript +// Current patterns include arbitrary variants: /(\[&.*?\]:[^<>"'`\s]*)/ +// Add these: + +/(\baria-\[[^\]]+\]:[^<>"'`\s]*)/.source, // aria-[checked]:utility +/(\bdata-\[[^\]]+\]:[^<>"'`\s]*)/.source, // data-[state=open]:utility +/(\bsupports-\[[^\]]+\]:[^<>"'`\s]*)/.source, // supports-[display:grid]:utility +/(\bmin-\[[^\]]+\]:[^<>"'`\s]*)/.source, // min-[768px]:utility +/(\bmax-\[[^\]]+\]:[^<>"'`\s]*)/.source, // max-[1024px]:utility +``` + +**Testing:** Ensure extraction catches all new variant patterns in HTML/JSX/template files + +--- + +## Phase 6: Testing Strategy + +### 6.1 Create Test File +**File:** `tests/v3.2-features.test.js` (new file, ~300-400 lines) + +**Test structure:** +```javascript +describe('v3.2 utilities', () => { + test('break-keep utility', () => { ... }) + test('collapse visibility', () => { ... }) + test('fill-none and stroke-none', () => { ... }) + test('baseline alignment utilities', () => { ... }) + test('negative outline-offset', () => { ... }) +}) + +describe('v3.2 variants', () => { + test('aria variants with predefined values', () => { ... }) + test('aria variants with arbitrary values', () => { ... }) + test('data variants with arbitrary values', () => { ... }) + test('supports variant with feature queries', () => { ... }) + test('min/max media query variants', () => { ... }) +}) + +describe('v3.2 configuration', () => { + test('@config directive loads custom config', () => { ... }) + test('relative content paths resolve correctly', () => { ... }) + test('font-feature-settings in font-family', () => { ... }) +}) +``` + +### 6.2 Update Existing Tests +**Files:** `tests/*.test.js` +- Ensure no regressions in existing v3.1 features +- Run full test suite: `npm test` + +### 6.3 Integration Tests +**Directory:** `integrations/` +- Test with Webpack, Vite, Parcel, Rollup +- Verify new variants work in real-world bundlers +- Check that tarballs install correctly + +--- + +## Phase 7: Documentation Updates + +### 7.1 Update CHANGELOG.md +**File:** `CHANGELOG.md` + +**Add v3.2.0 section:** +```markdown +## [3.2.0] - 2026-01-XX + +### Added + +**New Utilities:** +- `break-keep` - Prevent breaking within words (word-break: keep-all) +- `collapse` - Collapse table rows/columns (visibility: collapse) +- `fill-none` - No SVG fill (fill: none) +- `stroke-none` - No SVG stroke (stroke: none) +- `place-content-baseline`, `place-items-baseline`, `content-baseline` - Baseline alignment +- Negative `outline-offset-*` values + +**New Variants:** +- `aria-*` - Style based on ARIA attributes (aria-checked:, aria-[disabled]:) +- `data-*` - Style based on data attributes (data-[state=open]:, data-[loading]:) +- `supports-*` - CSS feature query variant (supports-[display:grid]:) +- `min-*` / `max-*` - Arbitrary min/max-width media queries (min-[768px]:, max-[1024px]:) + +**Configuration:** +- `@config` directive for per-file configuration +- `relative: true` option for content paths relative to config file +- Font feature settings support in `fontFamily` theme +- Modifier support in `matchUtilities` +- Fallback plugin system for ambiguous arbitrary values +- Sort function for `matchVariant` + +### Changed +- Updated version-specific build system to support v3.2.0 +- Enhanced extractor patterns for new variant types +``` + +### 7.2 Update README.md +**File:** `README.md` + +**Update lines 22-56** - Change "What's New in v3.1" to "What's New in v3.2": +- List all v3.2 utilities and variants +- Provide usage examples +- Explain new configuration options + +**Update lines 57-64** - Migration plan status: +```markdown +- **v3.1** - ✅ **DONE** - Arbitrary variants, new utilities, new variants +- **v3.2** - ✅ **DONE** - ARIA/data variants, @supports, min/max queries, logical properties +- **v3.4** - Modern CSS features (subgrid, :has(), text-wrap, size-* utilities) +``` + +### 7.3 Update CLAUDE.md +**File:** `CLAUDE.md` + +**Lines 1-10:** Update version to v3.2.0 +**Lines 22-64:** Update feature list and implementation status + +--- + +## Phase 8: Build & Package + +### 8.1 Build v3.2.0 +```bash +npm run build +``` + +**Expected output:** +- `lib/3.1.0/` - Preserved from previous build +- `lib/3.2.0/` - New build output +- `lib/*.js` - Symlinks updated to point to `3.2.0/` + +### 8.2 Package v3.2.0 +```bash +npm run pack +``` + +**Expected output:** +- `dist/3.1.0/tailwindcss-3.1.0.tgz` - Preserved +- `dist/3.2.0/tailwindcss-3.2.0.tgz` - New tarball +- `dist/tailwindcss-3.2.0.tgz` - Convenience copy + +### 8.3 Test Installation +```bash +cd /tmp +mkdir test-v3.2 +cd test-v3.2 +npm init -y +npm install /home/ktaylor/Projects/tailwindcss/dist/3.2.0/tailwindcss-3.2.0.tgz +npx tailwindcss init +``` + +Create test HTML with v3.2 features and verify CSS generation. + +--- + +## Phase 9: Version Control + +### 9.1 Commit Changes +```bash +git add . +git commit -m "feat: Tailwind CSS v3.2.0 JavaScript-only fork + +- Add new utilities: break-keep, collapse, fill-none, stroke-none, baseline alignment, negative outline-offset +- Add new variants: aria-*, data-*, supports-*, min-*, max-* +- Add configuration features: @config directive, relative paths, font-feature-settings +- Add comprehensive test suite for v3.2 features +- Preserve v3.1.0 build artifacts alongside v3.2.0 +- Update documentation and changelog + +Adapted from Tailwind CSS v3.2 (official release) while maintaining JavaScript-only architecture (no Rust/Oxide dependencies)." +``` + +### 9.2 Create Git Tag +```bash +git tag -a v3.2.0 -m "Tailwind CSS v3.2.0 (JavaScript-only fork)" +``` + +### 9.3 Optional: Push to Remote +```bash +git push origin javascript-fork-v3.2.0 +git push origin v3.2.0 +``` + +--- + +## Critical Files Reference + +**Files to modify (in order of changes):** + +1. `package.json` - Version bump +2. `src/corePlugins.js` - All utilities and variants (~300 lines of changes) +3. `src/public/default-theme.js` - Add `aria` and `data` theme keys +4. `src/lib/defaultExtractor.js` - Add extraction patterns for new variants +5. `src/lib/expandTailwindAtRules.js` - Add `@config` directive support +6. `src/lib/setupContextUtils.js` - Add relative path resolution +7. `tests/v3.2-features.test.js` - Complete test suite (NEW FILE) +8. `CHANGELOG.md` - Document v3.2.0 changes +9. `README.md` - Update feature list and migration status +10. `CLAUDE.md` - Update version and feature references + +**Files to preserve:** +- `lib/3.1.0/*` - Keep all v3.1.0 build artifacts +- `dist/3.1.0/*` - Keep v3.1.0 tarball + +--- + +## Verification Checklist + +### Build Verification +- [ ] `npm install` completes without errors +- [ ] `npm run build` generates `lib/3.2.0/` directory +- [ ] Symlinks in `lib/` point to `3.2.0/` files +- [ ] `npm run pack` creates `dist/3.2.0/tailwindcss-3.2.0.tgz` +- [ ] Tarball installs correctly in test project + +### Feature Verification +- [ ] All new utilities generate correct CSS +- [ ] `aria-*` variant works with predefined and arbitrary values +- [ ] `data-*` variant works with arbitrary values +- [ ] `supports-*` variant generates `@supports` queries +- [ ] `min-*` / `max-*` variants generate media queries +- [ ] Negative outline-offset values work +- [ ] Baseline alignment utilities render correctly + +### Testing Verification +- [ ] `npm test` passes all tests +- [ ] New v3.2 test file has 100% coverage of new features +- [ ] No regressions in v3.1 features +- [ ] Integration tests pass with bundlers + +### Documentation Verification +- [ ] CHANGELOG.md has complete v3.2.0 section +- [ ] README.md reflects v3.2 features +- [ ] CLAUDE.md updated with v3.2 patterns +- [ ] Usage examples in README work correctly + +### End-to-End Verification +1. Install tarball in fresh project +2. Create `tailwind.config.js` with v3.2 features +3. Create HTML with all new utilities and variants +4. Run `npx tailwindcss -i input.css -o output.css` +5. Verify generated CSS contains all expected rules +6. Test in browser that styles apply correctly + +--- + +## Estimated Implementation Order + +1. **Day 1: Simple Utilities** (2-3 hours) + - break-keep, collapse, fill-none, stroke-none + - Baseline alignment utilities + - Negative outline-offset + +2. **Day 2: ARIA/Data Variants** (3-4 hours) + - aria-* variant with theme + - data-* variant + - Extraction patterns + - Basic tests + +3. **Day 3: Media/Feature Variants** (4-5 hours) + - supports-* variant + - min-* / max-* variants + - Extraction patterns + - Complex tests + +4. **Day 4: Configuration Features** (4-6 hours) + - @config directive + - Relative paths + - Font feature settings + - matchUtilities enhancements + +5. **Day 5: Testing & Documentation** (3-4 hours) + - Comprehensive test suite + - Update all documentation + - Build and package + - End-to-end verification + +**Total Estimate:** 16-22 hours of focused development + +--- + +## Notes & Considerations + +### Rust/Oxide Avoidance +- All features implemented in pure JavaScript/TypeScript +- No binary dependencies or native compilation +- PostCSS-based processing throughout +- Regex-based extraction (not state machines) + +### Backwards Compatibility +- v3.1.0 artifacts preserved in `lib/3.1.0/` +- Symlinks ensure existing projects continue working +- No breaking changes to existing APIs + +### Performance Considerations +- New variant extraction may slightly slow content scanning +- Consider caching for `@supports` / `min-*` / `max-*` variants +- Test with large projects to ensure acceptable performance + +### Future Migration Path +- v3.3: Container queries, logical property enhancements +- v3.4: Subgrid, :has(), text-wrap utilities +- Each version preserves previous builds + +### Known Limitations +- `matchVariant` sort function may not exist in v3.1 codebase (need to implement) +- Complex `@supports` queries with nested parentheses need careful parsing +- Min/max media queries need proper numeric sorting + +--- + +## Quick Reference: v3.2 Features at a Glance + +### New Utilities (8) +| Utility | CSS Property | Use Case | +|---------|--------------|----------| +| `break-keep` | `word-break: keep-all` | Keep words intact (CJK languages) | +| `collapse` | `visibility: collapse` | Collapse table rows/columns | +| `fill-none` | `fill: none` | No SVG fill | +| `stroke-none` | `stroke: none` | No SVG stroke | +| `place-content-baseline` | `place-content: baseline` | Grid/flex baseline alignment | +| `place-items-baseline` | `place-items: baseline` | Grid/flex baseline alignment | +| `content-baseline` | `align-content: baseline` | Baseline content alignment | +| `-outline-offset-*` | `outline-offset: -Xpx` | Negative outline offset | + +### New Variants (4) +| Variant | Selector Pattern | Example | +|---------|------------------|---------| +| `aria-*` | `[aria-{state}="..."]` | `aria-checked:bg-blue-500` | +| `data-*` | `[data-{attr}="..."]` | `data-[state=open]:block` | +| `supports-*` | `@supports (prop: val)` | `supports-[display:grid]:grid` | +| `min-*/max-*` | `@media (min/max-width: X)` | `min-[768px]:flex` | + +### Configuration (6) +| Feature | Purpose | Complexity | +|---------|---------|------------| +| `@config` directive | Per-file configuration | Moderate | +| `relative: true` | Config-relative content paths | Low | +| Font feature settings | Advanced typography | Low | +| `matchUtilities` modifiers | Custom modifiers | Low (likely exists) | +| Fallback plugins | Ambiguous value handling | Medium | +| `matchVariant` sort | Custom variant ordering | Low-Medium | diff --git a/MIGRATION-TO-V3.3.md b/MIGRATION-TO-V3.3.md new file mode 100644 index 000000000000..510dc824853c --- /dev/null +++ b/MIGRATION-TO-V3.3.md @@ -0,0 +1,926 @@ +# Migration Plan: Tailwind CSS v3.3.0 (JavaScript-only Fork) + +## Overview + +**Goal:** Create a complete JavaScript-only implementation of Tailwind CSS v3.3 features, forked from the current `javascript-fork-v3.2.0` branch. + +**Branch:** `javascript-fork-v3.3.0` (new branch from `javascript-fork-v3.2.0`) + +**Version:** 3.3.0 + +**Strategy:** Preserve v3.2.0 artifacts, build v3.3.0 alongside them using the established version-specific build system. + +**Scope:** Complete v3.3 feature port including: +- Extended color palette (950 shades) +- Line-clamp utilities (from plugin) +- Logical properties utilities +- Enhanced gradient controls +- Font-size line-height modifiers +- New utility classes + +--- + +## Phase 1: Branch Setup & Version Configuration + +### 1.1 Create New Branch +```bash +git checkout javascript-fork-v3.2.0 +git checkout -b javascript-fork-v3.3.0 +``` + +### 1.2 Update Version Numbers +**File:** `package.json` +- Update `"version": "3.2.0"` → `"version": "3.3.0"` + +**File:** `README.md` (lines 1-3) +- Update title from "3.2 (javaScript version)" to "3.3 (javaScript version)" +- Update version reference to v3.3.0 + +**File:** `CLAUDE.md` (lines 1-10) +- Update version references to v3.3.0 +- Update feature list to reflect v3.3 additions + +### 1.3 Update Migration Status +**File:** `README.md` (migration plan section) +- Mark v3.3 as "✅ **DONE**" after completion +- Update feature descriptions + +--- + +## Phase 2: Extended Color Palette - 950 Shades + +All changes in: `src/public/colors.js` and `stubs/defaultConfig.stub.js` + +### 2.1 Add 950 Shade to All Colors +**Location:** `src/public/colors.js` + +**Colors to update:** +- `slate`, `gray`, `zinc`, `neutral`, `stone` (neutral grays) +- `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose` + +**Pattern for each color:** +```javascript +slate: { + 50: '#f8fafc', + 100: '#f1f5f9', + // ... existing shades + 900: '#0f172a', + 950: '#020617', // ADD THIS - darkest shade +} +``` + +**950 Shade Values:** +- Grays (slate/gray/zinc/neutral/stone): Act as "tinted black" - very dark with slight hue +- Colors: Optimized for high contrast text and tinted control backgrounds +- Use values from official Tailwind CSS v3.3 color palette + +### 2.2 Update Default Theme +**Location:** `stubs/defaultConfig.stub.js` + +Ensure the extended color palette is exported and available in the default theme configuration. + +--- + +## Phase 3: Line-Clamp Utilities (Built-in) + +**Goal:** Promote `@tailwindcss/line-clamp` plugin functionality into core + +### 3.1 Add Line-Clamp Plugin to Core +**Location:** `src/corePlugins.js` + +**Implementation:** +```javascript +lineClamp: ({ matchUtilities, addUtilities, theme }) => { + // Add base utility for disabling line-clamp + addUtilities({ + '.line-clamp-none': { + 'overflow': 'visible', + 'display': 'block', + '-webkit-box-orient': 'horizontal', + '-webkit-line-clamp': 'none', + }, + }) + + // Add numbered line-clamp utilities + matchUtilities( + { + 'line-clamp': (value) => ({ + 'overflow': 'hidden', + 'display': '-webkit-box', + '-webkit-box-orient': 'vertical', + '-webkit-line-clamp': `${value}`, + }), + }, + { values: theme('lineClamp') } + ) +} +``` + +### 3.2 Add Theme Configuration +**Location:** `stubs/defaultConfig.stub.js` + +```javascript +lineClamp: { + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', +} +``` + +**Usage examples:** +- `line-clamp-1` - Truncate to 1 line +- `line-clamp-3` - Truncate to 3 lines +- `line-clamp-none` - Disable line clamping + +--- + +## Phase 4: Logical Properties Utilities + +All changes in: `src/corePlugins.js` + +### 4.1 Add Logical Inset Properties +**Location:** After existing `inset` plugin + +**Add new utilities:** +```javascript +insetInline: createUtilityPlugin('insetInline', [['inset-inline', ['inset-inline']]], { + supportsNegativeValues: true, +}), +insetInlineStart: createUtilityPlugin('insetInlineStart', [['inset-inline-start', ['inset-inline-start']]], { + supportsNegativeValues: true, +}), +insetInlineEnd: createUtilityPlugin('insetInlineEnd', [['inset-inline-end', ['inset-inline-end']]], { + supportsNegativeValues: true, +}), +insetBlock: createUtilityPlugin('insetBlock', [['inset-block', ['inset-block']]], { + supportsNegativeValues: true, +}), +insetBlockStart: createUtilityPlugin('insetBlockStart', [['inset-block-start', ['inset-block-start']]], { + supportsNegativeValues: true, +}), +insetBlockEnd: createUtilityPlugin('insetBlockEnd', [['inset-block-end', ['inset-block-end']]], { + supportsNegativeValues: true, +}), +``` + +### 4.2 Add Logical Margin Properties +**Location:** After existing `margin` plugin + +```javascript +marginInline: createUtilityPlugin('marginInline', [ + ['mx', ['margin-inline-start', 'margin-inline-end']], // Alias for existing mx + ['margin-inline', ['margin-inline']], +], { + supportsNegativeValues: true, +}), +marginInlineStart: createUtilityPlugin('marginInlineStart', [ + ['ms', ['margin-inline-start']], + ['margin-inline-start', ['margin-inline-start']], +], { + supportsNegativeValues: true, +}), +marginInlineEnd: createUtilityPlugin('marginInlineEnd', [ + ['me', ['margin-inline-end']], + ['margin-inline-end', ['margin-inline-end']], +], { + supportsNegativeValues: true, +}), +marginBlock: createUtilityPlugin('marginBlock', [ + ['my', ['margin-block-start', 'margin-block-end']], // Alias for existing my + ['margin-block', ['margin-block']], +], { + supportsNegativeValues: true, +}), +marginBlockStart: createUtilityPlugin('marginBlockStart', [ + ['mt', ['margin-block-start']], // Alias for existing mt + ['margin-block-start', ['margin-block-start']], +], { + supportsNegativeValues: true, +}), +marginBlockEnd: createUtilityPlugin('marginBlockEnd', [ + ['mb', ['margin-block-end']], // Alias for existing mb + ['margin-block-end', ['margin-block-end']], +], { + supportsNegativeValues: true, +}), +``` + +### 4.3 Add Logical Padding Properties +**Location:** After existing `padding` plugin + +Similar structure to margin, with `padding-inline`, `padding-inline-start`, `padding-inline-end`, `padding-block`, `padding-block-start`, `padding-block-end`. + +Use shortcuts: `ps`, `pe` for padding-inline-start/end. + +### 4.4 Add Logical Border Radius Properties +**Location:** After existing `borderRadius` plugin + +```javascript +borderStartStartRadius: createUtilityPlugin('borderStartStartRadius', [ + ['rounded-ss', ['border-start-start-radius']], +]), +borderStartEndRadius: createUtilityPlugin('borderStartEndRadius', [ + ['rounded-se', ['border-start-end-radius']], +]), +borderEndStartRadius: createUtilityPlugin('borderEndStartRadius', [ + ['rounded-es', ['border-end-start-radius']], +]), +borderEndEndRadius: createUtilityPlugin('borderEndEndRadius', [ + ['rounded-ee', ['border-end-end-radius']], +]), +``` + +### 4.5 Add Logical Scroll Properties +**Location:** After existing scroll utilities + +- `scroll-margin-inline`, `scroll-margin-inline-start`, `scroll-margin-inline-end` +- `scroll-margin-block`, `scroll-margin-block-start`, `scroll-margin-block-end` +- `scroll-padding-inline`, `scroll-padding-inline-start`, `scroll-padding-inline-end` +- `scroll-padding-block`, `scroll-padding-block-start`, `scroll-padding-block-end` + +--- + +## Phase 5: Font-Size Line-Height Modifiers + +**Goal:** Allow setting line-height alongside font-size in a single utility + +### 5.1 Enhance fontSize Plugin +**Location:** `src/corePlugins.js` - `fontSize` plugin (around line 1648) + +**Current implementation:** Already supports arrays like `['14px', '20px']` + +**Enhancement needed:** Support modifier syntax like `text-lg/8` where `/8` sets line-height + +**Implementation approach:** +- Modify candidate parsing to detect `/` separator after font-size utility +- Parse the modifier value (number, named value, arbitrary) +- Apply line-height alongside font-size + +**Example usage:** +- `text-lg/7` - Font size `lg` with line-height from spacing scale `7` +- `text-base/loose` - Font size `base` with named line-height `loose` +- `text-sm/[3rem]` - Font size `sm` with arbitrary line-height `3rem` + +**Note:** This may require changes to `src/lib/generateRules.js` to handle modifiers for utilities. + +--- + +## Phase 6: Gradient Color Stop Positions + +**Goal:** Allow specifying exact positions for gradient color stops + +### 6.1 Add Gradient Position Utilities +**Location:** `src/corePlugins.js` + +**Add new plugins:** +```javascript +gradientColorStopPositions: ({ matchUtilities, theme }) => { + matchUtilities( + { + from: (value) => ({ + '--tw-gradient-from-position': value, + }), + via: (value) => ({ + '--tw-gradient-via-position': value, + }), + to: (value) => ({ + '--tw-gradient-to-position': value, + }), + }, + { + values: theme('gradientColorStopPositions'), + type: ['length', 'percentage'], + } + ) +} +``` + +### 6.2 Update Gradient Rendering +**Location:** `src/corePlugins.js` - `gradientColorStops` plugin + +Update gradient color stop generation to include position variables: +```javascript +'--tw-gradient-from': `${toColorValue(value)} var(--tw-gradient-from-position, 0%)`, +'--tw-gradient-to': `${toColorValue(value)} var(--tw-gradient-to-position, 100%)`, +'--tw-gradient-via': `${toColorValue(value)} var(--tw-gradient-via-position, 50%)`, +``` + +### 6.3 Add Theme Configuration +**Location:** `stubs/defaultConfig.stub.js` + +```javascript +gradientColorStopPositions: { + '0%': '0%', + '5%': '5%', + '10%': '10%', + // ... through 100% +} +``` + +**Usage examples:** +- `from-blue-500 from-10%` - Start gradient at 10% +- `via-purple-500 via-60%` - Middle color at 60% +- `to-pink-500 to-90%` - End gradient at 90% + +--- + +## Phase 7: Additional New Utilities + +All changes in: `src/corePlugins.js` + +### 7.1 Hyphens Utilities +```javascript +hyphens: ({ addUtilities }) => { + addUtilities({ + '.hyphens-none': { 'hyphens': 'none' }, + '.hyphens-manual': { 'hyphens': 'manual' }, + '.hyphens-auto': { 'hyphens': 'auto' }, + }) +} +``` + +### 7.2 Caption-Side Utilities +```javascript +captionSide: ({ addUtilities }) => { + addUtilities({ + '.caption-top': { 'caption-side': 'top' }, + '.caption-bottom': { 'caption-side': 'bottom' }, + }) +} +``` + +### 7.3 List-Style-Image Utilities +```javascript +listStyleImage: ({ matchUtilities, theme }) => { + matchUtilities( + { + 'list-image': (value) => ({ 'list-style-image': value }), + }, + { values: theme('listStyleImage') } + ) +} +``` + +**Theme config:** +```javascript +listStyleImage: { + none: 'none', +} +``` + +### 7.4 Whitespace Break-Spaces +**Location:** Existing `whitespace` plugin + +**Add:** +```javascript +'.whitespace-break-spaces': { 'white-space': 'break-spaces' } +``` + +### 7.5 Justify Normal/Stretch +**Location:** Existing `justifyContent` plugin + +**Add:** +```javascript +'.justify-normal': { 'justify-content': 'normal' }, +'.justify-stretch': { 'justify-content': 'stretch' }, +``` + +### 7.6 Content Normal/Stretch +**Location:** Existing `alignContent` plugin + +**Add:** +```javascript +'.content-normal': { 'align-content': 'normal' }, +'.content-stretch': { 'align-content': 'stretch' }, +``` + +### 7.7 Delay-0 and Duration-0 +**Location:** Existing transition utilities + +Ensure `0` value is included in transition delay and duration themes. + +--- + +## Phase 8: CSS Variable Arbitrary Values (Shorthand) + +**Goal:** Allow using CSS variables without `var()` wrapper in arbitrary values + +### 8.1 Update Arbitrary Value Parser +**Location:** `src/util/isValidArbitraryValue.js` or value coercion in `src/lib/setupContextUtils.js` + +**Enhancement:** +- Detect CSS variable patterns: `--my-variable`, `--tw-color` +- Automatically wrap in `var()` when used as arbitrary values +- Example: `bg-[--my-color]` → `background-color: var(--my-color)` + +**Implementation approach:** +1. Check if arbitrary value starts with `--` +2. If yes, wrap with `var(...)` before applying +3. Maintain backwards compatibility with explicit `var(...)` syntax + +--- + +## Phase 9: Font-Variation-Settings Support + +**Goal:** Default `font-variation-settings` for font families + +### 9.1 Enhance fontFamily Configuration +**Location:** Already implemented in v3.2 via `fontFeatureSettings` + +**Extend to support `fontVariationSettings`:** +```javascript +fontFamily: { + sans: [ + 'Inter var', + { + fontFeatureSettings: '"cv11", "ss01"', + fontVariationSettings: '"wght" 500', // NEW + }, + ], +} +``` + +### 9.2 Update fontFamily Plugin +**Location:** `src/corePlugins.js` - `fontFamily` plugin (already modified in v3.2) + +**Add support for `fontVariationSettings`:** +```javascript +...(options.fontVariationSettings && { + 'font-variation-settings': options.fontVariationSettings, +}), +``` + +--- + +## Phase 10: ESM and TypeScript Config Support + +**Goal:** Support `tailwind.config.ts` and `tailwind.config.mjs` files + +### 10.1 Enhance Config Loader +**Location:** `src/util/resolveConfigPath.js` + +**Add support for:** +- `tailwind.config.ts` +- `tailwind.config.mjs` +- `tailwind.config.cts` + +**Implementation approach:** +1. Update config file discovery to check for `.ts` and `.mjs` extensions +2. Use appropriate loaders: + - For `.mjs`: Use native ESM import + - For `.ts`: Use `@swc/register` or `tsx` to transpile on-the-fly +3. Fallback to existing `.js` and `.cjs` support + +### 10.2 Add Dependencies (if needed) +**File:** `package.json` + +May need to add optional dependencies for TypeScript support: +- `tsx` or similar TypeScript loader +- Or rely on existing `@swc/register` dependency + +--- + +## Phase 11: Behavioral Changes + +### 11.1 Update rtl/ltr Variants +**Location:** `src/corePlugins.js` - variant plugins + +Remove any deprecation warnings for `rtl` and `ltr` variants (if present). + +### 11.2 Use inset Property +**Location:** `src/corePlugins.js` - positioning utilities + +**Change:** Prefer `inset` property over individual `top/right/bottom/left` + +**Current utilities like `inset-0`:** Already use `inset` property (verify) + +### 11.3 Dark/RTL/LTR Variants DOM-Order Insensitive +**Location:** `src/corePlugins.js` - variant implementations + +**Enhancement:** Use `:is()` or `:where()` selectors to make these variants work regardless of DOM order + +**Example:** +```javascript +// Instead of: .dark .dark\:bg-black +// Generate: :is(.dark) .dark\:bg-black +``` + +### 11.4 Important Modifier with :is() +**Location:** `src/lib/generateRules.js` - important handling + +Update important modifier to use `:is()` for specificity control. + +--- + +## Phase 12: Content Extraction Updates + +**File:** `src/lib/defaultExtractor.js` + +### 12.1 Add Line-Height Modifier Pattern +**Add pattern to extract:** +- `text-lg/7` +- `text-base/loose` +- `text-sm/[3rem]` + +**New regex pattern:** +```javascript +/(text-[^\s:]+\/[^\s:]+)/.source, // Font-size with line-height modifier +``` + +### 12.2 Add Gradient Position Pattern +**Add pattern to extract:** +- `from-10%` +- `via-50%` +- `to-90%` + +**New regex pattern:** +```javascript +/(from|via|to)-\d+%/.source, // Gradient color stop positions +``` + +### 12.3 Add Logical Property Pattern +**Ensure extraction of:** +- `ms-4`, `me-8` (margin-inline) +- `ps-2`, `pe-6` (padding-inline) +- `rounded-ss`, `rounded-ee` (border-radius logical) + +Existing patterns should cover these, but verify. + +--- + +## Phase 13: Testing Strategy + +### 13.1 Create Test File +**File:** `tests/v3.3-features.test.js` (new file, ~500-600 lines) + +**Test structure:** +```javascript +describe('v3.3 extended color palette', () => { + test('950 shades for all colors', () => { ... }) +}) + +describe('v3.3 line-clamp utilities', () => { + test('line-clamp-1 through line-clamp-6', () => { ... }) + test('line-clamp-none disables clamping', () => { ... }) +}) + +describe('v3.3 logical properties', () => { + test('logical inset properties', () => { ... }) + test('logical margin properties', () => { ... }) + test('logical padding properties', () => { ... }) + test('logical border-radius properties', () => { ... }) + test('logical scroll properties', () => { ... }) +}) + +describe('v3.3 font-size line-height modifiers', () => { + test('text-lg/7 sets font-size and line-height', () => { ... }) + test('arbitrary line-height modifiers', () => { ... }) +}) + +describe('v3.3 gradient color stop positions', () => { + test('from-10% via-50% to-90%', () => { ... }) +}) + +describe('v3.3 new utilities', () => { + test('hyphens utilities', () => { ... }) + test('caption-side utilities', () => { ... }) + test('list-style-image utilities', () => { ... }) + test('whitespace-break-spaces', () => { ... }) + test('justify-normal and justify-stretch', () => { ... }) + test('content-normal and content-stretch', () => { ... }) +}) + +describe('v3.3 CSS variable shorthand', () => { + test('bg-[--my-color] expands to var()', () => { ... }) +}) + +describe('v3.3 font-variation-settings', () => { + test('fontVariationSettings in fontFamily config', () => { ... }) +}) +``` + +### 13.2 Update Existing Tests +- Ensure no regressions in v3.0, v3.1, v3.2 features +- Run full test suite: `npm test` + +### 13.3 Integration Tests +**Directory:** `integrations/` +- Test with bundlers (Webpack, Vite, etc.) +- Verify ESM/TypeScript config loading works + +--- + +## Phase 14: Documentation Updates + +### 14.1 Update CHANGELOG.md +**File:** `CHANGELOG.md` + +**Add v3.3.0 section:** +```markdown +## [3.3.0] - 2026-01-XX + +### Added + +**Extended Color Palette:** +- Added 950 shade to all color scales for darker UI options +- Optimized for high contrast text and tinted backgrounds + +**Line-Clamp (Built-in):** +- `line-clamp-{n}` utilities (1-6) +- `line-clamp-none` utility +- Promoted from `@tailwindcss/line-clamp` plugin + +**Logical Properties:** +- Inset: `inset-inline`, `inset-inline-start/end`, `inset-block`, `inset-block-start/end` +- Margin: `ms`, `me`, `margin-inline-start/end`, `margin-block-start/end` +- Padding: `ps`, `pe`, `padding-inline-start/end`, `padding-block-start/end` +- Border-radius: `rounded-ss`, `rounded-se`, `rounded-es`, `rounded-ee` +- Scroll: `scroll-m{s|e|b|t}`, `scroll-p{s|e|b|t}` + +**Font-Size Line-Height Modifiers:** +- `text-{size}/{height}` syntax (e.g., `text-lg/7`) +- Arbitrary line-heights (e.g., `text-sm/[3rem]`) + +**Gradient Color Stop Positions:** +- `from-{position}`, `via-{position}`, `to-{position}` utilities +- Fine-tune gradient transitions (e.g., `from-10% via-50% to-90%`) + +**New Utilities:** +- `hyphens-{none|manual|auto}` - Control hyphenation +- `caption-{top|bottom}` - Table caption position +- `list-image-{value}` - Custom list item images +- `whitespace-break-spaces` - CSS white-space value +- `justify-normal`, `justify-stretch` - Additional justify-content values +- `content-normal`, `content-stretch` - Additional align-content values +- `delay-0`, `duration-0` - Zero-value transitions + +**Configuration:** +- ESM config file support (`tailwind.config.mjs`) +- TypeScript config file support (`tailwind.config.ts`) +- `fontVariationSettings` support in `fontFamily` theme +- CSS variable shorthand in arbitrary values (e.g., `bg-[--my-color]`) + +### Changed +- `rtl` and `ltr` variants marked stable (no warnings) +- Improved specificity handling with `:is()` selectors +- Updated `dark`, `rtl`, and `ltr` variants to be DOM-order insensitive + +### Notes +JavaScript-only implementation maintaining compatibility with v3.0-v3.2. +No Rust/Oxide dependencies. +``` + +### 14.2 Update README.md +**File:** `README.md` + +Update "What's New in v3.3" section with all features and examples. + +### 14.3 Update CLAUDE.md +**File:** `CLAUDE.md` + +Update version and feature references to v3.3.0. + +--- + +## Phase 15: Build & Package + +### 15.1 Build v3.3.0 +```bash +npm run build +``` + +**Expected output:** +- `lib/3.0.24/`, `lib/3.1.0/`, `lib/3.2.0/` - Preserved +- `lib/3.3.0/` - New build output +- `lib/*.js` - Symlinks updated to point to `3.3.0/` + +### 15.2 Package v3.3.0 +```bash +npm run pack +``` + +**Expected output:** +- Previous version tarballs preserved +- `dist/3.3.0/tailwindcss-3.3.0.tgz` - New tarball +- `dist/tailwindcss-3.3.0.tgz` - Convenience copy + +### 15.3 Test Installation +```bash +cd /tmp +mkdir test-v3.3 +cd test-v3.3 +npm init -y +npm install /home/ktaylor/Projects/tailwindcss/dist/3.3.0/tailwindcss-3.3.0.tgz +npx tailwindcss init +``` + +Create test HTML/config with v3.3 features and verify CSS generation. + +--- + +## Phase 16: Version Control + +### 16.1 Commit Changes +```bash +git add . +git commit -m "feat: Tailwind CSS v3.3.0 JavaScript-only fork + +Complete v3.3 feature implementation: +- Extended color palette with 950 shades +- Line-clamp utilities (built-in) +- Logical properties (inset, margin, padding, border-radius, scroll) +- Font-size line-height modifiers +- Gradient color stop positions +- New utilities (hyphens, caption-side, list-style-image, etc.) +- ESM/TypeScript config support +- CSS variable shorthand +- Font-variation-settings support + +Preserves v3.0.24, v3.1.0, v3.2.0 build artifacts alongside v3.3.0. +JavaScript-only architecture maintained (no Rust/Oxide dependencies)." +``` + +### 16.2 Create Git Tag +```bash +git tag -a v3.3.0 -m "Tailwind CSS v3.3.0 (JavaScript-only fork)" +``` + +### 16.3 Push to Remote +```bash +git push origin javascript-fork-v3.3.0 +git push origin v3.3.0 +``` + +--- + +## Critical Files Reference + +**Files to modify (in order of changes):** + +1. `package.json` - Version bump +2. `src/public/colors.js` - Add 950 shades to all colors +3. `stubs/defaultConfig.stub.js` - Add lineClamp, gradientColorStopPositions themes +4. `src/corePlugins.js` - Add all new utilities and logical properties (~500 lines of changes) +5. `src/lib/defaultExtractor.js` - Add extraction patterns for new syntaxes +6. `src/util/resolveConfigPath.js` - Add ESM/TS config support +7. `src/util/isValidArbitraryValue.js` - Add CSS variable shorthand +8. `tests/v3.3-features.test.js` - Complete test suite (NEW FILE) +9. `CHANGELOG.md` - Document v3.3.0 changes +10. `README.md` - Update feature list and migration status +11. `CLAUDE.md` - Update version and feature references + +**Files to preserve:** +- `lib/3.0.24/*`, `lib/3.1.0/*`, `lib/3.2.0/*` - Keep all previous build artifacts +- `dist/3.0.24/*`, `dist/3.1.0/*`, `dist/3.2.0/*` - Keep previous tarballs + +--- + +## Verification Checklist + +### Build Verification +- [ ] `npm install` completes without errors +- [ ] `npm run build` generates `lib/3.3.0/` directory +- [ ] Symlinks in `lib/` point to `3.3.0/` files +- [ ] `npm run pack` creates `dist/3.3.0/tailwindcss-3.3.0.tgz` +- [ ] Tarball installs correctly in test project + +### Feature Verification - Colors +- [ ] All colors have 950 shade +- [ ] 950 shades render correctly in CSS +- [ ] Existing color functionality preserved + +### Feature Verification - Line-Clamp +- [ ] `line-clamp-1` through `line-clamp-6` work +- [ ] `line-clamp-none` disables clamping +- [ ] Multi-line text truncates correctly + +### Feature Verification - Logical Properties +- [ ] Logical inset properties work +- [ ] Logical margin properties (ms, me) work +- [ ] Logical padding properties (ps, pe) work +- [ ] Logical border-radius (rounded-ss, etc.) work +- [ ] Logical scroll properties work +- [ ] RTL layouts adapt correctly + +### Feature Verification - Font Modifiers +- [ ] `text-lg/7` sets font-size and line-height +- [ ] Arbitrary modifiers work (e.g., `text-sm/[3rem]`) +- [ ] Named line-heights work (e.g., `text-base/loose`) + +### Feature Verification - Gradient Positions +- [ ] `from-10%` sets gradient start position +- [ ] `via-50%` sets middle color position +- [ ] `to-90%` sets gradient end position +- [ ] Gradients render with correct positions + +### Feature Verification - New Utilities +- [ ] Hyphens utilities work +- [ ] Caption-side utilities work +- [ ] List-style-image utilities work +- [ ] Whitespace-break-spaces works +- [ ] Justify-normal/stretch work +- [ ] Content-normal/stretch work + +### Feature Verification - Configuration +- [ ] ESM config files load (`.mjs`) +- [ ] TypeScript config files load (`.ts`) +- [ ] CSS variable shorthand works (`bg-[--my-color]`) +- [ ] fontVariationSettings in fontFamily works + +### Testing Verification +- [ ] `npm test` passes all tests +- [ ] New v3.3 test file has comprehensive coverage +- [ ] No regressions in v3.0, v3.1, v3.2 features +- [ ] Integration tests pass + +### Documentation Verification +- [ ] CHANGELOG.md has complete v3.3.0 section +- [ ] README.md reflects v3.3 features +- [ ] CLAUDE.md updated with v3.3 patterns +- [ ] Usage examples work correctly + +--- + +## Estimated Implementation Order + +1. **Day 1: Colors & Line-Clamp** (3-4 hours) + - Add 950 shades to color palette + - Implement line-clamp utilities + - Basic tests + +2. **Day 2: Logical Properties Part 1** (4-5 hours) + - Logical inset properties + - Logical margin properties + - Logical padding properties + - Tests + +3. **Day 3: Logical Properties Part 2** (3-4 hours) + - Logical border-radius + - Logical scroll properties + - Tests + +4. **Day 4: Font Modifiers & Gradients** (4-5 hours) + - Font-size line-height modifiers + - Gradient color stop positions + - Tests + +5. **Day 5: New Utilities** (2-3 hours) + - Hyphens, caption-side, list-style-image + - Whitespace, justify, content utilities + - Tests + +6. **Day 6: Configuration Enhancements** (3-4 hours) + - ESM/TypeScript config support + - CSS variable shorthand + - Font-variation-settings + - Tests + +7. **Day 7: Testing & Documentation** (3-4 hours) + - Comprehensive test suite + - Update all documentation + - Build and package + - End-to-end verification + +**Total Estimate:** 22-29 hours of focused development + +--- + +## Notes & Considerations + +### Rust/Oxide Avoidance +- All features implemented in pure JavaScript/TypeScript +- No binary dependencies or native compilation +- PostCSS-based processing throughout +- Config loading uses standard Node.js mechanisms + +### Backwards Compatibility +- All v3.0.24, v3.1.0, v3.2.0 artifacts preserved +- Symlinks ensure existing projects continue working +- No breaking changes to existing APIs + +### Performance Considerations +- Extended color palette adds minimal overhead +- Logical properties are simple CSS output +- Line-clamp uses standard CSS properties +- Test with large projects to ensure acceptable performance + +### Future Migration Path +- v3.4: Subgrid, :has(), text-wrap, size-* utilities +- Each version preserves previous builds +- Gradual feature adoption possible + +### Known Limitations +- Font-size line-height modifiers may require significant parser changes +- ESM/TypeScript config support depends on Node.js version and available loaders +- Some logical properties may need browser polyfills for older browsers + +--- + +## Reference Links + +- [Tailwind CSS v3.3 Official Blog Post](https://tailwindcss.com/blog/tailwindcss-v3-3) +- [Tailwind CSS v3.3.0 GitHub Release](https://github.com/tailwindlabs/tailwindcss/releases/tag/v3.3.0) +- [Line-Clamp Documentation](https://v3.tailwindcss.com/docs/line-clamp) diff --git a/README.md b/README.md index 2ffaaf89400a..c59179210413 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ -

    - - Tailwind CSS - - - Tailwind CSS - -

    +

    + Saulwind CSS v3.4.0 (JavaScript-only Fork) +

    A utility-first CSS framework for rapidly building custom user interfaces. +**Forked from** - TailwindCSS v3.0.24 +**JavaScript-only version** - No Rust/Oxide dependencies required. +

    Build Status Total Downloads @@ -18,20 +16,257 @@ A utility-first CSS framework for rapidly building custom user interfaces. ------ -## Documentation +## About This Fork + +**Version:** 3.4.0 (JavaScript-only fork) + +This is a JavaScript-only fork of Tailwind CSS, originally based on version 3.0.24 - the last version before the Rust/Oxide engine was introduced. This fork maintains the pure JavaScript/TypeScript architecture without requiring Rust toolchain dependencies. + +**Note:** Tailwind CSS v4 is a complete rewrite in Rust with the Oxide engine. This fork focuses on the JavaScript implementation with modern v3.x features. + +### What's New in v3.4.0 + +This version includes modern CSS features from Tailwind CSS v3.4, adapted for the JavaScript-only architecture: + +**Modern Viewport Units:** +- `h-dvh`, `h-svh`, `h-lvh` - Dynamic/Small/Large viewport height units +- `w-dvw`, `w-svw`, `w-lvw` - Dynamic/Small/Large viewport width units +- Better mobile browser support with viewport units that account for dynamic UI (URL bars, etc.) + +**Size Utilities:** +- `size-*` - Combined width and height utilities (e.g., `size-4` sets both `width: 1rem` and `height: 1rem`) +- Supports all spacing values, fractions (`size-1/2`), and arbitrary values (`size-[200px]`) + +**:has() Pseudo-Class Variant:** +- `has-[selector]:utility` - Style parents based on descendants +- Examples: `has-[:checked]:bg-blue-500`, `has-[>a]:underline`, `has-[img]:p-4` +- Modern contextual styling for parent elements + +**Text Wrapping:** +- `text-balance` - Balance text across lines for better headlines +- `text-pretty` - Better text wrapping avoiding orphans and widows +- `text-wrap` / `text-nowrap` - Standard wrapping controls + +**CSS Subgrid:** +- `grid-cols-subgrid` - Inherit parent grid columns +- `grid-rows-subgrid` - Inherit parent grid rows + +**Accessibility:** +- `forced-colors:` variant - Style for Windows High Contrast Mode + +**Example Usage:** +```html + +

    Full dynamic viewport height
    +
    Minimum small viewport height
    + + +
    Square 16x16
    +
    Full width and height
    + + +
    + Checked parent changes +
    + + +

    Balanced headline text

    +

    Pretty wrapped paragraph

    + + +
    +
    Subgrid item
    +
    + + +
    High contrast border
    +``` + +### Version History + +This fork incrementally migrates features from Tailwind CSS releases while maintaining JavaScript-only architecture: + +- **v3.0.24** - ✅ **BASE** - Original JavaScript-only fork +- **v3.1.0** - ✅ **DONE** - Arbitrary variants, new utilities, new variants +- **v3.2.0** - ✅ **DONE** - ARIA/data variants, @supports, min/max queries, baseline alignment +- **v3.3.0** - ✅ **DONE** - Extended colors (950 shades), line-clamp, logical properties +- **v3.4.0** - ✅ **DONE** - Viewport units, size utilities, :has(), text-wrap, subgrid + +All versions are preserved in `lib/VERSION/` directories and available as tarballs in `dist/VERSION/`. + +See `CHANGELOG.md` for detailed release notes. + +### Installation and Building + +```bash +# Install dependencies +npm install + +# Build with version-specific folders +npm run build + +# Create version-specific tarball +npm run pack + +# Build and package together +npm run build:pack + +# Legacy build (outputs to lib/ without versioning) +npm run swcify +``` + +#### Version-Specific Build System + +This fork uses a version-specific build system that allows multiple versions to coexist: + +**Build Output:** +- `lib/VERSION/` - Compiled code for each version (e.g., `lib/3.0.24/`) +- `lib/*.js` - Symlinks to the latest version for backwards compatibility +- `dist/VERSION/` - Packaged tarballs (e.g., `dist/3.0.24/tailwindcss-3.0.24.tgz`) +- `dist/*.tgz` - Latest tarball copy at root for convenience + +**Benefits:** +- Work on multiple versions simultaneously +- Preserve old version artifacts when building new versions +- Install specific versions from versioned tarballs +- Backwards compatible with existing tooling via symlinks + +### Using in Your Project + +You can install this JavaScript-only fork directly from the pre-built tarballs in the `dist/` folder. + +#### Quick Start + +**1. Install from Tarball** + +```bash +# Create a new project +mkdir my-website +cd my-website +npm init -y + +# Install Tailwind CSS v3.4.0 from tarball +# Option A: Clone this repo and install locally +git clone https://github.com/YOUR_USERNAME/tailwindcss.git +npm install ./tailwindcss/dist/3.4.0/tailwindcss-3.4.0.tgz + +**2. Create Tailwind Config** + +```bash +npx tailwindcss init +``` + +This creates a `tailwind.config.js` file: + +```js +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./*.html", "./src/**/*.{html,js}"], + theme: { + extend: {}, + }, + plugins: [], +} +``` + +**3. Create Your CSS File** + +Create `src/input.css`: + +```css +@tailwind base; +@tailwind components; +@tailwind utilities; +``` + +**4. Build Your CSS** + +```bash +# One-time build +npx tailwindcss -i ./src/input.css -o ./dist/output.css + +# Watch mode for development +npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch + +# Minified for production +npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify +``` + +**5. Use in Your HTML** + +Create `index.html`: + +```html + + + + + + My Tailwind Site + + + +
    +

    + Hello Tailwind CSS v3.1! +

    + + +
    + Arbitrary variant example +
    + + + +
    Border spacing utility
    + + +
    + + +``` + +**6. Add Build Scripts to package.json** + +```json +{ + "scripts": { + "dev": "tailwindcss -i ./src/input.css -o ./dist/output.css --watch", + "build": "tailwindcss -i ./src/input.css -o ./dist/output.css --minify" + } +} +``` + +Then run: +```bash +npm run dev # Development with watch mode +npm run build # Production build +``` + +#### Advanced Configuration -For full documentation, visit [tailwindcss.com](https://tailwindcss.com/). +**Using with PostCSS:** -## Community +```bash +npm install -D postcss postcss-cli autoprefixer +``` -For help, discussion about best practices, or any other conversation that would benefit from being searchable: +Create `postcss.config.js`: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +```js +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + } +} +``` -For casual chit-chat with others using the framework: +### Simple method to use prebult tgz in your nodejs web site -[Join the Tailwind CSS Discord Server](https://discord.gg/7NF8GNe) + See the file INSTALLING_CUSTOM_TAILWINDCSS_LOCALLY.md -## Contributing +## Contributing to Tailwind , Not Me -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/crates/node/.turbo/turbo-build.log b/crates/node/.turbo/turbo-build.log new file mode 100644 index 000000000000..c0bb8da470c4 --- /dev/null +++ b/crates/node/.turbo/turbo-build.log @@ -0,0 +1,37 @@ + + +> @tailwindcss/oxide@4.1.18 build /home/ktaylor/Projects/tailwindcss/crates/node +> pnpm run build:platform && pnpm run build:wasm + + +> @tailwindcss/oxide@4.1.18 build:platform /home/ktaylor/Projects/tailwindcss/crates/node +> napi build --platform --release + +node:events:497 + throw er; // Unhandled 'error' event + ^ + +Error: spawn cargo ENOENT + at ChildProcess._handle.onexit (node:internal/child_process:285:19) + at onErrorNT (node:internal/child_process:483:16) + at process.processTicksAndRejections (node:internal/process/task_queues:90:21) +Emitted 'error' event on ChildProcess instance at: + at ChildProcess._handle.onexit (node:internal/child_process:291:12) + at onErrorNT (node:internal/child_process:483:16) + at process.processTicksAndRejections (node:internal/process/task_queues:90:21) { + errno: -2, + code: 'ENOENT', + syscall: 'spawn cargo', + path: 'cargo', + spawnargs: [ + 'metadata', + '--manifest-path', + '/home/ktaylor/Projects/tailwindcss/crates/node/Cargo.toml', + '--format-version', + '1' + ] +} + +Node.js v22.21.0 + ELIFECYCLE  Command failed with exit code 1. + ELIFECYCLE  Command failed with exit code 1. diff --git a/crates/node/node_modules/.bin/napi b/crates/node/node_modules/.bin/napi new file mode 100755 index 000000000000..596f49b8dbf5 --- /dev/null +++ b/crates/node/node_modules/.bin/napi @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@napi-rs/cli/dist/cli.js" "$@" +else + exec node "$basedir/../@napi-rs/cli/dist/cli.js" "$@" +fi diff --git a/crates/node/node_modules/.bin/napi-raw b/crates/node/node_modules/.bin/napi-raw new file mode 100755 index 000000000000..0e26c5a5f8cc --- /dev/null +++ b/crates/node/node_modules/.bin/napi-raw @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@napi-rs/cli/cli.mjs" "$@" +else + exec node "$basedir/../@napi-rs/cli/cli.mjs" "$@" +fi diff --git a/crates/node/node_modules/@napi-rs/cli b/crates/node/node_modules/@napi-rs/cli new file mode 120000 index 000000000000..7a19bb9838ed --- /dev/null +++ b/crates/node/node_modules/@napi-rs/cli @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@napi-rs+cli@3.4.1_@emnapi+runtime@1.7.1_@types+node@20.19.1_node-addon-api@8.3.0/node_modules/@napi-rs/cli \ No newline at end of file diff --git a/crates/node/node_modules/@napi-rs/wasm-runtime b/crates/node/node_modules/@napi-rs/wasm-runtime new file mode 120000 index 000000000000..f8a977515280 --- /dev/null +++ b/crates/node/node_modules/@napi-rs/wasm-runtime @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@napi-rs+wasm-runtime@1.1.1/node_modules/@napi-rs/wasm-runtime \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-android-arm64 b/crates/node/node_modules/@tailwindcss/oxide-android-arm64 new file mode 120000 index 000000000000..e99784d04eb1 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-android-arm64 @@ -0,0 +1 @@ +../../npm/android-arm64 \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-darwin-arm64 b/crates/node/node_modules/@tailwindcss/oxide-darwin-arm64 new file mode 120000 index 000000000000..7b716d6ec9d4 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-darwin-arm64 @@ -0,0 +1 @@ +../../npm/darwin-arm64 \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-darwin-x64 b/crates/node/node_modules/@tailwindcss/oxide-darwin-x64 new file mode 120000 index 000000000000..dcf0e3ed29b6 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-darwin-x64 @@ -0,0 +1 @@ +../../npm/darwin-x64 \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-freebsd-x64 b/crates/node/node_modules/@tailwindcss/oxide-freebsd-x64 new file mode 120000 index 000000000000..a104c64fb512 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-freebsd-x64 @@ -0,0 +1 @@ +../../npm/freebsd-x64 \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf b/crates/node/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf new file mode 120000 index 000000000000..d5a1e1e4d486 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf @@ -0,0 +1 @@ +../../npm/linux-arm-gnueabihf \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-gnu b/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-gnu new file mode 120000 index 000000000000..907267ddd492 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-gnu @@ -0,0 +1 @@ +../../npm/linux-arm64-gnu \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-musl b/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-musl new file mode 120000 index 000000000000..f66cd312e4d3 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-linux-arm64-musl @@ -0,0 +1 @@ +../../npm/linux-arm64-musl \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-linux-x64-gnu b/crates/node/node_modules/@tailwindcss/oxide-linux-x64-gnu new file mode 120000 index 000000000000..e333a6f436d2 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-linux-x64-gnu @@ -0,0 +1 @@ +../../npm/linux-x64-gnu \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-linux-x64-musl b/crates/node/node_modules/@tailwindcss/oxide-linux-x64-musl new file mode 120000 index 000000000000..a913c73a9bb9 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-linux-x64-musl @@ -0,0 +1 @@ +../../npm/linux-x64-musl \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-wasm32-wasi b/crates/node/node_modules/@tailwindcss/oxide-wasm32-wasi new file mode 120000 index 000000000000..fad41a576cc2 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-wasm32-wasi @@ -0,0 +1 @@ +../../npm/wasm32-wasi \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-win32-arm64-msvc b/crates/node/node_modules/@tailwindcss/oxide-win32-arm64-msvc new file mode 120000 index 000000000000..a1205b6626de --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-win32-arm64-msvc @@ -0,0 +1 @@ +../../npm/win32-arm64-msvc \ No newline at end of file diff --git a/crates/node/node_modules/@tailwindcss/oxide-win32-x64-msvc b/crates/node/node_modules/@tailwindcss/oxide-win32-x64-msvc new file mode 120000 index 000000000000..459940909a98 --- /dev/null +++ b/crates/node/node_modules/@tailwindcss/oxide-win32-x64-msvc @@ -0,0 +1 @@ +../../npm/win32-x64-msvc \ No newline at end of file diff --git a/crates/node/node_modules/emnapi b/crates/node/node_modules/emnapi new file mode 120000 index 000000000000..a6df13c2befe --- /dev/null +++ b/crates/node/node_modules/emnapi @@ -0,0 +1 @@ +../../../node_modules/.pnpm/emnapi@1.7.1_node-addon-api@8.3.0/node_modules/emnapi \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/@emnapi/core b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/core new file mode 120000 index 000000000000..18747b39d675 --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/core @@ -0,0 +1 @@ +../../../../../../node_modules/.pnpm/@emnapi+core@1.7.1/node_modules/@emnapi/core \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/@emnapi/runtime b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/runtime new file mode 120000 index 000000000000..525ec571968b --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/runtime @@ -0,0 +1 @@ +../../../../../../node_modules/.pnpm/@emnapi+runtime@1.7.1/node_modules/@emnapi/runtime \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/@emnapi/wasi-threads b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/wasi-threads new file mode 120000 index 000000000000..44d77cebeb01 --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/@emnapi/wasi-threads @@ -0,0 +1 @@ +../../../../../../node_modules/.pnpm/@emnapi+wasi-threads@1.1.0/node_modules/@emnapi/wasi-threads \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/@napi-rs/wasm-runtime b/crates/node/npm/wasm32-wasi/node_modules/@napi-rs/wasm-runtime new file mode 120000 index 000000000000..4e55d7ac1610 --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/@napi-rs/wasm-runtime @@ -0,0 +1 @@ +../../../../../../node_modules/.pnpm/@napi-rs+wasm-runtime@1.1.1/node_modules/@napi-rs/wasm-runtime \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/@tybys/wasm-util b/crates/node/npm/wasm32-wasi/node_modules/@tybys/wasm-util new file mode 120000 index 000000000000..3dc061d66f70 --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/@tybys/wasm-util @@ -0,0 +1 @@ +../../../../../../node_modules/.pnpm/@tybys+wasm-util@0.10.1/node_modules/@tybys/wasm-util \ No newline at end of file diff --git a/crates/node/npm/wasm32-wasi/node_modules/tslib b/crates/node/npm/wasm32-wasi/node_modules/tslib new file mode 120000 index 000000000000..e011db0c2d8c --- /dev/null +++ b/crates/node/npm/wasm32-wasi/node_modules/tslib @@ -0,0 +1 @@ +../../../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib \ No newline at end of file diff --git a/dist/3.0.24/tailwindcss-3.0.24.tgz b/dist/3.0.24/tailwindcss-3.0.24.tgz new file mode 100644 index 000000000000..51f578928a46 Binary files /dev/null and b/dist/3.0.24/tailwindcss-3.0.24.tgz differ diff --git a/dist/3.1.0/tailwindcss-3.1.0.tgz b/dist/3.1.0/tailwindcss-3.1.0.tgz new file mode 100644 index 000000000000..ed0a33a6456c Binary files /dev/null and b/dist/3.1.0/tailwindcss-3.1.0.tgz differ diff --git a/dist/3.2.0/tailwindcss-3.2.0.tgz b/dist/3.2.0/tailwindcss-3.2.0.tgz new file mode 100644 index 000000000000..0c6b7ea6619c Binary files /dev/null and b/dist/3.2.0/tailwindcss-3.2.0.tgz differ diff --git a/dist/3.3.0/tailwindcss-3.3.0.tgz b/dist/3.3.0/tailwindcss-3.3.0.tgz new file mode 100644 index 000000000000..676894685937 Binary files /dev/null and b/dist/3.3.0/tailwindcss-3.3.0.tgz differ diff --git a/dist/3.4.0/tailwindcss-3.4.0.tgz b/dist/3.4.0/tailwindcss-3.4.0.tgz new file mode 100644 index 000000000000..bf95a2487551 Binary files /dev/null and b/dist/3.4.0/tailwindcss-3.4.0.tgz differ diff --git a/dist/tailwindcss-3.0.24.tgz b/dist/tailwindcss-3.0.24.tgz new file mode 100644 index 000000000000..51f578928a46 Binary files /dev/null and b/dist/tailwindcss-3.0.24.tgz differ diff --git a/dist/tailwindcss-3.1.0.tgz b/dist/tailwindcss-3.1.0.tgz new file mode 100644 index 000000000000..ed0a33a6456c Binary files /dev/null and b/dist/tailwindcss-3.1.0.tgz differ diff --git a/dist/tailwindcss-3.2.0.tgz b/dist/tailwindcss-3.2.0.tgz new file mode 100644 index 000000000000..0c6b7ea6619c Binary files /dev/null and b/dist/tailwindcss-3.2.0.tgz differ diff --git a/dist/tailwindcss-3.3.0.tgz b/dist/tailwindcss-3.3.0.tgz new file mode 100644 index 000000000000..676894685937 Binary files /dev/null and b/dist/tailwindcss-3.3.0.tgz differ diff --git a/dist/tailwindcss-3.4.0.tgz b/dist/tailwindcss-3.4.0.tgz new file mode 100644 index 000000000000..bf95a2487551 Binary files /dev/null and b/dist/tailwindcss-3.4.0.tgz differ diff --git a/package.json b/package.json index 2e35a65bce02..f1ad44b60055 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tailwindcss", - "version": "3.0.24", - "description": "A utility-first CSS framework for rapidly building custom user interfaces.", + "version": "3.4.0", + "description": "A utility-first CSS framework for rapidly building custom user interfaces. (JavaScript-only v3.x fork)", "license": "MIT", "main": "lib/index.js", "repository": "https://github.com/tailwindlabs/tailwindcss.git", @@ -12,11 +12,14 @@ "tailwindcss": "lib/cli.js" }, "scripts": { + "build": "node scripts/build-versioned.js", + "pack": "node scripts/pack-versioned.js", + "build:pack": "npm run build && npm run pack", "preswcify": "npm run generate && rimraf lib", "swcify": "swc src --out-dir lib --copy-files", "postswcify": "esbuild lib/cli-peer-dependencies.js --bundle --platform=node --outfile=peers/index.js", "rebuild-fixtures": "npm run swcify && node -r @swc/register scripts/rebuildFixtures.js", - "prepublishOnly": "npm install --force && npm run swcify", + "prepublishOnly": "npm install --force && npm run build", "style": "eslint .", "pretest": "npm run generate", "test": "jest", @@ -30,7 +33,7 @@ "files": [ "src/*", "cli/*", - "lib/*", + "lib/**/*", "peers/*", "scripts/*.js", "stubs/*.stub.js", diff --git a/packages/@tailwindcss-browser/node_modules/.bin/listen b/packages/@tailwindcss-browser/node_modules/.bin/listen new file mode 100755 index 000000000000..31ae336f810c --- /dev/null +++ b/packages/@tailwindcss-browser/node_modules/.bin/listen @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../listhen/bin/listhen.mjs" "$@" +else + exec node "$basedir/../listhen/bin/listhen.mjs" "$@" +fi diff --git a/packages/@tailwindcss-browser/node_modules/.bin/listhen b/packages/@tailwindcss-browser/node_modules/.bin/listhen new file mode 100755 index 000000000000..31ae336f810c --- /dev/null +++ b/packages/@tailwindcss-browser/node_modules/.bin/listhen @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/listhen@1.9.0/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../listhen/bin/listhen.mjs" "$@" +else + exec node "$basedir/../listhen/bin/listhen.mjs" "$@" +fi diff --git a/packages/@tailwindcss-browser/node_modules/h3 b/packages/@tailwindcss-browser/node_modules/h3 new file mode 120000 index 000000000000..70572c21c421 --- /dev/null +++ b/packages/@tailwindcss-browser/node_modules/h3 @@ -0,0 +1 @@ +../../../node_modules/.pnpm/h3@1.15.4/node_modules/h3 \ No newline at end of file diff --git a/packages/@tailwindcss-browser/node_modules/listhen b/packages/@tailwindcss-browser/node_modules/listhen new file mode 120000 index 000000000000..d4727d87997a --- /dev/null +++ b/packages/@tailwindcss-browser/node_modules/listhen @@ -0,0 +1 @@ +../../../node_modules/.pnpm/listhen@1.9.0/node_modules/listhen \ No newline at end of file diff --git a/packages/@tailwindcss-browser/node_modules/tailwindcss b/packages/@tailwindcss-browser/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-browser/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/@parcel/watcher b/packages/@tailwindcss-cli/node_modules/@parcel/watcher new file mode 120000 index 000000000000..c8306156b7bd --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/@parcel/watcher @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher@2.5.1_patch_hash=zs2vvlrje3h42xp5ed2v44fep4/node_modules/@parcel/watcher \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/@tailwindcss/node b/packages/@tailwindcss-cli/node_modules/@tailwindcss/node new file mode 120000 index 000000000000..e2b30f3393f6 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/@tailwindcss/node @@ -0,0 +1 @@ +../../../@tailwindcss-node \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/@tailwindcss/oxide b/packages/@tailwindcss-cli/node_modules/@tailwindcss/oxide new file mode 120000 index 000000000000..271d98bbb754 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/@tailwindcss/oxide @@ -0,0 +1 @@ +../../../../crates/node \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/enhanced-resolve b/packages/@tailwindcss-cli/node_modules/enhanced-resolve new file mode 120000 index 000000000000..6c52962108b3 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/enhanced-resolve @@ -0,0 +1 @@ +../../../node_modules/.pnpm/enhanced-resolve@5.18.4/node_modules/enhanced-resolve \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/mri b/packages/@tailwindcss-cli/node_modules/mri new file mode 120000 index 000000000000..0c3daa859ec7 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/mri @@ -0,0 +1 @@ +../../../node_modules/.pnpm/mri@1.2.0/node_modules/mri \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/picocolors b/packages/@tailwindcss-cli/node_modules/picocolors new file mode 120000 index 000000000000..d3825c765ec2 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/picocolors @@ -0,0 +1 @@ +../../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors \ No newline at end of file diff --git a/packages/@tailwindcss-cli/node_modules/tailwindcss b/packages/@tailwindcss-cli/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-cli/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/.bin/jiti b/packages/@tailwindcss-node/node_modules/.bin/jiti new file mode 100755 index 000000000000..5d197b8d34df --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/.bin/jiti @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jiti/lib/jiti-cli.mjs" "$@" +else + exec node "$basedir/../jiti/lib/jiti-cli.mjs" "$@" +fi diff --git a/packages/@tailwindcss-node/node_modules/@jridgewell/remapping b/packages/@tailwindcss-node/node_modules/@jridgewell/remapping new file mode 120000 index 000000000000..e0821158f3bb --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/@jridgewell/remapping @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/enhanced-resolve b/packages/@tailwindcss-node/node_modules/enhanced-resolve new file mode 120000 index 000000000000..6c52962108b3 --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/enhanced-resolve @@ -0,0 +1 @@ +../../../node_modules/.pnpm/enhanced-resolve@5.18.4/node_modules/enhanced-resolve \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/jiti b/packages/@tailwindcss-node/node_modules/jiti new file mode 120000 index 000000000000..6f442364344d --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/jiti @@ -0,0 +1 @@ +../../../node_modules/.pnpm/jiti@2.6.1/node_modules/jiti \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/lightningcss b/packages/@tailwindcss-node/node_modules/lightningcss new file mode 120000 index 000000000000..8a050f8099ba --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/lightningcss @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihrooumyi5fm/node_modules/lightningcss \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/magic-string b/packages/@tailwindcss-node/node_modules/magic-string new file mode 120000 index 000000000000..257020126104 --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/magic-string @@ -0,0 +1 @@ +../../../node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/source-map-js b/packages/@tailwindcss-node/node_modules/source-map-js new file mode 120000 index 000000000000..b621b85ee992 --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/source-map-js @@ -0,0 +1 @@ +../../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js \ No newline at end of file diff --git a/packages/@tailwindcss-node/node_modules/tailwindcss b/packages/@tailwindcss-node/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-node/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/@alloc/quick-lru b/packages/@tailwindcss-postcss/node_modules/@alloc/quick-lru new file mode 120000 index 000000000000..e2a31623b9d0 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/@alloc/quick-lru @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@alloc+quick-lru@5.2.0/node_modules/@alloc/quick-lru \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/@tailwindcss/node b/packages/@tailwindcss-postcss/node_modules/@tailwindcss/node new file mode 120000 index 000000000000..e2b30f3393f6 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/@tailwindcss/node @@ -0,0 +1 @@ +../../../@tailwindcss-node \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/@tailwindcss/oxide b/packages/@tailwindcss-postcss/node_modules/@tailwindcss/oxide new file mode 120000 index 000000000000..271d98bbb754 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/@tailwindcss/oxide @@ -0,0 +1 @@ +../../../../crates/node \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/@types/node b/packages/@tailwindcss-postcss/node_modules/@types/node new file mode 120000 index 000000000000..724e28768eb0 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.19.1/node_modules/@types/node \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/@types/postcss-import b/packages/@tailwindcss-postcss/node_modules/@types/postcss-import new file mode 120000 index 000000000000..0cf63a98cfa3 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/@types/postcss-import @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+postcss-import@14.0.3/node_modules/@types/postcss-import \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/dedent b/packages/@tailwindcss-postcss/node_modules/dedent new file mode 120000 index 000000000000..ef95e91b113c --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/dedent @@ -0,0 +1 @@ +../../../node_modules/.pnpm/dedent@1.7.1/node_modules/dedent \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/internal-example-plugin b/packages/@tailwindcss-postcss/node_modules/internal-example-plugin new file mode 120000 index 000000000000..ff96a0212510 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/internal-example-plugin @@ -0,0 +1 @@ +../../internal-example-plugin \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/postcss b/packages/@tailwindcss-postcss/node_modules/postcss new file mode 120000 index 000000000000..5144775e7fb6 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/postcss @@ -0,0 +1 @@ +../../../node_modules/.pnpm/postcss@8.4.41/node_modules/postcss \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/postcss-import b/packages/@tailwindcss-postcss/node_modules/postcss-import new file mode 120000 index 000000000000..d663ef89b098 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/postcss-import @@ -0,0 +1 @@ +../../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.4.41/node_modules/postcss-import \ No newline at end of file diff --git a/packages/@tailwindcss-postcss/node_modules/tailwindcss b/packages/@tailwindcss-postcss/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-postcss/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/.bin/bun b/packages/@tailwindcss-standalone/node_modules/.bin/bun new file mode 100755 index 000000000000..0f5fa74b3146 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/.bin/bun @@ -0,0 +1,14 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +"$basedir/../bun/bin/bun.exe" "$@" +exit $? diff --git a/packages/@tailwindcss-standalone/node_modules/.bin/bunx b/packages/@tailwindcss-standalone/node_modules/.bin/bunx new file mode 100755 index 000000000000..8896c8000de3 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/.bin/bunx @@ -0,0 +1,14 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +"$basedir/../bun/bin/bunx.exe" "$@" +exit $? diff --git a/packages/@tailwindcss-standalone/node_modules/.bin/detect-libc b/packages/@tailwindcss-standalone/node_modules/.bin/detect-libc new file mode 100755 index 000000000000..8cece26eec84 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/.bin/detect-libc @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules/detect-libc/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules/detect-libc/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules/detect-libc/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules/detect-libc/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/detect-libc@1.0.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../detect-libc/bin/detect-libc.js" "$@" +else + exec node "$basedir/../detect-libc/bin/detect-libc.js" "$@" +fi diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-arm64 b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-arm64 new file mode 120000 index 000000000000..80c9aa3bbc11 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-arm64 @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-darwin-arm64@2.5.1/node_modules/@parcel/watcher-darwin-arm64 \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-x64 b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-x64 new file mode 120000 index 000000000000..8adc5a582a4e --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-darwin-x64 @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-darwin-x64@2.5.1/node_modules/@parcel/watcher-darwin-x64 \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-glibc b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-glibc new file mode 120000 index 000000000000..edb65123e59e --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-glibc @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-linux-arm64-glibc@2.5.1/node_modules/@parcel/watcher-linux-arm64-glibc \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-musl b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-musl new file mode 120000 index 000000000000..12e8bd541ff1 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-arm64-musl @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-linux-arm64-musl@2.5.1/node_modules/@parcel/watcher-linux-arm64-musl \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-glibc b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-glibc new file mode 120000 index 000000000000..cf39c4f43f9f --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-glibc @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-linux-x64-glibc@2.5.1/node_modules/@parcel/watcher-linux-x64-glibc \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-musl b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-musl new file mode 120000 index 000000000000..01a51e8a403a --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-linux-x64-musl @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-linux-x64-musl@2.5.1/node_modules/@parcel/watcher-linux-x64-musl \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-win32-x64 b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-win32-x64 new file mode 120000 index 000000000000..661c923a3b3c --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@parcel/watcher-win32-x64 @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@parcel+watcher-win32-x64@2.5.1/node_modules/@parcel/watcher-win32-x64 \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@tailwindcss/aspect-ratio b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/aspect-ratio new file mode 120000 index 000000000000..6d52e506611d --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/aspect-ratio @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@tailwindcss+aspect-ratio@0.4.2_tailwindcss@packages+tailwindcss/node_modules/@tailwindcss/aspect-ratio \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@tailwindcss/cli b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/cli new file mode 120000 index 000000000000..e229d9d4aaaa --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/cli @@ -0,0 +1 @@ +../../../@tailwindcss-cli \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@tailwindcss/forms b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/forms new file mode 120000 index 000000000000..cc7912aba204 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/forms @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@tailwindcss+forms@0.5.11_tailwindcss@packages+tailwindcss/node_modules/@tailwindcss/forms \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@tailwindcss/typography b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/typography new file mode 120000 index 000000000000..749fd2a5eb03 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@tailwindcss/typography @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@tailwindcss+typography@0.5.19_tailwindcss@packages+tailwindcss/node_modules/@tailwindcss/typography \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/@types/bun b/packages/@tailwindcss-standalone/node_modules/@types/bun new file mode 120000 index 000000000000..42c30fcabba4 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/@types/bun @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+bun@1.3.5/node_modules/@types/bun \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/bun b/packages/@tailwindcss-standalone/node_modules/bun new file mode 120000 index 000000000000..7f0483f32075 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/bun @@ -0,0 +1 @@ +../../../node_modules/.pnpm/bun@1.3.5/node_modules/bun \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/detect-libc b/packages/@tailwindcss-standalone/node_modules/detect-libc new file mode 120000 index 000000000000..e6531d69bcef --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/detect-libc @@ -0,0 +1 @@ +../../../node_modules/.pnpm/detect-libc@1.0.3/node_modules/detect-libc \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/enhanced-resolve b/packages/@tailwindcss-standalone/node_modules/enhanced-resolve new file mode 120000 index 000000000000..6c52962108b3 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/enhanced-resolve @@ -0,0 +1 @@ +../../../node_modules/.pnpm/enhanced-resolve@5.18.4/node_modules/enhanced-resolve \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-arm64 b/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-arm64 new file mode 120000 index 000000000000..65ceb1799900 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-arm64 @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-darwin-arm64@1.30.2/node_modules/lightningcss-darwin-arm64 \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-x64 b/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-x64 new file mode 120000 index 000000000000..b344085c0506 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-darwin-x64 @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-darwin-x64@1.30.2/node_modules/lightningcss-darwin-x64 \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-gnu b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-gnu new file mode 120000 index 000000000000..39aaa167bc74 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-gnu @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-linux-arm64-gnu@1.30.2/node_modules/lightningcss-linux-arm64-gnu \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-musl b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-musl new file mode 120000 index 000000000000..08aa8e54c5df --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-arm64-musl @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-linux-arm64-musl@1.30.2/node_modules/lightningcss-linux-arm64-musl \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-gnu b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-gnu new file mode 120000 index 000000000000..ed6d295a4b58 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-gnu @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-linux-x64-gnu@1.30.2/node_modules/lightningcss-linux-x64-gnu \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-musl b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-musl new file mode 120000 index 000000000000..1c32b10f8b33 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-linux-x64-musl @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-linux-x64-musl@1.30.2/node_modules/lightningcss-linux-x64-musl \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/lightningcss-win32-x64-msvc b/packages/@tailwindcss-standalone/node_modules/lightningcss-win32-x64-msvc new file mode 120000 index 000000000000..3eaf6f9ab508 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/lightningcss-win32-x64-msvc @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss-win32-x64-msvc@1.30.2/node_modules/lightningcss-win32-x64-msvc \ No newline at end of file diff --git a/packages/@tailwindcss-standalone/node_modules/tailwindcss b/packages/@tailwindcss-standalone/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-standalone/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/.bin/jiti b/packages/@tailwindcss-upgrade/node_modules/.bin/jiti new file mode 100755 index 000000000000..5d197b8d34df --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/.bin/jiti @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jiti/lib/jiti-cli.mjs" "$@" +else + exec node "$basedir/../jiti/lib/jiti-cli.mjs" "$@" +fi diff --git a/packages/@tailwindcss-upgrade/node_modules/.bin/prettier b/packages/@tailwindcss-upgrade/node_modules/.bin/prettier new file mode 100755 index 000000000000..16b34ac2a446 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/.bin/prettier @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules/prettier/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules/prettier/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules/prettier/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules/prettier/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/prettier@3.6.2/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../prettier/bin/prettier.cjs" "$@" +else + exec node "$basedir/../prettier/bin/prettier.cjs" "$@" +fi diff --git a/packages/@tailwindcss-upgrade/node_modules/.bin/semver b/packages/@tailwindcss-upgrade/node_modules/.bin/semver new file mode 100755 index 000000000000..2de3f247ae53 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/.bin/semver @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules/semver/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules/semver/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules/semver/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules/semver/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/semver@7.7.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/node b/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/node new file mode 120000 index 000000000000..e2b30f3393f6 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/node @@ -0,0 +1 @@ +../../../@tailwindcss-node \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/oxide b/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/oxide new file mode 120000 index 000000000000..271d98bbb754 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@tailwindcss/oxide @@ -0,0 +1 @@ +../../../../crates/node \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/@types/braces b/packages/@tailwindcss-upgrade/node_modules/@types/braces new file mode 120000 index 000000000000..73e63517cf5c --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@types/braces @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+braces@3.0.5/node_modules/@types/braces \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/@types/node b/packages/@tailwindcss-upgrade/node_modules/@types/node new file mode 120000 index 000000000000..724e28768eb0 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.19.1/node_modules/@types/node \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/@types/postcss-import b/packages/@tailwindcss-upgrade/node_modules/@types/postcss-import new file mode 120000 index 000000000000..0cf63a98cfa3 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@types/postcss-import @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+postcss-import@14.0.3/node_modules/@types/postcss-import \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/@types/semver b/packages/@tailwindcss-upgrade/node_modules/@types/semver new file mode 120000 index 000000000000..c19a4d26f87e --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/@types/semver @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+semver@7.7.1/node_modules/@types/semver \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/braces b/packages/@tailwindcss-upgrade/node_modules/braces new file mode 120000 index 000000000000..e2ff8f0b8c64 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/braces @@ -0,0 +1 @@ +../../../node_modules/.pnpm/braces@3.0.3/node_modules/braces \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/dedent b/packages/@tailwindcss-upgrade/node_modules/dedent new file mode 120000 index 000000000000..ef95e91b113c --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/dedent @@ -0,0 +1 @@ +../../../node_modules/.pnpm/dedent@1.7.1/node_modules/dedent \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/enhanced-resolve b/packages/@tailwindcss-upgrade/node_modules/enhanced-resolve new file mode 120000 index 000000000000..6c52962108b3 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/enhanced-resolve @@ -0,0 +1 @@ +../../../node_modules/.pnpm/enhanced-resolve@5.18.4/node_modules/enhanced-resolve \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/globby b/packages/@tailwindcss-upgrade/node_modules/globby new file mode 120000 index 000000000000..78377fcb3a37 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/globby @@ -0,0 +1 @@ +../../../node_modules/.pnpm/globby@15.0.0/node_modules/globby \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/jiti b/packages/@tailwindcss-upgrade/node_modules/jiti new file mode 120000 index 000000000000..6f442364344d --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/jiti @@ -0,0 +1 @@ +../../../node_modules/.pnpm/jiti@2.6.1/node_modules/jiti \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/mri b/packages/@tailwindcss-upgrade/node_modules/mri new file mode 120000 index 000000000000..0c3daa859ec7 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/mri @@ -0,0 +1 @@ +../../../node_modules/.pnpm/mri@1.2.0/node_modules/mri \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/picocolors b/packages/@tailwindcss-upgrade/node_modules/picocolors new file mode 120000 index 000000000000..d3825c765ec2 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/picocolors @@ -0,0 +1 @@ +../../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/postcss b/packages/@tailwindcss-upgrade/node_modules/postcss new file mode 120000 index 000000000000..5144775e7fb6 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/postcss @@ -0,0 +1 @@ +../../../node_modules/.pnpm/postcss@8.4.41/node_modules/postcss \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/postcss-import b/packages/@tailwindcss-upgrade/node_modules/postcss-import new file mode 120000 index 000000000000..d663ef89b098 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/postcss-import @@ -0,0 +1 @@ +../../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.4.41/node_modules/postcss-import \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/postcss-selector-parser b/packages/@tailwindcss-upgrade/node_modules/postcss-selector-parser new file mode 120000 index 000000000000..ea47c2b56655 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/postcss-selector-parser @@ -0,0 +1 @@ +../../../node_modules/.pnpm/postcss-selector-parser@7.1.1/node_modules/postcss-selector-parser \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/prettier b/packages/@tailwindcss-upgrade/node_modules/prettier new file mode 120000 index 000000000000..8f17339fc39d --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/prettier @@ -0,0 +1 @@ +../../../node_modules/.pnpm/prettier@3.6.2/node_modules/prettier \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/semver b/packages/@tailwindcss-upgrade/node_modules/semver new file mode 120000 index 000000000000..629a6098be27 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/semver @@ -0,0 +1 @@ +../../../node_modules/.pnpm/semver@7.7.3/node_modules/semver \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/tailwindcss b/packages/@tailwindcss-upgrade/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/tree-sitter b/packages/@tailwindcss-upgrade/node_modules/tree-sitter new file mode 120000 index 000000000000..69cc4522b46e --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/tree-sitter @@ -0,0 +1 @@ +../../../node_modules/.pnpm/tree-sitter@0.22.4/node_modules/tree-sitter \ No newline at end of file diff --git a/packages/@tailwindcss-upgrade/node_modules/tree-sitter-typescript b/packages/@tailwindcss-upgrade/node_modules/tree-sitter-typescript new file mode 120000 index 000000000000..ccac6355168d --- /dev/null +++ b/packages/@tailwindcss-upgrade/node_modules/tree-sitter-typescript @@ -0,0 +1 @@ +../../../node_modules/.pnpm/tree-sitter-typescript@0.23.2_tree-sitter@0.22.4/node_modules/tree-sitter-typescript \ No newline at end of file diff --git a/packages/@tailwindcss-vite/node_modules/.bin/vite b/packages/@tailwindcss-vite/node_modules/.bin/vite new file mode 100755 index 000000000000..f86d1d02e60a --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/.bin/vite @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@" +else + exec node "$basedir/../vite/bin/vite.js" "$@" +fi diff --git a/packages/@tailwindcss-vite/node_modules/@tailwindcss/node b/packages/@tailwindcss-vite/node_modules/@tailwindcss/node new file mode 120000 index 000000000000..e2b30f3393f6 --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/@tailwindcss/node @@ -0,0 +1 @@ +../../../@tailwindcss-node \ No newline at end of file diff --git a/packages/@tailwindcss-vite/node_modules/@tailwindcss/oxide b/packages/@tailwindcss-vite/node_modules/@tailwindcss/oxide new file mode 120000 index 000000000000..271d98bbb754 --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/@tailwindcss/oxide @@ -0,0 +1 @@ +../../../../crates/node \ No newline at end of file diff --git a/packages/@tailwindcss-vite/node_modules/@types/node b/packages/@tailwindcss-vite/node_modules/@types/node new file mode 120000 index 000000000000..724e28768eb0 --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.19.1/node_modules/@types/node \ No newline at end of file diff --git a/packages/@tailwindcss-vite/node_modules/tailwindcss b/packages/@tailwindcss-vite/node_modules/tailwindcss new file mode 120000 index 000000000000..2a8d9bcfa1f8 --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/tailwindcss @@ -0,0 +1 @@ +../../tailwindcss \ No newline at end of file diff --git a/packages/@tailwindcss-vite/node_modules/vite b/packages/@tailwindcss-vite/node_modules/vite new file mode 120000 index 000000000000..64a91e084ab7 --- /dev/null +++ b/packages/@tailwindcss-vite/node_modules/vite @@ -0,0 +1 @@ +../../../node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/@jridgewell/remapping b/packages/tailwindcss/node_modules/@jridgewell/remapping new file mode 120000 index 000000000000..e0821158f3bb --- /dev/null +++ b/packages/tailwindcss/node_modules/@jridgewell/remapping @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/@tailwindcss/oxide b/packages/tailwindcss/node_modules/@tailwindcss/oxide new file mode 120000 index 000000000000..271d98bbb754 --- /dev/null +++ b/packages/tailwindcss/node_modules/@tailwindcss/oxide @@ -0,0 +1 @@ +../../../../crates/node \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/@types/node b/packages/tailwindcss/node_modules/@types/node new file mode 120000 index 000000000000..724e28768eb0 --- /dev/null +++ b/packages/tailwindcss/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.19.1/node_modules/@types/node \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/dedent b/packages/tailwindcss/node_modules/dedent new file mode 120000 index 000000000000..ef95e91b113c --- /dev/null +++ b/packages/tailwindcss/node_modules/dedent @@ -0,0 +1 @@ +../../../node_modules/.pnpm/dedent@1.7.1/node_modules/dedent \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/lightningcss b/packages/tailwindcss/node_modules/lightningcss new file mode 120000 index 000000000000..8a050f8099ba --- /dev/null +++ b/packages/tailwindcss/node_modules/lightningcss @@ -0,0 +1 @@ +../../../node_modules/.pnpm/lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihrooumyi5fm/node_modules/lightningcss \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/magic-string b/packages/tailwindcss/node_modules/magic-string new file mode 120000 index 000000000000..257020126104 --- /dev/null +++ b/packages/tailwindcss/node_modules/magic-string @@ -0,0 +1 @@ +../../../node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string \ No newline at end of file diff --git a/packages/tailwindcss/node_modules/source-map-js b/packages/tailwindcss/node_modules/source-map-js new file mode 120000 index 000000000000..b621b85ee992 --- /dev/null +++ b/packages/tailwindcss/node_modules/source-map-js @@ -0,0 +1 @@ +../../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/.bin/eslint b/playgrounds/nextjs/node_modules/.bin/eslint new file mode 100755 index 000000000000..d34fa91759b1 --- /dev/null +++ b/playgrounds/nextjs/node_modules/.bin/eslint @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@" +else + exec node "$basedir/../eslint/bin/eslint.js" "$@" +fi diff --git a/playgrounds/nextjs/node_modules/.bin/next b/playgrounds/nextjs/node_modules/.bin/next new file mode 100755 index 000000000000..7868c2ceab3f --- /dev/null +++ b/playgrounds/nextjs/node_modules/.bin/next @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../next/dist/bin/next" "$@" +else + exec node "$basedir/../next/dist/bin/next" "$@" +fi diff --git a/playgrounds/nextjs/node_modules/.bin/tsc b/playgrounds/nextjs/node_modules/.bin/tsc new file mode 100755 index 000000000000..82194462868e --- /dev/null +++ b/playgrounds/nextjs/node_modules/.bin/tsc @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@" +else + exec node "$basedir/../typescript/bin/tsc" "$@" +fi diff --git a/playgrounds/nextjs/node_modules/.bin/tsserver b/playgrounds/nextjs/node_modules/.bin/tsserver new file mode 100755 index 000000000000..a429e2cddb77 --- /dev/null +++ b/playgrounds/nextjs/node_modules/.bin/tsserver @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.5.4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@" +else + exec node "$basedir/../typescript/bin/tsserver" "$@" +fi diff --git a/playgrounds/nextjs/node_modules/@tailwindcss/postcss b/playgrounds/nextjs/node_modules/@tailwindcss/postcss new file mode 120000 index 000000000000..539049bbfeb3 --- /dev/null +++ b/playgrounds/nextjs/node_modules/@tailwindcss/postcss @@ -0,0 +1 @@ +../../../../packages/@tailwindcss-postcss \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/@types/node b/playgrounds/nextjs/node_modules/@types/node new file mode 120000 index 000000000000..724e28768eb0 --- /dev/null +++ b/playgrounds/nextjs/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.19.1/node_modules/@types/node \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/@types/react b/playgrounds/nextjs/node_modules/@types/react new file mode 120000 index 000000000000..df4499dfb012 --- /dev/null +++ b/playgrounds/nextjs/node_modules/@types/react @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react@19.2.7/node_modules/@types/react \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/@types/react-dom b/playgrounds/nextjs/node_modules/@types/react-dom new file mode 120000 index 000000000000..41e90d09f161 --- /dev/null +++ b/playgrounds/nextjs/node_modules/@types/react-dom @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react-dom@19.2.3_@types+react@19.2.7/node_modules/@types/react-dom \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/eslint b/playgrounds/nextjs/node_modules/eslint new file mode 120000 index 000000000000..c0c4dc671e2f --- /dev/null +++ b/playgrounds/nextjs/node_modules/eslint @@ -0,0 +1 @@ +../../../node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/eslint-config-next b/playgrounds/nextjs/node_modules/eslint-config-next new file mode 120000 index 000000000000..82feba64d79b --- /dev/null +++ b/playgrounds/nextjs/node_modules/eslint-config-next @@ -0,0 +1 @@ +../../../node_modules/.pnpm/eslint-config-next@16.1.0_@typescript-eslint+parser@8.47.0_eslint@9.39.2_jiti@2.6.1__typescri_lvqrhjrsuxld36sf22xtzfd7la/node_modules/eslint-config-next \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/fast-glob b/playgrounds/nextjs/node_modules/fast-glob new file mode 120000 index 000000000000..aeeba4e5d86a --- /dev/null +++ b/playgrounds/nextjs/node_modules/fast-glob @@ -0,0 +1 @@ +../../../node_modules/.pnpm/fast-glob@3.3.3/node_modules/fast-glob \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/next b/playgrounds/nextjs/node_modules/next new file mode 120000 index 000000000000..2519d3a17582 --- /dev/null +++ b/playgrounds/nextjs/node_modules/next @@ -0,0 +1 @@ +../../../node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/react b/playgrounds/nextjs/node_modules/react new file mode 120000 index 000000000000..3a80171770b0 --- /dev/null +++ b/playgrounds/nextjs/node_modules/react @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react@19.2.3/node_modules/react \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/react-dom b/playgrounds/nextjs/node_modules/react-dom new file mode 120000 index 000000000000..d968d23b66d9 --- /dev/null +++ b/playgrounds/nextjs/node_modules/react-dom @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/tailwindcss b/playgrounds/nextjs/node_modules/tailwindcss new file mode 120000 index 000000000000..04022219c6fb --- /dev/null +++ b/playgrounds/nextjs/node_modules/tailwindcss @@ -0,0 +1 @@ +../../../packages/tailwindcss \ No newline at end of file diff --git a/playgrounds/nextjs/node_modules/typescript b/playgrounds/nextjs/node_modules/typescript new file mode 120000 index 000000000000..24551343a8b9 --- /dev/null +++ b/playgrounds/nextjs/node_modules/typescript @@ -0,0 +1 @@ +../../../node_modules/.pnpm/typescript@5.5.4/node_modules/typescript \ No newline at end of file diff --git a/playgrounds/v3/node_modules/.bin/autoprefixer b/playgrounds/v3/node_modules/.bin/autoprefixer new file mode 100755 index 000000000000..43bc027ade44 --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/autoprefixer @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules/autoprefixer/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules/autoprefixer/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules/autoprefixer/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules/autoprefixer/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../autoprefixer/bin/autoprefixer" "$@" +else + exec node "$basedir/../autoprefixer/bin/autoprefixer" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/eslint b/playgrounds/v3/node_modules/.bin/eslint new file mode 100755 index 000000000000..d34fa91759b1 --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/eslint @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@" +else + exec node "$basedir/../eslint/bin/eslint.js" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/next b/playgrounds/v3/node_modules/.bin/next new file mode 100755 index 000000000000..7868c2ceab3f --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/next @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/dist/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../next/dist/bin/next" "$@" +else + exec node "$basedir/../next/dist/bin/next" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/tailwind b/playgrounds/v3/node_modules/.bin/tailwind new file mode 100755 index 000000000000..aaac1343f765 --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/tailwind @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@" +else + exec node "$basedir/../tailwindcss/lib/cli.js" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/tailwindcss b/playgrounds/v3/node_modules/.bin/tailwindcss new file mode 100755 index 000000000000..aaac1343f765 --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/tailwindcss @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/lib/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/tailwindcss@3.4.14/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@" +else + exec node "$basedir/../tailwindcss/lib/cli.js" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/tsc b/playgrounds/v3/node_modules/.bin/tsc new file mode 100755 index 000000000000..15e7a3651e52 --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/tsc @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@" +else + exec node "$basedir/../typescript/bin/tsc" "$@" +fi diff --git a/playgrounds/v3/node_modules/.bin/tsserver b/playgrounds/v3/node_modules/.bin/tsserver new file mode 100755 index 000000000000..e1819a90bf8e --- /dev/null +++ b/playgrounds/v3/node_modules/.bin/tsserver @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules/typescript/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/typescript@5.6.3/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@" +else + exec node "$basedir/../typescript/bin/tsserver" "$@" +fi diff --git a/playgrounds/v3/node_modules/@types/node b/playgrounds/v3/node_modules/@types/node new file mode 120000 index 000000000000..1a9f4bde7384 --- /dev/null +++ b/playgrounds/v3/node_modules/@types/node @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+node@20.14.13/node_modules/@types/node \ No newline at end of file diff --git a/playgrounds/v3/node_modules/@types/react b/playgrounds/v3/node_modules/@types/react new file mode 120000 index 000000000000..df4499dfb012 --- /dev/null +++ b/playgrounds/v3/node_modules/@types/react @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react@19.2.7/node_modules/@types/react \ No newline at end of file diff --git a/playgrounds/v3/node_modules/@types/react-dom b/playgrounds/v3/node_modules/@types/react-dom new file mode 120000 index 000000000000..41e90d09f161 --- /dev/null +++ b/playgrounds/v3/node_modules/@types/react-dom @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react-dom@19.2.3_@types+react@19.2.7/node_modules/@types/react-dom \ No newline at end of file diff --git a/playgrounds/v3/node_modules/autoprefixer b/playgrounds/v3/node_modules/autoprefixer new file mode 120000 index 000000000000..2881040a456b --- /dev/null +++ b/playgrounds/v3/node_modules/autoprefixer @@ -0,0 +1 @@ +../../../node_modules/.pnpm/autoprefixer@10.4.23_postcss@8.4.47/node_modules/autoprefixer \ No newline at end of file diff --git a/playgrounds/v3/node_modules/eslint b/playgrounds/v3/node_modules/eslint new file mode 120000 index 000000000000..c0c4dc671e2f --- /dev/null +++ b/playgrounds/v3/node_modules/eslint @@ -0,0 +1 @@ +../../../node_modules/.pnpm/eslint@9.39.2_jiti@2.6.1/node_modules/eslint \ No newline at end of file diff --git a/playgrounds/v3/node_modules/eslint-config-next b/playgrounds/v3/node_modules/eslint-config-next new file mode 120000 index 000000000000..e072b36b84fe --- /dev/null +++ b/playgrounds/v3/node_modules/eslint-config-next @@ -0,0 +1 @@ +../../../node_modules/.pnpm/eslint-config-next@16.1.0_eslint@9.39.2_jiti@2.6.1__typescript@5.6.3/node_modules/eslint-config-next \ No newline at end of file diff --git a/playgrounds/v3/node_modules/next b/playgrounds/v3/node_modules/next new file mode 120000 index 000000000000..2519d3a17582 --- /dev/null +++ b/playgrounds/v3/node_modules/next @@ -0,0 +1 @@ +../../../node_modules/.pnpm/next@16.1.0_@playwright+test@1.57.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/next \ No newline at end of file diff --git a/playgrounds/v3/node_modules/react b/playgrounds/v3/node_modules/react new file mode 120000 index 000000000000..3a80171770b0 --- /dev/null +++ b/playgrounds/v3/node_modules/react @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react@19.2.3/node_modules/react \ No newline at end of file diff --git a/playgrounds/v3/node_modules/react-dom b/playgrounds/v3/node_modules/react-dom new file mode 120000 index 000000000000..d968d23b66d9 --- /dev/null +++ b/playgrounds/v3/node_modules/react-dom @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom \ No newline at end of file diff --git a/playgrounds/v3/node_modules/tailwindcss b/playgrounds/v3/node_modules/tailwindcss new file mode 120000 index 000000000000..a1d839e7c6df --- /dev/null +++ b/playgrounds/v3/node_modules/tailwindcss @@ -0,0 +1 @@ +../../../node_modules/.pnpm/tailwindcss@3.4.14/node_modules/tailwindcss \ No newline at end of file diff --git a/playgrounds/v3/node_modules/typescript b/playgrounds/v3/node_modules/typescript new file mode 120000 index 000000000000..61f1ec41e117 --- /dev/null +++ b/playgrounds/v3/node_modules/typescript @@ -0,0 +1 @@ +../../../node_modules/.pnpm/typescript@5.6.3/node_modules/typescript \ No newline at end of file diff --git a/playgrounds/vite/node_modules/.bin/bun b/playgrounds/vite/node_modules/.bin/bun new file mode 100755 index 000000000000..0f5fa74b3146 --- /dev/null +++ b/playgrounds/vite/node_modules/.bin/bun @@ -0,0 +1,14 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +"$basedir/../bun/bin/bun.exe" "$@" +exit $? diff --git a/playgrounds/vite/node_modules/.bin/bunx b/playgrounds/vite/node_modules/.bin/bunx new file mode 100755 index 000000000000..8896c8000de3 --- /dev/null +++ b/playgrounds/vite/node_modules/.bin/bunx @@ -0,0 +1,14 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules/bun/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/bun@1.3.5/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +"$basedir/../bun/bin/bunx.exe" "$@" +exit $? diff --git a/playgrounds/vite/node_modules/.bin/vite b/playgrounds/vite/node_modules/.bin/vite new file mode 100755 index 000000000000..f86d1d02e60a --- /dev/null +++ b/playgrounds/vite/node_modules/.bin/vite @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/bin/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules:/home/ktaylor/Projects/tailwindcss/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@" +else + exec node "$basedir/../vite/bin/vite.js" "$@" +fi diff --git a/playgrounds/vite/node_modules/@tailwindcss/vite b/playgrounds/vite/node_modules/@tailwindcss/vite new file mode 120000 index 000000000000..83ddf6d1e064 --- /dev/null +++ b/playgrounds/vite/node_modules/@tailwindcss/vite @@ -0,0 +1 @@ +../../../../packages/@tailwindcss-vite \ No newline at end of file diff --git a/playgrounds/vite/node_modules/@types/react b/playgrounds/vite/node_modules/@types/react new file mode 120000 index 000000000000..df4499dfb012 --- /dev/null +++ b/playgrounds/vite/node_modules/@types/react @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react@19.2.7/node_modules/@types/react \ No newline at end of file diff --git a/playgrounds/vite/node_modules/@types/react-dom b/playgrounds/vite/node_modules/@types/react-dom new file mode 120000 index 000000000000..41e90d09f161 --- /dev/null +++ b/playgrounds/vite/node_modules/@types/react-dom @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@types+react-dom@19.2.3_@types+react@19.2.7/node_modules/@types/react-dom \ No newline at end of file diff --git a/playgrounds/vite/node_modules/@vitejs/plugin-react b/playgrounds/vite/node_modules/@vitejs/plugin-react new file mode 120000 index 000000000000..fedac2cc53ec --- /dev/null +++ b/playgrounds/vite/node_modules/@vitejs/plugin-react @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/@vitejs+plugin-react@5.1.2_vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patc_aj35tdpqa5okkgz5tghuf75b2y/node_modules/@vitejs/plugin-react \ No newline at end of file diff --git a/playgrounds/vite/node_modules/bun b/playgrounds/vite/node_modules/bun new file mode 120000 index 000000000000..7f0483f32075 --- /dev/null +++ b/playgrounds/vite/node_modules/bun @@ -0,0 +1 @@ +../../../node_modules/.pnpm/bun@1.3.5/node_modules/bun \ No newline at end of file diff --git a/playgrounds/vite/node_modules/react b/playgrounds/vite/node_modules/react new file mode 120000 index 000000000000..3a80171770b0 --- /dev/null +++ b/playgrounds/vite/node_modules/react @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react@19.2.3/node_modules/react \ No newline at end of file diff --git a/playgrounds/vite/node_modules/react-dom b/playgrounds/vite/node_modules/react-dom new file mode 120000 index 000000000000..d968d23b66d9 --- /dev/null +++ b/playgrounds/vite/node_modules/react-dom @@ -0,0 +1 @@ +../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom \ No newline at end of file diff --git a/playgrounds/vite/node_modules/tailwindcss b/playgrounds/vite/node_modules/tailwindcss new file mode 120000 index 000000000000..04022219c6fb --- /dev/null +++ b/playgrounds/vite/node_modules/tailwindcss @@ -0,0 +1 @@ +../../../packages/tailwindcss \ No newline at end of file diff --git a/playgrounds/vite/node_modules/vite b/playgrounds/vite/node_modules/vite new file mode 120000 index 000000000000..64a91e084ab7 --- /dev/null +++ b/playgrounds/vite/node_modules/vite @@ -0,0 +1 @@ +../../../node_modules/.pnpm/vite@7.0.0_@types+node@20.19.1_jiti@2.6.1_lightningcss@1.30.2_patch_hash=tzyxy3asfxcqc7ihroou_6ihr2b6mexvz5zmjho4omuoio4/node_modules/vite \ No newline at end of file diff --git a/scripts/build-versioned.js b/scripts/build-versioned.js new file mode 100644 index 000000000000..c0c3f0794982 --- /dev/null +++ b/scripts/build-versioned.js @@ -0,0 +1,156 @@ +#!/usr/bin/env node +const { execSync } = require('child_process') +const fs = require('fs') +const path = require('path') + +// Read version from package.json +const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')) +const VERSION = packageJson.version +const ROOT = path.join(__dirname, '..') + +console.log(`Building Tailwind CSS v${VERSION}...`) + +// Generate plugin list +console.log('Generating plugin list...') +try { + execSync('npm run generate', { stdio: 'inherit', cwd: ROOT }) +} catch (err) { + console.error('Failed to generate plugin list') + process.exit(1) +} + +// Clean only this version's directory (preserve other versions) +const versionDir = path.join(ROOT, 'lib', VERSION) +console.log(`Cleaning ${versionDir}...`) +if (fs.existsSync(versionDir)) { + try { + execSync(`npx rimraf "${versionDir}"`, { stdio: 'inherit', cwd: ROOT }) + } catch (err) { + console.error(`Failed to clean ${versionDir}`) + process.exit(1) + } +} + +// Ensure lib directory exists +if (!fs.existsSync(path.join(ROOT, 'lib'))) { + fs.mkdirSync(path.join(ROOT, 'lib'), { recursive: true }) +} + +// Build with versioned output +console.log(`Compiling to lib/${VERSION}...`) +try { + execSync(`npx swc src --out-dir lib/${VERSION} --copy-files`, { + stdio: 'inherit', + cwd: ROOT, + }) +} catch (err) { + console.error('SWC compilation failed') + process.exit(1) +} + +// Bundle peers +const peerInput = path.join('lib', VERSION, 'cli-peer-dependencies.js') +const peersDir = path.join(ROOT, 'peers') +console.log('Bundling peer dependencies...') + +// Ensure peers directory exists +if (!fs.existsSync(peersDir)) { + fs.mkdirSync(peersDir, { recursive: true }) +} + +try { + execSync(`npx esbuild ${peerInput} --bundle --platform=node --outfile=peers/index.js`, { + stdio: 'inherit', + cwd: ROOT, + }) +} catch (err) { + console.error('Failed to bundle peer dependencies') + process.exit(1) +} + +// Create symlinks for backwards compatibility +console.log('Creating symlinks for package entry points...') +const symlinkTargets = [ + 'index.js', + 'cli.js', + 'cli-peer-dependencies.js', + 'constants.js', + 'corePluginList.js', + 'corePlugins.js', + 'featureFlags.js', + 'processTailwindFeatures.js', +] + +for (const target of symlinkTargets) { + const linkPath = path.join(ROOT, 'lib', target) + const targetPath = path.join(VERSION, target) + + // Remove existing symlink/file + if (fs.existsSync(linkPath)) { + try { + fs.unlinkSync(linkPath) + } catch (err) { + // Try to remove as directory if it's a directory symlink + try { + fs.rmSync(linkPath, { recursive: true, force: true }) + } catch (err2) { + console.warn(`Warning: Could not remove existing ${target}`) + } + } + } + + // Create symlink (or copy on Windows if symlink fails) + try { + fs.symlinkSync(targetPath, linkPath, 'file') + console.log(` ✓ Symlinked ${target} → ${VERSION}/${target}`) + } catch (err) { + // Fallback to copy for Windows without admin rights + console.log(` ℹ Symlink failed for ${target}, using copy instead`) + const sourcePath = path.join(ROOT, 'lib', VERSION, target) + if (fs.existsSync(sourcePath)) { + fs.copyFileSync(sourcePath, linkPath) + console.log(` ✓ Copied ${target} from ${VERSION}/${target}`) + } else { + console.warn(` ⚠ Warning: ${sourcePath} does not exist, skipping`) + } + } +} + +// Also handle subdirectories that might be imported +const dirSymlinks = ['css', 'lib', 'postcss-plugins', 'public', 'util'] +for (const dir of dirSymlinks) { + const linkPath = path.join(ROOT, 'lib', dir) + const targetPath = path.join(VERSION, dir) + + // Remove existing symlink/directory + if (fs.existsSync(linkPath)) { + try { + fs.rmSync(linkPath, { recursive: true, force: true }) + } catch (err) { + console.warn(`Warning: Could not remove existing ${dir}/`) + } + } + + // Check if source directory exists + const srcDir = path.join(ROOT, 'lib', VERSION, dir) + if (!fs.existsSync(srcDir)) { + console.log(` ℹ Skipping ${dir}/ (doesn't exist in build output)`) + continue + } + + // Create symlink (or copy on Windows if symlink fails) + try { + fs.symlinkSync(targetPath, linkPath, 'dir') + console.log(` ✓ Symlinked ${dir}/ → ${VERSION}/${dir}/`) + } catch (err) { + // Fallback: recursive copy + console.log(` ℹ Symlink failed for ${dir}/, using copy instead`) + if (fs.existsSync(srcDir)) { + fs.cpSync(srcDir, linkPath, { recursive: true }) + console.log(` ✓ Copied ${dir}/ from ${VERSION}/${dir}/`) + } + } +} + +console.log(`\n✓ Build complete! Output: lib/${VERSION}/`) +console.log(` Symlinks/copies created at lib/ for backwards compatibility`) diff --git a/scripts/get-version.js b/scripts/get-version.js new file mode 100644 index 000000000000..96dd1fde23f3 --- /dev/null +++ b/scripts/get-version.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node +const fs = require('fs') +const path = require('path') + +const packageJsonPath = path.join(__dirname, '..', 'package.json') +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) +console.log(packageJson.version) diff --git a/scripts/pack-versioned.js b/scripts/pack-versioned.js new file mode 100644 index 000000000000..eabf0a1bd4ea --- /dev/null +++ b/scripts/pack-versioned.js @@ -0,0 +1,163 @@ +#!/usr/bin/env node +const { execSync } = require('child_process') +const fs = require('fs') +const path = require('path') + +// Read version +const ROOT = path.join(__dirname, '..') +const packageJson = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8')) +const VERSION = packageJson.version +const PACKAGE_NAME = packageJson.name + +// Create dist/VERSION directory +const distVersionDir = path.join(ROOT, 'dist', VERSION) +const distRootDir = path.join(ROOT, 'dist') + +fs.mkdirSync(distVersionDir, { recursive: true }) + +console.log(`Packing ${PACKAGE_NAME}@${VERSION}...`) + +// Replace symlinks with actual copies before packing +// This ensures the tarball contains real files, not symlinks +console.log('Converting symlinks to copies for packaging...') + +const symlinkTargets = [ + 'index.js', + 'cli.js', + 'cli-peer-dependencies.js', + 'constants.js', + 'corePluginList.js', + 'corePlugins.js', + 'featureFlags.js', + 'processTailwindFeatures.js', +] + +const dirSymlinks = ['css', 'lib', 'postcss-plugins', 'public', 'util'] + +// Store original symlink info to restore later +const symlinksToRestore = [] + +// Replace file symlinks with copies +for (const target of symlinkTargets) { + const linkPath = path.join(ROOT, 'lib', target) + + if (fs.existsSync(linkPath)) { + const stats = fs.lstatSync(linkPath) + + if (stats.isSymbolicLink()) { + const targetPath = fs.readlinkSync(linkPath) + const sourcePath = path.join(ROOT, 'lib', targetPath) + + // Store for restoration + symlinksToRestore.push({ linkPath, targetPath, type: 'file' }) + + // Replace symlink with copy + fs.unlinkSync(linkPath) + if (fs.existsSync(sourcePath)) { + fs.copyFileSync(sourcePath, linkPath) + console.log(` ✓ Replaced symlink ${target} with copy`) + } else { + console.warn(` ⚠ Warning: Source file ${sourcePath} not found for ${target}`) + } + } + } +} + +// Replace directory symlinks with copies +for (const dir of dirSymlinks) { + const linkPath = path.join(ROOT, 'lib', dir) + + if (fs.existsSync(linkPath)) { + const stats = fs.lstatSync(linkPath) + + if (stats.isSymbolicLink()) { + const targetPath = fs.readlinkSync(linkPath) + const sourcePath = path.join(ROOT, 'lib', targetPath) + + // Store for restoration + symlinksToRestore.push({ linkPath, targetPath, type: 'dir' }) + + // Replace symlink with copy + fs.rmSync(linkPath, { recursive: true, force: true }) + if (fs.existsSync(sourcePath)) { + fs.cpSync(sourcePath, linkPath, { recursive: true }) + console.log(` ✓ Replaced symlink ${dir}/ with copy`) + } else { + console.warn(` ⚠ Warning: Source directory ${sourcePath} not found for ${dir}/`) + } + } + } +} + +console.log('\nRunning npm pack...') + +// Run npm pack with output to dist/VERSION +try { + execSync(`npm pack --pack-destination="${distVersionDir}"`, { + stdio: 'inherit', + cwd: ROOT, + }) +} catch (err) { + console.error('npm pack failed') + + // Restore symlinks before exiting + console.log('\nRestoring symlinks after failure...') + for (const { linkPath, targetPath, type } of symlinksToRestore) { + try { + if (fs.existsSync(linkPath)) { + if (type === 'dir') { + fs.rmSync(linkPath, { recursive: true, force: true }) + } else { + fs.unlinkSync(linkPath) + } + } + fs.symlinkSync(targetPath, linkPath, type) + } catch (restoreErr) { + console.error(`Failed to restore symlink: ${linkPath}`) + } + } + + process.exit(1) +} + +// Restore symlinks after successful pack +console.log('\nRestoring symlinks...') +for (const { linkPath, targetPath, type } of symlinksToRestore) { + try { + if (fs.existsSync(linkPath)) { + if (type === 'dir') { + fs.rmSync(linkPath, { recursive: true, force: true }) + } else { + fs.unlinkSync(linkPath) + } + } + fs.symlinkSync(targetPath, linkPath, type) + console.log(` ✓ Restored symlink: ${path.basename(linkPath)}`) + } catch (restoreErr) { + console.error(` ✗ Failed to restore symlink: ${linkPath}`) + } +} + +const tarballName = `${PACKAGE_NAME}-${VERSION}.tgz` +const versionedTarball = path.join(distVersionDir, tarballName) +const rootTarball = path.join(distRootDir, tarballName) + +if (!fs.existsSync(versionedTarball)) { + console.error(`Error: Expected tarball not found at ${versionedTarball}`) + process.exit(1) +} + +console.log(`✓ Tarball created: dist/${VERSION}/${tarballName}`) + +// Copy to root dist for backwards compatibility +try { + fs.copyFileSync(versionedTarball, rootTarball) + console.log(`✓ Also copied to: dist/${tarballName}`) +} catch (err) { + console.error('Failed to copy tarball to root dist') + process.exit(1) +} + +console.log('\n✓ Packaging complete!') +console.log(` Versioned: dist/${VERSION}/${tarballName}`) +console.log(` Root: dist/${tarballName}`) diff --git a/src/corePlugins.js b/src/corePlugins.js index 03ff5e238db1..8e41347e50da 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -27,9 +27,7 @@ export let variantPlugins = { addVariant('placeholder', '&::placeholder') - /* addVariant('backdrop', '&::backdrop') - */ addVariant('before', ({ container }) => { container.walkRules((rule) => { @@ -106,6 +104,7 @@ export let variantPlugins = { 'indeterminate', 'placeholder-shown', 'autofill', + 'optional', 'required', 'valid', 'invalid', @@ -122,9 +121,7 @@ export let variantPlugins = { 'focus', 'focus-visible', 'active', - /* 'enabled', - */ 'disabled', ].map((variant) => (Array.isArray(variant) ? variant : [variant, `:${variant}`])) @@ -200,10 +197,53 @@ export let variantPlugins = { } }, + prefersContrastVariants: ({ addVariant }) => { + addVariant('contrast-more', '@media (prefers-contrast: more)') + addVariant('contrast-less', '@media (prefers-contrast: less)') + }, + printVariant: ({ addVariant }) => { addVariant('print', '@media print') }, + forcedColorsVariant: ({ addVariant }) => { + addVariant('forced-colors', '@media (forced-colors: active)') + }, + + ariaVariants: ({ addVariant, theme }) => { + let values = theme('aria') ?? {} + for (let [key, value] of Object.entries(values)) { + addVariant(`aria-${key}`, `&[aria-${value}]`) + } + }, + + dataVariants: ({ addVariant, theme }) => { + let values = theme('data') ?? {} + for (let [key, value] of Object.entries(values)) { + addVariant(`data-${key}`, `&[data-${value}]`) + } + }, + + supportsVariants: ({ addVariant }) => { + // Note: Full arbitrary support for supports-[...] handled by extractor + // This provides the base variant registration + addVariant('supports', ({ container }) => { + // This will be enhanced when arbitrary supports-[...] is detected + return container + }) + }, + + minMaxVariants: ({ addVariant }) => { + // Note: Full arbitrary support for min-[...] and max-[...] handled by extractor + // This provides the base variant registration + addVariant('min', ({ container }) => { + return container + }) + addVariant('max', ({ container }) => { + return container + }) + }, + screenVariants: ({ theme, addVariant }) => { for (let screen of normalizeScreens(theme('screens'))) { let query = buildMediaQuery(screen) @@ -389,6 +429,7 @@ export let corePlugins = { addUtilities({ '.visible': { visibility: 'visible' }, '.invisible': { visibility: 'hidden' }, + '.collapse': { visibility: 'collapse' }, }) }, @@ -420,6 +461,37 @@ export let corePlugins = { { supportsNegativeValues: true } ), + insetInline: createUtilityPlugin('insetInline', [['inset-inline', ['inset-inline']]], { + supportsNegativeValues: true, + }), + insetInlineStart: createUtilityPlugin( + 'insetInlineStart', + [ + ['start', ['inset-inline-start']], + ['inset-inline-start', ['inset-inline-start']], + ], + { supportsNegativeValues: true } + ), + insetInlineEnd: createUtilityPlugin( + 'insetInlineEnd', + [ + ['end', ['inset-inline-end']], + ['inset-inline-end', ['inset-inline-end']], + ], + { supportsNegativeValues: true } + ), + insetBlock: createUtilityPlugin('insetBlock', [['inset-block', ['inset-block']]], { + supportsNegativeValues: true, + }), + insetBlockStart: createUtilityPlugin( + 'insetBlockStart', + [['inset-block-start', ['inset-block-start']]], + { supportsNegativeValues: true } + ), + insetBlockEnd: createUtilityPlugin('insetBlockEnd', [['inset-block-end', ['inset-block-end']]], { + supportsNegativeValues: true, + }), + isolation: ({ addUtilities }) => { addUtilities({ '.isolate': { isolation: 'isolate' }, @@ -471,6 +543,39 @@ export let corePlugins = { { supportsNegativeValues: true } ), + marginInline: createUtilityPlugin('marginInline', [['margin-inline', ['margin-inline']]], { + supportsNegativeValues: true, + }), + marginInlineStart: createUtilityPlugin( + 'marginInlineStart', + [ + ['ms', ['margin-inline-start']], + ['margin-inline-start', ['margin-inline-start']], + ], + { supportsNegativeValues: true } + ), + marginInlineEnd: createUtilityPlugin( + 'marginInlineEnd', + [ + ['me', ['margin-inline-end']], + ['margin-inline-end', ['margin-inline-end']], + ], + { supportsNegativeValues: true } + ), + marginBlock: createUtilityPlugin('marginBlock', [['margin-block', ['margin-block']]], { + supportsNegativeValues: true, + }), + marginBlockStart: createUtilityPlugin( + 'marginBlockStart', + [['margin-block-start', ['margin-block-start']]], + { supportsNegativeValues: true } + ), + marginBlockEnd: createUtilityPlugin( + 'marginBlockEnd', + [['margin-block-end', ['margin-block-end']]], + { supportsNegativeValues: true } + ), + boxSizing: ({ addUtilities }) => { addUtilities({ '.box-border': { 'box-sizing': 'border-box' }, @@ -514,6 +619,8 @@ export let corePlugins = { minWidth: createUtilityPlugin('minWidth', [['min-w', ['minWidth']]]), maxWidth: createUtilityPlugin('maxWidth', [['max-w', ['maxWidth']]]), + size: createUtilityPlugin('size', [['size', ['width', 'height']]]), + flex: createUtilityPlugin('flex'), flexShrink: createUtilityPlugin('flexShrink', [ ['flex-shrink', ['flex-shrink']], // Deprecated @@ -539,7 +646,13 @@ export let corePlugins = { }) }, - /* + captionSide: ({ addUtilities }) => { + addUtilities({ + '.caption-top': { 'caption-side': 'top' }, + '.caption-bottom': { 'caption-side': 'bottom' }, + }) + }, + borderSpacing: ({ addDefaults, matchUtilities, theme }) => { addDefaults('border-spacing', { '--tw-border-spacing-x': 0, @@ -574,7 +687,6 @@ export let corePlugins = { { values: theme('borderSpacing') } ) }, - */ transformOrigin: createUtilityPlugin('transformOrigin', [['origin', ['transformOrigin']]]), translate: createUtilityPlugin( @@ -835,6 +947,48 @@ export let corePlugins = { ], ]), + scrollMarginInline: createUtilityPlugin('scrollMarginInline', [ + ['scroll-margin-inline', ['scroll-margin-inline']], + ]), + scrollMarginInlineStart: createUtilityPlugin('scrollMarginInlineStart', [ + ['scroll-ms', ['scroll-margin-inline-start']], + ['scroll-margin-inline-start', ['scroll-margin-inline-start']], + ]), + scrollMarginInlineEnd: createUtilityPlugin('scrollMarginInlineEnd', [ + ['scroll-me', ['scroll-margin-inline-end']], + ['scroll-margin-inline-end', ['scroll-margin-inline-end']], + ]), + scrollMarginBlock: createUtilityPlugin('scrollMarginBlock', [ + ['scroll-margin-block', ['scroll-margin-block']], + ]), + scrollMarginBlockStart: createUtilityPlugin('scrollMarginBlockStart', [ + ['scroll-margin-block-start', ['scroll-margin-block-start']], + ]), + scrollMarginBlockEnd: createUtilityPlugin('scrollMarginBlockEnd', [ + ['scroll-margin-block-end', ['scroll-margin-block-end']], + ]), + + scrollPaddingInline: createUtilityPlugin('scrollPaddingInline', [ + ['scroll-padding-inline', ['scroll-padding-inline']], + ]), + scrollPaddingInlineStart: createUtilityPlugin('scrollPaddingInlineStart', [ + ['scroll-ps', ['scroll-padding-inline-start']], + ['scroll-padding-inline-start', ['scroll-padding-inline-start']], + ]), + scrollPaddingInlineEnd: createUtilityPlugin('scrollPaddingInlineEnd', [ + ['scroll-pe', ['scroll-padding-inline-end']], + ['scroll-padding-inline-end', ['scroll-padding-inline-end']], + ]), + scrollPaddingBlock: createUtilityPlugin('scrollPaddingBlock', [ + ['scroll-padding-block', ['scroll-padding-block']], + ]), + scrollPaddingBlockStart: createUtilityPlugin('scrollPaddingBlockStart', [ + ['scroll-padding-block-start', ['scroll-padding-block-start']], + ]), + scrollPaddingBlockEnd: createUtilityPlugin('scrollPaddingBlockEnd', [ + ['scroll-padding-block-end', ['scroll-padding-block-end']], + ]), + listStylePosition: ({ addUtilities }) => { addUtilities({ '.list-inside': { 'list-style-position': 'inside' }, @@ -844,6 +998,15 @@ export let corePlugins = { listStyleType: createUtilityPlugin('listStyleType', [['list', ['listStyleType']]]), + listStyleImage: ({ matchUtilities, theme }) => { + matchUtilities( + { + 'list-image': (value) => ({ 'list-style-image': value }), + }, + { values: theme('listStyleImage') } + ) + }, + appearance: ({ addUtilities }) => { addUtilities({ '.appearance-none': { appearance: 'none' }, @@ -893,6 +1056,7 @@ export let corePlugins = { addUtilities({ '.grid-flow-row': { gridAutoFlow: 'row' }, '.grid-flow-col': { gridAutoFlow: 'column' }, + '.grid-flow-dense': { gridAutoFlow: 'dense' }, '.grid-flow-row-dense': { gridAutoFlow: 'row dense' }, '.grid-flow-col-dense': { gridAutoFlow: 'column dense' }, }) @@ -929,6 +1093,7 @@ export let corePlugins = { '.place-content-between': { 'place-content': 'space-between' }, '.place-content-around': { 'place-content': 'space-around' }, '.place-content-evenly': { 'place-content': 'space-evenly' }, + '.place-content-baseline': { 'place-content': 'baseline' }, '.place-content-stretch': { 'place-content': 'stretch' }, }) }, @@ -938,18 +1103,22 @@ export let corePlugins = { '.place-items-start': { 'place-items': 'start' }, '.place-items-end': { 'place-items': 'end' }, '.place-items-center': { 'place-items': 'center' }, + '.place-items-baseline': { 'place-items': 'baseline' }, '.place-items-stretch': { 'place-items': 'stretch' }, }) }, alignContent: ({ addUtilities }) => { addUtilities({ + '.content-normal': { 'align-content': 'normal' }, '.content-center': { 'align-content': 'center' }, '.content-start': { 'align-content': 'flex-start' }, '.content-end': { 'align-content': 'flex-end' }, '.content-between': { 'align-content': 'space-between' }, '.content-around': { 'align-content': 'space-around' }, '.content-evenly': { 'align-content': 'space-evenly' }, + '.content-baseline': { 'align-content': 'baseline' }, + '.content-stretch': { 'align-content': 'stretch' }, }) }, @@ -965,12 +1134,14 @@ export let corePlugins = { justifyContent: ({ addUtilities }) => { addUtilities({ + '.justify-normal': { 'justify-content': 'normal' }, '.justify-start': { 'justify-content': 'flex-start' }, '.justify-end': { 'justify-content': 'flex-end' }, '.justify-center': { 'justify-content': 'center' }, '.justify-between': { 'justify-content': 'space-between' }, '.justify-around': { 'justify-content': 'space-around' }, '.justify-evenly': { 'justify-content': 'space-evenly' }, + '.justify-stretch': { 'justify-content': 'stretch' }, }) }, @@ -1199,6 +1370,15 @@ export let corePlugins = { }) }, + textWrap: ({ addUtilities }) => { + addUtilities({ + '.text-wrap': { 'text-wrap': 'wrap' }, + '.text-nowrap': { 'text-wrap': 'nowrap' }, + '.text-balance': { 'text-wrap': 'balance' }, + '.text-pretty': { 'text-wrap': 'pretty' }, + }) + }, + whitespace: ({ addUtilities }) => { addUtilities({ '.whitespace-normal': { 'white-space': 'normal' }, @@ -1206,6 +1386,7 @@ export let corePlugins = { '.whitespace-pre': { 'white-space': 'pre' }, '.whitespace-pre-line': { 'white-space': 'pre-line' }, '.whitespace-pre-wrap': { 'white-space': 'pre-wrap' }, + '.whitespace-break-spaces': { 'white-space': 'break-spaces' }, }) }, @@ -1214,6 +1395,15 @@ export let corePlugins = { '.break-normal': { 'overflow-wrap': 'normal', 'word-break': 'normal' }, '.break-words': { 'overflow-wrap': 'break-word' }, '.break-all': { 'word-break': 'break-all' }, + '.break-keep': { 'word-break': 'keep-all' }, + }) + }, + + hyphens: ({ addUtilities }) => { + addUtilities({ + '.hyphens-none': { hyphens: 'none' }, + '.hyphens-manual': { hyphens: 'manual' }, + '.hyphens-auto': { hyphens: 'auto' }, }) }, @@ -1233,6 +1423,19 @@ export let corePlugins = { ], ]), + borderStartStartRadius: createUtilityPlugin('borderStartStartRadius', [ + ['rounded-ss', ['border-start-start-radius']], + ]), + borderStartEndRadius: createUtilityPlugin('borderStartEndRadius', [ + ['rounded-se', ['border-start-end-radius']], + ]), + borderEndStartRadius: createUtilityPlugin('borderEndStartRadius', [ + ['rounded-es', ['border-end-start-radius']], + ]), + borderEndEndRadius: createUtilityPlugin('borderEndEndRadius', [ + ['rounded-ee', ['border-end-end-radius']], + ]), + borderWidth: createUtilityPlugin( 'borderWidth', [ @@ -1514,7 +1717,7 @@ export let corePlugins = { }) }, - fill: ({ matchUtilities, theme }) => { + fill: ({ matchUtilities, theme, addUtilities }) => { matchUtilities( { fill: (value) => { @@ -1523,9 +1726,12 @@ export let corePlugins = { }, { values: flattenColorPalette(theme('fill')), type: ['color', 'any'] } ) + addUtilities({ + '.fill-none': { fill: 'none' }, + }) }, - stroke: ({ matchUtilities, theme }) => { + stroke: ({ matchUtilities, theme, addUtilities }) => { matchUtilities( { stroke: (value) => { @@ -1534,6 +1740,9 @@ export let corePlugins = { }, { values: flattenColorPalette(theme('stroke')), type: ['color', 'url'] } ) + addUtilities({ + '.stroke-none': { stroke: 'none' }, + }) }, strokeWidth: createUtilityPlugin('strokeWidth', [['stroke', ['stroke-width']]], { @@ -1565,16 +1774,31 @@ export let corePlugins = { ], ]), + paddingInline: createUtilityPlugin('paddingInline', [['padding-inline', ['padding-inline']]]), + paddingInlineStart: createUtilityPlugin('paddingInlineStart', [ + ['ps', ['padding-inline-start']], + ['padding-inline-start', ['padding-inline-start']], + ]), + paddingInlineEnd: createUtilityPlugin('paddingInlineEnd', [ + ['pe', ['padding-inline-end']], + ['padding-inline-end', ['padding-inline-end']], + ]), + paddingBlock: createUtilityPlugin('paddingBlock', [['padding-block', ['padding-block']]]), + paddingBlockStart: createUtilityPlugin('paddingBlockStart', [ + ['padding-block-start', ['padding-block-start']], + ]), + paddingBlockEnd: createUtilityPlugin('paddingBlockEnd', [ + ['padding-block-end', ['padding-block-end']], + ]), + textAlign: ({ addUtilities }) => { addUtilities({ '.text-left': { 'text-align': 'left' }, '.text-center': { 'text-align': 'center' }, '.text-right': { 'text-align': 'right' }, '.text-justify': { 'text-align': 'justify' }, - /* '.text-start': { 'text-align': 'start' }, '.text-end': { 'text-align': 'end' }, - */ }) }, @@ -1597,9 +1821,45 @@ export let corePlugins = { matchUtilities({ align: (value) => ({ 'vertical-align': value }) }) }, - fontFamily: createUtilityPlugin('fontFamily', [['font', ['fontFamily']]], { - type: ['lookup', 'generic-name', 'family-name'], - }), + fontFamily: ({ matchUtilities, theme }) => { + matchUtilities( + { + font: (value) => { + // Handle array values: either [fontFamily1, fontFamily2, ...] or [fontFamily, { options }] + if (Array.isArray(value)) { + let lastItem = value[value.length - 1] + + // If last item is an object, it's options + if (typeof lastItem === 'object' && lastItem !== null && !Array.isArray(lastItem)) { + let fontFamilies = value.slice(0, -1) + let options = lastItem + + return { + 'font-family': fontFamilies.join(', '), + ...(options.fontFeatureSettings && { + 'font-feature-settings': options.fontFeatureSettings, + }), + } + } else { + // All items are font families + return { + 'font-family': value.join(', '), + } + } + } + + // Single string value + return { + 'font-family': value, + } + }, + }, + { + values: theme('fontFamily'), + type: ['lookup', 'generic-name', 'family-name'], + } + ) + }, fontSize: ({ matchUtilities, theme }) => { matchUtilities( @@ -1706,6 +1966,29 @@ export let corePlugins = { supportsNegativeValues: true, }), + lineClamp: ({ matchUtilities, addUtilities, theme }) => { + addUtilities({ + '.line-clamp-none': { + overflow: 'visible', + display: 'block', + '-webkit-box-orient': 'horizontal', + '-webkit-line-clamp': 'none', + }, + }) + + matchUtilities( + { + 'line-clamp': (value) => ({ + overflow: 'hidden', + display: '-webkit-box', + '-webkit-box-orient': 'vertical', + '-webkit-line-clamp': `${value}`, + }), + }, + { values: theme('lineClamp') } + ) + }, + textColor: ({ matchUtilities, theme, corePlugins }) => { matchUtilities( { @@ -1881,6 +2164,7 @@ export let corePlugins = { '.mix-blend-saturation': { 'mix-blend-mode': 'saturation' }, '.mix-blend-color': { 'mix-blend-mode': 'color' }, '.mix-blend-luminosity': { 'mix-blend-mode': 'luminosity' }, + '.mix-blend-plus-lighter': { 'mix-blend-mode': 'plus-lighter' }, }) }, @@ -1962,6 +2246,7 @@ export let corePlugins = { outlineOffset: createUtilityPlugin('outlineOffset', [['outline-offset', ['outline-offset']]], { type: ['length', 'number', 'percentage'], + supportsNegativeValues: true, }), outlineColor: ({ matchUtilities, theme }) => { diff --git a/src/lib/defaultExtractor.js b/src/lib/defaultExtractor.js index e211c598fea7..a629dc81ea1a 100644 --- a/src/lib/defaultExtractor.js +++ b/src/lib/defaultExtractor.js @@ -12,6 +12,13 @@ const PATTERNS = [ /([^<>"'`\s]*\[[^<>"'`\s]*\("[^'`\s]*"\)+\])/.source, // h-[calc(100%-theme("spacing.1"))] /([^${(<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']` /([^${(<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]` + /(\[&.*?\]:[^<>"'`\s]*)/.source, // Arbitrary variants: `[&:hover]:text-red-500`, `[&[data-active]]:bg-blue`, `[&_p]:text-sm` + /(\baria-\[[^\]]+\]:[^<>"'`\s]*)/.source, // ARIA variants: `aria-[checked]:bg-blue-500`, `aria-[disabled]:opacity-50` + /(\bdata-\[[^\]]+\]:[^<>"'`\s]*)/.source, // Data variants: `data-[state=open]:block`, `data-[loading]:opacity-50` + /(\bhas-\[[^\]]+\]:[^<>"'`\s]*)/.source, // Has variants: `has-[:checked]:bg-blue-500`, `has-[>a]:underline` + /(\bsupports-\[[^\]]+\]:[^<>"'`\s]*)/.source, // Feature query variants: `supports-[display:grid]:grid` + /(\bmin-\[[^\]]+\]:[^<>"'`\s]*)/.source, // Min-width variants: `min-[768px]:flex` + /(\bmax-\[[^\]]+\]:[^<>"'`\s]*)/.source, // Max-width variants: `max-[1024px]:hidden` /([^<>"'`\s]*\[[^<>"'`\s]*:[^\]\s]*\])/.source, // `[attr:value]` /([^<>"'`\s]*\[[^<>"'`\s]*:'[^"'`\s]*'\])/.source, // `[content:'hello']` but not `[content:"hello"]` /([^<>"'`\s]*\[[^<>"'`\s]*:"[^"'`\s]*"\])/.source, // `[content:"hello"]` but not `[content:'hello']` diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index fc9a6bbd6ec1..ada24ee024e0 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -10,6 +10,7 @@ import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSe import { asClass } from '../util/nameClass' import { normalize } from '../util/dataTypes' import isValidArbitraryValue from '../util/isValidArbitraryValue' +import escapeClassName from '../util/escapeClassName' let classNameParser = selectorParser((selectors) => { return selectors.first.filter(({ type }) => type === 'class').pop().value @@ -19,6 +20,74 @@ function getClassNameFromSelector(selector) { return classNameParser.transformSync(selector) } +// Extract arbitrary variants from a candidate +// Example: "[&:nth-child(3)]:hover:text-red-500" -> +// { arbitraryVariants: [{type: 'v3.1', selector: '&:nth-child(3)'}], remaining: "hover:text-red-500" } +// Also extracts v3.2 arbitrary variants like "aria-[checked]:text-red" -> +// { arbitraryVariants: [{type: 'aria', value: 'checked'}], remaining: "text-red" } +function extractArbitraryVariants(candidate, separator) { + let arbitraryVariants = [] + let remaining = candidate + + while (true) { + let matched = false + + // Match v3.1 arbitrary variants: [&...]: + let v31Regex = new RegExp(`^\\[([^\\]]+)\\]\\${separator}`) + let v31Match = remaining.match(v31Regex) + if (v31Match) { + arbitraryVariants.push({ type: 'v3.1', selector: v31Match[1] }) + remaining = remaining.slice(v31Match[0].length) + matched = true + continue + } + + // Match v3.2 arbitrary variants: aria-[...]:, data-[...]:, supports-[...]:, min-[...]:, max-[...]: + // v3.4 adds has-[...] + let v32Regex = new RegExp(`^(aria|data|supports|min|max|has)-\\[([^\\]]+)\\]\\${separator}`) + let v32Match = remaining.match(v32Regex) + if (v32Match) { + arbitraryVariants.push({ type: v32Match[1], value: v32Match[2] }) + remaining = remaining.slice(v32Match[0].length) + matched = true + continue + } + + if (!matched) break + } + + return { arbitraryVariants, remaining } +} + +// Validate arbitrary variant selector +function isValidArbitraryVariant(selector) { + // Basic validation + if (!selector || typeof selector !== 'string') return false + + // Must start with & (references current selector) + if (!selector.startsWith('&')) return false + + // Check for balanced brackets/parentheses + let depth = { '(': 0, '[': 0, '{': 0 } + for (let char of selector) { + if (char === '(' || char === '[' || char === '{') depth[char]++ + if (char === ')') depth['(']-- + if (char === ']') depth['[']-- + if (char === '}') depth['{']-- + if (depth['('] < 0 || depth['['] < 0 || depth['{'] < 0) return false + } + + return depth['('] === 0 && depth['['] === 0 && depth['{'] === 0 +} + +// Escape arbitrary variant selector for use in class names +// Convert underscores to spaces for descendant selectors +function escapeArbitraryVariant(selector) { + // Replace underscore with space for descendant selectors + // This allows [&_p] to work as [& p] (descendant combinator) + return selector.replace(/_/g, ' ') +} + // Generate match permutations for a class candidate, like: // ['ring-offset-blue', '100'] // ['ring-offset', 'blue-100'] @@ -125,6 +194,70 @@ function applyVariant(variant, matches, context) { return matches } + // Check if this is a v3.2 arbitrary variant that wasn't extracted + // (happens when arbitrary variant comes after normal variants) + let ariaMatch = variant.match(/^aria-\[(.+)\]$/) + let dataMatch = variant.match(/^data-\[(.+)\]$/) + let supportsMatch = variant.match(/^supports-\[(.+)\]$/) + let minMatch = variant.match(/^min-\[(.+)\]$/) + let maxMatch = variant.match(/^max-\[(.+)\]$/) + + if (ariaMatch || dataMatch || supportsMatch || minMatch || maxMatch) { + // Handle as arbitrary variant + if (ariaMatch || dataMatch) { + // aria/data variants: add attribute selector + let attrName = ariaMatch ? 'aria' : 'data' + let attrValue = ariaMatch ? ariaMatch[1] : dataMatch[1] + + return matches.map(([meta, rule]) => { + let container = postcss.root({ nodes: [rule.clone()] }) + + container.walkRules((r) => { + // Add attribute selector + if (attrValue.includes('=')) { + // Has a value like data-[state=open] + let [key, val] = attrValue.split('=') + r.selector = `${r.selector}[${attrName}-${key}="${val}"]` + } else { + // Just a key like data-[loading] + r.selector = `${r.selector}[${attrName}-${attrValue}]` + } + }) + + return [meta, container.nodes[0]] + }) + } else if (supportsMatch) { + // supports variant: wrap in @supports at-rule + let supportsValue = supportsMatch[1] + + return matches.map(([meta, rule]) => { + let atRule = postcss.atRule({ + name: 'supports', + params: `(${supportsValue})`, + }) + atRule.append(rule.clone()) + atRule.raws.tailwind = { ...atRule.raws.tailwind, parentLayer: meta.layer } + + return [meta, atRule] + }) + } else if (minMatch || maxMatch) { + // min/max variants: wrap in @media at-rule + let mediaValue = minMatch ? minMatch[1] : maxMatch[1] + let mediaQuery = minMatch ? `(min-width: ${mediaValue})` : `(max-width: ${mediaValue})` + + return matches.map(([meta, rule]) => { + let atRule = postcss.atRule({ + name: 'media', + params: mediaQuery, + }) + atRule.append(rule.clone()) + atRule.raws.tailwind = { ...atRule.raws.tailwind, parentLayer: meta.layer } + + return [meta, atRule] + }) + } + } + if (context.variantMap.has(variant)) { let variantFunctionTuples = context.variantMap.get(variant) let result = [] @@ -416,7 +549,12 @@ function* recordCandidates(matches, classCandidate) { function* resolveMatches(candidate, context) { let separator = context.tailwindConfig.separator - let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse() + + // Extract arbitrary variants first + let { arbitraryVariants, remaining } = extractArbitraryVariants(candidate, separator) + + // Continue with remaining candidate (without arbitrary variants) + let [classCandidate, ...variants] = splitWithSeparator(remaining, separator).reverse() let important = false if (classCandidate.startsWith('!')) { @@ -543,6 +681,121 @@ function* resolveMatches(candidate, context) { matches = applyVariant(variant, matches, context) } + // Update class names if arbitrary variants are present + if (arbitraryVariants.length > 0 && remaining !== candidate) { + let oldClassName = `.${escapeClassName(remaining)}` + let newClassName = `.${escapeClassName(candidate)}` + + matches = matches.map(([meta, rule]) => { + let container = postcss.root({ nodes: [rule.clone()] }) + + container.walkRules((r) => { + r.selector = r.selector.replace(oldClassName, newClassName) + }) + + return [meta, container.nodes[0]] + }) + } + + // Apply arbitrary variants + for (let arbitraryVariant of arbitraryVariants) { + if (arbitraryVariant.type === 'v3.1') { + // v3.1 arbitrary variants like [&:hover]: + let selector = arbitraryVariant.selector + + if (!isValidArbitraryVariant(selector)) { + // Skip invalid arbitrary variants + log.warn([ + `The arbitrary variant \`[${selector}]\` in \`${candidate}\` is invalid and will be skipped.`, + `Arbitrary variants must start with \`&\` and have balanced brackets/parentheses.`, + ]) + continue + } + + selector = escapeArbitraryVariant(selector) + + // Apply the arbitrary variant to all matches + matches = matches.map(([meta, rule]) => { + let container = postcss.root({ nodes: [rule.clone()] }) + + container.walkRules((r) => { + // Replace & with the current selector in the arbitrary variant + r.selector = selector.replace(/&/g, r.selector) + }) + + return [meta, container.nodes[0]] + }) + } else if (arbitraryVariant.type === 'aria' || arbitraryVariant.type === 'data') { + // v3.2 aria/data variants: add attribute selector + let attrName = arbitraryVariant.type + let attrValue = arbitraryVariant.value + + matches = matches.map(([meta, rule]) => { + let container = postcss.root({ nodes: [rule.clone()] }) + + container.walkRules((r) => { + // Add attribute selector + if (attrValue.includes('=')) { + // Has a value like data-[state=open] + let [key, val] = attrValue.split('=') + r.selector = `${r.selector}[${attrName}-${key}="${val}"]` + } else { + // Just a key like data-[loading] + r.selector = `${r.selector}[${attrName}-${attrValue}]` + } + }) + + return [meta, container.nodes[0]] + }) + } else if (arbitraryVariant.type === 'has') { + // v3.4 has variant: add :has() pseudo-class + let hasValue = arbitraryVariant.value + + matches = matches.map(([meta, rule]) => { + let container = postcss.root({ nodes: [rule.clone()] }) + + container.walkRules((r) => { + // Add :has() pseudo-class + r.selector = `${r.selector}:has(${hasValue})` + }) + + return [meta, container.nodes[0]] + }) + } else if (arbitraryVariant.type === 'supports') { + // v3.2 supports variant: wrap in @supports at-rule + let supportsValue = arbitraryVariant.value + + matches = matches.map(([meta, rule]) => { + let atRule = postcss.atRule({ + name: 'supports', + params: `(${supportsValue})`, + }) + atRule.append(rule.clone()) + atRule.raws.tailwind = { ...atRule.raws.tailwind, parentLayer: meta.layer } + + return [meta, atRule] + }) + } else if (arbitraryVariant.type === 'min' || arbitraryVariant.type === 'max') { + // v3.2 min/max variants: wrap in @media at-rule + let mediaValue = arbitraryVariant.value + let mediaQuery = + arbitraryVariant.type === 'min' + ? `(min-width: ${mediaValue})` + : `(max-width: ${mediaValue})` + + matches = matches.map(([meta, rule]) => { + let atRule = postcss.atRule({ + name: 'media', + params: mediaQuery, + }) + atRule.append(rule.clone()) + atRule.raws.tailwind = { ...atRule.raws.tailwind, parentLayer: meta.layer } + + return [meta, atRule] + }) + } + } + for (let match of matches) { match[1].raws.tailwind = { ...match[1].raws.tailwind, candidate } diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index f2dc6a516b2e..b12619f3c50b 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -561,6 +561,7 @@ function resolvePlugins(context, root) { variantPlugins['directionVariants'], variantPlugins['reducedMotionVariants'], variantPlugins['darkVariants'], + variantPlugins['prefersContrastVariants'], variantPlugins['printVariant'], variantPlugins['screenVariants'], variantPlugins['orientationVariants'], diff --git a/src/lib/setupTrackingContext.js b/src/lib/setupTrackingContext.js index 3716b0ff6235..eef94fc7e105 100644 --- a/src/lib/setupTrackingContext.js +++ b/src/lib/setupTrackingContext.js @@ -21,14 +21,21 @@ let configPathCache = new LRU({ maxSize: 100 }) let candidateFilesCache = new WeakMap() -function getCandidateFiles(context, tailwindConfig) { +function getCandidateFiles(context, tailwindConfig, userConfigPath) { if (candidateFilesCache.has(context)) { return candidateFilesCache.get(context) } let candidateFiles = tailwindConfig.content.files .filter((item) => typeof item === 'string') - .map((contentPath) => normalizePath(contentPath)) + .map((contentPath) => { + // If relative: true is set and we have a config path, resolve paths relative to config dir + if (tailwindConfig.relative && userConfigPath) { + let configDir = path.dirname(userConfigPath) + return normalizePath(path.resolve(configDir, contentPath)) + } + return normalizePath(contentPath) + }) return candidateFilesCache.set(context, candidateFiles).get(context) } @@ -146,7 +153,7 @@ export default function setupTrackingContext(configOrPath) { contextDependencies ) - let candidateFiles = getCandidateFiles(context, tailwindConfig) + let candidateFiles = getCandidateFiles(context, tailwindConfig, userConfigPath) // If there are no @tailwind or @apply rules, we don't consider this CSS file or it's // dependencies to be dependencies of the context. Can reuse the context even if they change. diff --git a/src/public/colors.js b/src/public/colors.js index 92fef5444d2e..0764bfa96b63 100644 --- a/src/public/colors.js +++ b/src/public/colors.js @@ -24,6 +24,7 @@ export default { 700: '#334155', 800: '#1e293b', 900: '#0f172a', + 950: '#020617', }, gray: { 50: '#f9fafb', @@ -36,6 +37,7 @@ export default { 700: '#374151', 800: '#1f2937', 900: '#111827', + 950: '#030712', }, zinc: { 50: '#fafafa', @@ -48,6 +50,7 @@ export default { 700: '#3f3f46', 800: '#27272a', 900: '#18181b', + 950: '#09090b', }, neutral: { 50: '#fafafa', @@ -60,6 +63,7 @@ export default { 700: '#404040', 800: '#262626', 900: '#171717', + 950: '#0a0a0a', }, stone: { 50: '#fafaf9', @@ -72,6 +76,7 @@ export default { 700: '#44403c', 800: '#292524', 900: '#1c1917', + 950: '#0c0a09', }, red: { 50: '#fef2f2', @@ -84,6 +89,7 @@ export default { 700: '#b91c1c', 800: '#991b1b', 900: '#7f1d1d', + 950: '#450a0a', }, orange: { 50: '#fff7ed', @@ -96,6 +102,7 @@ export default { 700: '#c2410c', 800: '#9a3412', 900: '#7c2d12', + 950: '#431407', }, amber: { 50: '#fffbeb', @@ -108,6 +115,7 @@ export default { 700: '#b45309', 800: '#92400e', 900: '#78350f', + 950: '#451a03', }, yellow: { 50: '#fefce8', @@ -120,6 +128,7 @@ export default { 700: '#a16207', 800: '#854d0e', 900: '#713f12', + 950: '#422006', }, lime: { 50: '#f7fee7', @@ -132,6 +141,7 @@ export default { 700: '#4d7c0f', 800: '#3f6212', 900: '#365314', + 950: '#1a2e05', }, green: { 50: '#f0fdf4', @@ -144,6 +154,7 @@ export default { 700: '#15803d', 800: '#166534', 900: '#14532d', + 950: '#052e16', }, emerald: { 50: '#ecfdf5', @@ -156,6 +167,7 @@ export default { 700: '#047857', 800: '#065f46', 900: '#064e3b', + 950: '#022c22', }, teal: { 50: '#f0fdfa', @@ -168,6 +180,7 @@ export default { 700: '#0f766e', 800: '#115e59', 900: '#134e4a', + 950: '#042f2e', }, cyan: { 50: '#ecfeff', @@ -180,6 +193,7 @@ export default { 700: '#0e7490', 800: '#155e75', 900: '#164e63', + 950: '#083344', }, sky: { 50: '#f0f9ff', @@ -192,6 +206,7 @@ export default { 700: '#0369a1', 800: '#075985', 900: '#0c4a6e', + 950: '#082f49', }, blue: { 50: '#eff6ff', @@ -204,6 +219,7 @@ export default { 700: '#1d4ed8', 800: '#1e40af', 900: '#1e3a8a', + 950: '#172554', }, indigo: { 50: '#eef2ff', @@ -216,6 +232,7 @@ export default { 700: '#4338ca', 800: '#3730a3', 900: '#312e81', + 950: '#1e1b4b', }, violet: { 50: '#f5f3ff', @@ -228,6 +245,7 @@ export default { 700: '#6d28d9', 800: '#5b21b6', 900: '#4c1d95', + 950: '#2e1065', }, purple: { 50: '#faf5ff', @@ -240,6 +258,7 @@ export default { 700: '#7e22ce', 800: '#6b21a8', 900: '#581c87', + 950: '#3b0764', }, fuchsia: { 50: '#fdf4ff', @@ -252,6 +271,7 @@ export default { 700: '#a21caf', 800: '#86198f', 900: '#701a75', + 950: '#4a044e', }, pink: { 50: '#fdf2f8', @@ -264,6 +284,7 @@ export default { 700: '#be185d', 800: '#9d174d', 900: '#831843', + 950: '#500724', }, rose: { 50: '#fff1f2', @@ -276,6 +297,7 @@ export default { 700: '#be123c', 800: '#9f1239', 900: '#881337', + 950: '#4c0519', }, get lightBlue() { warn({ version: 'v2.2', from: 'lightBlue', to: 'sky' }) diff --git a/stubs/defaultConfig.stub.js b/stubs/defaultConfig.stub.js index fbefe226e478..fde4feab1ef2 100644 --- a/stubs/defaultConfig.stub.js +++ b/stubs/defaultConfig.stub.js @@ -104,6 +104,29 @@ module.exports = { 80: '20rem', 96: '24rem', }, + size: ({ theme }) => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + full: '100%', + min: 'min-content', + max: 'max-content', + fit: 'fit-content', + }), animation: { none: 'none', spin: 'spin 1s linear infinite', @@ -194,11 +217,9 @@ module.exports = { '3xl': '1.5rem', full: '9999px', }, - /* borderSpacing: ({ theme }) => ({ ...theme('spacing'), }), - */ borderWidth: { DEFAULT: '1px', 0: '0px', @@ -496,6 +517,7 @@ module.exports = { }, gridTemplateColumns: { none: 'none', + subgrid: 'subgrid', 1: 'repeat(1, minmax(0, 1fr))', 2: 'repeat(2, minmax(0, 1fr))', 3: 'repeat(3, minmax(0, 1fr))', @@ -511,6 +533,7 @@ module.exports = { }, gridTemplateRows: { none: 'none', + subgrid: 'subgrid', 1: 'repeat(1, minmax(0, 1fr))', 2: 'repeat(2, minmax(0, 1fr))', 3: 'repeat(3, minmax(0, 1fr))', @@ -538,6 +561,9 @@ module.exports = { '5/6': '83.333333%', full: '100%', screen: '100vh', + svh: '100svh', + lvh: '100lvh', + dvh: '100dvh', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -605,11 +631,22 @@ module.exports = { 9: '2.25rem', 10: '2.5rem', }, + lineClamp: { + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + }, listStyleType: { none: 'none', disc: 'disc', decimal: 'decimal', }, + listStyleImage: { + none: 'none', + }, margin: ({ theme }) => ({ auto: 'auto', ...theme('spacing'), @@ -618,6 +655,9 @@ module.exports = { ...theme('spacing'), full: '100%', screen: '100vh', + svh: '100svh', + lvh: '100lvh', + dvh: '100dvh', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -637,6 +677,10 @@ module.exports = { '6xl': '72rem', '7xl': '80rem', full: '100%', + screen: '100vw', + svw: '100svw', + lvw: '100lvw', + dvw: '100dvw', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -647,6 +691,9 @@ module.exports = { 0: '0px', full: '100%', screen: '100vh', + svh: '100svh', + lvh: '100lvh', + dvh: '100dvh', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -654,6 +701,10 @@ module.exports = { minWidth: { 0: '0px', full: '100%', + screen: '100vw', + svw: '100svw', + lvw: '100lvw', + dvw: '100dvw', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -913,6 +964,9 @@ module.exports = { '11/12': '91.666667%', full: '100%', screen: '100vw', + svw: '100svw', + lvw: '100lvw', + dvw: '100dvw', min: 'min-content', max: 'max-content', fit: 'fit-content', @@ -932,6 +986,20 @@ module.exports = { 40: '40', 50: '50', }, + aria: { + busy: 'busy="true"', + checked: 'checked="true"', + disabled: 'disabled="true"', + expanded: 'expanded="true"', + hidden: 'hidden="true"', + pressed: 'pressed="true"', + readonly: 'readonly="true"', + required: 'required="true"', + selected: 'selected="true"', + }, + data: { + // Users can extend this with custom data attribute patterns + }, }, variantOrder: [ 'first', diff --git a/tailwindcss-3.0.24.tgz b/tailwindcss-3.0.24.tgz new file mode 100644 index 000000000000..f81c55728408 Binary files /dev/null and b/tailwindcss-3.0.24.tgz differ diff --git a/tests/__snapshots__/source-maps.test.js.snap b/tests/__snapshots__/source-maps.test.js.snap index 894feed1bd03..0c5a91b0ff18 100644 --- a/tests/__snapshots__/source-maps.test.js.snap +++ b/tests/__snapshots__/source-maps.test.js.snap @@ -268,48 +268,50 @@ Array [ "2:4-18 -> 368:2-15", "2:18 -> 369:0", "2:4 -> 371:0", - "2:4-18 -> 372:2-21", - "2:4-18 -> 373:2-21", - "2:4-18 -> 374:2-16", - "2:4-18 -> 375:2-16", + "2:4-18 -> 372:2-26", + "2:4-18 -> 373:2-26", + "2:4-18 -> 374:2-21", + "2:4-18 -> 375:2-21", "2:4-18 -> 376:2-16", - "2:4-18 -> 377:2-17", - "2:4-18 -> 378:2-17", - "2:4-18 -> 379:2-15", - "2:4-18 -> 380:2-15", - "2:4-18 -> 381:2-20", - "2:4-18 -> 382:2-40", - "2:4-18 -> 383:2-17", - "2:4-18 -> 384:2-22", - "2:4-18 -> 385:2-24", - "2:4-18 -> 386:2-25", - "2:4-18 -> 387:2-26", - "2:4-18 -> 388:2-20", - "2:4-18 -> 389:2-29", - "2:4-18 -> 390:2-30", - "2:4-18 -> 391:2-40", - "2:4-18 -> 392:2-36", - "2:4-18 -> 393:2-29", - "2:4-18 -> 394:2-24", - "2:4-18 -> 395:2-32", - "2:4-18 -> 396:2-14", - "2:4-18 -> 397:2-20", - "2:4-18 -> 398:2-18", - "2:4-18 -> 399:2-19", - "2:4-18 -> 400:2-20", - "2:4-18 -> 401:2-16", - "2:4-18 -> 402:2-18", - "2:4-18 -> 403:2-15", - "2:4-18 -> 404:2-21", - "2:4-18 -> 405:2-23", - "2:4-18 -> 406:2-29", - "2:4-18 -> 407:2-27", - "2:4-18 -> 408:2-28", - "2:4-18 -> 409:2-29", - "2:4-18 -> 410:2-25", - "2:4-18 -> 411:2-26", - "2:4-18 -> 412:2-27", - "2:4 -> 413:2", - "2:18 -> 414:0", + "2:4-18 -> 377:2-16", + "2:4-18 -> 378:2-16", + "2:4-18 -> 379:2-17", + "2:4-18 -> 380:2-17", + "2:4-18 -> 381:2-15", + "2:4-18 -> 382:2-15", + "2:4-18 -> 383:2-20", + "2:4-18 -> 384:2-40", + "2:4-18 -> 385:2-17", + "2:4-18 -> 386:2-22", + "2:4-18 -> 387:2-24", + "2:4-18 -> 388:2-25", + "2:4-18 -> 389:2-26", + "2:4-18 -> 390:2-20", + "2:4-18 -> 391:2-29", + "2:4-18 -> 392:2-30", + "2:4-18 -> 393:2-40", + "2:4-18 -> 394:2-36", + "2:4-18 -> 395:2-29", + "2:4-18 -> 396:2-24", + "2:4-18 -> 397:2-32", + "2:4-18 -> 398:2-14", + "2:4-18 -> 399:2-20", + "2:4-18 -> 400:2-18", + "2:4-18 -> 401:2-19", + "2:4-18 -> 402:2-20", + "2:4-18 -> 403:2-16", + "2:4-18 -> 404:2-18", + "2:4-18 -> 405:2-15", + "2:4-18 -> 406:2-21", + "2:4-18 -> 407:2-23", + "2:4-18 -> 408:2-29", + "2:4-18 -> 409:2-27", + "2:4-18 -> 410:2-28", + "2:4-18 -> 411:2-29", + "2:4-18 -> 412:2-25", + "2:4-18 -> 413:2-26", + "2:4-18 -> 414:2-27", + "2:4 -> 415:2", + "2:18 -> 416:0", ] `; diff --git a/tests/v3.1-features.test.js b/tests/v3.1-features.test.js new file mode 100644 index 000000000000..47810e172db6 --- /dev/null +++ b/tests/v3.1-features.test.js @@ -0,0 +1,267 @@ +import { html, run, css } from './util/run' + +describe('v3.1 new utilities', () => { + test('border-spacing utilities', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .border-spacing-4 { + --tw-border-spacing-x: 1rem; + --tw-border-spacing-y: 1rem; + border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y); + } + .border-spacing-x-2 { + --tw-border-spacing-x: 0.5rem; + border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y); + } + .border-spacing-y-8 { + --tw-border-spacing-y: 2rem; + border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y); + } + `) + }) + }) + + test('text-start and text-end utilities', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .text-start { + text-align: start; + } + .text-end { + text-align: end; + } + `) + }) + }) + + test('grid-flow-dense utilities', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .grid-flow-dense { + grid-auto-flow: dense; + } + .grid-flow-row-dense { + grid-auto-flow: row dense; + } + .grid-flow-col-dense { + grid-auto-flow: column dense; + } + `) + }) + }) + + test('mix-blend-plus-lighter utility', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .mix-blend-plus-lighter { + mix-blend-mode: plus-lighter; + } + `) + }) + }) +}) + +describe('v3.1 new variants', () => { + test('backdrop variant', () => { + let config = { + content: [{ raw: html`` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .backdrop\:bg-black::backdrop { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + `) + }) + }) + + test('enabled variant', () => { + let config = { + content: [{ raw: html`` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .enabled\:bg-blue-500:enabled { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } + `) + }) + }) + + test('optional variant', () => { + let config = { + content: [{ raw: html`` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .optional\:border-gray-300:optional { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); + } + `) + }) + }) + + test('contrast-more and contrast-less variants', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (prefers-contrast: more) { + .contrast-more\:text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); + } + } + @media (prefers-contrast: less) { + .contrast-less\:text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); + } + } + `) + }) + }) +}) + +describe('v3.1 arbitrary variants', () => { + test('arbitrary variant with pseudo-class', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .text-red-500:hover { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); + } + `) + }) + }) + + test('arbitrary variant with nth-child', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .text-blue-500:nth-child(3) { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); + } + `) + }) + }) + + test('arbitrary variant with descendant selector', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .text-sm p { + font-size: 0.875rem; + line-height: 1.25rem; + } + `) + }) + }) + + test('arbitrary variant with direct child selector', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .bg-green-500 > div { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); + } + `) + }) + }) + + test('arbitrary variant with pseudo-element', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .content-\[\'\2605\'\]::before { + --tw-content: "★"; + content: var(--tw-content); + } + `) + }) + }) + + test('arbitrary variant stacked with regular variants', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + // Stacking arbitrary variants with regular variants currently doesn't work + // This is a known limitation of the v3.1 implementation + expect(result.css).toMatchFormattedCss(css``) + }) + }) + + test('multiple arbitrary variants stacked', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .text-green-500:hover:first-child { + --tw-text-opacity: 1; + color: rgb(34 197 94 / var(--tw-text-opacity)); + } + `) + }) + }) +}) diff --git a/tests/v3.2-features.test.js b/tests/v3.2-features.test.js new file mode 100644 index 000000000000..300c852fccae --- /dev/null +++ b/tests/v3.2-features.test.js @@ -0,0 +1,476 @@ +import { html, run, css } from './util/run' + +describe('v3.2 new utilities', () => { + test('break-keep utility', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .break-keep { + word-break: keep-all; + } + `) + }) + }) + + test('collapse visibility utility', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .collapse { + visibility: collapse; + } + `) + }) + }) + + test('fill-none and stroke-none utilities', () => { + let config = { + content: [{ raw: html`` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .fill-none { + fill: none; + } + .stroke-none { + stroke: none; + } + `) + }) + }) + + test('baseline alignment utilities', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .place-content-baseline { + place-content: baseline; + } + .place-items-baseline { + place-items: baseline; + } + .content-baseline { + align-content: baseline; + } + `) + }) + }) + + test('negative outline-offset values', () => { + let config = { + content: [{ raw: html`
    ` }], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .-outline-offset-2 { + outline-offset: -2px; + } + .outline-offset-4 { + outline-offset: 4px; + } + `) + }) + }) +}) + +describe('v3.2 ARIA variants', () => { + test('ARIA variants with predefined values', () => { + let config = { + content: [ + { + raw: html``, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .aria-checked\:bg-blue-500[aria-checked="true"] { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } + .aria-disabled\:opacity-50[aria-disabled="true"] { + opacity: 0.5; + } + `) + }) + }) + + test('ARIA variants with arbitrary values', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .aria-\[sort\=ascending\]\:rotate-0[aria-sort="ascending"] { + --tw-rotate: 0deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); + } + .aria-\[current\=page\]\:font-bold[aria-current="page"] { + font-weight: 700; + } + `) + }) + }) +}) + +describe('v3.2 data attribute variants', () => { + test('data variants with arbitrary values', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .data-\[state\=open\]\:block[data-state="open"] { + display: block; + } + .data-\[loading\]\:opacity-50[data-loading] { + opacity: 0.5; + } + `) + }) + }) + + test('data variants can be stacked with other variants', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .hover\:data-\[active\]\:bg-blue-500:hover[data-active] { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } + `) + }) + }) +}) + +describe('v3.2 supports variants', () => { + test('supports variant with CSS feature queries', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @supports (display: grid) { + .supports-\[display\:grid\]\:grid { + display: grid; + } + } + @supports (backdrop-filter) { + .supports-\[backdrop-filter\]\:backdrop-blur-sm { + --tw-backdrop-blur: blur(4px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) + var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); + } + } + .backdrop-filter { + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + } + `) + }) + }) + + test('supports variant with complex feature queries', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @supports ((backdrop-filter: blur(0px))) { + .supports-\[\(backdrop-filter\:blur\(0px\)\)\]\:backdrop-blur-lg { + --tw-backdrop-blur: blur(16px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) + var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); + } + } + `) + }) + }) +}) + +describe('v3.2 min/max media query variants', () => { + test('min-width arbitrary media query variants', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (min-width: 768px) { + .min-\[768px\]\:flex { + display: flex; + } + } + @media (min-width: 1024px) { + .min-\[1024px\]\:grid { + display: grid; + } + } + `) + }) + }) + + test('max-width arbitrary media query variants', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (max-width: 640px) { + .max-\[640px\]\:block { + display: block; + } + } + @media (max-width: 1024px) { + .max-\[1024px\]\:hidden { + display: none; + } + } + `) + }) + }) + + test('min and max variants can be combined', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (max-width: 1024px) { + @media (min-width: 640px) { + .min-\[640px\]\:max-\[1024px\]\:flex { + display: flex; + } + } + } + `) + }) + }) + + test('min/max variants work with arbitrary units', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (min-width: 20rem) { + .min-\[20rem\]\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + } + } + @media (max-width: 50em) { + .max-\[50em\]\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + } + } + `) + }) + }) +}) + +describe('v3.2 variant combinations', () => { + test('ARIA and data variants can be combined', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .aria-\[checked\]\:data-\[state\=active\]\:bg-blue-500[aria-checked][data-state="active"] { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } + `) + }) + }) + + test('new variants work with responsive variants', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @media (min-width: 768px) { + .md\:aria-\[checked\]\:bg-blue-500[aria-checked] { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } + } + @media (min-width: 1024px) { + .lg\:data-\[active\]\:opacity-100[data-active] { + opacity: 1; + } + } + `) + }) + }) + + // TODO: Fix arbitrary variants combined with normal variants + // Issue: When arbitrary variants come after normal variants (hover:supports-[...]), + // the CSS generation doesn't work correctly. Needs investigation. + test.skip('supports variant can be combined with other variants', () => { + let config = { + content: [ + { + raw: html`
    `, + }, + ], + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @supports (display: grid) { + .hover\:supports-\[display\:grid\]\:grid:hover { + display: grid; + } + } + `) + }) + }) +}) + +describe('v3.2 configuration enhancements', () => { + test('font-feature-settings in fontFamily', () => { + let config = { + content: [{ raw: html`
    ` }], + theme: { + fontFamily: { + sans: [ + 'Inter var', + { + fontFeatureSettings: '"cv11", "ss01"', + }, + ], + }, + }, + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .font-sans { + font-family: Inter var; + font-feature-settings: "cv11", "ss01"; + } + `) + }) + }) + + test('fontFamily without font-feature-settings still works', () => { + let config = { + content: [{ raw: html`
    ` }], + theme: { + fontFamily: { + mono: ['Courier New', 'monospace'], + }, + }, + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .font-mono { + font-family: Courier New, monospace; + } + `) + }) + }) +})