@udixio/theme 0.3.1 → 0.4.0

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/index.cjs.js CHANGED
@@ -2,30 +2,6 @@
2
2
 
3
3
  var awilix = require('awilix');
4
4
  var materialColorUtilities = require('@material/material-color-utilities');
5
- var plugin = require('tailwindcss/plugin');
6
- var fs = require('fs');
7
- var path = require('path');
8
- var replaceInFile = require('replace-in-file');
9
-
10
- function _interopNamespaceDefault(e) {
11
- var n = Object.create(null);
12
- if (e) {
13
- Object.keys(e).forEach(function (k) {
14
- if (k !== 'default') {
15
- var d = Object.getOwnPropertyDescriptor(e, k);
16
- Object.defineProperty(n, k, d.get ? d : {
17
- enumerable: true,
18
- get: function () { return e[k]; }
19
- });
20
- }
21
- });
22
- }
23
- n.default = e;
24
- return Object.freeze(n);
25
- }
26
-
27
- var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
28
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
29
5
 
30
6
  class ColorApi {
31
7
  constructor({ colorManager }) {
@@ -1670,6 +1646,12 @@ const getRotatedHue = (sourceColorHct, hueBreakpoints, rotations) => {
1670
1646
  }
1671
1647
  return materialColorUtilities.sanitizeDegreesDouble(sourceColorHct.hue + rotation);
1672
1648
  };
1649
+ const Variants = {
1650
+ Expressive: expressiveVariant,
1651
+ Neutral: neutralVariant,
1652
+ TonalSpot: tonalSpotVariant,
1653
+ Vibrant: vibrantVariant,
1654
+ };
1673
1655
  class Variant {
1674
1656
  constructor(palettes = {}, name, customPalettes,
1675
1657
  /** TODO
@@ -2858,329 +2840,6 @@ class FontPluginImpl extends PluginImplAbstract {
2858
2840
  }
2859
2841
  }
2860
2842
 
2861
- /******************************************************************************
2862
- Copyright (c) Microsoft Corporation.
2863
-
2864
- Permission to use, copy, modify, and/or distribute this software for any
2865
- purpose with or without fee is hereby granted.
2866
-
2867
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2868
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2869
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2870
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2871
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2872
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2873
- PERFORMANCE OF THIS SOFTWARE.
2874
- ***************************************************************************** */
2875
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
2876
-
2877
-
2878
- function __awaiter(thisArg, _arguments, P, generator) {
2879
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2880
- return new (P || (P = Promise))(function (resolve, reject) {
2881
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2882
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2883
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2884
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2885
- });
2886
- }
2887
-
2888
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
2889
- var e = new Error(message);
2890
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2891
- };
2892
-
2893
- const createOrUpdateFile = (filePath, content) => {
2894
- try {
2895
- if (!fs__namespace.existsSync(filePath)) {
2896
- // Create the folder if necessary.
2897
- const dirPath = path__namespace.dirname(filePath);
2898
- if (!fs__namespace.existsSync(dirPath)) {
2899
- fs__namespace.mkdirSync(dirPath, { recursive: true });
2900
- }
2901
- // Create the file with the provided content.
2902
- fs__namespace.writeFileSync(filePath, content);
2903
- console.log(`✅ File successfully created: ${filePath}`);
2904
- }
2905
- else {
2906
- console.log(`⚠️ File already exists: ${filePath}`);
2907
- replaceFileContent(filePath, /[\s\S]*/, content);
2908
- }
2909
- }
2910
- catch (error) {
2911
- console.error('❌ Error while creating the file:', error);
2912
- }
2913
- };
2914
- const getFileContent = (filePath, searchPattern) => {
2915
- try {
2916
- // Vérifier si le fichier existe
2917
- if (!fs__namespace.existsSync(filePath)) {
2918
- console.error(`❌ The specified file does not exist: ${filePath}`);
2919
- return null;
2920
- }
2921
- // Lire le contenu du fichier entier
2922
- const fileContent = fs__namespace.readFileSync(filePath, 'utf8');
2923
- // Si un motif est fourni, chercher le texte correspondant
2924
- if (searchPattern) {
2925
- if (typeof searchPattern === 'string') {
2926
- const found = fileContent.includes(searchPattern)
2927
- ? searchPattern
2928
- : false;
2929
- console.log(found
2930
- ? `✅ The file contains the specified string: "${searchPattern}"`
2931
- : `⚠️ The file does NOT contain the specified string: "${searchPattern}"`);
2932
- return found;
2933
- }
2934
- else {
2935
- const match = fileContent.match(searchPattern);
2936
- if (match) {
2937
- console.log(`✅ Found match: "${match[0]}"`);
2938
- return match[0]; // Retourner le texte trouvé
2939
- }
2940
- else {
2941
- console.log(`⚠️ No match found for the pattern: "${searchPattern.toString()}"`);
2942
- return false; // Aucune correspondance trouvée
2943
- }
2944
- }
2945
- }
2946
- // Si aucun motif n'est fourni, retourner tout le contenu
2947
- console.log(`✅ File content successfully retrieved.`);
2948
- return fileContent;
2949
- }
2950
- catch (error) {
2951
- console.error('❌ An error occurred while processing the file:', error);
2952
- return null;
2953
- }
2954
- };
2955
- const replaceFileContent = (filePath, searchPattern, replacement) => {
2956
- try {
2957
- const results = replaceInFile.replaceInFileSync({
2958
- files: filePath,
2959
- from: searchPattern,
2960
- to: replacement,
2961
- });
2962
- if (results.length > 0 && results[0].hasChanged) {
2963
- console.log(`✅ Content successfully replaced in the file: ${filePath}`);
2964
- }
2965
- else {
2966
- console.log(`⚠️ No replacement made. Here are some possible reasons:\n- The pattern ${searchPattern} was not found.\n- The file might already contain the expected content.`);
2967
- }
2968
- }
2969
- catch (error) {
2970
- console.error('❌ Error while replacing the file content:', error);
2971
- }
2972
- };
2973
- const findTailwindCssFile = (startDir, searchPattern) => {
2974
- const files = fs__namespace.readdirSync(startDir);
2975
- for (const file of files) {
2976
- const filePath = path__namespace.join(startDir, file);
2977
- const stats = fs__namespace.statSync(filePath);
2978
- if (stats.isDirectory()) {
2979
- // Appeler récursivement si c'est un dossier
2980
- const result = findTailwindCssFile(filePath, searchPattern);
2981
- if (result)
2982
- return result;
2983
- }
2984
- else if (file.endsWith('.css')) {
2985
- // Lire chaque fichier .css
2986
- const content = fs__namespace.readFileSync(filePath, 'utf8');
2987
- if (content.includes(searchPattern)) {
2988
- console.log('Fichier trouvé :', filePath);
2989
- return filePath;
2990
- }
2991
- }
2992
- }
2993
- return null;
2994
- };
2995
-
2996
- const font = (fontStyles, responsiveBreakPoints) => {
2997
- const createUtilities = ({ theme }) => {
2998
- const pixelUnit = 'rem';
2999
- const newUtilities = {};
3000
- const baseTextStyle = (sizeValue) => ({
3001
- fontSize: sizeValue.fontSize + pixelUnit,
3002
- fontWeight: sizeValue.fontWeight,
3003
- lineHeight: sizeValue.lineHeight + pixelUnit,
3004
- letterSpacing: sizeValue.letterSpacing
3005
- ? sizeValue.letterSpacing + pixelUnit
3006
- : null,
3007
- fontFamily: theme('fontFamily.' + sizeValue.fontFamily),
3008
- });
3009
- const responsiveTextStyle = (sizeValue, breakPointName, breakPointRatio) => ({
3010
- [`@media (min-width: ${theme('screens.' + breakPointName, {})})`]: {
3011
- fontSize: sizeValue.fontSize * breakPointRatio + pixelUnit,
3012
- lineHeight: sizeValue.lineHeight * breakPointRatio + pixelUnit,
3013
- },
3014
- });
3015
- for (const [roleName, roleValue] of Object.entries(fontStyles)) {
3016
- for (const [sizeName, sizeValue] of Object.entries(roleValue)) {
3017
- newUtilities['.text-' + roleName + '-' + sizeName] = Object.assign(Object.assign({}, baseTextStyle(sizeValue)), Object.entries(responsiveBreakPoints).reduce((acc, [breakPointName, breakPointRatio]) => {
3018
- acc = Object.assign(Object.assign({}, acc), responsiveTextStyle(sizeValue, breakPointName, breakPointRatio));
3019
- return acc;
3020
- }, {}));
3021
- }
3022
- }
3023
- return newUtilities;
3024
- };
3025
- return plugin(({ addUtilities, theme, }) => {
3026
- const newUtilities = createUtilities({ theme });
3027
- addUtilities(newUtilities);
3028
- });
3029
- };
3030
-
3031
- // from tailwindcss src/util/flattenColors
3032
- const state = (colorKeys) => plugin((pluginArgs) => {
3033
- addAllNewComponents(pluginArgs, {
3034
- statePrefix: 'state',
3035
- disabledStyles: {
3036
- textOpacity: 0.38,
3037
- backgroundOpacity: 0.12,
3038
- },
3039
- transition: {
3040
- duration: 150,
3041
- },
3042
- }, colorKeys);
3043
- }, {});
3044
- const addAllNewComponents = ({ addComponents }, { statePrefix, disabledStyles, transition }, colorKeys) => {
3045
- const newComponents = {};
3046
- for (const isGroup of [false, true]) {
3047
- const group = isGroup ? 'group-' : '';
3048
- for (const colorName of colorKeys) {
3049
- const className = `.${group}${statePrefix}-${colorName}`;
3050
- newComponents[className] = {
3051
- [`@apply ${group}hover:bg-${colorName}/[0.08]`]: {},
3052
- [`@apply ${group}active:bg-${colorName}/[0.12]`]: {},
3053
- [`@apply ${group}focus-visible:bg-${colorName}/[0.12]`]: {},
3054
- };
3055
- if (transition) {
3056
- newComponents[className][`@apply transition-colors`] = {};
3057
- newComponents[className][`@apply duration-${transition.duration}`] = {};
3058
- }
3059
- if (disabledStyles) {
3060
- newComponents[className][`@apply ${group}disabled:text-on-surface/[${disabledStyles.textOpacity}]`] = {};
3061
- newComponents[className][`@apply ${group}disabled:bg-on-surface/[${disabledStyles.backgroundOpacity}]`] = {};
3062
- }
3063
- }
3064
- }
3065
- for (const colorName of colorKeys) {
3066
- for (const stateName of ['hover', 'active', 'focus', 'disabled']) {
3067
- const className = `.${stateName}-${statePrefix}-${colorName}`;
3068
- if (stateName === 'active' || stateName === 'focus') {
3069
- newComponents[className] = {
3070
- [`@apply bg-${colorName}/[0.12]`]: {},
3071
- };
3072
- }
3073
- else if (stateName === 'hover') {
3074
- newComponents[className] = {
3075
- [`@apply bg-${colorName}/[0.08]`]: {},
3076
- };
3077
- }
3078
- else if (stateName === 'disabled') {
3079
- newComponents[className] = {
3080
- [`@apply text-on-surface/[${disabledStyles.textOpacity}]`]: {},
3081
- };
3082
- newComponents[className] = {
3083
- [`@apply bg-on-surface/[${disabledStyles.backgroundOpacity}]`]: {},
3084
- };
3085
- }
3086
- }
3087
- }
3088
- addComponents(newComponents);
3089
- };
3090
-
3091
- class TailwindPlugin extends PluginAbstract {
3092
- constructor() {
3093
- super(...arguments);
3094
- this.dependencies = [FontPlugin];
3095
- this.name = 'tailwind';
3096
- this.pluginClass = TailwindImplPlugin;
3097
- }
3098
- }
3099
- class TailwindImplPlugin extends PluginImplAbstract {
3100
- onInit() {
3101
- var _a, _b;
3102
- var _c, _d;
3103
- (_a = (_c = this.options).darkMode) !== null && _a !== void 0 ? _a : (_c.darkMode = 'class');
3104
- (_b = (_d = this.options).responsiveBreakPoints) !== null && _b !== void 0 ? _b : (_d.responsiveBreakPoints = {
3105
- lg: 1.125,
3106
- });
3107
- }
3108
- load() {
3109
- var _a;
3110
- const searchKeyword = '@plugin "@udixio/tailwind"';
3111
- const tailwindCssPath = findTailwindCssFile(process.cwd(), searchKeyword);
3112
- if (!tailwindCssPath) {
3113
- throw new Error('Tailwind plugin not found. Please use it first. (@plugin "@udixio/tailwind")');
3114
- }
3115
- const searchPattern = /@import 'tailwindcss';/;
3116
- const replacement = `@import 'tailwindcss';\n@import "./udixio.css";`;
3117
- if (!getFileContent(tailwindCssPath, /@import\s+"\.\/udixio\.css";/)) {
3118
- replaceFileContent(tailwindCssPath, searchPattern, replacement);
3119
- }
3120
- const cssFilePath = path.dirname(tailwindCssPath);
3121
- const colors = {};
3122
- for (const isDark of [false, true]) {
3123
- this.api.themes.update({ isDark: isDark });
3124
- for (const [key, value] of this.api.colors.getColors().entries()) {
3125
- const newKey = key
3126
- .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2')
3127
- .toLowerCase();
3128
- (_a = colors[newKey]) !== null && _a !== void 0 ? _a : (colors[newKey] = { light: '', dark: '' });
3129
- colors[newKey][isDark ? 'dark' : 'light'] = value.getHex();
3130
- }
3131
- }
3132
- const { fontStyles, fontFamily } = this.api.plugins
3133
- .getPlugin(FontPlugin)
3134
- .getInstance()
3135
- .getFonts();
3136
- createOrUpdateFile(path.join(cssFilePath, 'udixio.css'), `
3137
- @custom-variant dark (&:where(.dark, .dark *));
3138
- @theme {
3139
- --color-*: initial;
3140
- ${Object.entries(colors)
3141
- .map(([key, value]) => `--color-${key}: ${value.light};`)
3142
- .join('\n ')}
3143
- }
3144
- @layer theme {
3145
- .dark {
3146
- ${Object.entries(colors)
3147
- .map(([key, value]) => `--color-${key}: ${value.dark};`)
3148
- .join('\n ')}
3149
- }
3150
- }
3151
- `);
3152
- const plugins = [
3153
- state(Object.keys(colors)),
3154
- font(fontStyles, this.options.responsiveBreakPoints),
3155
- ];
3156
- return plugin.withOptions(
3157
- // 1) factory(options) → la fonction “handler” du plugin
3158
- (options = {}) => {
3159
- return function (api) {
3160
- return __awaiter(this, void 0, void 0, function* () {
3161
- plugins.forEach((plugin) => {
3162
- plugin.handler(api);
3163
- });
3164
- });
3165
- };
3166
- },
3167
- // 2) config(options) → objet à merger dans tailwind.config
3168
- (options = {}) => {
3169
- return {
3170
- theme: {
3171
- fontFamily,
3172
- },
3173
- };
3174
- });
3175
- }
3176
- }
3177
-
3178
- const createTheme = () => {
3179
- const app = bootstrapFromConfig();
3180
- const plugin = app.plugins.getPlugin(TailwindPlugin).getInstance();
3181
- return plugin.load();
3182
- };
3183
-
3184
2843
  exports.API = API;
3185
2844
  exports.AppContainer = AppContainer;
3186
2845
  exports.AppModule = AppModule;
@@ -3199,25 +2858,22 @@ exports.PluginImplAbstract = PluginImplAbstract;
3199
2858
  exports.PluginModule = PluginModule;
3200
2859
  exports.Scheme = Scheme;
3201
2860
  exports.SchemeManager = SchemeManager;
3202
- exports.TailwindPlugin = TailwindPlugin;
3203
2861
  exports.ThemeApi = ThemeApi;
3204
2862
  exports.ThemeModule = ThemeModule;
3205
2863
  exports.ToneDeltaPair = ToneDeltaPair;
3206
2864
  exports.Variant = Variant;
3207
2865
  exports.VariantManager = VariantManager;
2866
+ exports.Variants = Variants;
3208
2867
  exports.bootstrap = bootstrap;
3209
2868
  exports.bootstrapFromConfig = bootstrapFromConfig;
3210
- exports.createTheme = createTheme;
3211
2869
  exports.defaultColors = defaultColors;
3212
2870
  exports.defineConfig = defineConfig;
3213
2871
  exports.expressiveVariant = expressiveVariant;
3214
2872
  exports.extendSpecVersion = extendSpecVersion;
3215
- exports.font = font;
3216
2873
  exports.getPiecewiseHue = getPiecewiseHue;
3217
2874
  exports.getRotatedHue = getRotatedHue;
3218
2875
  exports.highestSurface = highestSurface;
3219
2876
  exports.importContainer = importContainer;
3220
2877
  exports.neutralVariant = neutralVariant;
3221
- exports.state = state;
3222
2878
  exports.tonalSpotVariant = tonalSpotVariant;
3223
2879
  exports.vibrantVariant = vibrantVariant;
package/index.esm.js CHANGED
@@ -1,10 +1,5 @@
1
1
  import { asClass, createContainer, InjectionMode } from 'awilix';
2
2
  import { lerp, argbFromLstar, sanitizeDegreesDouble, yFromLstar, argbFromLinrgb, Cam16, signum, matrixMultiply, ViewingConditions, lstarFromArgb, lstarFromY, Contrast, clampDouble, hexFromArgb, argbFromHex, DynamicColor as DynamicColor$1, TonalPalette } from '@material/material-color-utilities';
3
- import plugin from 'tailwindcss/plugin';
4
- import * as fs from 'fs';
5
- import * as path from 'path';
6
- import path__default from 'path';
7
- import { replaceInFileSync } from 'replace-in-file';
8
3
 
9
4
  class ColorApi {
10
5
  constructor({ colorManager }) {
@@ -1649,6 +1644,12 @@ const getRotatedHue = (sourceColorHct, hueBreakpoints, rotations) => {
1649
1644
  }
1650
1645
  return sanitizeDegreesDouble(sourceColorHct.hue + rotation);
1651
1646
  };
1647
+ const Variants = {
1648
+ Expressive: expressiveVariant,
1649
+ Neutral: neutralVariant,
1650
+ TonalSpot: tonalSpotVariant,
1651
+ Vibrant: vibrantVariant,
1652
+ };
1652
1653
  class Variant {
1653
1654
  constructor(palettes = {}, name, customPalettes,
1654
1655
  /** TODO
@@ -2837,327 +2838,4 @@ class FontPluginImpl extends PluginImplAbstract {
2837
2838
  }
2838
2839
  }
2839
2840
 
2840
- /******************************************************************************
2841
- Copyright (c) Microsoft Corporation.
2842
-
2843
- Permission to use, copy, modify, and/or distribute this software for any
2844
- purpose with or without fee is hereby granted.
2845
-
2846
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2847
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2848
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2849
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2850
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2851
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2852
- PERFORMANCE OF THIS SOFTWARE.
2853
- ***************************************************************************** */
2854
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
2855
-
2856
-
2857
- function __awaiter(thisArg, _arguments, P, generator) {
2858
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2859
- return new (P || (P = Promise))(function (resolve, reject) {
2860
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2861
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2862
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2863
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2864
- });
2865
- }
2866
-
2867
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
2868
- var e = new Error(message);
2869
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2870
- };
2871
-
2872
- const createOrUpdateFile = (filePath, content) => {
2873
- try {
2874
- if (!fs.existsSync(filePath)) {
2875
- // Create the folder if necessary.
2876
- const dirPath = path.dirname(filePath);
2877
- if (!fs.existsSync(dirPath)) {
2878
- fs.mkdirSync(dirPath, { recursive: true });
2879
- }
2880
- // Create the file with the provided content.
2881
- fs.writeFileSync(filePath, content);
2882
- console.log(`✅ File successfully created: ${filePath}`);
2883
- }
2884
- else {
2885
- console.log(`⚠️ File already exists: ${filePath}`);
2886
- replaceFileContent(filePath, /[\s\S]*/, content);
2887
- }
2888
- }
2889
- catch (error) {
2890
- console.error('❌ Error while creating the file:', error);
2891
- }
2892
- };
2893
- const getFileContent = (filePath, searchPattern) => {
2894
- try {
2895
- // Vérifier si le fichier existe
2896
- if (!fs.existsSync(filePath)) {
2897
- console.error(`❌ The specified file does not exist: ${filePath}`);
2898
- return null;
2899
- }
2900
- // Lire le contenu du fichier entier
2901
- const fileContent = fs.readFileSync(filePath, 'utf8');
2902
- // Si un motif est fourni, chercher le texte correspondant
2903
- if (searchPattern) {
2904
- if (typeof searchPattern === 'string') {
2905
- const found = fileContent.includes(searchPattern)
2906
- ? searchPattern
2907
- : false;
2908
- console.log(found
2909
- ? `✅ The file contains the specified string: "${searchPattern}"`
2910
- : `⚠️ The file does NOT contain the specified string: "${searchPattern}"`);
2911
- return found;
2912
- }
2913
- else {
2914
- const match = fileContent.match(searchPattern);
2915
- if (match) {
2916
- console.log(`✅ Found match: "${match[0]}"`);
2917
- return match[0]; // Retourner le texte trouvé
2918
- }
2919
- else {
2920
- console.log(`⚠️ No match found for the pattern: "${searchPattern.toString()}"`);
2921
- return false; // Aucune correspondance trouvée
2922
- }
2923
- }
2924
- }
2925
- // Si aucun motif n'est fourni, retourner tout le contenu
2926
- console.log(`✅ File content successfully retrieved.`);
2927
- return fileContent;
2928
- }
2929
- catch (error) {
2930
- console.error('❌ An error occurred while processing the file:', error);
2931
- return null;
2932
- }
2933
- };
2934
- const replaceFileContent = (filePath, searchPattern, replacement) => {
2935
- try {
2936
- const results = replaceInFileSync({
2937
- files: filePath,
2938
- from: searchPattern,
2939
- to: replacement,
2940
- });
2941
- if (results.length > 0 && results[0].hasChanged) {
2942
- console.log(`✅ Content successfully replaced in the file: ${filePath}`);
2943
- }
2944
- else {
2945
- console.log(`⚠️ No replacement made. Here are some possible reasons:\n- The pattern ${searchPattern} was not found.\n- The file might already contain the expected content.`);
2946
- }
2947
- }
2948
- catch (error) {
2949
- console.error('❌ Error while replacing the file content:', error);
2950
- }
2951
- };
2952
- const findTailwindCssFile = (startDir, searchPattern) => {
2953
- const files = fs.readdirSync(startDir);
2954
- for (const file of files) {
2955
- const filePath = path.join(startDir, file);
2956
- const stats = fs.statSync(filePath);
2957
- if (stats.isDirectory()) {
2958
- // Appeler récursivement si c'est un dossier
2959
- const result = findTailwindCssFile(filePath, searchPattern);
2960
- if (result)
2961
- return result;
2962
- }
2963
- else if (file.endsWith('.css')) {
2964
- // Lire chaque fichier .css
2965
- const content = fs.readFileSync(filePath, 'utf8');
2966
- if (content.includes(searchPattern)) {
2967
- console.log('Fichier trouvé :', filePath);
2968
- return filePath;
2969
- }
2970
- }
2971
- }
2972
- return null;
2973
- };
2974
-
2975
- const font = (fontStyles, responsiveBreakPoints) => {
2976
- const createUtilities = ({ theme }) => {
2977
- const pixelUnit = 'rem';
2978
- const newUtilities = {};
2979
- const baseTextStyle = (sizeValue) => ({
2980
- fontSize: sizeValue.fontSize + pixelUnit,
2981
- fontWeight: sizeValue.fontWeight,
2982
- lineHeight: sizeValue.lineHeight + pixelUnit,
2983
- letterSpacing: sizeValue.letterSpacing
2984
- ? sizeValue.letterSpacing + pixelUnit
2985
- : null,
2986
- fontFamily: theme('fontFamily.' + sizeValue.fontFamily),
2987
- });
2988
- const responsiveTextStyle = (sizeValue, breakPointName, breakPointRatio) => ({
2989
- [`@media (min-width: ${theme('screens.' + breakPointName, {})})`]: {
2990
- fontSize: sizeValue.fontSize * breakPointRatio + pixelUnit,
2991
- lineHeight: sizeValue.lineHeight * breakPointRatio + pixelUnit,
2992
- },
2993
- });
2994
- for (const [roleName, roleValue] of Object.entries(fontStyles)) {
2995
- for (const [sizeName, sizeValue] of Object.entries(roleValue)) {
2996
- newUtilities['.text-' + roleName + '-' + sizeName] = Object.assign(Object.assign({}, baseTextStyle(sizeValue)), Object.entries(responsiveBreakPoints).reduce((acc, [breakPointName, breakPointRatio]) => {
2997
- acc = Object.assign(Object.assign({}, acc), responsiveTextStyle(sizeValue, breakPointName, breakPointRatio));
2998
- return acc;
2999
- }, {}));
3000
- }
3001
- }
3002
- return newUtilities;
3003
- };
3004
- return plugin(({ addUtilities, theme, }) => {
3005
- const newUtilities = createUtilities({ theme });
3006
- addUtilities(newUtilities);
3007
- });
3008
- };
3009
-
3010
- // from tailwindcss src/util/flattenColors
3011
- const state = (colorKeys) => plugin((pluginArgs) => {
3012
- addAllNewComponents(pluginArgs, {
3013
- statePrefix: 'state',
3014
- disabledStyles: {
3015
- textOpacity: 0.38,
3016
- backgroundOpacity: 0.12,
3017
- },
3018
- transition: {
3019
- duration: 150,
3020
- },
3021
- }, colorKeys);
3022
- }, {});
3023
- const addAllNewComponents = ({ addComponents }, { statePrefix, disabledStyles, transition }, colorKeys) => {
3024
- const newComponents = {};
3025
- for (const isGroup of [false, true]) {
3026
- const group = isGroup ? 'group-' : '';
3027
- for (const colorName of colorKeys) {
3028
- const className = `.${group}${statePrefix}-${colorName}`;
3029
- newComponents[className] = {
3030
- [`@apply ${group}hover:bg-${colorName}/[0.08]`]: {},
3031
- [`@apply ${group}active:bg-${colorName}/[0.12]`]: {},
3032
- [`@apply ${group}focus-visible:bg-${colorName}/[0.12]`]: {},
3033
- };
3034
- if (transition) {
3035
- newComponents[className][`@apply transition-colors`] = {};
3036
- newComponents[className][`@apply duration-${transition.duration}`] = {};
3037
- }
3038
- if (disabledStyles) {
3039
- newComponents[className][`@apply ${group}disabled:text-on-surface/[${disabledStyles.textOpacity}]`] = {};
3040
- newComponents[className][`@apply ${group}disabled:bg-on-surface/[${disabledStyles.backgroundOpacity}]`] = {};
3041
- }
3042
- }
3043
- }
3044
- for (const colorName of colorKeys) {
3045
- for (const stateName of ['hover', 'active', 'focus', 'disabled']) {
3046
- const className = `.${stateName}-${statePrefix}-${colorName}`;
3047
- if (stateName === 'active' || stateName === 'focus') {
3048
- newComponents[className] = {
3049
- [`@apply bg-${colorName}/[0.12]`]: {},
3050
- };
3051
- }
3052
- else if (stateName === 'hover') {
3053
- newComponents[className] = {
3054
- [`@apply bg-${colorName}/[0.08]`]: {},
3055
- };
3056
- }
3057
- else if (stateName === 'disabled') {
3058
- newComponents[className] = {
3059
- [`@apply text-on-surface/[${disabledStyles.textOpacity}]`]: {},
3060
- };
3061
- newComponents[className] = {
3062
- [`@apply bg-on-surface/[${disabledStyles.backgroundOpacity}]`]: {},
3063
- };
3064
- }
3065
- }
3066
- }
3067
- addComponents(newComponents);
3068
- };
3069
-
3070
- class TailwindPlugin extends PluginAbstract {
3071
- constructor() {
3072
- super(...arguments);
3073
- this.dependencies = [FontPlugin];
3074
- this.name = 'tailwind';
3075
- this.pluginClass = TailwindImplPlugin;
3076
- }
3077
- }
3078
- class TailwindImplPlugin extends PluginImplAbstract {
3079
- onInit() {
3080
- var _a, _b;
3081
- var _c, _d;
3082
- (_a = (_c = this.options).darkMode) !== null && _a !== void 0 ? _a : (_c.darkMode = 'class');
3083
- (_b = (_d = this.options).responsiveBreakPoints) !== null && _b !== void 0 ? _b : (_d.responsiveBreakPoints = {
3084
- lg: 1.125,
3085
- });
3086
- }
3087
- load() {
3088
- var _a;
3089
- const searchKeyword = '@plugin "@udixio/tailwind"';
3090
- const tailwindCssPath = findTailwindCssFile(process.cwd(), searchKeyword);
3091
- if (!tailwindCssPath) {
3092
- throw new Error('Tailwind plugin not found. Please use it first. (@plugin "@udixio/tailwind")');
3093
- }
3094
- const searchPattern = /@import 'tailwindcss';/;
3095
- const replacement = `@import 'tailwindcss';\n@import "./udixio.css";`;
3096
- if (!getFileContent(tailwindCssPath, /@import\s+"\.\/udixio\.css";/)) {
3097
- replaceFileContent(tailwindCssPath, searchPattern, replacement);
3098
- }
3099
- const cssFilePath = path__default.dirname(tailwindCssPath);
3100
- const colors = {};
3101
- for (const isDark of [false, true]) {
3102
- this.api.themes.update({ isDark: isDark });
3103
- for (const [key, value] of this.api.colors.getColors().entries()) {
3104
- const newKey = key
3105
- .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2')
3106
- .toLowerCase();
3107
- (_a = colors[newKey]) !== null && _a !== void 0 ? _a : (colors[newKey] = { light: '', dark: '' });
3108
- colors[newKey][isDark ? 'dark' : 'light'] = value.getHex();
3109
- }
3110
- }
3111
- const { fontStyles, fontFamily } = this.api.plugins
3112
- .getPlugin(FontPlugin)
3113
- .getInstance()
3114
- .getFonts();
3115
- createOrUpdateFile(path__default.join(cssFilePath, 'udixio.css'), `
3116
- @custom-variant dark (&:where(.dark, .dark *));
3117
- @theme {
3118
- --color-*: initial;
3119
- ${Object.entries(colors)
3120
- .map(([key, value]) => `--color-${key}: ${value.light};`)
3121
- .join('\n ')}
3122
- }
3123
- @layer theme {
3124
- .dark {
3125
- ${Object.entries(colors)
3126
- .map(([key, value]) => `--color-${key}: ${value.dark};`)
3127
- .join('\n ')}
3128
- }
3129
- }
3130
- `);
3131
- const plugins = [
3132
- state(Object.keys(colors)),
3133
- font(fontStyles, this.options.responsiveBreakPoints),
3134
- ];
3135
- return plugin.withOptions(
3136
- // 1) factory(options) → la fonction “handler” du plugin
3137
- (options = {}) => {
3138
- return function (api) {
3139
- return __awaiter(this, void 0, void 0, function* () {
3140
- plugins.forEach((plugin) => {
3141
- plugin.handler(api);
3142
- });
3143
- });
3144
- };
3145
- },
3146
- // 2) config(options) → objet à merger dans tailwind.config
3147
- (options = {}) => {
3148
- return {
3149
- theme: {
3150
- fontFamily,
3151
- },
3152
- };
3153
- });
3154
- }
3155
- }
3156
-
3157
- const createTheme = () => {
3158
- const app = bootstrapFromConfig();
3159
- const plugin = app.plugins.getPlugin(TailwindPlugin).getInstance();
3160
- return plugin.load();
3161
- };
3162
-
3163
- export { API, AppContainer, AppModule, ColorApi, ColorManager, ColorModule, ConfigModule, ConfigService, ConfigurableColor, ContrastCurve, DynamicColor, FontFamily, FontPlugin, PluginAbstract, PluginApi, PluginImplAbstract, PluginModule, Scheme, SchemeManager, TailwindPlugin, ThemeApi, ThemeModule, ToneDeltaPair, Variant, VariantManager, bootstrap, bootstrapFromConfig, createTheme, defaultColors, defineConfig, expressiveVariant, extendSpecVersion, font, getPiecewiseHue, getRotatedHue, highestSurface, importContainer, neutralVariant, state, tonalSpotVariant, vibrantVariant };
2841
+ export { API, AppContainer, AppModule, ColorApi, ColorManager, ColorModule, ConfigModule, ConfigService, ConfigurableColor, ContrastCurve, DynamicColor, FontFamily, FontPlugin, PluginAbstract, PluginApi, PluginImplAbstract, PluginModule, Scheme, SchemeManager, ThemeApi, ThemeModule, ToneDeltaPair, Variant, VariantManager, Variants, bootstrap, bootstrapFromConfig, defaultColors, defineConfig, expressiveVariant, extendSpecVersion, getPiecewiseHue, getRotatedHue, highestSurface, importContainer, neutralVariant, tonalSpotVariant, vibrantVariant };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@udixio/theme",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "main": "./index.cjs.js",
5
5
  "module": "./index.esm.js",
6
6
  "dependencies": {
@@ -8,5 +8,4 @@ export * from './main';
8
8
  export * from './material-color-utilities';
9
9
  export * from './plugin';
10
10
  export * from './plugins/font';
11
- export * from './plugins/tailwind';
12
11
  export * from './theme';
@@ -3,6 +3,12 @@ import { Hct } from '../material-color-utilities/htc';
3
3
  import { AddColors } from '../color';
4
4
  export declare const getPiecewiseHue: (sourceColorHct: Hct, hueBreakpoints: number[], hues: number[]) => number;
5
5
  export declare const getRotatedHue: (sourceColorHct: Hct, hueBreakpoints: number[], rotations: number[]) => number;
6
+ export declare const Variants: {
7
+ Expressive: Variant;
8
+ Neutral: Variant;
9
+ TonalSpot: Variant;
10
+ Vibrant: Variant;
11
+ };
6
12
  export declare class Variant {
7
13
  palettes: Record<string, (args: {
8
14
  sourceColorHct: Hct;
@@ -1,4 +0,0 @@
1
- export declare const createOrUpdateFile: (filePath: string, content: string) => void;
2
- export declare const getFileContent: (filePath: string, searchPattern?: RegExp | string) => string | false | null;
3
- export declare const replaceFileContent: (filePath: string, searchPattern: RegExp | string, replacement: string) => void;
4
- export declare const findTailwindCssFile: (startDir: string, searchPattern: string) => string | null;
@@ -1,3 +0,0 @@
1
- export * from './main';
2
- export * from './plugins-tailwind';
3
- export * from './tailwind.plugin';
@@ -1,2 +0,0 @@
1
- import plugin from 'tailwindcss/plugin';
2
- export declare const createTheme: () => ReturnType<typeof plugin.withOptions>;
@@ -1,3 +0,0 @@
1
- import { FontRole, FontSize, FontStyle } from '@udixio/theme';
2
- import plugin from 'tailwindcss/plugin';
3
- export declare const font: (fontStyles: Record<FontRole, Record<FontSize, FontStyle>>, responsiveBreakPoints: Record<string, number>) => ReturnType<typeof plugin>;
@@ -1,2 +0,0 @@
1
- export * from './state';
2
- export * from './font';
@@ -1,2 +0,0 @@
1
- import plugin from 'tailwindcss/plugin';
2
- export declare const state: (colorKeys: string[]) => ReturnType<typeof plugin>;
@@ -1,18 +0,0 @@
1
- import { PluginAbstract, PluginImplAbstract } from '../../plugin';
2
- import { FontPlugin } from '../font';
3
- import plugin from 'tailwindcss/plugin';
4
- interface TailwindPluginOptions {
5
- darkMode?: 'class' | 'media';
6
- responsiveBreakPoints?: Record<string, number>;
7
- subThemes?: Record<string, string>;
8
- }
9
- export declare class TailwindPlugin extends PluginAbstract<TailwindImplPlugin, TailwindPluginOptions> {
10
- dependencies: (typeof FontPlugin)[];
11
- name: string;
12
- pluginClass: typeof TailwindImplPlugin;
13
- }
14
- declare class TailwindImplPlugin extends PluginImplAbstract<TailwindPluginOptions> {
15
- onInit(): void;
16
- load(): ReturnType<typeof plugin.withOptions>;
17
- }
18
- export {};