diff --git a/__tests__/applyAtRule.test.js b/__tests__/applyAtRule.test.js index 4c415714b..410317402 100644 --- a/__tests__/applyAtRule.test.js +++ b/__tests__/applyAtRule.test.js @@ -1,12 +1,15 @@ import postcss from 'postcss' -import plugin from '../src/lib/substituteClassApplyAtRules' -import generateUtilities from '../src/util/generateUtilities' +import substituteClassApplyAtRules from '../src/lib/substituteClassApplyAtRules' +import processPlugins from '../src/util/processPlugins' +import defaultPlugins from '../src/defaultPlugins' import defaultConfig from '../defaultConfig.stub.js' -const defaultUtilities = generateUtilities(defaultConfig, []) +const { utilities: defaultUtilities } = processPlugins(defaultPlugins(defaultConfig), defaultConfig) function run(input, config = defaultConfig, utilities = defaultUtilities) { - return postcss([plugin(config, utilities)]).process(input, { from: undefined }) + return postcss([substituteClassApplyAtRules(config, utilities)]).process(input, { + from: undefined, + }) } test("it copies a class's declarations into itself", () => { @@ -206,10 +209,12 @@ test('you can apply utility classes without using the given prefix', () => { experiments: { shadowLookup: true }, } - return run(input, config, generateUtilities(config, [])).then(result => { - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) - }) + return run(input, config, processPlugins(defaultPlugins(defaultConfig), config).utilities).then( + result => { + expect(result.css).toEqual(expected) + expect(result.warnings().length).toBe(0) + } + ) }) test('you can apply utility classes without using the given prefix when using a function for the prefix', () => { @@ -232,8 +237,10 @@ test('you can apply utility classes without using the given prefix when using a experiments: { shadowLookup: true }, } - return run(input, config, generateUtilities(config, [])).then(result => { - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) - }) + return run(input, config, processPlugins(defaultPlugins(defaultConfig), config).utilities).then( + result => { + expect(result.css).toEqual(expected) + expect(result.warnings().length).toBe(0) + } + ) }) diff --git a/__tests__/containerPlugin.test.js b/__tests__/containerPlugin.test.js index 04cb3dba9..9b0612e83 100644 --- a/__tests__/containerPlugin.test.js +++ b/__tests__/containerPlugin.test.js @@ -7,28 +7,24 @@ function css(nodes) { return postcss.root({ nodes }).toString() } -function processPluginsWithValidConfig(config) { - return processPlugins( - _.defaultsDeep(config, { - screens: { - sm: '576px', - md: '768px', - lg: '992px', - xl: '1200px', - }, - options: { - prefix: '', - important: false, - separator: ':', - }, - }) - ) +function config(overrides) { + return _.defaultsDeep(overrides, { + screens: { + sm: '576px', + md: '768px', + lg: '992px', + xl: '1200px', + }, + options: { + prefix: '', + important: false, + separator: ':', + }, + }) } -test('options are not required', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [container()], - }) +test.only('options are not required', () => { + const { components } = processPlugins([container()], config()) expect(css(components)).toMatchCss(` .container { width: 100% } @@ -47,9 +43,9 @@ test('options are not required', () => { `) }) -test('screens can be specified explicitly', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ +test.only('screens can be specified explicitly', () => { + const { components } = processPlugins( + [ container({ screens: { sm: '400px', @@ -57,7 +53,8 @@ test('screens can be specified explicitly', () => { }, }), ], - }) + config() + ) expect(css(components)).toMatchCss(` .container { width: 100% } @@ -70,14 +67,15 @@ test('screens can be specified explicitly', () => { `) }) -test('screens can be an array', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ +test.only('screens can be an array', () => { + const { components } = processPlugins( + [ container({ screens: ['400px', '500px'], }), ], - }) + config() + ) expect(css(components)).toMatchCss(` .container { width: 100% } @@ -90,14 +88,15 @@ test('screens can be an array', () => { `) }) -test('the container can be centered by default', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ +test.only('the container can be centered by default', () => { + const { components } = processPlugins( + [ container({ center: true, }), ], - }) + config() + ) expect(css(components)).toMatchCss(` .container { @@ -120,14 +119,15 @@ test('the container can be centered by default', () => { `) }) -test('horizontal padding can be included by default', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ +test.only('horizontal padding can be included by default', () => { + const { components } = processPlugins( + [ container({ padding: '2rem', }), ], - }) + config() + ) expect(css(components)).toMatchCss(` .container { @@ -150,9 +150,9 @@ test('horizontal padding can be included by default', () => { `) }) -test('setting all options at once', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ +test.only('setting all options at once', () => { + const { components } = processPlugins( + [ container({ screens: { sm: '400px', @@ -162,7 +162,8 @@ test('setting all options at once', () => { padding: '2rem', }), ], - }) + config() + ) expect(css(components)).toMatchCss(` .container { diff --git a/__tests__/defineClass.test.js b/__tests__/defineClass.test.js deleted file mode 100644 index cb8fe09b5..000000000 --- a/__tests__/defineClass.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import c from '../src/util/collapseWhitespace' -import defineClass from '../src/util/defineClass' - -/** - * Tests - */ -it('creates a proper single-word class with rules', () => { - let output = defineClass('flex', { display: 'flex' }) - expect(c(output.toString())).toEqual(`.flex { display: flex }`) -}) - -it('does not modify the case of selector names', () => { - let output = defineClass('inlineBlock', { display: 'inline-block' }) - expect(c(output.toString())).toEqual(`.inlineBlock { display: inline-block }`) -}) - -it('does not modify the case of property names', () => { - let output = defineClass('smooth', { - '-webkit-font-smoothing': 'antialiased', - }) - expect(c(output.toString())).toEqual(`.smooth { -webkit-font-smoothing: antialiased }`) -}) - -it('escapes non-standard characters in selectors', () => { - let output = defineClass('w-1/4', { width: '25%' }) - expect(c(output.toString())).toEqual(`.w-1\\/4 { width: 25% }`) -}) diff --git a/__tests__/defineClasses.test.js b/__tests__/defineClasses.test.js deleted file mode 100644 index 4c6087440..000000000 --- a/__tests__/defineClasses.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import c from '../src/util/collapseWhitespace' -import defineClasses from '../src/util/defineClasses' - -/** - * Tests - */ -it('it generates a set of helper classes from a config', () => { - let output = defineClasses({ - flex: { - display: 'flex', - }, - 'inline-flex': { - display: 'inline-flex', - }, - }) - expect(output).toBeInstanceOf(Array) - expect(c(output[0].toString())).toEqual(`.flex { display: flex }`) - expect(c(output[1].toString())).toEqual(`.inline-flex { display: inline-flex }`) -}) diff --git a/__tests__/generateModules.test.js b/__tests__/generateModules.test.js deleted file mode 100644 index d9fdb1dff..000000000 --- a/__tests__/generateModules.test.js +++ /dev/null @@ -1,133 +0,0 @@ -import generateModules from '../src/util/generateModules' -import defineClasses from '../src/util/defineClasses' - -function textAlign() { - return defineClasses({ - 'text-left': { 'text-align': 'left' }, - 'text-right': { 'text-align': 'right' }, - 'text-center': { 'text-align': 'center' }, - }) -} - -function display() { - return defineClasses({ - block: { display: 'block' }, - inline: { display: 'inline' }, - 'inline-block': { display: 'inline-block' }, - }) -} - -function borderStyle() { - return defineClasses({ - 'border-solid': { 'border-style': 'solid' }, - 'border-dashed': { 'border-style': 'dashed' }, - 'border-dotted': { 'border-style': 'dotted' }, - }) -} - -test('an empty variants list generates a @variants at-rule with no parameters', () => { - const result = generateModules([{ name: 'textAlign', generator: textAlign }], { - textAlign: [], - }) - - const expected = ` - @variants { - .text-left { text-align: left } - .text-right { text-align: right } - .text-center { text-align: center } - } - ` - expect(result.toString()).toMatchCss(expected) -}) - -test('a `false` variants list generates no output', () => { - const result = generateModules([{ name: 'textAlign', generator: textAlign }], { - textAlign: false, - }) - - expect(result.toString()).toMatchCss('') -}) - -test('specified variants are included in the @variants at-rule', () => { - const result = generateModules([{ name: 'textAlign', generator: textAlign }], { - textAlign: ['responsive', 'hover'], - }) - - const expected = ` - @variants responsive, hover { - .text-left { text-align: left } - .text-right { text-align: right } - .text-center { text-align: center } - } - ` - expect(result.toString()).toMatchCss(expected) -}) - -test('options must provide variants for every module', () => { - expect(() => { - generateModules( - [{ name: 'textAlign', generator: textAlign }, { name: 'display', generator: display }], - { - textAlign: [], - } - ) - }).toThrow() -}) - -test('variants can be different for each module', () => { - const result = generateModules( - [ - { name: 'textAlign', generator: textAlign }, - { name: 'display', generator: display }, - { name: 'borderStyle', generator: borderStyle }, - ], - { - textAlign: [], - display: false, - borderStyle: ['responsive', 'hover', 'focus'], - } - ) - - const expected = ` - @variants { - .text-left { text-align: left } - .text-right { text-align: right } - .text-center { text-align: center } - } - - @variants responsive, hover, focus { - .border-solid { border-style: solid } - .border-dashed { border-style: dashed } - .border-dotted { border-style: dotted } - } - ` - expect(result.toString()).toMatchCss(expected) -}) - -test('generators can reference the generatorOptions object', () => { - const result = generateModules( - [ - { - name: 'parameterized', - generator: generatorParams => { - return defineClasses({ - foo: { color: generatorParams.color }, - }) - }, - }, - ], - { - parameterized: [], - }, - { - color: 'blue', - } - ) - - const expected = ` - @variants { - .foo { color: blue } - } - ` - expect(result.toString()).toMatchCss(expected) -}) diff --git a/__tests__/prefixSelector.test.js b/__tests__/prefixSelector.test.js new file mode 100644 index 000000000..ae55d580e --- /dev/null +++ b/__tests__/prefixSelector.test.js @@ -0,0 +1,26 @@ +import prefix from '../src/util/prefixSelector' + +test('it prefixes classes with the provided prefix', () => { + expect(prefix('tw-', '.foo')).toEqual('.tw-foo') +}) + +test('it handles a function as the prefix', () => { + const prefixFunc = selector => { + return selector === '.foo' ? 'tw-' : '' + } + + expect(prefix(prefixFunc, '.foo')).toEqual('.tw-foo') + expect(prefix(prefixFunc, '.bar')).toEqual('.bar') +}) + +test('it properly prefixes selectors with non-standard characters', () => { + expect(prefix('tw-', '.hello\\:world')).toEqual('.tw-hello\\:world') + expect(prefix('tw-', '.foo\\/bar')).toEqual('.tw-foo\\/bar') + expect(prefix('tw-', '.wew\\.lad')).toEqual('.tw-wew\\.lad') +}) + +test('it prefixes all classes in a selector', () => { + expect(prefix('tw-', '.btn-blue .w-1\\/4 > h1.text-xl + a .bar')).toEqual( + '.tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar' + ) +}) diff --git a/__tests__/prefixTree.test.js b/__tests__/prefixTree.test.js deleted file mode 100644 index 877aade19..000000000 --- a/__tests__/prefixTree.test.js +++ /dev/null @@ -1,70 +0,0 @@ -import postcss from 'postcss' -import prefixTree from '../src/util/prefixTree' - -test('it prefixes classes with the provided prefix', () => { - const input = postcss.parse(` - .foo { color: red; } - .apple, .pear { color: green; } - `) - - const expected = ` - .tw-foo { color: red; } - .tw-apple, .tw-pear { color: green; } - ` - - const result = prefixTree(input, 'tw-').toResult() - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) -}) - -test('it handles a function as the prefix', () => { - const input = postcss.parse(` - .foo { color: red; } - .apple, .pear { color: green; } - `) - - const expected = ` - .tw-foo { color: red; } - .apple, .pear { color: green; } - ` - - const prefixFunc = selector => { - return selector === '.foo' ? 'tw-' : '' - } - - const result = prefixTree(input, prefixFunc).toResult() - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) -}) - -test('it properly prefixes selectors with non-standard characters', () => { - const input = postcss.parse(` - .hello\\:world { color: blue; } - .foo\\/bar { color: green; } - .wew\\.lad { color: red; } - `) - - const expected = ` - .tw-hello\\:world { color: blue; } - .tw-foo\\/bar { color: green; } - .tw-wew\\.lad { color: red; } - ` - - const result = prefixTree(input, 'tw-').toResult() - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) -}) - -test('it prefixes all classes in a selector', () => { - const input = postcss.parse(` - .btn-blue .w-1\\/4 > h1.text-xl + a .bar { color: red; } - `) - - const expected = ` - .tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar { color: red; } - ` - - const result = prefixTree(input, 'tw-').toResult() - expect(result.css).toEqual(expected) - expect(result.warnings().length).toBe(0) -}) diff --git a/__tests__/processPlugins.test.js b/__tests__/processPlugins.test.js index 3115ad088..740bc0fcb 100644 --- a/__tests__/processPlugins.test.js +++ b/__tests__/processPlugins.test.js @@ -6,21 +6,19 @@ function css(nodes) { return postcss.root({ nodes }).toString() } -function processPluginsWithValidConfig(config) { - return processPlugins( - _.defaultsDeep(config, { - options: { - prefix: '', - important: false, - separator: ':', - }, - }) - ) +function makeConfig(overrides) { + return _.defaultsDeep(overrides, { + options: { + prefix: '', + important: false, + separator: ':', + }, + }) } test('plugins can create utilities with object syntax', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities({ '.object-fill': { @@ -35,7 +33,8 @@ test('plugins can create utilities with object syntax', () => { }) }, ], - }) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -50,12 +49,12 @@ test('plugins can create utilities with object syntax', () => { object-fit: cover } } - `) + `) }) test('plugins can create utilities with arrays of objects', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities([ { @@ -76,7 +75,8 @@ test('plugins can create utilities with arrays of objects', () => { ]) }, ], - }) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -91,12 +91,12 @@ test('plugins can create utilities with arrays of objects', () => { object-fit: cover } } - `) + `) }) test('plugins can create utilities with raw PostCSS nodes', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities([ postcss.rule({ selector: '.object-fill' }).append([ @@ -120,7 +120,8 @@ test('plugins can create utilities with raw PostCSS nodes', () => { ]) }, ], - }) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -135,12 +136,12 @@ test('plugins can create utilities with raw PostCSS nodes', () => { object-fit: cover } } - `) + `) }) test('plugins can create utilities with mixed object styles and PostCSS nodes', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities([ { @@ -163,7 +164,8 @@ test('plugins can create utilities with mixed object styles and PostCSS nodes', ]) }, ], - }) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -178,12 +180,12 @@ test('plugins can create utilities with mixed object styles and PostCSS nodes', object-fit: cover } } - `) + `) }) test('plugins can create utilities with variants', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities( { @@ -201,7 +203,8 @@ test('plugins can create utilities with variants', () => { ) }, ], - }) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -216,12 +219,12 @@ test('plugins can create utilities with variants', () => { object-fit: cover } } - `) + `) }) test('plugins can create components with object syntax', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents({ '.btn-blue': { @@ -236,7 +239,8 @@ test('plugins can create components with object syntax', () => { }) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -249,12 +253,12 @@ test('plugins can create components with object syntax', () => { .btn-blue:hover { background-color: darkblue } - `) + `) }) test('plugins can create components with raw PostCSS nodes', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents([ postcss.rule({ selector: '.btn-blue' }).append([ @@ -284,7 +288,8 @@ test('plugins can create components with raw PostCSS nodes', () => { ]) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -297,12 +302,12 @@ test('plugins can create components with raw PostCSS nodes', () => { .btn-blue:hover { background-color: darkblue } - `) + `) }) test('plugins can create components with mixed object styles and raw PostCSS nodes', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents([ postcss.rule({ selector: '.btn-blue' }).append([ @@ -331,7 +336,8 @@ test('plugins can create components with mixed object styles and raw PostCSS nod ]) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -344,12 +350,12 @@ test('plugins can create components with mixed object styles and raw PostCSS nod .btn-blue:hover { background-color: darkblue } - `) + `) }) test('plugins can create components with media queries with object syntax', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents({ '.container': { @@ -373,7 +379,8 @@ test('plugins can create components with media queries with object syntax', () = }) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -395,12 +402,12 @@ test('plugins can create components with media queries with object syntax', () = max-width: 300px } } - `) + `) }) test('media queries can be defined multiple times using objects-in-array syntax', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents([ { @@ -427,7 +434,8 @@ test('media queries can be defined multiple times using objects-in-array syntax' ]) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -448,12 +456,12 @@ test('media queries can be defined multiple times using objects-in-array syntax' display: inline-block } } - `) + `) }) test('plugins can create nested rules', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents }) { addComponents({ '.btn-blue': { @@ -479,7 +487,8 @@ test('plugins can create nested rules', () => { }) }, ], - }) + makeConfig() + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -503,12 +512,12 @@ test('plugins can create nested rules', () => { h1 .btn-blue { color: purple; } - `) + `) }) test('plugins can create rules with escaped selectors', () => { - const config = { - plugins: [ + const { components, utilities } = processPlugins( + [ function({ e, addUtilities }) { addUtilities({ [`.${e('top-1/4')}`]: { @@ -517,9 +526,8 @@ test('plugins can create rules with escaped selectors', () => { }) }, ], - } - - const { components, utilities } = processPluginsWithValidConfig(config) + makeConfig() + ) expect(components.length).toBe(0) expect(css(utilities)).toMatchCss(` @@ -528,18 +536,12 @@ test('plugins can create rules with escaped selectors', () => { top: 25% } } - `) + `) }) test('plugins can access the current config', () => { - const { components, utilities } = processPluginsWithValidConfig({ - screens: { - sm: '576px', - md: '768px', - lg: '992px', - xl: '1200px', - }, - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents, config }) { const containerClasses = [ { @@ -556,13 +558,18 @@ test('plugins can access the current config', () => { }, }) }) - - // console.log(containerClasses) - addComponents(containerClasses) }, ], - }) + makeConfig({ + screens: { + sm: '576px', + md: '768px', + lg: '992px', + xl: '1200px', + }, + }) + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` @@ -589,18 +596,12 @@ test('plugins can access the current config', () => { max-width: 1200px } } - `) + `) }) test('plugins can provide fallbacks to keys missing from the config', () => { - const { components, utilities } = processPluginsWithValidConfig({ - borderRadius: { - '1': '1px', - '2': '2px', - '4': '4px', - '8': '8px', - }, - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addComponents, config }) { addComponents({ '.btn': { @@ -609,19 +610,27 @@ test('plugins can provide fallbacks to keys missing from the config', () => { }) }, ], - }) + makeConfig({ + borderRadius: { + '1': '1px', + '2': '2px', + '4': '4px', + '8': '8px', + }, + }) + ) expect(utilities.length).toBe(0) expect(css(components)).toMatchCss(` .btn { border-radius: .25rem } - `) + `) }) test('variants are optional when adding utilities', () => { - const { utilities } = processPluginsWithValidConfig({ - plugins: [ + const { utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities({ '.border-collapse': { @@ -630,20 +639,20 @@ test('variants are optional when adding utilities', () => { }) }, ], - }) + makeConfig() + ) expect(css(utilities)).toMatchCss(` @variants { .border-collapse { border-collapse: collapse } - } - `) + }`) }) test('plugins can add multiple sets of utilities and components', () => { - const { components, utilities } = processPluginsWithValidConfig({ - plugins: [ + const { components, utilities } = processPlugins( + [ function({ addUtilities, addComponents }) { addComponents({ '.card': { @@ -672,7 +681,8 @@ test('plugins can add multiple sets of utilities and components', () => { }) }, ], - }) + makeConfig() + ) expect(css(utilities)).toMatchCss(` @variants { @@ -685,7 +695,7 @@ test('plugins can add multiple sets of utilities and components', () => { border-collapse: collapse } } - `) + `) expect(css(components)).toMatchCss(` .card { padding: 1rem; @@ -695,12 +705,12 @@ test('plugins can add multiple sets of utilities and components', () => { padding: 1rem .5rem; display: inline-block } - `) + `) }) test('plugins respect prefix and important options by default when adding utilities', () => { - const { utilities } = processPluginsWithValidConfig({ - plugins: [ + const { utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities({ '.rotate-90': { @@ -709,11 +719,13 @@ test('plugins respect prefix and important options by default when adding utilit }) }, ], - options: { - prefix: 'tw-', - important: true, - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + important: true, + }, + }) + ) expect(css(utilities)).toMatchCss(` @variants { @@ -721,12 +733,12 @@ test('plugins respect prefix and important options by default when adding utilit transform: rotate(90deg) !important } } - `) + `) }) test("component declarations respect the 'prefix' option by default", () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ + const { components } = processPlugins( + [ function({ addComponents }) { addComponents({ '.btn-blue': { @@ -735,21 +747,61 @@ test("component declarations respect the 'prefix' option by default", () => { }) }, ], - options: { - prefix: 'tw-', - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + }, + }) + ) expect(css(components)).toMatchCss(` .tw-btn-blue { background-color: blue } - `) + `) +}) + +test('all selectors in a rule are prefixed', () => { + const { utilities, components } = processPlugins( + [ + function({ addUtilities, addComponents }) { + addUtilities({ + '.rotate-90, .rotate-1\\/4': { + transform: 'rotate(90deg)', + }, + }) + addComponents({ + '.btn-blue, .btn-red': { + padding: '10px', + }, + }) + }, + ], + makeConfig({ + options: { + prefix: 'tw-', + }, + }) + ) + + expect(css(utilities)).toMatchCss(` + @variants { + .tw-rotate-90, .tw-rotate-1\\/4 { + transform: rotate(90deg) + } + } + `) + + expect(css(components)).toMatchCss(` + .tw-btn-blue, .tw-btn-red { + padding: 10px + } + `) }) test("component declarations can optionally ignore 'prefix' option", () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ + const { components } = processPlugins( + [ function({ addComponents }) { addComponents( { @@ -761,21 +813,23 @@ test("component declarations can optionally ignore 'prefix' option", () => { ) }, ], - options: { - prefix: 'tw-', - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + }, + }) + ) expect(css(components)).toMatchCss(` .btn-blue { background-color: blue } - `) + `) }) test("component declarations are not affected by the 'important' option", () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ + const { components } = processPlugins( + [ function({ addComponents }) { addComponents({ '.btn-blue': { @@ -784,21 +838,23 @@ test("component declarations are not affected by the 'important' option", () => }) }, ], - options: { - important: true, - }, - }) + makeConfig({ + options: { + important: true, + }, + }) + ) expect(css(components)).toMatchCss(` .btn-blue { background-color: blue } - `) + `) }) test("plugins can apply the user's chosen prefix to components manually", () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ + const { components } = processPlugins( + [ function({ addComponents, prefix }) { addComponents( { @@ -810,21 +866,23 @@ test("plugins can apply the user's chosen prefix to components manually", () => ) }, ], - options: { - prefix: 'tw-', - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + }, + }) + ) expect(css(components)).toMatchCss(` .tw-btn-blue { background-color: blue } - `) + `) }) test('prefix can optionally be ignored for utilities', () => { - const { utilities } = processPluginsWithValidConfig({ - plugins: [ + const { utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities( { @@ -838,11 +896,13 @@ test('prefix can optionally be ignored for utilities', () => { ) }, ], - options: { - prefix: 'tw-', - important: true, - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + important: true, + }, + }) + ) expect(css(utilities)).toMatchCss(` @variants { @@ -850,12 +910,12 @@ test('prefix can optionally be ignored for utilities', () => { transform: rotate(90deg) !important } } - `) + `) }) test('important can optionally be ignored for utilities', () => { - const { utilities } = processPluginsWithValidConfig({ - plugins: [ + const { utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities( { @@ -869,11 +929,13 @@ test('important can optionally be ignored for utilities', () => { ) }, ], - options: { - prefix: 'tw-', - important: true, - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + important: true, + }, + }) + ) expect(css(utilities)).toMatchCss(` @variants { @@ -881,12 +943,12 @@ test('important can optionally be ignored for utilities', () => { transform: rotate(90deg) } } - `) + `) }) test('variants can still be specified when ignoring prefix and important options', () => { - const { utilities } = processPluginsWithValidConfig({ - plugins: [ + const { utilities } = processPlugins( + [ function({ addUtilities }) { addUtilities( { @@ -902,11 +964,13 @@ test('variants can still be specified when ignoring prefix and important options ) }, ], - options: { - prefix: 'tw-', - important: true, - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + important: true, + }, + }) + ) expect(css(utilities)).toMatchCss(` @variants responsive, hover, focus { @@ -914,12 +978,12 @@ test('variants can still be specified when ignoring prefix and important options transform: rotate(90deg) } } - `) + `) }) test('prefix will prefix all classes in a selector', () => { - const { components } = processPluginsWithValidConfig({ - plugins: [ + const { components } = processPlugins( + [ function({ addComponents, prefix }) { addComponents( { @@ -931,14 +995,16 @@ test('prefix will prefix all classes in a selector', () => { ) }, ], - options: { - prefix: 'tw-', - }, - }) + makeConfig({ + options: { + prefix: 'tw-', + }, + }) + ) expect(css(components)).toMatchCss(` .tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar { background-color: blue } - `) + `) }) diff --git a/__tests__/variantsAtRule.test.js b/__tests__/variantsAtRule.test.js index f8a3dec1c..cce5e2572 100644 --- a/__tests__/variantsAtRule.test.js +++ b/__tests__/variantsAtRule.test.js @@ -4,7 +4,9 @@ import config from '../defaultConfig.stub.js' import processPlugins from '../src/util/processPlugins' function run(input, opts = config) { - return postcss([plugin(opts, processPlugins(opts))]).process(input, { from: undefined }) + return postcss([plugin(opts, processPlugins(opts.plugins, opts))]).process(input, { + from: undefined, + }) } test('it can generate hover variants', () => { diff --git a/src/defaultPlugins.js b/src/defaultPlugins.js new file mode 100644 index 000000000..3d648d8a0 --- /dev/null +++ b/src/defaultPlugins.js @@ -0,0 +1,111 @@ +import lists from './plugins/lists' +import appearance from './plugins/appearance' +import backgroundAttachment from './plugins/backgroundAttachment' +import backgroundColors from './plugins/backgroundColors' +import backgroundPosition from './plugins/backgroundPosition' +import backgroundRepeat from './plugins/backgroundRepeat' +import backgroundSize from './plugins/backgroundSize' +import borderCollapse from './plugins/borderCollapse' +import borderColors from './plugins/borderColors' +import borderRadius from './plugins/borderRadius' +import borderStyle from './plugins/borderStyle' +import borderWidths from './plugins/borderWidths' +import cursor from './plugins/cursor' +import display from './plugins/display' +import flexbox from './plugins/flexbox' +import float from './plugins/float' +import fonts from './plugins/fonts' +import fontWeights from './plugins/fontWeights' +import height from './plugins/height' +import leading from './plugins/leading' +import margin from './plugins/margin' +import maxHeight from './plugins/maxHeight' +import maxWidth from './plugins/maxWidth' +import minHeight from './plugins/minHeight' +import minWidth from './plugins/minWidth' +import negativeMargin from './plugins/negativeMargin' +import objectFit from './plugins/objectFit' +import objectPosition from './plugins/objectPosition' +import opacity from './plugins/opacity' +import outline from './plugins/outline' +import overflow from './plugins/overflow' +import padding from './plugins/padding' +import pointerEvents from './plugins/pointerEvents' +import position from './plugins/position' +import resize from './plugins/resize' +import shadows from './plugins/shadows' +import svgFill from './plugins/svgFill' +import svgStroke from './plugins/svgStroke' +import tableLayout from './plugins/tableLayout' +import textAlign from './plugins/textAlign' +import textColors from './plugins/textColors' +import textSizes from './plugins/textSizes' +import textStyle from './plugins/textStyle' +import tracking from './plugins/tracking' +import userSelect from './plugins/userSelect' +import verticalAlign from './plugins/verticalAlign' +import visibility from './plugins/visibility' +import whitespace from './plugins/whitespace' +import width from './plugins/width' +import zIndex from './plugins/zIndex' + +function loadPlugins(modules, plugins) { + return Object.keys(plugins) + .filter(plugin => modules[plugin] !== false) + .map(plugin => plugins[plugin]()) +} + +export default function(config) { + return loadPlugins(config.modules, { + lists, + appearance, + backgroundAttachment, + backgroundColors, + backgroundPosition, + backgroundRepeat, + backgroundSize, + borderCollapse, + borderColors, + borderRadius, + borderStyle, + borderWidths, + cursor, + display, + flexbox, + float, + fonts, + fontWeights, + height, + leading, + margin, + maxHeight, + maxWidth, + minHeight, + minWidth, + negativeMargin, + objectFit, + objectPosition, + opacity, + outline, + overflow, + padding, + pointerEvents, + position, + resize, + shadows, + svgFill, + svgStroke, + tableLayout, + textAlign, + textColors, + textSizes, + textStyle, + tracking, + userSelect, + verticalAlign, + visibility, + whitespace, + width, + zIndex, + }) +} diff --git a/src/generators/appearance.js b/src/generators/appearance.js deleted file mode 100644 index b97b7f1e2..000000000 --- a/src/generators/appearance.js +++ /dev/null @@ -1,7 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'appearance-none': { appearance: 'none' }, - }) -} diff --git a/src/generators/backgroundAttachment.js b/src/generators/backgroundAttachment.js deleted file mode 100644 index 04e77c459..000000000 --- a/src/generators/backgroundAttachment.js +++ /dev/null @@ -1,9 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'bg-fixed': { 'background-attachment': 'fixed' }, - 'bg-local': { 'background-attachment': 'local' }, - 'bg-scroll': { 'background-attachment': 'scroll' }, - }) -} diff --git a/src/generators/backgroundColors.js b/src/generators/backgroundColors.js deleted file mode 100644 index 955a072be..000000000 --- a/src/generators/backgroundColors.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ backgroundColors }) { - return _.map(backgroundColors, (color, className) => { - return defineClass(`bg-${className}`, { - 'background-color': color, - }) - }) -} diff --git a/src/generators/backgroundPosition.js b/src/generators/backgroundPosition.js deleted file mode 100644 index 1a1f9b93a..000000000 --- a/src/generators/backgroundPosition.js +++ /dev/null @@ -1,15 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'bg-bottom': { 'background-position': 'bottom' }, - 'bg-center': { 'background-position': 'center' }, - 'bg-left': { 'background-position': 'left' }, - 'bg-left-bottom': { 'background-position': 'left bottom' }, - 'bg-left-top': { 'background-position': 'left top' }, - 'bg-right': { 'background-position': 'right' }, - 'bg-right-bottom': { 'background-position': 'right bottom' }, - 'bg-right-top': { 'background-position': 'right top' }, - 'bg-top': { 'background-position': 'top' }, - }) -} diff --git a/src/generators/backgroundRepeat.js b/src/generators/backgroundRepeat.js deleted file mode 100644 index fe3147d7f..000000000 --- a/src/generators/backgroundRepeat.js +++ /dev/null @@ -1,10 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'bg-repeat': { 'background-repeat': 'repeat' }, - 'bg-no-repeat': { 'background-repeat': 'no-repeat' }, - 'bg-repeat-x': { 'background-repeat': 'repeat-x' }, - 'bg-repeat-y': { 'background-repeat': 'repeat-y' }, - }) -} diff --git a/src/generators/backgroundSize.js b/src/generators/backgroundSize.js deleted file mode 100644 index 607401a32..000000000 --- a/src/generators/backgroundSize.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ backgroundSize }) { - return _.map(backgroundSize, (size, className) => { - return defineClass(`bg-${className}`, { - 'background-size': size, - }) - }) -} diff --git a/src/generators/borderCollapse.js b/src/generators/borderCollapse.js deleted file mode 100644 index 321c89742..000000000 --- a/src/generators/borderCollapse.js +++ /dev/null @@ -1,8 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'border-collapse': { 'border-collapse': 'collapse' }, - 'border-separate': { 'border-collapse': 'separate' }, - }) -} diff --git a/src/generators/borderColors.js b/src/generators/borderColors.js deleted file mode 100644 index 7ea0f0ab2..000000000 --- a/src/generators/borderColors.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ borderColors }) { - return _.map(_.omit(borderColors, 'default'), (color, className) => { - return defineClass(`border-${className}`, { - 'border-color': color, - }) - }) -} diff --git a/src/generators/borderRadius.js b/src/generators/borderRadius.js deleted file mode 100644 index ba40d09aa..000000000 --- a/src/generators/borderRadius.js +++ /dev/null @@ -1,57 +0,0 @@ -import _ from 'lodash' -import defineClasses from '../util/defineClasses' - -function defineBorderRadiusUtilities(borderRadiuses) { - const generators = [ - (radius, modifier) => - defineClasses({ - [`rounded${modifier}`]: { - 'border-radius': `${radius}`, - }, - }), - (radius, modifier) => - defineClasses({ - [`rounded-t${modifier}`]: { - 'border-top-left-radius': `${radius}`, - 'border-top-right-radius': `${radius}`, - }, - [`rounded-r${modifier}`]: { - 'border-top-right-radius': `${radius}`, - 'border-bottom-right-radius': `${radius}`, - }, - [`rounded-b${modifier}`]: { - 'border-bottom-right-radius': `${radius}`, - 'border-bottom-left-radius': `${radius}`, - }, - [`rounded-l${modifier}`]: { - 'border-top-left-radius': `${radius}`, - 'border-bottom-left-radius': `${radius}`, - }, - }), - (radius, modifier) => - defineClasses({ - [`rounded-tl${modifier}`]: { - 'border-top-left-radius': `${radius}`, - }, - [`rounded-tr${modifier}`]: { - 'border-top-right-radius': `${radius}`, - }, - [`rounded-br${modifier}`]: { - 'border-bottom-right-radius': `${radius}`, - }, - [`rounded-bl${modifier}`]: { - 'border-bottom-left-radius': `${radius}`, - }, - }), - ] - - return _.flatMap(generators, generator => { - return _.flatMap(borderRadiuses, (radius, modifier) => { - return generator(radius, modifier === 'default' ? '' : `-${modifier}`) - }) - }) -} - -module.exports = function({ borderRadius }) { - return defineBorderRadiusUtilities(borderRadius) -} diff --git a/src/generators/borderStyle.js b/src/generators/borderStyle.js deleted file mode 100644 index 3dfca388c..000000000 --- a/src/generators/borderStyle.js +++ /dev/null @@ -1,18 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'border-solid': { - 'border-style': 'solid', - }, - 'border-dashed': { - 'border-style': 'dashed', - }, - 'border-dotted': { - 'border-style': 'dotted', - }, - 'border-none': { - 'border-style': 'none', - }, - }) -} diff --git a/src/generators/borderWidths.js b/src/generators/borderWidths.js deleted file mode 100644 index f02c4f7cf..000000000 --- a/src/generators/borderWidths.js +++ /dev/null @@ -1,38 +0,0 @@ -import _ from 'lodash' -import defineClasses from '../util/defineClasses' - -function defineBorderWidthUtilities(borderWidths) { - const generators = [ - (width, modifier) => - defineClasses({ - [`border${modifier}`]: { - 'border-width': `${width}`, - }, - }), - (width, modifier) => - defineClasses({ - [`border-t${modifier}`]: { - 'border-top-width': `${width}`, - }, - [`border-r${modifier}`]: { - 'border-right-width': `${width}`, - }, - [`border-b${modifier}`]: { - 'border-bottom-width': `${width}`, - }, - [`border-l${modifier}`]: { - 'border-left-width': `${width}`, - }, - }), - ] - - return _.flatMap(generators, generator => { - return _.flatMap(borderWidths, (width, modifier) => { - return generator(width, modifier === 'default' ? '' : `-${modifier}`) - }) - }) -} - -module.exports = function({ borderWidths }) { - return defineBorderWidthUtilities(borderWidths) -} diff --git a/src/generators/cursor.js b/src/generators/cursor.js deleted file mode 100644 index b2eda2ab2..000000000 --- a/src/generators/cursor.js +++ /dev/null @@ -1,12 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'cursor-auto': { cursor: 'auto' }, - 'cursor-default': { cursor: 'default' }, - 'cursor-pointer': { cursor: 'pointer' }, - 'cursor-wait': { cursor: 'wait' }, - 'cursor-move': { cursor: 'move' }, - 'cursor-not-allowed': { cursor: 'not-allowed' }, - }) -} diff --git a/src/generators/display.js b/src/generators/display.js deleted file mode 100644 index 93f04f169..000000000 --- a/src/generators/display.js +++ /dev/null @@ -1,27 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - block: { - display: 'block', - }, - 'inline-block': { - display: 'inline-block', - }, - inline: { - display: 'inline', - }, - table: { - display: 'table', - }, - 'table-row': { - display: 'table-row', - }, - 'table-cell': { - display: 'table-cell', - }, - hidden: { - display: 'none', - }, - }) -} diff --git a/src/generators/flexbox.js b/src/generators/flexbox.js deleted file mode 100644 index 30827dc7e..000000000 --- a/src/generators/flexbox.js +++ /dev/null @@ -1,117 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - flex: { - display: 'flex', - }, - 'inline-flex': { - display: 'inline-flex', - }, - 'flex-row': { - 'flex-direction': 'row', - }, - 'flex-row-reverse': { - 'flex-direction': 'row-reverse', - }, - 'flex-col': { - 'flex-direction': 'column', - }, - 'flex-col-reverse': { - 'flex-direction': 'column-reverse', - }, - 'flex-wrap': { - 'flex-wrap': 'wrap', - }, - 'flex-wrap-reverse': { - 'flex-wrap': 'wrap-reverse', - }, - 'flex-no-wrap': { - 'flex-wrap': 'nowrap', - }, - 'items-start': { - 'align-items': 'flex-start', - }, - 'items-end': { - 'align-items': 'flex-end', - }, - 'items-center': { - 'align-items': 'center', - }, - 'items-baseline': { - 'align-items': 'baseline', - }, - 'items-stretch': { - 'align-items': 'stretch', - }, - 'self-auto': { - 'align-self': 'auto', - }, - 'self-start': { - 'align-self': 'flex-start', - }, - 'self-end': { - 'align-self': 'flex-end', - }, - 'self-center': { - 'align-self': 'center', - }, - 'self-stretch': { - 'align-self': 'stretch', - }, - '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', - }, - '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', - }, - 'flex-1': { - flex: '1 1 0%', - }, - 'flex-auto': { - flex: '1 1 auto', - }, - 'flex-initial': { - flex: '0 1 auto', - }, - 'flex-none': { - flex: 'none', - }, - 'flex-grow': { - 'flex-grow': '1', - }, - 'flex-shrink': { - 'flex-shrink': '1', - }, - 'flex-no-grow': { - 'flex-grow': '0', - }, - 'flex-no-shrink': { - 'flex-shrink': '0', - }, - }) -} diff --git a/src/generators/float.js b/src/generators/float.js deleted file mode 100644 index e7707e783..000000000 --- a/src/generators/float.js +++ /dev/null @@ -1,20 +0,0 @@ -import _ from 'lodash' -import postcss from 'postcss' -import defineClasses from '../util/defineClasses' - -export default function() { - return _.concat( - defineClasses({ - 'float-right': { float: 'right' }, - 'float-left': { float: 'left' }, - 'float-none': { float: 'none' }, - }), - postcss.parse(` - .clearfix:after { - content: ""; - display: table; - clear: both; - } - `).nodes - ) -} diff --git a/src/generators/fontWeights.js b/src/generators/fontWeights.js deleted file mode 100644 index d959b8161..000000000 --- a/src/generators/fontWeights.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ fontWeights }) { - return _.map(fontWeights, (weight, modifier) => { - return defineClass(`font-${modifier}`, { - 'font-weight': `${weight}`, - }) - }) -} diff --git a/src/generators/fonts.js b/src/generators/fonts.js deleted file mode 100644 index d2a3bf308..000000000 --- a/src/generators/fonts.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ fonts }) { - return _.map(fonts, (families, font) => { - if (_.isArray(families)) { - families = families.join(', ') - } - - return defineClass(`font-${font}`, { - 'font-family': `${families}`, - }) - }) -} diff --git a/src/generators/height.js b/src/generators/height.js deleted file mode 100644 index 8ba099ca1..000000000 --- a/src/generators/height.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineHeights(heights) { - return _.map(heights, (size, modifer) => { - return defineClass(`h-${modifer}`, { - height: `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineHeights(config.height)]) -} diff --git a/src/generators/leading.js b/src/generators/leading.js deleted file mode 100644 index ce661b93a..000000000 --- a/src/generators/leading.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ leading }) { - return _.map(leading, (value, modifier) => { - return defineClass(`leading-${modifier}`, { - 'line-height': `${value}`, - }) - }) -} diff --git a/src/generators/lists.js b/src/generators/lists.js deleted file mode 100644 index bda288913..000000000 --- a/src/generators/lists.js +++ /dev/null @@ -1,10 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'list-reset': { - 'list-style': 'none', - padding: '0', - }, - }) -} diff --git a/src/generators/margin.js b/src/generators/margin.js deleted file mode 100644 index 9fe3c4bb0..000000000 --- a/src/generators/margin.js +++ /dev/null @@ -1,31 +0,0 @@ -import _ from 'lodash' -import defineClasses from '../util/defineClasses' - -function defineMargin(margin) { - const generators = [ - (size, modifier) => - defineClasses({ - [`m-${modifier}`]: { margin: `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`my-${modifier}`]: { 'margin-top': `${size}`, 'margin-bottom': `${size}` }, - [`mx-${modifier}`]: { 'margin-left': `${size}`, 'margin-right': `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`mt-${modifier}`]: { 'margin-top': `${size}` }, - [`mr-${modifier}`]: { 'margin-right': `${size}` }, - [`mb-${modifier}`]: { 'margin-bottom': `${size}` }, - [`ml-${modifier}`]: { 'margin-left': `${size}` }, - }), - ] - - return _.flatMap(generators, generator => { - return _.flatMap(margin, generator) - }) -} - -export default function({ margin }) { - return _.flatten([defineMargin(margin)]) -} diff --git a/src/generators/maxHeight.js b/src/generators/maxHeight.js deleted file mode 100644 index ae42ba6fb..000000000 --- a/src/generators/maxHeight.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineMaxHeights(heights) { - return _.map(heights, (size, modifer) => { - return defineClass(`max-h-${modifer}`, { - 'max-height': `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineMaxHeights(config.maxHeight)]) -} diff --git a/src/generators/maxWidth.js b/src/generators/maxWidth.js deleted file mode 100644 index 9daa4d270..000000000 --- a/src/generators/maxWidth.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineMaxWidths(widths) { - return _.map(widths, (size, modifer) => { - return defineClass(`max-w-${modifer}`, { - 'max-width': `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineMaxWidths(config.maxWidth)]) -} diff --git a/src/generators/minHeight.js b/src/generators/minHeight.js deleted file mode 100644 index 4d6233eff..000000000 --- a/src/generators/minHeight.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineMinHeights(heights) { - return _.map(heights, (size, modifer) => { - return defineClass(`min-h-${modifer}`, { - 'min-height': `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineMinHeights(config.minHeight)]) -} diff --git a/src/generators/minWidth.js b/src/generators/minWidth.js deleted file mode 100644 index d8fa8dce6..000000000 --- a/src/generators/minWidth.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineMinWidths(widths) { - return _.map(widths, (size, modifer) => { - return defineClass(`min-w-${modifer}`, { - 'min-width': `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineMinWidths(config.minWidth)]) -} diff --git a/src/generators/negativeMargin.js b/src/generators/negativeMargin.js deleted file mode 100644 index 8a818b121..000000000 --- a/src/generators/negativeMargin.js +++ /dev/null @@ -1,33 +0,0 @@ -import _ from 'lodash' -import defineClasses from '../util/defineClasses' - -function defineNegativeMargin(negativeMargin) { - const generators = [ - (size, modifier) => - defineClasses({ - [`-m-${modifier}`]: { margin: `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`-my-${modifier}`]: { 'margin-top': `${size}`, 'margin-bottom': `${size}` }, - [`-mx-${modifier}`]: { 'margin-left': `${size}`, 'margin-right': `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`-mt-${modifier}`]: { 'margin-top': `${size}` }, - [`-mr-${modifier}`]: { 'margin-right': `${size}` }, - [`-mb-${modifier}`]: { 'margin-bottom': `${size}` }, - [`-ml-${modifier}`]: { 'margin-left': `${size}` }, - }), - ] - - return _.flatMap(generators, generator => { - return _.flatMap(negativeMargin, (size, modifier) => { - return generator(`${size}` === '0' ? `${size}` : `-${size}`, modifier) - }) - }) -} - -export default function({ negativeMargin }) { - return _.flatten([defineNegativeMargin(negativeMargin)]) -} diff --git a/src/generators/objectFit.js b/src/generators/objectFit.js deleted file mode 100644 index e6723fdc7..000000000 --- a/src/generators/objectFit.js +++ /dev/null @@ -1,11 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'object-contain': { 'object-fit': 'contain' }, - 'object-cover': { 'object-fit': 'cover' }, - 'object-fill': { 'object-fit': 'fill' }, - 'object-none': { 'object-fit': 'none' }, - 'object-scale-down': { 'object-fit': 'scale-down' }, - }) -} diff --git a/src/generators/objectPosition.js b/src/generators/objectPosition.js deleted file mode 100644 index df8863099..000000000 --- a/src/generators/objectPosition.js +++ /dev/null @@ -1,15 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'object-bottom': { 'object-position': 'bottom' }, - 'object-center': { 'object-position': 'center' }, - 'object-left': { 'object-position': 'left' }, - 'object-left-bottom': { 'object-position': 'left bottom' }, - 'object-left-top': { 'object-position': 'left top' }, - 'object-right': { 'object-position': 'right' }, - 'object-right-bottom': { 'object-position': 'right bottom' }, - 'object-right-top': { 'object-position': 'right top' }, - 'object-top': { 'object-position': 'top' }, - }) -} diff --git a/src/generators/opacity.js b/src/generators/opacity.js deleted file mode 100644 index 31379145a..000000000 --- a/src/generators/opacity.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ opacity }) { - return _.map(opacity, (value, modifier) => { - return defineClass(`opacity-${modifier}`, { - opacity: value, - }) - }) -} diff --git a/src/generators/outline.js b/src/generators/outline.js deleted file mode 100644 index 328c58a7f..000000000 --- a/src/generators/outline.js +++ /dev/null @@ -1,7 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'outline-none': { outline: '0' }, - }) -} diff --git a/src/generators/overflow.js b/src/generators/overflow.js deleted file mode 100644 index eefeb01c3..000000000 --- a/src/generators/overflow.js +++ /dev/null @@ -1,20 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'overflow-auto': { overflow: 'auto' }, - 'overflow-hidden': { overflow: 'hidden' }, - 'overflow-visible': { overflow: 'visible' }, - 'overflow-scroll': { overflow: 'scroll' }, - 'overflow-x-auto': { 'overflow-x': 'auto' }, - 'overflow-y-auto': { 'overflow-y': 'auto' }, - 'overflow-x-hidden': { 'overflow-x': 'hidden' }, - 'overflow-y-hidden': { 'overflow-y': 'hidden' }, - 'overflow-x-visible': { 'overflow-x': 'visible' }, - 'overflow-y-visible': { 'overflow-y': 'visible' }, - 'overflow-x-scroll': { 'overflow-x': 'scroll' }, - 'overflow-y-scroll': { 'overflow-y': 'scroll' }, - 'scrolling-touch': { '-webkit-overflow-scrolling': 'touch' }, - 'scrolling-auto': { '-webkit-overflow-scrolling': 'auto' }, - }) -} diff --git a/src/generators/padding.js b/src/generators/padding.js deleted file mode 100644 index 82a5ac679..000000000 --- a/src/generators/padding.js +++ /dev/null @@ -1,31 +0,0 @@ -import _ from 'lodash' -import defineClasses from '../util/defineClasses' - -function definePadding(padding) { - const generators = [ - (size, modifier) => - defineClasses({ - [`p-${modifier}`]: { padding: `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`py-${modifier}`]: { 'padding-top': `${size}`, 'padding-bottom': `${size}` }, - [`px-${modifier}`]: { 'padding-left': `${size}`, 'padding-right': `${size}` }, - }), - (size, modifier) => - defineClasses({ - [`pt-${modifier}`]: { 'padding-top': `${size}` }, - [`pr-${modifier}`]: { 'padding-right': `${size}` }, - [`pb-${modifier}`]: { 'padding-bottom': `${size}` }, - [`pl-${modifier}`]: { 'padding-left': `${size}` }, - }), - ] - - return _.flatMap(generators, generator => { - return _.flatMap(padding, generator) - }) -} - -export default function({ padding }) { - return _.flatten([definePadding(padding)]) -} diff --git a/src/generators/pointerEvents.js b/src/generators/pointerEvents.js deleted file mode 100644 index b8ef3ff80..000000000 --- a/src/generators/pointerEvents.js +++ /dev/null @@ -1,8 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'pointer-events-none': { 'pointer-events': 'none' }, - 'pointer-events-auto': { 'pointer-events': 'auto' }, - }) -} diff --git a/src/generators/position.js b/src/generators/position.js deleted file mode 100644 index 5f3bba0f4..000000000 --- a/src/generators/position.js +++ /dev/null @@ -1,29 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - static: { position: 'static' }, - fixed: { position: 'fixed' }, - absolute: { position: 'absolute' }, - relative: { position: 'relative' }, - sticky: { position: 'sticky' }, - 'pin-none': { - top: 'auto', - right: 'auto', - bottom: 'auto', - left: 'auto', - }, - pin: { - top: 0, - right: 0, - bottom: 0, - left: 0, - }, - 'pin-y': { top: 0, bottom: 0 }, - 'pin-x': { right: 0, left: 0 }, - 'pin-t': { top: 0 }, - 'pin-r': { right: 0 }, - 'pin-b': { bottom: 0 }, - 'pin-l': { left: 0 }, - }) -} diff --git a/src/generators/resize.js b/src/generators/resize.js deleted file mode 100644 index af19ae292..000000000 --- a/src/generators/resize.js +++ /dev/null @@ -1,10 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'resize-none': { resize: 'none' }, - 'resize-y': { resize: 'vertical' }, - 'resize-x': { resize: 'horizontal' }, - resize: { resize: 'both' }, - }) -} diff --git a/src/generators/shadows.js b/src/generators/shadows.js deleted file mode 100644 index b16de5bbb..000000000 --- a/src/generators/shadows.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ shadows }) { - return _.map(shadows, (shadow, modifier) => { - return defineClass(modifier === 'default' ? 'shadow' : `shadow-${modifier}`, { - 'box-shadow': shadow, - }) - }) -} diff --git a/src/generators/svgFill.js b/src/generators/svgFill.js deleted file mode 100644 index d58fb50cd..000000000 --- a/src/generators/svgFill.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ svgFill }) { - return _.map(svgFill, (color, modifier) => { - return defineClass(`fill-${modifier}`, { - fill: color, - }) - }) -} diff --git a/src/generators/svgStroke.js b/src/generators/svgStroke.js deleted file mode 100644 index 802bf664d..000000000 --- a/src/generators/svgStroke.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ svgStroke }) { - return _.map(svgStroke, (color, modifier) => { - return defineClass(`stroke-${modifier}`, { - stroke: color, - }) - }) -} diff --git a/src/generators/tableLayout.js b/src/generators/tableLayout.js deleted file mode 100644 index 5aa0c8554..000000000 --- a/src/generators/tableLayout.js +++ /dev/null @@ -1,8 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'table-auto': { 'table-layout': 'auto' }, - 'table-fixed': { 'table-layout': 'fixed' }, - }) -} diff --git a/src/generators/textAlign.js b/src/generators/textAlign.js deleted file mode 100644 index e1b29f279..000000000 --- a/src/generators/textAlign.js +++ /dev/null @@ -1,10 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'text-left': { 'text-align': 'left' }, - 'text-center': { 'text-align': 'center' }, - 'text-right': { 'text-align': 'right' }, - 'text-justify': { 'text-align': 'justify' }, - }) -} diff --git a/src/generators/textColors.js b/src/generators/textColors.js deleted file mode 100644 index 8e9d8540e..000000000 --- a/src/generators/textColors.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ textColors }) { - return _.map(textColors, (color, modifier) => { - return defineClass(`text-${modifier}`, { - color, - }) - }) -} diff --git a/src/generators/textSizes.js b/src/generators/textSizes.js deleted file mode 100644 index 447e0db7c..000000000 --- a/src/generators/textSizes.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ textSizes }) { - return _.map(textSizes, (size, modifier) => { - return defineClass(`text-${modifier}`, { - 'font-size': `${size}`, - }) - }) -} diff --git a/src/generators/textStyle.js b/src/generators/textStyle.js deleted file mode 100644 index f411e84ab..000000000 --- a/src/generators/textStyle.js +++ /dev/null @@ -1,26 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - italic: { 'font-style': 'italic' }, - roman: { 'font-style': 'normal' }, - - uppercase: { 'text-transform': 'uppercase' }, - lowercase: { 'text-transform': 'lowercase' }, - capitalize: { 'text-transform': 'capitalize' }, - 'normal-case': { 'text-transform': 'none' }, - - underline: { 'text-decoration': 'underline' }, - 'line-through': { 'text-decoration': 'line-through' }, - 'no-underline': { 'text-decoration': 'none' }, - - antialiased: { - '-webkit-font-smoothing': 'antialiased', - '-moz-osx-font-smoothing': 'grayscale', - }, - 'subpixel-antialiased': { - '-webkit-font-smoothing': 'auto', - '-moz-osx-font-smoothing': 'auto', - }, - }) -} diff --git a/src/generators/tracking.js b/src/generators/tracking.js deleted file mode 100644 index 696ee34c3..000000000 --- a/src/generators/tracking.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ tracking }) { - return _.map(tracking, (value, modifier) => { - return defineClass(`tracking-${modifier}`, { - 'letter-spacing': `${value}`, - }) - }) -} diff --git a/src/generators/userSelect.js b/src/generators/userSelect.js deleted file mode 100644 index c7b46d420..000000000 --- a/src/generators/userSelect.js +++ /dev/null @@ -1,8 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'select-none': { 'user-select': 'none' }, - 'select-text': { 'user-select': 'text' }, - }) -} diff --git a/src/generators/verticalAlign.js b/src/generators/verticalAlign.js deleted file mode 100644 index c06c4c2b4..000000000 --- a/src/generators/verticalAlign.js +++ /dev/null @@ -1,12 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'align-baseline': { 'vertical-align': 'baseline' }, - 'align-top': { 'vertical-align': 'top' }, - 'align-middle': { 'vertical-align': 'middle' }, - 'align-bottom': { 'vertical-align': 'bottom' }, - 'align-text-top': { 'vertical-align': 'text-top' }, - 'align-text-bottom': { 'vertical-align': 'text-bottom' }, - }) -} diff --git a/src/generators/visibility.js b/src/generators/visibility.js deleted file mode 100644 index 7084040bb..000000000 --- a/src/generators/visibility.js +++ /dev/null @@ -1,8 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - visible: { visibility: 'visible' }, - invisible: { visibility: 'hidden' }, - }) -} diff --git a/src/generators/whitespace.js b/src/generators/whitespace.js deleted file mode 100644 index f869c8788..000000000 --- a/src/generators/whitespace.js +++ /dev/null @@ -1,20 +0,0 @@ -import defineClasses from '../util/defineClasses' - -export default function() { - return defineClasses({ - 'whitespace-normal': { 'white-space': 'normal' }, - 'whitespace-no-wrap': { 'white-space': 'nowrap' }, - 'whitespace-pre': { 'white-space': 'pre' }, - 'whitespace-pre-line': { 'white-space': 'pre-line' }, - 'whitespace-pre-wrap': { 'white-space': 'pre-wrap' }, - - 'break-words': { 'word-wrap': 'break-word' }, - 'break-normal': { 'word-wrap': 'normal' }, - - truncate: { - overflow: 'hidden', - 'text-overflow': 'ellipsis', - 'white-space': 'nowrap', - }, - }) -} diff --git a/src/generators/width.js b/src/generators/width.js deleted file mode 100644 index 111fa9c76..000000000 --- a/src/generators/width.js +++ /dev/null @@ -1,14 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -function defineWidths(widths) { - return _.map(widths, (size, modifer) => { - return defineClass(`w-${modifer}`, { - width: `${size}`, - }) - }) -} - -export default function(config) { - return _.flatten([defineWidths(config.width)]) -} diff --git a/src/generators/zIndex.js b/src/generators/zIndex.js deleted file mode 100644 index cea79b2f7..000000000 --- a/src/generators/zIndex.js +++ /dev/null @@ -1,10 +0,0 @@ -import _ from 'lodash' -import defineClass from '../util/defineClass' - -export default function({ zIndex }) { - return _.map(zIndex, (value, modifier) => { - return defineClass(`z-${modifier}`, { - 'z-index': value, - }) - }) -} diff --git a/src/lib/substituteTailwindAtRules.js b/src/lib/substituteTailwindAtRules.js index d9ca2e407..887dc3a7c 100644 --- a/src/lib/substituteTailwindAtRules.js +++ b/src/lib/substituteTailwindAtRules.js @@ -8,7 +8,7 @@ function updateSource(nodes, source) { }) } -export default function(config, { components: pluginComponents }, generatedUtilities) { +export default function(config, { components: pluginComponents, utilities: pluginUtilities }) { return function(css) { css.walkAtRules('tailwind', atRule => { if (atRule.params === 'preflight') { @@ -26,7 +26,7 @@ export default function(config, { components: pluginComponents }, generatedUtili } if (atRule.params === 'utilities') { - atRule.before(updateSource(generatedUtilities, atRule.source)) + atRule.before(updateSource(pluginUtilities, atRule.source)) atRule.remove() } }) diff --git a/src/plugins/appearance.js b/src/plugins/appearance.js new file mode 100644 index 000000000..a1cd31b9b --- /dev/null +++ b/src/plugins/appearance.js @@ -0,0 +1,10 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.appearance-none': { appearance: 'none' }, + }, + config('modules.appearance') + ) + } +} diff --git a/src/plugins/backgroundAttachment.js b/src/plugins/backgroundAttachment.js new file mode 100644 index 000000000..75fc3f4c4 --- /dev/null +++ b/src/plugins/backgroundAttachment.js @@ -0,0 +1,12 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.bg-fixed': { 'background-attachment': 'fixed' }, + '.bg-local': { 'background-attachment': 'local' }, + '.bg-scroll': { 'background-attachment': 'scroll' }, + }, + config('modules.backgroundAttachment') + ) + } +} diff --git a/src/plugins/backgroundColors.js b/src/plugins/backgroundColors.js new file mode 100644 index 000000000..0d7d47d25 --- /dev/null +++ b/src/plugins/backgroundColors.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('backgroundColors'), (value, modifier) => { + return [ + `.${e(`bg-${modifier}`)}`, + { + 'background-color': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.backgroundColors')) + } +} diff --git a/src/plugins/backgroundPosition.js b/src/plugins/backgroundPosition.js new file mode 100644 index 000000000..3a5144b45 --- /dev/null +++ b/src/plugins/backgroundPosition.js @@ -0,0 +1,18 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.bg-bottom': { 'background-position': 'bottom' }, + '.bg-center': { 'background-position': 'center' }, + '.bg-left': { 'background-position': 'left' }, + '.bg-left-bottom': { 'background-position': 'left bottom' }, + '.bg-left-top': { 'background-position': 'left top' }, + '.bg-right': { 'background-position': 'right' }, + '.bg-right-bottom': { 'background-position': 'right bottom' }, + '.bg-right-top': { 'background-position': 'right top' }, + '.bg-top': { 'background-position': 'top' }, + }, + config('modules.backgroundPosition') + ) + } +} diff --git a/src/plugins/backgroundRepeat.js b/src/plugins/backgroundRepeat.js new file mode 100644 index 000000000..d7f9aac55 --- /dev/null +++ b/src/plugins/backgroundRepeat.js @@ -0,0 +1,13 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.bg-repeat': { 'background-repeat': 'repeat' }, + '.bg-no-repeat': { 'background-repeat': 'no-repeat' }, + '.bg-repeat-x': { 'background-repeat': 'repeat-x' }, + '.bg-repeat-y': { 'background-repeat': 'repeat-y' }, + }, + config('modules.backgroundRepeat') + ) + } +} diff --git a/src/plugins/backgroundSize.js b/src/plugins/backgroundSize.js new file mode 100644 index 000000000..80bd9eec4 --- /dev/null +++ b/src/plugins/backgroundSize.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('backgroundSize'), (value, modifier) => { + return [ + `.${e(`bg-${modifier}`)}`, + { + 'background-size': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.opacity')) + } +} diff --git a/src/plugins/borderCollapse.js b/src/plugins/borderCollapse.js new file mode 100644 index 000000000..b3e39ca93 --- /dev/null +++ b/src/plugins/borderCollapse.js @@ -0,0 +1,11 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.border-collapse': { 'border-collapse': 'collapse' }, + '.border-separate': { 'border-collapse': 'separate' }, + }, + config('modules.borderCollapse') + ) + } +} diff --git a/src/plugins/borderColors.js b/src/plugins/borderColors.js new file mode 100644 index 000000000..251c92963 --- /dev/null +++ b/src/plugins/borderColors.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(_.omit(config('borderColors'), 'default'), (value, modifier) => { + return [ + `.${e(`border-${modifier}`)}`, + { + 'border-color': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.borderColors')) + } +} diff --git a/src/plugins/borderRadius.js b/src/plugins/borderRadius.js new file mode 100644 index 000000000..05f748465 --- /dev/null +++ b/src/plugins/borderRadius.js @@ -0,0 +1,43 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const generators = [ + (value, modifier) => ({ + [`.${e(`rounded${modifier}`)}`]: { borderRadius: `${value}` }, + }), + (value, modifier) => ({ + [`.${e(`rounded-t${modifier}`)}`]: { + borderTopLeftRadius: `${value}`, + borderTopRightRadius: `${value}`, + }, + [`.${e(`rounded-r${modifier}`)}`]: { + borderTopRightRadius: `${value}`, + borderBottomRightRadius: `${value}`, + }, + [`.${e(`rounded-b${modifier}`)}`]: { + borderBottomRightRadius: `${value}`, + borderBottomLeftRadius: `${value}`, + }, + [`.${e(`rounded-l${modifier}`)}`]: { + borderTopLeftRadius: `${value}`, + borderBottomLeftRadius: `${value}`, + }, + }), + (value, modifier) => ({ + [`.${e(`rounded-tl${modifier}`)}`]: { borderTopLeftRadius: `${value}` }, + [`.${e(`rounded-tr${modifier}`)}`]: { borderTopRightRadius: `${value}` }, + [`.${e(`rounded-br${modifier}`)}`]: { borderBottomRightRadius: `${value}` }, + [`.${e(`rounded-bl${modifier}`)}`]: { borderBottomLeftRadius: `${value}` }, + }), + ] + + const utilities = _.flatMap(generators, generator => { + return _.flatMap(config('borderRadius'), (value, modifier) => { + return generator(value, modifier === 'default' ? '' : `-${modifier}`) + }) + }) + + addUtilities(utilities, config('modules.borderRadius')) + } +} diff --git a/src/plugins/borderStyle.js b/src/plugins/borderStyle.js new file mode 100644 index 000000000..120033aec --- /dev/null +++ b/src/plugins/borderStyle.js @@ -0,0 +1,21 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.border-solid': { + 'border-style': 'solid', + }, + '.border-dashed': { + 'border-style': 'dashed', + }, + '.border-dotted': { + 'border-style': 'dotted', + }, + '.border-none': { + 'border-style': 'none', + }, + }, + config('modules.borderStyle') + ) + } +} diff --git a/src/plugins/borderWidths.js b/src/plugins/borderWidths.js new file mode 100644 index 000000000..29960705b --- /dev/null +++ b/src/plugins/borderWidths.js @@ -0,0 +1,25 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const generators = [ + (value, modifier) => ({ + [`.${e(`border${modifier}`)}`]: { borderWidth: `${value}` }, + }), + (value, modifier) => ({ + [`.${e(`border-t${modifier}`)}`]: { borderTopWidth: `${value}` }, + [`.${e(`border-r${modifier}`)}`]: { borderRightWidth: `${value}` }, + [`.${e(`border-b${modifier}`)}`]: { borderBottomWidth: `${value}` }, + [`.${e(`border-l${modifier}`)}`]: { borderLeftWidth: `${value}` }, + }), + ] + + const utilities = _.flatMap(generators, generator => { + return _.flatMap(config('borderWidths'), (value, modifier) => { + return generator(value, modifier === 'default' ? '' : `-${modifier}`) + }) + }) + + addUtilities(utilities, config('modules.borderWidths')) + } +} diff --git a/src/plugins/cursor.js b/src/plugins/cursor.js new file mode 100644 index 000000000..aae914fb1 --- /dev/null +++ b/src/plugins/cursor.js @@ -0,0 +1,15 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.cursor-auto': { cursor: 'auto' }, + '.cursor-default': { cursor: 'default' }, + '.cursor-pointer': { cursor: 'pointer' }, + '.cursor-wait': { cursor: 'wait' }, + '.cursor-move': { cursor: 'move' }, + '.cursor-not-allowed': { cursor: 'not-allowed' }, + }, + config('modules.cursor') + ) + } +} diff --git a/src/plugins/display.js b/src/plugins/display.js new file mode 100644 index 000000000..3208ca3c8 --- /dev/null +++ b/src/plugins/display.js @@ -0,0 +1,30 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.block': { + display: 'block', + }, + '.inline-block': { + display: 'inline-block', + }, + '.inline': { + display: 'inline', + }, + '.table': { + display: 'table', + }, + '.table-row': { + display: 'table-row', + }, + '.table-cell': { + display: 'table-cell', + }, + '.hidden': { + display: 'none', + }, + }, + config('modules.display') + ) + } +} diff --git a/src/plugins/flexbox.js b/src/plugins/flexbox.js new file mode 100644 index 000000000..ef38e2234 --- /dev/null +++ b/src/plugins/flexbox.js @@ -0,0 +1,120 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.flex': { + display: 'flex', + }, + '.inline-flex': { + display: 'inline-flex', + }, + '.flex-row': { + 'flex-direction': 'row', + }, + '.flex-row-reverse': { + 'flex-direction': 'row-reverse', + }, + '.flex-col': { + 'flex-direction': 'column', + }, + '.flex-col-reverse': { + 'flex-direction': 'column-reverse', + }, + '.flex-wrap': { + 'flex-wrap': 'wrap', + }, + '.flex-wrap-reverse': { + 'flex-wrap': 'wrap-reverse', + }, + '.flex-no-wrap': { + 'flex-wrap': 'nowrap', + }, + '.items-start': { + 'align-items': 'flex-start', + }, + '.items-end': { + 'align-items': 'flex-end', + }, + '.items-center': { + 'align-items': 'center', + }, + '.items-baseline': { + 'align-items': 'baseline', + }, + '.items-stretch': { + 'align-items': 'stretch', + }, + '.self-auto': { + 'align-self': 'auto', + }, + '.self-start': { + 'align-self': 'flex-start', + }, + '.self-end': { + 'align-self': 'flex-end', + }, + '.self-center': { + 'align-self': 'center', + }, + '.self-stretch': { + 'align-self': 'stretch', + }, + '.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', + }, + '.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', + }, + '.flex-1': { + flex: '1 1 0%', + }, + '.flex-auto': { + flex: '1 1 auto', + }, + '.flex-initial': { + flex: '0 1 auto', + }, + '.flex-none': { + flex: 'none', + }, + '.flex-grow': { + 'flex-grow': '1', + }, + '.flex-shrink': { + 'flex-shrink': '1', + }, + '.flex-no-grow': { + 'flex-grow': '0', + }, + '.flex-no-shrink': { + 'flex-shrink': '0', + }, + }, + config('modules.flexbox') + ) + } +} diff --git a/src/plugins/float.js b/src/plugins/float.js new file mode 100644 index 000000000..6ae4eb86e --- /dev/null +++ b/src/plugins/float.js @@ -0,0 +1,17 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.float-right': { float: 'right' }, + '.float-left': { float: 'left' }, + '.float-none': { float: 'none' }, + '.clearfix:after': { + content: '""', + display: 'table', + clear: 'both', + }, + }, + config('modules.float') + ) + } +} diff --git a/src/plugins/fontWeights.js b/src/plugins/fontWeights.js new file mode 100644 index 000000000..659956cd2 --- /dev/null +++ b/src/plugins/fontWeights.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('fontWeights'), (value, modifier) => { + return [ + `.${e(`font-${modifier}`)}`, + { + 'font-weight': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.fontWeights')) + } +} diff --git a/src/plugins/fonts.js b/src/plugins/fonts.js new file mode 100644 index 000000000..1cd374d88 --- /dev/null +++ b/src/plugins/fonts.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('fonts'), (value, modifier) => { + return [ + `.${e(`font-${modifier}`)}`, + { + 'font-family': _.isArray(value) ? value.join(', ') : value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.fonts')) + } +} diff --git a/src/plugins/height.js b/src/plugins/height.js new file mode 100644 index 000000000..17d3b6a69 --- /dev/null +++ b/src/plugins/height.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('height'), (value, modifier) => { + return [ + `.${e(`h-${modifier}`)}`, + { + height: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.height')) + } +} diff --git a/src/plugins/leading.js b/src/plugins/leading.js new file mode 100644 index 000000000..b1b5c5216 --- /dev/null +++ b/src/plugins/leading.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('leading'), (value, modifier) => { + return [ + `.${e(`leading-${modifier}`)}`, + { + 'line-height': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.leading')) + } +} diff --git a/src/plugins/lists.js b/src/plugins/lists.js new file mode 100644 index 000000000..13cb1c786 --- /dev/null +++ b/src/plugins/lists.js @@ -0,0 +1,13 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.list-reset': { + 'list-style': 'none', + padding: '0', + }, + }, + config('modules.lists') + ) + } +} diff --git a/src/plugins/margin.js b/src/plugins/margin.js new file mode 100644 index 000000000..b7c748876 --- /dev/null +++ b/src/plugins/margin.js @@ -0,0 +1,27 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const generators = [ + (size, modifier) => ({ + [`.${e(`m-${modifier}`)}`]: { margin: `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`my-${modifier}`)}`]: { 'margin-top': `${size}`, 'margin-bottom': `${size}` }, + [`.${e(`mx-${modifier}`)}`]: { 'margin-left': `${size}`, 'margin-right': `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`mt-${modifier}`)}`]: { 'margin-top': `${size}` }, + [`.${e(`mr-${modifier}`)}`]: { 'margin-right': `${size}` }, + [`.${e(`mb-${modifier}`)}`]: { 'margin-bottom': `${size}` }, + [`.${e(`ml-${modifier}`)}`]: { 'margin-left': `${size}` }, + }), + ] + + const utilities = _.flatMap(generators, generator => { + return _.flatMap(config('margin'), generator) + }) + + addUtilities(utilities, config('modules.margin')) + } +} diff --git a/src/plugins/maxHeight.js b/src/plugins/maxHeight.js new file mode 100644 index 000000000..ba1784db6 --- /dev/null +++ b/src/plugins/maxHeight.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('maxHeight'), (value, modifier) => { + return [ + `.${e(`max-h-${modifier}`)}`, + { + 'max-height': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.maxHeight')) + } +} diff --git a/src/plugins/maxWidth.js b/src/plugins/maxWidth.js new file mode 100644 index 000000000..ba3798e45 --- /dev/null +++ b/src/plugins/maxWidth.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('maxWidth'), (value, modifier) => { + return [ + `.${e(`max-w-${modifier}`)}`, + { + 'max-width': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.maxWidth')) + } +} diff --git a/src/plugins/minHeight.js b/src/plugins/minHeight.js new file mode 100644 index 000000000..6f2966e90 --- /dev/null +++ b/src/plugins/minHeight.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('minHeight'), (value, modifier) => { + return [ + `.${e(`min-h-${modifier}`)}`, + { + 'min-height': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.minHeight')) + } +} diff --git a/src/plugins/minWidth.js b/src/plugins/minWidth.js new file mode 100644 index 000000000..bd56df4f3 --- /dev/null +++ b/src/plugins/minWidth.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('minWidth'), (value, modifier) => { + return [ + `.${e(`min-w-${modifier}`)}`, + { + 'min-width': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.minWidth')) + } +} diff --git a/src/plugins/negativeMargin.js b/src/plugins/negativeMargin.js new file mode 100644 index 000000000..e3796f9e9 --- /dev/null +++ b/src/plugins/negativeMargin.js @@ -0,0 +1,29 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const generators = [ + (size, modifier) => ({ + [`.${e(`-m-${modifier}`)}`]: { margin: `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`-my-${modifier}`)}`]: { 'margin-top': `${size}`, 'margin-bottom': `${size}` }, + [`.${e(`-mx-${modifier}`)}`]: { 'margin-left': `${size}`, 'margin-right': `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`-mt-${modifier}`)}`]: { 'margin-top': `${size}` }, + [`.${e(`-mr-${modifier}`)}`]: { 'margin-right': `${size}` }, + [`.${e(`-mb-${modifier}`)}`]: { 'margin-bottom': `${size}` }, + [`.${e(`-ml-${modifier}`)}`]: { 'margin-left': `${size}` }, + }), + ] + + const utilities = _.flatMap(generators, generator => { + return _.flatMap(config('negativeMargin'), (size, modifier) => { + return generator(`${size}` === '0' ? `${size}` : `-${size}`, modifier) + }) + }) + + addUtilities(utilities, config('modules.negativeMargin')) + } +} diff --git a/src/plugins/objectFit.js b/src/plugins/objectFit.js new file mode 100644 index 000000000..cd0487915 --- /dev/null +++ b/src/plugins/objectFit.js @@ -0,0 +1,14 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.object-contain': { 'object-fit': 'contain' }, + '.object-cover': { 'object-fit': 'cover' }, + '.object-fill': { 'object-fit': 'fill' }, + '.object-none': { 'object-fit': 'none' }, + '.object-scale-down': { 'object-fit': 'scale-down' }, + }, + config('modules.objectFit') + ) + } +} diff --git a/src/plugins/objectPosition.js b/src/plugins/objectPosition.js new file mode 100644 index 000000000..54af2a1ef --- /dev/null +++ b/src/plugins/objectPosition.js @@ -0,0 +1,18 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.object-bottom': { 'object-position': 'bottom' }, + '.object-center': { 'object-position': 'center' }, + '.object-left': { 'object-position': 'left' }, + '.object-left-bottom': { 'object-position': 'left bottom' }, + '.object-left-top': { 'object-position': 'left top' }, + '.object-right': { 'object-position': 'right' }, + '.object-right-bottom': { 'object-position': 'right bottom' }, + '.object-right-top': { 'object-position': 'right top' }, + '.object-top': { 'object-position': 'top' }, + }, + config('modules.objectPosition') + ) + } +} diff --git a/src/plugins/opacity.js b/src/plugins/opacity.js new file mode 100644 index 000000000..68dd37dbb --- /dev/null +++ b/src/plugins/opacity.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('opacity'), (value, modifier) => { + return [ + `.${e(`opacity-${modifier}`)}`, + { + opacity: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.opacity')) + } +} diff --git a/src/plugins/outline.js b/src/plugins/outline.js new file mode 100644 index 000000000..552f7e511 --- /dev/null +++ b/src/plugins/outline.js @@ -0,0 +1,10 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.outline-none': { outline: '0' }, + }, + config('modules.outline') + ) + } +} diff --git a/src/plugins/overflow.js b/src/plugins/overflow.js new file mode 100644 index 000000000..c4faedd66 --- /dev/null +++ b/src/plugins/overflow.js @@ -0,0 +1,23 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.overflow-auto': { overflow: 'auto' }, + '.overflow-hidden': { overflow: 'hidden' }, + '.overflow-visible': { overflow: 'visible' }, + '.overflow-scroll': { overflow: 'scroll' }, + '.overflow-x-auto': { 'overflow-x': 'auto' }, + '.overflow-y-auto': { 'overflow-y': 'auto' }, + '.overflow-x-hidden': { 'overflow-x': 'hidden' }, + '.overflow-y-hidden': { 'overflow-y': 'hidden' }, + '.overflow-x-visible': { 'overflow-x': 'visible' }, + '.overflow-y-visible': { 'overflow-y': 'visible' }, + '.overflow-x-scroll': { 'overflow-x': 'scroll' }, + '.overflow-y-scroll': { 'overflow-y': 'scroll' }, + '.scrolling-touch': { '-webkit-overflow-scrolling': 'touch' }, + '.scrolling-auto': { '-webkit-overflow-scrolling': 'auto' }, + }, + config('modules.overflow') + ) + } +} diff --git a/src/plugins/padding.js b/src/plugins/padding.js new file mode 100644 index 000000000..519604576 --- /dev/null +++ b/src/plugins/padding.js @@ -0,0 +1,27 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const generators = [ + (size, modifier) => ({ + [`.${e(`p-${modifier}`)}`]: { padding: `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`py-${modifier}`)}`]: { 'padding-top': `${size}`, 'padding-bottom': `${size}` }, + [`.${e(`px-${modifier}`)}`]: { 'padding-left': `${size}`, 'padding-right': `${size}` }, + }), + (size, modifier) => ({ + [`.${e(`pt-${modifier}`)}`]: { 'padding-top': `${size}` }, + [`.${e(`pr-${modifier}`)}`]: { 'padding-right': `${size}` }, + [`.${e(`pb-${modifier}`)}`]: { 'padding-bottom': `${size}` }, + [`.${e(`pl-${modifier}`)}`]: { 'padding-left': `${size}` }, + }), + ] + + const utilities = _.flatMap(generators, generator => { + return _.flatMap(config('padding'), generator) + }) + + addUtilities(utilities, config('modules.padding')) + } +} diff --git a/src/plugins/pointerEvents.js b/src/plugins/pointerEvents.js new file mode 100644 index 000000000..31ee1f8c2 --- /dev/null +++ b/src/plugins/pointerEvents.js @@ -0,0 +1,11 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.pointer-events-none': { 'pointer-events': 'none' }, + '.pointer-events-auto': { 'pointer-events': 'auto' }, + }, + config('modules.pointerEvents') + ) + } +} diff --git a/src/plugins/position.js b/src/plugins/position.js new file mode 100644 index 000000000..595235700 --- /dev/null +++ b/src/plugins/position.js @@ -0,0 +1,32 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.static': { position: 'static' }, + '.fixed': { position: 'fixed' }, + '.absolute': { position: 'absolute' }, + '.relative': { position: 'relative' }, + '.sticky': { position: 'sticky' }, + '.pin-none': { + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto', + }, + '.pin': { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + '.pin-y': { top: 0, bottom: 0 }, + '.pin-x': { right: 0, left: 0 }, + '.pin-t': { top: 0 }, + '.pin-r': { right: 0 }, + '.pin-b': { bottom: 0 }, + '.pin-l': { left: 0 }, + }, + config('modules.position') + ) + } +} diff --git a/src/plugins/resize.js b/src/plugins/resize.js new file mode 100644 index 000000000..362686c05 --- /dev/null +++ b/src/plugins/resize.js @@ -0,0 +1,13 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.resize-none': { resize: 'none' }, + '.resize-y': { resize: 'vertical' }, + '.resize-x': { resize: 'horizontal' }, + '.resize': { resize: 'both' }, + }, + config('modules.resize') + ) + } +} diff --git a/src/plugins/shadows.js b/src/plugins/shadows.js new file mode 100644 index 000000000..b19054ed4 --- /dev/null +++ b/src/plugins/shadows.js @@ -0,0 +1,19 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('shadows'), (value, modifier) => { + const className = modifier === 'default' ? 'shadow' : `shadow-${modifier}` + return [ + `.${e(className)}`, + { + 'box-shadow': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.shadows')) + } +} diff --git a/src/plugins/svgFill.js b/src/plugins/svgFill.js new file mode 100644 index 000000000..f4ccba344 --- /dev/null +++ b/src/plugins/svgFill.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('svgFill'), (value, modifier) => { + return [ + `.${e(`fill-${modifier}`)}`, + { + fill: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.svgFill')) + } +} diff --git a/src/plugins/svgStroke.js b/src/plugins/svgStroke.js new file mode 100644 index 000000000..9937cc01f --- /dev/null +++ b/src/plugins/svgStroke.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('svgStroke'), (value, modifier) => { + return [ + `.${e(`stroke-${modifier}`)}`, + { + stroke: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.svgStroke')) + } +} diff --git a/src/plugins/tableLayout.js b/src/plugins/tableLayout.js new file mode 100644 index 000000000..98b090cdd --- /dev/null +++ b/src/plugins/tableLayout.js @@ -0,0 +1,11 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.table-auto': { 'table-layout': 'auto' }, + '.table-fixed': { 'table-layout': 'fixed' }, + }, + config('modules.tableLayout') + ) + } +} diff --git a/src/plugins/textAlign.js b/src/plugins/textAlign.js new file mode 100644 index 000000000..80ce95c39 --- /dev/null +++ b/src/plugins/textAlign.js @@ -0,0 +1,13 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.text-left': { 'text-align': 'left' }, + '.text-center': { 'text-align': 'center' }, + '.text-right': { 'text-align': 'right' }, + '.text-justify': { 'text-align': 'justify' }, + }, + config('modules.textAlign') + ) + } +} diff --git a/src/plugins/textColors.js b/src/plugins/textColors.js new file mode 100644 index 000000000..9652313da --- /dev/null +++ b/src/plugins/textColors.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('textColors'), (value, modifier) => { + return [ + `.${e(`text-${modifier}`)}`, + { + color: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.textColors')) + } +} diff --git a/src/plugins/textSizes.js b/src/plugins/textSizes.js new file mode 100644 index 000000000..c2f896b90 --- /dev/null +++ b/src/plugins/textSizes.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('textSizes'), (value, modifier) => { + return [ + `.${e(`text-${modifier}`)}`, + { + 'font-size': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.textSizes')) + } +} diff --git a/src/plugins/textStyle.js b/src/plugins/textStyle.js new file mode 100644 index 000000000..7a0c03bd7 --- /dev/null +++ b/src/plugins/textStyle.js @@ -0,0 +1,29 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.italic': { 'font-style': 'italic' }, + '.roman': { 'font-style': 'normal' }, + + '.uppercase': { 'text-transform': 'uppercase' }, + '.lowercase': { 'text-transform': 'lowercase' }, + '.capitalize': { 'text-transform': 'capitalize' }, + '.normal-case': { 'text-transform': 'none' }, + + '.underline': { 'text-decoration': 'underline' }, + '.line-through': { 'text-decoration': 'line-through' }, + '.no-underline': { 'text-decoration': 'none' }, + + '.antialiased': { + '-webkit-font-smoothing': 'antialiased', + '-moz-osx-font-smoothing': 'grayscale', + }, + '.subpixel-antialiased': { + '-webkit-font-smoothing': 'auto', + '-moz-osx-font-smoothing': 'auto', + }, + }, + config('modules.textStyle') + ) + } +} diff --git a/src/plugins/tracking.js b/src/plugins/tracking.js new file mode 100644 index 000000000..1fd6f185c --- /dev/null +++ b/src/plugins/tracking.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config }) { + const utilities = _.fromPairs( + _.map(config('tracking'), (value, modifier) => { + return [ + `.tracking-${modifier}`, + { + 'letter-spacing': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.tracking')) + } +} diff --git a/src/plugins/userSelect.js b/src/plugins/userSelect.js new file mode 100644 index 000000000..5fc759c15 --- /dev/null +++ b/src/plugins/userSelect.js @@ -0,0 +1,11 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.select-none': { 'user-select': 'none' }, + '.select-text': { 'user-select': 'text' }, + }, + config('modules.userSelect') + ) + } +} diff --git a/src/plugins/verticalAlign.js b/src/plugins/verticalAlign.js new file mode 100644 index 000000000..374a9da91 --- /dev/null +++ b/src/plugins/verticalAlign.js @@ -0,0 +1,15 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.align-baseline': { 'vertical-align': 'baseline' }, + '.align-top': { 'vertical-align': 'top' }, + '.align-middle': { 'vertical-align': 'middle' }, + '.align-bottom': { 'vertical-align': 'bottom' }, + '.align-text-top': { 'vertical-align': 'text-top' }, + '.align-text-bottom': { 'vertical-align': 'text-bottom' }, + }, + config('modules.verticalAlign') + ) + } +} diff --git a/src/plugins/visibility.js b/src/plugins/visibility.js new file mode 100644 index 000000000..9c5061d6e --- /dev/null +++ b/src/plugins/visibility.js @@ -0,0 +1,11 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.visible': { visibility: 'visible' }, + '.invisible': { visibility: 'hidden' }, + }, + config('modules.visibility') + ) + } +} diff --git a/src/plugins/whitespace.js b/src/plugins/whitespace.js new file mode 100644 index 000000000..4f3b2bee4 --- /dev/null +++ b/src/plugins/whitespace.js @@ -0,0 +1,23 @@ +export default function() { + return function({ addUtilities, config }) { + addUtilities( + { + '.whitespace-normal': { 'white-space': 'normal' }, + '.whitespace-no-wrap': { 'white-space': 'nowrap' }, + '.whitespace-pre': { 'white-space': 'pre' }, + '.whitespace-pre-line': { 'white-space': 'pre-line' }, + '.whitespace-pre-wrap': { 'white-space': 'pre-wrap' }, + + '.break-words': { 'word-wrap': 'break-word' }, + '.break-normal': { 'word-wrap': 'normal' }, + + '.truncate': { + overflow: 'hidden', + 'text-overflow': 'ellipsis', + 'white-space': 'nowrap', + }, + }, + config('modules.whitespace') + ) + } +} diff --git a/src/plugins/width.js b/src/plugins/width.js new file mode 100644 index 000000000..a83ed16e6 --- /dev/null +++ b/src/plugins/width.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config, e }) { + const utilities = _.fromPairs( + _.map(config('width'), (value, modifier) => { + return [ + `.${e(`w-${modifier}`)}`, + { + width: value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.width')) + } +} diff --git a/src/plugins/zIndex.js b/src/plugins/zIndex.js new file mode 100644 index 000000000..31f224b58 --- /dev/null +++ b/src/plugins/zIndex.js @@ -0,0 +1,18 @@ +import _ from 'lodash' + +export default function() { + return function({ addUtilities, config }) { + const utilities = _.fromPairs( + _.map(config('zIndex'), (value, modifier) => { + return [ + `.z-${modifier}`, + { + 'z-index': value, + }, + ] + }) + ) + + addUtilities(utilities, config('modules.zIndex')) + } +} diff --git a/src/processTailwindFeatures.js b/src/processTailwindFeatures.js index 51595f6f0..34b4299cf 100644 --- a/src/processTailwindFeatures.js +++ b/src/processTailwindFeatures.js @@ -8,22 +8,21 @@ import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules' import substituteScreenAtRules from './lib/substituteScreenAtRules' import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules' -import generateUtilities from './util/generateUtilities' import processPlugins from './util/processPlugins' +import defaultPlugins from './defaultPlugins' export default function(getConfig) { return function(css) { const config = getConfig() - const processedPlugins = processPlugins(config) - const utilities = generateUtilities(config, processedPlugins.utilities) + const processedPlugins = processPlugins([...defaultPlugins(config), ...config.plugins], config) return postcss([ - substituteTailwindAtRules(config, processedPlugins, utilities), + substituteTailwindAtRules(config, processedPlugins), evaluateTailwindFunctions(config), substituteVariantsAtRules(config, processedPlugins), substituteResponsiveAtRules(config), substituteScreenAtRules(config), - substituteClassApplyAtRules(config, utilities), + substituteClassApplyAtRules(config, processedPlugins.utilities), ]).process(css, { from: _.get(css, 'source.input.file') }) } } diff --git a/src/util/collapseWhitespace.js b/src/util/collapseWhitespace.js deleted file mode 100644 index 842031b59..000000000 --- a/src/util/collapseWhitespace.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function collapseWhitespace(str) { - return str.replace(/(\n|\r|\r\n)/g, ' ').replace(/\s+/g, ' ') -} diff --git a/src/util/defineClass.js b/src/util/defineClass.js deleted file mode 100644 index 8ccb3aa69..000000000 --- a/src/util/defineClass.js +++ /dev/null @@ -1,18 +0,0 @@ -import _ from 'lodash' -import postcss from 'postcss' -import escapeClassName from './escapeClassName' - -export default function(className, properties) { - const decls = _.map(properties, (value, property) => { - return postcss.decl({ - prop: `${property}`, - value: `${value}`, - }) - }) - - return postcss - .rule({ - selector: `.${escapeClassName(className)}`, - }) - .append(decls) -} diff --git a/src/util/defineClasses.js b/src/util/defineClasses.js deleted file mode 100644 index 4f80aef30..000000000 --- a/src/util/defineClasses.js +++ /dev/null @@ -1,8 +0,0 @@ -import _ from 'lodash' -import defineClass from './defineClass' - -export default function defineClasses(classes) { - return _.map(classes, (properties, className) => { - return defineClass(className, properties) - }) -} diff --git a/src/util/generateModules.js b/src/util/generateModules.js deleted file mode 100644 index 060f12943..000000000 --- a/src/util/generateModules.js +++ /dev/null @@ -1,20 +0,0 @@ -import _ from 'lodash' -import postcss from 'postcss' -import wrapWithVariants from '../util/wrapWithVariants' - -export default function(modules, moduleOptions, generatorOptions = {}) { - modules.forEach(module => { - if (!_.has(moduleOptions, module.name)) { - throw new Error(`Module \`${module.name}\` is missing from moduleOptions.`) - } - }) - - return postcss.root({ - nodes: _(modules) - .reject(module => moduleOptions[module.name] === false) - .flatMap(module => - wrapWithVariants(module.generator(generatorOptions), moduleOptions[module.name]) - ) - .value(), - }) -} diff --git a/src/util/generateUtilities.js b/src/util/generateUtilities.js deleted file mode 100644 index 8101961d0..000000000 --- a/src/util/generateUtilities.js +++ /dev/null @@ -1,20 +0,0 @@ -import postcss from 'postcss' -import utilityModules from '../utilityModules' -import prefixTree from '../util/prefixTree' -import generateModules from '../util/generateModules' - -export default function(config, pluginUtilities) { - const utilities = generateModules(utilityModules, config.modules, config) - - if (config.options.important) { - utilities.walkDecls(decl => (decl.important = true)) - } - - const tailwindUtilityTree = postcss.root({ - nodes: utilities.nodes, - }) - - prefixTree(tailwindUtilityTree, config.options.prefix) - - return [...tailwindUtilityTree.nodes, ...pluginUtilities] -} diff --git a/src/util/prefixTree.js b/src/util/prefixTree.js deleted file mode 100644 index 44499e9e6..000000000 --- a/src/util/prefixTree.js +++ /dev/null @@ -1,9 +0,0 @@ -import prefixSelector from './prefixSelector' - -export default function(css, prefix) { - css.walkRules(rule => { - rule.selectors = rule.selectors.map(selector => prefixSelector(prefix, selector)) - }) - - return css -} diff --git a/src/util/processPlugins.js b/src/util/processPlugins.js index bc7dd6bdb..07c9d3024 100644 --- a/src/util/processPlugins.js +++ b/src/util/processPlugins.js @@ -15,12 +15,12 @@ function parseStyles(styles) { return _.flatMap(styles, style => (style instanceof Node ? style : parseObjectStyles(style))) } -export default function(config) { +export default function(plugins, config) { const pluginComponents = [] const pluginUtilities = [] const pluginVariantGenerators = {} - config.plugins.forEach(plugin => { + plugins.forEach(plugin => { plugin({ config: (path, defaultValue) => _.get(config, path, defaultValue), e: escapeClassName, diff --git a/src/utilityModules.js b/src/utilityModules.js deleted file mode 100644 index 01f37dce3..000000000 --- a/src/utilityModules.js +++ /dev/null @@ -1,103 +0,0 @@ -import lists from './generators/lists' -import appearance from './generators/appearance' -import backgroundAttachment from './generators/backgroundAttachment' -import backgroundColors from './generators/backgroundColors' -import backgroundPosition from './generators/backgroundPosition' -import backgroundRepeat from './generators/backgroundRepeat' -import backgroundSize from './generators/backgroundSize' -import borderCollapse from './generators/borderCollapse' -import borderColors from './generators/borderColors' -import borderRadius from './generators/borderRadius' -import borderStyle from './generators/borderStyle' -import borderWidths from './generators/borderWidths' -import cursor from './generators/cursor' -import display from './generators/display' -import flexbox from './generators/flexbox' -import float from './generators/float' -import fonts from './generators/fonts' -import fontWeights from './generators/fontWeights' -import height from './generators/height' -import leading from './generators/leading' -import margin from './generators/margin' -import maxHeight from './generators/maxHeight' -import maxWidth from './generators/maxWidth' -import minHeight from './generators/minHeight' -import minWidth from './generators/minWidth' -import negativeMargin from './generators/negativeMargin' -import objectFit from './generators/objectFit' -import objectPosition from './generators/objectPosition' -import opacity from './generators/opacity' -import outline from './generators/outline' -import overflow from './generators/overflow' -import padding from './generators/padding' -import pointerEvents from './generators/pointerEvents' -import position from './generators/position' -import resize from './generators/resize' -import shadows from './generators/shadows' -import svgFill from './generators/svgFill' -import svgStroke from './generators/svgStroke' -import tableLayout from './generators/tableLayout' -import textAlign from './generators/textAlign' -import textColors from './generators/textColors' -import textSizes from './generators/textSizes' -import textStyle from './generators/textStyle' -import tracking from './generators/tracking' -import userSelect from './generators/userSelect' -import verticalAlign from './generators/verticalAlign' -import visibility from './generators/visibility' -import whitespace from './generators/whitespace' -import width from './generators/width' -import zIndex from './generators/zIndex' - -export default [ - { name: 'lists', generator: lists }, - { name: 'appearance', generator: appearance }, - { name: 'backgroundAttachment', generator: backgroundAttachment }, - { name: 'backgroundColors', generator: backgroundColors }, - { name: 'backgroundPosition', generator: backgroundPosition }, - { name: 'backgroundRepeat', generator: backgroundRepeat }, - { name: 'backgroundSize', generator: backgroundSize }, - { name: 'borderCollapse', generator: borderCollapse }, - { name: 'borderColors', generator: borderColors }, - { name: 'borderRadius', generator: borderRadius }, - { name: 'borderStyle', generator: borderStyle }, - { name: 'borderWidths', generator: borderWidths }, - { name: 'cursor', generator: cursor }, - { name: 'display', generator: display }, - { name: 'flexbox', generator: flexbox }, - { name: 'float', generator: float }, - { name: 'fonts', generator: fonts }, - { name: 'fontWeights', generator: fontWeights }, - { name: 'height', generator: height }, - { name: 'leading', generator: leading }, - { name: 'margin', generator: margin }, - { name: 'maxHeight', generator: maxHeight }, - { name: 'maxWidth', generator: maxWidth }, - { name: 'minHeight', generator: minHeight }, - { name: 'minWidth', generator: minWidth }, - { name: 'negativeMargin', generator: negativeMargin }, - { name: 'objectFit', generator: objectFit }, - { name: 'objectPosition', generator: objectPosition }, - { name: 'opacity', generator: opacity }, - { name: 'outline', generator: outline }, - { name: 'overflow', generator: overflow }, - { name: 'padding', generator: padding }, - { name: 'pointerEvents', generator: pointerEvents }, - { name: 'position', generator: position }, - { name: 'resize', generator: resize }, - { name: 'shadows', generator: shadows }, - { name: 'svgFill', generator: svgFill }, - { name: 'svgStroke', generator: svgStroke }, - { name: 'tableLayout', generator: tableLayout }, - { name: 'textAlign', generator: textAlign }, - { name: 'textColors', generator: textColors }, - { name: 'textSizes', generator: textSizes }, - { name: 'textStyle', generator: textStyle }, - { name: 'tracking', generator: tracking }, - { name: 'userSelect', generator: userSelect }, - { name: 'verticalAlign', generator: verticalAlign }, - { name: 'visibility', generator: visibility }, - { name: 'whitespace', generator: whitespace }, - { name: 'width', generator: width }, - { name: 'zIndex', generator: zIndex }, -]