Skip to content

Commit

Permalink
feat: 🎸 make the hashtag display to true by default
Browse files Browse the repository at this point in the history
  • Loading branch information
Saul-Mirone committed Jul 15, 2022
1 parent c5d3782 commit 38a6bcb
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 115 deletions.
237 changes: 122 additions & 115 deletions packages/preset-commonmark/src/node/heading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,133 +169,140 @@ const headingHashPlugin = (ctx: Ctx, type: NodeType, utils: Utils): Plugin => {
});
};

export const heading = createNode<Keys, { getId: (node: Node) => string }>((utils, options) => {
const id = 'heading';
export const heading = createNode<Keys, { getId: (node: Node) => string; displayHashtag: boolean }>(
(utils, options) => {
const id = 'heading';

const getId = options?.getId ?? createId;
const getId = options?.getId ?? createId;
const displayHashtag = options?.displayHashtag ?? true;

return {
id,
schema: () => ({
content: 'inline*',
group: 'block',
defining: true,
attrs: {
id: {
default: '',
return {
id,
schema: () => ({
content: 'inline*',
group: 'block',
defining: true,
attrs: {
id: {
default: '',
},
level: {
default: 1,
},
},
level: {
default: 1,
parseDOM: headingIndex.map((x) => ({
tag: `h${x}`,
getAttrs: (node) => {
if (!(node instanceof HTMLElement)) {
throw expectDomTypeError(node);
}
return { level: x, id: node.id };
},
})),
toDOM: (node) => {
return [
`h${node.attrs['level']}`,
{
id: node.attrs['id'] || getId(node),
class: utils.getClassName(node.attrs, `heading h${node.attrs['level']}`),
},
0,
];
},
},
parseDOM: headingIndex.map((x) => ({
tag: `h${x}`,
getAttrs: (node) => {
if (!(node instanceof HTMLElement)) {
throw expectDomTypeError(node);
}
return { level: x, id: node.id };
parseMarkdown: {
match: ({ type }) => type === id,
runner: (state, node, type) => {
const depth = node['depth'] as number;
state.openNode(type, { level: depth });
state.next(node.children);
state.closeNode();
},
},
})),
toDOM: (node) => {
return [
`h${node.attrs['level']}`,
{
id: node.attrs['id'] || getId(node),
class: utils.getClassName(node.attrs, `heading h${node.attrs['level']}`),
toMarkdown: {
match: (node) => node.type.name === id,
runner: (state, node) => {
state.openNode('heading', undefined, { depth: node.attrs['level'] });
const lastIsHardbreak = node.childCount >= 1 && node.lastChild?.type.name === 'hardbreak';
if (lastIsHardbreak) {
const contentArr: Node[] = [];
node.content.forEach((n, _, i) => {
if (i === node.childCount - 1) {
return;
}
contentArr.push(n);
});
state.next(Fragment.fromArray(contentArr));
} else {
state.next(node.content);
}
state.closeNode();
},
0,
];
},
parseMarkdown: {
match: ({ type }) => type === id,
runner: (state, node, type) => {
const depth = node['depth'] as number;
state.openNode(type, { level: depth });
state.next(node.children);
state.closeNode();
},
},
toMarkdown: {
match: (node) => node.type.name === id,
runner: (state, node) => {
state.openNode('heading', undefined, { depth: node.attrs['level'] });
const lastIsHardbreak = node.childCount >= 1 && node.lastChild?.type.name === 'hardbreak';
if (lastIsHardbreak) {
const contentArr: Node[] = [];
node.content.forEach((n, _, i) => {
if (i === node.childCount - 1) {
return;
}),
inputRules: (type, ctx) =>
headingIndex.map((x) =>
textblockTypeInputRule(new RegExp(`^(#{1,${x}})\\s$`), type, () => {
const view = ctx.get(editorViewCtx);
const { $from } = view.state.selection;
const node = $from.node();
if (node.type.name === 'heading') {
let level = Number(node.attrs['level']) + Number(x);
if (level > 6) {
level = 6;
}
contentArr.push(n);
});
state.next(Fragment.fromArray(contentArr));
} else {
state.next(node.content);
}
state.closeNode();
},
},
}),
inputRules: (type, ctx) =>
headingIndex.map((x) =>
textblockTypeInputRule(new RegExp(`^(#{1,${x}})\\s$`), type, () => {
const view = ctx.get(editorViewCtx);
const { $from } = view.state.selection;
const node = $from.node();
if (node.type.name === 'heading') {
let level = Number(node.attrs['level']) + Number(x);
if (level > 6) {
level = 6;
return {
level,
};
}
return {
level,
level: x,
};
}),
),
commands: (type, ctx) => [
createCmd(TurnIntoHeading, (level = 1) => {
if (level < 1) {
return setBlockType(level === 0 ? ctx.get(schemaCtx).nodes['paragraph'] || type : type);
}
return {
level: x,
};
return setBlockType(level === 0 ? ctx.get(schemaCtx).nodes['paragraph'] || type : type, { level });
}),
),
commands: (type, ctx) => [
createCmd(TurnIntoHeading, (level = 1) => {
if (level < 1) {
return setBlockType(level === 0 ? ctx.get(schemaCtx).nodes['paragraph'] || type : type);
}
return setBlockType(level === 0 ? ctx.get(schemaCtx).nodes['paragraph'] || type : type, { level });
}),
createCmd(DowngradeHeading, () => {
return (state, dispatch, view) => {
const { $from } = state.selection;
const node = $from.node();
if (node.type !== type || !state.selection.empty || $from.parentOffset !== 0) return false;
createCmd(DowngradeHeading, () => {
return (state, dispatch, view) => {
const { $from } = state.selection;
const node = $from.node();
if (node.type !== type || !state.selection.empty || $from.parentOffset !== 0) return false;

const level = node.attrs['level'] - 1;
if (!level) {
return setBlockType(ctx.get(schemaCtx).nodes['paragraph'] || type)(state, dispatch, view);
}
const level = node.attrs['level'] - 1;
if (!level) {
return setBlockType(ctx.get(schemaCtx).nodes['paragraph'] || type)(state, dispatch, view);
}

dispatch?.(
state.tr.setNodeMarkup(state.selection.$from.before(), undefined, {
...node.attrs,
level,
}),
);
return true;
};
}),
],
shortcuts: {
[SupportedKeys.H1]: createShortcut(TurnIntoHeading, 'Mod-Alt-1', 1),
[SupportedKeys.H2]: createShortcut(TurnIntoHeading, 'Mod-Alt-2', 2),
[SupportedKeys.H3]: createShortcut(TurnIntoHeading, 'Mod-Alt-3', 3),
[SupportedKeys.H4]: createShortcut(TurnIntoHeading, 'Mod-Alt-4', 4),
[SupportedKeys.H5]: createShortcut(TurnIntoHeading, 'Mod-Alt-5', 5),
[SupportedKeys.H6]: createShortcut(TurnIntoHeading, 'Mod-Alt-6', 6),
[SupportedKeys.DowngradeHeading]: createShortcut(DowngradeHeading, ['Backspace', 'Delete']),
},
prosePlugins: (type, ctx) => {
return [headingIdPlugin(ctx, type, getId), headingHashPlugin(ctx, type, utils)];
},
};
});
dispatch?.(
state.tr.setNodeMarkup(state.selection.$from.before(), undefined, {
...node.attrs,
level,
}),
);
return true;
};
}),
],
shortcuts: {
[SupportedKeys.H1]: createShortcut(TurnIntoHeading, 'Mod-Alt-1', 1),
[SupportedKeys.H2]: createShortcut(TurnIntoHeading, 'Mod-Alt-2', 2),
[SupportedKeys.H3]: createShortcut(TurnIntoHeading, 'Mod-Alt-3', 3),
[SupportedKeys.H4]: createShortcut(TurnIntoHeading, 'Mod-Alt-4', 4),
[SupportedKeys.H5]: createShortcut(TurnIntoHeading, 'Mod-Alt-5', 5),
[SupportedKeys.H6]: createShortcut(TurnIntoHeading, 'Mod-Alt-6', 6),
[SupportedKeys.DowngradeHeading]: createShortcut(DowngradeHeading, ['Backspace', 'Delete']),
},
prosePlugins: (type, ctx) => {
const plugins = [headingIdPlugin(ctx, type, getId)];
if (displayHashtag) {
plugins.push(headingHashPlugin(ctx, type, utils));
}
return plugins;
},
};
},
);
7 changes: 7 additions & 0 deletions website/pages/official-plugins/preset-commonmark/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ new Editor({ ... }).use(nodes);

## Node Options

### Heading

- getId: (node: PMNode) => string
Pass in a option to generate an id for the heading.
- displayHashtag: boolean
Whether to display the hashtag or not. Default is true.

### Image

- placeholder: The placeholder of empty status.
Expand Down

1 comment on commit 38a6bcb

@vercel
Copy link

@vercel vercel bot commented on 38a6bcb Jul 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.