Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Config from tailwind.config.js #4

Open
DawidMazur opened this issue Jul 9, 2023 · 8 comments
Open

Config from tailwind.config.js #4

DawidMazur opened this issue Jul 9, 2023 · 8 comments

Comments

@DawidMazur
Copy link

Hi,
Is it possible to add an option to import Tailwind configuration from a JavaScript configuration file?

@DawidMazur
Copy link
Author

I think that would solve the problem with unknown types in classes. I use numerical values for font sizes in my projects, for example, text-20, and when combined with a color like text-primary, it removes the first occurrence of text.

"text-20 text-primary" => "text-primary"

@gehrisandro
Copy link
Owner

@DawidMazur Thanks for your question.

This is already on my todo list.

@gehrisandro
Copy link
Owner

@DawidMazur Could you provide your tailwind.config.js or at least the relevant parts?

@DawidMazur
Copy link
Author


let themeSettings = [];
function getThemeSettings() {
  if(themeSettings.length == 0) {
    themeSettings = require('./theme/settings.json');
  }

  return themeSettings;
}


// colors

function prepareObject(obj, prefix, func, newObj = {}) {
  for(let key in obj) {
    if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
      newObj[key] = prepareObject(obj[key], prefix + key + '-', func, newObj[key]);
    } else {
      newObj[key] = func(prefix, key, obj[key]);
    }
  }
  return newObj;
}

function loadColors() {
  let { colors } = getThemeSettings();
  let r = prepareObject(colors, '', (prefix, key, value) => {
    return ColorOpacity(`${prefix}${key}`)
  })
  return r;
}

function loadSpacing() {
  let { spacing } = getThemeSettings();
  let r = prepareObject(spacing, '', (prefix, key, value) => {
    return `var(--pc-s-${prefix}${key});`
  })
  return r;
}

function loadShadows() {
  let { shadows } = getThemeSettings();
  let r = prepareObject(shadows, '', (prefix, key, value) => {
    return `var(--pc-shadow-${prefix}${key});`
  })
  return r;
}

function loadRounded() {
  let { rounded } = getThemeSettings();
  let r = prepareObject(rounded, '', (prefix, key, value) => {
    return `var(--pc-r-${prefix}${key});`
  })
  return r;
}

function ColorOpacity(name) {
  return ({
    opacityValue
  }) => {
    if (opacityValue != undefined) {
      return `rgba(var(--pc-c-${name}), ${opacityValue})`
    }
    return `rgb(var(--pc-c-${name}))`
  }
}

// sizes
function getPx(min = 0, max = 50, move = 1) {
  let r = {}

  for (let i = min; i <= max; i = i + move) {
    r[i] = (i / 10) + 'px'
  }

  return r;
}

function pxToRem(max = 200) {
  let r = {}

  for (let i = 0; i < 20; i++) {
    r[i] = (i / 10) + 'rem'
  }

  for (let i = 20; i < 70; i = i + 2) {
    r[i] = (i / 10) + 'rem'
  }

  for (let i = 0; i < 150; i = i + 5) {
    r[i] = (i / 10) + 'rem'
  }

  for (let i = 150; i <= max; i = i + 10) {
    r[i] = (i / 10) + 'rem'
  }

  return r
}

function getUnitList(unit, prefix = "", ratio = 1, min = 10, max = 100, move = 10) {
  let r = {}

  for (let i = min; i <= max; i = i + move) {
    r[i + prefix] = (i / ratio) + unit
  }

  return r;
}

// font sizes
function genFontSize(radio) {
  let r = {}
  let ratioSizeLineHeight = 30 / 18
  let ratios = radio ? radio : {
    0: ratioSizeLineHeight,
    30: 40/30,
    40: 1.3,
    54: 58 / 54,
    60: 1,
  }
  for (let i = 1; i <= 120; i++) {
    if (ratios[i]) {
      ratioSizeLineHeight = ratios[i];
    }
    r[i] = [
      (i / 10) + 'rem',
      {
        lineHeight: Math.round((i / 10) * ratioSizeLineHeight * 10) / 10 + 'rem',
      }
    ]
  }
  return r;
}

