@snack-uikit/code-editor 0.4.7-preview-e698fca9.0 → 0.4.7-preview-2af706c7.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/README.md CHANGED
@@ -12,9 +12,9 @@
12
12
  ### Props
13
13
  | name | type | default value | description |
14
14
  |------|------|---------------|-------------|
15
+ | jsonSchema* | `JsonSchema` | - | Схема для валидации |
15
16
  | themeName | `string` | - | Название текущей темы. Значение не важно, важно что смена значения запускает пересчет стилей. |
16
17
  | hasBackground | `boolean` | true | Включение/отключение псевдобекграунда |
17
- | schema | `SchemasSettings` | - | Схема для валидации |
18
18
  | defaultValue | `string` | - | Default value of the current model |
19
19
  | defaultLanguage | `string` | - | Default language of the current model |
20
20
  | defaultPath | `string` | - | Default path of the current model Will be passed as the third argument to `.createModel` method `monaco.editor.createModel(..., ..., monaco.Uri.parse(defaultPath))` |
@@ -1,5 +1,5 @@
1
1
  import { WithSupportProps } from '@snack-uikit/utils';
2
- import { EditorProps, EditorWithSchemaProps } from './types';
2
+ import { EditorBaseProps, EditorWithJsonSchemaProps } from './types';
3
3
  export type CodeEditorProps = WithSupportProps<{
4
4
  /**
5
5
  * Название текущей темы. Значение не важно, важно что смена значения запускает пересчет стилей.
@@ -9,5 +9,5 @@ export type CodeEditorProps = WithSupportProps<{
9
9
  * Включение/отключение псевдобекграунда
10
10
  */
11
11
  hasBackground?: boolean;
12
- }> & (EditorProps | EditorWithSchemaProps);
13
- export declare function CodeEditor({ themeName, className, theme, options, loading, hasBackground, onMount, ...props }: CodeEditorProps): import("react/jsx-runtime").JSX.Element;
12
+ }> & (EditorBaseProps | EditorWithJsonSchemaProps);
13
+ export declare function CodeEditor({ themeName, className, theme, options, loading, hasBackground, onMount, language, ...props }: CodeEditorProps): import("react/jsx-runtime").JSX.Element;
@@ -29,7 +29,6 @@ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
29
29
  const utils_2 = require("./utils");
30
30
  (0, utils_2.initLoaderConfig)();
