Skip to content
This repository was archived by the owner on Feb 22, 2022. It is now read-only.

Commit aefb532

Browse files
committed
Add text style components (fix #2)
1 parent 8d1c1de commit aefb532

File tree

6 files changed

+974
-100
lines changed

6 files changed

+974
-100
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.1.0] - 2019-05-26
9+
10+
### Added
11+
- Added text style components (see the `textStyles` theme object in the `README` for more info)
12+
813
## [2.0.0] - 2019-05-13
914

1015
### Changed since 2.0.0-beta.2
@@ -56,7 +61,8 @@ and this project mostly adheres to [Semantic Versioning](https://semver.org/spec
5661

5762
Initial release
5863

59-
[Unreleased]: https://github.com/benface/tailwindcss-typography/compare/v2.0.0...HEAD
64+
[Unreleased]: https://github.com/benface/tailwindcss-typography/compare/v2.1.0...HEAD
65+
[2.1.0]: https://github.com/benface/tailwindcss-typography/compare/v2.0.0...v2.1.0
6066
[2.0.0]: https://github.com/benface/tailwindcss-typography/compare/v2.0.0-beta.2...v2.0.0
6167
[2.0.0-beta.2]: https://github.com/benface/tailwindcss-typography/compare/v2.0.0-beta.1...v2.0.0-beta.2
6268
[2.0.0-beta.1]: https://github.com/benface/tailwindcss-typography/compare/v1.1.0...v2.0.0-beta.1

README.md

Lines changed: 187 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,86 @@ npm install tailwindcss-typography
2020
'default': '0 2px 5px rgba(0, 0, 0, 0.5)',
2121
'lg': '0 2px 10px rgba(0, 0, 0, 0.5)',
2222
},
23+
textStyles: theme => ({ // defaults to {}
24+
heading: {
25+
output: false, // this means there won't be a "heading" component in the CSS, but it can be extended
26+
fontWeight: theme('fontWeight.bold'),
27+
lineHeight: theme('lineHeight.tight'),
28+
},
29+
h1: {
30+
extends: 'heading', // this means all the styles in "heading" will be copied here; "extends" can also be an array to extend multiple text styles
31+
fontSize: theme('fontSize.6xl'),
32+
},
33+
h2: {
34+
extends: 'heading',
35+
fontSize: theme('fontSize.5xl'),
36+
},
37+
h3: {
38+
extends: 'heading',
39+
fontSize: theme('fontSize.4xl'),
40+
},
41+
h4: {
42+
extends: 'heading',
43+
fontSize: theme('fontSize.3xl'),
44+
},
45+
h5: {
46+
extends: 'heading',
47+
fontSize: theme('fontSize.2xl'),
48+
},
49+
h6: {
50+
extends: 'heading',
51+
fontSize: theme('fontSize.xl'),
52+
},
53+
link: {
54+
fontWeight: theme('fontWeight.bold'),
55+
color: theme('colors.blue.400'),
56+
'&:hover': {
57+
color: theme('colors.blue.600'),
58+
textDecoration: 'underline',
59+
},
60+
},
61+
richText: {
62+
fontWeight: theme('fontWeight.normal'),
63+
fontSize: theme('fontSize.base'),
64+
lineHeight: theme('lineHeight.relaxed'),
65+
'> * + *': {
66+
marginTop: '1em',
67+
},
68+
'h1': {
69+
extends: 'h1',
70+
},
71+
'h2': {
72+
extends: 'h2',
73+
},
74+
'h3': {
75+
extends: 'h3',
76+
},
77+
'h4': {
78+
extends: 'h4',
79+
},
80+
'h5': {
81+
extends: 'h5',
82+
},
83+
'h6': {
84+
extends: 'h6',
85+
},
86+
'ul': {
87+
listStyleType: 'disc',
88+
},
89+
'ol': {
90+
listStyleType: 'decimal',
91+
},
92+
'a': {
93+
extends: 'link',
94+
},
95+
'b, strong': {
96+
fontWeight: theme('fontWeight.bold'),
97+
},
98+
'i, em': {
99+
fontStyle: 'italic',
100+
},
101+
},
102+
}),
23103
},
24104
variants: { // all the following default to ['responsive']
25105
textIndent: ['responsive'],
@@ -30,9 +110,10 @@ npm install tailwindcss-typography
30110
},
31111
plugins: [
32112
require('tailwindcss-typography')({
33-
ellipsis: true, // defaults to true
34-
hyphens: true, // defaults to true
35-
textUnset: true, // defaults to true
113+
ellipsis: true, // defaults to true
114+
hyphens: true, // defaults to true
115+
textUnset: true, // defaults to true
116+
componentPrefix: 'c-', // for text styles; defaults to 'c-'
36117
}),
37118
],
38119
}
@@ -47,6 +128,7 @@ This plugin generates the following utilities:
47128
}
48129