/** @type {import('tailwindcss').Config} */
module.exports = {
  mode: 'jit',
  content: [
    '!./node_modules/**/*',
    './**/*.twig',
    // './*.php',
    './**/*.php',
    './**/*.html',
    './src/js/global/**/*.js',
    './views/**/*.js'
    // './src/**/*.scss',
    // './**/*.css',
  ],
  corePlugins: {
    fontFamily: false,
    container: false,
    aspectRatio: false,
  },
  theme: {
    colors: {
      white: '#fff',
      black: '#000',
      transparent: 'transparent',
      current: 'currentColor',

      ...loadColors(),
    },

    screens: {
      'sm': '360px',
      'md': '600px',
      'lg': '991px',
      'slap': '1280px',
      'mlap': '1356px',
      'llap': '1536px',
      'full': '1920px',
    },

    blur: {
      ...getPx(),
      DEFAULT: '8px',
    },

    borderRadius: {
      none: '0px',
      DEFAULT: '0.25rem',
      ...pxToRem(),
      '50p': '50%',
      full: '9999px',
      ...loadRounded(),
    },

    borderWidth: {
      DEFAULT: '1px',
      0: '0px',
      2: '2px',
      4: '4px',
      8: '8px',
    },

    spacing: {
      ...pxToRem(500),
      ...loadSpacing(),
    },

    fontFamily: {
      'TitilliumWeb': ['Titillium Web', 'ui-sans-serif'],
      'Montserrat': ['Montserrat', 'ui-sans-serif'],
    },

    fontSize: genFontSize(),

    fontWeight: {
      100: '100',
      200: '200',
      300: '300',
      400: '400',
      500: '500',
      600: '600',
      700: '700',
      800: '800',
      900: '900',
    },

    lineHeight: {
      none: '1',
      tight: '1.25',
      snug: '1.375',
      normal: '1.5',
      relaxed: '1.625',
      loose: '2',
      ...pxToRem()
    },

    maxWidth: (theme, {
      breakpoints
    }) => ({
      none: 'none',
      ...pxToRem(2000),
      ...getUnitList('vw', 'vw'),
      full: '100%',
      min: 'min-content',
      max: 'max-content',
      screen: '100vw',
      prose: '65ch',
      ...breakpoints(theme('screens')),
    }),

    maxHeight: (theme, {
      breakpoints
    }) => ({
      none: 'none',
      ...pxToRem(2000),
      ...getUnitList('vh', 'vh'),
      full: '100%',
      min: 'min-content',
      max: 'max-content',
      prose: '65ch',
      ...breakpoints(theme('screens')),
    }),

    minWidth: theme => theme('maxWidth'),

    minHeight: theme => theme('maxHeight'),

    // poprawka dla vscode
    borderColor: theme => ({
      DEFAULT: '#000',
      ...theme('colors'),
    }),

    ringColor: theme => ({
      DEFAULT: 'blue',
      ...theme('colors'),
    }),

    extend: {
      zIndex: {
        '-2': '-2',
        '-1': '-1',
        0: '0',
        5: '5',
        1000: '1000',
        1010: '1010',
        1020: '1020',
        1030: '1030',
        1040: '1040',
        1050: '1050',
        1060: '1060',
        1070: '1070',
        1080: '1080',
        1090: '1090',
      },

      flex: {
        '2': '2 2 0%',
        '3': '3 3 0%',
        '4': '4 4 0%',
        '5': '5 5 0%',
        '6': '6 6 0%',
        '7': '7 7 0%',
        '8': '8 8 0%',
        '9': '9 9 0%',
        '10': '10 10 0%',
        '11': '11 11 0%',
        '12': '12 12 0%',
      },

      width: {
        ...getUnitList('vw', 'vw')
      },

      height: {
        ...getUnitList('vh', 'vh')
      },

      padding: {
        ...getUnitList('vw', 'vw'),
        ...getUnitList('vh', 'vh')
      },

      typography: theme => ({
        DEFAULT: {
          css: {
            color: null,
            fontSize: null,
            lineHeight: null,
            maxWidth: null,
            a: {
              color: theme('colors.primary'),
            },
            strong: {
              color: null,
            }
          }
        }
      }),
      boxShadow: {
        std: '0 0 5rem rgba(0,0,0,1)',
        img: '0 0 3rem rgba(0, 181, 238, 0.21)',
        gallery: '0 0 2rem rgba(0, 181, 238, 0.57)',
        tabs: '0 0.3rem 9.9rem rgba(217, 228, 231, 1)',
        order: '0 0.3rem 9.9rem rgba(217, 228, 231, 1)',
        ...loadShadows(),
      },
      animation: {
        pulsing: 'pulsing 5s ease-in-out infinite',
      },
      keyframes: {
        'pulsing': {
          '0%': { transform: 'scale(.9)' },
          '70%': { transform: 'scale(1)' },
          '100%': { transform: 'scale(.9)' },
        },
      }
    },
  },
  variants: {
    extend: {
      lineClamp: {
        7: '7',
        8: '8',
        9: '9',
        10: '10',
      }
    },
    container: [],
  },
  plugins: [
    require('@tailwindcss/typography')({
      modifiers: [],
    }),
    // require('@tailwindcss/aspect-ratio'),
    // require('@tailwindcss/line-clamp'),
    ({ matchUtilities, theme /* … */ }) => {
      // …
      matchUtilities(
        // https://gist.github.com/olets/9b833a33d01384eed1e9f1e106003a3b
        {
          'aspect': (value) => ({
            '@supports (aspect-ratio: 1 / 1)': {
              aspectRatio: value,
            },
            '@supports not (aspect-ratio: 1 / 1)': {
              // https://github.com/takamoso/postcss-aspect-ratio-polyfill

              '&::before': {
                content: '""',
                float: 'left',
                paddingTop: `calc(100% / (${value}))`,
              },
              '&::after': {
                clear: 'left',
                content: '""',
                display: 'block',
              }
            },
          }),
        },
        { values: theme('aspectRatio') }
      )
    },
  ],
}

