Skip to content

Commit d0056ee

Browse files
committed
Add a CSS version of the Tailwind JS config
This will enable downstream projects to migrate from JS-based configuration for Tailwind to the preferred CSS-based theme config. See also https://tailwindcss.com/docs/upgrade-guide#using-a-javascript-config-file. The Getting Started page has been updated to recommend the CSS-based config. The JS configuration has been kept for compatibility under all downstream projects have been migrated.
1 parent e19709e commit d0056ee

File tree

6 files changed

+301
-35
lines changed

6 files changed

+301
-35
lines changed

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,15 @@
8383
"files": [
8484
"lib",
8585
"styles",
86-
"images"
86+
"images",
87+
"src/tailwind-config.css"
8788
],
8889
"type": "module",
8990
"main": "./lib/index.js",
91+
"exports": {
92+
".": "./lib/index.js",
93+
"./tailwind-config.css": "./src/tailwind-config.css"
94+
},
9095
"browserslist": "chrome 70, firefox 70, safari 11.1",
9196
"dependencies": {
9297
"highlight.js": "^11.6.0",

src/pattern-library/components/Library.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Scroll,
1212
ScrollContainer,
1313
} from '../../';
14+
import type { CodeLanguage } from '../util/jsx-to-string';
1415
import { highlightCode, jsxToHTML } from '../util/jsx-to-string';
1516

1617
/**
@@ -464,13 +465,18 @@ type CodeContentProps =
464465
| {
465466
/** Code content (to be rendered with syntax highlighting) */
466467
content: ComponentChildren;
468+
469+
/** Programming language. */
470+
lang?: CodeLanguage;
467471
}
468472
| {
469473
/**
470474
* Example file to read and use as content (to be rendered with syntax
471-
* highlighting)
475+
* highlighting).
472476
*/
473477
exampleFile: string;
478+
479+
// Example files are currently assumed to always be TypeScript.
474480
};
475481

