@gravity-ui/page-constructor 4.40.6 → 4.41.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 (74) hide show
  1. package/build/cjs/editor/components/CodeEditor/CodeEditor.css +56 -0
  2. package/build/cjs/editor/components/CodeEditor/CodeEditor.d.ts +12 -0
  3. package/build/cjs/editor/components/CodeEditor/CodeEditor.js +31 -0
  4. package/build/cjs/editor/components/CodeEditor/constants.d.ts +2 -0
  5. package/build/cjs/editor/components/CodeEditor/constants.js +20 -0
  6. package/build/cjs/editor/components/Layout/Layout.css +2 -1
  7. package/build/cjs/editor/containers/Editor/Editor.js +9 -5
  8. package/build/cjs/editor/containers/Form/Form.css +5 -2
  9. package/build/cjs/editor/containers/Form/Form.d.ts +10 -3
  10. package/build/cjs/editor/containers/Form/Form.js +12 -16
  11. package/build/cjs/editor/hooks/useCodeValidator.d.ts +4 -0
  12. package/build/cjs/editor/hooks/useCodeValidator.js +10 -0
  13. package/build/cjs/editor/hooks/useFormSpec.d.ts +2 -2
  14. package/build/cjs/editor/hooks/useFormSpec.js +2 -6
  15. package/build/cjs/editor/store/main/index.d.ts +12 -0
  16. package/build/cjs/editor/store/{index.js → main/index.js} +10 -16
  17. package/build/cjs/editor/store/{reducer.d.ts → main/reducer.d.ts} +5 -15
  18. package/build/cjs/editor/store/{reducer.js → main/reducer.js} +1 -7
  19. package/build/cjs/editor/store/{utils.d.ts → main/utils.d.ts} +3 -3
  20. package/build/cjs/editor/store/settings/index.d.ts +12 -0
  21. package/build/cjs/editor/store/settings/index.js +21 -0
  22. package/build/cjs/editor/store/settings/reducer.d.ts +37 -0
  23. package/build/cjs/editor/store/settings/reducer.js +32 -0
  24. package/build/cjs/editor/styles/root.css +2 -1
  25. package/build/cjs/editor/types/index.d.ts +5 -0
  26. package/build/cjs/editor/types/index.js +7 -1
  27. package/build/cjs/editor/utils/code.d.ts +6 -0
  28. package/build/cjs/editor/utils/code.js +11 -0
  29. package/build/cjs/editor/utils/validation.d.ts +13 -0
  30. package/build/cjs/editor/utils/validation.js +57 -0
  31. package/build/esm/editor/components/CodeEditor/CodeEditor.css +56 -0
  32. package/build/esm/editor/components/CodeEditor/CodeEditor.d.ts +13 -0
  33. package/build/esm/editor/components/CodeEditor/CodeEditor.js +27 -0
  34. package/build/esm/editor/components/CodeEditor/constants.d.ts +2 -0
  35. package/build/esm/editor/components/CodeEditor/constants.js +17 -0
  36. package/build/esm/editor/components/Layout/Layout.css +2 -1
  37. package/build/esm/editor/containers/Editor/Editor.js +9 -5
  38. package/build/esm/editor/containers/Form/Form.css +5 -2
  39. package/build/esm/editor/containers/Form/Form.d.ts +10 -3
  40. package/build/esm/editor/containers/Form/Form.js +9 -13
  41. package/build/esm/editor/hooks/useCodeValidator.d.ts +4 -0
  42. package/build/esm/editor/hooks/useCodeValidator.js +6 -0
  43. package/build/esm/editor/hooks/useFormSpec.d.ts +2 -2
  44. package/build/esm/editor/hooks/useFormSpec.js +2 -6
  45. package/build/esm/editor/store/main/index.d.ts +12 -0
  46. package/build/esm/editor/store/{index.js → main/index.js} +9 -15
  47. package/build/esm/editor/store/{reducer.d.ts → main/reducer.d.ts} +5 -15
  48. package/build/esm/editor/store/{reducer.js → main/reducer.js} +0 -6
  49. package/build/esm/editor/store/{utils.d.ts → main/utils.d.ts} +3 -3
  50. package/build/esm/editor/store/settings/index.d.ts +12 -0
  51. package/build/esm/editor/store/settings/index.js +17 -0
  52. package/build/esm/editor/store/settings/reducer.d.ts +37 -0
  53. package/build/esm/editor/store/settings/reducer.js +28 -0
  54. package/build/esm/editor/styles/root.css +2 -1
  55. package/build/esm/editor/types/index.d.ts +5 -0
  56. package/build/esm/editor/types/index.js +6 -0
  57. package/build/esm/editor/utils/code.d.ts +6 -0
  58. package/build/esm/editor/utils/code.js +6 -0
  59. package/build/esm/editor/utils/validation.d.ts +13 -0
  60. package/build/esm/editor/utils/validation.js +51 -0
  61. package/package.json +4 -1
  62. package/styles/styles.css +1 -0
  63. package/styles/styles.scss +1 -0
  64. package/widget/index.js +1 -1
  65. package/build/cjs/editor/components/YamlEditor/YamlEditor.css +0 -12
  66. package/build/cjs/editor/components/YamlEditor/YamlEditor.d.ts +0 -6
  67. package/build/cjs/editor/components/YamlEditor/YamlEditor.js +0 -34
  68. package/build/cjs/editor/store/index.d.ts +0 -16
  69. package/build/esm/editor/components/YamlEditor/YamlEditor.css +0 -12
  70. package/build/esm/editor/components/YamlEditor/YamlEditor.d.ts +0 -7
  71. package/build/esm/editor/components/YamlEditor/YamlEditor.js +0 -30
  72. package/build/esm/editor/store/index.d.ts +0 -16
  73. /package/build/cjs/editor/store/{utils.js → main/utils.js} +0 -0
  74. /package/build/esm/editor/store/{utils.js → main/utils.js} +0 -0
