app-studio 0.2.2 → 0.2.7

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.
@@ -304,6 +304,7 @@ const palette = {
304
304
  }
305
305
  };
306
306
 
307
+ // Configuration de thème par défaut
307
308
  const defaultThemeMain = {
308
309
  primary: 'color.black',
309
310
  secondary: 'color.blue',
@@ -313,6 +314,7 @@ const defaultThemeMain = {
313
314
  disabled: 'color.gray.500',
314
315
  loading: 'color.dark.500'
315
316
  };
317
+ // Configuration des couleurs par défaut
316
318
  const defaultColors = {
317
319
  white: '#FFFFFF',
318
320
  black: '#000000',
@@ -345,10 +347,9 @@ const defaultColors = {
345
347
  darkGreen: '#006400',
346
348
  salmon: '#FA8072'
347
349
  };
350
+ // Création du contexte de thème avec des valeurs par défaut
348
351
  const ThemeContext = /*#__PURE__*/createContext({
349
- getColor: name => {
350
- return name;
351
- },
352
+ getColor: name => name,
352
353
  colors: {
353
354
  main: defaultColors,
354
355
  palette: palette
@@ -358,7 +359,35 @@ const ThemeContext = /*#__PURE__*/createContext({
358
359
  components: {}
359
360
  }
360
361
  });
362
+ // Hook personnalisé pour utiliser le contexte de thème
361
363
  const useTheme = () => useContext(ThemeContext);
364
+ // Fonction de fusion profonde simple
365
+ const deepMerge = (target, source) => {
366
+ if (typeof source !== 'object' || source === null) {
367
+ return target;
368
+ }
369
+ const merged = {
370
+ ...target
371
+ };
372
+ for (const key in source) {
373
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
374
+ const sourceValue = source[key];
375
+ const targetValue = target[key];
376
+ if (Array.isArray(sourceValue)) {
377
+ // Remplacer les tableaux
378
+ merged[key] = sourceValue;
379
+ } else if (typeof sourceValue === 'object' && sourceValue !== null && !Array.isArray(sourceValue)) {
380
+ // Fusion récursive des objets
381
+ merged[key] = deepMerge(targetValue || {}, sourceValue);
382
+ } else {
383
+ // Remplacer les autres types de valeurs
384
+ merged[key] = sourceValue;
385
+ }
386
+ }
387
+ }
388
+ return merged;
389
+ };
390
+ // Composant ThemeProvider
362
391
  const ThemeProvider = _ref => {
363
392
  let {
364
393
  theme = {
@@ -371,58 +400,69 @@ const ThemeProvider = _ref => {
371
400
  },
372
401
  children
373
402
  } = _ref;
403
+ // Fusion profonde des thèmes par défaut avec ceux fournis
404
+ const mergedTheme = deepMerge({
405
+ main: defaultThemeMain,
406
+ components: {}
407
+ }, theme);
408
+ // Fusion profonde des couleurs par défaut avec celles fournies
409
+ const mergedColors = deepMerge({
410
+ main: defaultColors,
411
+ palette: palette
412
+ }, colors);
413
+ /**
414
+ * Fonction pour récupérer une couleur basée sur un chemin en chaîne.
415
+ * Supporte les références imbriquées comme 'theme.button.primary.background'.
416
+ * @param name - Le nom de la couleur à récupérer.
417
+ * @returns La valeur de couleur résolue ou le nom original si non trouvé.
418
+ */
374
419
  const getColor = name => {
375
420
  if (name === 'transparent') return name;
376
421
  try {
377
- // Si le nom commence par "theme.", nous recherchons dans les couleurs du thème
378
422
  if (name.startsWith('theme.')) {
379
423
  const keys = name.split('.');
380
- if (keys[1] !== undefined && typeof theme.components[keys[1]] == 'object' && theme.components[keys[1]][keys[2]] !== undefined) {
381
- return getColor(theme.components[keys[1]][keys[2]]);
382
- } else if (theme.main[keys[1]] && theme.main[keys[1]] !== undefined) {
383
- return getColor(theme.main[keys[1]]);
384
- } else {
385
- console.log('Color ' + name + ' not found');
424
+ let value = mergedTheme;
425
+ for (let i = 1; i < keys.length; i++) {
426
+ value = value[keys[i]];
427
+ if (value === undefined) {
428
+ console.warn(`Couleur "${name}" non trouvée dans le thème.`);
429
+ return name;
430
+ }
386
431
  }
387
- }
388
- // Si le nom commence par "color.", nous recherchons dans la palette
389
- else if (name.startsWith('color.')) {
390
- const keys = name.split('.'); // Retirer le préfixe "color."
391
- if (colors.palette && colors.palette[keys[1]][keys[2]] !== undefined) {
392
- return colors.palette[keys[1]][keys[2]];
393
- } else if (colors.palette && colors.palette[keys[1]][parseInt(keys[2])] !== undefined) {
394
- return colors.palette[keys[1]][parseInt(keys[2])];
395
- } else if (colors.main && colors.main[keys[1]] !== undefined) {
396
- return colors.main[keys[1]];
432
+ if (typeof value === 'string') {
433
+ return getColor(value); // Résoudre les références imbriquées
397
434
  } else {
398
- console.log('Color ' + name + ' not found');
435
+ console.warn(`La couleur "${name}" a résolu à une valeur non-string.`);
436
+ return name;
437
+ }
438
+ } else if (name.startsWith('color.')) {
439
+ const keys = name.split('.');
440
+ if (keys.length === 2) {
441
+ // Exemple : "color.white"
442
+ const colorName = keys[1];
443
+ return mergedColors.main[colorName] || name;
444
+ } else if (keys.length === 3) {
445
+ // Exemple : "color.palette.primary.500"
446
+ const [_, paletteName, variant] = keys;
447
+ if (mergedColors.palette[paletteName] && mergedColors.palette[paletteName][variant]) {
448
+ return mergedColors.palette[paletteName][variant];
449
+ } else {
450
+ console.warn(`Color ${_} non trouvée`);
451
+ }
399
452
  }
453
+ console.warn(`Color "${name}" non trouvée dans la palette ou les couleurs principales.`);
400
454
  }
401
- } catch (e) {}
402
- return name;
455
+ } catch (e) {
456
+ console.error('Erreur lors de la récupération de la couleur:', e);
457
+ }
458
+ return name; // Retourner le nom original si non trouvé
403
459
  };
460
+
404
461
  return /*#__PURE__*/React.createElement(ThemeContext.Provider, {
405
462
  value: {
406
463
  getColor,
407
- theme: {
408
- main: {
409
- ...defaultThemeMain,
410
- ...theme.main
411
- },
412
- components: {
413
- ...theme.components
414
- }
415
- },
416
- colors: {
417
- main: {
418
- ...defaultColors,
419
- ...colors.main
420
- },
421
- palette: {
422
- ...palette,
423
- ...colors.palette
424
- }
425
- }
464
+ theme: mergedTheme,
465
+ colors: mergedColors
426
466
  }
427
467
  }, children);
428
468
  };
@@ -763,7 +803,106 @@ const generateCssRules = (selector, styles, getColor, mediaQueries) => {
763
803
  return rules;
764
804
  };
765
805
  // Function to apply styles to a component
766
- const applyStyle = (props, getColor, mediaQueries, devices) => {
806
+ const computeStyleProps = (props, getColor, mediaQueries, devices) => {
807
+ const styleProps = {};
808
+ const keyframesList = [];
809
+ // Gestion de la taille de l'élément
810
+ const size = props.height !== undefined && props.width !== undefined && props.height === props.width ? props.height : props.size ? props.size : null;
811
+ if (size) {
812
+ styleProps.height = styleProps.width = size;
813
+ }
814
+ // Gestion du padding et de la marge
815
+ if (props.paddingHorizontal) {
816
+ styleProps.paddingLeft = props.paddingHorizontal;
817
+ styleProps.paddingRight = props.paddingHorizontal;
818
+ }
819
+ if (props.marginHorizontal) {
820
+ styleProps.marginLeft = props.marginHorizontal;
821
+ styleProps.marginRight = props.marginHorizontal;
822
+ }
823
+ if (props.paddingVertical) {
824
+ styleProps.paddingTop = props.paddingVertical;
825
+ styleProps.paddingBottom = props.paddingVertical;
826
+ }
827
+ if (props.marginVertical) {
828
+ styleProps.marginTop = props.marginVertical;
829
+ styleProps.marginBottom = props.marginVertical;
830
+ }
831
+ // Application des ombres si spécifié
832
+ if (props.shadow) {
833
+ if (typeof props.shadow === 'number' || typeof props.shadow === 'boolean') {
834
+ const shadowValue = typeof props.shadow === 'number' && Shadows[props.shadow] !== undefined ? props.shadow : 2;
835
+ if (Shadows[shadowValue]) {
836
+ const shadowColor = Color.hex.rgb(Shadows[shadowValue].shadowColor) || [];
837
+ styleProps['boxShadow'] = `${Shadows[shadowValue].shadowOffset.height}px ${Shadows[shadowValue].shadowOffset.width}px ${Shadows[shadowValue].shadowRadius}px rgba(${shadowColor.join(',')},${Shadows[shadowValue].shadowOpacity})`;
838
+ }
839
+ } else {
840
+ const shadowColor = Color.hex.rgb(props.shadow.shadowColor) || [];
841
+ styleProps['boxShadow'] = `${props.shadow.shadowOffset.height}px ${props.shadow.shadowOffset.width}px ${props.shadow.shadowRadius}px rgba(${shadowColor.join(',')},${props.shadow.shadowOpacity})`;
842
+ }
843
+ }
844
+ // Gestion des animations
845
+ if (props.animate) {
846
+ const animation = props.animate;
847
+ const {
848
+ keyframesName,
849
+ keyframes
850
+ } = generateKeyframes(animation);
851
+ if (keyframes) {
852
+ keyframesList.push(keyframes);
853
+ }
854
+ styleProps.animationName = keyframesName;
855
+ styleProps.animationDuration = animation.duration || '1s';
856
+ styleProps.animationTimingFunction = animation.timingFunction || 'ease';
857
+ styleProps.animationDelay = animation.delay || '0s';
858
+ styleProps.animationIterationCount = `${animation.iterationCount || '1'}`;
859
+ styleProps.animationDirection = animation.direction || 'normal';
860
+ styleProps.animationFillMode = animation.fillMode || 'both';
861
+ styleProps.animationPlayState = animation.playState || 'running';
862
+ }
863
+ Object.keys(props).forEach(property => {
864
+ if (property !== 'style' && (isStyleProp(property) || extraKeys.has(property))) {
865
+ const value = props[property];
866
+ if (typeof value === 'object' && value !== null) {
867
+ // For other nested styles, exclude 'on' and 'media'
868
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
869
+ const {
870
+ on,
871
+ media,
872
+ ...nestedProps
873
+ } = value;
874
+ const nestedResult = applyStyle(nestedProps, getColor, mediaQueries, devices);
875
+ styleProps[property] = nestedResult.styleProps;
876
+ keyframesList.push(...(nestedResult.keyframes || []));
877
+ } else {
878
+ // Simple style property
879
+ styleProps[property] = value;
880
+ }
881
+ }
882
+ });
883
+ return {
884
+ styleProps,
885
+ keyframes: keyframesList
886
+ };
887
+ };
888
+ // Function to apply styles to a component
889
+ const applyStyle = function (props, getColor, mediaQueries, devices, depth,
890
+ // Add a depth parameter
891
+ maxDepth // Set a maximum depth
892
+ ) {
893
+ if (depth === void 0) {
894
+ depth = 0;
895
+ }
896
+ if (maxDepth === void 0) {
897
+ maxDepth = 10;
898
+ }
899
+ if (depth > maxDepth) {
900
+ console.error('Maximum recursion depth reached in applyStyle');
901
+ return {
902
+ styleProps: {},
903
+ keyframes: []
904
+ };
905
+ }
767
906
  const styleProps = {};
768
907
  const keyframesList = [];
769
908
  // Gestion de la taille de l'élément
@@ -820,24 +959,20 @@ const applyStyle = (props, getColor, mediaQueries, devices) => {
820
959
  styleProps.animationFillMode = animation.fillMode || 'both';
821
960
  styleProps.animationPlayState = animation.playState || 'running';
822
961
  }
823
- // Traitement des propriétés de style
824
962
  Object.keys(props).forEach(property => {
825
963
  if (property !== 'style' && (isStyleProp(property) || extraKeys.has(property))) {
826
964
  const value = props[property];
827
965
  if (typeof value === 'object' && value !== null) {
828
- // Pour les propriétés comme 'on', 'media'
829
966
  if (property === 'on') {
830
- // Pseudo-sélecteurs
831
967
  for (const event in value) {
832
968
  if (!styleProps[`&:${event}`]) {
833
969
  styleProps[`&:${event}`] = {};
834
970
  }
835
- const nestedResult = applyStyle(value[event], getColor, mediaQueries, devices);
971
+ const nestedResult = computeStyleProps(value[event], getColor, mediaQueries, devices);
836
972
  Object.assign(styleProps[`&:${event}`], nestedResult.styleProps);
837
973
  keyframesList.push(...(nestedResult.keyframes || []));
838
974
  }
839
975
  } else if (property === 'media') {
840
- // Media queries
841
976
  for (const screenOrDevices in value) {
842
977
  const mediaValue = value[screenOrDevices];
843
978
  if (mediaQueries[screenOrDevices]) {
@@ -845,7 +980,7 @@ const applyStyle = (props, getColor, mediaQueries, devices) => {
845
980
  if (!styleProps[mediaQuery]) {
846
981
  styleProps[mediaQuery] = {};
847
982
  }
848
- const nestedResult = applyStyle(mediaValue, getColor, mediaQueries, devices);
983
+ const nestedResult = computeStyleProps(mediaValue, getColor, mediaQueries, devices);
849
984
  Object.assign(styleProps[mediaQuery], nestedResult.styleProps);
850
985
  keyframesList.push(...(nestedResult.keyframes || []));
851
986
  } else if (devices[screenOrDevices]) {
@@ -856,7 +991,7 @@ const applyStyle = (props, getColor, mediaQueries, devices) => {
856
991
  if (!styleProps[mediaQuery]) {
857
992
  styleProps[mediaQuery] = {};
858
993
  }
859
- const nestedResult = applyStyle(mediaValue, getColor, mediaQueries, devices);
994
+ const nestedResult = computeStyleProps(mediaValue, getColor, mediaQueries, devices);
860
995
  Object.assign(styleProps[mediaQuery], nestedResult.styleProps);
861
996
  keyframesList.push(...(nestedResult.keyframes || []));
862
997
  }
@@ -864,13 +999,19 @@ const applyStyle = (props, getColor, mediaQueries, devices) => {
864
999
  }
865
1000
  }
866
1001
  } else {
867
- // Styles imbriqués
868
- const nestedResult = applyStyle(value, getColor, mediaQueries, devices);
1002
+ // For other nested styles, exclude 'on' and 'media'
1003
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1004
+ const {
1005
+ on,
1006
+ media,
1007
+ ...nestedProps
1008
+ } = value;
1009
+ const nestedResult = computeStyleProps(nestedProps, getColor, mediaQueries, devices);
869
1010
  styleProps[property] = nestedResult.styleProps;
870
1011
  keyframesList.push(...(nestedResult.keyframes || []));
871
1012
  }
872
1013
  } else {
873
- // Propriété de style simple
1014
+ // Simple style property
874
1015
  styleProps[property] = value;
875
1016
  }
876
1017
  }