@tailwindcss/typography
Advanced tools
Comparing version 0.1.4 to 0.2.0-cb415ad
{ | ||
"name": "@tailwindcss/typography", | ||
"version": "0.1.4", | ||
"version": "0.2.0-cb415ad", | ||
"description": "A Tailwind CSS plugin for automatically styling plain HTML content with beautiful typographic defaults.", | ||
@@ -8,3 +8,13 @@ "main": "src/index.js", | ||
"license": "MIT", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"prettier": { | ||
"printWidth": 100, | ||
"semi": false, | ||
"singleQuote": true, | ||
"trailingComma": "es5" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"dev": "next dev demo", | ||
@@ -15,6 +25,6 @@ "build": "next build demo", | ||
"start": "next start demo", | ||
"prepare": "node scripts/build.js" | ||
"prepublishOnly": "node scripts/build.js" | ||
}, | ||
"peerDependencies": { | ||
"tailwindcss": "^1.0" | ||
"tailwindcss": "2.0.0-alpha.24 || ^2.0.0" | ||
}, | ||
@@ -30,8 +40,11 @@ "devDependencies": { | ||
"highlight.js": "^9.15.6", | ||
"jest": "^26.6.1", | ||
"next": "^9.4.4", | ||
"postcss": "^7.0.17", | ||
"prettier": "^2.1.2", | ||
"react": "^16.8.6", | ||
"react-dom": "^16.8.6", | ||
"tailwindcss": "^1.4.6" | ||
"snapshot-diff": "^0.8.1", | ||
"tailwindcss": "^2.0.0-alpha.16" | ||
} | ||
} |
102
README.md
@@ -15,3 +15,3 @@ <p> | ||
## Usage | ||
## Installation | ||
@@ -43,2 +43,34 @@ Install the plugin from npm: | ||
### Using a CDN | ||
If you need to pull in these styles via CDN, you can do so using services like UNPKG or jsDeliver: | ||
```html | ||
<!-- From UNPKG --> | ||
<link | ||
rel="stylesheet" | ||
href="https://unpkg.com/@tailwindcss/typography@0.2.x/dist/typography.min.css" | ||
/> | ||
<!-- From jsDelivr --> | ||
<link | ||
rel="stylesheet" | ||
href="https://cdn.jsdelivr.net/npm/@tailwindcss/typography@0.2.x/dist/typography.min.css" | ||
/> | ||
``` | ||
To use these styles alongside the rest of Tailwind via CDN, we recommend pulling in each layer separately so you can put the styles in the correct order: | ||
```html | ||
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@^1.5/dist/base.min.css" /> | ||
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@^1.5/dist/components.min.css" /> | ||
<link | ||
rel="stylesheet" | ||
href="https://unpkg.com/@tailwindcss/typography@0.2.x/dist/typography.min.css" | ||
/> | ||
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@^1.5/dist/utilities.min.css" /> | ||
``` | ||
## Usage | ||
Now you can use the `prose` classes to add sensible typography styles to any vanilla HTML: | ||
@@ -84,3 +116,3 @@ | ||
Size modifiers are designed to be used with the [multi-class modifier pattern](http://nicolasgallagher.com/about-html-semantics-front-end-architecture/#component-modifiers) and **must be used in conjuction with the base `prose` class**: | ||
Size modifiers are designed to be used with the [multi-class modifier pattern](http://nicolasgallagher.com/about-html-semantics-front-end-architecture/#component-modifiers) and **must be used in conjunction with the base `prose` class**: | ||
@@ -109,2 +141,45 @@ ```html | ||
## Purging unused styles | ||
Since the typography styles are added to the `components` layer and Tailwind only purges `utilities` by default, you will notice that even with the `purge` option configured in your `tailwind.config.js` file, all of the typography styles still remain in your final CSS. | ||
If you'd like to purge unused typography styles, you'll need to use the `mode: 'all'` option in your `purge` configuration: | ||
```js | ||
// tailwind.config.js | ||
module.exports = { | ||
purge: { | ||
mode: 'all', | ||
content: [ | ||
// Paths to your templates here... | ||
], | ||
}, | ||
} | ||
``` | ||
It's important to note that if you are using markdown for any of your source files (perhaps you're working on a blog or similar), that you need to be careful not to accidentally purge styles you actually need. | ||
Markdown files for example contain no actual `h2`, `blockquote`, `strong`, etc. elements, so PurgeCSS will remove those styles because it doesn't think you need them. | ||
You have two options for solving this: | ||
1. Safelist all of the plain HTML elements you need in your config file: | ||
```js | ||
// tailwind.config.js | ||
module.exports = { | ||
purge: { | ||
mode: 'all', | ||
content: [ | ||
// Paths to your templates here... | ||
], | ||
options: { | ||
whitelist: ['h1', 'h2', 'h3', 'p', 'blockquote', 'strong' /* etc. */], | ||
}, | ||
}, | ||
} | ||
``` | ||
2. Use a custom extractor to compile your markdown files _before_ scanning them for tokens. This is more complicated but it is [what we do for the Tailwind blog](https://github.com/tailwindlabs/blog.tailwindcss.com/blob/eb2a0ff80c8e56a79f6514c8dc4253ef84ac5548/tailwind.config.js#L13) for example. | ||
## Customization | ||
@@ -141,2 +216,25 @@ | ||
Like with all theme customizations in Tailwind, you can also define the `typography` key as a function if you need access to the `theme` helper: | ||
```js | ||
// tailwind.config.js | ||
module.exports = { | ||
theme: { | ||
typography: (theme) => ({ | ||
default: { | ||
css: { | ||
color: theme('colors.gray.800'), | ||
// ... | ||
}, | ||
}, | ||
}), | ||
}, | ||
plugins: [ | ||
require('@tailwindcss/typography'), | ||
// ... | ||
], | ||
} | ||
``` | ||
Customizations should be applied to a specific modifier like `default` or `xl`, and must be added under the `css` property. Customizations are authored in the same [CSS-in-JS syntax](https://tailwindcss.com/docs/plugins#css-in-js-syntax) used to write Tailwind plugins. | ||
@@ -143,0 +241,0 @@ |
const plugin = require('tailwindcss/plugin') | ||
const merge = require('lodash/merge') | ||
const castArray = require('lodash/castArray') | ||
const uniq = require('lodash/uniq') | ||
const styles = require('./styles') | ||
const { isUsableColor } = require('./utils') | ||
@@ -11,4 +13,5 @@ const computed = { | ||
function configToCss(config) { | ||
function configToCss(config = {}) { | ||
return merge( | ||
{}, | ||
...Object.keys(config) | ||
@@ -22,27 +25,39 @@ .filter((key) => computed[key]) | ||
module.exports = plugin.withOptions( | ||
({ modifiers = ['sm', 'lg', 'xl', '2xl'] } = {}) => { | ||
({ modifiers, className = 'prose' } = {}) => { | ||
return function ({ addComponents, theme, variants }) { | ||
const config = theme('typography', {}) | ||
const DEFAULT_MODIFIERS = [ | ||
'DEFAULT', | ||
'sm', | ||
'lg', | ||
'xl', | ||
'2xl', | ||
...Object.entries(theme('colors')) | ||
.filter(([color, values]) => { | ||
return isUsableColor(color, values) | ||
}) | ||
.map(([color]) => color), | ||
] | ||
modifiers = modifiers === undefined ? DEFAULT_MODIFIERS : modifiers | ||
const config = theme('typography') | ||
addComponents({ | ||
[`@variants ${variants('typography').join(', ')}`]: [ | ||
{ | ||
'.prose': merge(...castArray(styles.default.css), configToCss(config.default || {})), | ||
}, | ||
...modifiers.map((modifier) => ({ | ||
[`.prose-${modifier}`]: merge( | ||
...castArray(styles[modifier].css), | ||
configToCss(config[modifier] || {}) | ||
), | ||
})), | ||
...Object.keys(config) | ||
.filter((key) => !['default', ...modifiers].includes(key)) | ||
.map((modifier) => ({ | ||
[`.prose-${modifier}`]: configToCss(config[modifier]), | ||
})), | ||
], | ||
}) | ||
const all = uniq([ | ||
'DEFAULT', | ||
...modifiers, | ||
...Object.keys(config).filter((modifier) => !DEFAULT_MODIFIERS.includes(modifier)), | ||
]) | ||
addComponents( | ||
all.map((modifier) => ({ | ||
[modifier === 'DEFAULT' ? `.${className}` : `.${className}-${modifier}`]: configToCss( | ||
config[modifier] | ||
), | ||
})), | ||
variants('typography') | ||
) | ||
} | ||
}, | ||
() => ({ variants: { typography: ['responsive'] } }) | ||
() => ({ | ||
theme: { typography: styles }, | ||
variants: { typography: ['responsive'] }, | ||
}) | ||
) |
const defaultTheme = require('tailwindcss/defaultTheme') | ||
const { isUsableColor } = require('./utils') | ||
@@ -11,17 +12,18 @@ const round = (num) => | ||
module.exports = { | ||
default: { | ||
module.exports = (theme) => ({ | ||
DEFAULT: { | ||
css: [ | ||
{ | ||
color: defaultTheme.colors.gray[700], | ||
color: theme('colors.gray.700', defaultTheme.colors.gray[700]), | ||
maxWidth: '65ch', | ||
'[class~="lead"]': { | ||
color: defaultTheme.colors.gray[700], | ||
color: theme('colors.gray.600', defaultTheme.colors.gray[600]), | ||
}, | ||
a: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
textDecoration: 'underline', | ||
fontWeight: '500', | ||
}, | ||
strong: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '600', | ||
@@ -40,3 +42,3 @@ }, | ||
fontWeight: '400', | ||
color: defaultTheme.colors.gray[600], | ||
color: theme('colors.gray.500', defaultTheme.colors.gray[500]), | ||
}, | ||
@@ -49,7 +51,7 @@ 'ul > li': { | ||
position: 'absolute', | ||
backgroundColor: defaultTheme.colors.gray[400], | ||
backgroundColor: theme('colors.gray.300', defaultTheme.colors.gray[300]), | ||
borderRadius: '50%', | ||
}, | ||
hr: { | ||
borderColor: defaultTheme.colors.gray[300], | ||
borderColor: theme('colors.gray.200', defaultTheme.colors.gray[200]), | ||
borderTopWidth: 1, | ||
@@ -60,5 +62,5 @@ }, | ||
fontStyle: 'italic', | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
borderLeftWidth: '0.25rem', | ||
borderLeftColor: defaultTheme.colors.gray[300], | ||
borderLeftColor: theme('colors.gray.200', defaultTheme.colors.gray[200]), | ||
quotes: '"\\201C""\\201D""\\2018""\\2019"', | ||
@@ -73,22 +75,22 @@ }, | ||
h1: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '800', | ||
}, | ||
h2: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '700', | ||
}, | ||
h3: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '600', | ||
}, | ||
h4: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '600', | ||
}, | ||
'figure figcaption': { | ||
color: defaultTheme.colors.gray[600], | ||
color: theme('colors.gray.500', defaultTheme.colors.gray[500]), | ||
}, | ||
code: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '600', | ||
@@ -102,5 +104,8 @@ }, | ||
}, | ||
'a code': { | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
}, | ||
pre: { | ||
color: defaultTheme.colors.gray[300], | ||
backgroundColor: defaultTheme.colors.gray[800], | ||
color: theme('colors.gray.200', defaultTheme.colors.gray[200]), | ||
backgroundColor: theme('colors.gray.800', defaultTheme.colors.gray[800]), | ||
overflowX: 'auto', | ||
@@ -133,6 +138,6 @@ }, | ||
thead: { | ||
color: defaultTheme.colors.gray[900], | ||
color: theme('colors.gray.900', defaultTheme.colors.gray[900]), | ||
fontWeight: '600', | ||
borderBottomWidth: '1px', | ||
borderBottomColor: defaultTheme.colors.gray[400], | ||
borderBottomColor: theme('colors.gray.300', defaultTheme.colors.gray[300]), | ||
}, | ||
@@ -144,3 +149,3 @@ 'thead th': { | ||
borderBottomWidth: '1px', | ||
borderBottomColor: defaultTheme.colors.gray[300], | ||
borderBottomColor: theme('colors.gray.200', defaultTheme.colors.gray[200]), | ||
}, | ||
@@ -251,3 +256,3 @@ 'tbody tr:last-child': { | ||
}, | ||
'ol > li:before': { | ||
'ol > li::before': { | ||
left: '0', | ||
@@ -437,3 +442,3 @@ }, | ||
}, | ||
'ol > li:before': { | ||
'ol > li::before': { | ||
left: '0', | ||
@@ -623,3 +628,3 @@ }, | ||
}, | ||
'ol > li:before': { | ||
'ol > li::before': { | ||
left: '0', | ||
@@ -809,3 +814,3 @@ }, | ||
}, | ||
'ol > li:before': { | ||
'ol > li::before': { | ||
left: '0', | ||
@@ -995,3 +1000,3 @@ }, | ||
}, | ||
'ol > li:before': { | ||
'ol > li::before': { | ||
left: '0', | ||
@@ -1082,2 +1087,21 @@ }, | ||
}, | ||
} | ||
// Add color modifiers | ||
...Object.entries(theme('colors')).reduce((reduced, [color, values]) => { | ||
if (!isUsableColor(color, values)) { | ||
return {} | ||
} | ||
return { | ||
...reduced, | ||
[color]: { | ||
css: [ | ||
{ | ||
a: { color: values[600] }, | ||
'a code': { color: values[600] }, | ||
}, | ||
], | ||
}, | ||
} | ||
}, {}), | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
358
2
999436
16
33
25858