@@ -0,0 +1,13 @@
1
+ import { ValidateFunction } from 'ajv';
2
+ import { JSONSchema4 } from 'json-schema';
3
+ export interface CodeEditorMessageProps {
4
+ text: string;
5
+ status: CodeEditorMessageStatus;
6
+ }
7
+ export declare enum CodeEditorMessageStatus {
8
+ SUCCESS = "success",
9
+ WARNING = "warning",
10
+ ERROR = "error"
11
+ }
12
+ export declare function createValidator(schema: JSONSchema4): ValidateFunction<unknown>;
13
+ export declare function validate(content: string, validator: ValidateFunction): CodeEditorMessageProps;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validate = exports.createValidator = exports.CodeEditorMessageStatus = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const ajv_1 = tslib_1.__importDefault(require("ajv"));
6
+ const ajv_keywords_1 = tslib_1.__importDefault(require("ajv-keywords"));
7
+ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
8
+ const js_yaml_source_map_1 = tslib_1.__importDefault(require("js-yaml-source-map"));
9
+ const isArray_1 = tslib_1.__importDefault(require("lodash/isArray"));
10
+ const SUCCESS_MESSAGE = 'Valid';
11
+ var CodeEditorMessageStatus;
12
+ (function (CodeEditorMessageStatus) {
13
+ CodeEditorMessageStatus["SUCCESS"] = "success";
14
+ CodeEditorMessageStatus["WARNING"] = "warning";
15
+ CodeEditorMessageStatus["ERROR"] = "error";
16
+ })(CodeEditorMessageStatus = exports.CodeEditorMessageStatus || (exports.CodeEditorMessageStatus = {}));
17
+ function createValidator(schema) {
18
+ const ajv = new ajv_1.default({ $data: true, allErrors: true, schemas: [schema], strict: false });
19
+ // TODO: select is deprecated, replace with discriminator:
20
+ // https://github.com/ajv-validator/ajv-keywords#selectselectcasesselectdefault
21
+ (0, ajv_keywords_1.default)(ajv, 'select');
22
+ return ajv.compile(schema);
23
+ }
24
+ exports.createValidator = createValidator;
25
+ function validate(content, validator) {
26
+ let result;
27
+ if (!content) {
28
+ return { status: CodeEditorMessageStatus.SUCCESS, text: SUCCESS_MESSAGE };
29
+ }
30
+ try {
31
+ const jsYamlMap = new js_yaml_source_map_1.default();
32
+ const data = js_yaml_1.default.load(content, { listener: jsYamlMap.listen() });
33
+ validator(data);
34
+ if (validator.errors) {
35
+ const messages = validator.errors.map(({ instancePath, schemaPath, message, params }) => {
36
+ const pointer = jsYamlMap.lookup(instancePath.split('/').filter(Boolean));
37
+ const stringParams = Object.entries(params).map(([key, value]) => {
38
+ if ((0, isArray_1.default)(value)) {
39
+ return `${key}: ${value.join(' | ')}`;
40
+ }
41
+ return `${key}: ${value}`;
42
+ });
43
+ const ref = pointer ? `${pointer.line}: ` : '';
44
+ return `${ref}${instancePath || schemaPath}: ${message}\n${stringParams.join('\n')}`;
45
+ });
46
+ result = { status: CodeEditorMessageStatus.WARNING, text: messages.join('\n\n') };
47
+ }
48
+ else {
49
+ result = { status: CodeEditorMessageStatus.SUCCESS, text: SUCCESS_MESSAGE };
50
+ }
51
+ }
52
+ catch ({ message }) {
53
+ result = { status: CodeEditorMessageStatus.ERROR, text: message };
54
+ }
55
+ return result;
56
+ }
57
+ exports.validate = validate;
@@ -0,0 +1,56 @@
1
+ .pc-code-editor {
2
+ height: 100%;
3
+ position: relative;
4
+ overflow: hidden;
5
+ }
6
+ .pc-code-editor_fullscreen {
7
+ position: fixed;
8
+ top: 0;
9
+ left: 0;
10
+ width: 100%;
11
+ height: 100vh;
12
+ z-index: 1000;
13
+ background: var(--g-color-base-background);
14
+ }
15
+ .pc-code-editor_fullscreen .pc-code-editor__header {
16
+ margin-top: var(--pc-editor-header-height);
17
+ }
18
+ .pc-code-editor__code {
19
+ width: 100%;
20
+ height: 100%;
21
+ }
22
+ .pc-code-editor__header, .pc-code-editor__footer {
23
+ padding: 0 20px;
24
+ background: var(--g-color-base-background);
25
+ }
26
+ .pc-code-editor__header {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: flex-end;
30
+ height: var(--pc-editor-code-header-height);
31
+ border-bottom: 1px solid var(--g-color-line-generic);
32
+ }
33
+ .pc-code-editor__footer {
34
+ position: absolute;
35
+ left: 0;
36
+ bottom: 0;
37
+ width: 100%;
38
+ min-height: var(--pc-editor-code-header-height);
39
+ border-top: 1px solid var(--g-color-line-generic);
40
+ }
41
+ .pc-code-editor__message-container {
42
+ max-height: 140px;
43
+ padding: 12px;
44
+ overflow-y: auto;
45
+ font-family: Menlo, Monaco, "Courier New", monospace;
46
+ white-space: pre-wrap;
47
+ }
48
+ .pc-code-editor__message_status_success {
49
+ color: var(--g-color-text-positive);
50
+ }
51
+ .pc-code-editor__message_status_warning {
52
+ color: var(--g-color-text-warning-heavy);
53
+ }
54
+ .pc-code-editor__message_status_error {
55
+ color: var(--g-color-text-danger);
56
+ }
@@ -0,0 +1,13 @@
1
+ import { PageContent } from '../../../models';
2
+ import { CodeEditorMessageProps } from '../../utils/validation';
3
+ import './CodeEditor.css';
4
+ interface CodeEditorProps {
5
+ content: PageContent;
6
+ fullscreenModeOn: boolean;
7
+ validator: (code: string) => CodeEditorMessageProps;
8
+ onFullscreenModeOnUpdate: (fullscreenModeOn: boolean) => void;
9
+ onChange: (content: PageContent) => void;
10
+ message?: CodeEditorMessageProps;
11
+ }
12
+ export declare const CodeEditor: ({ content, onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, }: CodeEditorProps) => JSX.Element;
13
+ export {};
@@ -0,0 +1,27 @@
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
+ import { ChevronsCollapseUpRight, ChevronsExpandUpRight } from '@gravity-ui/icons';
3
+ import { Button, Icon } from '@gravity-ui/uikit';
4
+ import yaml from 'js-yaml';
5
+ import MonacoEditor from 'react-monaco-editor';
6
+ import { block } from '../../../utils';
7
+ import { parseCode } from '../../utils/code';
8
+ import { options } from './constants';
9
+ import './CodeEditor.css';
10
+ const b = block('code-editor');
11
+ export const CodeEditor = ({ content, onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, }) => {
12
+ const value = useMemo(() => yaml.dump(content), [content]);
13
+ const [message, setMessage] = useState(() => validator(value));
14
+ const onChangeWithValidation = useCallback((code) => {
15
+ const validationResult = validator(code);
16
+ setMessage(validationResult);
17
+ onChange(parseCode(code));
18
+ }, [onChange, validator]);
19
+ return (React.createElement("div", { className: b({ fullscreen: fullscreenModeOn }) },
20
+ React.createElement("div", { className: b('header') },
21
+ React.createElement(Button, { view: "flat-secondary", onClick: () => onFullscreenModeOnUpdate(!fullscreenModeOn) },
22
+ React.createElement(Icon, { data: fullscreenModeOn ? ChevronsCollapseUpRight : ChevronsExpandUpRight, size: 16 }))),
23
+ React.createElement("div", { className: b('code') },
24
+ React.createElement(MonacoEditor, { key: String(fullscreenModeOn), value: value, language: "yaml", options: options, onChange: onChangeWithValidation, theme: "vs" })),
25
+ React.createElement("div", { className: b('footer') }, message && (React.createElement("div", { className: b('message-container') },
26
+ React.createElement("div", { className: b('message', { status: message.status }) }, message.text))))));
27
+ };
@@ -0,0 +1,2 @@
1
+ import { monaco } from 'react-monaco-editor';
2
+ export declare const options: monaco.editor.IStandaloneEditorConstructionOptions;
@@ -0,0 +1,17 @@
1
+ export const options = {
2
+ wordWrap: 'on',
3
+ renderLineHighlight: 'none',
4
+ selectOnLineNumbers: true,
5
+ renderWhitespace: 'all',
6
+ automaticLayout: true,
7
+ minimap: {
8
+ enabled: false,
9
+ },
10
+ overviewRulerLanes: 0,
11
+ hideCursorInOverviewRuler: true,
12
+ scrollbar: {
13
+ vertical: 'hidden',
14
+ },
15
+ overviewRulerBorder: false,
16
+ readOnly: false,
17
+ };
@@ -2,11 +2,12 @@
2
2
  unpredictable css rules order in build */