31
31
  function CodeEditor(_a) {
32
- var _b, _c;
33
32
  var {
34
33
  themeName,
35
34
  className,
@@ -37,17 +36,16 @@ function CodeEditor(_a) {
37
36
  options,
38
37
  loading,
39
38
  hasBackground = true,
40
- onMount
39
+ onMount,
40
+ language
41
41
  } = _a,
42
- props = __rest(_a, ["themeName", "className", "theme", "options", "loading", "hasBackground", "onMount"]);
43
- const {
44
- language
45
- } = props;
42
+ props = __rest(_a, ["themeName", "className", "theme", "options", "loading", "hasBackground", "onMount", "language"]);
46
43
  const monaco = (0, react_1.useMonaco)();
47
44
  const [wrapperElement, setWrapperElement] = (0, react_2.useState)(null);
48
- const modelPath = 'schema' in props ? (_c = (_b = props.schema) === null || _b === void 0 ? void 0 : _b.fileMatch) === null || _c === void 0 ? void 0 : _c[0] : undefined;
49
- (0, hooks_1.useYamlEditor)(props.language === 'yaml' ? props.schema : undefined);
50
- (0, hooks_1.useJsonEditor)(props.language === 'json' ? props.schema : undefined);
45
+ const {
46
+ jsonSchemaProps,
47
+ jsonSchemaOptions
48
+ } = (0, hooks_1.useApplyJsonSchema)(language, 'jsonSchema' in props ? props.jsonSchema : undefined);
51
49
  const onEditorMount = (0, react_2.useCallback)((editor, monaco) => {
52
50
  var _a;
53
51
  monaco && (0, utils_1.isBrowser)() && ((_a = document === null || document === void 0 ? void 0 : document.fonts) === null || _a === void 0 ? void 0 : _a.ready.finally(monaco.editor.remeasureFonts));
@@ -108,16 +106,16 @@ function CodeEditor(_a) {
108
106
  monaco === null || monaco === void 0 ? void 0 : monaco.editor.defineTheme('snack', Object.assign(Object.assign({}, themeDataWithoutBase), {
109
107
  base: 'vs'
110
108
  }));
111
- const mergedOptions = (0, react_2.useMemo)(() => Object.assign(Object.assign(Object.assign(Object.assign({}, constants_1.CODE_EDITOR_OPTIONS), language === 'yaml' ? constants_1.YAML_CODE_EDITOR_OPTIONS : {}), (themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono) ? {
109
+ const mergedOptions = (0, react_2.useMemo)(() => Object.assign(Object.assign(Object.assign(Object.assign({}, constants_1.CODE_EDITOR_OPTIONS), jsonSchemaOptions), (themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono) ? {
112
110
  fontSize: Number.parseFloat(themeValues.mono.body.s['font-size']),
113
111
  fontWeight: themeValues.mono.body.s['font-weight'],
114
112
  fontFamily: themeValues.mono.body.s['font-family']
115
- } : constants_1.DEFAULT_THEME_OPTIONS.mono.s), options), [options, language, themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono]);
113
+ } : constants_1.DEFAULT_THEME_OPTIONS.mono.s), options), [options, themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono, jsonSchemaOptions]);
116
114
  return (0, jsx_runtime_1.jsx)("div", Object.assign({
117
115
  className: className
118
116
  }, (0, utils_1.extractSupportProps)(props), {
119
117
  ref: setWrapperElement,
120
- children: (0, jsx_runtime_1.jsx)(react_1.Editor, Object.assign({}, props, {
118
+ children: (0, jsx_runtime_1.jsx)(react_1.Editor, Object.assign({}, props, jsonSchemaProps, {
121
119
  theme: theme !== null && theme !== void 0 ? theme : dark ? 'snackDark' : 'snack',
122
120
  className: (0, classnames_1.default)({
123
121
  [styles_module_scss_1.default.editor]: hasBackground
@@ -125,7 +123,7 @@ function CodeEditor(_a) {
125
123
  loading: loading !== null && loading !== void 0 ? loading : (0, jsx_runtime_1.jsx)(loaders_1.Spinner, {}),
126
124
  options: mergedOptions,
127
125
  onMount: onEditorMount,
128
- path: modelPath
126
+ language: language
129
127
  }))
130
128
  }));
131
129
  }
@@ -104,3 +104,4 @@ export declare const YAML_CODE_EDITOR_OPTIONS: {
104
104
  strings: boolean;
105
105
  };
106
106
  };
107
+ export declare const DEFAULT_SCHEMA_URI = "schema://editor-schema";
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.YAML_CODE_EDITOR_OPTIONS = exports.CODE_EDITOR_OPTIONS = exports.THEME_VARS = exports.DEFAULT_THEME_OPTIONS = exports.DEFAULT_THEME_VALUES = void 0;
6
+ exports.DEFAULT_SCHEMA_URI = exports.YAML_CODE_EDITOR_OPTIONS = exports.CODE_EDITOR_OPTIONS = exports.THEME_VARS = exports.DEFAULT_THEME_OPTIONS = exports.DEFAULT_THEME_VALUES = void 0;
7
7
  exports.DEFAULT_THEME_VALUES = {
8
8
  semanticTokenColors: {
9
9
  enumMember: {
@@ -118,4 +118,5 @@ exports.YAML_CODE_EDITOR_OPTIONS = {
118
118
  quickSuggestions: {
119
119
  strings: true
120
120
  }
121
- };
121
+ };
122
+ exports.DEFAULT_SCHEMA_URI = 'schema://editor-schema';
@@ -1,4 +1,4 @@
1
- import { SchemasSettings } from 'monaco-yaml';
1
+ import { JsonSchema } from './types';
2
2
  type UseCalculatedThemeValuesProps = {
3
3
  stylesOriginNode: HTMLDivElement | null;
4
4
  themeName?: string;
@@ -42,6 +42,10 @@ export declare function useCalculatedThemeValues({ stylesOriginNode, themeName }
42
42
  };
43
43
  };
44
44
  } | undefined;
45
- export declare function useYamlEditor(yamlSchema?: SchemasSettings): string | undefined;
46
- export declare function useJsonEditor(jsonSchema?: SchemasSettings): void;
45
+ export declare function useApplyJsonSchema(language?: string, jsonSchema?: JsonSchema): {
46
+ jsonSchemaProps: {
47
+ path: string | undefined;
48
+ };
49
+ jsonSchemaOptions: import("monaco-editor").editor.IStandaloneEditorConstructionOptions | undefined;
50
+ };
47
51
  export {};
@@ -4,13 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.useCalculatedThemeValues = useCalculatedThemeValues;
7
- exports.useYamlEditor = useYamlEditor;
8
- exports.useJsonEditor = useJsonEditor;
7
+ exports.useApplyJsonSchema = useApplyJsonSchema;
9
8
  const react_1 = require("@monaco-editor/react");
10
9
  const monaco_yaml_1 = require("monaco-yaml");
11
10
  const react_2 = require("react");
12
11
  const utils_1 = require("@snack-uikit/utils");
13
12
  const constants_1 = require("./constants");
13
+ const utils_2 = require("./utils");
14
14
  function getThemeVars(styles) {
15
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
16
  return function mapComputedTree(tree) {
@@ -42,31 +42,57 @@ function useCalculatedThemeValues(_ref) {
42
42
  }, [stylesOriginNode, trigger]);
43
43
  return values;
44
44
  }
45
- function useYamlEditor(yamlSchema) {
46
- var _a;
47
- const modelPath = (_a = yamlSchema === null || yamlSchema === void 0 ? void 0 : yamlSchema.fileMatch) === null || _a === void 0 ? void 0 : _a[0];
45
+ function useApplyJsonSchema(language, jsonSchema) {
48
46
  const monaco = (0, react_1.useMonaco)();
49
- (0, react_2.useEffect)(() => {
50
- if (!yamlSchema || !monaco) {
47
+ const [jsonSchemaOptions, setJsonSchemaOptions] = (0, react_2.useState)({});
48
+ const modelPath = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.fileMatch;
49
+ const preparedJsonSchema = (0, react_2.useMemo)(() => (0, utils_2.getJsonSchema)(jsonSchema), [jsonSchema]);
50
+ const configureYamlLanguage = (0, react_2.useCallback)(() => {
51
+ if (!monaco || !preparedJsonSchema) {
51
52
  return;
52
53
  }
53
54
  const model = (0, monaco_yaml_1.configureMonacoYaml)(monaco, {
54
55
  enableSchemaRequest: true,
55
- schemas: [yamlSchema]
56
+ schemas: [preparedJsonSchema]
56
57
  });
57
- return () => model.dispose();
58
- }, [monaco, yamlSchema]);
59
- return modelPath;
60
- }
61
- function useJsonEditor(jsonSchema) {
62
- const monaco = (0, react_1.useMonaco)();
63
- (0, react_2.useEffect)(() => {
64
- if (!jsonSchema || !monaco) {
58
+ return {
59
+ options: constants_1.YAML_CODE_EDITOR_OPTIONS,
60
+ dispose: model.dispose
61
+ };
62
+ }, [monaco, preparedJsonSchema]);
63
+ const configureJsonLanguage = (0, react_2.useCallback)(() => {
64
+ if (!monaco || !preparedJsonSchema) {
65
65
  return;
66
66
  }
67
67
  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
68
68
  validate: true,
69
- schemas: [jsonSchema]
69
+ schemas: [preparedJsonSchema]
70
70
  });
71
- }, [monaco, jsonSchema]);
71
+ }, [monaco, preparedJsonSchema]);
72
+ const configureJsonSchema = (0, react_2.useCallback)(() => {
73
+ switch (language) {
74
+ case 'yaml':
75
+ return configureYamlLanguage();
76
+ case 'json':
77
+ return configureJsonLanguage();
78
+ default:
79
+ break;
80
+ }
81
+ }, [language, configureYamlLanguage, configureJsonLanguage]);
82
+ (0, react_2.useEffect)(() => {
83
+ var _a;
84
+ const jsonSchemaSettings = configureJsonSchema();
85
+ setJsonSchemaOptions((_a = jsonSchemaSettings === null || jsonSchemaSettings === void 0 ? void 0 : jsonSchemaSettings.options) !== null && _a !== void 0 ? _a : {});
86
+ return () => {
87
+ var _a;
88
+ setJsonSchemaOptions({});
89
+ (_a = jsonSchemaSettings === null || jsonSchemaSettings === void 0 ? void 0 : jsonSchemaSettings.dispose) === null || _a === void 0 ? void 0 : _a.call(jsonSchemaSettings);
90
+ };
91
+ }, [configureJsonSchema]);
92
+ return (0, react_2.useMemo)(() => ({
93
+ jsonSchemaProps: {
94
+ path: modelPath
95
+ },
96
+ jsonSchemaOptions
97
+ }), [jsonSchemaOptions, modelPath]);
72
98
  }
@@ -1,12 +1,25 @@
1
1
  import { EditorProps as MonacoEditorProps } from '@monaco-editor/react';
2
- import { SchemasSettings } from 'monaco-yaml';
3
- export type EditorProps = {
4
- schema?: never;
5
- } & MonacoEditorProps;
6
- export type EditorWithSchemaProps = {
7
- language: 'yaml' | 'json';
2
+ import { JSONSchema } from 'monaco-yaml';
3
+ export type EditorBaseProps = MonacoEditorProps;
4
+ export type SupportedSchemaLanguage = 'json' | 'yaml';
5
+ export type JsonSchema = {
6
+ uri?: string;
7
+ schema?: JSONSchema;
8
+ fileMatch: string;
9
+ };
10
+ export type WithJsonSchema = {
8
11
  /**
9
12
  * Схема для валидации
10
13
  */
11
- schema?: SchemasSettings;
12
- } & Omit<MonacoEditorProps, 'language'>;
14
+ jsonSchema: JsonSchema;
15
+ path?: never;
16
+ };
17
+ type WithoutJsonSchema = Pick<MonacoEditorProps, 'path'>;
18
+ export type EditorWithJsonSchemaProps = Omit<EditorBaseProps, 'language' | 'path'> & {
19
+ language: SupportedSchemaLanguage;
20
+ } & (WithJsonSchema | WithoutJsonSchema);
21
+ export type ConfigureJsonSchemaReturn = {
22
+ options?: MonacoEditorProps['options'];
23
+ dispose?: () => void;
24
+ } | undefined;
25
+ export {};
@@ -1,3 +1,6 @@
1
+ import { SchemasSettings } from 'monaco-yaml';
2
+ import { JsonSchema } from './types';
1
3
  export declare function rgb2hsl(HTMLcolor: string): number[];
2
4
  export declare function isDark(color: string): boolean;
3
5
  export declare function initLoaderConfig(): void;
6
+ export declare const getJsonSchema: (jsonSchema?: JsonSchema) => SchemasSettings | undefined;
@@ -8,11 +8,13 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
8
8
  Object.defineProperty(exports, "__esModule", {
9
9
  value: true
10
10
  });
11
+ exports.getJsonSchema = void 0;
11
12
  exports.rgb2hsl = rgb2hsl;
12
13
  exports.isDark = isDark;
13
14
  exports.initLoaderConfig = initLoaderConfig;
14
15
  const react_1 = require("@monaco-editor/react");
15
16
  const chroma_js_1 = __importDefault(require("chroma-js"));
17
+ const constants_1 = require("./constants");
16
18
  function rgb2hsl(HTMLcolor) {
17
19
  const [r, g, b] = chroma_js_1.default.valid(HTMLcolor) ? (0, chroma_js_1.default)(HTMLcolor).rgb().map(c => c / 255) : [0, 0, 0];
18
20
  const max = Math.max(r, g, b),
@@ -53,4 +55,9 @@ function initLoaderConfig() {
53
55
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
54
56
  // @ts-ignore
55
57
  window['__snack-code-editor-loader-config__'] && react_1.loader.config(window['__snack-code-editor-loader-config__']);
56
- }
58
+ }
59
+ const getJsonSchema = jsonSchema => jsonSchema && Object.assign(Object.assign({}, jsonSchema), {
60
+ uri: (jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.uri) || constants_1.DEFAULT_SCHEMA_URI,
61
+ fileMatch: [jsonSchema.fileMatch]
62
+ });
63
+ exports.getJsonSchema = getJsonSchema;
@@ -2,5 +2,5 @@
2
2
  Monaco loader defines the way how monaco will be loaded.
3
3
  @see https://github.com/suren-atoyan/monaco-react/tree/master?tab=readme-ov-file#loader-config
4
4
  */
5
- export { loader } from '@monaco-editor/react';
5
+ export { loader, useMonaco } from '@monaco-editor/react';
6
6
  export * from './components';
package/dist/cjs/index.js CHANGED
@@ -22,7 +22,7 @@ var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
22
22
  Object.defineProperty(exports, "__esModule", {
23
23
  value: true
24
24
  });
25
- exports.loader = void 0;
25
+ exports.useMonaco = exports.loader = void 0;
26
26
  /**
27
27
  Monaco loader defines the way how monaco will be loaded.
28
28
  @see https://github.com/suren-atoyan/monaco-react/tree/master?tab=readme-ov-file#loader-config
@@ -34,4 +34,10 @@ Object.defineProperty(exports, "loader", {
34
34
  return react_1.loader;
35
35
  }
36
36
  });
37
+ Object.defineProperty(exports, "useMonaco", {
38
+ enumerable: true,
39
+ get: function () {
40
+ return react_1.useMonaco;
41
+ }
42
+ });
37
43
  __exportStar(require("./components"), exports);
@@ -1,5 +1,5 @@
1
1
  import { WithSupportProps } from '@snack-uikit/utils';
2
- import { EditorProps, EditorWithSchemaProps } from './types';
2
+ import { EditorBaseProps, EditorWithJsonSchemaProps } from './types';
3
3
  export type CodeEditorProps = WithSupportProps<{
4
4
  /**
5
5
  * Название текущей темы. Значение не важно, важно что смена значения запускает пересчет стилей.
@@ -9,5 +9,5 @@ export type CodeEditorProps = WithSupportProps<{
9
9
  * Включение/отключение псевдобекграунда
10
10
  */
11
11
  hasBackground?: boolean;
12
- }> & (EditorProps | EditorWithSchemaProps);
13
- export declare function CodeEditor({ themeName, className, theme, options, loading, hasBackground, onMount, ...props }: CodeEditorProps): import("react/jsx-runtime").JSX.Element;
12
+ }> & (EditorBaseProps | EditorWithJsonSchemaProps);
13
+ export declare function CodeEditor({ themeName, className, theme, options, loading, hasBackground, onMount, language, ...props }: CodeEditorProps): import("react/jsx-runtime").JSX.Element;
@@ -15,20 +15,16 @@ import cn from 'classnames';
15
15
  import { useCallback, useMemo, useState } from 'react';
16
16
  import { Spinner } from '@snack-uikit/loaders';
17
17
  import { extractSupportProps, isBrowser } from '@snack-uikit/utils';
18
- import { CODE_EDITOR_OPTIONS, DEFAULT_THEME_OPTIONS, DEFAULT_THEME_VALUES, YAML_CODE_EDITOR_OPTIONS, } from './constants';
19
- import { useCalculatedThemeValues, useJsonEditor, useYamlEditor } from './hooks';
18
+ import { CODE_EDITOR_OPTIONS, DEFAULT_THEME_OPTIONS, DEFAULT_THEME_VALUES } from './constants';
19
+ import { useApplyJsonSchema, useCalculatedThemeValues } from './hooks';
20
20
  import styles from './styles.module.css';
21
21
  import { initLoaderConfig, isDark } from './utils';
22
22
  initLoaderConfig();
23
23
  export function CodeEditor(_a) {
24
- var _b, _c;
25
- var { themeName, className, theme, options, loading, hasBackground = true, onMount } = _a, props = __rest(_a, ["themeName", "className", "theme", "options", "loading", "hasBackground", "onMount"]);
26
- const { language } = props;
24
+ var { themeName, className, theme, options, loading, hasBackground = true, onMount, language } = _a, props = __rest(_a, ["themeName", "className", "theme", "options", "loading", "hasBackground", "onMount", "language"]);
27
25
  const monaco = useMonaco();
28
26
  const [wrapperElement, setWrapperElement] = useState(null);
29
- const modelPath = 'schema' in props ? (_c = (_b = props.schema) === null || _b === void 0 ? void 0 : _b.fileMatch) === null || _c === void 0 ? void 0 : _c[0] : undefined;
30
- useYamlEditor(props.language === 'yaml' ? props.schema : undefined);
31
- useJsonEditor(props.language === 'json' ? props.schema : undefined);
27
+ const { jsonSchemaProps, jsonSchemaOptions } = useApplyJsonSchema(language, 'jsonSchema' in props ? props.jsonSchema : undefined);
32
28
  const onEditorMount = useCallback((editor, monaco) => {
33
29
  var _a;
34
30
  monaco && isBrowser() && ((_a = document === null || document === void 0 ? void 0 : document.fonts) === null || _a === void 0 ? void 0 : _a.ready.finally(monaco.editor.remeasureFonts));
@@ -84,12 +80,12 @@ export function CodeEditor(_a) {
84
80
  const dark = useMemo(() => { var _a; return isDark((_a = themeValues === null || themeValues === void 0 ? void 0 : themeValues.sys.available.complementary) !== null && _a !== void 0 ? _a : ''); }, [themeValues === null || themeValues === void 0 ? void 0 : themeValues.sys.available.complementary]);
85
81
  monaco === null || monaco === void 0 ? void 0 : monaco.editor.defineTheme('snackDark', Object.assign(Object.assign({}, themeDataWithoutBase), { base: 'vs-dark' }));
86
82
  monaco === null || monaco === void 0 ? void 0 : monaco.editor.defineTheme('snack', Object.assign(Object.assign({}, themeDataWithoutBase), { base: 'vs' }));
87
- const mergedOptions = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign({}, CODE_EDITOR_OPTIONS), (language === 'yaml' ? YAML_CODE_EDITOR_OPTIONS : {})), ((themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono)
83
+ const mergedOptions = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign({}, CODE_EDITOR_OPTIONS), jsonSchemaOptions), ((themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono)
88
84
  ? {
89
85
  fontSize: Number.parseFloat(themeValues.mono.body.s['font-size']),
90
86
  fontWeight: themeValues.mono.body.s['font-weight'],
91
87
  fontFamily: themeValues.mono.body.s['font-family'],
92
88
  }
93
- : DEFAULT_THEME_OPTIONS.mono.s)), options)), [options, language, themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono]);
94
- return (_jsx("div", Object.assign({ className: className }, extractSupportProps(props), { ref: setWrapperElement, children: _jsx(Editor, Object.assign({}, props, { theme: theme !== null && theme !== void 0 ? theme : (dark ? 'snackDark' : 'snack'), className: cn({ [styles.editor]: hasBackground }), loading: loading !== null && loading !== void 0 ? loading : _jsx(Spinner, {}), options: mergedOptions, onMount: onEditorMount, path: modelPath })) })));
89
+ : DEFAULT_THEME_OPTIONS.mono.s)), options)), [options, themeValues === null || themeValues === void 0 ? void 0 : themeValues.mono, jsonSchemaOptions]);
90
+ return (_jsx("div", Object.assign({ className: className }, extractSupportProps(props), { ref: setWrapperElement, children: _jsx(Editor, Object.assign({}, props, jsonSchemaProps, { theme: theme !== null && theme !== void 0 ? theme : (dark ? 'snackDark' : 'snack'), className: cn({ [styles.editor]: hasBackground }), loading: loading !== null && loading !== void 0 ? loading : _jsx(Spinner, {}), options: mergedOptions, onMount: onEditorMount, language: language })) })));
95
91
  }
@@ -104,3 +104,4 @@ export declare const YAML_CODE_EDITOR_OPTIONS: {
104
104
  strings: boolean;
105
105
  };
106
106
  };
107
+ export declare const DEFAULT_SCHEMA_URI = "schema://editor-schema";
@@ -100,3 +100,4 @@ export const YAML_CODE_EDITOR_OPTIONS = {
100
100
  strings: true,
101
101
  },
102
102
  };
