@crowdstrike/tailwind-toucan-base 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/index.js +390 -0
- package/package.json +76 -0
- package/plugins/form-fields.js +46 -0
- package/plugins/index.js +12 -0
- package/plugins/interaction.js +157 -0
- package/plugins/line-clamp.js +44 -0
- package/plugins/theme-plugin.js +42 -0
- package/plugins/typography.js +140 -0
- package/plugins/variables.js +45 -0
package/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# @crowdstrike/tailwind-toucan-base
|
2
|
+
|
3
|
+
A Tailwind preset that provides the base styles for CrowdStrike's Toucan design system.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```bash
|
8
|
+
yarn add @crowdstrike/tailwind-toucan-base
|
9
|
+
#
|
10
|
+
npm install @crowdstrike/tailwind-toucan-base
|
11
|
+
#
|
12
|
+
pnpm add @crowdstrike/tailwind-toucan-base
|
13
|
+
```
|
14
|
+
|
15
|
+
### Tailwind
|
16
|
+
|
17
|
+
_Note_: This preset is presently only tested with Tailwind v2
|
18
|
+
|
19
|
+
```js
|
20
|
+
// tailwind.config.js
|
21
|
+
|
22
|
+
module.exports = {
|
23
|
+
presets: [require('@crowdstrike/tailwind-toucan-base')],
|
24
|
+
extends: {
|
25
|
+
// your customizations here
|
26
|
+
}
|
27
|
+
};
|
28
|
+
```
|
29
|
+
|
30
|
+
### CSS `@import`
|
31
|
+
|
32
|
+
If your packager supports importing styles directly from an npm package, the Toucan styles are pre-built and can be imported at:
|
33
|
+
|
34
|
+
```css
|
35
|
+
@import "@crowdstrike/tailwind-toucan-base";
|
36
|
+
```
|
37
|
+
|
38
|
+
### CDN Usage
|
39
|
+
|
40
|
+
Many JS CDNs scrape NPM and automatically serve and cache assets
|
41
|
+
deployed to NPM.
|
42
|
+
|
43
|
+
Here as an example with JSDelivr
|
44
|
+
```
|
45
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crowdstrike/tailwind-toucan-base/toucan.css">
|
46
|
+
```
|
47
|
+
|
48
|
+
## Previewing the config locally
|
49
|
+
|
50
|
+
```bash
|
51
|
+
pnpm start
|
52
|
+
```
|
53
|
+
which is an alias for:
|
54
|
+
|
55
|
+
```bash
|
56
|
+
pnpm run build:preview
|
57
|
+
npx http-server ./dist
|
58
|
+
```
|
59
|
+
|
60
|
+
## Importing colors and shadows from Figma
|
61
|
+
|
62
|
+
This addon provides the ability to pull our palette information directly from Figma files and store them in
|
63
|
+
`themes.json` which is used by the Tailwind configuration to set up our CSS.
|
64
|
+
|
65
|
+
To import the colors run:
|
66
|
+
|
67
|
+
```bash
|
68
|
+
LIGHT_ID=fileId DARK_ID=fileId MEZZANINE_ID=fileId \
|
69
|
+
FIGMA_TOKEN=some-key pnpm run figma:export-styles
|
70
|
+
```
|
71
|
+
|
72
|
+
- `FIGMA_TOKEN` here is figma [Personal Access Token](https://www.figma.com/developers/api#access-tokens).
|
73
|
+
- `LIGHT_ID`, `DARK_ID`, and `MEZZANINE_ID` are `fileId`s that can be obtained from the URL of the figma project containing the color tokens.
|
74
|
+
|
75
|
+
...and commit the changes to `themes.json`.
|
76
|
+
|
77
|
+
If you see any errors reported then you _may_ need to ensure that the Figma file is set up correctly (and e.g.
|
78
|
+
there are corresponding colors across each of the palettes).
|
package/index.js
ADDED
@@ -0,0 +1,390 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const themesData = require('./themes');
|
4
|
+
|
5
|
+
let colors = themesData.themes['dark'].colors.reduce((acc, { name }) => {
|
6
|
+
acc[name.replace('\\.', '.')] = `var(--${name})`;
|
7
|
+
|
8
|
+
return acc;
|
9
|
+
}, {});
|
10
|
+
|
11
|
+
let boxShadow = themesData.themes['dark'].shadows.reduce((acc, { name }) => {
|
12
|
+
acc[name.replace(/^elevation-/, '')] = `var(--${name})`;
|
13
|
+
|
14
|
+
return acc;
|
15
|
+
}, {});
|
16
|
+
|
17
|
+
const FONT_SIZES = {
|
18
|
+
xxs: '.5625rem',
|
19
|
+
xs: '.75rem',
|
20
|
+
sm: '.875rem',
|
21
|
+
md: '1rem',
|
22
|
+
lg: '1.25rem',
|
23
|
+
xl: '1.5rem',
|
24
|
+
'2xl': '2rem',
|
25
|
+
'3xl': '2.5rem',
|
26
|
+
'4xl': '3rem',
|
27
|
+
};
|
28
|
+
|
29
|
+
module.exports = {
|
30
|
+
theme: {
|
31
|
+
// Keys placed here will REMOVE the classes included with tailwindcss
|
32
|
+
// eg if `padding` was added here we would lose all of tailwinds padding classes.
|
33
|
+
// If you want to ADD a custom class then place them in the `extend` object below
|
34
|
+
boxShadow: {
|
35
|
+
none: 'none',
|
36
|
+
'focusable-outline': 'inset 0 0 0 1px var(--lines-dark), var(--elevation-inner-md)',
|
37
|
+
'focus-outline': 'inset 0 0 0 2px var(--focus)',
|
38
|
+
'error-outline': 'inset 0 0 0 2px var(--critical)',
|
39
|
+
'search-input': 'inset 0 0 0 1px var(--nav-text-secondary)',
|
40
|
+
...boxShadow,
|
41
|
+
},
|
42
|
+
|
43
|
+
colors: {
|
44
|
+
current: 'currentColor',
|
45
|
+
transparent: 'transparent',
|
46
|
+
falcon: 'var(--falcon)',
|
47
|
+
...colors,
|
48
|
+
},
|
49
|
+
|
50
|
+
fontFamily: {
|
51
|
+
sans: ['Calibre', 'sans-serif'],
|
52
|
+
mono: ['Monaco', 'monospace'],
|
53
|
+
},
|
54
|
+
|
55
|
+
fontSize: (theme) => {
|
56
|
+
return {
|
57
|
+
xxs: [FONT_SIZES.xxs, theme('lineHeight.4')],
|
58
|
+
xs: [FONT_SIZES.xs, theme('lineHeight.5')],
|
59
|
+
sm: [FONT_SIZES.sm, theme('lineHeight.6')],
|
60
|
+
md: [FONT_SIZES.md, theme('lineHeight.6')],
|
61
|
+
lg: [FONT_SIZES.lg, theme('lineHeight.8')],
|
62
|
+
xl: [FONT_SIZES.xl, theme('lineHeight.8')],
|
63
|
+
'2xl': [FONT_SIZES['2xl'], theme('lineHeight.10')],
|
64
|
+
'3xl': [FONT_SIZES['3xl'], theme('lineHeight.12')],
|
65
|
+
'4xl': [FONT_SIZES['4xl'], theme('lineHeight.13')],
|
66
|
+
};
|
67
|
+
},
|
68
|
+
|
69
|
+
zIndex: {
|
70
|
+
'-1': '-1',
|
71
|
+
1: '1',
|
72
|
+
2: '2',
|
73
|
+
3: '3',
|
74
|
+
4: '4',
|
75
|
+
5: '5',
|
76
|
+
6: '6',
|
77
|
+
7: '7',
|
78
|
+
8: '8',
|
79
|
+
9: '9',
|
80
|
+
10: '10',
|
81
|
+
'flash-messages': 'var(--z-index-flash-messages)',
|
82
|
+
overlay: 'var(--z-index-overlay)',
|
83
|
+
tooltip: 'var(--z-index-tooltip)',
|
84
|
+
'popover-sticky': 'var(--z-index-popover-sticky)',
|
85
|
+
popover: 'var(--z-index-popover)',
|
86
|
+
'skip-to-content': 'var(--z-index-skip-to-content)',
|
87
|
+
tablist: 'var(--z-index-tablist)',
|
88
|
+
tabpanel: 'var(--z-index-tabpanel)',
|
89
|
+
'tabpanel-scrim': 'var(--z-index-tabpanel-scrim)',
|
90
|
+
'template-head': 'var(--z-index-template-head)',
|
91
|
+
'template-main-head-sticky': 'var(--z-index-template-main-head-sticky)',
|
92
|
+
'template-main-head': 'var(--z-index-template-main-head)',
|
93
|
+
'template-main': 'var(--z-index-template-main)',
|
94
|
+
'search-results-navigation': 'var(--z-index-navigation-search)',
|
95
|
+
},
|
96
|
+
|
97
|
+
extend: {
|
98
|
+
animation: {
|
99
|
+
'fade-in': 'fade-in .25s linear',
|
100
|
+
},
|
101
|
+
|
102
|
+
cursor: {
|
103
|
+
'col-resize': 'col-resize',
|
104
|
+
},
|
105
|
+
|
106
|
+
flex: {
|
107
|
+
2: '2 2 0%',
|
108
|
+
3: '3 3 0%',
|
109
|
+
4: '4 4 0%',
|
110
|
+
},
|
111
|
+
|
112
|
+
gridTemplateColumns: {
|
113
|
+
'centered-2/3': '2fr 8fr 2fr',
|
114
|
+
|
115
|
+
'auto-2': 'auto auto',
|
116
|
+
|
117
|
+
'max-content-4': 'repeat(4, minmax(max-content, 1fr))',
|
118
|
+
'max-content-6': 'repeat(6, minmax(max-content, 1fr))',
|
119
|
+
},
|
120
|
+
|
121
|
+
height: {
|
122
|
+
2.5: '0.375rem',
|
123
|
+
7: '1.75rem',
|
124
|
+
9: '2.25rem',
|
125
|
+
11: '2.75rem',
|
126
|
+
'main-content-area': 'calc(100vh - var(--template-head-height))',
|
127
|
+
},
|
128
|
+
|
129
|
+
keyframes: {
|
130
|
+
'fade-in': {
|
131
|
+
'0%': { opacity: '0%' },
|
132
|
+
'100%': { opacity: '100%' },
|
133
|
+
},
|
134
|
+
},
|
135
|
+
|
136
|
+
rotate: {
|
137
|
+
'-5': '-5deg',
|
138
|
+
},
|
139
|
+
|
140
|
+
inset: {
|
141
|
+
'1/2': '50%',
|
142
|
+
},
|
143
|
+
|
144
|
+
lineHeight: {
|
145
|
+
12: '3rem',
|
146
|
+
13: '3.25rem',
|
147
|
+
},
|
148
|
+
|
149
|
+
maxHeight: {
|
150
|
+
listbox: '12em',
|
151
|
+
'under-header': 'calc(100vh - var(--template-head-height))',
|
152
|
+
},
|
153
|
+
|
154
|
+
maxWidth: {
|
155
|
+
paragraph: '34rem',
|
156
|
+
},
|
157
|
+
|
158
|
+
minHeight: (theme) => {
|
159
|
+
return {
|
160
|
+
3: theme('height.3'),
|
161
|
+
4: theme('height.4'),
|
162
|
+
6: theme('height.6'),
|
163
|
+
16: theme('height.16'),
|
164
|
+
};
|
165
|
+
},
|
166
|
+
|
167
|
+
minWidth: (theme) => {
|
168
|
+
return {
|
169
|
+
3: theme('width.3'),
|
170
|
+
4: theme('width.4'),
|
171
|
+
6: theme('width.6'),
|
172
|
+
16: theme('width.16'),
|
173
|
+
24: theme('width.24'),
|
174
|
+
48: theme('width.48'),
|
175
|
+
phoenix: '1024px',
|
176
|
+
popover: '140px',
|
177
|
+
toucan: '1380px',
|
178
|
+
};
|
179
|
+
},
|
180
|
+
|
181
|
+
padding: {
|
182
|
+
0.25: '0.063rem',
|
183
|
+
'property-tabs-top': 'var(--property-tabs-top)',
|
184
|
+
unset: 'unset',
|
185
|
+
},
|
186
|
+
|
187
|
+
spacing: {
|
188
|
+
0.5: '0.125rem',
|
189
|
+
},
|
190
|
+
|
191
|
+
transitionProperty: {
|
192
|
+
width: 'width',
|
193
|
+
},
|
194
|
+
|
195
|
+
width: {
|
196
|
+
2.5: '0.375rem',
|
197
|
+
'max-content': 'max-content',
|
198
|
+
7: '1.75rem',
|
199
|
+
15: '3.75rem',
|
200
|
+
},
|
201
|
+
},
|
202
|
+
|
203
|
+
screens: {
|
204
|
+
print: { raw: 'print' },
|
205
|
+
|
206
|
+
// Defaults omitted to reduce payload size,
|
207
|
+
// sm: md: lg: variants removed to reduce file size by ~700kb
|
208
|
+
// https://tailwindcss.com/docs/theme/#screens
|
209
|
+
//
|
210
|
+
// Now, we add the screens we only need for specific properties
|
211
|
+
lg: '1120px',
|
212
|
+
'2xl': '1536px',
|
213
|
+
},
|
214
|
+
},
|
215
|
+
|
216
|
+
variants: {
|
217
|
+
// defaults
|
218
|
+
// https://tailwindcss.com/docs/pseudo-class-variants/#default-variants-reference
|
219
|
+
// **** NOTE *****
|
220
|
+
// Order of variants passed here controls order in source code. You almost certainly
|
221
|
+
// want active and disabled at the end so they can override other styles!
|
222
|
+
accessibility: ['focus'],
|
223
|
+
alignContent: [],
|
224
|
+
alignItems: [],
|
225
|
+
alignSelf: [],
|
226
|
+
animation: [],
|
227
|
+
appearance: [],
|
228
|
+
backdropBlur: [],
|
229
|
+
backdropBrightness: [],
|
230
|
+
backdropContrast: [],
|
231
|
+
backdropDropShadow: [],
|
232
|
+
backdropFilter: [],
|
233
|
+
backdropGrayscale: [],
|
234
|
+
backdropHueRotate: [],
|
235
|
+
backdropInvert: [],
|
236
|
+
backdropSaturate: [],
|
237
|
+
backdropSepia: [],
|
238
|
+
backgroundAttachment: [],
|
239
|
+
backgroundBlendMode: [],
|
240
|
+
backgroundClip: [],
|
241
|
+
backgroundColor: [
|
242
|
+
'even',
|
243
|
+
'group-hover',
|
244
|
+
'hover',
|
245
|
+
'focus',
|
246
|
+
'focus-within',
|
247
|
+
'focus-visible',
|
248
|
+
'active',
|
249
|
+
'disabled',
|
250
|
+
],
|
251
|
+
backgroundImage: [],
|
252
|
+
backgroundOpacity: ['hover', 'focus'],
|
253
|
+
backgroundPosition: [],
|
254
|
+
backgroundRepeat: [],
|
255
|
+
backgroundSize: [],
|
256
|
+
blur: [],
|
257
|
+
borderCollapse: [],
|
258
|
+
borderColor: ['hover', 'active'],
|
259
|
+
borderOpacity: ['hover', 'focus'],
|
260
|
+
borderRadius: ['focus', 'first', 'last'],
|
261
|
+
borderStyle: [],
|
262
|
+
borderWidth: ['first', 'last', 'active'],
|
263
|
+
boxDecorationBreak: [],
|
264
|
+
boxShadow: [
|
265
|
+
'hover',
|
266
|
+
'group-hover',
|
267
|
+
'focus',
|
268
|
+
'focus-within',
|
269
|
+
'focus-visible',
|
270
|
+
'active',
|
271
|
+
'disabled',
|
272
|
+
],
|
273
|
+
boxSizing: [],
|
274
|
+
brightness: [],
|
275
|
+
clear: [],
|
276
|
+
container: [],
|
277
|
+
contrast: [],
|
278
|
+
cursor: ['disabled'],
|
279
|
+
display: ['responsive', 'group-hover'],
|
280
|
+
divideColor: [],
|
281
|
+
divideOpacity: [],
|
282
|
+
divideStyle: [],
|
283
|
+
divideWidth: [],
|
284
|
+
dropShadow: [],
|
285
|
+
fill: [],
|
286
|
+
filter: [],
|
287
|
+
flex: [],
|
288
|
+
flexDirection: [],
|
289
|
+
flexGrow: [],
|
290
|
+
flexShrink: [],
|
291
|
+
flexWrap: [],
|
292
|
+
float: [],
|
293
|
+
fontFamily: [],
|
294
|
+
fontSize: [],
|
295
|
+
fontSmoothing: [],
|
296
|
+
fontStyle: [],
|
297
|
+
fontVariantNumeric: [],
|
298
|
+
fontWeight: ['hover', 'focus'],
|
299
|
+
gap: [],
|
300
|
+
gradientColorStops: ['dark', 'hover', 'focus'],
|
301
|
+
grayscale: [],
|
302
|
+
gridAutoColumns: [],
|
303
|
+
gridAutoFlow: [],
|
304
|
+
gridAutoRows: [],
|
305
|
+
gridColumn: [],
|
306
|
+
gridColumnEnd: [],
|
307
|
+
gridColumnStart: [],
|
308
|
+
gridRow: [],
|
309
|
+
gridRowEnd: [],
|
310
|
+
gridRowStart: [],
|
311
|
+
gridTemplateColumns: ['responsive'],
|
312
|
+
gridTemplateRows: [],
|
313
|
+
height: [],
|
314
|
+
hueRotate: [],
|
315
|
+
inset: ['focus'],
|
316
|
+
invert: [],
|
317
|
+
isolation: [],
|
318
|
+
justifyContent: [],
|
319
|
+
justifyItems: [],
|
320
|
+
justifySelf: [],
|
321
|
+
letterSpacing: [],
|
322
|
+
lineHeight: [],
|
323
|
+
listStylePosition: [],
|
324
|
+
listStyleType: [],
|
325
|
+
margin: ['first', 'last'],
|
326
|
+
maxHeight: [],
|
327
|
+
maxWidth: [],
|
328
|
+
minHeight: [],
|
329
|
+
minWidth: [],
|
330
|
+
mixBlendMode: [],
|
331
|
+
objectFit: [],
|
332
|
+
objectPosition: [],
|
333
|
+
opacity: ['hover', 'focus', 'group-hover', 'group-focus'],
|
334
|
+
order: [],
|
335
|
+
outline: ['focus'],
|
336
|
+
overflow: [],
|
337
|
+
overscrollBehavior: [],
|
338
|
+
padding: [],
|
339
|
+
placeItems: [],
|
340
|
+
placeContent: [],
|
341
|
+
placeSelf: [],
|
342
|
+
placeholderColor: ['focus'],
|
343
|
+
placeholderOpacity: ['focus'],
|
344
|
+
pointerEvents: ['disabled'],
|
345
|
+
position: ['hover'],
|
346
|
+
resize: [],
|
347
|
+
ringColor: ['dark', 'focus-within', 'focus'],
|
348
|
+
ringOffsetColor: ['dark', 'focus-within', 'focus'],
|
349
|
+
ringOffsetWidth: ['focus-within', 'focus'],
|
350
|
+
ringOpacity: ['dark', 'focus-within', 'focus'],
|
351
|
+
ringWidth: ['focus-within', 'focus-visible', 'focus'],
|
352
|
+
rotate: ['active'],
|
353
|
+
saturate: [],
|
354
|
+
scale: ['hover', 'focus', 'active'],
|
355
|
+
sepia: [],
|
356
|
+
skew: ['hover', 'focus'],
|
357
|
+
space: [],
|
358
|
+
stroke: [],
|
359
|
+
strokeWidth: [],
|
360
|
+
tableLayout: [],
|
361
|
+
textAlign: [],
|
362
|
+
textColor: ['hover', 'focus', 'focus-visible', 'group-hover', 'active', 'disabled'],
|
363
|
+
textDecoration: ['hover', 'focus'],
|
364
|
+
textOpacity: ['hover', 'focus'],
|
365
|
+
textOverflow: [],
|
366
|
+
textTransform: [],
|
367
|
+
transform: [],
|
368
|
+
transformOrigin: [],
|
369
|
+
transitionDelay: [],
|
370
|
+
transitionDuration: [],
|
371
|
+
transitionProperty: ['active'],
|
372
|
+
transitionTimingFunction: [],
|
373
|
+
translate: ['hover', 'focus'],
|
374
|
+
userSelect: [],
|
375
|
+
verticalAlign: [],
|
376
|
+
visibility: [],
|
377
|
+
whitespace: [],
|
378
|
+
width: [],
|
379
|
+
wordBreak: [],
|
380
|
+
zIndex: ['hover', 'active', 'group-hover'],
|
381
|
+
},
|
382
|
+
|
383
|
+
plugins: [
|
384
|
+
/**
|
385
|
+
* All of our own custom plugins are wrapped up this single
|
386
|
+
* configure call -- form fields, variables, etc
|
387
|
+
*/
|
388
|
+
...require('./plugins').configure({ FONT_SIZES, themesData }),
|
389
|
+
],
|
390
|
+
};
|
package/package.json
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
{
|
2
|
+
"name": "@crowdstrike/tailwind-toucan-base",
|
3
|
+
"version": "3.0.1",
|
4
|
+
"private": false,
|
5
|
+
"description": "Tailwind preset for CrowdStrike's Toucan design system",
|
6
|
+
"repository": "https://github.com/CrowdStrike/tailwind-toucan-base",
|
7
|
+
"license": "MIT",
|
8
|
+
"author": "CrowdStrike UX Team",
|
9
|
+
"main": "index.js",
|
10
|
+
"files": [
|
11
|
+
"index.js",
|
12
|
+
"index.css",
|
13
|
+
"toucan.css",
|
14
|
+
"plugins/**/*.js"
|
15
|
+
],
|
16
|
+
"scripts": {
|
17
|
+
"start": "pnpm run build && npx http-server ./dist",
|
18
|
+
"build": "npm-run-all clean build:cdn build:alias build:preview",
|
19
|
+
"build:preview": "node ./lib/build-preview.mjs",
|
20
|
+
"build:cdn": "NODE_ENV=production tailwind build -i ./lib/index.css -o ./index.css -c ./lib/tailwind.config.cdn.js",
|
21
|
+
"clean": "rm -f ./toucan.css ./index.css",
|
22
|
+
"build:alias": "cp index.css toucan.css",
|
23
|
+
"figma:export-styles": "figma-export use-config",
|
24
|
+
"test": "pnpm exec vitest --coverage --run",
|
25
|
+
"lint:fix": "pnpm run lint:js --fix",
|
26
|
+
"lint:js": "eslint ."
|
27
|
+
},
|
28
|
+
"dependencies": {
|
29
|
+
"@figma-export/cli": "3.3.1",
|
30
|
+
"tailwindcss": "^2.2.15"
|
31
|
+
},
|
32
|
+
"devDependencies": {
|
33
|
+
"@nullvoxpopuli/eslint-configs": "2.2.16",
|
34
|
+
"@semantic-release/changelog": "^5.0.1",
|
35
|
+
"@semantic-release/git": "^9.0.1",
|
36
|
+
"@types/fs-extra": "^9.0.13",
|
37
|
+
"autoprefixer": "^10.3.4",
|
38
|
+
"c8": "^7.11.2",
|
39
|
+
"common-tags": "^1.8.2",
|
40
|
+
"eslint": "^7.32.0",
|
41
|
+
"execa": "^6.1.0",
|
42
|
+
"fs-extra": "^10.1.0",
|
43
|
+
"npm-run-all": "^4.1.5",
|
44
|
+
"postcss": "^8.3.6",
|
45
|
+
"semantic-release": "^17.4.7",
|
46
|
+
"tailwind-config-viewer": "^1.7.0",
|
47
|
+
"typescript": "^4.6.4",
|
48
|
+
"vitest": "0.12.4"
|
49
|
+
},
|
50
|
+
"engines": {
|
51
|
+
"node": ">=14.15.0"
|
52
|
+
},
|
53
|
+
"publishConfig": {
|
54
|
+
"access": "public"
|
55
|
+
},
|
56
|
+
"release": {
|
57
|
+
"branches": [
|
58
|
+
"main",
|
59
|
+
"master"
|
60
|
+
],
|
61
|
+
"plugins": [
|
62
|
+
"@semantic-release/commit-analyzer",
|
63
|
+
"@semantic-release/release-notes-generator",
|
64
|
+
"@semantic-release/changelog",
|
65
|
+
"@semantic-release/npm",
|
66
|
+
"@semantic-release/github",
|
67
|
+
"@semantic-release/git"
|
68
|
+
]
|
69
|
+
},
|
70
|
+
"packageManager": "pnpm@7.1.0",
|
71
|
+
"volta": {
|
72
|
+
"node": "16.15.0",
|
73
|
+
"yarn": "1.22.11",
|
74
|
+
"npm": "8.9.0"
|
75
|
+
}
|
76
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
module.exports = () =>
|
6
|
+
plugin((pluginApi) => {
|
7
|
+
addFormFieldStyles(pluginApi);
|
8
|
+
});
|
9
|
+
|
10
|
+
function addFormFieldStyles({ addComponents }) {
|
11
|
+
let textbox = {
|
12
|
+
backgroundColor: 'var(--overlay-1)',
|
13
|
+
borderRadius: 'var(--border-radius)',
|
14
|
+
boxShadow: 'inset 0 0 0 1px var(--lines-dark), var(--elevation-inner-md)',
|
15
|
+
color: 'var(--titles-and-attributes)',
|
16
|
+
display: 'block',
|
17
|
+
fontFamily: 'inherit',
|
18
|
+
fontSize: '1rem',
|
19
|
+
lineHeight: '1.5',
|
20
|
+
padding: 'var(--space-1) var(--space-2)',
|
21
|
+
width: '100%',
|
22
|
+
|
23
|
+
'&:focus': {
|
24
|
+
// TODO: share with definition of boxShadow: shadow-focus-outline
|
25
|
+
boxShadow: 'inset 0 0 0 2px var(--focus);',
|
26
|
+
outline: 0,
|
27
|
+
},
|
28
|
+
|
29
|
+
'&::placeholder': {
|
30
|
+
color: 'var(--disabled)',
|
31
|
+
},
|
32
|
+
};
|
33
|
+
|
34
|
+
let textarea = {
|
35
|
+
...textbox,
|
36
|
+
minHeight: '150px',
|
37
|
+
resize: 'vertical',
|
38
|
+
};
|
39
|
+
|
40
|
+
let formFields = {
|
41
|
+
'.textbox': textbox,
|
42
|
+
'.textarea': textarea,
|
43
|
+
};
|
44
|
+
|
45
|
+
addComponents(formFields);
|
46
|
+
}
|
package/plugins/index.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
configure: ({ FONT_SIZES, themesData }) => [
|
5
|
+
require('./interaction')(),
|
6
|
+
require('./form-fields')(),
|
7
|
+
require('./line-clamp'),
|
8
|
+
require('./typography')(FONT_SIZES),
|
9
|
+
require('./theme-plugin')(themesData),
|
10
|
+
require('./variables'),
|
11
|
+
],
|
12
|
+
};
|
@@ -0,0 +1,157 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
module.exports = () =>
|
6
|
+
plugin((pluginApi) => {
|
7
|
+
addFocusStyles(pluginApi);
|
8
|
+
addInteractiveStyles(pluginApi);
|
9
|
+
});
|
10
|
+
|
11
|
+
function addFocusStyles({ addComponents }) {
|
12
|
+
addComponents({
|
13
|
+
'.focusable': {
|
14
|
+
'@apply ring-ground-floor': {},
|
15
|
+
'@apply ring-inset': {},
|
16
|
+
'@apply ring-offset-2': {},
|
17
|
+
'@apply ring-offset-focus': {},
|
18
|
+
},
|
19
|
+
|
20
|
+
'.focusable:focus': {
|
21
|
+
'@apply outline-none': {},
|
22
|
+
},
|
23
|
+
|
24
|
+
'.focusable:focus-visible': {
|
25
|
+
'@apply ring-2': {},
|
26
|
+
},
|
27
|
+
|
28
|
+
'.focusable-destructive': {
|
29
|
+
'@apply ring-offset-destructive-pressed': {},
|
30
|
+
},
|
31
|
+
|
32
|
+
'.focusable-outer': {
|
33
|
+
'@apply ring-offset-ground-floor': {},
|
34
|
+
'@apply ring-offset-1': {},
|
35
|
+
'@apply ring-focus': {},
|
36
|
+
},
|
37
|
+
|
38
|
+
'.focusable-outer:focus': {
|
39
|
+
'@apply outline-none': {},
|
40
|
+
},
|
41
|
+
|
42
|
+
'.focusable-outer:focus-visible': {
|
43
|
+
'@apply ring-2': {},
|
44
|
+
},
|
45
|
+
});
|
46
|
+
}
|
47
|
+
|
48
|
+
function addInteractiveStyles({ addComponents }) {
|
49
|
+
addComponents({
|
50
|
+
'.interactive-normal': {
|
51
|
+
'@apply bg-normal-idle': {},
|
52
|
+
'@apply shadow-base': {},
|
53
|
+
'@apply text-text-and-icons': {},
|
54
|
+
},
|
55
|
+
|
56
|
+
'.interactive-normal:not(.interactive-disabled):hover': {
|
57
|
+
'@apply bg-normal-hover': {},
|
58
|
+
'@apply shadow-md': {},
|
59
|
+
},
|
60
|
+
|
61
|
+
'.interactive-normal:not(.interactive-disabled):focus-visible': {
|
62
|
+
'@apply bg-normal-hover': {},
|
63
|
+
},
|
64
|
+
|
65
|
+
'.interactive-normal:not(.interactive-disabled):active': {
|
66
|
+
'@apply bg-normal-pressed': {},
|
67
|
+
'@apply shadow-inner-md': {},
|
68
|
+
},
|
69
|
+
|
70
|
+
'.interactive-primary': {
|
71
|
+
'@apply bg-primary-idle': {},
|
72
|
+
'@apply shadow-base': {},
|
73
|
+
'@apply text-ground-floor': {},
|
74
|
+
},
|
75
|
+
|
76
|
+
'.interactive-primary:not(.interactive-disabled):focus-visible': {
|
77
|
+
'@apply bg-primary-hover': {},
|
78
|
+
},
|
79
|
+
|
80
|
+
'.interactive-primary:not(.interactive-disabled):hover': {
|
81
|
+
'@apply bg-primary-hover': {},
|
82
|
+
'@apply shadow-md': {},
|
83
|
+
},
|
84
|
+
|
85
|
+
'.interactive-primary:not(.interactive-disabled):active': {
|
86
|
+
'@apply bg-primary-pressed': {},
|
87
|
+
'@apply shadow-inner-md': {},
|
88
|
+
},
|
89
|
+
|
90
|
+
'.interactive-destructive': {
|
91
|
+
'@apply bg-destructive-idle': {},
|
92
|
+
'@apply shadow-base': {},
|
93
|
+
'@apply text-destructive-pressed': {},
|
94
|
+
},
|
95
|
+
|
96
|
+
'.interactive-destructive:not(.interactive-disabled):focus-visible': {
|
97
|
+
'@apply bg-destructive-hover': {},
|
98
|
+
'@apply text-ground-floor': {},
|
99
|
+
},
|
100
|
+
|
101
|
+
'.interactive-destructive:not(.interactive-disabled):hover': {
|
102
|
+
'@apply shadow-md': {},
|
103
|
+
'@apply bg-destructive-hover': {},
|
104
|
+
'@apply text-ground-floor': {},
|
105
|
+
},
|
106
|
+
|
107
|
+
'.interactive-destructive:not(.interactive-disabled):active': {
|
108
|
+
'@apply bg-destructive-pressed': {},
|
109
|
+
'@apply text-ground-floor': {},
|
110
|
+
'@apply shadow-inner-md': {},
|
111
|
+
},
|
112
|
+
|
113
|
+
'.interactive-link': {
|
114
|
+
'@apply bg-transparent': {},
|
115
|
+
'@apply text-primary-idle': {},
|
116
|
+
},
|
117
|
+
|
118
|
+
'.interactive-link:not(.interactive-disabled):hover': {
|
119
|
+
'@apply bg-opacity-0': {},
|
120
|
+
'@apply text-primary-hover': {},
|
121
|
+
},
|
122
|
+
|
123
|
+
'.interactive-link:not(.interactive-disabled):active': {
|
124
|
+
'@apply text-primary-pressed': {},
|
125
|
+
},
|
126
|
+
|
127
|
+
'.interactive-quiet': {
|
128
|
+
'@apply bg-transparent': {},
|
129
|
+
'@apply text-text-and-icons': {},
|
130
|
+
},
|
131
|
+
|
132
|
+
'.interactive-quiet:not(.interactive-disabled):focus-visible': {
|
133
|
+
'@apply bg-normal-hover': {},
|
134
|
+
},
|
135
|
+
|
136
|
+
'.interactive-quiet:not(.interactive-disabled):hover': {
|
137
|
+
'@apply bg-normal-hover': {},
|
138
|
+
'@apply shadow-md': {},
|
139
|
+
},
|
140
|
+
|
141
|
+
'.interactive-quiet:not(.interactive-disabled):active': {
|
142
|
+
'@apply bg-normal-pressed': {},
|
143
|
+
'@apply shadow-inner-md': {},
|
144
|
+
},
|
145
|
+
|
146
|
+
'.interactive-disabled': {
|
147
|
+
'@apply bg-overlay-1': {},
|
148
|
+
'@apply cursor-default': {},
|
149
|
+
'@apply shadow-none': {},
|
150
|
+
'@apply text-disabled': {},
|
151
|
+
},
|
152
|
+
|
153
|
+
'.interactive-quiet.interactive-disabled': {
|
154
|
+
'@apply bg-transparent': {},
|
155
|
+
},
|
156
|
+
});
|
157
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
const addLineClampUtilities = ({ addUtilities }) => {
|
6
|
+
let clampUtility = {};
|
7
|
+
|
8
|
+
for (let c = 1; c <= 10; c++) {
|
9
|
+
clampUtility[`.clamp-${c}`] = {
|
10
|
+
display: '-webkit-box',
|
11
|
+
'-webkit-line-clamp': `${c}`,
|
12
|
+
'-webkit-box-orient': 'vertical',
|
13
|
+
overflow: 'hidden',
|
14
|
+
};
|
15
|
+
}
|
16
|
+
|
17
|
+
return addUtilities(clampUtility);
|
18
|
+
};
|
19
|
+
|
20
|
+
/*
|
21
|
+
Clamp
|
22
|
+
|
23
|
+
this adds overflow hidden and ellipsis for multiple lines of text
|
24
|
+
The following utility is added for creating truncated line:
|
25
|
+
|
26
|
+
clamp-<lineNumber>
|
27
|
+
|
28
|
+
This currently support up to 10 lines.
|
29
|
+
|
30
|
+
Examples
|
31
|
+
|
32
|
+
<div>
|
33
|
+
<span class="clamp-7">
|
34
|
+
Green juice tumeric coloring book, before they sold out sartorial post-ironic edison bulb. Beard fashion axe +1 hell of, bushwick ugh kogi pickled williamsburg chartreuse. Kale chips normcore cornhole, art party before they sold out PBR&B kogi roof party listicle taxidermy asymmetrical actually hot chicken. Etsy XOXO freegan trust fund bicycle rights, cronut meditation chillwave ramps meggings letterpress.
|
35
|
+
Pork belly yr pickled twee shaman biodiesel hammock tattooed etsy keffiyeh literally semiotics forage tote bag. Kinfolk chicharrones wolf shaman butcher knausgaard. Ethical seitan beard hella asymmetrical. Prism trust fund lomo, next level sriracha iceland snackwave sustainable chillwave locavore gluten-free drinking vinegar raclette yr. Edison bulb celiac brunch flexitarian. Beard yuccie venmo keytar chillwave tbh trust fund locavore.
|
36
|
+
</span>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
This will truncate the paragraph after 7 lines and show an ellipsis
|
40
|
+
|
41
|
+
*/
|
42
|
+
module.exports = plugin(function (pluginApi) {
|
43
|
+
addLineClampUtilities(pluginApi);
|
44
|
+
});
|
@@ -0,0 +1,42 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
module.exports = function (themesData) {
|
6
|
+
const addThemeColorBaseClasses = ({ addBase }) => {
|
7
|
+
let generatedCss = Object.entries(themesData.themes).reduce((css, [, themeData]) => {
|
8
|
+
css[themeData.cssSelector] = themeData.colors.reduce((acc, { name, value }) => {
|
9
|
+
acc[`--${name}`] = value;
|
10
|
+
|
11
|
+
return acc;
|
12
|
+
}, {});
|
13
|
+
|
14
|
+
return css;
|
15
|
+
}, {});
|
16
|
+
|
17
|
+
addBase(generatedCss);
|
18
|
+
};
|
19
|
+
|
20
|
+
const addThemeShadowBaseClasses = ({ addBase }) => {
|
21
|
+
let generatedCss = Object.entries(themesData.themes).reduce((css, [, themeData]) => {
|
22
|
+
css[themeData.cssSelector] = themeData.shadows.reduce((acc, { name, effects }) => {
|
23
|
+
acc[`--${name}`] = effects.join(', ');
|
24
|
+
|
25
|
+
return acc;
|
26
|
+
}, {});
|
27
|
+
|
28
|
+
return css;
|
29
|
+
}, {});
|
30
|
+
|
31
|
+
addBase(generatedCss);
|
32
|
+
};
|
33
|
+
|
34
|
+
/*
|
35
|
+
This plugin will add base classes for each theme which specify all of the color
|
36
|
+
values for that theme.
|
37
|
+
*/
|
38
|
+
return plugin(function (pluginApi) {
|
39
|
+
addThemeColorBaseClasses(pluginApi);
|
40
|
+
addThemeShadowBaseClasses(pluginApi);
|
41
|
+
});
|
42
|
+
};
|
@@ -0,0 +1,140 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
module.exports = (fontSizes) =>
|
6
|
+
plugin((pluginApi) => {
|
7
|
+
addTextStyles(pluginApi, fontSizes);
|
8
|
+
});
|
9
|
+
|
10
|
+
function addTextStyles({ addComponents, theme }, fontSize) {
|
11
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/text-rendering
|
12
|
+
let geometricPrecision = { textRendering: 'geometricPrecision' };
|
13
|
+
let underline = { textDecoration: 'underline' };
|
14
|
+
|
15
|
+
let text = {
|
16
|
+
'.geometric-precision-text': {
|
17
|
+
...geometricPrecision,
|
18
|
+
},
|
19
|
+
};
|
20
|
+
|
21
|
+
/**
|
22
|
+
* NOTE:
|
23
|
+
* We cannot use theme('fontSize.XY') for everything because it contains both
|
24
|
+
* fontSize and lineHeight when used in this type of object, every usage
|
25
|
+
* provides *two* fontSizes (one desired, one is supposed to be the lineHeight,
|
26
|
+
* but is interpreted as a fontSize here).
|
27
|
+
*/
|
28
|
+
let textStyles = {
|
29
|
+
'.type-4xl': {
|
30
|
+
fontSize: fontSize['4xl'],
|
31
|
+
lineHeight: theme('lineHeight.13'),
|
32
|
+
fontWeight: theme('fontWeight.medium'),
|
33
|
+
letterSpacing: theme('letterSpacing.tight'),
|
34
|
+
},
|
35
|
+
'.type-3xl': {
|
36
|
+
fontSize: fontSize['3xl'],
|
37
|
+
lineHeight: theme('lineHeight.12'),
|
38
|
+
fontWeight: theme('fontWeight.medium'),
|
39
|
+
letterSpacing: theme('letterSpacing.tight'),
|
40
|
+
},
|
41
|
+
'.type-2xl': {
|
42
|
+
fontSize: fontSize['2xl'],
|
43
|
+
lineHeight: theme('lineHeight.10'),
|
44
|
+
fontWeight: theme('fontWeight.medium'),
|
45
|
+
},
|
46
|
+
'.type-xl': {
|
47
|
+
fontSize: fontSize.xl,
|
48
|
+
lineHeight: theme('lineHeight.8'),
|
49
|
+
fontWeight: theme('fontWeight.medium'),
|
50
|
+
...geometricPrecision,
|
51
|
+
},
|
52
|
+
'.type-lg': {
|
53
|
+
fontSize: fontSize.lg,
|
54
|
+
lineHeight: theme('lineHeight.8'),
|
55
|
+
},
|
56
|
+
'.type-lg-medium': {
|
57
|
+
fontSize: fontSize.lg,
|
58
|
+
lineHeight: theme('lineHeight.8'),
|
59
|
+
fontWeight: theme('fontWeight.medium'),
|
60
|
+
},
|
61
|
+
'.type-lg-tight-medium': {
|
62
|
+
fontSize: fontSize.lg,
|
63
|
+
lineHeight: theme('lineHeight.6'),
|
64
|
+
fontWeight: theme('fontWeight.medium'),
|
65
|
+
...geometricPrecision,
|
66
|
+
},
|
67
|
+
'.type-md': {
|
68
|
+
fontSize: fontSize.md,
|
69
|
+
lineHeight: theme('lineHeight.6'),
|
70
|
+
},
|
71
|
+
// deprecated? md-medium?
|
72
|
+
'.type-md-medium': {
|
73
|
+
fontSize: fontSize.md,
|
74
|
+
lineHeight: theme('lineHeight.6'),
|
75
|
+
fontWeight: theme('fontWeight.medium'),
|
76
|
+
},
|
77
|
+
'.type-md-underline': {
|
78
|
+
fontSize: fontSize.md,
|
79
|
+
lineHeight: theme('lineHeight.6'),
|
80
|
+
...underline,
|
81
|
+
},
|
82
|
+
'.type-md-tight': {
|
83
|
+
fontSize: fontSize.md,
|
84
|
+
lineHeight: theme('lineHeight.5'),
|
85
|
+
},
|
86
|
+
'.type-md-tight-medium': {
|
87
|
+
fontSize: fontSize.md,
|
88
|
+
lineHeight: theme('lineHeight.5'),
|
89
|
+
fontWeight: theme('fontWeight.medium'),
|
90
|
+
...geometricPrecision,
|
91
|
+
},
|
92
|
+
'.type-md-tight-underline': {
|
93
|
+
fontSize: fontSize.md,
|
94
|
+
lineHeight: theme('lineHeight.5'),
|
95
|
+
...underline,
|
96
|
+
},
|
97
|
+
'.type-sm-mono': {
|
98
|
+
fontSize: fontSize.sm,
|
99
|
+
lineHeight: theme('lineHeight.6'),
|
100
|
+
fontFamily: theme('fontFamily.mono'),
|
101
|
+
},
|
102
|
+
'.type-sm-mono-tight': {
|
103
|
+
fontSize: fontSize.sm,
|
104
|
+
fontFamily: theme('fontFamily.mono'),
|
105
|
+
lineHeight: theme('lineHeight.5'),
|
106
|
+
},
|
107
|
+
'.type-sm-mono-underline': {
|
108
|
+
fontSize: fontSize.sm,
|
109
|
+
lineHeight: theme('lineHeight.6'),
|
110
|
+
fontFamily: theme('fontFamily.mono'),
|
111
|
+
...underline,
|
112
|
+
},
|
113
|
+
'.type-xs': {
|
114
|
+
fontSize: fontSize.xs,
|
115
|
+
lineHeight: theme('lineHeight.5'),
|
116
|
+
},
|
117
|
+
'.type-xs-tight': {
|
118
|
+
fontSize: fontSize.xs,
|
119
|
+
lineHeight: theme('lineHeight.4'),
|
120
|
+
},
|
121
|
+
'.type-xs-tight-underline': {
|
122
|
+
fontSize: fontSize.xs,
|
123
|
+
lineHeight: theme('lineHeight.4'),
|
124
|
+
...underline,
|
125
|
+
},
|
126
|
+
'.type-xs-mono': {
|
127
|
+
fontSize: fontSize.xs,
|
128
|
+
lineHeight: theme('lineHeight.6'),
|
129
|
+
fontFamily: theme('fontFamily.mono'),
|
130
|
+
},
|
131
|
+
'.type-xxs-mono': {
|
132
|
+
fontSize: fontSize.xxs,
|
133
|
+
lineHeight: theme('lineHeight.4'),
|
134
|
+
fontFamily: theme('fontFamily.mono'),
|
135
|
+
},
|
136
|
+
};
|
137
|
+
|
138
|
+
addComponents(textStyles);
|
139
|
+
addComponents(text);
|
140
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const plugin = require('tailwindcss/plugin');
|
4
|
+
|
5
|
+
const FALCON_VARIBALES = {
|
6
|
+
'--side-nav-width-collapsed': '122px',
|
7
|
+
'--side-nav-width-expanded': '247px',
|
8
|
+
|
9
|
+
'--tab-list-height': '40px',
|
10
|
+
'--tab-height': '40px',
|
11
|
+
'--tab-border-radius': '8px',
|
12
|
+
|
13
|
+
'--process-offset-top': '40px',
|
14
|
+
|
15
|
+
'--default-animation-duration': '125ms',
|
16
|
+
'--default-animation-timing-function': 'ease-out',
|
17
|
+
|
18
|
+
'--default-animation-settings':
|
19
|
+
'var(--default-animation-duration) var(--default-animation-timing-function)',
|
20
|
+
};
|
21
|
+
|
22
|
+
module.exports = plugin(function ({ addComponents, theme }) {
|
23
|
+
let roots = {};
|
24
|
+
|
25
|
+
// See: https://tailwindcss.com/docs/margin/#app
|
26
|
+
// for values
|
27
|
+
let space = theme(`space`);
|
28
|
+
|
29
|
+
if (!space) {
|
30
|
+
throw new Error('TailwindCSS 1.9.6 or greater is required');
|
31
|
+
}
|
32
|
+
|
33
|
+
for (let [specifier, amount] of Object.entries(space)) {
|
34
|
+
let varName = `--space-${specifier}`;
|
35
|
+
|
36
|
+
roots[varName] = amount;
|
37
|
+
}
|
38
|
+
|
39
|
+
addComponents({
|
40
|
+
':root': {
|
41
|
+
...roots,
|
42
|
+
...FALCON_VARIBALES,
|
43
|
+
},
|
44
|
+
});
|
45
|
+
});
|