3
3
  body {
4
4
  --pc-editor-header-height: 48px;
5
+ --pc-editor-code-header-height: 36px;
5
6
  --pc-editor-divider-width: 12px;
7
+ --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
6
8
  --pc-editor-base-color: var(--g-color-base-brand);
7
9
  --pc-editor-control-color: var(--g-color-base-brand);
8
10
  --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
9
- --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
10
11
  }
11
12
 
12
13
  .pc-editor-layout__left, .pc-editor-layout__right {
@@ -1,23 +1,27 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useEffect, useMemo } from 'react';
3
3
  import { PageConstructor, PageConstructorProvider } from '../../../containers/PageConstructor';
4
+ import { generateDefaultSchema } from '../../../schema';
4
5
  import AddBlock from '../../components/AddBlock/AddBlock';
5
6
  import EditBlock from '../../components/EditBlock/EditBlock';
6
7
  import { ErrorBoundary } from '../../components/ErrorBoundary/ErrorBoundary';
7
8
  import Layout from '../../components/Layout/Layout';
8
9
  import { NotFoundBlock } from '../../components/NotFoundBlock/NotFoundBlock';
9
10
  import { EditorContext } from '../../context';
10
- import useFormSpec from '../../hooks/useFormSpec';
11
- import { useEditorState } from '../../store';
11
+ import { useCodeValidator } from '../../hooks/useCodeValidator';
12
+ import { useMainState } from '../../store/main';
13
+ import { useSettingsState } from '../../store/settings';
12
14
  import { ViewModeItem } from '../../types';
