@pallasoft/ps-input-components 1.22.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/components/ps-option-card-group.d.ts +8 -0
  2. package/dist/components/ps-option-card-group.js +12 -0
  3. package/dist/components/ps-portable-text-editor.d.ts +2 -2
  4. package/dist/components/ps-portable-text-editor.js +4 -29
  5. package/dist/components/ps-portable-text-link-dialog.d.ts +1 -1
  6. package/dist/components/ps-portable-text-link-dialog.js +4 -26
  7. package/dist/components/ps-portable-text-toolbar.d.ts +1 -1
  8. package/dist/components/ps-portable-text-toolbar.js +12 -52
  9. package/dist/constants/ps-portable-text-editor-config.d.ts +0 -55
  10. package/dist/constants/ps-portable-text-editor-config.js +0 -40
  11. package/dist/constants/ps-portable-text-editor-renderers.js +8 -8
  12. package/dist/esm/components/ps-option-card-group.js +8 -0
  13. package/dist/esm/components/ps-portable-text-editor.js +5 -30
  14. package/dist/esm/components/ps-portable-text-link-dialog.js +4 -26
  15. package/dist/esm/components/ps-portable-text-toolbar.js +13 -53
  16. package/dist/esm/constants/ps-portable-text-editor-config.js +0 -40
  17. package/dist/esm/constants/ps-portable-text-editor-renderers.js +8 -8
  18. package/dist/esm/form/components/ps-form-name-modal.js +16 -0
  19. package/dist/esm/form/index.js +2 -0
  20. package/dist/esm/index.js +3 -1
  21. package/dist/esm/interfaces/ps-option-card-data.js +1 -0
  22. package/dist/esm/portable-text-core/components/ps-portable-text-core.js +31 -0
  23. package/dist/esm/portable-text-core/constants/ps-portable-text-core-config.js +42 -0
  24. package/dist/esm/portable-text-core/hooks/use-ps-portable-text-link-form.js +32 -0
  25. package/dist/esm/portable-text-core/hooks/use-ps-portable-text-toolbar.js +54 -0
  26. package/dist/esm/portable-text-core/index.js +6 -0
  27. package/dist/esm/portable-text-core/interfaces/ps-portable-text-editor-labels.js +1 -0
  28. package/dist/esm/{services → portable-text-core/services}/ps-portable-text-editor-service.js +6 -6
  29. package/dist/form/components/ps-form-name-modal.d.ts +15 -0
  30. package/dist/form/components/ps-form-name-modal.js +20 -0
  31. package/dist/form/index.d.ts +2 -0
  32. package/dist/form/index.js +2 -0
  33. package/dist/form/models/ps-form-name-data.d.ts +3 -0
  34. package/dist/index.d.ts +3 -1
  35. package/dist/index.js +3 -1
  36. package/dist/interfaces/ps-option-card-data.d.ts +5 -0
  37. package/dist/interfaces/ps-option-card-data.js +2 -0
  38. package/dist/portable-text-core/components/ps-portable-text-core.d.ts +17 -0
  39. package/dist/portable-text-core/components/ps-portable-text-core.js +35 -0
  40. package/dist/portable-text-core/constants/ps-portable-text-core-config.d.ts +57 -0
  41. package/dist/portable-text-core/constants/ps-portable-text-core-config.js +45 -0
  42. package/dist/portable-text-core/hooks/use-ps-portable-text-link-form.d.ts +13 -0
  43. package/dist/portable-text-core/hooks/use-ps-portable-text-link-form.js +36 -0
  44. package/dist/portable-text-core/hooks/use-ps-portable-text-toolbar.d.ts +18 -0
  45. package/dist/portable-text-core/hooks/use-ps-portable-text-toolbar.js +58 -0
  46. package/dist/portable-text-core/index.d.ts +7 -0
  47. package/dist/portable-text-core/index.js +22 -0
  48. package/dist/portable-text-core/interfaces/ps-portable-text-editor-labels.js +2 -0
  49. package/dist/{services → portable-text-core/services}/ps-portable-text-editor-service.js +6 -6
  50. package/package.json +10 -1
  51. /package/dist/esm/{interfaces/ps-portable-text-editor-labels.js → form/models/ps-form-name-data.js} +0 -0
  52. /package/dist/{interfaces/ps-portable-text-editor-labels.js → form/models/ps-form-name-data.js} +0 -0
  53. /package/dist/{interfaces → portable-text-core/interfaces}/ps-portable-text-editor-labels.d.ts +0 -0
  54. /package/dist/{services → portable-text-core/services}/ps-portable-text-editor-service.d.ts +0 -0
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { PsFormModal } from '@pallasoft/ps-popovers';
4
+ import { useForm } from 'react-hook-form';
5
+ import { PsFormTextField } from './ps-form-text-field';
6
+ export const PsFormNameModal = ({ cancelLabel, initialName, isOpen, isSubmitting = false, label, maxLength = 80, onClose, onSave, placeholder, requiredMessage, submitLabel, title, }) => {
7
+ const { control, formState: { isDirty, isValid }, handleSubmit, reset, } = useForm({ mode: 'onChange' });
8
+ useEffect(() => {
9
+ if (isOpen)
10
+ reset({ name: initialName });
11
+ }, [initialName, isOpen, reset]);
12
+ return (_jsx(PsFormModal, { cancelLabel: cancelLabel, isOpen: isOpen, isSubmitDisabled: !isValid || (initialName !== '' && !isDirty), isSubmitting: isSubmitting, onClose: onClose, onSubmit: handleSubmit((values) => onSave(values.name.trim())), size: 'sm', submitLabel: submitLabel, title: title, children: _jsx(PsFormTextField, { control: control, label: label, maxLength: maxLength, name: 'name', placeholder: placeholder, rules: {
13
+ required: requiredMessage,
14
+ validate: (value) => value.trim() !== '' || requiredMessage,
15
+ } }) }));
16
+ };
@@ -9,3 +9,5 @@ export * from './components/ps-form-year-field';
9
9
  export * from './constants/ps-form-text-kind';