103
+ export const DEFAULT_SCHEMA_URI = 'schema://editor-schema';
@@ -1,4 +1,4 @@
1
- import { SchemasSettings } from 'monaco-yaml';
1
+ import { JsonSchema } from './types';
2
2
  type UseCalculatedThemeValuesProps = {
3
3
  stylesOriginNode: HTMLDivElement | null;
4
4
  themeName?: string;
@@ -42,6 +42,10 @@ export declare function useCalculatedThemeValues({ stylesOriginNode, themeName }
42
42
  };
43
43
  };
44
44
  } | undefined;
45
- export declare function useYamlEditor(yamlSchema?: SchemasSettings): string | undefined;
46
- export declare function useJsonEditor(jsonSchema?: SchemasSettings): void;
45
+ export declare function useApplyJsonSchema(language?: string, jsonSchema?: JsonSchema): {
46
+ jsonSchemaProps: {
47
+ path: string | undefined;
48
+ };
49
+ jsonSchemaOptions: import("monaco-editor").editor.IStandaloneEditorConstructionOptions | undefined;
50
+ };
47
51
  export {};
@@ -1,8 +1,9 @@
1
1
  import { useMonaco } from '@monaco-editor/react';
2
2
  import { configureMonacoYaml } from 'monaco-yaml';
