@contentful/experiences-visual-editor-react 3.1.1 → 3.2.0-dev-20250812T1256-c477cd9.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/dist/renderApp.js CHANGED
@@ -44069,35 +44069,69 @@ const breakpointsRefinement$1 = (value, ctx) => {
44069
44069
  code: z.ZodIssueCode.custom,
44070
44070
  message: `The first breakpoint should include the following attributes: { "query": "*" }`,
44071
44071
  });
44072
+ return;
44072
44073
  }
44073
- const hasDuplicateIds = value.some((currentBreakpoint, currentBreakpointIndex) => {
44074
- // check if the current breakpoint id is found in the rest of the array
44075
- const breakpointIndex = value.findIndex((breakpoint) => breakpoint.id === currentBreakpoint.id);
44076
- return breakpointIndex !== currentBreakpointIndex;
44077
- });
44074
+ // Return early if there's only one generic breakpoint
44075
+ const hasNoBreakpointsStrategy = value.length === 1;
44076
+ if (hasNoBreakpointsStrategy) {
44077
+ return;
44078
+ }
44079
+ // Check if any breakpoint id occurs twice
44080
+ const ids = value.map((breakpoint) => breakpoint.id);
44081
+ const hasDuplicateIds = new Set(ids).size !== ids.length;
44078
44082
  if (hasDuplicateIds) {
44079
44083
  ctx.addIssue({
44080
44084
  code: z.ZodIssueCode.custom,
44081
44085
  message: `Breakpoint IDs must be unique`,
44082
44086
  });
44087
+ return;
44088
+ }
44089
+ // Skip the first one which is guaranteed to be a wildcard query
44090
+ const nonBaseBreakpoints = value.slice(1);
44091
+ const isMobileFirstStrategy = nonBaseBreakpoints[0].query.startsWith('>');
44092
+ const isDesktopFirstStrategy = nonBaseBreakpoints[0].query.startsWith('<');
44093
+ if (isMobileFirstStrategy) {
44094
+ const areOperatorsEqual = nonBaseBreakpoints.every(({ query }) => query.startsWith('>'));
44095
+ if (!areOperatorsEqual) {
44096
+ ctx.addIssue({
44097
+ code: z.ZodIssueCode.custom,
44098
+ message: `Breakpoint queries must be in the format ">[size]px" for mobile-first strategy`,
44099
+ });
44100
+ }
44101
+ // Extract the queries boundary by removing the special characters around it
44102
+ const queries = nonBaseBreakpoints.map((bp) => parseInt(bp.query.replace(/px|<|>/, '')));
44103
+ // Starting with the third breakpoint, check that every query is higher than the one above
44104
+ const isIncreasing = queries.every((value, index, array) => index === 0 || value > array[index - 1]);
44105
+ if (!isIncreasing) {
44106
+ ctx.addIssue({
44107
+ code: z.ZodIssueCode.custom,
44108
+ message: `When using a mobile-first strategy, all breakpoints must have strictly increasing pixel values`,
44109
+ });
44110
+ }
44083
44111
  }
