benface / tailwindcss-typography

Tailwind CSS plugin to generate typography utilities and text style components
ISC License
244 stars 5 forks source link

Fluid font sizes #21

Open zizther opened 4 years ago

zizther commented 4 years ago

It would be great to support fluid font sizes along with the rest of the offerings this plugin has.

My thinking is it would work similarly to https://github.com/bradlc/tailwindcss-fluid.

dan2k3k4 commented 4 years ago

I made a local copy of this plugin but stripped it down to just textStyles as I wanted to override base styles for h1, h2, p etc

This is what I have in my tailwind.config.js file:

const typography = require('./tailwind-local-typography');

// ------------------------------------------------
//... in module.exports.theme.extend: {
      textStyles: theme => ({
        heading: {
          output: false,
          fontWeight: theme('fontWeight.bold'),
          lineHeight: theme('lineHeight.tight'),
        },
        'h1': {
          extends: 'heading',
          fontSize: theme('fontSize.5xl'),
          fontWeight: theme('fontWeight.black'),
          '@screen sm': {
            fontSize: theme('fontSize.6xl'),
          },
          fontFamily: theme('fontFamily.serif'),
          textTransform: 'uppercase',
        },
      }),

// ------------------------------------------------
// ... then add typography plugin, you could just require here instead:
plugins: [
    typography,
],

This is the content of the tailwind-local-typography.js file, it's stripped down and I remove the . so that I match on h1 instead of .h1 and use addBase instead of addComponents.

const plugin = require('tailwindcss/plugin');
const _ = require('lodash');

const defaultOptions = {};

const camelCaseToKebabCase = function(string) {
  return string
    .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
    .replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2')
    .toLowerCase();
};

module.exports = plugin.withOptions(function(options = {}) {
  return function({ theme, e, addBase }) {
    options = _.defaults({}, options, defaultOptions);

    const textStylesTheme = theme('textStyles');

    const resolveTextStyle = function(name, styles, topLevel = false) {
      if (_.isPlainObject(styles)) {
        const resolvedStyles = _.reduce(styles, function(result, value, key) {
          if (key === 'extends') {
            _.forEach(_.castArray(value), function(textStyleToExtend) {
              _.forEach(resolveTextStyle(textStyleToExtend, textStylesTheme[textStyleToExtend], true), function(extendedValue, extendedKey) {
                if (extendedKey === 'output') {
                  return; // continue
                }
                result = {
                  ...result,
                  ...resolveTextStyle(extendedKey, extendedValue),
                };
              });
            });
            return result;
          }
          return {
            ...result,
            ...resolveTextStyle(key, value),
          };
        }, {});

        if (topLevel) {
          return resolvedStyles;
        }

        return {
          [name]: resolvedStyles,
        };
      }

      if (_.isArray(styles)) {
        if (name === 'fontSize' && styles.length === 2) {
          return {
            fontSize: styles[0],
            lineHeight: styles[1],
          };
        }
        return {
          [name]: styles.join(', '),
        };
      }

      return {
        [name]: styles,
      };
    };

    const textStyles = _.fromPairs(
      _.map(textStylesTheme, (componentStyles, componentName) => {
        componentStyles = resolveTextStyle(componentName, componentStyles, true);
        if (componentStyles.output === false) {
          return [];
        }
        return [
          `${e(`${camelCaseToKebabCase(componentName)}`)}`,
          componentStyles,
        ];
      })
    );

    addBase(textStyles);
  };
}, function() {
  return {
    theme: {
      textStyles: {},
    }
  };
});
dan2k3k4 commented 4 years ago

Ah I just read through what bradlc/tailwindcss-fluid does... so my solution above is only about being able to change base styles 🙈 my bad 😄, but hopefully it helps someone out there...