49130
/* configurable with the "textShadow" theme object */
131+
/* note: the "default" key generates a simple "text-shadow" class (instead of "text-shadow-default") */
50132
.text-shadow-[key] {
51133
text-shadow: [value];
52134
}
@@ -97,4 +179,105 @@ This plugin generates the following utilities:
97179
}
98180
```
99181

100-
Note: The `textShadow` theme object accepts a `default` key which generates a simple `text-shadow` class (instead of `text-shadow-default`).
182+
The plugin also generates components for text styles. The above config example would generate something like this:
183+
184+
```
185+
.c-h1 {
186+
font-weight: 700;
187+
line-height: 1.25;
188+
font-size: 4rem;
189+
}
190+
.c-h2 {
191+
font-weight: 800;
192+
line-height: 1.25;
193+
font-size: 3rem;
194+
}
195+
.c-h3 {
196+
font-weight: 700;
197+
line-height: 1.25;
198+
font-size: 2.25rem;
199+
}
200+
.c-h4 {
201+
font-weight: 700;
202+
line-height: 1.25;
203+
font-size: 1.875rem;
204+
}
205+
.c-h5 {
206+
font-weight: 700;
207+
line-height: 1.25;
208+
font-size: 1.5rem;
209+
}
210+
.c-h6 {
211+
font-weight: 700;
212+
line-height: 1.25;
213+
font-size: 1.25rem;
214+
}
215+
216+
.c-link {
217+
font-weight: 700;
218+
color: #63b3ed;
219+
}
220+
.c-link:hover {
221+
color: #3182ce;
222+
text-decoration: underline;
223+
}
224+
225+
.c-rich-text {
226+
font-weight: 400;
227+
font-size: 1rem;
228+
line-height: 1.625;
229+
}
230+
.c-rich-text > * + * {
231+
margin-top: 1em;
232+
}
233+
.c-rich-text h1 {
234+
font-weight: 700;
235+
line-height: 1.25;
236+
font-size: 4rem;
237+
}
238+
.c-rich-text h2 {
239+
font-weight: 800;
240+
line-height: 1.25;
241+
font-size: 3rem;
242+
}
243+
.c-rich-text h3 {
244+
font-weight: 700;
245+
line-height: 1.25;
246+
font-size: 2.25rem;
247+
}
248+
.c-rich-text h4 {
249+
font-weight: 700;
250+
line-height: 1.25;
251+
font-size: 1.875rem;
252+
}
253+
.c-rich-text h5 {
254+
font-weight: 700;
255+
line-height: 1.25;
256+
font-size: 1.5rem;
257+
}
258+
.c-rich-text h6 {
259+
font-weight: 700;
260+
line-height: 1.25;
261+
font-size: 1.25rem;
262+
}
263+
.c-rich-text ul {
264+
list-style-type: disc;
265+
}
266+
.c-rich-text ol {
267+
list-style-type: decimal;
268+
}
269+
.c-rich-text a {
270+
font-weight: 700;
271+
color: #63b3ed;
272+
}
273+
.c-rich-text a:hover {
274+
color: #3182ce;
275+
text-decoration: underline;
276+
}
277+
.c-rich-text b, .c-rich-text strong {
278+
font-weight: 700;
279+
}
280+
.c-rich-text i, .c-rich-text em {
281+
font-style: italic;
282+
}
283+
```

index.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
const _ = require('lodash');
22

3+
const camelCaseToKebabCase = function(string) {
4+
return string
5+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
6+
.replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2')
7+
.toLowerCase();
8+
};
9+
310
module.exports = function(options = {}) {
4-
return ({ theme, variants, e, addUtilities }) => {
11+
return ({ theme, variants, e, addUtilities, addComponents }) => {
512
const defaultOptions = {
613
ellipsis: true,
714
hyphens: true,
815
textUnset: true,
16+
componentPrefix: 'c-',
917
};
1018
options = _.defaults({}, options, defaultOptions);
1119

@@ -16,6 +24,7 @@ module.exports = function(options = {}) {
1624
const defaultEllipsisVariants = ['responsive'];
1725
const defaultHyphensVariants = ['responsive'];
1826
const defaultTextUnsetVariants = ['responsive'];
27+
const defaultTextStylesTheme = {};
1928

2029
const textIndentTheme = theme('textIndent', defaultTextIndentTheme);
2130
const textIndentVariants = variants('textIndent', defaultTextIndentVariants);
@@ -24,6 +33,7 @@ module.exports = function(options = {}) {
2433
const ellipsisVariants = variants('ellipsis', defaultEllipsisVariants);
2534
const hyphensVariants = variants('hyphens', defaultHyphensVariants);
2635
const textUnsetVariants = variants('textUnset', defaultTextUnsetVariants);
36+
const textStylesTheme = theme('textStyles', defaultTextStylesTheme);
2737

2838
const textIndentUtilities = _.fromPairs(
2939
_.map(textIndentTheme, (value, modifier) => {
@@ -95,6 +105,39 @@ module.exports = function(options = {}) {
95105
},
96106
};
97107

108+
const resolveTextStyle = function(styles) {
109+
if (!_.isObject(styles)) {
110+
return styles;
111+
}
112+
return _.transform(styles, function(result, value, key) {
113+
if (key === 'extends') {
114+
_.forEach(_.castArray(value), function(textStyleToExtend) {
115+
_.forEach(resolveTextStyle(textStylesTheme[textStyleToExtend]), function(extendedValue, extendedKey) {
116+
if (extendedKey === 'output') {
117+
return; // continue
118+
}
119+
result[extendedKey] = resolveTextStyle(extendedValue);
120+
});
121+
});
122+
return;
123+
}
124+
result[key] = resolveTextStyle(value);
125+
});
126+
};
127+
128+
const textStyles = _.fromPairs(
129+
_.map(textStylesTheme, (componentStyles, componentName) => {
130+
componentStyles = resolveTextStyle(componentStyles);
131+
if (componentStyles.output === false) {
132+
return [];
133+
}
134+
return [
135+
`.${e(`${options.componentPrefix}${camelCaseToKebabCase(componentName)}`)}`,
136+
componentStyles,
137+
];
138+
})
139+
);
140+
98141
addUtilities(textIndentUtilities, textIndentVariants);
99142
addUtilities(textShadowUtilities, textShadowVariants);
100143
if (options.ellipsis) {
@@ -106,5 +149,6 @@ module.exports = function(options = {}) {
106149
if (options.textUnset) {
107150
addUtilities(textUnsetUtilities, textUnsetVariants);
108151
}
152+
addComponents(textStyles);
109153
};
110154
};

0 commit comments

Comments
 (0)