@gravity-ui/page-constructor 4.40.6 → 4.41.1-alpha.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/build/cjs/components/Author/Author.css +4 -2
- package/build/cjs/components/Author/Author.js +2 -2
- package/build/cjs/editor/components/CodeEditor/CodeEditor.css +56 -0
- package/build/cjs/editor/components/CodeEditor/CodeEditor.d.ts +12 -0
- package/build/cjs/editor/components/CodeEditor/CodeEditor.js +31 -0
- package/build/cjs/editor/components/CodeEditor/constants.d.ts +2 -0
- package/build/cjs/editor/components/CodeEditor/constants.js +20 -0
- package/build/cjs/editor/components/Layout/Layout.css +2 -1
- package/build/cjs/editor/containers/Editor/Editor.js +9 -5
- package/build/cjs/editor/containers/Form/Form.css +5 -2
- package/build/cjs/editor/containers/Form/Form.d.ts +10 -3
- package/build/cjs/editor/containers/Form/Form.js +12 -16
- package/build/cjs/editor/hooks/useCodeValidator.d.ts +4 -0
- package/build/cjs/editor/hooks/useCodeValidator.js +10 -0
- package/build/cjs/editor/hooks/useFormSpec.d.ts +2 -2
- package/build/cjs/editor/hooks/useFormSpec.js +2 -6
- package/build/cjs/editor/store/main/index.d.ts +12 -0
- package/build/cjs/editor/store/{index.js → main/index.js} +10 -16
- package/build/cjs/editor/store/{reducer.d.ts → main/reducer.d.ts} +5 -15
- package/build/cjs/editor/store/{reducer.js → main/reducer.js} +1 -7
- package/build/cjs/editor/store/{utils.d.ts → main/utils.d.ts} +3 -3
- package/build/cjs/editor/store/settings/index.d.ts +12 -0
- package/build/cjs/editor/store/settings/index.js +21 -0
- package/build/cjs/editor/store/settings/reducer.d.ts +37 -0
- package/build/cjs/editor/store/settings/reducer.js +32 -0
- package/build/cjs/editor/styles/root.css +2 -1
- package/build/cjs/editor/types/index.d.ts +5 -0
- package/build/cjs/editor/types/index.js +7 -1
- package/build/cjs/editor/utils/code.d.ts +6 -0
- package/build/cjs/editor/utils/code.js +11 -0
- package/build/cjs/editor/utils/validation.d.ts +13 -0
- package/build/cjs/editor/utils/validation.js +57 -0
- package/build/cjs/models/constructor-items/common.d.ts +1 -0
- package/build/cjs/models/constructor-items/sub-blocks.d.ts +12 -1
- package/build/cjs/schema/constants.d.ts +4 -0
- package/build/cjs/sub-blocks/Quote/Quote.css +11 -18
- package/build/cjs/sub-blocks/Quote/Quote.js +7 -6
- package/build/cjs/sub-blocks/Quote/schema.d.ts +4 -0
- package/build/cjs/sub-blocks/Quote/schema.js +4 -1
- package/build/cjs/text-transform/config.js +10 -4
- package/build/esm/components/Author/Author.css +4 -2
- package/build/esm/components/Author/Author.js +2 -2
- package/build/esm/editor/components/CodeEditor/CodeEditor.css +56 -0
- package/build/esm/editor/components/CodeEditor/CodeEditor.d.ts +13 -0
- package/build/esm/editor/components/CodeEditor/CodeEditor.js +27 -0
- package/build/esm/editor/components/CodeEditor/constants.d.ts +2 -0
- package/build/esm/editor/components/CodeEditor/constants.js +17 -0
- package/build/esm/editor/components/Layout/Layout.css +2 -1
- package/build/esm/editor/containers/Editor/Editor.js +9 -5
- package/build/esm/editor/containers/Form/Form.css +5 -2
- package/build/esm/editor/containers/Form/Form.d.ts +10 -3
- package/build/esm/editor/containers/Form/Form.js +9 -13
- package/build/esm/editor/hooks/useCodeValidator.d.ts +4 -0
- package/build/esm/editor/hooks/useCodeValidator.js +6 -0
- package/build/esm/editor/hooks/useFormSpec.d.ts +2 -2
- package/build/esm/editor/hooks/useFormSpec.js +2 -6
- package/build/esm/editor/store/main/index.d.ts +12 -0
- package/build/esm/editor/store/{index.js → main/index.js} +9 -15
- package/build/esm/editor/store/{reducer.d.ts → main/reducer.d.ts} +5 -15
- package/build/esm/editor/store/{reducer.js → main/reducer.js} +0 -6
- package/build/esm/editor/store/{utils.d.ts → main/utils.d.ts} +3 -3
- package/build/esm/editor/store/settings/index.d.ts +12 -0
- package/build/esm/editor/store/settings/index.js +17 -0
- package/build/esm/editor/store/settings/reducer.d.ts +37 -0
- package/build/esm/editor/store/settings/reducer.js +28 -0
- package/build/esm/editor/styles/root.css +2 -1
- package/build/esm/editor/types/index.d.ts +5 -0
- package/build/esm/editor/types/index.js +6 -0
- package/build/esm/editor/utils/code.d.ts +6 -0
- package/build/esm/editor/utils/code.js +6 -0
- package/build/esm/editor/utils/validation.d.ts +13 -0
- package/build/esm/editor/utils/validation.js +51 -0
- package/build/esm/models/constructor-items/common.d.ts +1 -0
- package/build/esm/models/constructor-items/sub-blocks.d.ts +12 -1
- package/build/esm/schema/constants.d.ts +4 -0
- package/build/esm/sub-blocks/Quote/Quote.css +11 -18
- package/build/esm/sub-blocks/Quote/Quote.js +8 -7
- package/build/esm/sub-blocks/Quote/schema.d.ts +4 -0
- package/build/esm/sub-blocks/Quote/schema.js +4 -1
- package/build/esm/text-transform/config.js +10 -4
- package/package.json +4 -1
- package/server/models/constructor-items/common.d.ts +1 -0
- package/server/models/constructor-items/sub-blocks.d.ts +12 -1
- package/server/text-transform/config.js +10 -4
- package/styles/styles.css +1 -0
- package/styles/styles.scss +1 -0
- package/styles/variables.scss +2 -0
- package/widget/index.js +1 -1
- package/build/cjs/editor/components/YamlEditor/YamlEditor.css +0 -12
- package/build/cjs/editor/components/YamlEditor/YamlEditor.d.ts +0 -6
- package/build/cjs/editor/components/YamlEditor/YamlEditor.js +0 -34
- package/build/cjs/editor/store/index.d.ts +0 -16
- package/build/esm/editor/components/YamlEditor/YamlEditor.css +0 -12
- package/build/esm/editor/components/YamlEditor/YamlEditor.d.ts +0 -7
- package/build/esm/editor/components/YamlEditor/YamlEditor.js +0 -30
- package/build/esm/editor/store/index.d.ts +0 -16
- /package/build/cjs/editor/store/{utils.js → main/utils.js} +0 -0
- /package/build/esm/editor/store/{utils.js → main/utils.js} +0 -0
|
@@ -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(
|
|
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 '
|
|
4
|
-
import { HeaderBlockTypes } from '
|
|
5
|
-
import { getCustomTypes, getHeaderBlock } from '
|
|
6
|
-
import { EditBlockControls } from '
|
|
7
|
-
import { ViewModeItem } from '
|
|
8
|
-
import { ADD_BLOCK, COPY_BLOCK, DELETE_BLOCK, ORDER_BLOCK, SELECT_BLOCK, UPDATE_CONTENT,
|
|
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
|
|
11
|
-
const [{ activeBlockIndex, content, errorBoundaryState
|
|
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
|
|
76
|
+
}, [content, activeBlockIndex, errorBoundaryState, custom]);
|
|
83
77
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ConstructorBlock, PageContent, Theme } from '
|
|
2
|
-
import { ViewModeItem } from '
|
|
1
|
+
import { ConstructorBlock, PageContent, Theme } from '../../../models';
|
|
2
|
+
import { ViewModeItem } from '../../types';
|
|
3
3
|
export type EditorBlockId = number | string;
|
|
4
|
-
interface
|
|
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
|
-
|
|
53
|
-
|
|
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 '
|
|
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("
|
|
11
|
-
background?: import("
|
|
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
|
}
|
|
@@ -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 = {}));
|
|
@@ -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,51 @@
|
|
|
1
|
+
import Ajv from 'ajv';
|
|
2
|
+
import ajvKeywords from 'ajv-keywords';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import SourceMap from 'js-yaml-source-map';
|
|
5
|
+
import isArray from 'lodash/isArray';
|
|
6
|
+
const SUCCESS_MESSAGE = 'Valid';
|
|
7
|
+
export var CodeEditorMessageStatus;
|
|
8
|
+
(function (CodeEditorMessageStatus) {
|
|
9
|
+
CodeEditorMessageStatus["SUCCESS"] = "success";
|
|
10
|
+
CodeEditorMessageStatus["WARNING"] = "warning";
|
|
11
|
+
CodeEditorMessageStatus["ERROR"] = "error";
|
|
12
|
+
})(CodeEditorMessageStatus || (CodeEditorMessageStatus = {}));
|
|
13
|
+
export function createValidator(schema) {
|
|
14
|
+
const ajv = new Ajv({ $data: true, allErrors: true, schemas: [schema], strict: false });
|
|
15
|
+
// TODO: select is deprecated, replace with discriminator:
|
|
16
|
+
// https://github.com/ajv-validator/ajv-keywords#selectselectcasesselectdefault
|
|
17
|
+
ajvKeywords(ajv, 'select');
|
|
18
|
+
return ajv.compile(schema);
|
|
19
|
+
}
|
|
20
|
+
export function validate(content, validator) {
|
|
21
|
+
let result;
|
|
22
|
+
if (!content) {
|
|
23
|
+
return { status: CodeEditorMessageStatus.SUCCESS, text: SUCCESS_MESSAGE };
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const jsYamlMap = new SourceMap();
|
|
27
|
+
const data = yaml.load(content, { listener: jsYamlMap.listen() });
|
|
28
|
+
validator(data);
|
|
29
|
+
if (validator.errors) {
|
|
30
|
+
const messages = validator.errors.map(({ instancePath, schemaPath, message, params }) => {
|
|
31
|
+
const pointer = jsYamlMap.lookup(instancePath.split('/').filter(Boolean));
|
|
32
|
+
const stringParams = Object.entries(params).map(([key, value]) => {
|
|
33
|
+
if (isArray(value)) {
|
|
34
|
+
return `${key}: ${value.join(' | ')}`;
|
|
35
|
+
}
|
|
36
|
+
return `${key}: ${value}`;
|
|
37
|
+
});
|
|
38
|
+
const ref = pointer ? `${pointer.line}: ` : '';
|
|
39
|
+
return `${ref}${instancePath || schemaPath}: ${message}\n${stringParams.join('\n')}`;
|
|
40
|
+
});
|
|
41
|
+
result = { status: CodeEditorMessageStatus.WARNING, text: messages.join('\n\n') };
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
result = { status: CodeEditorMessageStatus.SUCCESS, text: SUCCESS_MESSAGE };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch ({ message }) {
|
|
48
|
+
result = { status: CodeEditorMessageStatus.ERROR, text: message };
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
@@ -63,16 +63,27 @@ export interface HubspotFormProps extends HubspotEventHandlers, AnalyticsEventsB
|
|
|
63
63
|
createDOMElement?: boolean;
|
|
64
64
|
}
|
|
65
65
|
export interface QuoteProps extends Themable, CardBaseProps {
|
|
66
|
-
text
|
|
66
|
+
text?: string;
|
|
67
|
+
yfmText?: string;
|
|
67
68
|
image: ThemedImage;
|
|
68
69
|
logo: ImageProps;
|
|
69
70
|
color?: string;
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated use property button instead
|
|
73
|
+
*/
|
|
70
74
|
url?: string;
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated use property button instead
|
|
77
|
+
*/
|
|
71
78
|
urlTitle?: string;
|
|
72
79
|
author?: AuthorItem;
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated use property button instead
|
|
82
|
+
*/
|
|
73
83
|
buttonText?: string;
|
|
74
84
|
theme?: TextTheme;
|
|
75
85
|
quoteType?: QuoteType;
|
|
86
|
+
button?: ButtonProps;
|
|
76
87
|
}
|
|
77
88
|
export interface BackgroundCardProps extends CardBaseProps, AnalyticsEventsBase, Omit<ContentBlockProps, 'colSizes' | 'centered'> {
|
|
78
89
|
url?: string;
|
|
@@ -76,6 +76,17 @@ unpredictable css rules order in build */
|
|
|
76
76
|
.pc-quote__content_quote-type_english-double .pc-quote__text::after {
|
|
77
77
|
content: "”";
|
|
78
78
|
}
|
|
79
|
+
.pc-quote__content .yfm {
|
|
80
|
+
font-size: var(--g-text-body-3-font-size);
|
|
81
|
+
line-height: var(--g-text-body-3-line-height);
|
|
82
|
+
}
|
|
83
|
+
.pc-quote__content .yfm > * {
|
|
84
|
+
display: inline;
|
|
85
|
+
}
|
|
86
|
+
.pc-quote__content .yfm:after {
|
|
87
|
+
position: relative;
|
|
88
|
+
left: -5px;
|
|
89
|
+
}
|
|
79
90
|
.pc-quote__image {
|
|
80
91
|
width: 100%;
|
|
81
92
|
height: 100%;
|
|
@@ -87,24 +98,6 @@ unpredictable css rules order in build */
|
|
|
87
98
|
align-items: flex-end;
|
|
88
99
|
margin-top: 20px;
|
|
89
100
|
}
|
|
90
|
-
.pc-quote__author_theme_dark, .pc-quote_theme_dark {
|
|
91
|
-
color: var(--g-color-text-light-primary);
|
|
92
|
-
}
|
|
93
|
-
.pc-quote__author_theme_dark h1,
|
|
94
|
-
.pc-quote__author_theme_dark h2,
|
|
95
|
-
.pc-quote__author_theme_dark h3,
|
|
96
|
-
.pc-quote__author_theme_dark h4,
|
|
97
|
-
.pc-quote__author_theme_dark h5,
|
|
98
|
-
.pc-quote__author_theme_dark h6,
|
|
99
|
-
.pc-quote__author_theme_dark .yfm, .pc-quote_theme_dark h1,
|
|
100
|
-
.pc-quote_theme_dark h2,
|
|
101
|
-
.pc-quote_theme_dark h3,
|
|
102
|
-
.pc-quote_theme_dark h4,
|
|
103
|
-
.pc-quote_theme_dark h5,
|
|
104
|
-
.pc-quote_theme_dark h6,
|
|
105
|
-
.pc-quote_theme_dark .yfm {
|
|
106
|
-
color: var(--g-color-text-light-primary);
|
|
107
|
-
}
|
|
108
101
|
.pc-quote__author {
|
|
109
102
|
max-width: calc(60% - 20px);
|
|
110
103
|
margin-right: 20px;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import { Button } from '
|
|
3
|
-
import { Author, HTML, Image } from '../../components';
|
|
2
|
+
import { Author, Button, HTML, Image, YFMWrapper } from '../../components';
|
|
4
3
|
import { getMediaImage } from '../../components/Media/Image/utils';
|
|
5
4
|
import { useTheme } from '../../context/theme';
|
|
6
5
|
import { useAnalytics } from '../../hooks';
|
|
@@ -9,23 +8,25 @@ import { block, getThemedValue } from '../../utils';
|
|
|
9
8
|
import './Quote.css';
|
|
10
9
|
const b = block('quote');
|
|
11
10
|
const Quote = (props) => {
|
|
12
|
-
const { theme: textTheme = 'light', color, image, border = 'shadow', text, logo, author, url, urlTitle, buttonText, quoteType = QuoteType.Chevron, } = props;
|
|
11
|
+
const { theme: textTheme = 'light', color, image, border = 'shadow', text, yfmText, logo, author, url, urlTitle, buttonText, quoteType = QuoteType.Chevron, button, } = props;
|
|
13
12
|
const theme = useTheme();
|
|
14
13
|
const imageThemed = getThemedValue(image, theme);
|
|
15
14
|
const imageData = getMediaImage(imageThemed);
|
|
16
15
|
const handleAnalytics = useAnalytics(DefaultEventNames.QuoteButton, url);
|
|
17
16
|
const handleButtonClick = useCallback(() => handleAnalytics(), [handleAnalytics]);
|
|
18
17
|
const renderFooter = Boolean(author || url) && (React.createElement("div", { className: b('author-wrapper') },
|
|
19
|
-
author && (React.createElement(Author, { className: b('author', { theme: textTheme }), author: author, type: AuthorType.Line })),
|
|
20
|
-
url && buttonText && (React.createElement(Button, {
|
|
18
|
+
author && (React.createElement(Author, { className: b('author', { theme: textTheme }), author: author, type: AuthorType.Line, theme: textTheme })),
|
|
19
|
+
url && buttonText && !button && (React.createElement(Button, { theme: "outlined", size: "xl", url: url, className: b('link-button', { theme: textTheme }), onClick: handleButtonClick, urlTitle: urlTitle, text: buttonText })),
|
|
20
|
+
button && React.createElement(Button, Object.assign({ size: "xl" }, button))));
|
|
21
21
|
const logoProps = getMediaImage(logo);
|
|
22
22
|
return (React.createElement("div", { className: b({ theme: textTheme, border }), style: color ? { backgroundColor: color } : {} },
|
|
23
23
|
React.createElement("div", { key: text, className: b('content-wrapper') },
|
|
24
24
|
React.createElement("div", null,
|
|
25
25
|
React.createElement(Image, Object.assign({ className: b('logo') }, logoProps)),
|
|
26
26
|
React.createElement("div", { className: b('content', { 'quote-type': quoteType }) },
|
|
27
|
-
React.createElement("span", { className: b('text') },
|
|
28
|
-
React.createElement(HTML, null, text)))
|
|
27
|
+
text && (React.createElement("span", { className: b('text') },
|
|
28
|
+
React.createElement(HTML, null, text))),
|
|
29
|
+
yfmText && (React.createElement(YFMWrapper, { className: b('text'), content: yfmText, modifiers: { constructor: true } })))),
|
|
29
30
|
renderFooter),
|
|
30
31
|
React.createElement("div", { className: b('image-wrapper') },
|
|
31
32
|
React.createElement(Image, Object.assign({}, imageData, { className: b('image') })))));
|
|
@@ -3,10 +3,13 @@ import { BaseProps, ThemeProps, authorItem, quoteTypes, withTheme, } from '../..
|
|
|
3
3
|
export const Quote = {
|
|
4
4
|
quote: {
|
|
5
5
|
additionalProperties: false,
|
|
6
|
-
required: ['
|
|
6
|
+
required: ['image', 'logo'],
|
|
7
7
|
properties: Object.assign(Object.assign({}, BaseProps), { text: {
|
|
8
8
|
type: 'string',
|
|
9
9
|
contentType: 'text',
|
|
10
|
+
}, yfmText: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
contentType: 'text',
|
|
10
13
|
}, image: withTheme(ImageProps), logo: ImageProps, color: {
|
|
11
14
|
type: 'string',
|
|
12
15
|
}, url: {
|
|
@@ -127,10 +127,16 @@ export const config = {
|
|
|
127
127
|
transformer: yfmTransformer,
|
|
128
128
|
},
|
|
129
129
|
],
|
|
130
|
-
[SubBlockType.Quote]:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
[SubBlockType.Quote]: [
|
|
131
|
+
{
|
|
132
|
+
fields: ['text'],
|
|
133
|
+
transformer: typografTransformer,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
fields: ['yfmText'],
|
|
137
|
+
transformer: yfmTransformer,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
134
140
|
[BlockType.ExtendedFeaturesBlock]: [
|
|
135
141
|
...blockHeaderTransformer,
|
|
136
142
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/page-constructor",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.41.1-alpha.0",
|
|
4
4
|
"description": "Gravity UI Page Constructor",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -86,8 +86,10 @@
|
|
|
86
86
|
"@gravity-ui/i18n": "^1.0.0",
|
|
87
87
|
"@react-spring/web": "^9.7.3",
|
|
88
88
|
"ajv": "^8.12.0",
|
|
89
|
+
"ajv-keywords": "^5.1.0",
|
|
89
90
|
"final-form": "^4.20.9",
|
|
90
91
|
"github-buttons": "2.23.0",
|
|
92
|
+
"js-yaml-source-map": "^0.2.2",
|
|
91
93
|
"lodash": "^4.17.21",
|
|
92
94
|
"monaco-editor": "^0.38.0",
|
|
93
95
|
"react-final-form": "^6.5.9",
|
|
@@ -164,6 +166,7 @@
|
|
|
164
166
|
"js-yaml": "^4.1.0",
|
|
165
167
|
"lint-staged": "^11.2.6",
|
|
166
168
|
"markdown-loader": "^6.0.0",
|
|
169
|
+
"monaco-editor-webpack-plugin": "^7.1.0",
|
|
167
170
|
"move-file-cli": "^3.0.0",
|
|
168
171
|
"npm-run-all": "^4.1.5",
|
|
169
172
|
"postcss": "^8.4.16",
|
|
@@ -63,16 +63,27 @@ export interface HubspotFormProps extends HubspotEventHandlers, AnalyticsEventsB
|
|
|
63
63
|
createDOMElement?: boolean;
|
|
64
64
|
}
|
|
65
65
|
export interface QuoteProps extends Themable, CardBaseProps {
|
|
66
|
-
text
|
|
66
|
+
text?: string;
|
|
67
|
+
yfmText?: string;
|
|
67
68
|
image: ThemedImage;
|
|
68
69
|
logo: ImageProps;
|
|
69
70
|
color?: string;
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated use property button instead
|
|
73
|
+
*/
|
|
70
74
|
url?: string;
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated use property button instead
|
|
77
|
+
*/
|
|
71
78
|
urlTitle?: string;
|
|
72
79
|
author?: AuthorItem;
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated use property button instead
|
|
82
|
+
*/
|
|
73
83
|
buttonText?: string;
|
|
74
84
|
theme?: TextTheme;
|
|
75
85
|
quoteType?: QuoteType;
|
|
86
|
+
button?: ButtonProps;
|
|
76
87
|
}
|
|
77
88
|
export interface BackgroundCardProps extends CardBaseProps, AnalyticsEventsBase, Omit<ContentBlockProps, 'colSizes' | 'centered'> {
|
|
78
89
|
url?: string;
|
|
@@ -140,10 +140,16 @@ exports.config = {
|
|
|
140
140
|
transformer: common_1.yfmTransformer,
|
|
141
141
|
},
|
|
142
142
|
],
|
|
143
|
-
[models_1.SubBlockType.Quote]:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
[models_1.SubBlockType.Quote]: [
|
|
144
|
+
{
|
|
145
|
+
fields: ['text'],
|
|
146
|
+
transformer: common_1.typografTransformer,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
fields: ['yfmText'],
|
|
150
|
+
transformer: common_1.yfmTransformer,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
147
153
|
[models_1.BlockType.ExtendedFeaturesBlock]: [
|
|
148
154
|
...exports.blockHeaderTransformer,
|
|
149
155
|
{
|
package/styles/styles.css
CHANGED
package/styles/styles.scss
CHANGED