13
15
  import { addCustomDecorator, checkIsMobile, getBlockId } from '../../utils';
14
16
  import { Form } from '../Form/Form';
15
17
  export const Editor = (_a) => {
16
18
  var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings"]);
17
- const { content, activeBlockIndex, errorBoundaryState, viewMode, theme, onContentUpdate, onViewModeUpdate, onAdd, onSelect, injectEditBlockProps, onThemeUpdate, } = useEditorState(rest);
18
- const formSpecs = useFormSpec(customSchema);
19
+ const { content, activeBlockIndex, errorBoundaryState, onContentUpdate, onAdd, onSelect, injectEditBlockProps, } = useMainState(rest);
20
+ const { viewMode, theme, onViewModeUpdate, onThemeUpdate, formTab, onFormTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, } = useSettingsState();
19
21
  const isEditingMode = viewMode === ViewModeItem.Edititng;
20
22
  const transformedContent = useMemo(() => (transformContent ? transformContent(content, { viewMode }) : content), [content, transformContent, viewMode]);
23
+ const schema = useMemo(() => generateDefaultSchema(customSchema), [customSchema]);
24
+ const codeValidator = useCodeValidator(schema);
21
25
  const outgoingProps = useMemo(() => {
22
26
  const custom = isEditingMode
23
27
  ? addCustomDecorator([
@@ -54,7 +58,7 @@ export const Editor = (_a) => {
54
58
  return (React.createElement(EditorContext.Provider, { value: context },
55
59
  React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate, theme: theme, onThemeChange: onThemeUpdate },
56
60
  isEditingMode && (React.createElement(Layout.Left, null,
57
- React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, onSelect: onSelect, spec: formSpecs }))),
61
+ React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, activeTab: formTab, codeFullscreeModeOn: codeFullscreeModeOn, schema: schema, codeValidator: codeValidator, onActiveTabUpdate: onFormTabUpdate, onCodeFullscreeModeOnUpdate: onCodeFullscreeModeOnUpdate, onSelect: onSelect }))),
58
62
  React.createElement(Layout.Right, null,
59
63
  React.createElement(ErrorBoundary, { key: errorBoundaryState },
60
64
  React.createElement(PageConstructorProvider, Object.assign({}, providerProps, { theme: theme }),
@@ -89,6 +89,9 @@ unpredictable css rules order in build */
89
89
  .pc-editor-form__block-form {
90
90
  margin-bottom: 16px;
91
91
  }
92
- .pc-editor-form_yaml-editor-enabled {
93
- height: 100%;
92
+ .pc-editor-form_code-editor-active {
93
+ height: calc(100% - var(--pc-editor-code-header-height));
94
+ }
95
+ .pc-editor-form_code-editor-active .pc-editor-form__tabs {
96
+ margin-bottom: 0;
94
97
  }
@@ -1,12 +1,19 @@
1
1
  import React from 'react';
2
+ import { JSONSchema4 } from 'json-schema';
2
3
  import { PageContent } from '../../../models';
3
- import { FormSpecs } from '../../dynamic-forms-custom/parser/types';
4
+ import { FormTab } from '../../types';
5
+ import { CodeEditorMessageProps } from '../../utils/validation';
4
6
  import './Form.css';
5
7
  export interface FormProps {
6
8
  content: PageContent;
9
+ schema: JSONSchema4;
7
10
  activeBlockIndex: number;
8
- spec: FormSpecs;
11
+ activeTab: FormTab;
12
+ codeFullscreeModeOn: boolean;
13
+ onActiveTabUpdate: (tab: FormTab) => void;
14
+ onCodeFullscreeModeOnUpdate: (codeFullscreeModeOn: boolean) => void;
15
+ codeValidator: (code: string) => CodeEditorMessageProps;
9
16
  onChange: (content: PageContent) => void;
10
17
  onSelect: (index: number) => void;
11
18
  }
12
- export declare const Form: React.MemoExoticComponent<({ content, onChange, activeBlockIndex, onSelect, spec }: FormProps) => JSX.Element>;
19
+ export declare const Form: React.MemoExoticComponent<({ content, onChange, activeBlockIndex, onSelect, schema, codeValidator, activeTab, onActiveTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, }: FormProps) => JSX.Element>;
@@ -3,23 +3,19 @@ import React, { Fragment, memo } from 'react';
3
3
  import { Tabs } from '@gravity-ui/uikit';
4
4
  import { block, getBlockKey } from '../../../utils';
5
5
  import { BlockForm } from '../../components/BlockForm/BlockForm';
6
+ import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
6
7
  import { PagePropsForm } from '../../components/PagePropsForm/PagePropsForm';
7
- import { YamlEditor } from '../../components/YamlEditor/YamlEditor';
8
+ import useFormSpec from '../../hooks/useFormSpec';
9
+ import { FormTab } from '../../types';
8
10
  import './Form.css';
9
- var FormTab;
10
- (function (FormTab) {
11
- FormTab["Blocks"] = "blocks";
12
- FormTab["Page"] = "page";
13
- FormTab["Yaml"] = "yaml";
14
- })(FormTab || (FormTab = {}));
15
11
  const b = block('editor-form');
16
12
  const tabsItems = Object.values(FormTab).map((tab) => ({
17
13
  id: tab,
18
14
  title: tab,
19
15
  }));
20
- export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, spec }) => {
21
- const [activeTab, setActiveTab] = React.useState(FormTab.Blocks);
16
+ export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, schema, codeValidator, activeTab, onActiveTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, }) => {
22
17
  const _a = content || {}, { blocks } = _a, page = __rest(_a, ["blocks"]);
18
+ const spec = useFormSpec(schema);
23
19
  const { blocks: blocksSpec, page: pageSpec } = spec || {};
24
20
  let form;
25
21
  switch (activeTab) {
@@ -40,13 +36,13 @@ export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, spec
40
36
  }, onSelect: () => onSelect(index) }))) : null)));