3
- import { useEffect, useState } from 'react';
3
+ import { useCallback, useEffect, useMemo, useState } from 'react';
4
4
  import { useThemeContext } from '@snack-uikit/utils';
5
- import { THEME_VARS } from './constants';
5
+ import { THEME_VARS, YAML_CODE_EDITOR_OPTIONS } from './constants';
6
+ import { getJsonSchema } from './utils';
6
7
  function getThemeVars(styles) {
7
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
9
  return function mapComputedTree(tree) {
@@ -28,31 +29,55 @@ export function useCalculatedThemeValues({ stylesOriginNode, themeName }) {
28
29
  }, [stylesOriginNode, trigger]);
29
30
  return values;
30
31
  }
31
- export function useYamlEditor(yamlSchema) {
32
- var _a;
33
- const modelPath = (_a = yamlSchema === null || yamlSchema === void 0 ? void 0 : yamlSchema.fileMatch) === null || _a === void 0 ? void 0 : _a[0];
32
+ export function useApplyJsonSchema(language, jsonSchema) {
34
33
  const monaco = useMonaco();
35
- useEffect(() => {
36
- if (!yamlSchema || !monaco) {
34
+ const [jsonSchemaOptions, setJsonSchemaOptions] = useState({});
35
+ const modelPath = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.fileMatch;
36
+ const preparedJsonSchema = useMemo(() => getJsonSchema(jsonSchema), [jsonSchema]);
37
+ const configureYamlLanguage = useCallback(() => {
38
+ if (!monaco || !preparedJsonSchema) {
37
39
  return;
38
40
  }
39
41
  const model = configureMonacoYaml(monaco, {
40
42
  enableSchemaRequest: true,
41
- schemas: [yamlSchema],
43
+ schemas: [preparedJsonSchema],
42
44
  });
43
- return () => model.dispose();
44
- }, [monaco, yamlSchema]);
45
- return modelPath;
46
- }
47
- export function useJsonEditor(jsonSchema) {
48
- const monaco = useMonaco();
49
- useEffect(() => {
50
- if (!jsonSchema || !monaco) {
45
+ return {
46
+ options: YAML_CODE_EDITOR_OPTIONS,
47
+ dispose: model.dispose,
48
+ };
49
+ }, [monaco, preparedJsonSchema]);
50
+ const configureJsonLanguage = useCallback(() => {
51
+ if (!monaco || !preparedJsonSchema) {
51
52
  return;
52
53
  }
53
54
  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
54
55
  validate: true,
55
- schemas: [jsonSchema],
56
+ schemas: [preparedJsonSchema],
56
57
  });
57
- }, [monaco, jsonSchema]);
58
+ }, [monaco, preparedJsonSchema]);
59
+ const configureJsonSchema = useCallback(() => {
60
+ switch (language) {
61
+ case 'yaml':
62
+ return configureYamlLanguage();
63
+ case 'json':
64
+ return configureJsonLanguage();
65
+ default:
66
+ break;
67
+ }
68
+ }, [language, configureYamlLanguage, configureJsonLanguage]);
69
+ useEffect(() => {
70
+ var _a;
71
+ const jsonSchemaSettings = configureJsonSchema();
72
+ setJsonSchemaOptions((_a = jsonSchemaSettings === null || jsonSchemaSettings === void 0 ? void 0 : jsonSchemaSettings.options) !== null && _a !== void 0 ? _a : {});
73
+ return () => {
74
+ var _a;
75
+ setJsonSchemaOptions({});
76
+ (_a = jsonSchemaSettings === null || jsonSchemaSettings === void 0 ? void 0 : jsonSchemaSettings.dispose) === null || _a === void 0 ? void 0 : _a.call(jsonSchemaSettings);
77
+ };
78
+ }, [configureJsonSchema]);
79
+ return useMemo(() => ({
80
+ jsonSchemaProps: { path: modelPath },
81
+ jsonSchemaOptions,
82
+ }), [jsonSchemaOptions, modelPath]);
58
83
  }
@@ -1,12 +1,25 @@
1
1
  import { EditorProps as MonacoEditorProps } from '@monaco-editor/react';
2
- import { SchemasSettings } from 'monaco-yaml';
3
- export type EditorProps = {
4
- schema?: never;
5
- } & MonacoEditorProps;
6
- export type EditorWithSchemaProps = {
7
- language: 'yaml' | 'json';
2
+ import { JSONSchema } from 'monaco-yaml';
3
+ export type EditorBaseProps = MonacoEditorProps;
4
+ export type SupportedSchemaLanguage = 'json' | 'yaml';
5
+ export type JsonSchema = {
6
+ uri?: string;
7
+ schema?: JSONSchema;
8
+ fileMatch: string;
9
+ };
10
+ export type WithJsonSchema = {
8
11
  /**
9
12
  * Схема для валидации
10
13
  */
11
- schema?: SchemasSettings;
12
- } & Omit<MonacoEditorProps, 'language'>;
14
+ jsonSchema: JsonSchema;
15
+ path?: never;
16
+ };
17
+ type WithoutJsonSchema = Pick<MonacoEditorProps, 'path'>;
18
+ export type EditorWithJsonSchemaProps = Omit<EditorBaseProps, 'language' | 'path'> & {
19
+ language: SupportedSchemaLanguage;
20
+ } & (WithJsonSchema | WithoutJsonSchema);
21
+ export type ConfigureJsonSchemaReturn = {
22
+ options?: MonacoEditorProps['options'];
23
+ dispose?: () => void;
24
+ } | undefined;
25
+ export {};
@@ -1,3 +1,6 @@
1
+ import { SchemasSettings } from 'monaco-yaml';
2
+ import { JsonSchema } from './types';
1
3
  export declare function rgb2hsl(HTMLcolor: string): number[];
2
4
  export declare function isDark(color: string): boolean;
3
5
  export declare function initLoaderConfig(): void;
6
+ export declare const getJsonSchema: (jsonSchema?: JsonSchema) => SchemasSettings | undefined;
@@ -1,5 +1,6 @@
1
1
  import { loader } from '@monaco-editor/react';
2
2
  import chroma from 'chroma-js';
3
+ import { DEFAULT_SCHEMA_URI } from './constants';
3
4
  export function rgb2hsl(HTMLcolor) {
4
5
  const [r, g, b] = chroma.valid(HTMLcolor)
5
6
  ? chroma(HTMLcolor)
@@ -45,3 +46,4 @@ export function initLoaderConfig() {
45
46
  // @ts-ignore
46
47
  window['__snack-code-editor-loader-config__'] && loader.config(window['__snack-code-editor-loader-config__']);
47
48
  }
49
+ export const getJsonSchema = (jsonSchema) => jsonSchema && Object.assign(Object.assign({}, jsonSchema), { uri: (jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.uri) || DEFAULT_SCHEMA_URI, fileMatch: [jsonSchema.fileMatch] });
@@ -2,5 +2,5 @@
2
2
  Monaco loader defines the way how monaco will be loaded.
3
3
  @see https://github.com/suren-atoyan/monaco-react/tree/master?tab=readme-ov-file#loader-config
4
4
  */
5
- export { loader } from '@monaco-editor/react';
5
+ export { loader, useMonaco } from '@monaco-editor/react';
6
6
  export * from './components';
package/dist/esm/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Monaco loader defines the way how monaco will be loaded.
3
3
  @see https://github.com/suren-atoyan/monaco-react/tree/master?tab=readme-ov-file#loader-config
4
4
  */
5
- export { loader } from '@monaco-editor/react';
5
+ export { loader, useMonaco } from '@monaco-editor/react';
6
6
  export * from './components';
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.4.7-preview-e698fca9.0",
7
+ "version": "0.4.7-preview-2af706c7.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -46,5 +46,5 @@
46
46
  "devDependencies": {
47
47
  "@types/chroma-js": "2.4.4"
48
48
  },
49
- "gitHead": "47cf244ae899e49b7cffec403d0c31648dfc3999"
49
+ "gitHead": "eee00bc3192c976778bbc1995fed33e98d0f16dc"
50
50
  }
@@ -5,15 +5,10 @@ import { useCallback, useMemo, useState } from 'react';
5
5
  import { Spinner } from '@snack-uikit/loaders';
6
6
  import { extractSupportProps, isBrowser, WithSupportProps } from '@snack-uikit/utils';
7
7
 
8
- import {
9
- CODE_EDITOR_OPTIONS,
10
- DEFAULT_THEME_OPTIONS,
11
- DEFAULT_THEME_VALUES,
12
- YAML_CODE_EDITOR_OPTIONS,
13
- } from './constants';
14
- import { useCalculatedThemeValues, useJsonEditor, useYamlEditor } from './hooks';
8
+ import { CODE_EDITOR_OPTIONS, DEFAULT_THEME_OPTIONS, DEFAULT_THEME_VALUES } from './constants';
9
+ import { useApplyJsonSchema, useCalculatedThemeValues } from './hooks';
15
10
  import styles from './styles.module.scss';
16
- import { EditorProps, EditorWithSchemaProps } from './types';
11
+ import { EditorBaseProps, EditorWithJsonSchemaProps } from './types';
17
12
  import { initLoaderConfig, isDark } from './utils';
18
13
 
19
14
  initLoaderConfig();
@@ -28,7 +23,7 @@ export type CodeEditorProps = WithSupportProps<{
28
23
  */
29
24
  hasBackground?: boolean;
30
25
  }> &
31
- (EditorProps | EditorWithSchemaProps);
26
+ (EditorBaseProps | EditorWithJsonSchemaProps);
32
27
 
33
28
  export function CodeEditor({
34
29
  themeName,
@@ -38,16 +33,16 @@ export function CodeEditor({
38
33
  loading,
39
34
  hasBackground = true,
40
35
  onMount,
36
+ language,
41
37
  ...props
42
38
  }: CodeEditorProps) {
43
- const { language } = props;
44
-
45
39
  const monaco = useMonaco();
46
40
  const [wrapperElement, setWrapperElement] = useState<HTMLDivElement | null>(null);
47
41
 
48
- const modelPath = 'schema' in props ? props.schema?.fileMatch?.[0] : undefined;
49
- useYamlEditor(props.language === 'yaml' ? props.schema : undefined);
50
- useJsonEditor(props.language === 'json' ? props.schema : undefined);
42
+ const { jsonSchemaProps, jsonSchemaOptions } = useApplyJsonSchema(
43
+ language,
44
+ 'jsonSchema' in props ? props.jsonSchema : undefined,
45
+ );
51
46
 
52
47
  const onEditorMount = useCallback<OnMount>(
53
48
  (editor, monaco) => {
@@ -123,7 +118,7 @@ export function CodeEditor({
123
118
  const mergedOptions = useMemo(
124
119
  () => ({
125
120
  ...CODE_EDITOR_OPTIONS,
126
- ...(language === 'yaml' ? YAML_CODE_EDITOR_OPTIONS : {}),
121
+ ...jsonSchemaOptions,
127
122
  ...(themeValues?.mono
128
123
  ? {
129
124
  fontSize: Number.parseFloat(themeValues.mono.body.s['font-size']),
@@ -133,19 +128,20 @@ export function CodeEditor({
133
128
  : DEFAULT_THEME_OPTIONS.mono.s),
134
129
  ...options,
135
130
  }),
136
- [options, language, themeValues?.mono],
131
+ [options, themeValues?.mono, jsonSchemaOptions],
137
132
  );
138
133
 
139
134
  return (
140
135
  <div className={className} {...extractSupportProps(props)} ref={setWrapperElement}>
141
136
  <Editor
142
137
  {...props}
138
+ {...jsonSchemaProps}
143
139
  theme={theme ?? (dark ? 'snackDark' : 'snack')}
144
140
  className={cn({ [styles.editor]: hasBackground })}
145
141
  loading={loading ?? <Spinner />}
146
142
  options={mergedOptions}
147
143
  onMount={onEditorMount}
148
- path={modelPath}
144
+ language={language}
149
145
  />
150
146
  </div>
151
147
  );
@@ -104,3 +104,5 @@ export const YAML_CODE_EDITOR_OPTIONS = {
104
104
  strings: true,
105
105
  },
106
106
  };
107
+
108
+ export const DEFAULT_SCHEMA_URI = 'schema://editor-schema';
@@ -1,10 +1,12 @@
1
- import { useMonaco } from '@monaco-editor/react';
1
+ import { EditorProps as MonacoEditorProps, useMonaco } from '@monaco-editor/react';
2
2
  import { configureMonacoYaml, SchemasSettings } from 'monaco-yaml';
3
- import { useEffect, useState } from 'react';
3
+ import { useCallback, useEffect, useMemo, useState } from 'react';
4
4
 
5
5
  import { useThemeContext } from '@snack-uikit/utils';
6
6
 
7
- import { THEME_VARS } from './constants';
7
+ import { THEME_VARS, YAML_CODE_EDITOR_OPTIONS } from './constants';
8
+ import { ConfigureJsonSchemaReturn, JsonSchema } from './types';
9
+ import { getJsonSchema } from './utils';
8
10
 
9
11
  function getThemeVars(styles: CSSStyleDeclaration) {
10
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -45,37 +47,67 @@ export function useCalculatedThemeValues({ stylesOriginNode, themeName }: UseCal
45
47
  return values;
46
48
  }
47
49
 
48
- export function useYamlEditor(yamlSchema?: SchemasSettings) {
49
- const modelPath = yamlSchema?.fileMatch?.[0];
50
+ export function useApplyJsonSchema(language?: string, jsonSchema?: JsonSchema) {
50
51
  const monaco = useMonaco();
51
52
 
52
- useEffect(() => {
53
- if (!yamlSchema || !monaco) {
53
+ const [jsonSchemaOptions, setJsonSchemaOptions] = useState<MonacoEditorProps['options']>({});
54
+ const modelPath = jsonSchema?.fileMatch;
55
+
56
+ const preparedJsonSchema: SchemasSettings | undefined = useMemo(() => getJsonSchema(jsonSchema), [jsonSchema]);
57
+
58
+ const configureYamlLanguage = useCallback((): ConfigureJsonSchemaReturn => {
59
+ if (!monaco || !preparedJsonSchema) {
54
60
  return;
55
61
  }
56
62
 
57
63
  const model = configureMonacoYaml(monaco, {
58
64
  enableSchemaRequest: true,
59
- schemas: [yamlSchema],
65
+ schemas: [preparedJsonSchema],
60
66
  });
61
67
 
62
- return () => model.dispose();
63
- }, [monaco, yamlSchema]);
68
+ return {
69
+ options: YAML_CODE_EDITOR_OPTIONS,
70
+ dispose: model.dispose,
71
+ };
72
+ }, [monaco, preparedJsonSchema]);
64
73
 
65
- return modelPath;
66
- }
67
-
68
- export function useJsonEditor(jsonSchema?: SchemasSettings) {
69
- const monaco = useMonaco();
70
-
71
- useEffect(() => {
72
- if (!jsonSchema || !monaco) {
74
+ const configureJsonLanguage = useCallback((): ConfigureJsonSchemaReturn => {
75
+ if (!monaco || !preparedJsonSchema) {
73
76
  return;
74
77
  }
75
78
 
76
79
  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
77
80
  validate: true,
78
- schemas: [jsonSchema],
81
+ schemas: [preparedJsonSchema],
79
82
  });
80
- }, [monaco, jsonSchema]);
83
+ }, [monaco, preparedJsonSchema]);
84
+
85
+ const configureJsonSchema = useCallback(() => {
86
+ switch (language) {
87
+ case 'yaml':
88
+ return configureYamlLanguage();
89
+ case 'json':
90
+ return configureJsonLanguage();
91
+ default:
92
+ break;
93
+ }
94
+ }, [language, configureYamlLanguage, configureJsonLanguage]);
95
+
96
+ useEffect(() => {
97
+ const jsonSchemaSettings = configureJsonSchema();
98
+ setJsonSchemaOptions(jsonSchemaSettings?.options ?? {});
99
+
100
+ return () => {
101
+ setJsonSchemaOptions({});
102
+ jsonSchemaSettings?.dispose?.();
103
+ };
104
+ }, [configureJsonSchema]);
105
+
106
+ return useMemo(
107
+ () => ({
108
+ jsonSchemaProps: { path: modelPath } satisfies MonacoEditorProps,
109
+ jsonSchemaOptions,
110
+ }),
111
+ [jsonSchemaOptions, modelPath],
112
+ );
81
113
  }
@@ -1,14 +1,33 @@
1
1
  import { EditorProps as MonacoEditorProps } from '@monaco-editor/react';
2
- import { SchemasSettings } from 'monaco-yaml';
2
+ import { JSONSchema } from 'monaco-yaml';
3
3
 
4
- export type EditorProps = {
5
- schema?: never;
6
- } & MonacoEditorProps;
4
+ export type EditorBaseProps = MonacoEditorProps;
7
5
 
8
- export type EditorWithSchemaProps = {
9
- language: 'yaml' | 'json';
6
+ export type SupportedSchemaLanguage = 'json' | 'yaml';
7
+
8
+ export type JsonSchema = {
9
+ uri?: string;
10
+ schema?: JSONSchema;
11
+ fileMatch: string;
12
+ };
13
+
14
+ export type WithJsonSchema = {
10
15
  /**
11
16
  * Схема для валидации
12
17
  */
13
- schema?: SchemasSettings;
14
- } & Omit<MonacoEditorProps, 'language'>;
18
+ jsonSchema: JsonSchema;
19
+ path?: never;
20
+ };
21
+
22
+ type WithoutJsonSchema = Pick<MonacoEditorProps, 'path'>;
23
+
24
+ export type EditorWithJsonSchemaProps = Omit<EditorBaseProps, 'language' | 'path'> & {
25
+ language: SupportedSchemaLanguage;
26
+ } & (WithJsonSchema | WithoutJsonSchema);
27
+
28
+ export type ConfigureJsonSchemaReturn =
29
+ | {
30
+ options?: MonacoEditorProps['options'];
31
+ dispose?: () => void;
32
+ }
33
+ | undefined;
@@ -1,5 +1,9 @@
1
1
  import { loader } from '@monaco-editor/react';
2
2
  import chroma from 'chroma-js';
3
+ import { SchemasSettings } from 'monaco-yaml';
4
+
5
+ import { DEFAULT_SCHEMA_URI } from './constants';
6
+ import { JsonSchema } from './types';
3
7
 
4
8
  export function rgb2hsl(HTMLcolor: string) {
5
9
  const [r, g, b] = chroma.valid(HTMLcolor)
@@ -60,3 +64,6 @@ export function initLoaderConfig() {
60
64
  // @ts-ignore
61
65
  window['__snack-code-editor-loader-config__'] && loader.config(window['__snack-code-editor-loader-config__']);
62
66
  }
67
+
68
+ export const getJsonSchema = (jsonSchema?: JsonSchema): SchemasSettings | undefined =>
69
+ jsonSchema && { ...jsonSchema, uri: jsonSchema?.uri || DEFAULT_SCHEMA_URI, fileMatch: [jsonSchema.fileMatch] };
package/src/index.ts CHANGED
@@ -2,5 +2,5 @@
2
2
  Monaco loader defines the way how monaco will be loaded.
3
3
  @see https://github.com/suren-atoyan/monaco-react/tree/master?tab=readme-ov-file#loader-config
4
4
  */
5
- export { loader } from '@monaco-editor/react';
5
+ export { loader, useMonaco } from '@monaco-editor/react';
6
6
  export * from './components';