476482
export type LibraryCodeProps = {
@@ -495,7 +501,7 @@ function useCodeContent(
495501
): [string | undefined, Error | undefined] {
496502
const hasStaticContent = isCodeWithContent(props);
497503
const [codeMarkup, setCodeMarkup] = useState<string | undefined>(
498-
hasStaticContent ? jsxToHTML(props.content) : undefined,
504+
hasStaticContent ? jsxToHTML(props.content, props.lang) : undefined,
499505
);
500506
const [error, setError] = useState<Error>();
501507

@@ -506,7 +512,7 @@ function useCodeContent(
506512

507513
const controller = new AbortController();
508514
fetchCodeExample(`/examples/${props.exampleFile}.tsx`, controller.signal)
509-
.then(code => setCodeMarkup(highlightCode(code)))
515+
.then(code => setCodeMarkup(highlightCode(code, 'typescript')))
510516
.catch(setError);
511517

512518
return () => controller.abort();

src/pattern-library/components/patterns/GettingStartedPage.tsx

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,58 @@ export default function GettingStartedPage() {
1818
<Library.Section>
1919
<Library.SectionL2 title="Installation">
2020
<p>
21-
Your application needs to install{' '}
21+
Add{' '}
2222
<Link href="https://tailwindcss.com/" underline="always">
2323
tailwindcss
2424
</Link>{' '}
25-
to use this {"package's"} updated components.
25+
to your application&apos;s dependencies.
2626
</p>
2727
<Library.Code
28-
content={`$ yarn add tailwindcss @hypothesis/frontend-shared`}
28+
content={`$ yarn add tailwindcss @tailwindcss/postcss @hypothesis/frontend-shared`}
29+
/>
30+
<p>
31+
Then, in your project&apos;s gulp configuration, pass{' '}
32+
<code>
33+
{'{'} tailwind: true {'}'}
34+
</code>{' '}
35+
to the <code>buildCSS</code> function:
36+
</p>
37+
<Library.Code
38+
content={`import { buildCSS } from '@hypothesis/frontend-build';
39+
40+
gulp.task('build-tailwind-css', () =>
41+
buildCSS(['app.css'], {
42+
tailwind: true,
43+
}),
44+
);`}
2945
/>
3046
</Library.SectionL2>
3147
<Library.SectionL2 title="Configuration">
32-
<Library.SectionL3 title="Configure tailwindcss">
33-
<p>Configure your {"project's"} tailwind configuration object:</p>
34-
<ul>
35-
<li>Use this {"package's"} tailwind preset</li>
36-
<li>
37-
Add this {"package's"} source to the {"configuration's"}{' '}
38-
<code>content</code> globs
39-
</li>
40-
</ul>
41-
<Library.Code
42-
size="sm"
43-
title="Your project's tailwind config"
44-
content={`import tailwindConfig from '@hypothesis/frontend-shared/lib/tailwind.preset.js';
48+
<p>
49+
In your project&apos;s CSS entry point, import the Tailwind theme
50+
from this package:
51+
</p>
52+
<Library.Code
53+
size="sm"
54+
title="Your project's tailwind config"
55+
lang="css"
56+
content={`@import 'tailwindcss' @source(none);
57+
58+
/* Scan the frontend-shared package for used classes. The path is relative to
59+
the location of the CSS file. */
60+
@source 'node_modules/@hypothesis/frontend-shared/lib/**/*.js';
4561
46-
export default {
47-
presets: [tailwindConfig],
48-
content: [
49-
'./node_modules/@hypothesis/frontend-shared/lib/**/*.{js,ts,tsx}',
50-
// ...
51-
],
52-
// ...`}
53-
/>
54-
</Library.SectionL3>
62+
/* Enable the Tailwind theme and additional utilities. */
63+
@import '@hypothesis/frontend-shared/tailwind-config.css';
64+
`}
65+
/>
66+
<p>
67+
See the{' '}
68+
<a href="https://tailwindcss.com/docs/functions-and-directives">
69+
Tailwind documentation
70+
</a>{' '}
71+
for more details on configuration at-rules.
72+
</p>
5573
</Library.SectionL2>
5674
<Library.SectionL2 title="Usage">
5775
<Library.Usage componentName="Card, Link" />

src/pattern-library/util/jsx-to-string.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import hljs from 'highlight.js/lib/core';
2+
import hljsCSSLang from 'highlight.js/lib/languages/css';
23
import hljsTypeScriptLang from 'highlight.js/lib/languages/typescript';
34
import hljsXMLLang from 'highlight.js/lib/languages/xml';
45
import { Fragment } from 'preact';
@@ -155,6 +156,8 @@ export function jsxToString(vnode: ComponentChildren): string {
155156
}
156157
}
157158

159+
export type CodeLanguage = 'css' | 'typescript';
160+
158161
/**
159162
* Render a code snippet as syntax-highlighted HTML markup.
160163
*
@@ -164,7 +167,7 @@ export function jsxToString(vnode: ComponentChildren): string {
164167
* The content returned by this function is sanitized and safe to use as
165168
* `dangerouslySetInnerHTML` prop.
166169
*/
167-
export function highlightCode(code: string): string {
170+
export function highlightCode(code: string, lang?: CodeLanguage): string {
168171
// JSX support in Highlight.js involves a combination of the TS and XML
169172
// languages, so we need to load both.
170173
if (!hljs.getLanguage('typescript')) {
@@ -173,8 +176,11 @@ export function highlightCode(code: string): string {
173176
if (!hljs.getLanguage('xml')) {
174177
hljs.registerLanguage('xml', hljsXMLLang);
175178
}
176-
177-
return hljs.highlightAuto(code).value;
179+
if (!hljs.getLanguage('css')) {
180+
hljs.registerLanguage('css', hljsCSSLang);
181+
}
182+
const languages = lang !== undefined ? [lang] : undefined;
183+
return hljs.highlightAuto(code, languages).value;
178184
}
179185

180186
/**
@@ -183,7 +189,10 @@ export function highlightCode(code: string): string {
183189
* The content returned by this function is sanitized and safe to use as
184190
* `dangerouslySetInnerHTML` prop.
185191
*/
186-
export function jsxToHTML(vnode: ComponentChildren): string {
192+
export function jsxToHTML(
193+
vnode: ComponentChildren,
194+
lang?: CodeLanguage,
195+
): string {
187196
const code = jsxToString(vnode);
188-
return highlightCode(code);
197+
return highlightCode(code, lang);
189198
}

0 commit comments

Comments
 (0)