webstudio 0.204.0 → 0.205.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/lib/cli.js CHANGED
@@ -71,11 +71,6 @@ const jsonToGlobalConfig = (json) => {
71
71
  return zGlobalConfig.parse(json);
72
72
  };
73
73
  const PROJECT_TEMPLATES = [
74
- {
75
- value: "vanilla",
76
- label: "Vanilla",
77
- expand: ["defaults"]
78
- },
79
74
  {
80
75
  value: "docker",
81
76
  label: "Docker",
@@ -84,7 +79,7 @@ const PROJECT_TEMPLATES = [
84
79
  {
85
80
  value: "vercel",
86
81
  label: "Vercel",
87
- expand: ["defaults", "vercel"]
82
+ expand: ["react-router", "react-router-vercel"]
88
83
  },
89
84
  {
90
85
  value: "netlify",
@@ -709,18 +704,48 @@ const getFontFaces = (assets, options) => {
709
704
  }
710
705
  return Array.from(faces.values());
711
706
  };
712
- const addGlobalRules = (sheet, { assets, assetBaseUrl }) => {
713
- const fontAssets = [];
714
- for (const asset of assets.values()) {
715
- if (asset.type === "font") {
716
- fontAssets.push(asset);
717
- }
718
- }
719
- const fontFaces = getFontFaces(fontAssets, { assetBaseUrl });
720
- for (const fontFace of fontFaces) {
721
- sheet.addFontFaceRule(fontFace);
722
- }
723
- };
707
+ const TextChild = z.object({
708
+ type: z.literal("text"),
709
+ value: z.string(),
710
+ placeholder: z.boolean().optional()
711
+ });
712
+ const InstanceId = z.string();
713
+ const IdChild = z.object({
714
+ type: z.literal("id"),
715
+ value: InstanceId
716
+ });
717
+ const ExpressionChild = z.object({
718
+ type: z.literal("expression"),
719
+ value: z.string()
720
+ });
721
+ const InstanceChild = z.union([IdChild, TextChild, ExpressionChild]);
722
+ const Instance = z.object({
723
+ type: z.literal("instance"),
724
+ id: InstanceId,
725
+ component: z.string(),
726
+ label: z.string().optional(),
727
+ children: z.array(InstanceChild)
728
+ });
729
+ z.map(InstanceId, Instance);
730
+ const MatcherRelation = z.union([
731
+ z.literal("ancestor"),
732
+ z.literal("parent"),
733
+ z.literal("self"),
734
+ z.literal("child"),
735
+ z.literal("descendant")
736
+ ]);
737
+ const MatcherOperation = z.object({
738
+ $eq: z.string().optional(),
739
+ $neq: z.string().optional(),
740
+ $in: z.array(z.string()).optional(),
741
+ $nin: z.array(z.string()).optional()
742
+ });
743
+ const Matcher = z.object({
744
+ relation: MatcherRelation,
745
+ component: MatcherOperation.optional(),
746
+ tag: MatcherOperation.optional()
747
+ });
748
+ const Matchers = z.union([Matcher, z.array(Matcher)]);
724
749
  const prefixStyles = (styleMap) => {
725
750
  const newStyleMap = /* @__PURE__ */ new Map();
726
751
  for (const [property, value] of styleMap) {
@@ -736,7 +761,7 @@ const prefixStyles = (styleMap) => {
736
761
  if (property === "backdrop-filter") {
737
762
  newStyleMap.set("-webkit-backdrop-filter", value);
738
763
  }
739
- if (property === "view-timeline-name" || property === "scroll-timeline-name") {
764
+ if (property === "view-timeline-name" || property === "scroll-timeline-name" || property === "view-timeline-inset") {
740
765
  newStyleMap.set(`--${property}`, value);
741
766
  }
742
767
  newStyleMap.set(property, value);
@@ -1119,11 +1144,10 @@ const mergeDeclarations = (declarations) => {
1119
1144
  }
1120
1145
  return newDeclarations;
1121
1146
  };
1122
- const generateStyleMap = ({
1123
- style,
1147
+ const generateStyleMap = (style, {
1124
1148
  indent = 0,
1125
1149
  transformValue
1126
- }) => {
1150
+ } = {}) => {
1127
1151
  const spaces = " ".repeat(indent);
1128
1152
  let lines = "";
1129
1153
  for (const [property, value] of style) {
@@ -1256,8 +1280,7 @@ class NestingRule {
1256
1280
  const generated = Array.from(styleBySelector).sort(
1257
1281
  ([leftSelector], [rightSelector]) => leftSelector.localeCompare(rightSelector)
1258
1282
  ).map(([selector, style]) => {
1259
- const content = generateStyleMap({
1260
- style: prefixStyles(style),
1283
+ const content = generateStyleMap(prefixStyles(style), {
1261
1284
  indent: indent + 2,
1262
1285
  transformValue
1263
1286
  });
@@ -1618,48 +1641,6 @@ const generateAtomic = (sheet, options) => {
1618
1641
  });
1619
1642
  return { cssText, classes };
1620
1643
  };
1621
- const TextChild = z.object({
1622
- type: z.literal("text"),
1623
- value: z.string(),
1624
- placeholder: z.boolean().optional()
1625
- });
1626
- const InstanceId = z.string();
1627
- const IdChild = z.object({
1628
- type: z.literal("id"),
1629
- value: InstanceId
1630
- });
1631
- const ExpressionChild = z.object({
1632
- type: z.literal("expression"),
1633
- value: z.string()
1634
- });
1635
- const InstanceChild = z.union([IdChild, TextChild, ExpressionChild]);
1636
- const Instance = z.object({
1637
- type: z.literal("instance"),
1638
- id: InstanceId,
1639
- component: z.string(),
1640
- label: z.string().optional(),
1641
- children: z.array(InstanceChild)
1642
- });
1643
- z.map(InstanceId, Instance);
1644
- const MatcherRelation = z.union([
1645
- z.literal("ancestor"),
1646
- z.literal("parent"),
1647
- z.literal("self"),
1648
- z.literal("child"),
1649
- z.literal("descendant")
1650
- ]);
1651
- const MatcherOperation = z.object({
1652
- $eq: z.string().optional(),
1653
- $neq: z.string().optional(),
1654
- $in: z.array(z.string()).optional(),
1655
- $nin: z.array(z.string()).optional()
1656
- });
1657
- const Matcher = z.object({
1658
- relation: MatcherRelation,
1659
- component: MatcherOperation.optional(),
1660
- tag: MatcherOperation.optional()
1661
- });
1662
- const Matchers = z.union([Matcher, z.array(Matcher)]);
1663
1644
  const common = {
1664
1645
  label: z.string().optional(),
1665
1646
  description: z.string().optional(),
@@ -1795,6 +1776,12 @@ const TextContent = z.object({
1795
1776
  type: z.literal("string"),
1796
1777
  defaultValue: z.string().optional()
1797
1778
  });
1779
+ const AnimationAction = z.object({
1780
+ ...common,
1781
+ control: z.literal("animationAction"),
1782
+ type: z.literal("animationAction"),
1783
+ defaultValue: z.undefined().optional()
1784
+ });
1798
1785
  const PropMeta = z.union([
1799
1786
  Number,
1800
1787
  Range,
@@ -1814,7 +1801,8 @@ const PropMeta = z.union([
1814
1801
  Json,
1815
1802
  Date,
1816
1803
  Action,
1817
- TextContent
1804
+ TextContent,
1805
+ AnimationAction
1818
1806
  ]);
1819
1807
  const EmbedTemplateText = z.object({
1820
1808
  type: z.literal("text"),
@@ -1938,6 +1926,11 @@ z.object({
1938
1926
  // embed - images, videos or other embeddable components, without children
1939
1927
  // rich-text-child - formatted text fragment, not listed in components list
1940
1928
  type: z.enum(["container", "control", "embed", "rich-text-child"]),
1929
+ /**
1930
+ * a property used as textual placeholder when no content specified while in builder
1931
+ * also signals to not insert components inside unless dropped explicitly
1932
+ */
1933
+ placeholder: z.string().optional(),
1941
1934
  constraints: Matchers.optional(),
1942
1935
  // when this field is specified component receives
1943
1936
  // prop with index of same components withiin specified ancestor
@@ -2413,6 +2406,13 @@ const parseComponentName = (componentName) => {
2413
2406
  }
2414
2407
  return [namespace, name2];
2415
2408
  };
2409
+ const SYSTEM_VARIABLE_ID = ":system";
2410
+ const systemParameter = {
2411
+ id: SYSTEM_VARIABLE_ID,
2412
+ scopeInstanceId: ROOT_INSTANCE_ID,
2413
+ type: "parameter",
2414
+ name: "system"
2415
+ };
2416
2416
  const transpileExpression = ({
2417
2417
  expression,
2418
2418
  executable = false,
@@ -2462,7 +2462,10 @@ const transpileExpression = ({
2462
2462
  return expression;
2463
2463
  };
2464
2464
  const dataSourceVariablePrefix = "$ws$dataSource$";
2465
- const decodeDataSourceVariable = (name2) => {
2465
+ const decodeDataVariableId = (name2) => {
2466
+ if (name2 === "$ws$system") {
2467
+ return SYSTEM_VARIABLE_ID;
2468
+ }
2466
2469
  if (name2.startsWith(dataSourceVariablePrefix)) {
2467
2470
  const encoded = name2.slice(dataSourceVariablePrefix.length);
2468
2471
  return encoded.replaceAll("__DASH__", "-");
@@ -2479,8 +2482,11 @@ const generateExpression = ({
2479
2482
  expression,
2480
2483
  executable: true,
2481
2484
  replaceVariable: (identifier) => {
2482
- const depId = decodeDataSourceVariable(identifier);
2483
- const dep = depId ? dataSources.get(depId) : void 0;
2485
+ const depId = decodeDataVariableId(identifier);
2486
+ let dep = depId ? dataSources.get(depId) : void 0;
2487
+ if (depId === SYSTEM_VARIABLE_ID) {
2488
+ dep = systemParameter;
2489
+ }
2484
2490
  if (dep) {
2485
2491
  usedDataSources == null ? void 0 : usedDataSources.set(dep.id, dep);
2486
2492
  return scope.getName(dep.id, dep.name);
@@ -2650,12 +2656,11 @@ const generateResources = ({
2650
2656
  `;
2651
2657
  }
2652
2658
  if (dataSource.type === "parameter") {
2653
- if (dataSource.id !== page.systemDataSourceId) {
2654
- continue;
2655
- }
2656
- const name2 = scope.getName(dataSource.id, dataSource.name);
2657
- generatedVariables += ` const ${name2} = _props.system
2659
+ if (dataSource.id === page.systemDataSourceId || dataSource.id === SYSTEM_VARIABLE_ID) {
2660
+ const name2 = scope.getName(dataSource.id, dataSource.name);
2661
+ generatedVariables += ` const ${name2} = _props.system
2658
2662
  `;
2663
+ }
2659
2664
  }
2660
2665
  }
2661
2666
  let generated = "";
@@ -2852,7 +2857,7 @@ const generatePageMeta = ({
2852
2857
  continue;
2853
2858
  }
2854
2859
  if (dataSource.type === "parameter") {
2855
- if (dataSource.id === page.systemDataSourceId) {
2860
+ if (dataSource.id === page.systemDataSourceId || dataSource.id === SYSTEM_VARIABLE_ID) {
2856
2861
  const valueName = localScope.getName(dataSource.id, dataSource.name);
2857
2862
  generated += ` let ${valueName} = system
2858
2863
  `;
@@ -2896,6 +2901,22 @@ const generatePageMeta = ({
2896
2901
  `;
2897
2902
  return generated;
2898
2903
  };
2904
+ const addFontRules = ({
2905
+ sheet,
2906
+ assets,
2907
+ assetBaseUrl
2908
+ }) => {
2909
+ const fontAssets = [];
2910
+ for (const asset of assets.values()) {
2911
+ if (asset.type === "font") {
2912
+ fontAssets.push(asset);
2913
+ }
2914
+ }
2915
+ const fontFaces = getFontFaces(fontAssets, { assetBaseUrl });
2916
+ for (const fontFace of fontFaces) {
2917
+ sheet.addFontFaceRule(fontFace);
2918
+ }
2919
+ };
2899
2920
  const createImageValueTransformer = (assets, { assetBaseUrl }) => (styleValue) => {
2900
2921
  if (styleValue.type === "image" && styleValue.value.type === "asset") {
2901
2922
  const asset = assets.get(styleValue.value.value);
@@ -2925,10 +2946,11 @@ const generateCss = ({
2925
2946
  assetBaseUrl,
2926
2947
  atomic
2927
2948
  }) => {
2928
- const globalSheet = createRegularStyleSheet({ name: "ssr" });
2929
- const sheet = createRegularStyleSheet({ name: "ssr" });
2930
- addGlobalRules(globalSheet, { assets, assetBaseUrl });
2931
- globalSheet.addMediaRule("presets");
2949
+ const fontSheet = createRegularStyleSheet({ name: "ssr" });
2950
+ const presetSheet = createRegularStyleSheet({ name: "ssr" });
2951
+ const userSheet = createRegularStyleSheet({ name: "ssr" });
2952
+ addFontRules({ sheet: fontSheet, assets, assetBaseUrl });
2953
+ presetSheet.addMediaRule("presets");
2932
2954
  const presetClasses = /* @__PURE__ */ new Map();
2933
2955
  const scope = createScope([], normalizeClassName, "-");
2934
2956
  for (const [component, meta2] of componentMetas) {
@@ -2939,8 +2961,8 @@ const generateCss = ({
2939
2961
  presetClasses.set(component, className);
2940
2962
  }
2941
2963
  for (const [tag, styles2] of presetStyle2) {
2942
- const selector = component === rootComponent ? ":root" : `:where(${tag}.${className})`;
2943
- const rule = globalSheet.addNestingRule(selector);
2964
+ const selector = component === rootComponent ? ":root" : `${tag}.${className}`;
2965
+ const rule = presetSheet.addNestingRule(selector);
2944
2966
  for (const declaration of styles2) {
2945
2967
  rule.setDeclaration({
2946
2968
  breakpoint: "presets",
@@ -2952,14 +2974,14 @@ const generateCss = ({
2952
2974
  }
2953
2975
  }
2954
2976
  for (const breakpoint of breakpoints.values()) {
2955
- sheet.addMediaRule(breakpoint.id, breakpoint);
2977
+ userSheet.addMediaRule(breakpoint.id, breakpoint);
2956
2978
  }
2957
2979
  const imageValueTransformer = createImageValueTransformer(assets, {
2958
2980
  assetBaseUrl
2959
2981
  });
2960
- sheet.setTransformer(imageValueTransformer);
2982
+ userSheet.setTransformer(imageValueTransformer);
2961
2983
  for (const styleDecl of styles.values()) {
2962
- const rule = sheet.addMixinRule(styleDecl.styleSourceId);
2984
+ const rule = userSheet.addMixinRule(styleDecl.styleSourceId);
2963
2985
  rule.setDeclaration({
2964
2986
  breakpoint: styleDecl.breakpointId,
2965
2987
  selector: styleDecl.state ?? "",
@@ -2991,7 +3013,7 @@ const generateCss = ({
2991
3013
  let { instanceId } = selection;
2992
3014
  const { values } = selection;
2993
3015
  if (instanceId === ROOT_INSTANCE_ID) {
2994
- const rule2 = sheet.addNestingRule(`:root`);
3016
+ const rule2 = userSheet.addNestingRule(`:root`);
2995
3017
  rule2.applyMixins(values);
2996
3018
  continue;
2997
3019
  }
@@ -3020,22 +3042,30 @@ const generateCss = ({
3020
3042
  }
3021
3043
  classList.push(className);
3022
3044
  }
3023
- const rule = sheet.addNestingRule(`.${className}`, descendantSuffix);
3045
+ const rule = userSheet.addNestingRule(`.${className}`, descendantSuffix);
3024
3046
  rule.applyMixins(values);
3025
3047
  instanceByRule.set(rule, instanceId);
3026
3048
  }
3049
+ const fontCss = fontSheet.cssText;
3050
+ const presetCss = presetSheet.cssText.replaceAll(
3051
+ "@media all ",
3052
+ "@layer presets "
3053
+ );
3027
3054
  if (atomic) {
3028
- const { cssText } = generateAtomic(sheet, {
3055
+ const { cssText } = generateAtomic(userSheet, {
3029
3056
  getKey: (rule) => instanceByRule.get(rule),
3030
3057
  transformValue: imageValueTransformer,
3031
3058
  classes
3032
3059
  });
3033
- return { cssText: `${globalSheet.cssText}
3034
- ${cssText}`, classes };
3060
+ return {
3061
+ cssText: `${fontCss}${presetCss}
3062
+ ${cssText}`,
3063
+ classes
3064
+ };
3035
3065
  }
3036
3066
  return {
3037
- cssText: `${globalSheet.cssText}
3038
- ${sheet.cssText}`,
3067
+ cssText: `${fontCss}${presetCss}
3068
+ ${userSheet.cssText}`,
3039
3069
  classes
3040
3070
  };
3041
3071
  };
@@ -3280,7 +3310,7 @@ const generateAction = ({
3280
3310
  if (args == null ? void 0 : args.includes(identifier)) {
3281
3311
  return;
3282
3312
  }
3283
- const depId = decodeDataSourceVariable(identifier);
3313
+ const depId = decodeDataVariableId(identifier);
3284
3314
  const dep = depId ? dataSources.get(depId) : void 0;
3285
3315
  if (dep) {
3286
3316
  usedDataSources.set(dep.id, dep);
@@ -3324,7 +3354,7 @@ const generatePropValue = ({
3324
3354
  if (prop.type === "asset" || prop.type === "page") {
3325
3355
  return;
3326
3356
  }
3327
- if (prop.type === "string" || prop.type === "number" || prop.type === "boolean" || prop.type === "string[]" || prop.type === "json") {
3357
+ if (prop.type === "string" || prop.type === "number" || prop.type === "boolean" || prop.type === "string[]" || prop.type === "json" || prop.type === "animationAction") {
3328
3358
  return JSON.stringify(prop.value);
3329
3359
  }
3330
3360
  if (prop.type === "parameter") {
@@ -3585,20 +3615,24 @@ const generateWebstudioComponent = ({
3585
3615
  })
3586
3616
  });
3587
3617
  let generatedProps = "";
3618
+ let generatedParameters = "";
3619
+ const uniqueParameters = new Set(
3620
+ parameters.map((parameter) => parameter.name)
3621
+ );
3588
3622
  if (parameters.length > 0) {
3589
- let generatedPropsValue = "{ ";
3590
- let generatedPropsType = "{ ";
3623
+ let generatedPropsType = "";
3624
+ for (const parameterName of uniqueParameters) {
3625
+ generatedPropsType += `${parameterName}: any; `;
3626
+ }
3627
+ generatedProps = `_props: { ${generatedPropsType}}`;
3591
3628
  for (const parameter of parameters) {
3592
3629
  const dataSource = usedDataSources.get(parameter.value);
3593
3630
  if (dataSource) {
3594
3631
  const valueName = scope.getName(dataSource.id, dataSource.name);
3595
- generatedPropsValue += `${parameter.name}: ${valueName}, `;
3632
+ generatedParameters += `const ${valueName} = _props.${parameter.name};
3633
+ `;
3596
3634
  }
3597
- generatedPropsType += `${parameter.name}: any; `;
3598
3635
  }
3599
- generatedPropsValue += `}`;
3600
- generatedPropsType += `}`;
3601
- generatedProps = `${generatedPropsValue}: ${generatedPropsType}`;
3602
3636
  }
3603
3637
  let generatedDataSources = "";
3604
3638
  for (const dataSource of usedDataSources.values()) {
@@ -3627,6 +3661,7 @@ const generateWebstudioComponent = ({
3627
3661
  let generatedComponent = "";
3628
3662
  generatedComponent += `const ${name2} = (${generatedProps}) => {
3629
3663
  `;
3664
+ generatedComponent += `${generatedParameters}`;
3630
3665
  generatedComponent += `${generatedDataSources}`;
3631
3666
  generatedComponent += `return ${generatedJsx}`;
3632
3667
  generatedComponent += `}
@@ -3744,14 +3779,14 @@ const htmlToJsx = (html2) => {
3744
3779
  }
3745
3780
  return result;
3746
3781
  };
3747
- const meta$I = {
3782
+ const meta$J = {
3748
3783
  category: "general",
3749
3784
  type: "container",
3750
3785
  description: "Slot is a container for content that you want to reference across the project. Changes made to a Slot's children will be reflected in all other instances of that Slot.",
3751
3786
  icon: SlotComponentIcon,
3752
3787
  order: 5
3753
3788
  };
3754
- const meta$H = {
3789
+ const meta$I = {
3755
3790
  type: "container",
3756
3791
  icon: ""
3757
3792
  };
@@ -3777,7 +3812,7 @@ const presetStyle$y = {
3777
3812
  }
3778
3813
  ]
3779
3814
  };
3780
- const meta$G = {
3815
+ const meta$H = {
3781
3816
  category: "general",
3782
3817
  type: "embed",
3783
3818
  label: "HTML Embed",
@@ -3807,7 +3842,7 @@ const meta$G = {
3807
3842
  },
3808
3843
  initialProps: ["className", "clientOnly", "executeScriptOnCanvas"]
3809
3844
  });
3810
- const meta$F = {
3845
+ const meta$G = {
3811
3846
  type: "embed",
3812
3847
  icon: MarkdownEmbedIcon,
3813
3848
  presetStyle: {
@@ -3836,7 +3871,7 @@ const presetStyle$x = {
3836
3871
  }
3837
3872
  ]
3838
3873
  };
3839
- const meta$E = {
3874
+ const meta$F = {
3840
3875
  type: "container",
3841
3876
  icon: BodyIcon,
3842
3877
  states: defaultStates,
@@ -3854,7 +3889,7 @@ const presetStyle$w = {
3854
3889
  nav,
3855
3890
  section
3856
3891
  };
3857
- const meta$D = {
3892
+ const meta$E = {
3858
3893
  category: "general",
3859
3894
  type: "container",
3860
3895
  description: "A container for content. By default this is a Div, but the tag can be changed in settings.",
@@ -3872,7 +3907,7 @@ const presetStyle$v = {
3872
3907
  }
3873
3908
  ]
3874
3909
  };
3875
- const meta$C = {
3910
+ const meta$D = {
3876
3911
  type: "container",
3877
3912
  icon: TextIcon,
3878
3913
  states: defaultStates,
@@ -3886,8 +3921,9 @@ const presetStyle$u = {
3886
3921
  h5,
3887
3922
  h6
3888
3923
  };
3889
- const meta$B = {
3924
+ const meta$C = {
3890
3925
  type: "container",
3926
+ placeholder: "Heading",
3891
3927
  icon: HeadingIcon,
3892
3928
  constraints: {
3893
3929
  relation: "ancestor",
@@ -3899,8 +3935,9 @@ const meta$B = {
3899
3935
  const presetStyle$t = {
3900
3936
  p
3901
3937
  };
3902
- const meta$A = {
3938
+ const meta$B = {
3903
3939
  type: "container",
3940
+ placeholder: "Paragraph",
3904
3941
  icon: TextAlignLeftIcon,
3905
3942
  constraints: {
3906
3943
  relation: "ancestor",
@@ -3918,8 +3955,9 @@ const presetStyle$s = {
3918
3955
  }
3919
3956
  ]
3920
3957
  };
3921
- const meta$z = {
3958
+ const meta$A = {
3922
3959
  type: "container",
3960
+ placeholder: "Link",
3923
3961
  icon: LinkIcon,
3924
3962
  constraints: {
3925
3963
  relation: "ancestor",
@@ -3939,14 +3977,14 @@ const meta$z = {
3939
3977
  }
3940
3978
  ]
3941
3979
  };
3942
- const meta$y = {
3943
- ...meta$z,
3980
+ const meta$z = {
3981
+ ...meta$A,
3944
3982
  type: "rich-text-child"
3945
3983
  };
3946
3984
  const presetStyle$r = {
3947
3985
  span
3948
3986
  };
3949
- const meta$x = {
3987
+ const meta$y = {
3950
3988
  type: "rich-text-child",
3951
3989
  label: "Text",
3952
3990
  icon: PaintBrushIcon,
@@ -3956,7 +3994,7 @@ const meta$x = {
3956
3994
  const presetStyle$q = {
3957
3995
  b
3958
3996
  };
3959
- const meta$w = {
3997
+ const meta$x = {
3960
3998
  type: "rich-text-child",
3961
3999
  label: "Bold Text",
3962
4000
  icon: BoldIcon,
@@ -3972,7 +4010,7 @@ const presetStyle$p = {
3972
4010
  }
3973
4011
  ]
3974
4012
  };
3975
- const meta$v = {
4013
+ const meta$w = {
3976
4014
  type: "rich-text-child",
3977
4015
  label: "Italic Text",
3978
4016
  icon: TextItalicIcon,
@@ -3982,7 +4020,7 @@ const meta$v = {
3982
4020
  const presetStyle$o = {
3983
4021
  sup
3984
4022
  };
3985
- const meta$u = {
4023
+ const meta$v = {
3986
4024
  type: "rich-text-child",
3987
4025
  label: "Superscript Text",
3988
4026
  icon: SuperscriptIcon,
@@ -3992,7 +4030,7 @@ const meta$u = {
3992
4030
  const presetStyle$n = {
3993
4031
  sub
3994
4032
  };
3995
- const meta$t = {
4033
+ const meta$u = {
3996
4034
  type: "rich-text-child",
3997
4035
  label: "Subscript Text",
3998
4036
  icon: SubscriptIcon,
@@ -4002,7 +4040,7 @@ const meta$t = {
4002
4040
  const presetStyle$m = {
4003
4041
  button
4004
4042
  };
4005
- const meta$s = {
4043
+ const meta$t = {
4006
4044
  icon: ButtonElementIcon,
4007
4045
  type: "container",
4008
4046
  constraints: {
@@ -4025,7 +4063,7 @@ const presetStyle$l = {
4025
4063
  }
4026
4064
  ]
4027
4065
  };
4028
- const meta$r = {
4066
+ const meta$s = {
4029
4067
  category: "forms",
4030
4068
  constraints: {
4031
4069
  relation: "ancestor",
@@ -4051,7 +4089,7 @@ const meta$r = {
4051
4089
  //{ selector: ":read-write", label: "Read Write" },
4052
4090
  ]
4053
4091
  };
4054
- const meta$q = {
4092
+ const meta$r = {
4055
4093
  label: "Webhook Form",
4056
4094
  icon: WebhookFormIcon,
4057
4095
  type: "container",
@@ -4073,7 +4111,7 @@ const presetStyle$k = {
4073
4111
  { property: "minHeight", value: { type: "unit", unit: "px", value: 20 } }
4074
4112
  ]
4075
4113
  };
4076
- const meta$p = {
4114
+ const meta$q = {
4077
4115
  category: "forms",
4078
4116
  type: "container",
4079
4117
  label: "Form",
@@ -4110,7 +4148,7 @@ const presetStyle$j = {
4110
4148
  }
4111
4149
  ]
4112
4150
  };
4113
- const meta$o = {
4151
+ const meta$p = {
4114
4152
  category: "media",
4115
4153
  type: "embed",
4116
4154
  description: "Add an image asset to the page. Webstudio automatically converts images to WebP or AVIF format and makes them responsive for best performance.",
@@ -4167,8 +4205,9 @@ const presetStyle$i = {
4167
4205
  }
4168
4206
  ]
4169
4207
  };
4170
- const meta$n = {
4208
+ const meta$o = {
4171
4209
  type: "container",
4210
+ placeholder: "Blockquote",
4172
4211
  icon: BlockquoteIcon,
4173
4212
  states: defaultStates,
4174
4213
  presetStyle: presetStyle$i
@@ -4205,7 +4244,7 @@ const presetStyle$h = {
4205
4244
  }
4206
4245
  ]
4207
4246
  };
4208
- const meta$m = {
4247
+ const meta$n = {
4209
4248
  type: "container",
4210
4249
  icon: ListIcon,
4211
4250
  states: defaultStates,
@@ -4214,8 +4253,9 @@ const meta$m = {
4214
4253
  const presetStyle$g = {
4215
4254
  li
4216
4255
  };
4217
- const meta$l = {
4256
+ const meta$m = {
4218
4257
  type: "container",
4258
+ placeholder: "List item",
4219
4259
  constraints: {
4220
4260
  // cannot use parent relation here
4221
4261
  // because list item can be put inside of collection or slot
@@ -4256,7 +4296,7 @@ const presetStyle$f = {
4256
4296
  }
4257
4297
  ]
4258
4298
  };
4259
- const meta$k = {
4299
+ const meta$l = {
4260
4300
  category: "general",
4261
4301
  type: "embed",
4262
4302
  description: "Used to visually divide sections of content, helping to improve readability and organization within a webpage.",
@@ -4294,7 +4334,7 @@ const presetStyle$e = {
4294
4334
  }
4295
4335
  ]
4296
4336
  };
4297
- const meta$j = {
4337
+ const meta$k = {
4298
4338
  category: "general",
4299
4339
  type: "embed",
4300
4340
  description: "Use this component when you want to display code as text on the page.",
@@ -4313,7 +4353,7 @@ const presetStyle$d = {
4313
4353
  { property: "display", value: { type: "keyword", value: "block" } }
4314
4354
  ]
4315
4355
  };
4316
- const meta$i = {
4356
+ const meta$j = {
4317
4357
  constraints: {
4318
4358
  relation: "ancestor",
4319
4359
  component: { $nin: ["Button", "Link"] }
@@ -4335,7 +4375,7 @@ const presetStyle$c = {
4335
4375
  }
4336
4376
  ]
4337
4377
  };
4338
- const meta$h = {
4378
+ const meta$i = {
4339
4379
  category: "forms",
4340
4380
  type: "control",
4341
4381
  label: "Text Area",
@@ -4370,7 +4410,7 @@ const presetStyle$b = {
4370
4410
  }
4371
4411
  ]
4372
4412
  };
4373
- const meta$g = {
4413
+ const meta$h = {
4374
4414
  constraints: {
4375
4415
  relation: "ancestor",
4376
4416
  component: { $nin: ["Button", "Link"] }
@@ -4400,7 +4440,7 @@ const presetStyle$a = {
4400
4440
  }
4401
4441
  ]
4402
4442
  };
4403
- const meta$f = {
4443
+ const meta$g = {
4404
4444
  constraints: {
4405
4445
  relation: "ancestor",
4406
4446
  component: { $nin: ["Button", "Link"] }
@@ -4422,7 +4462,7 @@ const meta$f = {
4422
4462
  const presetStyle$9 = {
4423
4463
  div
4424
4464
  };
4425
- const meta$e = {
4465
+ const meta$f = {
4426
4466
  type: "container",
4427
4467
  icon: VimeoIcon,
4428
4468
  states: defaultStates,
@@ -4435,7 +4475,7 @@ const meta$e = {
4435
4475
  const presetStyle$8 = {
4436
4476
  div
4437
4477
  };
4438
- const meta$d = {
4478
+ const meta$e = {
4439
4479
  type: "container",
4440
4480
  icon: YoutubeIcon,
4441
4481
  states: defaultStates,
@@ -4445,8 +4485,8 @@ const meta$d = {
4445
4485
  component: { $nin: ["Button", "Link", "Heading"] }
4446
4486
  }
4447
4487
  };
4448
- const meta$c = {
4449
- ...meta$o,
4488
+ const meta$d = {
4489
+ ...meta$p,
4450
4490
  category: "hidden",
4451
4491
  label: "Preview Image",
4452
4492
  constraints: {
@@ -4457,7 +4497,7 @@ const meta$c = {
4457
4497
  const presetStyle$7 = {
4458
4498
  button
4459
4499
  };
4460
- const meta$b = {
4500
+ const meta$c = {
4461
4501
  category: "hidden",
4462
4502
  type: "container",
4463
4503
  constraints: [
@@ -4478,7 +4518,7 @@ const meta$b = {
4478
4518
  const presetStyle$6 = {
4479
4519
  div
4480
4520
  };
4481
- const meta$a = {
4521
+ const meta$b = {
4482
4522
  type: "container",
4483
4523
  constraints: {
4484
4524
  relation: "ancestor",
@@ -4490,14 +4530,14 @@ const meta$a = {
4490
4530
  category: "hidden",
4491
4531
  label: "Spinner"
4492
4532
  };
4493
- const meta$9 = {
4533
+ const meta$a = {
4494
4534
  category: "xml",
4495
4535
  order: 6,
4496
4536
  type: "container",
4497
4537
  icon: XmlIcon,
4498
4538
  description: "XML Node"
4499
4539
  };
4500
- const meta$8 = {
4540
+ const meta$9 = {
4501
4541
  category: "xml",
4502
4542
  type: "container",
4503
4543
  description: "Converts machine-readable date and time to ISO format.",
@@ -4507,7 +4547,7 @@ const meta$8 = {
4507
4547
  const presetStyle$5 = {
4508
4548
  time
4509
4549
  };
4510
- const meta$7 = {
4550
+ const meta$8 = {
4511
4551
  category: "localization",
4512
4552
  type: "container",
4513
4553
  description: "Converts machine-readable date and time to a human-readable format.",
@@ -4524,7 +4564,7 @@ const presetStyle$4 = {
4524
4564
  }
4525
4565
  ]
4526
4566
  };
4527
- const meta$6 = {
4567
+ const meta$7 = {
4528
4568
  constraints: {
4529
4569
  relation: "ancestor",
4530
4570
  component: { $nin: ["Button", "Link"] }
@@ -4556,7 +4596,7 @@ const presetStyle$3 = {
4556
4596
  }
4557
4597
  ]
4558
4598
  };
4559
- const meta$5 = {
4599
+ const meta$6 = {
4560
4600
  category: "hidden",
4561
4601
  constraints: {
4562
4602
  relation: "parent",
@@ -4577,7 +4617,7 @@ const meta$5 = {
4577
4617
  { selector: ":disabled", label: "Disabled" }
4578
4618
  ]
4579
4619
  };
4580
- const meta$4 = {
4620
+ const meta$5 = {
4581
4621
  icon: HeaderIcon,
4582
4622
  type: "container",
4583
4623
  description: "Inserts children into the head of the document",
@@ -4592,7 +4632,7 @@ const meta$4 = {
4592
4632
  }
4593
4633
  ]
4594
4634
  };
4595
- const meta$3 = {
4635
+ const meta$4 = {
4596
4636
  category: "hidden",
4597
4637
  icon: ResourceIcon,
4598
4638
  type: "embed",
@@ -4601,7 +4641,7 @@ const meta$3 = {
4601
4641
  component: { $eq: "HeadSlot" }
4602
4642
  }
4603
4643
  };
4604
- const meta$2 = {
4644
+ const meta$3 = {
4605
4645
  category: "hidden",
4606
4646
  icon: WindowInfoIcon,
4607
4647
  type: "embed",
@@ -4610,7 +4650,7 @@ const meta$2 = {
4610
4650
  component: { $eq: "HeadSlot" }
4611
4651
  }
4612
4652
  };
4613
- const meta$1 = {
4653
+ const meta$2 = {
4614
4654
  category: "hidden",
4615
4655
  icon: WindowTitleIcon,
4616
4656
  type: "container",
@@ -4621,61 +4661,70 @@ const meta$1 = {
4621
4661
  };
4622
4662
  const baseComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4623
4663
  __proto__: null,
4624
- Blockquote: meta$n,
4625
- Body: meta$E,
4626
- Bold: meta$w,
4627
- Box: meta$D,
4628
- Button: meta$s,
4629
- Checkbox: meta$f,
4630
- CodeText: meta$j,
4631
- Form: meta$q,
4632
- Fragment: meta$H,
4633
- HeadLink: meta$3,
4634
- HeadMeta: meta$2,
4635
- HeadSlot: meta$4,
4636
- HeadTitle: meta$1,
4637
- Heading: meta$B,
4638
- HtmlEmbed: meta$G,
4639
- Image: meta$o,
4640
- Input: meta$r,
4641
- Italic: meta$v,
4642
- Label: meta$i,
4643
- Link: meta$z,
4644
- List: meta$m,
4645
- ListItem: meta$l,
4646
- MarkdownEmbed: meta$F,
4647
- Option: meta$5,
4648
- Paragraph: meta$A,
4649
- RadioButton: meta$g,
4650
- RemixForm: meta$p,
4651
- RichTextLink: meta$y,
4652
- Select: meta$6,
4653
- Separator: meta$k,
4654
- Slot: meta$I,
4655
- Span: meta$x,
4656
- Subscript: meta$t,
4657
- Superscript: meta$u,
4658
- Text: meta$C,
4659
- Textarea: meta$h,
4660
- Time: meta$7,
4661
- Vimeo: meta$e,
4662
- VimeoPlayButton: meta$b,
4663
- VimeoPreviewImage: meta$c,
4664
- VimeoSpinner: meta$a,
4665
- XmlNode: meta$9,
4666
- XmlTime: meta$8,
4667
- YouTube: meta$d
4664
+ Blockquote: meta$o,
4665
+ Body: meta$F,
4666
+ Bold: meta$x,
4667
+ Box: meta$E,
4668
+ Button: meta$t,
4669
+ Checkbox: meta$g,
4670
+ CodeText: meta$k,
4671
+ Form: meta$r,
4672
+ Fragment: meta$I,
4673
+ HeadLink: meta$4,
4674
+ HeadMeta: meta$3,
4675
+ HeadSlot: meta$5,
4676
+ HeadTitle: meta$2,
4677
+ Heading: meta$C,
4678
+ HtmlEmbed: meta$H,
4679
+ Image: meta$p,
4680
+ Input: meta$s,
4681
+ Italic: meta$w,
4682
+ Label: meta$j,
4683
+ Link: meta$A,
4684
+ List: meta$n,
4685
+ ListItem: meta$m,
4686
+ MarkdownEmbed: meta$G,
4687
+ Option: meta$6,
4688
+ Paragraph: meta$B,
4689
+ RadioButton: meta$h,
4690
+ RemixForm: meta$q,
4691
+ RichTextLink: meta$z,
4692
+ Select: meta$7,
4693
+ Separator: meta$l,
4694
+ Slot: meta$J,
4695
+ Span: meta$y,
4696
+ Subscript: meta$u,
4697
+ Superscript: meta$v,
4698
+ Text: meta$D,
4699
+ Textarea: meta$i,
4700
+ Time: meta$8,
4701
+ Vimeo: meta$f,
4702
+ VimeoPlayButton: meta$c,
4703
+ VimeoPreviewImage: meta$d,
4704
+ VimeoSpinner: meta$b,
4705
+ XmlNode: meta$a,
4706
+ XmlTime: meta$9,
4707
+ YouTube: meta$e
4668
4708
  }, Symbol.toStringTag, { value: "Module" }));
4709
+ const meta$1 = {
4710
+ category: "general",
4711
+ type: "container",
4712
+ description: "Animate Children",
4713
+ icon: SlotComponentIcon,
4714
+ order: 5,
4715
+ label: "Animate Children"
4716
+ };
4669
4717
  const animationComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4670
- __proto__: null
4718
+ __proto__: null,
4719
+ AnimateChildren: meta$1
4671
4720
  }, Symbol.toStringTag, { value: "Module" }));
4672
4721
  const remixComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4673
4722
  __proto__: null,
4674
- Body: meta$E,
4675
- Form: meta$q,
4676
- Link: meta$z,
4677
- RemixForm: meta$p,
4678
- RichTextLink: meta$y
4723
+ Body: meta$F,
4724
+ Form: meta$r,
4725
+ Link: meta$A,
4726
+ RemixForm: meta$q,
4727
+ RichTextLink: meta$z
4679
4728
  }, Symbol.toStringTag, { value: "Module" }));
4680
4729
  const metaCollapsible = {
4681
4730
  type: "container",
@@ -5587,11 +5636,11 @@ const createFramework$2 = async () => {
5587
5636
  };
5588
5637
  const reactRouterComponentMetas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
5589
5638
  __proto__: null,
5590
- Body: meta$E,
5591
- Form: meta$q,
5592
- Link: meta$z,
5593
- RemixForm: meta$p,
5594
- RichTextLink: meta$y
5639
+ Body: meta$F,
5640
+ Form: meta$r,
5641
+ Link: meta$A,
5642
+ RemixForm: meta$q,
5643
+ RichTextLink: meta$z
5595
5644
  }, Symbol.toStringTag, { value: "Module" }));
5596
5645
  const createFramework$1 = async () => {
5597
5646
  const routeTemplatesDir = join("app", "route-templates");
@@ -6099,11 +6148,18 @@ Please check webstudio --help for more details`
6099
6148
  rootInstanceId,
6100
6149
  parameters: [
6101
6150
  {
6102
- id: `system`,
6151
+ id: `page-system`,
6103
6152
  instanceId: "",
6104
6153
  name: "system",
6105
6154
  type: "parameter",
6106
6155
  value: pageData.page.systemDataSourceId ?? ""
6156
+ },
6157
+ {
6158
+ id: "global-system",
6159
+ type: "parameter",
6160
+ instanceId: "",
6161
+ name: "system",
6162
+ value: SYSTEM_VARIABLE_ID
6107
6163
  }
6108
6164
  ],
6109
6165
  instances,
@@ -6414,7 +6470,7 @@ const getDeploymentInstructions = (deployTarget) => {
6414
6470
  }
6415
6471
  };
6416
6472
  const name = "webstudio";
6417
- const version = "0.204.0";
6473
+ const version = "0.205.0";
6418
6474
  const description = "Webstudio CLI";
6419
6475
  const author = "Webstudio <github@webstudio.is>";
6420
6476
  const homepage = "https://webstudio.is";
@@ -6474,6 +6530,7 @@ const devDependencies = {
6474
6530
  "@types/react": "^18.2.70",
6475
6531
  "@types/react-dom": "^18.2.25",
6476
6532
  "@types/yargs": "^17.0.33",
6533
+ "@vercel/react-router": "^1.0.2",
6477
6534
  "@vitejs/plugin-react": "^4.3.4",
6478
6535
  "@webstudio-is/http-client": "workspace:*",
6479
6536
  "@webstudio-is/image": "workspace:*",
@@ -6485,14 +6542,14 @@ const devDependencies = {
6485
6542
  "@webstudio-is/sdk-components-react-remix": "workspace:*",
6486
6543
  "@webstudio-is/sdk-components-react-router": "workspace:*",
6487
6544
  "@webstudio-is/tsconfig": "workspace:*",
6488
- h3: "^1.14.0",
6545
+ h3: "^1.15.0",
6489
6546
  ipx: "^3.0.1",
6490
6547
  prettier: "3.4.2",
6491
6548
  react: "18.3.0-canary-14898b6a9-20240318",
6492
6549
  "react-dom": "18.3.0-canary-14898b6a9-20240318",
6493
6550
  "react-router": "^7.1.5",
6494
6551
  "ts-expect": "^1.3.0",
6495
- vike: "^0.4.220",
6552
+ vike: "^0.4.222",
6496
6553
  vite: "^5.4.11",
6497
6554
  vitest: "^3.0.4",
6498
6555
  wrangler: "^3.63.2"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webstudio",
3
- "version": "0.204.0",
3
+ "version": "0.205.0",
4
4
  "description": "Webstudio CLI",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -55,27 +55,28 @@
55
55
  "@types/react": "^18.2.70",
56
56
  "@types/react-dom": "^18.2.25",
57
57
  "@types/yargs": "^17.0.33",
58
+ "@vercel/react-router": "^1.0.2",
58
59
  "@vitejs/plugin-react": "^4.3.4",
59
- "h3": "^1.14.0",
60
+ "h3": "^1.15.0",
60
61
  "ipx": "^3.0.1",
61
62
  "prettier": "3.4.2",
62
63
  "react": "18.3.0-canary-14898b6a9-20240318",
63
64
  "react-dom": "18.3.0-canary-14898b6a9-20240318",
64
65
  "react-router": "^7.1.5",
65
66
  "ts-expect": "^1.3.0",
66
- "vike": "^0.4.220",
67
+ "vike": "^0.4.222",
67
68
  "vite": "^5.4.11",
68
69
  "vitest": "^3.0.4",
69
70
  "wrangler": "^3.63.2",
70
- "@webstudio-is/http-client": "0.204.0",
71
- "@webstudio-is/image": "0.204.0",
72
- "@webstudio-is/react-sdk": "0.204.0",
73
- "@webstudio-is/sdk": "0.204.0",
74
- "@webstudio-is/sdk-components-animation": "0.204.0",
75
- "@webstudio-is/sdk-components-react": "0.204.0",
76
- "@webstudio-is/sdk-components-react-radix": "0.204.0",
77
- "@webstudio-is/sdk-components-react-router": "0.204.0",
78
- "@webstudio-is/sdk-components-react-remix": "0.204.0",
71
+ "@webstudio-is/http-client": "0.205.0",
72
+ "@webstudio-is/image": "0.205.0",
73
+ "@webstudio-is/sdk": "0.205.0",
74
+ "@webstudio-is/sdk-components-animation": "0.205.0",
75
+ "@webstudio-is/react-sdk": "0.205.0",
76
+ "@webstudio-is/sdk-components-react": "0.205.0",
77
+ "@webstudio-is/sdk-components-react-remix": "0.205.0",
78
+ "@webstudio-is/sdk-components-react-radix": "0.205.0",
79
+ "@webstudio-is/sdk-components-react-router": "0.205.0",
79
80
  "@webstudio-is/tsconfig": "1.0.7"
80
81
  },
81
82
  "scripts": {
@@ -11,13 +11,13 @@
11
11
  "@remix-run/node": "2.15.2",
12
12
  "@remix-run/react": "2.15.2",
13
13
  "@remix-run/server-runtime": "2.15.2",
14
- "@webstudio-is/image": "0.204.0",
15
- "@webstudio-is/react-sdk": "0.204.0",
16
- "@webstudio-is/sdk": "0.204.0",
17
- "@webstudio-is/sdk-components-react": "0.204.0",
18
- "@webstudio-is/sdk-components-animation": "0.204.0",
19
- "@webstudio-is/sdk-components-react-radix": "0.204.0",
20
- "@webstudio-is/sdk-components-react-remix": "0.204.0",
14
+ "@webstudio-is/image": "0.205.0",
15
+ "@webstudio-is/react-sdk": "0.205.0",
16
+ "@webstudio-is/sdk": "0.205.0",
17
+ "@webstudio-is/sdk-components-react": "0.205.0",
18
+ "@webstudio-is/sdk-components-animation": "0.205.0",
19
+ "@webstudio-is/sdk-components-react-radix": "0.205.0",
20
+ "@webstudio-is/sdk-components-react-remix": "0.205.0",
21
21
  "isbot": "^5.1.22",
22
22
  "react": "18.3.0-canary-14898b6a9-20240318",
23
23
  "react-dom": "18.3.0-canary-14898b6a9-20240318"
@@ -10,13 +10,13 @@
10
10
  "dependencies": {
11
11
  "@react-router/dev": "^7.1.5",
12
12
  "@react-router/fs-routes": "^7.1.5",
13
- "@webstudio-is/image": "0.204.0",
14
- "@webstudio-is/react-sdk": "0.204.0",
15
- "@webstudio-is/sdk": "0.204.0",
16
- "@webstudio-is/sdk-components-animation": "0.204.0",
17
- "@webstudio-is/sdk-components-react-radix": "0.204.0",
18
- "@webstudio-is/sdk-components-react-router": "0.204.0",
19
- "@webstudio-is/sdk-components-react": "0.204.0",
13
+ "@webstudio-is/image": "0.205.0",
14
+ "@webstudio-is/react-sdk": "0.205.0",
15
+ "@webstudio-is/sdk": "0.205.0",
16
+ "@webstudio-is/sdk-components-animation": "0.205.0",
17
+ "@webstudio-is/sdk-components-react-radix": "0.205.0",
18
+ "@webstudio-is/sdk-components-react-router": "0.205.0",
19
+ "@webstudio-is/sdk-components-react": "0.205.0",
20
20
  "isbot": "^5.1.22",
21
21
  "react": "18.3.0-canary-14898b6a9-20240318",
22
22
  "react-dom": "18.3.0-canary-14898b6a9-20240318",
@@ -5,7 +5,7 @@
5
5
  "dependencies": {
6
6
  "@react-router/node": "^7.1.5",
7
7
  "@react-router/serve": "^7.1.5",
8
- "h3": "^1.14.0",
8
+ "h3": "^1.15.0",
9
9
  "ipx": "^3.0.1"
10
10
  }
11
11
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * We use mjs extension as constants in this file is shared with the build script
3
+ * and we use `node --eval` to extract the constants.
4
+ */
5
+ export const assetBaseUrl = "/assets/";
6
+
7
+ /**
8
+ * @type {import("@webstudio-is/image").ImageLoader}
9
+ */
10
+ export const imageLoader = (props) => {
11
+ if (import.meta.env.DEV) {
12
+ return props.src;
13
+ }
14
+
15
+ if (props.format === "raw") {
16
+ return props.src;
17
+ }
18
+
19
+ // https://vercel.com/blog/build-your-own-web-framework#automatic-image-optimization
20
+ const searchParams = new URLSearchParams();
21
+ searchParams.set("url", props.src);
22
+ searchParams.set("w", props.width.toString());
23
+ searchParams.set("q", props.quality.toString());
24
+ return `/_vercel/image?${searchParams}`;
25
+ };
@@ -0,0 +1,9 @@
1
+ {
2
+ "scripts": {
3
+ "deploy": "npx vercel deploy"
4
+ },
5
+ "dependencies": {
6
+ "@react-router/node": "^7.1.5",
7
+ "@vercel/react-router": "^1.0.2"
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ import type { Config } from "@react-router/dev/config";
2
+ import { vercelPreset } from "@vercel/react-router/vite";
3
+
4
+ export default {
5
+ presets: [vercelPreset()],
6
+ } satisfies Config;
@@ -0,0 +1,12 @@
1
+ {
2
+ "framework": "react-router",
3
+ "images": {
4
+ "domains": [],
5
+ "sizes": [
6
+ 16, 32, 48, 64, 96, 128, 144, 256, 384, 640, 750, 828, 1080, 1200, 1920,
7
+ 2048, 3840
8
+ ],
9
+ "minimumCacheTTL": 60,
10
+ "formats": ["image/webp", "image/avif"]
11
+ }
12
+ }
@@ -8,15 +8,15 @@
8
8
  "typecheck": "tsc"
9
9
  },
10
10
  "dependencies": {
11
- "@webstudio-is/image": "0.204.0",
12
- "@webstudio-is/react-sdk": "0.204.0",
13
- "@webstudio-is/sdk": "0.204.0",
14
- "@webstudio-is/sdk-components-react": "0.204.0",
15
- "@webstudio-is/sdk-components-animation": "0.204.0",
16
- "@webstudio-is/sdk-components-react-radix": "0.204.0",
11
+ "@webstudio-is/image": "0.205.0",
12
+ "@webstudio-is/react-sdk": "0.205.0",
13
+ "@webstudio-is/sdk": "0.205.0",
14
+ "@webstudio-is/sdk-components-react": "0.205.0",
15
+ "@webstudio-is/sdk-components-animation": "0.205.0",
16
+ "@webstudio-is/sdk-components-react-radix": "0.205.0",
17
17
  "react": "18.3.0-canary-14898b6a9-20240318",
18
18
  "react-dom": "18.3.0-canary-14898b6a9-20240318",
19
- "vike": "^0.4.220"
19
+ "vike": "^0.4.222"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/react": "^18.2.70",