@udixio/ui-react 1.3.0 → 1.5.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.
@@ -0,0 +1,6 @@
1
+ import { ConfigInterface } from '@udixio/theme';
2
+ export declare const ThemeProvider: ({ config, throttleDelay, }: {
3
+ config: ConfigInterface;
4
+ throttleDelay?: number;
5
+ }) => import("react/jsx-runtime").JSX.Element | null;
6
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/effects/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAU,MAAM,eAAe,CAAC;AAS7D,eAAO,MAAM,aAAa,GAAI,4BAG3B;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,mDA2FA,CAAC"}
@@ -2,4 +2,5 @@ export * from './ripple';
2
2
  export * from './custom-scroll';
3
3
  export * from './smooth-scroll.effect';
4
4
  export * from './SyncedFixedWrapper';
5
+ export * from './ThemeProvider';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/effects/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/effects/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@udixio/ui-react",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "throttle-debounce": "^5.0.2",
24
- "clsx": "^2.1.1",
24
+ "clsx": "^1.1.1",
25
25
  "react-textarea-autosize": "^8.5.9",
26
26
  "motion": "^12.23.0",
27
27
  "tailwind-merge": "^3.3.1",
@@ -35,8 +35,8 @@
35
35
  "devDependencies": {
36
36
  "react": "^19.1.1",
37
37
  "react-dom": "^19.1.1",
38
- "@udixio/theme": "1.1.0",
39
- "@udixio/tailwind": "1.3.0"
38
+ "@udixio/theme": "1.2.0",
39
+ "@udixio/tailwind": "1.5.0"
40
40
  },
41
41
  "repository": {
42
42
  "type": "git",
@@ -0,0 +1,107 @@
1
+ import { type ConfigInterface, loader } from '@udixio/theme';
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { TailwindPlugin } from '@udixio/tailwind';
4
+
5
+ function isValidHexColor(hexColorString: string) {
6
+ const regex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
7
+ return regex.test(hexColorString);
8
+ }
9
+
10
+ export const ThemeProvider = ({
11
+ config,
12
+ throttleDelay = 100, // Délai par défaut de 300ms
13
+ }: {
14
+ config: ConfigInterface;
15
+ throttleDelay?: number;
16
+ }) => {
17
+ const [error, setError] = useState<string | null>(null);
18
+ const [outputCss, setOutputCss] = useState<null | string>(null);
19
+
20
+ // Refs pour gérer le throttling
21
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null);
22
+ const lastSourceColorRef = useRef<string>(config.sourceColor);
23
+ const isInitialLoadRef = useRef<boolean>(true);
24
+
25
+ useEffect(() => {
26
+ // Si c'est le premier chargement, on applique immédiatement
27
+ if (isInitialLoadRef.current) {
28
+ isInitialLoadRef.current = false;
29
+ lastSourceColorRef.current = config.sourceColor;
30
+ applyThemeChange(config.sourceColor);
31
+ return;
32
+ }
33
+
34
+ // Si la couleur n'a pas changé, on ne fait rien
35
+ if (config.sourceColor === lastSourceColorRef.current) {
36
+ return;
37
+ }
38
+
39
+ // Annuler le timeout précédent s'il existe
40
+ if (timeoutRef.current) {
41
+ clearTimeout(timeoutRef.current);
42
+ }
43
+
44
+ // Programmer un nouveau changement de thème avec un délai
45
+ timeoutRef.current = setTimeout(() => {
46
+ lastSourceColorRef.current = config.sourceColor;
47
+ applyThemeChange(config.sourceColor);
48
+ timeoutRef.current = null;
49
+ }, throttleDelay);
50
+
51
+ // Cleanup function pour annuler le timeout si le composant se démonte
52
+ return () => {
53
+ if (timeoutRef.current) {
54
+ clearTimeout(timeoutRef.current);
55
+ timeoutRef.current = null;
56
+ }
57
+ };
58
+ }, [config.sourceColor, throttleDelay]);
59
+
60
+ const applyThemeChange = async (sourceColor: string) => {
61
+ if (!isValidHexColor(sourceColor)) {
62
+ setError('Invalid hex color');
63
+ return;
64
+ }
65
+
66
+ setError(null);
67
+
68
+ try {
69
+ // Mesure du temps de chargement de l'API
70
+ const api = await loader(config);
71
+ api.themes.update({
72
+ sourceColorHex: sourceColor,
73
+ });
74
+ await api.load();
75
+
76
+ const generatedCss = api.plugins
77
+ .getPlugin(TailwindPlugin)
78
+ .getInstance().outputCss;
79
+
80
+ if (generatedCss) {
81
+ setOutputCss(generatedCss);
82
+ }
83
+ } catch (err) {
84
+ setError(err instanceof Error ? err.message : 'Theme loading failed');
85
+ }
86
+ };
87
+
88
+ // Cleanup lors du démontage du composant
89
+ useEffect(() => {
90
+ return () => {
91
+ if (timeoutRef.current) {
92
+ clearTimeout(timeoutRef.current);
93
+ }
94
+ };
95
+ }, []);
96
+
97
+ if (error) {
98
+ return null;
99
+ }
100
+
101
+ if (!outputCss) {
102
+ console.error('ThemeProvider null');
103
+ return null;
104
+ }
105
+
106
+ return <style dangerouslySetInnerHTML={{ __html: outputCss }} />;
107
+ };
@@ -2,3 +2,4 @@ export * from './ripple';
2
2
  export * from './custom-scroll';
