Skip to content

Commit

Permalink
feat: add options for placeholders
Browse files Browse the repository at this point in the history
  • Loading branch information
rusandorx committed Oct 16, 2023
1 parent 19540e1 commit 593f2c7
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 33 deletions.
14 changes: 10 additions & 4 deletions src/extensions/base/BaseSchema/BaseSchemaSpecs/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {NodeSpec} from 'prosemirror-model';
import type {ExtensionAuto} from '../../../../core';
import {nodeTypeFactory} from '../../../../utils/schema';
import {processPlaceholderContent, PlaceholderOptions} from '../../../../utils/placeholder';

export enum BaseNode {
Doc = 'doc',
Expand All @@ -11,12 +12,17 @@ export enum BaseNode {
export const pType = nodeTypeFactory(BaseNode.Paragraph);

export type BaseSchemaSpecsOptions = {
/**
* @deprecated: use placeholderOptions instead.
*/
paragraphPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
placeholderOptions?: PlaceholderOptions;
};

export const BaseSchemaSpecs: ExtensionAuto<BaseSchemaSpecsOptions> = (builder, opts) => {
const {paragraphPlaceholder} = opts;

const {placeholderOptions, paragraphPlaceholder} = opts;
const placeholderContent =
processPlaceholderContent(placeholderOptions?.[BaseNode.Paragraph]) ?? paragraphPlaceholder;
builder
.addNode(BaseNode.Doc, () => ({
spec: {
Expand Down Expand Up @@ -45,9 +51,9 @@ export const BaseSchemaSpecs: ExtensionAuto<BaseSchemaSpecsOptions> = (builder,
toDOM() {
return ['p', 0];
},
placeholder: paragraphPlaceholder
placeholder: placeholderContent
? {
content: paragraphPlaceholder,
content: placeholderContent,
alwaysVisible: false,
}
: undefined,
Expand Down
9 changes: 7 additions & 2 deletions src/extensions/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {BaseSchema, BaseSchemaOptions} from './BaseSchema';
import {BaseInputRules} from './BaseInputRules';
import {BaseKeymap} from './BaseKeymap';
import {BaseStyles} from './BaseStyles';
import {PlaceholderOptions} from '../../utils/placeholder';

export * from './BaseSchema';
export * from './BaseStyles';
Expand All @@ -12,11 +13,15 @@ export * from './BaseInputRules';

export type BasePresetOptions = {
baseSchema?: BaseSchemaOptions;
placeholderOptions?: PlaceholderOptions;
};

export const BasePreset: ExtensionAuto<BasePresetOptions> = (builder, opts) => {
export const BasePreset: ExtensionAuto<BasePresetOptions> = (
builder,
{placeholderOptions, ...opts},
) => {
builder
.use(BaseSchema, opts.baseSchema ?? {})
.use(BaseSchema, {...opts.baseSchema, placeholderOptions})
.use(BaseKeymap)
.use(BaseInputRules)
.use(BaseStyles);
Expand Down
8 changes: 8 additions & 0 deletions src/extensions/markdown/Deflist/DeflistSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@ import {DeflistNode} from './const';
import {fromYfm} from './fromYfm';
import {getSpec} from './spec';
import {toYfm} from './toYfm';
import {PlaceholderOptions} from '../../../../utils/placeholder';

export {DeflistNode} from './const';
export const defListType = nodeTypeFactory(DeflistNode.List);
export const defTermType = nodeTypeFactory(DeflistNode.Term);
export const defDescType = nodeTypeFactory(DeflistNode.Desc);

export type DeflistSpecsOptions = {
/**
* @deprecated: use placeholderOptions instead.
*/
deflistTermPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
/**
* @deprecated: use placeholderOptions instead.
*/
deflistDescPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
placeholderOptions?: PlaceholderOptions;
};

export const DeflistSpecs: ExtensionAuto<DeflistSpecsOptions> = (builder, opts) => {
Expand Down
11 changes: 9 additions & 2 deletions src/extensions/markdown/Deflist/DeflistSpecs/spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {NodeSpec} from 'prosemirror-model';
import type {DeflistSpecsOptions} from './index';
import {DeflistNode} from './const';
import {processPlaceholderContent} from '../../../../utils/placeholder';

const DEFAULT_PLACEHOLDERS = {
Term: 'Definition term',
Expand Down Expand Up @@ -29,7 +30,10 @@ export const getSpec = (opts?: DeflistSpecsOptions): Record<DeflistNode, NodeSpe
return ['dt', 0];
},
placeholder: {
content: opts?.deflistTermPlaceholder ?? DEFAULT_PLACEHOLDERS.Term,
content:
processPlaceholderContent(opts?.placeholderOptions?.[DeflistNode.Term]) ??
opts?.deflistTermPlaceholder ??
DEFAULT_PLACEHOLDERS.Term,
alwaysVisible: true,
},
selectable: false,
Expand All @@ -46,7 +50,10 @@ export const getSpec = (opts?: DeflistSpecsOptions): Record<DeflistNode, NodeSpe
return ['dd', 0];
},
placeholder: {
content: opts?.deflistDescPlaceholder ?? DEFAULT_PLACEHOLDERS.Desc,
content:
processPlaceholderContent(opts?.placeholderOptions?.[DeflistNode.Desc]) ??
opts?.deflistDescPlaceholder ??
DEFAULT_PLACEHOLDERS.Desc,
alwaysVisible: true,
},
selectable: false,
Expand Down
9 changes: 7 additions & 2 deletions src/extensions/markdown/Heading/HeadingSpecs/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {Node, NodeSpec} from 'prosemirror-model';
import type {ExtensionAuto} from '../../../../core';
import {nodeTypeFactory} from '../../../../utils/schema';
import {processPlaceholderContent, PlaceholderOptions} from '../../../../utils/placeholder';

export const headingNodeName = 'heading';
export const headingLevelAttr = 'level';
Expand All @@ -10,10 +11,11 @@ const DEFAULT_PLACEHOLDER = (node: Node) => 'Heading ' + node.attrs[headingLevel

export type HeadingSpecsOptions = {
headingPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
placeholderOptions?: PlaceholderOptions;
};

export const HeadingSpecs: ExtensionAuto<HeadingSpecsOptions> = (builder, opts) => {
const {headingPlaceholder} = opts ?? {};
const {headingPlaceholder, placeholderOptions} = opts ?? {};

builder.addNode(headingNodeName, () => ({
spec: {
Expand All @@ -33,7 +35,10 @@ export const HeadingSpecs: ExtensionAuto<HeadingSpecsOptions> = (builder, opts)
return ['h' + node.attrs[headingLevelAttr], 0];
},
placeholder: {
content: headingPlaceholder ?? DEFAULT_PLACEHOLDER,
content:
processPlaceholderContent(placeholderOptions?.heading) ??
headingPlaceholder ??
DEFAULT_PLACEHOLDER,
alwaysVisible: true,
},
},
Expand Down
13 changes: 9 additions & 4 deletions src/extensions/markdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {HorizontalRule} from './HorizontalRule';
import {Heading, HeadingOptions} from './Heading';
import {CodeBlock, CodeBlockOptions} from './CodeBlock';
import {Blockquote, BlockquoteOptions} from './Blockquote';
import {PlaceholderOptions} from '../../utils/placeholder';

export * from './Bold';
export * from './Code';
Expand Down Expand Up @@ -72,16 +73,20 @@ export type MarkdownBlocksPresetOptions = {
codeBlock?: CodeBlockOptions;
blockquote?: BlockquoteOptions;
heading?: false | Extension | HeadingOptions;
placeholderOptions?: PlaceholderOptions;
};

export const MarkdownBlocksPreset: ExtensionAuto<MarkdownBlocksPresetOptions> = (builder, opts) => {
export const MarkdownBlocksPreset: ExtensionAuto<MarkdownBlocksPresetOptions> = (
builder,
{placeholderOptions, ...opts},
) => {
builder
.use(Html)
.use(Table)
.use(HorizontalRule)
.use(Lists, opts.lists ?? {})
.use(Breaks, opts.breaks ?? {})
.use(Deflist, opts.deflist ?? {})
.use(Deflist, {...opts.deflist, placeholderOptions})
.use(CodeBlock, opts.codeBlock ?? {})
.use(Blockquote, opts.blockquote ?? {});

Expand All @@ -90,7 +95,7 @@ export const MarkdownBlocksPreset: ExtensionAuto<MarkdownBlocksPresetOptions> =
}

if (opts.heading !== false) {
if (isFunction(opts.heading)) builder.use(opts.heading);
else builder.use(Heading, opts.heading ?? {});
if (isFunction(opts.heading)) builder.use(opts.heading, {placeholderOptions});
else builder.use(Heading, {...opts.heading, placeholderOptions});
}
};
5 changes: 5 additions & 0 deletions src/extensions/yfm/Checkbox/CheckboxSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ import {b, CheckboxNode, idPrefix} from './const';
import {fromYfm} from './fromYfm';
import {getSpec} from './spec';
import {toYfm} from './toYfm';
import {PlaceholderOptions} from '../../../../utils/placeholder';

export {CheckboxNode} from './const';
export const checkboxType = nodeTypeFactory(CheckboxNode.Checkbox);
export const checkboxLabelType = nodeTypeFactory(CheckboxNode.Label);
export const checkboxInputType = nodeTypeFactory(CheckboxNode.Input);

export type CheckboxSpecsOptions = {
/**
* @deprecated: use placeholderOptions instead.
*/
checkboxLabelPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
inputView?: YENodeSpec['view'];
labelView?: YENodeSpec['view'];
checkboxView?: YENodeSpec['view'];
placeholderOptions?: PlaceholderOptions;
};

export const CheckboxSpecs: ExtensionAuto<CheckboxSpecsOptions> = (builder, opts) => {
Expand Down
8 changes: 6 additions & 2 deletions src/extensions/yfm/Checkbox/CheckboxSpecs/spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type {NodeSpec} from 'prosemirror-model';
import type {CheckboxSpecsOptions} from './index';
import {b, CheckboxNode} from '../const';
import {processPlaceholderContent} from '../../../../utils/placeholder';

const DEFAULT_LABEL_PLACEHOLDER = 'Checkbox';

export const getSpec = (
opts?: Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'>,
opts?: Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder' | 'placeholderOptions'>,
): Record<CheckboxNode, NodeSpec> => ({
[CheckboxNode.Checkbox]: {
group: 'block',
Expand Down Expand Up @@ -54,7 +55,10 @@ export const getSpec = (
},
escapeText: false,
placeholder: {
content: opts?.checkboxLabelPlaceholder ?? DEFAULT_LABEL_PLACEHOLDER,
content:
processPlaceholderContent(opts?.placeholderOptions?.[CheckboxNode.Label]) ??
opts?.checkboxLabelPlaceholder ??
DEFAULT_LABEL_PLACEHOLDER,
alwaysVisible: true,
},
toDOM(node) {
Expand Down
5 changes: 4 additions & 1 deletion src/extensions/yfm/Checkbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ const checkboxAction = 'addCheckbox';

export {CheckboxNode, checkboxType, checkboxLabelType, checkboxInputType} from './CheckboxSpecs';

export type CheckboxOptions = Pick<CheckboxSpecsOptions, 'checkboxLabelPlaceholder'> & {};
export type CheckboxOptions = Pick<
CheckboxSpecsOptions,
'checkboxLabelPlaceholder' | 'placeholderOptions'
> & {};

export const Checkbox: ExtensionAuto<CheckboxOptions> = (builder, opts) => {
builder.use(CheckboxSpecs, {
Expand Down
9 changes: 8 additions & 1 deletion src/extensions/yfm/ImgSize/ImgSizeSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import log from '@doc-tools/transform/lib/log';

import type {ExtensionAuto} from '../../../../core';
import {imageNodeName} from '../../../markdown/Image/const';
import {processPlaceholderContent, PlaceholderOptions} from '../../../../utils/placeholder';

type ImsizeTypedAttributes = {
[ImgSizeAttr.Src]: string;
Expand All @@ -18,10 +19,16 @@ type ImsizeTypedAttributes = {
export {ImgSizeAttr};

export type ImgSizeSpecsOptions = {
/**
* @deprecated: use placeholderOptions instead.
*/
placeholder?: NodeSpec['placeholder'];
placeholderOptions?: PlaceholderOptions;
};

export const ImgSizeSpecs: ExtensionAuto<ImgSizeSpecsOptions> = (builder, opts) => {
const placeholderContent = processPlaceholderContent(opts?.placeholderOptions?.imgSize);

builder.configureMd((md) => md.use(imsize, {log}));
builder.addNode(imageNodeName, () => ({
spec: {
Expand All @@ -33,7 +40,7 @@ export const ImgSizeSpecs: ExtensionAuto<ImgSizeSpecsOptions> = (builder, opts)
[ImgSizeAttr.Height]: {default: null},
[ImgSizeAttr.Width]: {default: null},
},
placeholder: opts.placeholder,
placeholder: placeholderContent ? {content: placeholderContent} : opts.placeholder,
group: 'inline',
draggable: true,
parseDOM: [
Expand Down
8 changes: 8 additions & 0 deletions src/extensions/yfm/YfmCut/YfmCutSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {CutNode} from './const';
import {fromYfm} from './fromYfm';
import {getSpec} from './spec';
import {toYfm} from './toYfm';
import {PlaceholderOptions} from '../../../../utils/placeholder';

export {CutNode} from './const';
export const cutType = nodeTypeFactory(CutNode.Cut);
Expand All @@ -18,8 +19,15 @@ export type YfmCutSpecsOptions = {
cutView?: YENodeSpec['view'];
cutTitleView?: YENodeSpec['view'];
cutContentView?: YENodeSpec['view'];
/**
* @deprecated: use placeholderOptions instead.
*/
yfmCutTitlePlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
/**
* @deprecated: use placeholderOptions instead.
*/
yfmCutContentPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
placeholderOptions?: PlaceholderOptions;
};

export const YfmCutSpecs: ExtensionAuto<YfmCutSpecsOptions> = (builder, opts) => {
Expand Down
11 changes: 9 additions & 2 deletions src/extensions/yfm/YfmCut/YfmCutSpecs/spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {NodeSpec} from 'prosemirror-model';
import type {YfmCutSpecsOptions} from './index';
import {CutNode} from '../const';
import {processPlaceholderContent} from '../../../../utils/placeholder';

const DEFAULT_PLACEHOLDERS = {
Title: 'Cut title',
Expand Down Expand Up @@ -31,7 +32,10 @@ export const getSpec = (opts?: YfmCutSpecsOptions): Record<CutNode, NodeSpec> =>
return ['div', node.attrs, 0];
},
placeholder: {
content: opts?.yfmCutTitlePlaceholder ?? DEFAULT_PLACEHOLDERS.Title,
content:
processPlaceholderContent(opts?.placeholderOptions?.[CutNode.CutTitle]) ??
opts?.yfmCutTitlePlaceholder ??
DEFAULT_PLACEHOLDERS.Title,
alwaysVisible: true,
},
selectable: false,
Expand All @@ -48,7 +52,10 @@ export const getSpec = (opts?: YfmCutSpecsOptions): Record<CutNode, NodeSpec> =>
return ['div', node.attrs, 0];
},
placeholder: {
content: opts?.yfmCutContentPlaceholder ?? DEFAULT_PLACEHOLDERS.Content,
content:
processPlaceholderContent(opts?.placeholderOptions?.[CutNode.CutContent]) ??
opts?.yfmCutContentPlaceholder ??
DEFAULT_PLACEHOLDERS.Content,
alwaysVisible: true,
},
selectable: false,
Expand Down
12 changes: 10 additions & 2 deletions src/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ import type {Node, NodeSpec} from 'prosemirror-model';
import type {ExtensionAuto} from '../../../../core';
import {headingNodeName, YfmHeadingAttr} from './const';
import {getNodeAttrs} from './utils';
import {processPlaceholderContent, PlaceholderOptions} from '../../../../utils/placeholder';

const DEFAULT_PLACEHOLDER = (node: Node) => 'Heading ' + node.attrs[YfmHeadingAttr.Level];

export {YfmHeadingAttr} from './const';

export type YfmHeadingSpecsOptions = {
/**
* @deprecated: use placeholderOptions instead.
*/
headingPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
placeholderOptions?: PlaceholderOptions;
};

/** YfmHeading extension needs markdown-it-attrs plugin */
export const YfmHeadingSpecs: ExtensionAuto<YfmHeadingSpecsOptions> = (builder, opts) => {
const {headingPlaceholder} = opts ?? {};
const {headingPlaceholder, placeholderOptions} = opts ?? {};

builder.addNode(headingNodeName, () => ({
spec: {
Expand Down Expand Up @@ -52,7 +57,10 @@ export const YfmHeadingSpecs: ExtensionAuto<YfmHeadingSpecsOptions> = (builder,
];
},
placeholder: {
content: headingPlaceholder ?? DEFAULT_PLACEHOLDER,
content:
processPlaceholderContent(placeholderOptions?.heading) ??
headingPlaceholder ??
DEFAULT_PLACEHOLDER,
alwaysVisible: true,
},
},
Expand Down
Loading

0 comments on commit 593f2c7

Please sign in to comment.