10
10
  export * from './models/ps-form-field-rules';
11
11
  export * from './services/ps-form-field-service';
12
+ export * from './components/ps-form-name-modal';
13
+ export * from './models/ps-form-name-data';
package/dist/esm/index.js CHANGED
@@ -46,4 +46,6 @@ export * from './components/ps-select-with-create';
46
46
  export * from './constants/ps-select-with-create-config';
47
47
  export * from './interfaces/ps-date-preset-data';
48
48
  export * from './components/ps-portable-text-editor';
49
- export * from './interfaces/ps-portable-text-editor-labels';
49
+ export * from './portable-text-core/interfaces/ps-portable-text-editor-labels';
50
+ export * from './components/ps-option-card-group';
51
+ export * from './interfaces/ps-option-card-data';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { EditorProvider, PortableTextEditable, } from '@portabletext/editor';
4
+ import { EventListenerPlugin } from '@portabletext/editor/plugins';
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, }) => {
8
+ const [isMounted, setIsMounted] = useState(false);
9
+ const [version, setVersion] = useState(0);
10
+ const lastValue = useRef(value);
11
+ useEffect(() => {
12
+ setIsMounted(true);
13
+ }, []);
14
+ useEffect(() => {
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) }));
31
+ };
@@ -0,0 +1,42 @@
1
+ import { Common } from '@pallasoft/ps-models';
2
+ import { defineSchema } from '@portabletext/editor';
3
+ const Models = Common.PortableTextConfig;
4
+ export const PsPortableTextCoreConfig = {
5
+ linkAnnotation: Models.linkType,
6
+ mailtoPrefix: 'mailto:',
7
+ emailPattern: /^[^\s@/:]+@[^\s@/:]+\.[^\s@/:]+$/,
8
+ lineHeightRem: 1.5,
9
+ decorators: {
10
+ bold: Models.decorators[0],
11
+ code: Models.decorators[3],
12
+ italic: Models.decorators[1],
13
+ underline: Models.decorators[2],
14
+ },
15
+ styles: { blockquote: Models.styles[1], normal: Models.styles[0] },
16
+ listItems: { bullet: Models.listItems[0], number: Models.listItems[1] },
17
+ schemaDefinition: defineSchema({
18
+ annotations: [{ name: Models.linkType, fields: [{ name: 'href', type: 'string' }] }],
19
+ blockObjects: [],
20
+ decorators: Models.decorators.map((name) => ({ name })),
21
+ inlineObjects: [],
22
+ lists: Models.listItems.map((name) => ({ name })),
23
+ styles: Models.styles.map((name) => ({ name })),
24
+ }),
25
+ labels: {
26
+ bold: 'Bold',
27
+ bulletedList: 'Bulleted list',
28
+ cancel: 'Cancel',
29
+ code: 'Code',
30
+ invalidLink: 'Enter a web address or email address',
31
+ italic: 'Italic',
32
+ link: 'Link',
33
+ linkDialogTitle: 'Link',
34
+ linkUrl: 'Address',
35
+ numberedList: 'Numbered list',
36
+ quote: 'Quote',
37
+ removeLink: 'Remove link',
38
+ saveLink: 'Save',
39
+ toolbar: 'Formatting',
40
+ underline: 'Underline',
41
+ },
42
+ };
@@ -0,0 +1,32 @@
1
+ import { useState } from 'react';
2
+ import { PsPortableTextEditorService } from '../services/ps-portable-text-editor-service';
3
+ export const usePsPortableTextLinkForm = ({ onClose, onSubmit, }) => {
4
+ const [address, setAddress] = useState('');
5
+ const [hasError, setHasError] = useState(false);
6
+ return {
7
+ address,
8
+ close: () => {
9
+ setAddress('');
10
+ setHasError(false);
11
+ onClose();
12
+ },
13
+ hasError,
14
+ isSubmitDisabled: address.trim() === '',
15
+ setAddress: (next) => {
16
+ setAddress(next);
17
+ setHasError(false);
18
+ },
19
+ submit: (event) => {
20
+ event.preventDefault();
21
+ event.stopPropagation();
22
+ const href = PsPortableTextEditorService.normalizeLink(address);
23
+ if (href === null) {
24
+ setHasError(true);
25
+ return;
26
+ }
27
+ setAddress('');
28
+ setHasError(false);
29
+ onSubmit(href);
30
+ },
31
+ };
32
+ };
@@ -0,0 +1,54 @@
1
+ import { useEditor, useEditorSelector } from '@portabletext/editor';
2
+ import { isActiveAnnotation, isActiveDecorator, isActiveListItem, isActiveStyle, } from '@portabletext/editor/selectors';
3
+ import { PsPortableTextCoreConfig } from '../constants/ps-portable-text-core-config';
4
+ export const usePsPortableTextToolbar = () => {
5
+ const editor = useEditor();
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' });
15
+ return {
16
+ active: {
17
+ bold: isBold,
18
+ bulletedList: isBulletedList,
19
+ code: isCode,
20
+ italic: isItalic,
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();
52
+ },
53
+ };
54
+ };
@@ -0,0 +1,6 @@
1
+ export * from './components/ps-portable-text-core';
2
+ export * from './constants/ps-portable-text-core-config';
3
+ export * from './hooks/use-ps-portable-text-link-form';
4
+ export * from './hooks/use-ps-portable-text-toolbar';
5
+ export * from './interfaces/ps-portable-text-editor-labels';
6
+ export * from './services/ps-portable-text-editor-service';
@@ -1,14 +1,14 @@
1
1
  import { Common } from '@pallasoft/ps-models';