41
37
  break;
42
38
  }
43
- case FormTab.Yaml: {
44
- form = React.createElement(YamlEditor, { content: content });
39
+ case FormTab.Code: {
40
+ form = (React.createElement(CodeEditor, { content: content, onChange: onChange, validator: codeValidator, fullscreenModeOn: codeFullscreeModeOn, onFullscreenModeOnUpdate: onCodeFullscreeModeOnUpdate }));
45
41
  break;
46
42
  }
47
43
  }
48
- return (React.createElement("div", { className: b({ 'yaml-editor-enabled': activeTab === FormTab.Yaml }) },
49
- React.createElement(Tabs, { activeTab: activeTab, className: b('tabs'), items: tabsItems, onSelectTab: setActiveTab }),
44
+ return (React.createElement("div", { className: b({ 'code-editor-active': activeTab === FormTab.Code }) },
45
+ React.createElement(Tabs, { activeTab: activeTab, className: b('tabs'), items: tabsItems, onSelectTab: onActiveTabUpdate }),
50
46
  form));
51
47
  });
52
48
  Form.displayName = 'Form';
@@ -0,0 +1,4 @@
1
+ import { JSONSchema4 } from 'json-schema';
2
+ import { CodeEditorMessageProps } from '../utils/validation';
3
+ export type CodeValidator = (code: string) => CodeEditorMessageProps;
4
+ export declare function useCodeValidator(schema: JSONSchema4): CodeValidator;
@@ -0,0 +1,6 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { createValidator, validate } from '../utils/validation';
3
+ export function useCodeValidator(schema) {
4
+ const validator = useMemo(() => createValidator(schema), [schema]);
5
+ return useCallback((code) => validate(code, validator), [validator]);
6
+ }
@@ -1,2 +1,2 @@
1
- import { SchemaCustomConfig } from '../../schema';
2
- export default function useFormSpec(customSchema?: SchemaCustomConfig): import("../dynamic-forms-custom/parser/types").FormSpecs;
1
+ import { JSONSchema4 } from 'json-schema';
2
+ export default function useFormSpec(schema: JSONSchema4): import("../dynamic-forms-custom/parser/types").FormSpecs;
@@ -1,9 +1,5 @@
1
1
  import { useMemo } from 'react';
2
- import { generateDefaultSchema } from '../../schema';
3
2
  import formSpecParser from '../dynamic-forms-custom/parser';
