@standhigher/puck-page-builder 0.8.0 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +22 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -728,6 +728,18 @@ function blockTypeLabel(type, registry) {
728
728
  if (type === "core.image") return "\u56FE\u7247";
729
729
  return registry?.getBlock(type)?.label ?? type;
730
730
  }
731
+ function validateDocumentBlocks(document, registry) {
732
+ if (!registry) return [];
733
+ return document.blocks.flatMap((block) => {
734
+ const definition = registry.getBlock(block.type);
735
+ if (!definition) return [];
736
+ const issues = [...definition.validate?.(block.props) ?? []];
737
+ if (definition.variants?.length && !definition.variants.some((variant) => variant.id === block.variant)) {
738
+ issues.push({ path: "variant", message: `Unsupported variant: ${block.variant}.` });
739
+ }
740
+ return issues.map((issue) => ({ ...issue, path: `${block.id}.${issue.path}` }));
741
+ });
742
+ }
731
743
  function PageDocumentEditorShell(props) {
732
744
  return /* @__PURE__ */ jsx6(EditorProvider, { initialDocument: props.initialDocument, registry: props.registry, loadState: props.loadState, leaveWarning: createAdminI18n(props.adminLocale).t("leaveWarning"), onDocumentChange: props.onDocumentChange, children: /* @__PURE__ */ jsx6(PageDocumentEditor, { ...props }) });
733
745
  }
@@ -741,6 +753,7 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
741
753
  const [notice, setNotice] = useState3(null);
742
754
  const i18n = createAdminI18n(adminLocale);
743
755
  const engineData = useMemo2(() => toEngineData(editor.document, registry), [editor.document, registry]);
756
+ const validationIssues = useMemo2(() => validateDocumentBlocks(editor.document, registry), [editor.document, registry]);
744
757
  const { confirmCanvasSelection, selectedBlockId, updateBlockProps } = editor;
745
758
  const updateFromCanvasInput = useCallback2((id, props, preserveCanvasValue = false) => {
746
759
  if (preserveCanvasValue) setCanvasMutationVersion((version) => version + 1);
@@ -785,7 +798,7 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
785
798
  setDraggingLibraryType(null);
786
799
  };
787
800
  const save = async () => {
788
- if (!onSave || request !== "idle") return;
801
+ if (!onSave || request !== "idle" || validationIssues.length > 0) return;
789
802
  setRequest("saving");
790
803
  setNotice(null);
791
804
  try {
@@ -798,7 +811,7 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
798
811
  }
799
812
  };
800
813
  const publish = async () => {
801
- if (!onPublish || request !== "idle") return;
814
+ if (!onPublish || request !== "idle" || validationIssues.length > 0) return;
802
815
  setRequest("publishing");
803
816
  setNotice(null);
804
817
  try {
@@ -826,14 +839,19 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
826
839
  ] }),
827
840
  /* @__PURE__ */ jsxs4(InlineStack2, { gap: "150", blockAlign: "center", wrap: false, children: [
828
841
  /* @__PURE__ */ jsx6(Badge2, { tone: editor.isDirty ? "attention" : "success", children: editor.isDirty ? i18n.t("unsaved") : i18n.t("saved") }),
829
- /* @__PURE__ */ jsx6(Button2, { disabled: !onSave || !editor.isDirty || request !== "idle", onClick: () => void save(), children: request === "saving" ? i18n.t("saving") : i18n.t("save") }),
830
- /* @__PURE__ */ jsx6(Button2, { variant: "primary", disabled: !onPublish || request !== "idle", onClick: () => void publish(), children: request === "publishing" ? i18n.t("publishing") : i18n.t("publish") }),
842
+ /* @__PURE__ */ jsx6(Button2, { disabled: !onSave || !editor.isDirty || request !== "idle" || validationIssues.length > 0, onClick: () => void save(), children: request === "saving" ? i18n.t("saving") : i18n.t("save") }),
843
+ /* @__PURE__ */ jsx6(Button2, { variant: "primary", disabled: !onPublish || request !== "idle" || validationIssues.length > 0, onClick: () => void publish(), children: request === "publishing" ? i18n.t("publishing") : i18n.t("publish") }),
831
844
  /* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("undo"), icon: UndoIcon2, variant: "tertiary", disabled: !editor.actionState.canUndo, onClick: editor.undo }),
832
845
  /* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("redo"), icon: RedoIcon2, variant: "tertiary", disabled: !editor.actionState.canRedo, onClick: editor.redo })
833
846
  ] })
834
847
  ] }) }),
835
848
  editor.loadState === "success" ? /* @__PURE__ */ jsx6(Banner, { tone: "success", children: i18n.t("success") }) : null,
836
849
  notice ? /* @__PURE__ */ jsx6(Banner, { tone: notice === "published" ? "success" : "critical", children: i18n.t(notice) }) : null,
850
+ validationIssues.length > 0 ? /* @__PURE__ */ jsx6(Banner, { tone: "critical", title: "\u533A\u5757\u5C5E\u6027\u672A\u901A\u8FC7\u6821\u9A8C", children: /* @__PURE__ */ jsx6("ul", { children: validationIssues.map((issue) => /* @__PURE__ */ jsxs4("li", { children: [
851
+ issue.path,
852
+ ": ",
853
+ issue.message
854
+ ] }, `${issue.path}-${issue.message}`)) }) }) : null,
837
855
  /* @__PURE__ */ jsxs4("div", { className: "pb-workspace pb-workspace--document", children: [
838
856
  /* @__PURE__ */ jsxs4("nav", { className: "pb-tool-rail", "aria-label": "\u7F16\u8F91\u5668\u5DE5\u5177", children: [
839
857
  /* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("blocks"), icon: LayoutSectionIcon2, pressed: blockView === "blocks", variant: "tertiary", onClick: () => setBlockView("blocks") }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@standhigher/puck-page-builder",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "React PageDocument editor, extension registry, and web renderer for BestTrack page experiences.",
5
5
  "type": "module",
6
6
  "repository": {