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