@KawanSoares
Copy link

Same issue here, Im using with tailpress, so I have a font size config like this:

theme.extend.fontSize: [
  "subtitle": [
    "1rem",
    {
      "lineHeight": "129%",
      "fontWeight": "600"
    }
  ]
]

My results:

"text-white text-subtitle" = "text-subtitle"
OR
"text-subtitle text-white" = " text-white"

@gehrisandro
Copy link
Owner

Hi @KawanSoares

You could already achieve this by manually configure TwMerge.

TailwindMerge::factory()->withConfiguration([
        'classGroups' => [
            'font-size' => [
                ['text' => ['subtitle']]
            ],
        ],
    ])->make()

Auto configure from tailwind.config.js is not required for that, but would be a nice improvement.

Additionally I need to add the documentation for the configuration.

@KawanSoares
Copy link

KawanSoares commented Sep 9, 2023

Hi guys, me again 👍

Thanks for reply @gehrisandro, that was just one example, I have many more font sizes 😆, so I did use of this @vendeka/tailwind-config-php to create a tailwind.config.php and following your tip I did this code:

$tw = TailwindMerge::factory()->withConfiguration([
  'classGroups' => [
      'font-size' => [
        ['text' => array_keys((array)$tailwindConfig->theme->fontSize)]
      ],
      'text-color' => [
        ['text' => array_keys((array)$tailwindConfig->theme->colors)]
      ],
    ],
])->make();

It worked! 😆

@gehrisandro
Copy link
Owner

Hi @KawanSoares

Thank you very much for your reply. I have definitively to check this one. Maybe it will help us to automate this more easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants