shadcn-ui / ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.
https://ui.shadcn.com
MIT License
75.11k stars 4.69k forks source link

[bug]: CLI can't parse existing tailwind.config.ts and messes up while running "add" command #5860

Open kunalshah opened 5 days ago

kunalshah commented 5 days ago

Describe the bug

In my project, I use shadcn ui components and tremor components. I installed shadcn ui components first and then configured tremor components (https://tremor.so/docs/getting-started/installation/next)

Both of these component libraries require the tailwind.config.ts to be modified.

So, I have current tailwind.config.ts like this:

import type { Config } from 'tailwindcss'
import colors from 'tailwindcss/colors'

const config: Config = {
  darkMode: ['class'],
  content: [
    './src/**/*.{js,ts,jsx,tsx,mdx}',

    // Path to Tremor module
    './node_modules/@tremor/**/*.{js,ts,jsx,tsx}'
  ],
  theme: {
    transparent: 'transparent',
    current: 'currentColor',
    extend: {
        backgroundImage: {
            'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
            'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
        },
        boxShadow: {
            'tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
            'tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
            'tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
            'dark-tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
            'dark-tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
            'dark-tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)'
        },
        borderRadius: {
            lg: 'var(--radius)',
            md: 'calc(var(--radius) - 2px)',
            sm: 'calc(var(--radius) - 4px)',
            'tremor-small': '0.375rem',
            'tremor-default': '0.5rem',
            'tremor-full': '9999px'
        },
        fontSize: {
            'tremor-label': ['0.75rem', { lineHeight: '1rem' }],
            'tremor-default': ['0.875rem', { lineHeight: '1.25rem' }],
            'tremor-title': ['1.125rem', { lineHeight: '1.75rem' }],
            'tremor-metric': ['1.875rem', { lineHeight: '2.25rem' }]
        },
        colors: {
            tremor: {
                brand: {
                    faint: 'colors.blue[50],
                    muted: 'colors.blue[200],
                    subtle: 'colors.blue[400],
                    DEFAULT: 'colors.blue[500],
                    emphasis: 'colors.blue[700],
                    inverted: 'colors.white'
                },
                background: {
                    muted: 'colors.gray[50],
                    subtle: 'colors.gray[100],
                    DEFAULT: 'colors.white',
                    emphasis: 'colors.gray[700]
                },
                border: {
                    DEFAULT: 'colors.gray[200]
                },
                ring: {
                    DEFAULT: 'colors.gray[200]
                },
                content: {
                    subtle: 'colors.gray[400],
                    DEFAULT: 'colors.gray[500],
                    emphasis: 'colors.gray[700],
                    strong: 'colors.gray[900],
                    inverted: 'colors.white'
                }
            },
            'dark-tremor': {
                brand: {
                    faint: '#0B1229',
                    muted: 'colors.blue[950],
                    subtle: 'colors.blue[800],
                    DEFAULT: 'colors.blue[500],
                    emphasis: 'colors.blue[400],
                    inverted: 'colors.blue[950]
                },
                background: {
                    muted: '#131A2B',
                    subtle: 'colors.gray[800],
                    DEFAULT: 'colors.gray[900],
                    emphasis: 'colors.gray[300]
                },
                border: {
                    DEFAULT: 'colors.gray[800]
                },
                ring: {
                    DEFAULT: 'colors.gray[800]
                },
                content: {
                    subtle: 'colors.gray[600],
                    DEFAULT: 'colors.gray[500],
                    emphasis: 'colors.gray[200],
                    strong: 'colors.gray[50],
                    inverted: 'colors.gray[950]
                }
            },
            background: 'hsl(var(--background))',
            foreground: 'hsl(var(--foreground))',
            card: {
                DEFAULT: 'hsl(var(--card))',
                foreground: 'hsl(var(--card-foreground))'
            },
            popover: {
                DEFAULT: 'hsl(var(--popover))',
                foreground: 'hsl(var(--popover-foreground))'
            },
            primary: {
                DEFAULT: 'hsl(var(--primary))',
                foreground: 'hsl(var(--primary-foreground))'
            },
            secondary: {
                DEFAULT: 'hsl(var(--secondary))',
                foreground: 'hsl(var(--secondary-foreground))'
            },
            muted: {
                DEFAULT: 'hsl(var(--muted))',
                foreground: 'hsl(var(--muted-foreground))'
            },
            accent: {
                DEFAULT: 'hsl(var(--accent))',
                foreground: 'hsl(var(--accent-foreground))'
            },
            destructive: {
                DEFAULT: 'hsl(var(--destructive))',
                foreground: 'hsl(var(--destructive-foreground))'
            },
            border: 'hsl(var(--border))',
            input: 'hsl(var(--input))',
            ring: 'hsl(var(--ring))',
            chart: {
                '1': 'hsl(var(--chart-1))',
                '2': 'hsl(var(--chart-2))',
                '3': 'hsl(var(--chart-3))',
                '4': 'hsl(var(--chart-4))',
                '5': 'hsl(var(--chart-5))'
            },
            sidebar: {
                DEFAULT: 'hsl(var(--sidebar-background))',
                foreground: 'hsl(var(--sidebar-foreground))',
                primary: 'hsl(var(--sidebar-primary))',
                'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
                accent: 'hsl(var(--sidebar-accent))',
                'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
                border: 'hsl(var(--sidebar-border))',
                ring: 'hsl(var(--sidebar-ring))'
            },
            'color-1': 'hsl(var(--color-1))',
            'color-2': 'hsl(var(--color-2))',
            'color-3': 'hsl(var(--color-3))',
            'color-4': 'hsl(var(--color-4))',
            'color-5': 'hsl(var(--color-5))'
        },
        keyframes: {
            hide: {
                from: {
                    opacity: '1'
                },
                to: {
                    opacity: '0'
                }
            },
            slideDownAndFade: {
                from: {
                    opacity: '0',
                    transform: 'translateY(-6px)'
                },
                to: {
                    opacity: '1',
                    transform: 'translateY(0)'
                }
            },
            slideLeftAndFade: {
                from: {
                    opacity: '0',
                    transform: 'translateX(6px)'
                },
                to: {
                    opacity: '1',
                    transform: 'translateX(0)'
                }
            },
            slideUpAndFade: {
                from: {
                    opacity: '0',
                    transform: 'translateY(6px)'
                },
                to: {
                    opacity: '1',
                    transform: 'translateY(0)'
                }
            },
            slideRightAndFade: {
                from: {
                    opacity: '0',
                    transform: 'translateX(-6px)'
                },
                to: {
                    opacity: '1',
                    transform: 'translateX(0)'
                }
            },
            accordionOpen: {
                from: {
                    height: '0px'
                },
                to: {
                    height: 'var(--radix-accordion-content-height)'
                }
            },
            accordionClose: {
                from: {
                    height: 'var(--radix-accordion-content-height)'
                },
                to: {
                    height: '0px'
                }
            },
            dialogOverlayShow: {
                from: {
                    opacity: '0'
                },
                to: {
                    opacity: '1'
                }
            },
            dialogContentShow: {
                from: {
                    opacity: '0',
                    transform: 'translate(-50%, -45%) scale(0.95)'
                },
                to: {
                    opacity: '1',
                    transform: 'translate(-50%, -50%) scale(1)'
                }
            },
            drawerSlideLeftAndFade: {
                from: {
                    opacity: '0',
                    transform: 'translateX(100%)'
                },
                to: {
                    opacity: '1',
                    transform: 'translateX(0)'
                }
            },
            drawerSlideRightAndFade: {
                from: {
                    opacity: '1',
                    transform: 'translateX(0)'
                },
                to: {
                    opacity: '0',
                    transform: 'translateX(100%)'
                }
            },
            'accordion-down': {
                from: {
                    height: '0'
                },
                to: {
                    height: 'var(--radix-accordion-content-height)'
                }
            },
            'accordion-up': {
                from: {
                    height: 'var(--radix-accordion-content-height)'
                },
                to: {
                    height: '0'
                }
            },
            marquee: {
                from: {
                    transform: 'translateX(0)'
                },
                to: {
                    transform: 'translateX(calc(-100% - var(--gap)))'
                }
            },
            'marquee-vertical': {
                from: {
                    transform: 'translateY(0)'
                },
                to: {
                    transform: 'translateY(calc(-100% - var(--gap)))'
                }
            },
            orbit: {
                '0%': {
                    transform: 'rotate(0deg) translateY(calc(var(--radius) * 1px)) rotate(0deg)'
                },
                '100%': {
                    transform: 'rotate(360deg) translateY(calc(var(--radius) * 1px)) rotate(-360deg)'
                }
            },
            'border-beam': {
                '100%': {
                    'offset-distance': '100%'
                }
            },
            shine: {
                '0%': {
                    'background-position': '0% 0%'
                },
                '50%': {
                    'background-position': '100% 100%'
                },
                to: {
                    'background-position': '0% 0%'
                }
            },
            meteor: {
                '0%': {
                    transform: 'rotate(215deg) translateX(0)',
                    opacity: '1'
                },
                '70%': {
                    opacity: '1'
                },
                '100%': {
                    transform: 'rotate(215deg) translateX(-500px)',
                    opacity: '0'
                }
            },
            'background-position-spin': {
                '0%': {
                    backgroundPosition: 'top center'
                },
                '100%': {
                    backgroundPosition: 'bottom center'
                }
            },
            'shiny-text': {
                '0%, 90%, 100%': {
                    'background-position': 'calc(-100% - var(--shiny-width)) 0'
                },
                '30%, 60%': {
                    'background-position': 'calc(100% + var(--shiny-width)) 0'
                }
            },
            gradient: {
                to: {
                    backgroundPosition: 'var(--bg-size) 0'
                }
            },
            rainbow: {
                '0%': {
                    'background-position': '0%'
                },
                '100%': {
                    'background-position': '200%'
                }
            },
            'shimmer-slide': {
                to: {
                    transform: 'translate(calc(100cqw - 100%), 0)'
                }
            },
            'spin-around': {
                '0%': {
                    transform: 'translateZ(0) rotate(0)'
                },
                '15%, 35%': {
                    transform: 'translateZ(0) rotate(90deg)'
                },
                '65%, 85%': {
                    transform: 'translateZ(0) rotate(270deg)'
                },
                '100%': {
                    transform: 'translateZ(0) rotate(360deg)'
                }
            },
            pulse: {
                '0%, 100%': {
                    boxShadow: '0 0 0 0 var(--pulse-color)'
                },
                '50%': {
                    boxShadow: '0 0 0 8px var(--pulse-color)'
                }
            },
            grid: {
                '0%': {
                    transform: 'translateY(-50%)'
                },
                '100%': {
                    transform: 'translateY(0)'
                }
            },
            ripple: {
                '0%, 100%': {
                    transform: 'translate(-50%, -50%) scale(1)'
                },
                '50%': {
                    transform: 'translate(-50%, -50%) scale(0.9)'
                }
            }
        },
        animation: {
            hide: 'hide 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            slideDownAndFade: 'slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            slideLeftAndFade: 'slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            slideUpAndFade: 'slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            slideRightAndFade: 'slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            accordionOpen: 'accordionOpen 150ms cubic-bezier(0.87, 0, 0.13, 1)',
            accordionClose: 'accordionClose 150ms cubic-bezier(0.87, 0, 0.13, 1)',
            dialogOverlayShow: 'dialogOverlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            dialogContentShow: 'dialogContentShow 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            drawerSlideLeftAndFade: 'drawerSlideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)',
            drawerSlideRightAndFade: 'drawerSlideRightAndFade 150ms ease-in',
            'accordion-down': 'accordion-down 0.2s ease-out',
            'accordion-up': 'accordion-up 0.2s ease-out',
            marquee: 'marquee var(--duration) infinite linear',
            'marquee-vertical': 'marquee-vertical var(--duration) linear infinite',
            orbit: 'orbit calc(var(--duration)*1s) linear infinite',
            'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear',
            shine: 'shine var(--duration) infinite linear',
            meteor: 'meteor 5s linear infinite',
            'background-position-spin': 'background-position-spin 3000ms infinite alternate',
            'shiny-text': 'shiny-text 8s infinite',
            gradient: 'gradient 8s linear infinite',
            rainbow: 'rainbow var(--speed, 2s) infinite linear',
            'shimmer-slide': 'shimmer-slide var(--speed) ease-in-out infinite alternate',
            'spin-around': 'spin-around calc(var(--speed) * 2) infinite linear',
            pulse: 'pulse var(--duration) ease-out infinite',
            grid: 'grid 15s linear infinite',
            ripple: 'ripple var(--duration,2s) ease calc(var(--i, 0)*.2s) infinite'
        }
    }
  },
  safelist: [
    {
      pattern:
        /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
      variants: ['hover', 'ui-selected']
    },
    {
      pattern:
        /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
      variants: ['hover', 'ui-selected']
    },
    {
      pattern:
        /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
      variants: ['hover', 'ui-selected']
    },
    {
      pattern:
        /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/
    },
    {
      pattern:
        /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/
    },
    {
      pattern:
        /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/
    }
  ],
  corePlugins: {
    aspectRatio: false
  },
  plugins: [
    require('./src/generated/js/tailwindcss-extend.mjs'),
    require('preline/plugin'),
    require('tailwindcss-animate'),
    require('tailwindcss-motion'),
    require('@tailwindcss/aspect-ratio'),
    require('@tailwindcss/container-queries'),
    require('@tailwindcss/forms'),
<img width="1726" alt="Screenshot 2024-11-17 at 18 45 25" src="https://github.com/user-attachments/assets/2eddd36b-d6e4-4df5-ad08-d09112160c7e">

    require('@tailwindcss/typography'),
    require('@headlessui/tailwindcss')
  ]
}

export default config

This file has no issues and works fine.

However, when I want to upgrade shadcn ui components with the command "npx shadcn@latest add -a -y -o", it cannot parse existing tailwind.config.ts and messes up the file.

See the attached screenshot.

Affected component/components

All

How to reproduce

  1. Install all shadcn components with "npx shadcn@latest add -a -y -o"
  2. Install tremor components. Instructions: https://tremor.so/docs/getting-started/installation/next
  3. Run "npx shadcn@latest add -a -y -o" again

Codesandbox/StackBlitz link

No response

Logs

No response

System Info

MacOS

Before submitting

kunalshah commented 4 days ago
Screenshot 2024-11-17 at 18 45 25