2
- import { PsPortableTextEditorConfig } from '../constants/ps-portable-text-editor-config';
3
- import { PsTextFormatService } from './ps-text-format-service';
2
+ import { PsTextFormatService } from '../../services/ps-text-format-service';
3
+ import { PsPortableTextCoreConfig } from '../constants/ps-portable-text-core-config';
4
4
  export class PsPortableTextEditorService {
5
5
  static normalizeLink(raw) {
6
6
  const trimmed = raw.trim();
7
7
  if (trimmed === '')
8
8
  return null;
9
- const candidate = PsPortableTextEditorConfig.emailPattern.test(trimmed)
10
- ? `${PsPortableTextEditorConfig.mailtoPrefix}${trimmed}`
11
- : trimmed.toLowerCase().startsWith(PsPortableTextEditorConfig.mailtoPrefix)
9
+ const candidate = PsPortableTextCoreConfig.emailPattern.test(trimmed)
10
+ ? `${PsPortableTextCoreConfig.mailtoPrefix}${trimmed}`
11
+ : trimmed.toLowerCase().startsWith(PsPortableTextCoreConfig.mailtoPrefix)
12
12
  ? trimmed
13
13
  : PsTextFormatService.url(trimmed);
14
14
  try {
@@ -22,7 +22,7 @@ export class PsPortableTextEditorService {
22
22
  }
23
23
  }
24
24
  static minHeight(minRows) {
25
- return `${minRows * PsPortableTextEditorConfig.lineHeightRem}rem`;
25
+ return `${minRows * PsPortableTextCoreConfig.lineHeightRem}rem`;
26
26
  }
27
27
  static isSame(first, second) {
28
28
  return JSON.stringify(first) === JSON.stringify(second);
@@ -0,0 +1,15 @@
1
+ export interface PsFormNameModalProps {
2
+ cancelLabel: string;
3
+ initialName: string;
4
+ isOpen: boolean;
5
+ isSubmitting?: boolean;
6
+ label: string;
7
+ maxLength?: number;
8
+ onClose: () => void;
9
+ onSave: (name: string) => void;
10
+ placeholder?: string;
11
+ requiredMessage: string;
12
+ submitLabel: string;
13
+ title: string;
14
+ }
15
+ export declare const PsFormNameModal: ({ cancelLabel, initialName, isOpen, isSubmitting, label, maxLength, onClose, onSave, placeholder, requiredMessage, submitLabel, title, }: PsFormNameModalProps) => import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsFormNameModal = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const ps_popovers_1 = require("@pallasoft/ps-popovers");
7
+ const react_hook_form_1 = require("react-hook-form");
8
+ const ps_form_text_field_1 = require("./ps-form-text-field");
9
+ const PsFormNameModal = ({ cancelLabel, initialName, isOpen, isSubmitting = false, label, maxLength = 80, onClose, onSave, placeholder, requiredMessage, submitLabel, title, }) => {
10
+ const { control, formState: { isDirty, isValid }, handleSubmit, reset, } = (0, react_hook_form_1.useForm)({ mode: 'onChange' });
11
+ (0, react_1.useEffect)(() => {
12
+ if (isOpen)
13
+ reset({ name: initialName });
14
+ }, [initialName, isOpen, reset]);
15
+ return ((0, jsx_runtime_1.jsx)(ps_popovers_1.PsFormModal, { cancelLabel: cancelLabel, isOpen: isOpen, isSubmitDisabled: !isValid || (initialName !== '' && !isDirty), isSubmitting: isSubmitting, onClose: onClose, onSubmit: handleSubmit((values) => onSave(values.name.trim())), size: 'sm', submitLabel: submitLabel, title: title, children: (0, jsx_runtime_1.jsx)(ps_form_text_field_1.PsFormTextField, { control: control, label: label, maxLength: maxLength, name: 'name', placeholder: placeholder, rules: {
16
+ required: requiredMessage,
17
+ validate: (value) => value.trim() !== '' || requiredMessage,
18
+ } }) }));
19
+ };
20
+ exports.PsFormNameModal = PsFormNameModal;
@@ -9,3 +9,5 @@ export * from './components/ps-form-year-field';
9
9
  export * from './constants/ps-form-text-kind';
10
10
  export * from './models/ps-form-field-rules';
11
11
  export * from './services/ps-form-field-service';
12
+ export * from './components/ps-form-name-modal';
13
+ export * from './models/ps-form-name-data';
@@ -25,3 +25,5 @@ __exportStar(require("./components/ps-form-year-field"), exports);
25
25
  __exportStar(require("./constants/ps-form-text-kind"), exports);
26
26
  __exportStar(require("./models/ps-form-field-rules"), exports);
27
27
  __exportStar(require("./services/ps-form-field-service"), exports);
28
+ __exportStar(require("./components/ps-form-name-modal"), exports);
29
+ __exportStar(require("./models/ps-form-name-data"), exports);
@@ -0,0 +1,3 @@
1
+ export interface PsFormNameData {
2
+ name: string;
3
+ }
package/dist/index.d.ts CHANGED
@@ -46,5 +46,7 @@ export * from './components/ps-select-with-create';
46
46
  export * from './constants/ps-select-with-create-config';
47
47
  export * from './interfaces/ps-date-preset-data';
48
48
  export * from './components/ps-portable-text-editor';
49
- export * from './interfaces/ps-portable-text-editor-labels';
49
+ export * from './portable-text-core/interfaces/ps-portable-text-editor-labels';
50
50
  export type { PortableTextBlock } from '@portabletext/editor';
51
+ export * from './components/ps-option-card-group';
52
+ export * from './interfaces/ps-option-card-data';
package/dist/index.js CHANGED
@@ -62,4 +62,6 @@ __exportStar(require("./components/ps-select-with-create"), exports);
62
62
  __exportStar(require("./constants/ps-select-with-create-config"), exports);
63
63
  __exportStar(require("./interfaces/ps-date-preset-data"), exports);
64
64
  __exportStar(require("./components/ps-portable-text-editor"), exports);
65
- __exportStar(require("./interfaces/ps-portable-text-editor-labels"), exports);
65
+ __exportStar(require("./portable-text-core/interfaces/ps-portable-text-editor-labels"), exports);
66
+ __exportStar(require("./components/ps-option-card-group"), exports);
67
+ __exportStar(require("./interfaces/ps-option-card-data"), exports);
@@ -0,0 +1,5 @@
1
+ export interface PsOptionCardData {
2
+ description: string;
3
+ label: string;
4
+ value: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type PortableTextBlock, type RenderAnnotationFunction, type RenderBlockFunction, type RenderDecoratorFunction, type RenderPlaceholderFunction } from '@portabletext/editor';
3
+ export interface PsPortableTextCoreProps {
4
+ className?: string;
5
+ disabled?: boolean;
6
+ editableClassName?: string;
7
+ fallback?: ReactNode;
8
+ minRows?: number;
9
+ onChange: (value: PortableTextBlock[]) => void;
10
+ renderAnnotation?: RenderAnnotationFunction;
11
+ renderBlock?: RenderBlockFunction;
12
+ renderDecorator?: RenderDecoratorFunction;
13
+ renderPlaceholder?: RenderPlaceholderFunction;
14
+ toolbar?: ReactNode;
15
+ value: PortableTextBlock[];
16
+ }
17
+ export declare const PsPortableTextCore: ({ className, disabled, editableClassName, fallback, minRows, onChange, renderAnnotation, renderBlock, renderDecorator, renderPlaceholder, toolbar, value, }: PsPortableTextCoreProps) => import("react").JSX.Element;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsPortableTextCore = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const editor_1 = require("@portabletext/editor");
7
+ const plugins_1 = require("@portabletext/editor/plugins");
8
+ const ps_portable_text_core_config_1 = require("../constants/ps-portable-text-core-config");
9
+ const ps_portable_text_editor_service_1 = require("../services/ps-portable-text-editor-service");
10
+ const PsPortableTextCore = ({ className, disabled = false, editableClassName, fallback, minRows = 4, onChange, renderAnnotation, renderBlock, renderDecorator, renderPlaceholder, toolbar, value, }) => {
11
+ const [isMounted, setIsMounted] = (0, react_1.useState)(false);
12
+ const [version, setVersion] = (0, react_1.useState)(0);
13
+ const lastValue = (0, react_1.useRef)(value);
14
+ (0, react_1.useEffect)(() => {
15
+ setIsMounted(true);
16
+ }, []);
17
+ (0, react_1.useEffect)(() => {
18
+ if (ps_portable_text_editor_service_1.PsPortableTextEditorService.isSame(value, lastValue.current))
19
+ return;
20
+ lastValue.current = value;
21
+ setVersion((current) => current + 1);
22
+ }, [value]);
23
+ return ((0, jsx_runtime_1.jsx)("div", { className: className, children: isMounted ? ((0, jsx_runtime_1.jsxs)(editor_1.EditorProvider, { initialConfig: {
24
+ initialValue: value,
25
+ readOnly: disabled,
26
+ schemaDefinition: ps_portable_text_core_config_1.PsPortableTextCoreConfig.schemaDefinition,
27
+ }, children: [(0, jsx_runtime_1.jsx)(plugins_1.EventListenerPlugin, { on: (event) => {
28
+ if (event.type !== 'mutation')
29
+ return;
30
+ const next = Array.isArray(event.value) ? event.value : [];
31
+ lastValue.current = next;
32
+ onChange(next);
33
+ } }), toolbar, (0, jsx_runtime_1.jsx)(editor_1.PortableTextEditable, { className: editableClassName, readOnly: disabled, renderAnnotation: renderAnnotation, renderBlock: renderBlock, renderDecorator: renderDecorator, renderPlaceholder: renderPlaceholder, style: { minHeight: ps_portable_text_editor_service_1.PsPortableTextEditorService.minHeight(minRows) } })] }, version)) : (fallback) }));
34
+ };
35
+ exports.PsPortableTextCore = PsPortableTextCore;
@@ -0,0 +1,57 @@
1
+ export declare const PsPortableTextCoreConfig: {
2
+ readonly linkAnnotation: "link";
3
+ readonly mailtoPrefix: "mailto:";
4
+ readonly emailPattern: RegExp;
5
+ readonly lineHeightRem: 1.5;
6
+ readonly decorators: {
7
+ readonly bold: "strong";
8
+ readonly code: "code";
9
+ readonly italic: "em";
10
+ readonly underline: "underline";
11
+ };
12
+ readonly styles: {
13
+ readonly blockquote: "blockquote";
14
+ readonly normal: "normal";
15
+ };
16
+ readonly listItems: {
17
+ readonly bullet: "bullet";
18
+ readonly number: "number";
19
+ };
20
+ readonly schemaDefinition: {
21
+ readonly annotations: readonly [{
22
+ readonly name: "link";
23
+ readonly fields: readonly [{
24
+ readonly name: "href";
25
+ readonly type: "string";
26
+ }];
27
+ }];
28
+ readonly blockObjects: readonly [];
29
+ readonly decorators: {
30
+ name: "code" | "em" | "strong" | "underline";
31
+ }[];
32
+ readonly inlineObjects: readonly [];
33
+ readonly lists: {
34
+ name: "number" | "bullet";
35
+ }[];
36
+ readonly styles: {
37
+ name: "blockquote" | "normal";
38
+ }[];
39
+ };
40
+ readonly labels: {
41
+ bold: string;
42
+ bulletedList: string;
43
+ cancel: string;
44
+ code: string;
45
+ invalidLink: string;
46
+ italic: string;
47
+ link: string;
48
+ linkDialogTitle: string;
49
+ linkUrl: string;
50
+ numberedList: string;
51
+ quote: string;
52
+ removeLink: string;
53
+ saveLink: string;
54
+ toolbar: string;
55
+ underline: string;
56
+ };
57
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsPortableTextCoreConfig = void 0;
4
+ const ps_models_1 = require("@pallasoft/ps-models");
5
+ const editor_1 = require("@portabletext/editor");
6
+ const Models = ps_models_1.Common.PortableTextConfig;
7
+ exports.PsPortableTextCoreConfig = {
8
+ linkAnnotation: Models.linkType,
9
+ mailtoPrefix: 'mailto:',
10
+ emailPattern: /^[^\s@/:]+@[^\s@/:]+\.[^\s@/:]+$/,
11
+ lineHeightRem: 1.5,
12
+ decorators: {
13
+ bold: Models.decorators[0],
14
+ code: Models.decorators[3],
15
+ italic: Models.decorators[1],
16
+ underline: Models.decorators[2],
17
+ },
18
+ styles: { blockquote: Models.styles[1], normal: Models.styles[0] },
19
+ listItems: { bullet: Models.listItems[0], number: Models.listItems[1] },
20
+ schemaDefinition: (0, editor_1.defineSchema)({
21
+ annotations: [{ name: Models.linkType, fields: [{ name: 'href', type: 'string' }] }],
22
+ blockObjects: [],
23
+ decorators: Models.decorators.map((name) => ({ name })),
24
+ inlineObjects: [],
25
+ lists: Models.listItems.map((name) => ({ name })),
26
+ styles: Models.styles.map((name) => ({ name })),
27
+ }),
28
+ labels: {
29
+ bold: 'Bold',
30
+ bulletedList: 'Bulleted list',
31
+ cancel: 'Cancel',
32
+ code: 'Code',
33
+ invalidLink: 'Enter a web address or email address',
34
+ italic: 'Italic',
35
+ link: 'Link',
36
+ linkDialogTitle: 'Link',
37
+ linkUrl: 'Address',
38
+ numberedList: 'Numbered list',
39
+ quote: 'Quote',
40
+ removeLink: 'Remove link',
41
+ saveLink: 'Save',
42
+ toolbar: 'Formatting',
43
+ underline: 'Underline',
44
+ },
45
+ };
@@ -0,0 +1,13 @@
1
+ import { type FormEvent } from 'react';
2
+ export interface UsePsPortableTextLinkFormOptions {
3
+ onClose: () => void;
4
+ onSubmit: (href: string) => void;
5
+ }
6
+ export declare const usePsPortableTextLinkForm: ({ onClose, onSubmit, }: UsePsPortableTextLinkFormOptions) => {
7
+ address: string;
8
+ close: () => void;
9
+ hasError: boolean;
10
+ isSubmitDisabled: boolean;
11
+ setAddress: (next: string) => void;
12
+ submit: (event: FormEvent) => void;
13
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsPortableTextLinkForm = void 0;
4
+ const react_1 = require("react");
5
+ const ps_portable_text_editor_service_1 = require("../services/ps-portable-text-editor-service");
6
+ const usePsPortableTextLinkForm = ({ onClose, onSubmit, }) => {
7
+ const [address, setAddress] = (0, react_1.useState)('');
8
+ const [hasError, setHasError] = (0, react_1.useState)(false);
9
+ return {
10
+ address,
11
+ close: () => {
12
+ setAddress('');
13
+ setHasError(false);
14
+ onClose();
15
+ },
16
+ hasError,
17
+ isSubmitDisabled: address.trim() === '',
18
+ setAddress: (next) => {
19
+ setAddress(next);
20
+ setHasError(false);
21
+ },
22
+ submit: (event) => {
23
+ event.preventDefault();
24
+ event.stopPropagation();
25
+ const href = ps_portable_text_editor_service_1.PsPortableTextEditorService.normalizeLink(address);
26
+ if (href === null) {
27
+ setHasError(true);
28
+ return;
29
+ }
30
+ setAddress('');
31
+ setHasError(false);
32
+ onSubmit(href);
33
+ },
34
+ };
35
+ };
36
+ exports.usePsPortableTextLinkForm = usePsPortableTextLinkForm;
@@ -0,0 +1,18 @@
1
+ export declare const usePsPortableTextToolbar: () => {
2
+ active: {
3
+ bold: boolean;
4
+ bulletedList: boolean;
5
+ code: boolean;
6
+ italic: boolean;
7
+ link: boolean;
8
+ numberedList: boolean;
9
+ quote: boolean;
10
+ underline: boolean;
11
+ };
12
+ addLink: (href: string) => void;
13
+ focus: () => void;
14
+ removeLink: () => void;
15
+ toggleDecorator: (decorator: string) => void;
16
+ toggleListItem: (listItem: string) => void;
17
+ toggleQuote: () => void;
18
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsPortableTextToolbar = void 0;
4
+ const editor_1 = require("@portabletext/editor");
5
+ const selectors_1 = require("@portabletext/editor/selectors");
6
+ const ps_portable_text_core_config_1 = require("../constants/ps-portable-text-core-config");
7
+ const usePsPortableTextToolbar = () => {
8
+ const editor = (0, editor_1.useEditor)();
9
+ const isBold = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveDecorator)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.bold));
10
+ const isItalic = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveDecorator)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.italic));
11
+ const isUnderline = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveDecorator)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.underline));
12
+ const isCode = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveDecorator)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.decorators.code));
13
+ const isBulletedList = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveListItem)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.listItems.bullet));
14
+ const isNumberedList = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveListItem)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.listItems.number));
15
+ const isQuote = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveStyle)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.styles.blockquote));
16
+ const isLink = (0, editor_1.useEditorSelector)(editor, (0, selectors_1.isActiveAnnotation)(ps_portable_text_core_config_1.PsPortableTextCoreConfig.linkAnnotation));
17
+ const focus = () => editor.send({ type: 'focus' });
18
+ return {
19
+ active: {
20
+ bold: isBold,
21
+ bulletedList: isBulletedList,
22
+ code: isCode,
23
+ italic: isItalic,
24
+ link: isLink,
25
+ numberedList: isNumberedList,
26
+ quote: isQuote,
27
+ underline: isUnderline,
28
+ },
29
+ addLink: (href) => {
30
+ editor.send({
31
+ type: 'annotation.add',
32
+ annotation: { name: ps_portable_text_core_config_1.PsPortableTextCoreConfig.linkAnnotation, value: { href } },
33
+ });
34
+ focus();
35
+ },
36
+ focus,
37
+ removeLink: () => {
38
+ editor.send({
39
+ type: 'annotation.remove',
40
+ annotation: { name: ps_portable_text_core_config_1.PsPortableTextCoreConfig.linkAnnotation },
41
+ });
42
+ focus();
43
+ },
44
+ toggleDecorator: (decorator) => {
45
+ editor.send({ type: 'decorator.toggle', decorator });
46
+ focus();
47
+ },
48
+ toggleListItem: (listItem) => {
49
+ editor.send({ type: 'list item.toggle', listItem });
50
+ focus();
51
+ },
52
+ toggleQuote: () => {
53
+ editor.send({ type: 'style.toggle', style: ps_portable_text_core_config_1.PsPortableTextCoreConfig.styles.blockquote });
54
+ focus();
55
+ },
56
+ };
57
+ };
58
+ exports.usePsPortableTextToolbar = usePsPortableTextToolbar;
@@ -0,0 +1,7 @@
1
+ export * from './components/ps-portable-text-core';
2
+ export * from './constants/ps-portable-text-core-config';
3
+ export * from './hooks/use-ps-portable-text-link-form';
4
+ export * from './hooks/use-ps-portable-text-toolbar';
5
+ export * from './interfaces/ps-portable-text-editor-labels';
6
+ export * from './services/ps-portable-text-editor-service';
7
+ export type { BlockAnnotationRenderProps, BlockDecoratorRenderProps, BlockRenderProps, PortableTextBlock, } from '@portabletext/editor';