diff --git a/index.js b/index.js index 1c48474..5a81f6d 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,42 @@ const plugin = require("tailwindcss/plugin"); -const { map, fromPairs, find } = require("lodash"); +const { map, fromPairs, find, isPlainObject, get } = require("lodash"); + +const parser = require("postcss-selector-parser"); + +const escapeClassName = (className) => { + const node = parser.className(); + node.value = className; + return get(node, "raws.value", node.value); +}; const stripUnit = (string) => string.match(/[\d.]+/)[0]; +const asClass = (name) => `.${escapeClassName(name)}`; + +const nameClass = (classPrefix, key) => { + if (key === "DEFAULT") { + return asClass(classPrefix); + } + + if (key === "-") { + return asClass(`-${classPrefix}`); + } + + if (key.startsWith("-")) { + return asClass(`-${classPrefix}${key}`); + } + + return asClass(`${classPrefix}-${key}`); +}; + +const offsetFromLineHeight = (value) => { + const valueStripped = stripUnit(value); + + return valueStripped === value + ? (Number(value) - 1) / -2 + "em" + : `calc( (${value} - 1em) / -2)`; +}; + const fontMetricsList = require("./metrics.json"); module.exports = plugin( @@ -10,17 +44,17 @@ module.exports = plugin( addUtilities({ ".trim-start": { "margin-top": - "calc( var(--leading-offset) + var(--font-offset-start,0) )", + "calc( var(--leading-offset,-.25em) + var(--font-offset-start,0em) )", }, ".trim-end": { "margin-bottom": - "calc( var(--leading-offset) + var(--font-offset-end,0) )", + "calc( var(--leading-offset,-.25em) + var(--font-offset-end,0em) )", }, ".trim-both": { "margin-top": - "calc( var(--leading-offset) + var(--font-offset-start,0) )", + "calc( var(--leading-offset,-.25em) + var(--font-offset-start,0em) )", "margin-bottom": - "calc( var(--leading-offset) + var(--font-offset-end,0) )", + "calc( var(--leading-offset,-.25em) + var(--font-offset-end,0em) )", }, }); @@ -65,19 +99,44 @@ module.exports = plugin( addUtilities(fontFamilyUtilities, variants("fontFamily")); + const fontSizeUtilities = fromPairs( + map(theme("fontSize"), (value, modifier) => { + const [fontSize, options] = Array.isArray(value) ? value : [value]; + const { lineHeight, letterSpacing } = isPlainObject(options) + ? options + : { + lineHeight: options, + }; + + return [ + nameClass("text", modifier), + { + "font-size": fontSize, + ...(lineHeight === undefined + ? {} + : { + "line-height": lineHeight, + "--leading-offset": offsetFromLineHeight(lineHeight), + }), + ...(letterSpacing === undefined + ? {} + : { + "letter-spacing": letterSpacing, + }), + }, + ]; + }) + ); + + addUtilities(fontSizeUtilities, variants("fontSize")); + const lineHeightUtilities = fromPairs( map(theme("lineHeight"), (value, modifier) => { - const valueStripped = stripUnit(value); - - const offset = - valueStripped === value - ? (Number(value) - 1) / -2 + "em" - : `calc( (${value} - 1em) / -2)`; return [ `.${e(`leading-${modifier}`)}`, { "line-height": value, - "--leading-offset": offset, + "--leading-offset": offsetFromLineHeight(value), }, ]; }) @@ -88,6 +147,7 @@ module.exports = plugin( { corePlugins: { fontFamily: false, + fontSize: false, lineHeight: false, }, } diff --git a/package.json b/package.json index 7f69611..b2f247b 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,9 @@ ], "license": "WTFPL", "devDependencies": { - "tailwindcss": "^1.7.6", - "tailwindcss-rtl": "^0.4.0" + "tailwindcss": "^2.0.1", + "tailwindcss-rtl": "^0.6.0", + "postcss": "^8.1.9" }, "dependencies": { "capsize": "^1.1.0", diff --git a/test.css b/test.css index 3d2e9cd..76fa966 100644 --- a/test.css +++ b/test.css @@ -1,14 +1,14 @@ .trim-start { - margin-top: calc( var(--leading-offset) + var(--font-offset-start,0) ) + margin-top: calc( var(--leading-offset,-.25em) + var(--font-offset-start,0em) ) } .trim-end { - margin-bottom: calc( var(--leading-offset) + var(--font-offset-end,0) ) + margin-bottom: calc( var(--leading-offset,-.25em) + var(--font-offset-end,0em) ) } .trim-both { - margin-top: calc( var(--leading-offset) + var(--font-offset-start,0) ); - margin-bottom: calc( var(--leading-offset) + var(--font-offset-end,0) ) + margin-top: calc( var(--leading-offset,-.25em) + var(--font-offset-start,0em) ); + margin-bottom: calc( var(--leading-offset,-.25em) + var(--font-offset-end,0em) ) } .font-source-sans { @@ -17,6 +17,84 @@ --font-offset-end: -0.1445em } +.text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) +} + +.text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em +} + +.text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em +} + +.text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em +} + +.text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em +} + +.text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em +} + .leading-3 { line-height: .75rem; --leading-offset: calc( (.75rem - 1em) / -2) @@ -94,6 +172,84 @@ --font-offset-end: -0.1445em } + .sm\:text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .sm\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .sm\:text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .sm\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .sm\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .sm\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .sm\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .sm\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .sm\:text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em + } + + .sm\:text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em + } + + .sm\:text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em + } + + .sm\:text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em + } + + .sm\:text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em + } + .sm\:leading-3 { line-height: .75rem; --leading-offset: calc( (.75rem - 1em) / -2) @@ -172,6 +328,84 @@ --font-offset-end: -0.1445em } + .md\:text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .md\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .md\:text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .md\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .md\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .md\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .md\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .md\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .md\:text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em + } + + .md\:text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em + } + + .md\:text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em + } + + .md\:text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em + } + + .md\:text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em + } + .md\:leading-3 { line-height: .75rem; --leading-offset: calc( (.75rem - 1em) / -2) @@ -250,6 +484,84 @@ --font-offset-end: -0.1445em } + .lg\:text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .lg\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .lg\:text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .lg\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .lg\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .lg\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .lg\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .lg\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .lg\:text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em + } + + .lg\:text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em + } + + .lg\:text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em + } + + .lg\:text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em + } + + .lg\:text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em + } + .lg\:leading-3 { line-height: .75rem; --leading-offset: calc( (.75rem - 1em) / -2) @@ -328,6 +640,84 @@ --font-offset-end: -0.1445em } + .xl\:text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .xl\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .xl\:text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .xl\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .xl\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .xl\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .xl\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .xl\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .xl\:text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em + } + + .xl\:text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em + } + + .xl\:text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em + } + + .xl\:text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em + } + + .xl\:text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em + } + .xl\:leading-3 { line-height: .75rem; --leading-offset: calc( (.75rem - 1em) / -2) @@ -397,4 +787,160 @@ line-height: 2; --leading-offset: -0.5em } +} + +@media (min-width: 1536px) { + .\32xl\:font-source-sans { + font-family: Source Sans Pro; + --font-offset-start: -0.1955em; + --font-offset-end: -0.1445em + } + + .\32xl\:text-xs { + font-size: 0.75rem; + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .\32xl\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .\32xl\:text-base { + font-size: 1rem; + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .\32xl\:text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .\32xl\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .\32xl\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .\32xl\:text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .\32xl\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .\32xl\:text-5xl { + font-size: 3rem; + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:text-6xl { + font-size: 3.75rem; + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:text-7xl { + font-size: 4.5rem; + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:text-8xl { + font-size: 6rem; + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:text-9xl { + font-size: 8rem; + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:leading-3 { + line-height: .75rem; + --leading-offset: calc( (.75rem - 1em) / -2) + } + + .\32xl\:leading-4 { + line-height: 1rem; + --leading-offset: calc( (1rem - 1em) / -2) + } + + .\32xl\:leading-5 { + line-height: 1.25rem; + --leading-offset: calc( (1.25rem - 1em) / -2) + } + + .\32xl\:leading-6 { + line-height: 1.5rem; + --leading-offset: calc( (1.5rem - 1em) / -2) + } + + .\32xl\:leading-7 { + line-height: 1.75rem; + --leading-offset: calc( (1.75rem - 1em) / -2) + } + + .\32xl\:leading-8 { + line-height: 2rem; + --leading-offset: calc( (2rem - 1em) / -2) + } + + .\32xl\:leading-9 { + line-height: 2.25rem; + --leading-offset: calc( (2.25rem - 1em) / -2) + } + + .\32xl\:leading-10 { + line-height: 2.5rem; + --leading-offset: calc( (2.5rem - 1em) / -2) + } + + .\32xl\:leading-none { + line-height: 1; + --leading-offset: 0em + } + + .\32xl\:leading-tight { + line-height: 1.25; + --leading-offset: -0.125em + } + + .\32xl\:leading-snug { + line-height: 1.375; + --leading-offset: -0.1875em + } + + .\32xl\:leading-normal { + line-height: 1.5; + --leading-offset: -0.25em + } + + .\32xl\:leading-relaxed { + line-height: 1.625; + --leading-offset: -0.3125em + } + + .\32xl\:leading-loose { + line-height: 2; + --leading-offset: -0.5em + } } \ No newline at end of file