4
- export default function useFormSpec(customSchema) {
5
- return useMemo(() => {
6
- const schema = generateDefaultSchema(customSchema);
7
- return formSpecParser.parse(schema);
8
- }, [customSchema]);
3
+ export default function useFormSpec(schema) {
4
+ return useMemo(() => formSpecParser.parse(schema), [schema]);
9
5
  }
@@ -0,0 +1,12 @@
1
+ import { Block, BlockDecorationProps, PageContent } from '../../../models';
2
+ import { EditBlockProps, EditorProps } from '../../types';
3
+ export type EditorBlockId = number | string;
4
+ export declare function useMainState({ content: intialContent, custom }: Omit<EditorProps, 'children'>): {
5
+ activeBlockIndex: number;
6
+ content: PageContent;
7
+ errorBoundaryState: number;
8
+ injectEditBlockProps: ({ type, index: relativeIndex, children, ...rest }: BlockDecorationProps) => EditBlockProps;
9
+ onAdd: (block: Block) => void;
10
+ onSelect: (index: number) => void;
11
+ onContentUpdate: (newContent: PageContent) => void;
12
+ };
@@ -1,14 +1,14 @@
1
1
  import { __rest } from "tslib";
2
2
  import { useMemo, useReducer } from 'react';
3
- import { DEFAULT_THEME } from '../../components/constants';
4
- import { HeaderBlockTypes } from '../../models';
5
- import { getCustomTypes, getHeaderBlock } from '../../utils';
6
- import { EditBlockControls } from '../components/EditBlock/EditBlock';
7
- import { ViewModeItem } from '../types';
8
- import { ADD_BLOCK, COPY_BLOCK, DELETE_BLOCK, ORDER_BLOCK, SELECT_BLOCK, UPDATE_CONTENT, UPDATE_THEME, UPDATE_VIEW_MODE, reducer, } from './reducer';
3
+ import { DEFAULT_THEME } from '../../../components/constants';
4
+ import { HeaderBlockTypes } from '../../../models';
5
+ import { getCustomTypes, getHeaderBlock } from '../../../utils';
6
+ import { EditBlockControls } from '../../components/EditBlock/EditBlock';
7
+ import { ViewModeItem } from '../../types';
8
+ import { ADD_BLOCK, COPY_BLOCK, DELETE_BLOCK, ORDER_BLOCK, SELECT_BLOCK, UPDATE_CONTENT, reducer, } from './reducer';
9
9
  import { addEditorProps } from './utils';
10
- export function useEditorState({ content: intialContent, custom }) {
11
- const [{ activeBlockIndex, content, errorBoundaryState, viewMode, theme }, dispatch] = useReducer(reducer, {
10
+ export function useMainState({ content: intialContent, custom }) {
11
+ const [{ activeBlockIndex, content, errorBoundaryState }, dispatch] = useReducer(reducer, {
12
12
  activeBlockIndex: 0,
13
13
  errorBoundaryState: 0,
14
14
  content: addEditorProps(intialContent),
@@ -35,8 +35,6 @@ export function useEditorState({ content: intialContent, custom }) {
35
35
  };
36
36
  const onSelect = (index) => dispatch({ type: SELECT_BLOCK, payload: index });
37
37
  const onContentUpdate = (newContent) => dispatch({ type: UPDATE_CONTENT, payload: newContent });
38
- const onViewModeUpdate = (newViewMode) => dispatch({ type: UPDATE_VIEW_MODE, payload: newViewMode });
39
- const onThemeUpdate = (newTheme) => dispatch({ type: UPDATE_THEME, payload: newTheme });
40
38
  const injectEditBlockProps = (_a) => {
41
39
  var { type, index: relativeIndex = 0, children } = _a, rest = __rest(_a, ["type", "index", "children"]);
42
40
  const orderedBlocksStartIndex = contentHasHeader ? 1 : 0;
@@ -70,14 +68,10 @@ export function useEditorState({ content: intialContent, custom }) {
70
68
  activeBlockIndex,
71
69
  content,
72
70
  errorBoundaryState,
73
- viewMode,
74
- theme,
75
71
  injectEditBlockProps,
76
72
  onAdd,
77
73
  onSelect,
78
74
  onContentUpdate,
79
- onViewModeUpdate,
80
- onThemeUpdate,
81
75
  };
82
- }, [content, activeBlockIndex, errorBoundaryState, custom, viewMode, theme]);
76
+ }, [content, activeBlockIndex, errorBoundaryState, custom]);
83
77
  }
@@ -1,7 +1,7 @@
1
- import { ConstructorBlock, PageContent, Theme } from '../../models';
2
- import { ViewModeItem } from '../types';
1
+ import { ConstructorBlock, PageContent, Theme } from '../../../models';
2
+ import { ViewModeItem } from '../../types';
3
3
  export type EditorBlockId = number | string;
4
- interface EditorState {
4
+ interface MainState {
5
5
  content: PageContent;
6
6
  activeBlockIndex: number;
7
7
  errorBoundaryState: number;
@@ -23,8 +23,6 @@ export declare const ADD_BLOCK = "ADD_BLOCK";
23
23
  export declare const SET_REGION = "SET_REGION";
24
24
  export declare const ORDER_BLOCK = "ORDER_BLOCK";
25
25
  export declare const UPDATE_CONTENT = "UPDATE_CONTENT";
26
- export declare const UPDATE_VIEW_MODE = "UPDATE_VIEW_MODE";
27
- export declare const UPDATE_THEME = "UPDATE_THEME";
28
26
  interface SelectBlock {
29
27
  type: typeof SELECT_BLOCK;
30
28
  payload: number;
@@ -49,14 +47,6 @@ interface UpdateContent {
49
47
  type: typeof UPDATE_CONTENT;
50
48
  payload: PageContent;
51
49
  }
52
- interface UpdateViewMode {
53
- type: typeof UPDATE_VIEW_MODE;
54
- payload: ViewModeItem;
55
- }
56
- interface UpdateTheme {
57
- type: typeof UPDATE_THEME;
58
- payload: Theme;
59
- }
60
- export type EditorAction = SelectBlock | DeleteBlock | CopyBlock | AddBlock | OrderBlock | UpdateContent | UpdateViewMode | UpdateTheme;
61
- export declare const reducer: (state: EditorState, action: EditorAction) => EditorState;
50
+ export type EditorAction = SelectBlock | DeleteBlock | CopyBlock | AddBlock | OrderBlock | UpdateContent;
51
+ export declare const reducer: (state: MainState, action: EditorAction) => MainState;
62
52
  export {};
@@ -7,8 +7,6 @@ export const ADD_BLOCK = 'ADD_BLOCK';
7
7
  export const SET_REGION = 'SET_REGION';
8
8
  export const ORDER_BLOCK = 'ORDER_BLOCK';
9
9
  export const UPDATE_CONTENT = 'UPDATE_CONTENT';
10
- export const UPDATE_VIEW_MODE = 'UPDATE_VIEW_MODE';
11
- export const UPDATE_THEME = 'UPDATE_THEME';
12
10
  // reducer
13
11
  export const reducer = (state, action) => {
14
12
  const { content } = state;
@@ -34,10 +32,6 @@ export const reducer = (state, action) => {
34
32
  const { oldIndex, newIndex } = action.payload;
35
33
  return getNewState(changeBlocksOrder(content.blocks, oldIndex, newIndex), newIndex);
36
34
  }
37
- case UPDATE_VIEW_MODE:
38
- return Object.assign(Object.assign({}, state), { viewMode: action.payload });
39
- case UPDATE_THEME:
40
- return Object.assign(Object.assign({}, state), { theme: action.payload });
41
35
  default:
42
36
  return state;
43
37
  }
@@ -1,4 +1,4 @@
1
- import { ConstructorBlock, PageContent } from '../../models';
1
+ import { ConstructorBlock, PageContent } from '../../../models';
2
2
  import { EditorBlockId } from './reducer';
3
3
  export declare const changeBlocksOrder: (array: ConstructorBlock[], oldIndex: number, newIndex: number) => ConstructorBlock[];
4
4
  export declare const duplicateBlock: (array: ConstructorBlock[], index: number) => ConstructorBlock[];
@@ -7,7 +7,7 @@ export declare const addBlock: (array: ConstructorBlock[], block: ConstructorBlo
7
7
  export declare const addEditorProps: (content: PageContent) => {
8
8
  animated: boolean;
9
9
  blocks: ConstructorBlock[];
10
- menu?: import("../../models").Menu | undefined;
11
- background?: import("../../models").ThemedMediaProps | undefined;
10
+ menu?: import("../../../models").Menu | undefined;
11
+ background?: import("../../../models").ThemedMediaProps | undefined;
12
12
  };
13
13
  export declare const getErrorBoundaryState: (prevState: number) => number;
@@ -0,0 +1,12 @@
1
+ import { Theme } from '../../../models';
2
+ import { FormTab, ViewModeItem } from '../../types';
3
+ export declare function useSettingsState(): {
4
+ formTab: FormTab;
5
+ viewMode: ViewModeItem;
6
+ theme: Theme;
7
+ codeFullscreeModeOn: boolean;
8
+ onFormTabUpdate: (newFormTab: FormTab) => void;
9
+ onViewModeUpdate: (newViewMode: ViewModeItem) => void;
10
+ onThemeUpdate: (newTheme: Theme) => void;
11
+ onCodeFullscreeModeOnUpdate: (newCodeFullscreeModeOn: boolean) => void;
12
+ };
@@ -0,0 +1,17 @@
1
+ import { useMemo, useReducer } from 'react';
2
+ import { UPDATE_CODE_FULLSCREEN_MODE_ON, UPDATE_FORM_TAB, UPDATE_THEME, UPDATE_VIEW_MODE, initialState, reducer, } from './reducer';
3
+ export function useSettingsState() {
4
+ const [{ formTab, viewMode, theme, codeFullscreeModeOn }, dispatch] = useReducer(reducer, initialState);
5
+ return useMemo(() => {
6
+ return {
7
+ formTab,
8
+ viewMode,
9
+ theme,
10
+ codeFullscreeModeOn,
11
+ onFormTabUpdate: (newFormTab) => dispatch({ type: UPDATE_FORM_TAB, payload: newFormTab }),
12
+ onViewModeUpdate: (newViewMode) => dispatch({ type: UPDATE_VIEW_MODE, payload: newViewMode }),
13
+ onThemeUpdate: (newTheme) => dispatch({ type: UPDATE_THEME, payload: newTheme }),
14
+ onCodeFullscreeModeOnUpdate: (newCodeFullscreeModeOn) => dispatch({ type: UPDATE_CODE_FULLSCREEN_MODE_ON, payload: newCodeFullscreeModeOn }),
15
+ };
16
+ }, [formTab, viewMode, theme, codeFullscreeModeOn]);
17
+ }
@@ -0,0 +1,37 @@
1
+ import { Theme } from '../../../models';
2
+ import { FormTab, ViewModeItem } from '../../types';
3
+ export declare const UPDATE_FORM_TAB = "UPDATE_FORM_TAB";
4
+ export declare const UPDATE_CODE_FULLSCREEN_MODE_ON = "UPDATE_CODE_FULLSCREEN_MODE_ON";
5
+ export declare const UPDATE_VIEW_MODE = "UPDATE_VIEW_MODE";
6
+ export declare const UPDATE_THEME = "UPDATE_THEME";
7
+ interface EditorSettingsState {
8
+ theme: Theme;
9
+ viewMode: ViewModeItem;
10
+ codeFullscreeModeOn: boolean;
11
+ formTab: FormTab;
12
+ }
13
+ interface UpdateViewMode {
14
+ type: typeof UPDATE_VIEW_MODE;
15
+ payload: ViewModeItem;
16
+ }
17
+ interface UpdateTheme {
18
+ type: typeof UPDATE_THEME;
19
+ payload: Theme;
20
+ }
21
+ interface UpdateCodeFullscreenModeOn {
22
+ type: typeof UPDATE_CODE_FULLSCREEN_MODE_ON;
23
+ payload: boolean;
24
+ }
25
+ interface UpdateFormTab {
26
+ type: typeof UPDATE_FORM_TAB;
27
+ payload: FormTab;
28
+ }
29
+ export type EditorSettingsAction = UpdateViewMode | UpdateTheme | UpdateCodeFullscreenModeOn | UpdateFormTab;
30
+ export declare const reducer: (state: EditorSettingsState, action: EditorSettingsAction) => EditorSettingsState;
31
+ export declare const initialState: {
32
+ viewMode: ViewModeItem;
33
+ theme: Theme;
34
+ codeFullscreeModeOn: boolean;
35
+ formTab: FormTab;
36
+ };
37
+ export {};
@@ -0,0 +1,28 @@
1
+ import { DEFAULT_THEME } from '../../../components/constants';
2
+ import { FormTab, ViewModeItem } from '../../types';
3
+ // actions
4
+ export const UPDATE_FORM_TAB = 'UPDATE_FORM_TAB';
5
+ export const UPDATE_CODE_FULLSCREEN_MODE_ON = 'UPDATE_CODE_FULLSCREEN_MODE_ON';
6
+ export const UPDATE_VIEW_MODE = 'UPDATE_VIEW_MODE';
7
+ export const UPDATE_THEME = 'UPDATE_THEME';
8
+ // reducer
9
+ export const reducer = (state, action) => {
10
+ switch (action.type) {
11
+ case UPDATE_VIEW_MODE:
12
+ return Object.assign(Object.assign({}, state), { viewMode: action.payload });
13
+ case UPDATE_THEME:
14
+ return Object.assign(Object.assign({}, state), { theme: action.payload });
15
+ case UPDATE_CODE_FULLSCREEN_MODE_ON:
16
+ return Object.assign(Object.assign({}, state), { codeFullscreeModeOn: action.payload });
17
+ case UPDATE_FORM_TAB:
18
+ return Object.assign(Object.assign({}, state), { formTab: action.payload });
19
+ default:
20
+ return state;
21
+ }
22
+ };
23
+ export const initialState = {
24
+ viewMode: ViewModeItem.Edititng,
25
+ theme: DEFAULT_THEME,
26
+ codeFullscreeModeOn: false,
27
+ formTab: FormTab.Blocks,
28
+ };
@@ -1,8 +1,9 @@
1
1
  body {
2
2
  --pc-editor-header-height: 48px;
3
+ --pc-editor-code-header-height: 36px;
3
4
  --pc-editor-divider-width: 12px;
5
+ --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
4
6
  --pc-editor-base-color: var(--g-color-base-brand);
5
7
  --pc-editor-control-color: var(--g-color-base-brand);
6
8
  --pc-editor-control-icon-color: var(--g-color-text-dark-primary);
7
- --pc-editor-left-column-width: calc(400px + var(--pc-editor-divider-width));
8
9
  }
@@ -32,4 +32,9 @@ export declare enum ViewModeItem {
32
32
  Tablet = "tablet",
33
33
  Mobile = "mobile"
34
34
  }
35
+ export declare enum FormTab {
36
+ Blocks = "blocks",
37
+ Page = "page",
38
+ Code = "code"
39
+ }
35
40
  export {};
@@ -5,3 +5,9 @@ export var ViewModeItem;
5
5
  ViewModeItem["Tablet"] = "tablet";
6
6
  ViewModeItem["Mobile"] = "mobile";
7
7
  })(ViewModeItem || (ViewModeItem = {}));
8
+ export var FormTab;
9
+ (function (FormTab) {
10
+ FormTab["Blocks"] = "blocks";
11
+ FormTab["Page"] = "page";
12
+ FormTab["Code"] = "code";
13
+ })(FormTab || (FormTab = {}));