44084
- // Extract the queries boundary by removing the special characters around it
44085
- const queries = value.map((bp) => bp.query === '*' ? bp.query : parseInt(bp.query.replace(/px|<|>/, '')));
44086
- // sort updates queries array in place so we need to create a copy
44087
- const originalQueries = [...queries];
44088
- queries.sort((q1, q2) => {
44089
- if (q1 === '*') {
44090
- return -1;
44112
+ else if (isDesktopFirstStrategy) {
44113
+ const areOperatorsEqual = nonBaseBreakpoints.every(({ query }) => query.startsWith('<'));
44114
+ if (!areOperatorsEqual) {
44115
+ ctx.addIssue({
44116
+ code: z.ZodIssueCode.custom,
44117
+ message: `Breakpoint queries must be in the format "<[size]px" for desktop-first strategy`,
44118
+ });
44091
44119
  }
44092
- if (q2 === '*') {
44093
- return 1;
44120
+ // Extract the queries boundary by removing the special characters around it
44121
+ const queries = nonBaseBreakpoints.map((bp) => parseInt(bp.query.replace(/px|<|>/, '')));
44122
+ // Starting with the third breakpoint, check that every query is lower than the one above
44123
+ const isDecreasing = queries.every((value, index, array) => index === 0 || value < array[index - 1]);
44124
+ if (!isDecreasing) {
44125
+ ctx.addIssue({
44126
+ code: z.ZodIssueCode.custom,
44127
+ message: `When using a desktop-first strategy, all breakpoints must have strictly decreasing pixel values`,
44128
+ });
44094
44129
  }
44095
- return q1 > q2 ? -1 : 1;
44096
- });
44097
- if (originalQueries.join('') !== queries.join('')) {
44130
+ }
44131
+ else if (!isMobileFirstStrategy && !isDesktopFirstStrategy) {
44098
44132
  ctx.addIssue({
44099
44133
  code: z.ZodIssueCode.custom,
44100
- message: `Breakpoints should be ordered from largest to smallest pixel value`,
44134
+ message: `You may only use a mobile-first or desktop-first strategy for breakpoints using '<' or '>' queries`,
44101
44135
  });
44102
44136
  }
44103
44137
  };
@@ -44156,7 +44190,7 @@ const ParametersSchema$1 = z.record(propertyKeySchema$1, ParameterSchema$1);
44156
44190
  const BreakpointSchema$1 = z
44157
44191
  .object({
44158
44192
  id: propertyKeySchema$1,
44159
- query: z.string().regex(/^\*$|^<[0-9*]+px$/),
44193
+ query: z.string().regex(/^\*$|^[<>][0-9*]+px$/),
44160
44194
  previewSize: z.string(),
44161
44195
  displayName: z.string(),
44162
44196
  displayIcon: z.enum(['desktop', 'tablet', 'mobile']).optional(),
@@ -44434,7 +44468,7 @@ const toCSSMediaQuery = ({ query }) => {
44434
44468
  };
44435
44469
  // Remove this helper when upgrading to TypeScript 5.0 - https://github.com/microsoft/TypeScript/issues/48829
44436
44470
  const findLast = (array, predicate) => {
44437
- return array.reverse().find(predicate);
44471
+ return [...array].reverse().find(predicate);
44438
44472
  };
44439
44473
  // Initialise media query matchers. This won't include the always matching fallback breakpoint.
44440
44474
  const mediaQueryMatcher = (breakpoints) => {
@@ -44454,19 +44488,19 @@ const mediaQueryMatcher = (breakpoints) => {
44454
44488
  return [mediaQueryMatchers, mediaQueryMatches];
44455
44489
  };
44456
44490
  const getActiveBreakpointIndex = (breakpoints, mediaQueryMatches, fallbackBreakpointIndex) => {
44457
- // The breakpoints are ordered (desktop-first: descending by screen width)
44491
+ // The breakpoints are ordered (desktop-first: descending by screen width, mobile-first: ascending by screen width).
44458
44492
  const breakpointsWithMatches = breakpoints.map(({ id }, index) => ({
44459
44493
  id,
44460
44494
  index,
44461
44495
  // The fallback breakpoint with wildcard query will always match
44462
44496
  isMatch: mediaQueryMatches[id] ?? index === fallbackBreakpointIndex,
44463
44497
  }));
44464
- // Find the last breakpoint in the list that matches (desktop-first: the narrowest one)
44498
+ // Find the last breakpoint in the list that matches (desktop-first: the narrowest one, mobile-first: the widest one)
44465
44499
  const mostSpecificIndex = findLast(breakpointsWithMatches, ({ isMatch }) => isMatch)?.index;
44466
44500
  return mostSpecificIndex ?? fallbackBreakpointIndex;
44467
44501
  };
44468
44502
  const getFallbackBreakpointIndex = (breakpoints) => {
44469
- // We assume that there will be a single breakpoint which uses the wildcard query.
44503
+ // The validation ensures that there will be exactly one breakpoint using the wildcard query.
44470
44504
  // If there is none, we just take the first one in the list.
44471
44505
  return Math.max(breakpoints.findIndex(({ query }) => query === '*'), 0);
44472
44506
  };
@@ -48684,35 +48718,69 @@ const breakpointsRefinement = (value, ctx) => {
48684
48718
  code: z.ZodIssueCode.custom,
48685
48719
  message: `The first breakpoint should include the following attributes: { "query": "*" }`,
48686
48720
  });
48721
+ return;
48687
48722
  }
48688
- const hasDuplicateIds = value.some((currentBreakpoint, currentBreakpointIndex) => {
48689
- // check if the current breakpoint id is found in the rest of the array
48690
- const breakpointIndex = value.findIndex((breakpoint) => breakpoint.id === currentBreakpoint.id);
48691
- return breakpointIndex !== currentBreakpointIndex;
48692
- });
48723
+ // Return early if there's only one generic breakpoint
48724
+ const hasNoBreakpointsStrategy = value.length === 1;
48725
+ if (hasNoBreakpointsStrategy) {
48726
+ return;
48727
+ }
48728
+ // Check if any breakpoint id occurs twice
48729
+ const ids = value.map((breakpoint) => breakpoint.id);
48730
+ const hasDuplicateIds = new Set(ids).size !== ids.length;
48693
48731
  if (hasDuplicateIds) {
48694
48732
  ctx.addIssue({
48695
48733
  code: z.ZodIssueCode.custom,
48696
48734
  message: `Breakpoint IDs must be unique`,
48697
48735
  });
48736
+ return;
48737
+ }
48738
+ // Skip the first one which is guaranteed to be a wildcard query
48739
+ const nonBaseBreakpoints = value.slice(1);
48740
+ const isMobileFirstStrategy = nonBaseBreakpoints[0].query.startsWith('>');
48741
+ const isDesktopFirstStrategy = nonBaseBreakpoints[0].query.startsWith('<');
48742
+ if (isMobileFirstStrategy) {
48743
+ const areOperatorsEqual = nonBaseBreakpoints.every(({ query }) => query.startsWith('>'));
48744
+ if (!areOperatorsEqual) {
48745
+ ctx.addIssue({
48746
+ code: z.ZodIssueCode.custom,
48747
+ message: `Breakpoint queries must be in the format ">[size]px" for mobile-first strategy`,
48748
+ });
48749
+ }
48750
+ // Extract the queries boundary by removing the special characters around it
48751
+ const queries = nonBaseBreakpoints.map((bp) => parseInt(bp.query.replace(/px|<|>/, '')));
48752
+ // Starting with the third breakpoint, check that every query is higher than the one above
48753
+ const isIncreasing = queries.every((value, index, array) => index === 0 || value > array[index - 1]);
48754
+ if (!isIncreasing) {
48755
+ ctx.addIssue({
48756
+ code: z.ZodIssueCode.custom,
48757
+ message: `When using a mobile-first strategy, all breakpoints must have strictly increasing pixel values`,
48758
+ });
48759
+ }
48698
48760
  }
48699
- // Extract the queries boundary by removing the special characters around it
48700
- const queries = value.map((bp) => bp.query === '*' ? bp.query : parseInt(bp.query.replace(/px|<|>/, '')));
48701
- // sort updates queries array in place so we need to create a copy
48702
- const originalQueries = [...queries];
48703
- queries.sort((q1, q2) => {
48704
- if (q1 === '*') {
48705
- return -1;
48761
+ else if (isDesktopFirstStrategy) {
48762
+ const areOperatorsEqual = nonBaseBreakpoints.every(({ query }) => query.startsWith('<'));
48763
+ if (!areOperatorsEqual) {
48764
+ ctx.addIssue({
48765
+ code: z.ZodIssueCode.custom,
48766
+ message: `Breakpoint queries must be in the format "<[size]px" for desktop-first strategy`,
48767
+ });
48706
48768
  }
48707
- if (q2 === '*') {
48708
- return 1;
48769
+ // Extract the queries boundary by removing the special characters around it
48770
+ const queries = nonBaseBreakpoints.map((bp) => parseInt(bp.query.replace(/px|<|>/, '')));
48771
+ // Starting with the third breakpoint, check that every query is lower than the one above
48772
+ const isDecreasing = queries.every((value, index, array) => index === 0 || value < array[index - 1]);
48773
+ if (!isDecreasing) {
48774
+ ctx.addIssue({
48775
+ code: z.ZodIssueCode.custom,
48776
+ message: `When using a desktop-first strategy, all breakpoints must have strictly decreasing pixel values`,
48777
+ });
48709
48778
  }
48710
- return q1 > q2 ? -1 : 1;
48711
- });
48712
- if (originalQueries.join('') !== queries.join('')) {
48779
+ }
48780
+ else if (!isMobileFirstStrategy && !isDesktopFirstStrategy) {
48713
48781
  ctx.addIssue({
48714
48782
  code: z.ZodIssueCode.custom,
48715
- message: `Breakpoints should be ordered from largest to smallest pixel value`,
48783
+ message: `You may only use a mobile-first or desktop-first strategy for breakpoints using '<' or '>' queries`,
48716
48784
  });
48717
48785
  }
48718
48786
  };
@@ -48771,7 +48839,7 @@ const ParametersSchema = z.record(propertyKeySchema, ParameterSchema);
48771
48839
  const BreakpointSchema = z
48772
48840
  .object({
48773
48841
  id: propertyKeySchema,
48774
- query: z.string().regex(/^\*$|^<[0-9*]+px$/),
48842
+ query: z.string().regex(/^\*$|^[<>][0-9*]+px$/),
48775
48843
  previewSize: z.string(),
48776
48844
  displayName: z.string(),
48777
48845
  displayIcon: z.enum(['desktop', 'tablet', 'mobile']).optional(),