@brightspot/ui 0.0.0-alpha.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 +153 -0
- package/dist/lucide-static.d.ts +1 -0
- package/dist/tailwind-plugin-badge.js +68 -0
- package/dist/tailwind-plugin-badge.ts +103 -0
- package/dist/tailwind-plugin-button.js +223 -0
- package/dist/tailwind-plugin-button.ts +244 -0
- package/dist/tailwind-plugin-heading.js +51 -0
- package/dist/tailwind-plugin-heading.ts +54 -0
- package/dist/tailwind-plugin-icon.js +247 -0
- package/dist/tailwind-plugin-icon.ts +280 -0
- package/dist/tailwind-plugin-loader.js +31 -0
- package/dist/tailwind-plugin-loader.ts +34 -0
- package/dist/tailwind-plugin-scroll-shadow.js +77 -0
- package/dist/tailwind-plugin-scroll-shadow.ts +86 -0
- package/dist/tailwind-plugin-theme.js +48 -0
- package/dist/tailwind-plugin-theme.ts +73 -0
- package/dist/tailwind.config.js +567 -0
- package/dist/tailwind.config.ts +582 -0
- package/package.json +33 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin'
|
|
2
|
+
import icons from 'lucide-static/font/info.json'
|
|
3
|
+
import * as LucideExports from 'lucide-static/dist/cjs/lucide-static'
|
|
4
|
+
declare let module: any
|
|
5
|
+
|
|
6
|
+
interface LucideTypes {
|
|
7
|
+
encodedCode: string
|
|
8
|
+
prefix: string
|
|
9
|
+
className: string
|
|
10
|
+
unicode: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Lucide Icons | https://lucide.dev/icons/
|
|
15
|
+
* Each icon is designed on a 24x24 grid with an emphasis on simplicity, consistency and readability.
|
|
16
|
+
* Colors can also be changed via symbol overrides.
|
|
17
|
+
* All strokes in these icons have been converted to single vectors
|
|
18
|
+
* so color overrides are respected within variants.
|
|
19
|
+
*
|
|
20
|
+
* Class Names:
|
|
21
|
+
*
|
|
22
|
+
* btu-icon - Establishes the standard icon styles and font.
|
|
23
|
+
* btu-icon-{name-of-icon} - Sets the font glyph to the value of the icon you want.
|
|
24
|
+
* btu-icon-[xs|sm|md|lg|xl|{arbitary value}] - Size of the icon.
|
|
25
|
+
* btu-icon-gradient-[primary] - Gradient to use for the icon background.
|
|
26
|
+
* btu-icon-via-mask-{name of icon} - SVG mask to use given a specific icon name.
|
|
27
|
+
* - exposes a custom property `--Icon-svg` data URI to set the mask.
|
|
28
|
+
*
|
|
29
|
+
* Usages:
|
|
30
|
+
*
|
|
31
|
+
* A heart icon:
|
|
32
|
+
* > before:btu-icon before:btu-icon-heart
|
|
33
|
+
*
|
|
34
|
+
* A heart icon that is 2rem in size:
|
|
35
|
+
* > before:btu-icon before:btu-icon-heart before:[--Icon-size:2rem]
|
|
36
|
+
* - or -
|
|
37
|
+
* > before:btu-icon before:btu-icon-heart before:btu-icon-lg
|
|
38
|
+
*
|
|
39
|
+
* A heart icon with a gradient background:
|
|
40
|
+
* > before:btu-icon-gradient-primary before:btu-icon-via-mask-heart
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
const svgs: Record<string, string> = {}
|
|
44
|
+
const symbols = /[\r\n%#()<>?[\\\]^`{|}]/g
|
|
45
|
+
for (const [key, value] of Object.entries(LucideExports)) {
|
|
46
|
+
if (LucideExports.hasOwnProperty(key)) {
|
|
47
|
+
if (typeof value === 'string') {
|
|
48
|
+
svgs[key] = value
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function addNameSpace(data: string): string {
|
|
54
|
+
if (data.indexOf(`http://www.w3.org/2000/svg`) < 0) {
|
|
55
|
+
data = data.replace(/<svg/g, `<svg xmlns='http://www.w3.org/2000/svg'`)
|
|
56
|
+
}
|
|
57
|
+
return data
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function pascalToKebab(str: string): string {
|
|
61
|
+
return str
|
|
62
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
63
|
+
.replace(/([A-Za-z])([0-9])/g, '$1-$2')
|
|
64
|
+
.toLowerCase()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function kebabToPascal(str: string): string {
|
|
68
|
+
return str
|
|
69
|
+
.split('-')
|
|
70
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
71
|
+
.join('')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function encodeSVG(data: string): string {
|
|
75
|
+
data = data.replace(/"/g, `'`)
|
|
76
|
+
data = data.replace(/>\s{1,}</g, `><`)
|
|
77
|
+
data = data.replace(/\s{2,}/g, ` `)
|
|
78
|
+
return data.replace(symbols, encodeURIComponent)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = plugin(
|
|
82
|
+
function ({ addBase, addComponents, matchUtilities, theme }) {
|
|
83
|
+
const size = 'var(--Icon-size)'
|
|
84
|
+
const prefix = '.btu-icon-'
|
|
85
|
+
|
|
86
|
+
Object.entries(svgs).forEach(([key, svg]) => {
|
|
87
|
+
addComponents({
|
|
88
|
+
[`${prefix}via-mask`]: {
|
|
89
|
+
'--size': '20px',
|
|
90
|
+
mask: 'var(--Icon-svg, var(--compat-icon-via-mask)) center / contain no-repeat',
|
|
91
|
+
'aspect-ratio': '1',
|
|
92
|
+
'inline-size': 'var(--Icon-size, --size)',
|
|
93
|
+
},
|
|
94
|
+
[`${prefix}via-mask-${pascalToKebab(key)}`]: {
|
|
95
|
+
'--size': '20px',
|
|
96
|
+
'--Icon-svg': `url("data:image/svg+xml,${encodeSVG(addNameSpace(svg))}")`,
|
|
97
|
+
mask: 'var(--Icon-svg) center / contain no-repeat',
|
|
98
|
+
'aspect-ratio': '1',
|
|
99
|
+
'inline-size': 'var(--Icon-size, --size)',
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
addComponents({
|
|
105
|
+
'.btu-icon': {
|
|
106
|
+
'font-family': theme('fontFamily.lucide'),
|
|
107
|
+
direction: 'ltr',
|
|
108
|
+
display: 'inline-flex',
|
|
109
|
+
'font-feature-settings': '"liga" 0',
|
|
110
|
+
'-moz-osx-font-smoothing': 'grayscale',
|
|
111
|
+
'-webkit-font-smoothing': 'antialiased',
|
|
112
|
+
'font-size': size,
|
|
113
|
+
'font-style': 'normal',
|
|
114
|
+
'font-weight': 'normal',
|
|
115
|
+
'letter-spacing': 'normal',
|
|
116
|
+
'line-height': size,
|
|
117
|
+
'text-transform': 'none',
|
|
118
|
+
'white-space': 'nowrap',
|
|
119
|
+
'word-wrap': 'normal',
|
|
120
|
+
'vertical-align': 'top',
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
addComponents(
|
|
125
|
+
Object.entries(icons).map((value) => {
|
|
126
|
+
return {
|
|
127
|
+
[prefix + value[0]]: {
|
|
128
|
+
'--tw-content': `'${value[1].encodedCode}'`,
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
133
|
+
matchUtilities(
|
|
134
|
+
{
|
|
135
|
+
'btu-icon-gradient': (value) => ({
|
|
136
|
+
'background-image': value,
|
|
137
|
+
'background-repeat': 'no-repeat',
|
|
138
|
+
'background-position': 'center',
|
|
139
|
+
'background-size': 'var(--Icon-size) var(--Icon-size)',
|
|
140
|
+
}),
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
values: {
|
|
144
|
+
primary:
|
|
145
|
+
'linear-gradient(to top right, theme(colors.primary.500), theme(colors.primary.700), theme(colors.primary.900))',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
matchUtilities(
|
|
150
|
+
{
|
|
151
|
+
'btu-icon': (value) => ({
|
|
152
|
+
'--Icon-size': value,
|
|
153
|
+
}),
|
|
154
|
+
},
|
|
155
|
+
{ values: theme('iconSize') },
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
// Compat v4 Icons:
|
|
159
|
+
// Icon names which are Google Material icons mapped to a lucide equivalent to support the legacy markup.
|
|
160
|
+
const compatNames = new Map()
|
|
161
|
+
compatNames.set('arrow_downward', 'arrow-down')
|
|
162
|
+
compatNames.set('arrow_upward', 'arrow-up')
|
|
163
|
+
compatNames.set('assessment', 'file-chart-pie')
|
|
164
|
+
compatNames.set('assignment', 'clipboard-check')
|
|
165
|
+
compatNames.set('attachment', 'file')
|
|
166
|
+
compatNames.set('auto_stories', 'book')
|
|
167
|
+
compatNames.set('ballot', 'shield-question')
|
|
168
|
+
compatNames.set('border_all', 'table-2')
|
|
169
|
+
compatNames.set('cancel', 'circle-x')
|
|
170
|
+
compatNames.set('chat_bubble', 'message-circle')
|
|
171
|
+
compatNames.set('check_circle', 'circle-check-big')
|
|
172
|
+
compatNames.set('chrome_reader_mode', 'table-properties')
|
|
173
|
+
compatNames.set('class', 'book-type')
|
|
174
|
+
compatNames.set('close', 'x')
|
|
175
|
+
compatNames.set('code', 'code')
|
|
176
|
+
compatNames.set('comment', 'message-circle-plus')
|
|
177
|
+
compatNames.set('comments_disabled', 'message-circle-x')
|
|
178
|
+
compatNames.set('create_new_folder', 'boxes')
|
|
179
|
+
compatNames.set('description', 'file-text')
|
|
180
|
+
compatNames.set('edit', 'pencil')
|
|
181
|
+
compatNames.set('error', 'circle-alert')
|
|
182
|
+
compatNames.set('expand_more', 'chevrons-up-down')
|
|
183
|
+
compatNames.set('expand_less', 'chevrons-down-up')
|
|
184
|
+
compatNames.set('feed', 'scroll-text')
|
|
185
|
+
compatNames.set('format_align_center', 'align-center')
|
|
186
|
+
compatNames.set('format_align_left', 'align-left')
|
|
187
|
+
compatNames.set('format_align_right', 'align-right')
|
|
188
|
+
compatNames.set('format_bold', 'bold')
|
|
189
|
+
compatNames.set('format_clear', 'remove-formatting')
|
|
190
|
+
compatNames.set('format_indent_increase', 'indent-increase')
|
|
191
|
+
compatNames.set('format_indent_decrease', 'indent-decrease')
|
|
192
|
+
compatNames.set('format_italic', 'italic')
|
|
193
|
+
compatNames.set('format_list_bulleted', 'list')
|
|
194
|
+
compatNames.set('format_list_numbered', 'badge-help')
|
|
195
|
+
compatNames.set('format_quote', 'quote')
|
|
196
|
+
compatNames.set('format_strikethrough', 'strikethrough')
|
|
197
|
+
compatNames.set('format_underlined', 'underline')
|
|
198
|
+
compatNames.set('fullscreen', 'maximize-2')
|
|
199
|
+
compatNames.set('grid_on', 'file-spreadsheet')
|
|
200
|
+
compatNames.set('handshake', 'handshake')
|
|
201
|
+
compatNames.set('help', 'circle-help')
|
|
202
|
+
compatNames.set('history', 'history')
|
|
203
|
+
compatNames.set('home', 'house')
|
|
204
|
+
compatNames.set('import_contacts', 'book')
|
|
205
|
+
compatNames.set('insert_photo', 'file-image')
|
|
206
|
+
compatNames.set('keyboard', 'keyboard')
|
|
207
|
+
compatNames.set('link', 'link-2')
|
|
208
|
+
compatNames.set('link_off', 'link-2-off')
|
|
209
|
+
compatNames.set('live_tv', 'tv-minimal-play')
|
|
210
|
+
compatNames.set('local_offer', 'tag')
|
|
211
|
+
compatNames.set('manage_search', 'text-search')
|
|
212
|
+
compatNames.set('menu_book', 'book-marked')
|
|
213
|
+
compatNames.set('more_horiz', 'ellipsis')
|
|
214
|
+
compatNames.set('music_note', 'music-2')
|
|
215
|
+
compatNames.set('notes', 'notebook-text')
|
|
216
|
+
compatNames.set('ondemand_video', 'video')
|
|
217
|
+
compatNames.set('open_with', 'move')
|
|
218
|
+
compatNames.set('person', 'user-pen')
|
|
219
|
+
compatNames.set('photo', 'file-image')
|
|
220
|
+
compatNames.set('photo_camera', 'camera')
|
|
221
|
+
compatNames.set('photo_library', 'images')
|
|
222
|
+
compatNames.set('picture', 'image-up')
|
|
223
|
+
compatNames.set('play', 'square-play')
|
|
224
|
+
compatNames.set('playlist_play', 'list-video')
|
|
225
|
+
compatNames.set('post_add', 'clipboard-plus')
|
|
226
|
+
compatNames.set('question_answer', 'pencil-line')
|
|
227
|
+
compatNames.set('rate_review', 'square-pen')
|
|
228
|
+
compatNames.set('redo', 'redo')
|
|
229
|
+
compatNames.set('remove', 'minus')
|
|
230
|
+
compatNames.set('school', 'badge-info')
|
|
231
|
+
compatNames.set('search', 'search')
|
|
232
|
+
compatNames.set('settings_ethernet', 'chevrons-left-right-ellipsis')
|
|
233
|
+
compatNames.set('short_text', 'text')
|
|
234
|
+
compatNames.set('slideshow', 'film')
|
|
235
|
+
compatNames.set('slow_motion_video', 'list-video')
|
|
236
|
+
compatNames.set('subject', 'letter-text')
|
|
237
|
+
compatNames.set('textsms', 'message-circle-more')
|
|
238
|
+
compatNames.set('theaters', 'clapperboard')
|
|
239
|
+
compatNames.set('toc', 'notebook-tabs')
|
|
240
|
+
compatNames.set('toggle_off', 'toggle-left')
|
|
241
|
+
compatNames.set('toggle_on', 'toggle-right')
|
|
242
|
+
compatNames.set('undo', 'undo')
|
|
243
|
+
compatNames.set('vertical_align_bottom', 'subscript')
|
|
244
|
+
compatNames.set('vertical_align_top', 'superscript')
|
|
245
|
+
compatNames.set('view_compact', 'layout-panel-top')
|
|
246
|
+
compatNames.set('volume_up', 'volume-2')
|
|
247
|
+
compatNames.set('warning', 'triangle-alert')
|
|
248
|
+
compatNames.set('wb_incandescent', 'lightbulb')
|
|
249
|
+
compatNames.set('widgets', 'blocks')
|
|
250
|
+
compatNames.set('zap', 'zap')
|
|
251
|
+
|
|
252
|
+
compatNames.forEach((value: string, key) => {
|
|
253
|
+
addBase({
|
|
254
|
+
/* this is the default icon when no mapped icon is found */
|
|
255
|
+
[`[data-icon],[data-icon-name],[data-icon-button-name]`]: {
|
|
256
|
+
'--compat-icon': `'${icons['circle-dashed'].encodedCode}'`,
|
|
257
|
+
'--compat-icon-via-mask': `url("data:image/svg+xml,${encodeSVG(addNameSpace(svgs['CircleDashed']))}")`,
|
|
258
|
+
},
|
|
259
|
+
[`html [data-icon="${key}"],html [data-icon-name="${key}"],html [data-icon-button-name="${key}"]`]:
|
|
260
|
+
{
|
|
261
|
+
// tslint:disable-next-line
|
|
262
|
+
'--compat-icon': `'${(icons as Record<string, LucideTypes>)[value].encodedCode}'`,
|
|
263
|
+
'--compat-icon-via-mask': `url("data:image/svg+xml,${encodeSVG(addNameSpace(svgs[kebabToPascal(value)]))}")`,
|
|
264
|
+
},
|
|
265
|
+
})
|
|
266
|
+
})
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
theme: {
|
|
270
|
+
iconSize: {
|
|
271
|
+
DEFAULT: '1.25rem',
|
|
272
|
+
xs: '0.75rem',
|
|
273
|
+
sm: '1rem',
|
|
274
|
+
md: '1.25rem',
|
|
275
|
+
lg: '1.5rem',
|
|
276
|
+
xl: '1.75rem',
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
/**
|
|
3
|
+
* Loading indicators are a helpful way to indicate to the user that content is on the way.
|
|
4
|
+
* These should be user sparingly, and only in cases where the loading time is very short.
|
|
5
|
+
* For longer load times, we suggest using a progress bar to give the user a more
|
|
6
|
+
* realistic indication of how long the process will take.
|
|
7
|
+
*
|
|
8
|
+
* Since we cannot change markup, the loader SVG is rendered as a Data URI and
|
|
9
|
+
* then used as a background image of a pseudo-elements' content.
|
|
10
|
+
*
|
|
11
|
+
* Loaders come with light and dark styles.
|
|
12
|
+
*
|
|
13
|
+
* If you need to reference the loader size, you can do so with:
|
|
14
|
+
* --Loader-size
|
|
15
|
+
*
|
|
16
|
+
* Class Name: btu-loader
|
|
17
|
+
*
|
|
18
|
+
* Typical Usage (user defined pseudo-element):
|
|
19
|
+
* @apply after:btu-loader;
|
|
20
|
+
*/
|
|
21
|
+
module.exports = plugin(function ({ addComponents, theme }) {
|
|
22
|
+
const loader = {
|
|
23
|
+
'--Loader-size': '2rem',
|
|
24
|
+
display: 'block',
|
|
25
|
+
content: 'var(--tw-content)',
|
|
26
|
+
'--tw-content': `url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 50 50%27%3E %3Cstyle%3E :root %7B --Loader-bg-color: oklch%28${encodeURIComponent(theme('colors.gray.light.200'))}%29; --Loader-fg-color: oklch%28${encodeURIComponent(theme('colors.primary.light.600'))}%29; --btu-theme-primary-hue: 264; %7D @media %28prefers-color-scheme: dark%29 %7B :root %7B --Loader-bg-color: oklch%28${encodeURIComponent(theme('colors.gray.dark.100'))}%29; --Loader-fg-color: oklch%28${encodeURIComponent(theme('colors.primary.dark.700'))}%29; %7D %7D @keyframes rotate%7B100%25%7Btransform:rotate%28360deg%29;%7D%7D @keyframes dash%7B0%25%7Bstroke-dasharray:1,200;stroke-dashoffset:0;%7D50%25%7Bstroke-dasharray:89,200;stroke-dashoffset:-35;%7D100%25%7Bstroke-dasharray:89,200;stroke-dashoffset:-124;%7D%7D svg %7Bwill-change:transform;position:relative;animation:rotate 1.6s linear infinite;%7D .Loader-bg %7Bwill-change:transform;fill:none;transform-origin:center;%7D .Loader-fg %7Bwill-change:transform;animation:dash 1s infinite ease-in-out;animation-fill-mode:both;fill:none;transform-origin:center;stroke-linecap:round;stroke-dasharray:1,200;stroke-dashoffset:0;%7D %3C/style%3E %3Ccircle cx=%2725%27 cy=%2725%27 r=%2720%27 stroke-width=%274%27 class=%27Loader-bg%27 stroke=%27var%28--Loader-bg-color%29%27/%3E %3Ccircle cx=%2725%27 cy=%2725%27 r=%2720%27 stroke-width=%274%27 class=%27Loader-fg%27 stroke=%27var%28--Loader-fg-color%29%27/%3E %3C/svg%3E")`,
|
|
27
|
+
};
|
|
28
|
+
addComponents({
|
|
29
|
+
'.btu-loader': loader,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin'
|
|
2
|
+
declare let module: any
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Loading indicators are a helpful way to indicate to the user that content is on the way.
|
|
6
|
+
* These should be user sparingly, and only in cases where the loading time is very short.
|
|
7
|
+
* For longer load times, we suggest using a progress bar to give the user a more
|
|
8
|
+
* realistic indication of how long the process will take.
|
|
9
|
+
*
|
|
10
|
+
* Since we cannot change markup, the loader SVG is rendered as a Data URI and
|
|
11
|
+
* then used as a background image of a pseudo-elements' content.
|
|
12
|
+
*
|
|
13
|
+
* Loaders come with light and dark styles.
|
|
14
|
+
*
|
|
15
|
+
* If you need to reference the loader size, you can do so with:
|
|
16
|
+
* --Loader-size
|
|
17
|
+
*
|
|
18
|
+
* Class Name: btu-loader
|
|
19
|
+
*
|
|
20
|
+
* Typical Usage (user defined pseudo-element):
|
|
21
|
+
* @apply after:btu-loader;
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
module.exports = plugin(function ({ addComponents, theme }) {
|
|
25
|
+
const loader = {
|
|
26
|
+
'--Loader-size': '2rem',
|
|
27
|
+
display: 'block',
|
|
28
|
+
content: 'var(--tw-content)',
|
|
29
|
+
'--tw-content': `url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 50 50%27%3E %3Cstyle%3E :root %7B --Loader-bg-color: oklch%28${encodeURIComponent(theme('colors.gray.light.200'))}%29; --Loader-fg-color: oklch%28${encodeURIComponent(theme('colors.primary.light.600'))}%29; --btu-theme-primary-hue: 264; %7D @media %28prefers-color-scheme: dark%29 %7B :root %7B --Loader-bg-color: oklch%28${encodeURIComponent(theme('colors.gray.dark.100'))}%29; --Loader-fg-color: oklch%28${encodeURIComponent(theme('colors.primary.dark.700'))}%29; %7D %7D @keyframes rotate%7B100%25%7Btransform:rotate%28360deg%29;%7D%7D @keyframes dash%7B0%25%7Bstroke-dasharray:1,200;stroke-dashoffset:0;%7D50%25%7Bstroke-dasharray:89,200;stroke-dashoffset:-35;%7D100%25%7Bstroke-dasharray:89,200;stroke-dashoffset:-124;%7D%7D svg %7Bwill-change:transform;position:relative;animation:rotate 1.6s linear infinite;%7D .Loader-bg %7Bwill-change:transform;fill:none;transform-origin:center;%7D .Loader-fg %7Bwill-change:transform;animation:dash 1s infinite ease-in-out;animation-fill-mode:both;fill:none;transform-origin:center;stroke-linecap:round;stroke-dasharray:1,200;stroke-dashoffset:0;%7D %3C/style%3E %3Ccircle cx=%2725%27 cy=%2725%27 r=%2720%27 stroke-width=%274%27 class=%27Loader-bg%27 stroke=%27var%28--Loader-bg-color%29%27/%3E %3Ccircle cx=%2725%27 cy=%2725%27 r=%2720%27 stroke-width=%274%27 class=%27Loader-fg%27 stroke=%27var%28--Loader-fg-color%29%27/%3E %3C/svg%3E")`,
|
|
30
|
+
}
|
|
31
|
+
addComponents({
|
|
32
|
+
'.btu-loader': loader,
|
|
33
|
+
})
|
|
34
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
/**
|
|
3
|
+
* This plugin adds shadows to the edges of a scrollable container when the content
|
|
4
|
+
* of the container is overflowing.
|
|
5
|
+
* You can choose a light or dark shadow.
|
|
6
|
+
* Your container must not already use before & after pseudo elements.
|
|
7
|
+
* If you use TWCSS before/after modifiers on this element, make sure you also manually
|
|
8
|
+
* set the content property to the `--whitespace` variable. This is a workaround for TWCSS
|
|
9
|
+
* automatically adding a content property to the before/after pseudo-elements, which
|
|
10
|
+
* overrides the `--whitespace` variable by default.
|
|
11
|
+
*
|
|
12
|
+
* Class Names:
|
|
13
|
+
* btu-scrollshadow-light - light shadow.
|
|
14
|
+
* btu-scrollshadow-dark - dark shadow.
|
|
15
|
+
*
|
|
16
|
+
* Typical Usage:
|
|
17
|
+
* @apply btu-scrollshadow-light;
|
|
18
|
+
*
|
|
19
|
+
* Custom usage for when you need to style before/after pseudo-elements:
|
|
20
|
+
* @apply btu-scrollshadow-light before:absolute before:content-[--whitespace] <-- must do this (see more info above);
|
|
21
|
+
*/
|
|
22
|
+
module.exports = plugin(function ({ addComponents }) {
|
|
23
|
+
const shared = {
|
|
24
|
+
/* these 3 whitespaces dictate the width of the shadow (necessary to give the pseudo elements an intrinsic size). */
|
|
25
|
+
'--whitespace': '"\u2002\u2002\u2002"',
|
|
26
|
+
animation: 'detect-scroll',
|
|
27
|
+
'overflow-x': 'auto',
|
|
28
|
+
'animation-fill-mode': 'none',
|
|
29
|
+
'animation-timeline': '--scroll-timeline',
|
|
30
|
+
'scroll-timeline': '--scroll-timeline x',
|
|
31
|
+
'&:before, &:after': {
|
|
32
|
+
'--visibility-if-can-scroll': 'var(--can-scroll) visible',
|
|
33
|
+
'--visibility-if-cant-scroll': 'hidden',
|
|
34
|
+
content: 'var(--whitespace)',
|
|
35
|
+
'animation-name': 'fade-in',
|
|
36
|
+
'animation-fill-mode': 'both',
|
|
37
|
+
'animation-timeline': '--scroll-timeline',
|
|
38
|
+
'pointer-events': 'none',
|
|
39
|
+
display: 'block',
|
|
40
|
+
position: 'sticky',
|
|
41
|
+
bottom: '0px',
|
|
42
|
+
top: '0px',
|
|
43
|
+
visibility: 'var(--visibility-if-can-scroll, var(--visibility-if-cant-scroll))',
|
|
44
|
+
'z-index': '10',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const light = Object.assign({}, shared, {
|
|
48
|
+
'&:before': {
|
|
49
|
+
left: '0px',
|
|
50
|
+
'background-image': 'linear-gradient(to left, transparent, oklch(var(--btu-theme-gray-25)/0.9) 90% 100%)',
|
|
51
|
+
'animation-range': '0ch 3ch',
|
|
52
|
+
},
|
|
53
|
+
'&:after': {
|
|
54
|
+
right: '0px',
|
|
55
|
+
'background-image': 'linear-gradient(to right, transparent, oklch(var(--btu-theme-gray-25)/0.9) 90% 100%)',
|
|
56
|
+
'animation-direction': 'reverse',
|
|
57
|
+
'animation-range': 'calc(100% - 3ch) calc(100% - 0ch)',
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const dark = Object.assign({}, shared, {
|
|
61
|
+
'&:before': {
|
|
62
|
+
left: '0px',
|
|
63
|
+
'background-image': `linear-gradient(to left, transparent, oklch(var(--btu-theme-gray-50)/0.9) 90% 100%)`,
|
|
64
|
+
'animation-range': '0ch 3ch',
|
|
65
|
+
},
|
|
66
|
+
'&:after': {
|
|
67
|
+
right: '0px',
|
|
68
|
+
'background-image': `linear-gradient(to right, transparent, oklch(var(--btu-theme-gray-50)/0.9) 90% 100%)`,
|
|
69
|
+
'animation-direction': 'reverse',
|
|
70
|
+
'animation-range': 'calc(100% - 3ch) calc(100% - 0ch)',
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
addComponents({
|
|
74
|
+
'.btu-scrollshadow-light': light,
|
|
75
|
+
'.btu-scrollshadow-dark': dark,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin'
|
|
2
|
+
declare let module: any
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This plugin adds shadows to the edges of a scrollable container when the content
|
|
6
|
+
* of the container is overflowing.
|
|
7
|
+
* You can choose a light or dark shadow.
|
|
8
|
+
* Your container must not already use before & after pseudo elements.
|
|
9
|
+
* If you use TWCSS before/after modifiers on this element, make sure you also manually
|
|
10
|
+
* set the content property to the `--whitespace` variable. This is a workaround for TWCSS
|
|
11
|
+
* automatically adding a content property to the before/after pseudo-elements, which
|
|
12
|
+
* overrides the `--whitespace` variable by default.
|
|
13
|
+
*
|
|
14
|
+
* Class Names:
|
|
15
|
+
* btu-scrollshadow-light - light shadow.
|
|
16
|
+
* btu-scrollshadow-dark - dark shadow.
|
|
17
|
+
*
|
|
18
|
+
* Typical Usage:
|
|
19
|
+
* @apply btu-scrollshadow-light;
|
|
20
|
+
*
|
|
21
|
+
* Custom usage for when you need to style before/after pseudo-elements:
|
|
22
|
+
* @apply btu-scrollshadow-light before:absolute before:content-[--whitespace] <-- must do this (see more info above);
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
module.exports = plugin(function ({ addComponents }) {
|
|
26
|
+
const shared = {
|
|
27
|
+
/* these 3 whitespaces dictate the width of the shadow (necessary to give the pseudo elements an intrinsic size). */
|
|
28
|
+
'--whitespace': '"\u2002\u2002\u2002"',
|
|
29
|
+
animation: 'detect-scroll',
|
|
30
|
+
'overflow-x': 'auto',
|
|
31
|
+
'animation-fill-mode': 'none',
|
|
32
|
+
'animation-timeline': '--scroll-timeline',
|
|
33
|
+
'scroll-timeline': '--scroll-timeline x',
|
|
34
|
+
'&:before, &:after': {
|
|
35
|
+
'--visibility-if-can-scroll': 'var(--can-scroll) visible',
|
|
36
|
+
'--visibility-if-cant-scroll': 'hidden',
|
|
37
|
+
content: 'var(--whitespace)',
|
|
38
|
+
'animation-name': 'fade-in',
|
|
39
|
+
'animation-fill-mode': 'both',
|
|
40
|
+
'animation-timeline': '--scroll-timeline',
|
|
41
|
+
'pointer-events': 'none',
|
|
42
|
+
display: 'block',
|
|
43
|
+
position: 'sticky',
|
|
44
|
+
bottom: '0px',
|
|
45
|
+
top: '0px',
|
|
46
|
+
visibility:
|
|
47
|
+
'var(--visibility-if-can-scroll, var(--visibility-if-cant-scroll))',
|
|
48
|
+
'z-index': '10',
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const light = Object.assign({}, shared, {
|
|
53
|
+
'&:before': {
|
|
54
|
+
left: '0px',
|
|
55
|
+
'background-image':
|
|
56
|
+
'linear-gradient(to left, transparent, oklch(var(--btu-theme-gray-25)/0.9) 90% 100%)',
|
|
57
|
+
'animation-range': '0ch 3ch',
|
|
58
|
+
},
|
|
59
|
+
'&:after': {
|
|
60
|
+
right: '0px',
|
|
61
|
+
'background-image':
|
|
62
|
+
'linear-gradient(to right, transparent, oklch(var(--btu-theme-gray-25)/0.9) 90% 100%)',
|
|
63
|
+
'animation-direction': 'reverse',
|
|
64
|
+
'animation-range': 'calc(100% - 3ch) calc(100% - 0ch)',
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const dark = Object.assign({}, shared, {
|
|
69
|
+
'&:before': {
|
|
70
|
+
left: '0px',
|
|
71
|
+
'background-image': `linear-gradient(to left, transparent, oklch(var(--btu-theme-gray-50)/0.9) 90% 100%)`,
|
|
72
|
+
'animation-range': '0ch 3ch',
|
|
73
|
+
},
|
|
74
|
+
'&:after': {
|
|
75
|
+
right: '0px',
|
|
76
|
+
'background-image': `linear-gradient(to right, transparent, oklch(var(--btu-theme-gray-50)/0.9) 90% 100%)`,
|
|
77
|
+
'animation-direction': 'reverse',
|
|
78
|
+
'animation-range': 'calc(100% - 3ch) calc(100% - 0ch)',
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
addComponents({
|
|
83
|
+
'.btu-scrollshadow-light': light,
|
|
84
|
+
'.btu-scrollshadow-dark': dark,
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin';
|
|
2
|
+
/**
|
|
3
|
+
* Generates all the CSS color properties from the Tailwind configuration.
|
|
4
|
+
*/
|
|
5
|
+
module.exports = plugin(function ({ addUtilities, theme }) {
|
|
6
|
+
const colors = theme('colors');
|
|
7
|
+
const lightStyles = new Map();
|
|
8
|
+
const darkStyles = new Map();
|
|
9
|
+
const lightStylesHC = new Map();
|
|
10
|
+
const darkStylesHC = new Map();
|
|
11
|
+
const HCChromaFactor = 0.01;
|
|
12
|
+
const HCLightnessFactors = [
|
|
13
|
+
0.01, 0.01, 0.03, 0.07, 0.07, 0.07, 0.08, 0.08, 0.08, 0.09, 0.09,
|
|
14
|
+
];
|
|
15
|
+
lightStyles.set('--btu-theme-primary-hue', '264'); /* 264 = Closest average primary hue to design system */
|
|
16
|
+
lightStyles.set('--btu-theme-error-hue', '27'); /* 27 = Closest average red hue to design system */
|
|
17
|
+
lightStyles.set('--btu-theme-success-hue', '157'); /* 157 = Closest average green hue to design system */
|
|
18
|
+
lightStyles.set('--btu-theme-white', theme('colors.white.light'));
|
|
19
|
+
lightStyles.set('--btu-theme-black', theme('colors.black.light'));
|
|
20
|
+
darkStyles.set('--btu-theme-white', theme('colors.white.dark'));
|
|
21
|
+
darkStyles.set('--btu-theme-black', theme('colors.black.dark'));
|
|
22
|
+
for (const color in colors) {
|
|
23
|
+
if (colors[color].light && colors[color].dark) {
|
|
24
|
+
const lightValues = colors[color].light;
|
|
25
|
+
const darkValues = colors[color].dark;
|
|
26
|
+
if (typeof lightValues === 'object') {
|
|
27
|
+
for (const key in lightValues) {
|
|
28
|
+
lightStyles.set(`--btu-theme-${color}-${key}`, `${lightValues[key]}`);
|
|
29
|
+
// Light high contrast palette.
|
|
30
|
+
lightStylesHC.set(`--btu-theme-${color}-${key}`, `from oklch(${lightValues[key]}) calc(l - ${HCLightnessFactors[Object.keys(lightValues).indexOf(key)]}) calc(c + ${HCChromaFactor}) h`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (typeof darkValues === 'object') {
|
|
34
|
+
for (const key in darkValues) {
|
|
35
|
+
darkStyles.set(`--btu-theme-${color}-${key}`, `${darkValues[key]}`);
|
|
36
|
+
// Dark high contrast palette.
|
|
37
|
+
darkStylesHC.set(`--btu-theme-${color}-${key}`, `from oklch(${darkValues[key]}) calc(l - ${HCLightnessFactors[Object.keys(darkValues).indexOf(key)]}) calc(c + ${HCChromaFactor}) h`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
addUtilities({
|
|
43
|
+
'.lightTheme': Object.fromEntries(lightStyles.entries()),
|
|
44
|
+
'.lightTheme-highcontrast': Object.fromEntries(lightStylesHC.entries()),
|
|
45
|
+
'.darkTheme': Object.fromEntries(darkStyles.entries()),
|
|
46
|
+
'.darkTheme-highcontrast': Object.fromEntries(darkStylesHC.entries()),
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import plugin from 'tailwindcss/plugin'
|
|
2
|
+
declare let module: any
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates all the CSS color properties from the Tailwind configuration.
|
|
6
|
+
*/
|
|
7
|
+
module.exports = plugin(function ({ addUtilities, theme }) {
|
|
8
|
+
const colors = theme('colors')
|
|
9
|
+
const lightStyles = new Map()
|
|
10
|
+
const darkStyles = new Map()
|
|
11
|
+
const lightStylesHC = new Map()
|
|
12
|
+
const darkStylesHC = new Map()
|
|
13
|
+
const HCChromaFactor = 0.01
|
|
14
|
+
const HCLightnessFactors = [
|
|
15
|
+
0.01, 0.01, 0.03, 0.07, 0.07, 0.07, 0.08, 0.08, 0.08, 0.09, 0.09,
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
lightStyles.set(
|
|
19
|
+
'--btu-theme-primary-hue',
|
|
20
|
+
'264',
|
|
21
|
+
) /* 264 = Closest average primary hue to design system */
|
|
22
|
+
lightStyles.set(
|
|
23
|
+
'--btu-theme-error-hue',
|
|
24
|
+
'27',
|
|
25
|
+
) /* 27 = Closest average red hue to design system */
|
|
26
|
+
lightStyles.set(
|
|
27
|
+
'--btu-theme-success-hue',
|
|
28
|
+
'157',
|
|
29
|
+
) /* 157 = Closest average green hue to design system */
|
|
30
|
+
lightStyles.set('--btu-theme-white', theme('colors.white.light'))
|
|
31
|
+
lightStyles.set('--btu-theme-black', theme('colors.black.light'))
|
|
32
|
+
|
|
33
|
+
darkStyles.set('--btu-theme-white', theme('colors.white.dark'))
|
|
34
|
+
darkStyles.set('--btu-theme-black', theme('colors.black.dark'))
|
|
35
|
+
|
|
36
|
+
for (const color in colors) {
|
|
37
|
+
if (colors[color].light && colors[color].dark) {
|
|
38
|
+
const lightValues = colors[color].light
|
|
39
|
+
const darkValues = colors[color].dark
|
|
40
|
+
|
|
41
|
+
if (typeof lightValues === 'object') {
|
|
42
|
+
for (const key in lightValues) {
|
|
43
|
+
lightStyles.set(`--btu-theme-${color}-${key}`, `${lightValues[key]}`)
|
|
44
|
+
|
|
45
|
+
// Light high contrast palette.
|
|
46
|
+
lightStylesHC.set(
|
|
47
|
+
`--btu-theme-${color}-${key}`,
|
|
48
|
+
`from oklch(${lightValues[key]}) calc(l - ${HCLightnessFactors[Object.keys(lightValues).indexOf(key)]}) calc(c + ${HCChromaFactor}) h`,
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (typeof darkValues === 'object') {
|
|
54
|
+
for (const key in darkValues) {
|
|
55
|
+
darkStyles.set(`--btu-theme-${color}-${key}`, `${darkValues[key]}`)
|
|
56
|
+
|
|
57
|
+
// Dark high contrast palette.
|
|
58
|
+
darkStylesHC.set(
|
|
59
|
+
`--btu-theme-${color}-${key}`,
|
|
60
|
+
`from oklch(${darkValues[key]}) calc(l - ${HCLightnessFactors[Object.keys(darkValues).indexOf(key)]}) calc(c + ${HCChromaFactor}) h`,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
addUtilities({
|
|
68
|
+
'.lightTheme': Object.fromEntries(lightStyles.entries()),
|
|
69
|
+
'.lightTheme-highcontrast': Object.fromEntries(lightStylesHC.entries()),
|
|
70
|
+
'.darkTheme': Object.fromEntries(darkStyles.entries()),
|
|
71
|
+
'.darkTheme-highcontrast': Object.fromEntries(darkStylesHC.entries()),
|
|
72
|
+
})
|
|
73
|
+
})
|