3
3
  export * from './smooth-scroll.effect';
4
4
  export * from './SyncedFixedWrapper';
5
+ export * from './ThemeProvider';
package/src/udixio.css CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  @plugin "@udixio/tailwind" {
3
2
  colorKeys: surface, surface-dim, surface-bright, surface-container-lowest, surface-container-low, surface-container, surface-container-high, surface-container-highest, on-surface, on-surface-variant, outline, outline-variant, inverse-surface, inverse-on-surface, primary, primary-dim, on-primary, primary-container, on-primary-container, primary-fixed, primary-fixed-dim, on-primary-fixed, on-primary-fixed-variant, inverse-primary, secondary, secondary-dim, on-secondary, secondary-container, on-secondary-container, secondary-fixed, secondary-fixed-dim, on-secondary-fixed, on-secondary-fixed-variant, tertiary, tertiary-dim, on-tertiary, tertiary-container, on-tertiary-container, tertiary-fixed, tertiary-fixed-dim, on-tertiary-fixed, on-tertiary-fixed-variant, error, error-dim, on-error, error-container, on-error-container, surface-variant, surface-tint, background, on-background;
4
3
  fontStyles: display-large fontWeight[400] fontSize[3.5625] lineHeight[4] letterSpacing[-0.015625] fontFamily[expressive], display-medium fontWeight[400] fontSize[2.8125] lineHeight[3.25] fontFamily[expressive], display-small fontWeight[400] fontSize[2.25] lineHeight[2.75] fontFamily[expressive], headline-large fontWeight[400] fontSize[2] lineHeight[2.5] fontFamily[expressive], headline-medium fontWeight[400] fontSize[1.75] lineHeight[2.25] fontFamily[expressive], headline-small fontWeight[400] fontSize[1.5] lineHeight[2] fontFamily[expressive], title-large fontWeight[400] fontSize[1.375] lineHeight[1.75] fontFamily[neutral], title-medium fontWeight[500] fontSize[1] lineHeight[1.5] fontFamily[neutral] letterSpacing[0.009375], title-small fontWeight[500] fontSize[0.875] lineHeight[1.25] fontFamily[neutral] letterSpacing[0.00625], label-large fontWeight[500] fontSize[0.875] lineHeight[1.25] fontFamily[neutral] letterSpacing[0.00625], label-medium fontWeight[500] fontSize[0.75] lineHeight[1] fontFamily[neutral] letterSpacing[0.03125], label-small fontWeight[500] fontSize[0.6875] lineHeight[1] fontFamily[neutral] letterSpacing[0.03125], body-large fontWeight[400] fontSize[1] lineHeight[1.5625] fontFamily[neutral] letterSpacing[0.03125], body-medium fontWeight[400] fontSize[0.875] lineHeight[1.25] fontFamily[neutral] letterSpacing[0.015625], body-small fontWeight[400] fontSize[0.75] lineHeight[1] fontFamily[neutral] letterSpacing[0.025];
@@ -114,7 +113,8 @@
114
113
  --color-on-background: #eae3ef;
115
114
  }
116
115
  }
116
+
117
117
  @theme {
118
118
  --font-expressive: "Roboto", "sans-serif";
119
119
  --font-neutral: "Roboto", "sans-serif";
120
- }
120
+ }
package/vite.config.ts CHANGED
@@ -3,6 +3,7 @@ import { defineConfig } from 'vite';
3
3
  import react from '@vitejs/plugin-react';
4
4
  import dts from 'vite-plugin-dts';
5
5
  import * as path from 'path';
6
+ import { visualizer } from 'rollup-plugin-visualizer';
6
7
 
7
8
  const getUdixioVite = async () => {
8
9
  // @ts-expect-error - NX_GRAPH_CREATION is a global variable set by Nx
@@ -10,7 +11,7 @@ const getUdixioVite = async () => {
10
11
  return;
11
12
  } else {
12
13
  const dynamicPath = '@udixio/theme';
13
- return (await import(dynamicPath)).udixioVite();
14
+ return (await import(dynamicPath)).vitePlugin;
14
15
  }
15
16
  };
16
17
 
@@ -24,6 +25,12 @@ export default defineConfig(async () => ({
24
25
  entryRoot: 'src',
25
26
  tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'),
26
27
  }),
28
+ visualizer({
29
+ filename: '../../stats/ui-react.html',
30
+ open: false,
31
+ gzipSize: true,
32
+ brotliSize: true,
33
+ }),
27
34
  ],
28
35
  // Uncomment this if you are using workers.
29
36
  // worker: {
@@ -39,6 +46,7 @@ export default defineConfig(async () => ({
39
46
  transformMixedEsModules: true,
40
47
  },
41
48
  lib: {
49
+ ssr: true,
42
50
  // Could also be a dictionary or array of multiple entry points.
43
51
  entry: 'src/index.ts',
44
52
  name: '@udixio/ui-react',
@@ -58,8 +66,9 @@ export default defineConfig(async () => ({
58
66
  'react-textarea-autosize',
59
67
  'tailwind-merge',
60
68
  'motion',
61
- 'motion/react',
62
69
  '@udixio/theme',
70
+ '@udixio/tailwind',
71
+ 'motion/react',
63
72
  ],
64
73
  },
65
74
  },