@nuxt/ui 2.14.0 → 2.14.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/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "configKey": "ui",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.10.0"
package/dist/module.mjs CHANGED
@@ -1,7 +1,8 @@
1
- import { addTemplate, useNuxt, installModule, defineNuxtModule, createResolver, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
1
  import { createRequire } from 'node:module';
3
- import { join } from 'pathe';
4
- import { kebabCase } from 'scule';
2
+ import { addTemplate, useNuxt, defineNuxtModule, createResolver, installModule, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
3
+ import { defaultExtractor as defaultExtractor$1 } from 'tailwindcss/lib/lib/defaultExtractor.js';
4
+ import { iconsPlugin, getIconCollections } from '@egoist/tailwindcss-icons';
5
+ import { kebabCase, upperFirst, camelCase } from 'scule';
5
6
 
6
7
 
7
8
 
@@ -13,7 +14,7 @@ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
13
14
  const __dirname = __cjs_path__.dirname(__filename);
14
15
  const require = __cjs_mod__.createRequire(import.meta.url);
15
16
  const name = "@nuxt/ui";
16
- const version = "2.14.0";
17
+ const version = "2.14.1";
17
18
 
18
19
  function createTemplates(nuxt = useNuxt()) {
19
20
  const template = addTemplate({
@@ -244,6 +245,13 @@ const safelistByComponent = {
244
245
  pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
245
246
  }]
246
247
  };
248
+ const safelistComponentAliasesMap = {
249
+ "USelect": "UInput",
250
+ "USelectMenu": "UInput",
251
+ "UTextarea": "UInput",
252
+ "URadioGroup": "URadio",
253
+ "UMeterGroup": "UMeter"
254
+ };
247
255
  const colorsAsRegex = (colors) => colors.join("|");
248
256
  const excludeColors = (colors) => {
249
257
  return Object.entries(omit(colors, colorsToExclude)).filter(([, value]) => typeof value === "object").map(([key]) => kebabCase(key));
@@ -263,7 +271,37 @@ const generateSafelist = (colors, globalColors) => {
263
271
  "dark:text-gray-400"
264
272
  ];
265
273
  };
274
+ const customSafelistExtractor = (prefix, content, colors, safelistColors) => {
275
+ const classes = [];
276
+ const regex = /<([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z][A-Za-z0-9]*)*)\s+(?![^>]*:color\b)[^>]*\bcolor=["']([^"']+)["'][^>]*>/gs;
277
+ const matches = content.matchAll(regex);
278
+ const components = Object.keys(safelistByComponent).map((component) => `${prefix}${component.charAt(0).toUpperCase() + component.slice(1)}`);
279
+ for (const match of matches) {
280
+ const [, component, color] = match;
281
+ const camelComponent = upperFirst(camelCase(component));
282
+ if (!colors.includes(color) || safelistColors.includes(color)) {
283
+ continue;
284
+ }
285
+ let name = safelistComponentAliasesMap[camelComponent] ? safelistComponentAliasesMap[camelComponent] : camelComponent;
286
+ if (!components.includes(name)) {
287
+ continue;
288
+ }
289
+ name = name.replace(prefix, "").toLowerCase();
290
+ const matchClasses = safelistByComponent[name](color).flatMap((group) => {
291
+ return ["", ...group.variants || []].flatMap((variant) => {
292
+ const matches2 = group.pattern.source.match(/\(([^)]+)\)/g);
293
+ return matches2.map((match2) => {
294
+ const colorOptions = match2.substring(1, match2.length - 1).split("|");
295
+ return colorOptions.map((color2) => `${variant ? variant + ":" : ""}` + group.pattern.source.replace(match2, color2));
296
+ }).flat();
297
+ });
298
+ });
299
+ classes.push(...matchClasses);
300
+ }
301
+ return classes;
302
+ };
266
303
 
304
+ const defaultExtractor = defaultExtractor$1({ tailwindConfig: { separator: ":" } });
267
305
  const _require = createRequire(import.meta.url);
268
306
  const defaultColors = _require("tailwindcss/colors.js");
269
307
  delete defaultColors.lightBlue;
@@ -271,108 +309,6 @@ delete defaultColors.warmGray;
271
309
  delete defaultColors.trueGray;
272
310
  delete defaultColors.coolGray;
273
311
  delete defaultColors.blueGray;
274
- async function installTailwind(moduleOptions, nuxt = useNuxt(), { resolve, runtimeDir }) {
275
- nuxt.hook("tailwindcss:config", function(tailwindConfig) {
276
- tailwindConfig.theme = tailwindConfig.theme || {};
277
- tailwindConfig.theme.extend = tailwindConfig.theme.extend || {};
278
- tailwindConfig.theme.extend.colors = tailwindConfig.theme.extend.colors || {};
279
- const globalColors = {
280
- ...tailwindConfig.theme.colors || defaultColors,
281
- ...tailwindConfig.theme.extend?.colors
282
- };
283
- globalColors.primary = tailwindConfig.theme.extend.colors.primary = {
284
- 50: "rgb(var(--color-primary-50) / <alpha-value>)",
285
- 100: "rgb(var(--color-primary-100) / <alpha-value>)",
286
- 200: "rgb(var(--color-primary-200) / <alpha-value>)",
287
- 300: "rgb(var(--color-primary-300) / <alpha-value>)",
288
- 400: "rgb(var(--color-primary-400) / <alpha-value>)",
289
- 500: "rgb(var(--color-primary-500) / <alpha-value>)",
290
- 600: "rgb(var(--color-primary-600) / <alpha-value>)",
291
- 700: "rgb(var(--color-primary-700) / <alpha-value>)",
292
- 800: "rgb(var(--color-primary-800) / <alpha-value>)",
293
- 900: "rgb(var(--color-primary-900) / <alpha-value>)",
294
- 950: "rgb(var(--color-primary-950) / <alpha-value>)",
295
- DEFAULT: "rgb(var(--color-primary-DEFAULT) / <alpha-value>)"
296
- };
297
- if (globalColors.gray) {
298
- globalColors.cool = tailwindConfig.theme.extend.colors.cool = defaultColors.gray;
299
- }
300
- globalColors.gray = tailwindConfig.theme.extend.colors.gray = {
301
- 50: "rgb(var(--color-gray-50) / <alpha-value>)",
302
- 100: "rgb(var(--color-gray-100) / <alpha-value>)",
303
- 200: "rgb(var(--color-gray-200) / <alpha-value>)",
304
- 300: "rgb(var(--color-gray-300) / <alpha-value>)",
305
- 400: "rgb(var(--color-gray-400) / <alpha-value>)",
306
- 500: "rgb(var(--color-gray-500) / <alpha-value>)",
307
- 600: "rgb(var(--color-gray-600) / <alpha-value>)",
308
- 700: "rgb(var(--color-gray-700) / <alpha-value>)",
309
- 800: "rgb(var(--color-gray-800) / <alpha-value>)",
310
- 900: "rgb(var(--color-gray-900) / <alpha-value>)",
311
- 950: "rgb(var(--color-gray-950) / <alpha-value>)"
312
- };
313
- const colors = excludeColors(globalColors);
314
- nuxt.options.appConfig.ui = {
315
- primary: "green",
316
- gray: "cool",
317
- colors,
318
- strategy: "merge"
319
- };
320
- tailwindConfig.safelist = tailwindConfig.safelist || [];
321
- tailwindConfig.safelist.push(
322
- ...generateSafelist(moduleOptions.safelistColors || [], colors)
323
- );
324
- });
325
- const configTemplate = addTemplate({
326
- filename: "nuxtui-tailwind.config.cjs",
327
- write: true,
328
- getContents: () => `
329
- const { defaultExtractor: createDefaultExtractor } = require('tailwindcss/lib/lib/defaultExtractor.js')
330
- const { customSafelistExtractor } = require(${JSON.stringify(resolve(runtimeDir, "utils", "colors"))})
331
- const { iconsPlugin, getIconCollections } = require('@egoist/tailwindcss-icons')
332
-
333
- const defaultExtractor = createDefaultExtractor({ tailwindConfig: { separator: ':' } })
334
-
335
- module.exports = {
336
- darkMode: 'class',
337
- plugins: [
338
- require('@tailwindcss/forms')({ strategy: 'class' }),
339
- require('@tailwindcss/aspect-ratio'),
340
- require('@tailwindcss/typography'),
341
- require('@tailwindcss/container-queries'),
342
- require('@headlessui/tailwindcss'),
343
- iconsPlugin(${Array.isArray(moduleOptions.icons) || moduleOptions.icons === "all" ? `{ collections: getIconCollections(${JSON.stringify(moduleOptions.icons)}) }` : typeof moduleOptions.icons === "object" ? JSON.stringify(moduleOptions.icons) : "{}"})
344
- ],
345
- content: {
346
- files: [
347
- ${JSON.stringify(resolve(runtimeDir, "components/**/*.{vue,mjs,ts}"))},
348
- ${JSON.stringify(resolve(runtimeDir, "ui.config/**/*.{mjs,js,ts}"))}
349
- ],
350
- transform: {
351
- vue: (content) => {
352
- return content.replaceAll(/(?:\\r\\n|\\r|\\n)/g, ' ')
353
- }
354
- },
355
- extract: {
356
- vue: (content) => {
357
- return [
358
- ...defaultExtractor(content),
359
- ...customSafelistExtractor(${JSON.stringify(moduleOptions.prefix)}, content, ${JSON.stringify(nuxt.options.appConfig.ui.colors)}, ${JSON.stringify(moduleOptions.safelistColors)})
360
- ]
361
- }
362
- }
363
- }
364
- }
365
- `
366
- });
367
- await installModule("@nuxtjs/tailwindcss", {
368
- exposeConfig: true,
369
- configPath: [
370
- configTemplate.dst,
371
- join(nuxt.options.rootDir, "tailwind.config")
372
- ]
373
- });
374
- }
375
-
376
312
  const module = defineNuxtModule({
377
313
  meta: {
378
314
  name,
@@ -397,10 +333,91 @@ const module = defineNuxtModule({
397
333
  if (!options.disableGlobalStyles) {
398
334
  nuxt.options.css.push(resolve(runtimeDir, "ui.css"));
399
335
  }
336
+ nuxt.hook("tailwindcss:config", function(tailwindConfig) {
337
+ tailwindConfig.theme = tailwindConfig.theme || {};
338
+ tailwindConfig.theme.extend = tailwindConfig.theme.extend || {};
339
+ tailwindConfig.theme.extend.colors = tailwindConfig.theme.extend.colors || {};
340
+ const globalColors = {
341
+ ...tailwindConfig.theme.colors || defaultColors,
342
+ ...tailwindConfig.theme.extend?.colors
343
+ };
344
+ globalColors.primary = tailwindConfig.theme.extend.colors.primary = {
345
+ 50: "rgb(var(--color-primary-50) / <alpha-value>)",
346
+ 100: "rgb(var(--color-primary-100) / <alpha-value>)",
347
+ 200: "rgb(var(--color-primary-200) / <alpha-value>)",
348
+ 300: "rgb(var(--color-primary-300) / <alpha-value>)",
349
+ 400: "rgb(var(--color-primary-400) / <alpha-value>)",
350
+ 500: "rgb(var(--color-primary-500) / <alpha-value>)",
351
+ 600: "rgb(var(--color-primary-600) / <alpha-value>)",
352
+ 700: "rgb(var(--color-primary-700) / <alpha-value>)",
353
+ 800: "rgb(var(--color-primary-800) / <alpha-value>)",
354
+ 900: "rgb(var(--color-primary-900) / <alpha-value>)",
355
+ 950: "rgb(var(--color-primary-950) / <alpha-value>)",
356
+ DEFAULT: "rgb(var(--color-primary-DEFAULT) / <alpha-value>)"
357
+ };
358
+ if (globalColors.gray) {
359
+ globalColors.cool = tailwindConfig.theme.extend.colors.cool = defaultColors.gray;
360
+ }
361
+ globalColors.gray = tailwindConfig.theme.extend.colors.gray = {
362
+ 50: "rgb(var(--color-gray-50) / <alpha-value>)",
363
+ 100: "rgb(var(--color-gray-100) / <alpha-value>)",
364
+ 200: "rgb(var(--color-gray-200) / <alpha-value>)",
365
+ 300: "rgb(var(--color-gray-300) / <alpha-value>)",
366
+ 400: "rgb(var(--color-gray-400) / <alpha-value>)",
367
+ 500: "rgb(var(--color-gray-500) / <alpha-value>)",
368
+ 600: "rgb(var(--color-gray-600) / <alpha-value>)",
369
+ 700: "rgb(var(--color-gray-700) / <alpha-value>)",
370
+ 800: "rgb(var(--color-gray-800) / <alpha-value>)",
371
+ 900: "rgb(var(--color-gray-900) / <alpha-value>)",
372
+ 950: "rgb(var(--color-gray-950) / <alpha-value>)"
373
+ };
374
+ const colors = excludeColors(globalColors);
375
+ nuxt.options.appConfig.ui = {
376
+ primary: "green",
377
+ gray: "cool",
378
+ colors,
379
+ strategy: "merge"
380
+ };
381
+ tailwindConfig.safelist = tailwindConfig.safelist || [];
382
+ tailwindConfig.safelist.push(...generateSafelist(options.safelistColors || [], colors));
383
+ });
400
384
  createTemplates(nuxt);
401
385
  await installModule("nuxt-icon");
402
386
  await installModule("@nuxtjs/color-mode", { classSuffix: "" });
403
- await installTailwind(options, nuxt, { resolve, runtimeDir });
387
+ await installModule("@nuxtjs/tailwindcss", {
388
+ exposeConfig: true,
389
+ config: {
390
+ darkMode: "class",
391
+ plugins: [
392
+ require("@tailwindcss/forms")({ strategy: "class" }),
393
+ require("@tailwindcss/aspect-ratio"),
394
+ require("@tailwindcss/typography"),
395
+ require("@tailwindcss/container-queries"),
396
+ require("@headlessui/tailwindcss"),
397
+ iconsPlugin(Array.isArray(options.icons) || options.icons === "all" ? { collections: getIconCollections(options.icons) } : typeof options.icons === "object" ? options.icons : {})
398
+ ],
399
+ content: {
400
+ files: [
401
+ resolve(runtimeDir, "components/**/*.{vue,mjs,ts}"),
402
+ resolve(runtimeDir, "ui.config/**/*.{mjs,js,ts}")
403
+ ],
404
+ transform: {
405
+ vue: (content) => {
406
+ return content.replaceAll(/(?:\r\n|\r|\n)/g, " ");
407
+ }
408
+ },
409
+ extract: {
410
+ vue: (content) => {
411
+ return [
412
+ ...defaultExtractor(content),
413
+ // @ts-ignore
414
+ ...customSafelistExtractor(options.prefix, content, nuxt.options.appConfig.ui.colors, options.safelistColors)
415
+ ];
416
+ }
417
+ }
418
+ }
419
+ }
420
+ });
404
421
  addPlugin({
405
422
  src: resolve(runtimeDir, "plugins", "colors")
406
423
  });
@@ -326,8 +326,8 @@ declare const _default: import("vue").DefineComponent<{
326
326
  leading: boolean;
327
327
  variant: ButtonVariant;
328
328
  label: string;
329
- disabled: boolean;
330
329
  loading: boolean;
330
+ disabled: boolean;
331
331
  block: boolean;
332
332
  padded: boolean;
333
333
  loadingIcon: string;
@@ -212,8 +212,8 @@ declare const _default: import("vue").DefineComponent<{
212
212
  replace: NuxtLinkProps;
213
213
  ariaCurrentValue: NuxtLinkProps;
214
214
  external: NuxtLinkProps;
215
- disabled: boolean;
216
215
  as: string;
216
+ disabled: boolean;
217
217
  to: RouteLocationRaw;
218
218
  href: RouteLocationRaw;
219
219
  active: boolean;
@@ -128,9 +128,9 @@ declare const _default: import("vue").DefineComponent<{
128
128
  class: any;
129
129
  name: string;
130
130
  label: string;
131
- disabled: boolean;
132
131
  modelValue: boolean | unknown[];
133
132
  indeterminate: boolean;
133
+ disabled: boolean;
134
134
  required: boolean;
135
135
  help: string;
136
136
  inputClass: string;
@@ -242,9 +242,9 @@ declare const _default: import("vue").DefineComponent<{
242
242
  name: string;
243
243
  leading: boolean;
244
244
  variant: InputVariant;
245
- disabled: boolean;
246
245
  modelValue: string | number;
247
246
  loading: boolean;
247
+ disabled: boolean;
248
248
  placeholder: string;
249
249
  padded: boolean;
250
250
  loadingIcon: string;
@@ -317,10 +317,10 @@ declare const _default: import("vue").DefineComponent<{
317
317
  leading: boolean;
318
318
  search: (query: string) => Promise<any[]> | any[];
319
319
  variant: InputVariant;
320
- disabled: boolean;
321
320
  modelValue: string | number | unknown[] | Record<string, any>;
322
321
  by: string;
323
322
  loading: boolean;
323
+ disabled: boolean;
324
324
  placeholder: string;
325
325
  padded: boolean;
326
326
  loadingIcon: string;
@@ -119,8 +119,8 @@ declare const _default: import("vue").DefineComponent<{
119
119
  class: any;
120
120
  name: string;
121
121
  label: string;
122
- disabled: boolean;
123
122
  modelValue: string | number | boolean | Record<string, any>;
123
+ disabled: boolean;
124
124
  required: boolean;
125
125
  help: string;
126
126
  inputClass: string;
@@ -109,8 +109,8 @@ declare const _default: import("vue").DefineComponent<{
109
109
  options: unknown[];
110
110
  name: string;
111
111
  legend: string;
112
- disabled: boolean;
113
112
  modelValue: string | number | Record<string, any>;
113
+ disabled: boolean;
114
114
  optionAttribute: string;
115
115
  valueAttribute: string;
116
116
  uiRadio: any;
@@ -129,8 +129,8 @@ declare const _default: import("vue").DefineComponent<{
129
129
  color: any;
130
130
  class: any;
131
131
  name: string;
132
- disabled: boolean;
133
132
  modelValue: number;
133
+ disabled: boolean;
134
134
  max: number;
135
135
  min: number;
136
136
  inputClass: string;
@@ -231,9 +231,9 @@ declare const _default: import("vue").DefineComponent<{
231
231
  name: string;
232
232
  leading: boolean;
233
233
  variant: SelectVariant;
234
- disabled: boolean;
235
234
  modelValue: string | number | Record<string, any>;
236
235
  loading: boolean;
236
+ disabled: boolean;
237
237
  placeholder: string;
238
238
  padded: boolean;
239
239
  loadingIcon: string;
@@ -351,10 +351,10 @@ declare const _default: import("vue").DefineComponent<{
351
351
  name: string;
352
352
  leading: boolean;
353
353
  variant: SelectVariant;
354
- disabled: boolean;
355
354
  modelValue: string | number | unknown[] | Record<string, any>;
356
355
  by: string;
357
356
  loading: boolean;
357
+ disabled: boolean;
358
358
  multiple: boolean;
359
359
  placeholder: string;
360
360
  padded: boolean;
@@ -200,9 +200,9 @@ declare const _default: import("vue").DefineComponent<{
200
200
  class: any;
201
201
  name: string;
202
202
  variant: TextareaVariant;
203
- disabled: boolean;
204
203
  modelValue: string | number;
205
204
  rows: number;
205
+ disabled: boolean;
206
206
  placeholder: string;
207
207
  padded: boolean;
208
208
  required: boolean;
@@ -108,8 +108,8 @@ declare const _default: import("vue").DefineComponent<{
108
108
  color: any;
109
109
  class: any;
110
110
  name: string;
111
- disabled: boolean;
112
111
  modelValue: boolean;
112
+ disabled: boolean;
113
113
  onIcon: string;
114
114
  offIcon: string;
115
115
  }, {}>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "repository": "nuxt/ui",
5
5
  "homepage": "https://ui.nuxt.com",
6
6
  "type": "module",
@@ -37,7 +37,7 @@
37
37
  "@headlessui/tailwindcss": "^0.2.0",
38
38
  "@headlessui/vue": "^1.7.19",
39
39
  "@iconify-json/heroicons": "^1.1.20",
40
- "@nuxt/kit": "^3.10.2",
40
+ "@nuxt/kit": "^3.10.3",
41
41
  "@nuxtjs/color-mode": "^3.3.2",
42
42
  "@nuxtjs/tailwindcss": "^6.11.4",
43
43
  "@popperjs/core": "^2.11.8",
@@ -64,9 +64,9 @@
64
64
  "@release-it/conventional-changelog": "^8.0.1",
65
65
  "@vue/test-utils": "^2.4.4",
66
66
  "eslint": "^8.56.0",
67
- "happy-dom": "^13.3.8",
68
- "joi": "^17.12.1",
69
- "nuxt": "^3.10.2",
67
+ "happy-dom": "^13.4.1",
68
+ "joi": "^17.12.2",
69
+ "nuxt": "^3.10.3",
70
70
  "release-it": "^17.1.1",
71
71
  "typescript": "^5.3.3",
72
72
  "unbuild": "^2.0.0",
@@ -78,10 +78,10 @@
78
78
  "zod": "^3.22.4"
79
79
  },
80
80
  "resolutions": {
81
- "@nuxt/kit": "^3.10.2",
82
- "@nuxt/schema": "3.10.2",
81
+ "@nuxt/kit": "3.10.3",
82
+ "@nuxt/schema": "3.10.3",
83
83
  "tailwindcss": "3.4.1",
84
- "@headlessui/vue": "^1.7.19",
84
+ "@headlessui/vue": "1.7.19",
85
85
  "vue": "3.4.19"
86
86
  }
87
87
  }
@@ -1,3 +0,0 @@
1
- export declare const excludeColors: (colors: object) => string[];
2
- export declare const generateSafelist: (colors: string[], globalColors: any) => any[];
3
- export declare const customSafelistExtractor: (prefix: any, content: string, colors: string[], safelistColors: string[]) => string[];
@@ -1,261 +0,0 @@
1
- import { omit } from "./lodash.mjs";
2
- import { kebabCase, camelCase, upperFirst } from "scule";
3
- const colorsToExclude = [
4
- "inherit",
5
- "transparent",
6
- "current",
7
- "white",
8
- "black",
9
- "slate",
10
- "gray",
11
- "zinc",
12
- "neutral",
13
- "stone",
14
- "cool"
15
- ];
16
- const safelistByComponent = {
17
- alert: (colorsAsRegex2) => [{
18
- pattern: new RegExp(`bg-(${colorsAsRegex2})-50`)
19
- }, {
20
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
21
- variants: ["dark"]
22
- }, {
23
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
24
- }, {
25
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
26
- variants: ["dark"]
27
- }, {
28
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
29
- }, {
30
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
31
- variants: ["dark"]
32
- }, {
33
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`)
34
- }],
35
- avatar: (colorsAsRegex2) => [{
36
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
37
- variants: ["dark"]
38
- }, {
39
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
40
- }],
41
- badge: (colorsAsRegex2) => [{
42
- pattern: new RegExp(`bg-(${colorsAsRegex2})-50`)
43
- }, {
44
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
45
- variants: ["dark"]
46
- }, {
47
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
48
- }, {
49
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
50
- variants: ["dark"]
51
- }, {
52
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
53
- }, {
54
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
55
- variants: ["dark"]
56
- }, {
57
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`)
58
- }],
59
- button: (colorsAsRegex2) => [{
60
- pattern: new RegExp(`bg-(${colorsAsRegex2})-50`),
61
- variants: ["hover", "disabled"]
62
- }, {
63
- pattern: new RegExp(`bg-(${colorsAsRegex2})-100`),
64
- variants: ["hover"]
65
- }, {
66
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
67
- variants: ["dark", "dark:disabled"]
68
- }, {
69
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`),
70
- variants: ["disabled", "dark:hover"]
71
- }, {
72
- pattern: new RegExp(`bg-(${colorsAsRegex2})-600`),
73
- variants: ["hover"]
74
- }, {
75
- pattern: new RegExp(`bg-(${colorsAsRegex2})-900`),
76
- variants: ["dark:hover"]
77
- }, {
78
- pattern: new RegExp(`bg-(${colorsAsRegex2})-950`),
79
- variants: ["dark", "dark:hover", "dark:disabled"]
80
- }, {
81
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
82
- variants: ["dark", "dark:disabled"]
83
- }, {
84
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`),
85
- variants: ["dark:hover", "disabled"]
86
- }, {
87
- pattern: new RegExp(`text-(${colorsAsRegex2})-600`),
88
- variants: ["hover"]
89
- }, {
90
- pattern: new RegExp(`outline-(${colorsAsRegex2})-400`),
91
- variants: ["dark:focus-visible"]
92
- }, {
93
- pattern: new RegExp(`outline-(${colorsAsRegex2})-500`),
94
- variants: ["focus-visible"]
95
- }, {
96
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
97
- variants: ["dark:focus-visible"]
98
- }, {
99
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
100
- variants: ["focus-visible"]
101
- }],
102
- input: (colorsAsRegex2) => [{
103
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
104
- variants: ["dark"]
105
- }, {
106
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
107
- }, {
108
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
109
- variants: ["dark", "dark:focus"]
110
- }, {
111
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
112
- variants: ["focus"]
113
- }],
114
- radio: (colorsAsRegex2) => [{
115
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
116
- variants: ["dark"]
117
- }, {
118
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
119
- }, {
120
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
121
- variants: ["dark:focus-visible"]
122
- }, {
123
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
124
- variants: ["focus-visible"]
125
- }],
126
- checkbox: (colorsAsRegex2) => [{
127
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
128
- variants: ["dark"]
129
- }, {
130
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
131
- }, {
132
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
133
- variants: ["dark:focus-visible"]
134
- }, {
135
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
136
- variants: ["focus-visible"]
137
- }],
138
- toggle: (colorsAsRegex2) => [{
139
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
140
- variants: ["dark"]
141
- }, {
142
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
143
- }, {
144
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
145
- variants: ["dark"]
146
- }, {
147
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
148
- }, {
149
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
150
- variants: ["dark:focus-visible"]
151
- }, {
152
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
153
- variants: ["focus-visible"]
154
- }],
155
- range: (colorsAsRegex2) => [{
156
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
157
- variants: ["dark"]
158
- }, {
159
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
160
- }, {
161
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
162
- variants: ["dark"]
163
- }, {
164
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
165
- }, {
166
- pattern: new RegExp(`ring-(${colorsAsRegex2})-400`),
167
- variants: ["dark:focus-visible"]
168
- }, {
169
- pattern: new RegExp(`ring-(${colorsAsRegex2})-500`),
170
- variants: ["focus-visible"]
171
- }],
172
- progress: (colorsAsRegex2) => [{
173
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
174
- variants: ["dark"]
175
- }, {
176
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
177
- }],
178
- meter: (colorsAsRegex2) => [{
179
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
180
- variants: ["dark"]
181
- }, {
182
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
183
- }, {
184
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
185
- variants: ["dark"]
186
- }, {
187
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
188
- }],
189
- notification: (colorsAsRegex2) => [{
190
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
191
- variants: ["dark"]
192
- }, {
193
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
194
- }, {
195
- pattern: new RegExp(`text-(${colorsAsRegex2})-400`),
196
- variants: ["dark"]
197
- }, {
198
- pattern: new RegExp(`text-(${colorsAsRegex2})-500`)
199
- }],
200
- chip: (colorsAsRegex2) => [{
201
- pattern: new RegExp(`bg-(${colorsAsRegex2})-400`),
202
- variants: ["dark"]
203
- }, {
204
- pattern: new RegExp(`bg-(${colorsAsRegex2})-500`)
205
- }]
206
- };
207
- const safelistComponentAliasesMap = {
208
- "USelect": "UInput",
209
- "USelectMenu": "UInput",
210
- "UTextarea": "UInput",
211
- "URadioGroup": "URadio",
212
- "UMeterGroup": "UMeter"
213
- };
214
- const colorsAsRegex = (colors) => colors.join("|");
215
- export const excludeColors = (colors) => {
216
- return Object.entries(omit(colors, colorsToExclude)).filter(([, value]) => typeof value === "object").map(([key]) => kebabCase(key));
217
- };
218
- export const generateSafelist = (colors, globalColors) => {
219
- const baseSafelist = Object.keys(safelistByComponent).flatMap((component) => safelistByComponent[component](colorsAsRegex(colors)));
220
- const formsSafelist = ["input", "radio", "checkbox", "toggle", "range"].flatMap((component) => safelistByComponent[component](colorsAsRegex(["red"])));
221
- return [
222
- ...baseSafelist,
223
- ...formsSafelist,
224
- // Ensure all global colors are safelisted for the Notification (toast.add)
225
- ...safelistByComponent["notification"](colorsAsRegex(globalColors)),
226
- // Gray safelist for Avatar & Notification
227
- "bg-gray-500",
228
- "dark:bg-gray-400",
229
- "text-gray-500",
230
- "dark:text-gray-400"
231
- ];
232
- };
233
- export const customSafelistExtractor = (prefix, content, colors, safelistColors) => {
234
- const classes = [];
235
- const regex = /<([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z][A-Za-z0-9]*)*)\s+(?![^>]*:color\b)[^>]*\bcolor=["']([^"']+)["'][^>]*>/gs;
236
- const matches = content.matchAll(regex);
237
- const components = Object.keys(safelistByComponent).map((component) => `${prefix}${component.charAt(0).toUpperCase() + component.slice(1)}`);
238
- for (const match of matches) {
239
- const [, component, color] = match;
240
- const camelComponent = upperFirst(camelCase(component));
241
- if (!colors.includes(color) || safelistColors.includes(color)) {
242
- continue;
243
- }
244
- let name = safelistComponentAliasesMap[camelComponent] ? safelistComponentAliasesMap[camelComponent] : camelComponent;
245
- if (!components.includes(name)) {
246
- continue;
247
- }
248
- name = name.replace(prefix, "").toLowerCase();
249
- const matchClasses = safelistByComponent[name](color).flatMap((group) => {
250
- return ["", ...group.variants || []].flatMap((variant) => {
251
- const matches2 = group.pattern.source.match(/\(([^)]+)\)/g);
252
- return matches2.map((match2) => {
253
- const colorOptions = match2.substring(1, match2.length - 1).split("|");
254
- return colorOptions.map((color2) => `${variant ? variant + ":" : ""}` + group.pattern.source.replace(match2, color2));
255
- }).flat();
256
- });
257
- });
258
- classes.push(...matchClasses);
259
- }
260
- return classes;
261
- };