@pallasoft/ps-input-components 2.2.0 → 3.0.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/dist/components/ps-portable-text-editor.d.ts +1 -1
- package/dist/components/ps-portable-text-editor.js +1 -2
- package/dist/components/ps-portable-text-link-dialog.d.ts +2 -1
- package/dist/components/ps-portable-text-link-dialog.js +2 -2
- package/dist/components/ps-portable-text-toolbar.js +2 -7
- package/dist/constants/ps-portable-text-editor-config.d.ts +8 -0
- package/dist/constants/ps-portable-text-editor-config.js +8 -0
- package/dist/esm/components/ps-portable-text-editor.js +1 -2
- package/dist/esm/components/ps-portable-text-link-dialog.js +2 -2
- package/dist/esm/components/ps-portable-text-toolbar.js +2 -7
- package/dist/esm/constants/ps-portable-text-editor-config.js +8 -0
- package/dist/esm/portable-text-core/components/ps-portable-text-core-editor-stub.js +2 -0
- package/dist/esm/portable-text-core/components/ps-portable-text-core-editor.js +64 -0
- package/dist/esm/portable-text-core/components/ps-portable-text-core.js +5 -26
- package/dist/esm/portable-text-core/constants/ps-portable-text-core-config.js +29 -9
- package/dist/esm/portable-text-core/contexts/ps-portable-text-core-context.js +9 -0
- package/dist/esm/portable-text-core/hooks/use-ps-portable-text-link-form.js +11 -5
- package/dist/esm/portable-text-core/hooks/use-ps-portable-text-toolbar.js +17 -49
- package/dist/esm/portable-text-core/index.js +4 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-active-formats.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-block-draft.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-core-class-names.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-core-context-data.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-core-props.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-extension-options.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-span-draft.js +1 -0
- package/dist/esm/portable-text-core/interfaces/ps-portable-text-toolbar-state.js +1 -0
- package/dist/esm/portable-text-core/services/ps-portable-text-command-service.js +73 -0
- package/dist/esm/portable-text-core/services/ps-portable-text-converter-service.js +196 -0
- package/dist/esm/portable-text-core/services/ps-portable-text-editor-service.js +4 -0
- package/dist/esm/portable-text-core/services/ps-portable-text-extension-service.js +89 -0
- package/dist/esm/portable-text-engine/index.js +1 -0
- package/dist/esm/portable-text-engine/worker.js +1 -0
- package/dist/portable-text/index.d.ts +1 -1
- package/dist/portable-text-core/components/ps-portable-text-core-editor-stub.d.ts +2 -0
- package/dist/portable-text-core/components/ps-portable-text-core-editor-stub.js +6 -0
- package/dist/portable-text-core/components/ps-portable-text-core-editor.d.ts +2 -0
- package/dist/portable-text-core/components/ps-portable-text-core-editor.js +68 -0
- package/dist/portable-text-core/components/ps-portable-text-core.d.ts +2 -17
- package/dist/portable-text-core/components/ps-portable-text-core.js +3 -24
- package/dist/portable-text-core/constants/ps-portable-text-core-config.d.ts +36 -19
- package/dist/portable-text-core/constants/ps-portable-text-core-config.js +29 -9
- package/dist/portable-text-core/contexts/ps-portable-text-core-context.d.ts +2 -0
- package/dist/portable-text-core/contexts/ps-portable-text-core-context.js +12 -0
- package/dist/portable-text-core/hooks/use-ps-portable-text-link-form.d.ts +3 -1
- package/dist/portable-text-core/hooks/use-ps-portable-text-link-form.js +10 -4
- package/dist/portable-text-core/hooks/use-ps-portable-text-toolbar.d.ts +5 -10
- package/dist/portable-text-core/hooks/use-ps-portable-text-toolbar.js +17 -49
- package/dist/portable-text-core/index.d.ts +5 -1
- package/dist/portable-text-core/index.js +4 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-active-formats.d.ts +10 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-active-formats.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-block-draft.d.ts +7 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-block-draft.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-class-names.d.ts +8 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-class-names.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-context-data.d.ts +9 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-context-data.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-props.d.ts +16 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-core-props.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-editor-labels.d.ts +1 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-extension-options.d.ts +6 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-extension-options.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-span-draft.d.ts +4 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-span-draft.js +2 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-toolbar-state.d.ts +5 -0
- package/dist/portable-text-core/interfaces/ps-portable-text-toolbar-state.js +2 -0
- package/dist/portable-text-core/services/ps-portable-text-command-service.d.ts +14 -0
- package/dist/portable-text-core/services/ps-portable-text-command-service.js +77 -0
- package/dist/portable-text-core/services/ps-portable-text-converter-service.d.ts +18 -0
- package/dist/portable-text-core/services/ps-portable-text-converter-service.js +200 -0
- package/dist/portable-text-core/services/ps-portable-text-editor-service.d.ts +1 -0
- package/dist/portable-text-core/services/ps-portable-text-editor-service.js +4 -0
- package/dist/portable-text-core/services/ps-portable-text-extension-service.d.ts +8 -0
- package/dist/portable-text-core/services/ps-portable-text-extension-service.js +93 -0
- package/dist/portable-text-engine/index.d.ts +1 -0
- package/dist/portable-text-engine/index.js +17 -0
- package/dist/portable-text-engine/worker.d.ts +1 -0
- package/dist/portable-text-engine/worker.js +17 -0
- package/package.json +29 -5
- package/dist/constants/ps-portable-text-editor-renderers.d.ts +0 -6
- package/dist/constants/ps-portable-text-editor-renderers.js +0 -32
- package/dist/esm/constants/ps-portable-text-editor-renderers.js +0 -29
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PortableTextBlock } from '@portabletext/
|
|
1
|
+
import type { PortableTextBlock } from '@portabletext/schema';
|
|
2
2
|
import type { PsPortableTextEditorLabels } from '../portable-text-core/interfaces/ps-portable-text-editor-labels';
|
|
3
3
|
export interface PsPortableTextEditorProps {
|
|
4
4
|
className?: string;
|
|
@@ -4,10 +4,9 @@ exports.PsPortableTextEditor = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
6
|
const ps_portable_text_editor_config_1 = require("../constants/ps-portable-text-editor-config");
|
|
7
|
-
const ps_portable_text_editor_renderers_1 = require("../constants/ps-portable-text-editor-renderers");
|
|
8
7
|
const ps_portable_text_core_1 = require("../portable-text-core/components/ps-portable-text-core");
|
|
9
8
|
const ps_portable_text_core_config_1 = require("../portable-text-core/constants/ps-portable-text-core-config");
|
|
10
9
|
const ps_portable_text_editor_service_1 = require("../portable-text-core/services/ps-portable-text-editor-service");
|
|
11
10
|
const ps_portable_text_toolbar_1 = require("./ps-portable-text-toolbar");
|
|
12
|
-
const PsPortableTextEditor = ({ className, disabled = false, labels = ps_portable_text_core_config_1.PsPortableTextCoreConfig.labels, minRows = 4, onChange, placeholder, value, }) => ((0, jsx_runtime_1.jsx)(ps_portable_text_core_1.PsPortableTextCore, {
|
|
11
|
+
const PsPortableTextEditor = ({ className, disabled = false, labels = ps_portable_text_core_config_1.PsPortableTextCoreConfig.labels, minRows = 4, onChange, placeholder, value, }) => ((0, jsx_runtime_1.jsx)(ps_portable_text_core_1.PsPortableTextCore, { className: ps_design_system_1.PallasoftClassNameService.merge(ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.root, className), classNames: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.contentClassNames, disabled: disabled, editableClassName: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.editable, fallback: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { "aria-hidden": 'true', className: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.toolbar, children: (0, jsx_runtime_1.jsx)("span", { className: 'h-9' }) }), (0, jsx_runtime_1.jsx)("div", { "aria-hidden": 'true', className: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.editable, style: { minHeight: ps_portable_text_editor_service_1.PsPortableTextEditorService.minHeight(minRows) } })] }), label: labels.editor, minRows: minRows, onChange: onChange, placeholder: placeholder, toolbar: (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_1.PsPortableTextToolbar, { disabled: disabled, labels: labels }), value: value }));
|
|
13
12
|
exports.PsPortableTextEditor = PsPortableTextEditor;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { PsPortableTextEditorLabels } from '../portable-text-core/interfaces/ps-portable-text-editor-labels';
|
|
2
2
|
export interface PsPortableTextLinkDialogProps {
|
|
3
|
+
href?: string;
|
|
3
4
|
isOpen: boolean;
|
|
4
5
|
labels: PsPortableTextEditorLabels;
|
|
5
6
|
onClose: () => void;
|
|
6
7
|
onSubmit: (href: string) => void;
|
|
7
8
|
}
|
|
8
|
-
export declare const PsPortableTextLinkDialog: ({ isOpen, labels, onClose, onSubmit, }: PsPortableTextLinkDialogProps) => import("react").JSX.Element;
|
|
9
|
+
export declare const PsPortableTextLinkDialog: ({ href, isOpen, labels, onClose, onSubmit, }: PsPortableTextLinkDialogProps) => import("react").JSX.Element;
|
|
@@ -6,8 +6,8 @@ const ps_popovers_1 = require("@pallasoft/ps-popovers");
|
|
|
6
6
|
const ps_portable_text_core_config_1 = require("../portable-text-core/constants/ps-portable-text-core-config");
|
|
7
7
|
const use_ps_portable_text_link_form_1 = require("../portable-text-core/hooks/use-ps-portable-text-link-form");
|
|
8
8
|
const ps_url_input_1 = require("./ps-url-input");
|
|
9
|
-
const PsPortableTextLinkDialog = ({ isOpen, labels, onClose, onSubmit, }) => {
|
|
10
|
-
const form = (0, use_ps_portable_text_link_form_1.usePsPortableTextLinkForm)({ onClose, onSubmit });
|
|
9
|
+
const PsPortableTextLinkDialog = ({ href, isOpen, labels, onClose, onSubmit, }) => {
|
|
10
|
+
const form = (0, use_ps_portable_text_link_form_1.usePsPortableTextLinkForm)({ href, isOpen, onClose, onSubmit });
|
|
11
11
|
return ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsFormModal, { cancelLabel: labels.cancel, isOpen: isOpen, isSubmitDisabled: form.isSubmitDisabled, onClose: form.close, onSubmit: form.submit, size: 'sm', submitLabel: labels.saveLink, title: labels.linkDialogTitle, children: (0, jsx_runtime_1.jsx)(ps_url_input_1.PsUrlInput, { "aria-invalid": form.hasError, autoFocus: true, helperText: form.hasError ? labels.invalidLink : undefined, label: labels.linkUrl, name: ps_portable_text_core_config_1.PsPortableTextCoreConfig.linkAnnotation, onChange: (event) => form.setAddress(event.target.value), value: form.address }) }));
|
|
12
12
|
};
|
|
13
13
|
exports.PsPortableTextLinkDialog = PsPortableTextLinkDialog;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsPortableTextToolbar = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const react_1 = require("react");
|
|
6
5
|
const ps_portable_text_editor_config_1 = require("../constants/ps-portable-text-editor-config");
|
|
7
6
|
const ps_portable_text_core_config_1 = require("../portable-text-core/constants/ps-portable-text-core-config");
|
|
8
7
|
const use_ps_portable_text_toolbar_1 = require("../portable-text-core/hooks/use-ps-portable-text-toolbar");
|
|
@@ -10,13 +9,9 @@ const ps_portable_text_link_dialog_1 = require("./ps-portable-text-link-dialog")
|
|
|
10
9
|
const ps_portable_text_toolbar_button_1 = require("./ps-portable-text-toolbar-button");
|
|
11
10
|
const PsPortableTextToolbar = ({ disabled, labels }) => {
|
|
12
11
|
const toolbar = (0, use_ps_portable_text_toolbar_1.usePsPortableTextToolbar)();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
setIsLinkOpen(false);
|
|
16
|
-
toolbar.focus();
|
|
17
|
-
}, onSubmit: (href) => {
|
|
12
|
+
return ((0, jsx_runtime_1.jsxs)("div", { "aria-label": labels.toolbar, className: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.toolbar, role: 'toolbar', children: [(0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { className: 'font-bold', disabled: disabled, isActive: toolbar.active.bold, label: labels.bold, onClick: () => toolbar.toggleDecorator(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.bold), children: "B" }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { className: 'italic', disabled: disabled, isActive: toolbar.active.italic, label: labels.italic, onClick: () => toolbar.toggleDecorator(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.italic), children: "I" }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { className: 'underline', disabled: disabled, isActive: toolbar.active.underline, label: labels.underline, onClick: () => toolbar.toggleDecorator(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.underline), children: "U" }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { className: 'font-mono', disabled: disabled, isActive: toolbar.active.code, label: labels.code, onClick: () => toolbar.toggleDecorator(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.code), children: '</>' }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.link, label: toolbar.active.link ? labels.removeLink : labels.link, onClick: () => (toolbar.active.link ? toolbar.removeLink() : toolbar.openLink()), children: (0, jsx_runtime_1.jsx)("span", { className: 'underline', children: labels.link }) }), (0, jsx_runtime_1.jsx)(ps_portable_text_link_dialog_1.PsPortableTextLinkDialog, { href: toolbar.linkHref, isOpen: toolbar.isLinkOpen, labels: labels, onClose: toolbar.closeLink, onSubmit: (href) => {
|
|
13
|
+
toolbar.closeLink();
|
|
18
14
|
toolbar.addLink(href);
|
|
19
|
-
setIsLinkOpen(false);
|
|
20
15
|
} }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: ps_portable_text_editor_config_1.PsPortableTextEditorConfig.classNames.separator }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.bulletedList, label: labels.bulletedList, onClick: () => toolbar.toggleListItem(ps_portable_text_core_config_1.PsPortableTextCoreConfig.listItems.bullet), children: "\u2022" }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.numberedList, label: labels.numberedList, onClick: () => toolbar.toggleListItem(ps_portable_text_core_config_1.PsPortableTextCoreConfig.listItems.number), children: "1." }), (0, jsx_runtime_1.jsx)(ps_portable_text_toolbar_button_1.PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.quote, label: labels.quote, onClick: toolbar.toggleQuote, children: "\u201D" })] }));
|
|
21
16
|
};
|
|
22
17
|
exports.PsPortableTextToolbar = PsPortableTextToolbar;
|
|
@@ -7,4 +7,12 @@ export declare const PsPortableTextEditorConfig: {
|
|
|
7
7
|
readonly buttonActive: "bg-primary text-white hover:bg-primary hover:text-white";
|
|
8
8
|
readonly separator: "mx-1 h-5 w-px bg-line";
|
|
9
9
|
};
|
|
10
|
+
readonly contentClassNames: {
|
|
11
|
+
readonly blockquote: "border-l-2 border-primary pl-3 text-ink/80";
|
|
12
|
+
readonly bulletList: "list-disc pl-6";
|
|
13
|
+
readonly code: "rounded bg-ink/10 px-1 font-mono text-[0.9em]";
|
|
14
|
+
readonly link: "text-primary underline";
|
|
15
|
+
readonly orderedList: "list-decimal pl-6";
|
|
16
|
+
readonly placeholder: "before:pointer-events-none before:float-left before:h-0 before:text-ink/45 before:content-[attr(data-placeholder)]";
|
|
17
|
+
};
|
|
10
18
|
};
|
|
@@ -10,4 +10,12 @@ exports.PsPortableTextEditorConfig = {
|
|
|
10
10
|
buttonActive: 'bg-primary text-white hover:bg-primary hover:text-white',
|
|
11
11
|
separator: 'mx-1 h-5 w-px bg-line',
|
|
12
12
|
},
|
|
13
|
+
contentClassNames: {
|
|
14
|
+
blockquote: 'border-l-2 border-primary pl-3 text-ink/80',
|
|
15
|
+
bulletList: 'list-disc pl-6',
|
|
16
|
+
code: 'rounded bg-ink/10 px-1 font-mono text-[0.9em]',
|
|
17
|
+
link: 'text-primary underline',
|
|
18
|
+
orderedList: 'list-decimal pl-6',
|
|
19
|
+
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-ink/45 before:content-[attr(data-placeholder)]',
|
|
20
|
+
},
|
|
13
21
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
3
|
import { PsPortableTextEditorConfig } from '../constants/ps-portable-text-editor-config';
|
|
4
|
-
import { PsPortableTextEditorRenderers } from '../constants/ps-portable-text-editor-renderers';
|
|
5
4
|
import { PsPortableTextCore } from '../portable-text-core/components/ps-portable-text-core';
|
|
6
5
|
import { PsPortableTextCoreConfig } from '../portable-text-core/constants/ps-portable-text-core-config';
|
|
7
6
|
import { PsPortableTextEditorService } from '../portable-text-core/services/ps-portable-text-editor-service';
|
|
8
7
|
import { PsPortableTextToolbar } from './ps-portable-text-toolbar';
|
|
9
|
-
export const PsPortableTextEditor = ({ className, disabled = false, labels = PsPortableTextCoreConfig.labels, minRows = 4, onChange, placeholder, value, }) => (_jsx(PsPortableTextCore, {
|
|
8
|
+
export const PsPortableTextEditor = ({ className, disabled = false, labels = PsPortableTextCoreConfig.labels, minRows = 4, onChange, placeholder, value, }) => (_jsx(PsPortableTextCore, { className: PallasoftClassNameService.merge(PsPortableTextEditorConfig.classNames.root, className), classNames: PsPortableTextEditorConfig.contentClassNames, disabled: disabled, editableClassName: PsPortableTextEditorConfig.classNames.editable, fallback: _jsxs(_Fragment, { children: [_jsx("div", { "aria-hidden": 'true', className: PsPortableTextEditorConfig.classNames.toolbar, children: _jsx("span", { className: 'h-9' }) }), _jsx("div", { "aria-hidden": 'true', className: PsPortableTextEditorConfig.classNames.editable, style: { minHeight: PsPortableTextEditorService.minHeight(minRows) } })] }), label: labels.editor, minRows: minRows, onChange: onChange, placeholder: placeholder, toolbar: _jsx(PsPortableTextToolbar, { disabled: disabled, labels: labels }), value: value }));
|
|
@@ -3,7 +3,7 @@ import { PsFormModal } from '@pallasoft/ps-popovers';
|
|
|
3
3
|
import { PsPortableTextCoreConfig } from '../portable-text-core/constants/ps-portable-text-core-config';
|
|
4
4
|
import { usePsPortableTextLinkForm } from '../portable-text-core/hooks/use-ps-portable-text-link-form';
|
|
5
5
|
import { PsUrlInput } from './ps-url-input';
|
|
6
|
-
export const PsPortableTextLinkDialog = ({ isOpen, labels, onClose, onSubmit, }) => {
|
|
7
|
-
const form = usePsPortableTextLinkForm({ onClose, onSubmit });
|
|
6
|
+
export const PsPortableTextLinkDialog = ({ href, isOpen, labels, onClose, onSubmit, }) => {
|
|
7
|
+
const form = usePsPortableTextLinkForm({ href, isOpen, onClose, onSubmit });
|
|
8
8
|
return (_jsx(PsFormModal, { cancelLabel: labels.cancel, isOpen: isOpen, isSubmitDisabled: form.isSubmitDisabled, onClose: form.close, onSubmit: form.submit, size: 'sm', submitLabel: labels.saveLink, title: labels.linkDialogTitle, children: _jsx(PsUrlInput, { "aria-invalid": form.hasError, autoFocus: true, helperText: form.hasError ? labels.invalidLink : undefined, label: labels.linkUrl, name: PsPortableTextCoreConfig.linkAnnotation, onChange: (event) => form.setAddress(event.target.value), value: form.address }) }));
|
|
9
9
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
2
|
import { PsPortableTextEditorConfig } from '../constants/ps-portable-text-editor-config';
|
|
4
3
|
import { PsPortableTextCoreConfig } from '../portable-text-core/constants/ps-portable-text-core-config';
|
|
5
4
|
import { usePsPortableTextToolbar } from '../portable-text-core/hooks/use-ps-portable-text-toolbar';
|
|
@@ -7,12 +6,8 @@ import { PsPortableTextLinkDialog } from './ps-portable-text-link-dialog';
|
|
|
7
6
|
import { PsPortableTextToolbarButton } from './ps-portable-text-toolbar-button';
|
|
8
7
|
export const PsPortableTextToolbar = ({ disabled, labels }) => {
|
|
9
8
|
const toolbar = usePsPortableTextToolbar();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
setIsLinkOpen(false);
|
|
13
|
-
toolbar.focus();
|
|
14
|
-
}, onSubmit: (href) => {
|
|
9
|
+
return (_jsxs("div", { "aria-label": labels.toolbar, className: PsPortableTextEditorConfig.classNames.toolbar, role: 'toolbar', children: [_jsx(PsPortableTextToolbarButton, { className: 'font-bold', disabled: disabled, isActive: toolbar.active.bold, label: labels.bold, onClick: () => toolbar.toggleDecorator(PsPortableTextCoreConfig.decorators.bold), children: "B" }), _jsx(PsPortableTextToolbarButton, { className: 'italic', disabled: disabled, isActive: toolbar.active.italic, label: labels.italic, onClick: () => toolbar.toggleDecorator(PsPortableTextCoreConfig.decorators.italic), children: "I" }), _jsx(PsPortableTextToolbarButton, { className: 'underline', disabled: disabled, isActive: toolbar.active.underline, label: labels.underline, onClick: () => toolbar.toggleDecorator(PsPortableTextCoreConfig.decorators.underline), children: "U" }), _jsx(PsPortableTextToolbarButton, { className: 'font-mono', disabled: disabled, isActive: toolbar.active.code, label: labels.code, onClick: () => toolbar.toggleDecorator(PsPortableTextCoreConfig.decorators.code), children: '</>' }), _jsx(PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.link, label: toolbar.active.link ? labels.removeLink : labels.link, onClick: () => (toolbar.active.link ? toolbar.removeLink() : toolbar.openLink()), children: _jsx("span", { className: 'underline', children: labels.link }) }), _jsx(PsPortableTextLinkDialog, { href: toolbar.linkHref, isOpen: toolbar.isLinkOpen, labels: labels, onClose: toolbar.closeLink, onSubmit: (href) => {
|
|
10
|
+
toolbar.closeLink();
|
|
15
11
|
toolbar.addLink(href);
|
|
16
|
-
setIsLinkOpen(false);
|
|
17
12
|
} }), _jsx("span", { "aria-hidden": 'true', className: PsPortableTextEditorConfig.classNames.separator }), _jsx(PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.bulletedList, label: labels.bulletedList, onClick: () => toolbar.toggleListItem(PsPortableTextCoreConfig.listItems.bullet), children: "\u2022" }), _jsx(PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.numberedList, label: labels.numberedList, onClick: () => toolbar.toggleListItem(PsPortableTextCoreConfig.listItems.number), children: "1." }), _jsx(PsPortableTextToolbarButton, { disabled: disabled, isActive: toolbar.active.quote, label: labels.quote, onClick: toolbar.toggleQuote, children: "\u201D" })] }));
|
|
18
13
|
};
|
|
@@ -7,4 +7,12 @@ export const PsPortableTextEditorConfig = {
|
|
|
7
7
|
buttonActive: 'bg-primary text-white hover:bg-primary hover:text-white',
|
|
8
8
|
separator: 'mx-1 h-5 w-px bg-line',
|
|
9
9
|
},
|
|
10
|
+
contentClassNames: {
|
|
11
|
+
blockquote: 'border-l-2 border-primary pl-3 text-ink/80',
|
|
12
|
+
bulletList: 'list-disc pl-6',
|
|
13
|
+
code: 'rounded bg-ink/10 px-1 font-mono text-[0.9em]',
|
|
14
|
+
link: 'text-primary underline',
|
|
15
|
+
orderedList: 'list-decimal pl-6',
|
|
16
|
+
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-ink/45 before:content-[attr(data-placeholder)]',
|
|
17
|
+
},
|
|
10
18
|
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { EditorContent, useEditor, useEditorState } from '@tiptap/react';
|
|
4
|
+
import { PsPortableTextCoreContext } from '../contexts/ps-portable-text-core-context';
|
|
5
|
+
import { PsPortableTextCommandService } from '../services/ps-portable-text-command-service';
|
|
6
|
+
import { PsPortableTextConverterService } from '../services/ps-portable-text-converter-service';
|
|
7
|
+
import { PsPortableTextEditorService } from '../services/ps-portable-text-editor-service';
|
|
8
|
+
import { PsPortableTextExtensionService } from '../services/ps-portable-text-extension-service';
|
|
9
|
+
export const PsPortableTextCoreEditor = ({ className, classNames, disabled = false, editableClassName = '', label, minRows = 4, onChange, placeholder = '', toolbar, value, }) => {
|
|
10
|
+
const [isLinkOpen, setIsLinkOpen] = useState(false);
|
|
11
|
+
const lastValue = useRef(value);
|
|
12
|
+
const editor = useEditor({
|
|
13
|
+
content: PsPortableTextConverterService.toDocument(value),
|
|
14
|
+
editable: !disabled,
|
|
15
|
+
editorProps: {
|
|
16
|
+
attributes: {
|
|
17
|
+
...(label === undefined ? {} : { 'aria-label': label }),
|
|
18
|
+
'aria-multiline': 'true',
|
|
19
|
+
'class': editableClassName,
|
|
20
|
+
'role': 'textbox',
|
|
21
|
+
'style': `min-height: ${PsPortableTextEditorService.minHeight(minRows)}`,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
extensions: PsPortableTextExtensionService.extensions({
|
|
25
|
+
classNames,
|
|
26
|
+
onLinkShortcut: () => setIsLinkOpen(true),
|
|
27
|
+
placeholder,
|
|
28
|
+
}),
|
|
29
|
+
immediatelyRender: true,
|
|
30
|
+
}, []);
|
|
31
|
+
const state = useEditorState({
|
|
32
|
+
editor,
|
|
33
|
+
selector: ({ editor: current }) => PsPortableTextCommandService.state(current),
|
|
34
|
+
});
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
editor.setEditable(!disabled, false);
|
|
37
|
+
}, [editor, disabled]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const update = () => {
|
|
40
|
+
const next = PsPortableTextConverterService.toBlocks(editor.getJSON());
|
|
41
|
+
lastValue.current = next;
|
|
42
|
+
onChange(next);
|
|
43
|
+
};
|
|
44
|
+
editor.on('update', update);
|
|
45
|
+
return () => {
|
|
46
|
+
editor.off('update', update);
|
|
47
|
+
};
|
|
48
|
+
}, [editor, onChange]);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (PsPortableTextEditorService.isSame(value, lastValue.current))
|
|
51
|
+
return;
|
|
52
|
+
lastValue.current = value;
|
|
53
|
+
editor.commands.setContent(PsPortableTextConverterService.toDocument(value), {
|
|
54
|
+
emitUpdate: false,
|
|
55
|
+
});
|
|
56
|
+
}, [editor, value]);
|
|
57
|
+
return (_jsx("div", { className: className, children: _jsxs(PsPortableTextCoreContext.Provider, { value: {
|
|
58
|
+
closeLink: () => setIsLinkOpen(false),
|
|
59
|
+
editor,
|
|
60
|
+
isLinkOpen,
|
|
61
|
+
openLink: () => setIsLinkOpen(true),
|
|
62
|
+
state,
|
|
63
|
+
}, children: [toolbar, _jsx(EditorContent, { editor: editor })] }) }));
|
|
64
|
+
};
|
|
@@ -1,31 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import { useEffect,
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { PsPortableTextCoreConfig } from '../constants/ps-portable-text-core-config';
|
|
6
|
-
import { PsPortableTextEditorService } from '../services/ps-portable-text-editor-service';
|
|
7
|
-
export const PsPortableTextCore = ({ className, disabled = false, editableClassName, fallback, minRows = 4, onChange, renderAnnotation, renderBlock, renderDecorator, renderPlaceholder, toolbar, value, }) => {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { PsPortableTextCoreEditor } from '@pallasoft/ps-input-components/portable-text-engine';
|
|
4
|
+
export const PsPortableTextCore = (props) => {
|
|
8
5
|
const [isMounted, setIsMounted] = useState(false);
|
|
9
|
-
const [version, setVersion] = useState(0);
|
|
10
|
-
const lastValue = useRef(value);
|
|
11
6
|
useEffect(() => {
|
|
12
7
|
setIsMounted(true);
|
|
13
8
|
}, []);
|
|
14
|
-
|
|
15
|
-
if (PsPortableTextEditorService.isSame(value, lastValue.current))
|
|
16
|
-
return;
|
|
17
|
-
lastValue.current = value;
|
|
18
|
-
setVersion((current) => current + 1);
|
|
19
|
-
}, [value]);
|
|
20
|
-
return (_jsx("div", { className: className, children: isMounted ? (_jsxs(EditorProvider, { initialConfig: {
|
|
21
|
-
initialValue: value,
|
|
22
|
-
readOnly: disabled,
|
|
23
|
-
schemaDefinition: PsPortableTextCoreConfig.schemaDefinition,
|
|
24
|
-
}, children: [_jsx(EventListenerPlugin, { on: (event) => {
|
|
25
|
-
if (event.type !== 'mutation')
|
|
26
|
-
return;
|
|
27
|
-
const next = Array.isArray(event.value) ? event.value : [];
|
|
28
|
-
lastValue.current = next;
|
|
29
|
-
onChange(next);
|
|
30
|
-
} }), toolbar, _jsx(PortableTextEditable, { className: editableClassName, readOnly: disabled, renderAnnotation: renderAnnotation, renderBlock: renderBlock, renderDecorator: renderDecorator, renderPlaceholder: renderPlaceholder, style: { minHeight: PsPortableTextEditorService.minHeight(minRows) } })] }, version)) : (fallback) }));
|
|
9
|
+
return isMounted ? (_jsx(PsPortableTextCoreEditor, { ...props })) : (_jsx("div", { className: props.className, children: props.fallback }));
|
|
31
10
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Common } from '@pallasoft/ps-models';
|
|
2
|
-
import { defineSchema } from '@portabletext/editor';
|
|
3
2
|
const Models = Common.PortableTextConfig;
|
|
4
3
|
export const PsPortableTextCoreConfig = {
|
|
5
4
|
linkAnnotation: Models.linkType,
|
|
6
5
|
mailtoPrefix: 'mailto:',
|
|
7
6
|
emailPattern: /^[^\s@/:]+@[^\s@/:]+\.[^\s@/:]+$/,
|
|
8
7
|
lineHeightRem: 1.5,
|
|
8
|
+
lineBreak: '\n',
|
|
9
|
+
defaultLinkProtocol: 'https',
|
|
10
|
+
keyPrefix: { block: 'b', link: 'l', span: 's' },
|
|
9
11
|
decorators: {
|
|
10
12
|
bold: Models.decorators[0],
|
|
11
13
|
code: Models.decorators[3],
|
|
@@ -14,19 +16,37 @@ export const PsPortableTextCoreConfig = {
|
|
|
14
16
|
},
|
|
15
17
|
styles: { blockquote: Models.styles[1], normal: Models.styles[0] },
|
|
16
18
|
listItems: { bullet: Models.listItems[0], number: Models.listItems[1] },
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
decoratorMarks: {
|
|
20
|
+
[Models.decorators[0]]: 'bold',
|
|
21
|
+
[Models.decorators[1]]: 'italic',
|
|
22
|
+
[Models.decorators[2]]: 'underline',
|
|
23
|
+
[Models.decorators[3]]: 'code',
|
|
24
|
+
},
|
|
25
|
+
listNodes: {
|
|
26
|
+
[Models.listItems[0]]: 'bulletList',
|
|
27
|
+
[Models.listItems[1]]: 'orderedList',
|
|
28
|
+
},
|
|
29
|
+
nodes: {
|
|
30
|
+
blockquote: 'blockquote',
|
|
31
|
+
bulletList: 'bulletList',
|
|
32
|
+
document: 'doc',
|
|
33
|
+
hardBreak: 'hardBreak',
|
|
34
|
+
listItem: 'listItem',
|
|
35
|
+
orderedList: 'orderedList',
|
|
36
|
+
paragraph: 'paragraph',
|
|
37
|
+
text: 'text',
|
|
38
|
+
},
|
|
39
|
+
linkMark: 'link',
|
|
40
|
+
linkShortcutExtension: 'psLinkShortcut',
|
|
41
|
+
listItemContent: 'paragraph (bulletList | orderedList)*',
|
|
42
|
+
blockquoteContent: 'paragraph+',
|
|
43
|
+
shortcuts: { link: 'Mod-k', nest: 'Tab', unnest: 'Shift-Tab' },
|
|
25
44
|
labels: {
|
|
26
45
|
bold: 'Bold',
|
|
27
46
|
bulletedList: 'Bulleted list',
|
|
28
47
|
cancel: 'Cancel',
|
|
29
48
|
code: 'Code',
|
|
49
|
+
editor: 'Text',
|
|
30
50
|
invalidLink: 'Enter a web address or email address',
|
|
31
51
|
italic: 'Italic',
|
|
32
52
|
link: 'Link',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { PsPortableTextCommandService } from '../services/ps-portable-text-command-service';
|
|
3
|
+
export const PsPortableTextCoreContext = createContext({
|
|
4
|
+
closeLink: () => undefined,
|
|
5
|
+
editor: null,
|
|
6
|
+
isLinkOpen: false,
|
|
7
|
+
openLink: () => undefined,
|
|
8
|
+
state: PsPortableTextCommandService.state(null),
|
|
9
|
+
});
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import { PsPortableTextEditorService } from '../services/ps-portable-text-editor-service';
|
|
3
|
-
export const usePsPortableTextLinkForm = ({ onClose, onSubmit, }) => {
|
|
3
|
+
export const usePsPortableTextLinkForm = ({ href, isOpen = false, onClose, onSubmit, }) => {
|
|
4
4
|
const [address, setAddress] = useState('');
|
|
5
5
|
const [hasError, setHasError] = useState(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isOpen)
|
|
8
|
+
return;
|
|
9
|
+
setAddress(href === undefined ? '' : href);
|
|
10
|
+
setHasError(false);
|
|
11
|
+
}, [isOpen]);
|
|
6
12
|
return {
|
|
7
13
|
address,
|
|
8
14
|
close: () => {
|
|
@@ -19,14 +25,14 @@ export const usePsPortableTextLinkForm = ({ onClose, onSubmit, }) => {
|
|
|
19
25
|
submit: (event) => {
|
|
20
26
|
event.preventDefault();
|
|
21
27
|
event.stopPropagation();
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
28
|
+
const normalized = PsPortableTextEditorService.normalizeLink(address);
|
|
29
|
+
if (normalized === null) {
|
|
24
30
|
setHasError(true);
|
|
25
31
|
return;
|
|
26
32
|
}
|
|
27
33
|
setAddress('');
|
|
28
34
|
setHasError(false);
|
|
29
|
-
onSubmit(
|
|
35
|
+
onSubmit(normalized);
|
|
30
36
|
},
|
|
31
37
|
};
|
|
32
38
|
};
|
|
@@ -1,54 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { PsPortableTextCoreContext } from '../contexts/ps-portable-text-core-context';
|
|
3
|
+
import { PsPortableTextCommandService } from '../services/ps-portable-text-command-service';
|
|
4
4
|
export const usePsPortableTextToolbar = () => {
|
|
5
|
-
const editor =
|
|
6
|
-
const isBold = useEditorSelector(editor, isActiveDecorator(PsPortableTextCoreConfig.decorators.bold));
|
|
7
|
-
const isItalic = useEditorSelector(editor, isActiveDecorator(PsPortableTextCoreConfig.decorators.italic));
|
|
8
|
-
const isUnderline = useEditorSelector(editor, isActiveDecorator(PsPortableTextCoreConfig.decorators.underline));
|
|
9
|
-
const isCode = useEditorSelector(editor, isActiveDecorator(PsPortableTextCoreConfig.decorators.code));
|
|
10
|
-
const isBulletedList = useEditorSelector(editor, isActiveListItem(PsPortableTextCoreConfig.listItems.bullet));
|
|
11
|
-
const isNumberedList = useEditorSelector(editor, isActiveListItem(PsPortableTextCoreConfig.listItems.number));
|
|
12
|
-
const isQuote = useEditorSelector(editor, isActiveStyle(PsPortableTextCoreConfig.styles.blockquote));
|
|
13
|
-
const isLink = useEditorSelector(editor, isActiveAnnotation(PsPortableTextCoreConfig.linkAnnotation));
|
|
14
|
-
const focus = () => editor.send({ type: 'focus' });
|
|
5
|
+
const { closeLink, editor, isLinkOpen, openLink, state } = useContext(PsPortableTextCoreContext);
|
|
15
6
|
return {
|
|
16
|
-
active:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
link: isLink,
|
|
22
|
-
numberedList: isNumberedList,
|
|
23
|
-
quote: isQuote,
|
|
24
|
-
underline: isUnderline,
|
|
25
|
-
},
|
|
26
|
-
addLink: (href) => {
|
|
27
|
-
editor.send({
|
|
28
|
-
type: 'annotation.add',
|
|
29
|
-
annotation: { name: PsPortableTextCoreConfig.linkAnnotation, value: { href } },
|
|
30
|
-
});
|
|
31
|
-
focus();
|
|
32
|
-
},
|
|
33
|
-
focus,
|
|
34
|
-
removeLink: () => {
|
|
35
|
-
editor.send({
|
|
36
|
-
type: 'annotation.remove',
|
|
37
|
-
annotation: { name: PsPortableTextCoreConfig.linkAnnotation },
|
|
38
|
-
});
|
|
39
|
-
focus();
|
|
40
|
-
},
|
|
41
|
-
toggleDecorator: (decorator) => {
|
|
42
|
-
editor.send({ type: 'decorator.toggle', decorator });
|
|
43
|
-
focus();
|
|
44
|
-
},
|
|
45
|
-
toggleListItem: (listItem) => {
|
|
46
|
-
editor.send({ type: 'list item.toggle', listItem });
|
|
47
|
-
focus();
|
|
48
|
-
},
|
|
49
|
-
toggleQuote: () => {
|
|
50
|
-
editor.send({ type: 'style.toggle', style: PsPortableTextCoreConfig.styles.blockquote });
|
|
51
|
-
focus();
|
|
7
|
+
active: state.active,
|
|
8
|
+
addLink: (href) => PsPortableTextCommandService.setLink(editor, href),
|
|
9
|
+
closeLink: () => {
|
|
10
|
+
closeLink();
|
|
11
|
+
PsPortableTextCommandService.focus(editor);
|
|
52
12
|
},
|
|
13
|
+
focus: () => PsPortableTextCommandService.focus(editor),
|
|
14
|
+
isLinkOpen,
|
|
15
|
+
linkHref: state.linkHref,
|
|
16
|
+
openLink,
|
|
17
|
+
removeLink: () => PsPortableTextCommandService.removeLink(editor),
|
|
18
|
+
toggleDecorator: (decorator) => PsPortableTextCommandService.toggleDecorator(editor, decorator),
|
|
19
|
+
toggleListItem: (listItem) => PsPortableTextCommandService.toggleListItem(editor, listItem),
|
|
20
|
+
toggleQuote: () => PsPortableTextCommandService.toggleQuote(editor),
|
|
53
21
|
};
|
|
54
22
|
};
|
|
@@ -2,5 +2,9 @@ export * from './components/ps-portable-text-core';
|
|
|
2
2
|
export * from './constants/ps-portable-text-core-config';
|
|
3
3
|
export * from './hooks/use-ps-portable-text-link-form';
|
|
4
4
|
export * from './hooks/use-ps-portable-text-toolbar';
|
|
5
|
+
export * from './interfaces/ps-portable-text-active-formats';
|
|
6
|
+
export * from './interfaces/ps-portable-text-core-class-names';
|
|
7
|
+
export * from './interfaces/ps-portable-text-core-props';
|
|
5
8
|
export * from './interfaces/ps-portable-text-editor-labels';
|
|
9
|
+
export * from './services/ps-portable-text-converter-service';
|
|
6
10
|
export * from './services/ps-portable-text-editor-service';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { PsPortableTextCoreConfig } from '../constants/ps-portable-text-core-config';
|
|
2
|
+
import { PsPortableTextEditorService } from './ps-portable-text-editor-service';
|
|
3
|
+
export class PsPortableTextCommandService {
|
|
4
|
+
static state(editor) {
|
|
5
|
+
return { active: this.active(editor), linkHref: this.linkHref(editor) };
|
|
6
|
+
}
|
|
7
|
+
static active(editor) {
|
|
8
|
+
const isActive = (name) => (editor === null ? false : editor.isActive(name));
|
|
9
|
+
const marks = PsPortableTextCoreConfig.decoratorMarks;
|
|
10
|
+
const decorators = PsPortableTextCoreConfig.decorators;
|
|
11
|
+
return {
|
|
12
|
+
bold: isActive(marks[decorators.bold]),
|
|
13
|
+
bulletedList: isActive(PsPortableTextCoreConfig.nodes.bulletList),
|
|
14
|
+
code: isActive(marks[decorators.code]),
|
|
15
|
+
italic: isActive(marks[decorators.italic]),
|
|
16
|
+
link: isActive(PsPortableTextCoreConfig.linkMark),
|
|
17
|
+
numberedList: isActive(PsPortableTextCoreConfig.nodes.orderedList),
|
|
18
|
+
quote: isActive(PsPortableTextCoreConfig.nodes.blockquote),
|
|
19
|
+
underline: isActive(marks[decorators.underline]),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
static linkHref(editor) {
|
|
23
|
+
const href = editor === null ? undefined : editor.getAttributes(PsPortableTextCoreConfig.linkMark).href;
|
|
24
|
+
return typeof href === 'string' ? href : '';
|
|
25
|
+
}
|
|
26
|
+
static toggleDecorator(editor, decorator) {
|
|
27
|
+
const mark = PsPortableTextEditorService.lookup(PsPortableTextCoreConfig.decoratorMarks, decorator);
|
|
28
|
+
if (editor !== null && mark !== null)
|
|
29
|
+
editor.chain().focus().toggleMark(mark).run();
|
|
30
|
+
}
|
|
31
|
+
static toggleListItem(editor, listItem) {
|
|
32
|
+
const list = PsPortableTextEditorService.lookup(PsPortableTextCoreConfig.listNodes, listItem);
|
|
33
|
+
if (editor !== null && list !== null) {
|
|
34
|
+
editor.chain().focus().toggleList(list, PsPortableTextCoreConfig.nodes.listItem).run();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
static toggleQuote(editor) {
|
|
38
|
+
if (editor !== null)
|
|
39
|
+
editor.chain().focus().toggleBlockquote().run();
|
|
40
|
+
}
|
|
41
|
+
static setLink(editor, href) {
|
|
42
|
+
if (editor === null)
|
|
43
|
+
return;
|
|
44
|
+
if (editor.state.selection.empty && !editor.isActive(PsPortableTextCoreConfig.linkMark)) {
|
|
45
|
+
editor
|
|
46
|
+
.chain()
|
|
47
|
+
.focus()
|
|
48
|
+
.insertContent({
|
|
49
|
+
type: PsPortableTextCoreConfig.nodes.text,
|
|
50
|
+
text: href.replace(PsPortableTextCoreConfig.mailtoPrefix, ''),
|
|
51
|
+
marks: [{ type: PsPortableTextCoreConfig.linkMark, attrs: { href } }],
|
|
52
|
+
})
|
|
53
|
+
.unsetMark(PsPortableTextCoreConfig.linkMark)
|
|
54
|
+
.run();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
editor
|
|
58
|
+
.chain()
|
|
59
|
+
.focus()
|
|
60
|
+
.extendMarkRange(PsPortableTextCoreConfig.linkMark)
|
|
61
|
+
.setLink({ href })
|
|
62
|
+
.run();
|
|
63
|
+
}
|
|
64
|
+
static removeLink(editor) {
|
|
65
|
+
if (editor !== null) {
|
|
66
|
+
editor.chain().focus().extendMarkRange(PsPortableTextCoreConfig.linkMark).unsetLink().run();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
static focus(editor) {
|
|
70
|
+
if (editor !== null)
|
|
71
|
+
editor.commands.focus();
|
|
72
|
+
}
|
|
73
|
+
}
|