···11+import { InputRule, markInputRule, markPasteRule, PasteRule } from '@tiptap/core';
22+import { Link } from '@tiptap/extension-link';
33+44+import type { LinkOptions } from '@tiptap/extension-link';
55+66+/**
77+ * The input regex for Markdown links with title support, and multiple quotation marks (required
88+ * in case the `Typography` extension is being included).
99+ */
1010+const inputRegex = /(?:^|\s)\[([^\]]*)?\]\((\S+)(?: ["“](.+)["”])?\)$/i;
1111+1212+/**
1313+ * The paste regex for Markdown links with title support, and multiple quotation marks (required
1414+ * in case the `Typography` extension is being included).
1515+ */
1616+const pasteRegex = /(?:^|\s)\[([^\]]*)?\]\((\S+)(?: ["“](.+)["”])?\)/gi;
1717+1818+/**
1919+ * Input rule built specifically for the `Link` extension, which ignores the auto-linked URL in
2020+ * parentheses (e.g., `(https://doist.dev)`).
2121+ *
2222+ * @see https://github.com/ueberdosis/tiptap/discussions/1865
2323+ */
2424+function linkInputRule(config: Parameters<typeof markInputRule>[0]) {
2525+ const defaultMarkInputRule = markInputRule(config);
2626+2727+ return new InputRule({
2828+ find: config.find,
2929+ handler(props) {
3030+ const { tr } = props.state;
3131+3232+ defaultMarkInputRule.handler(props);
3333+ tr.setMeta('preventAutolink', true);
3434+ }
3535+ });
3636+}
3737+3838+/**
3939+ * Paste rule built specifically for the `Link` extension, which ignores the auto-linked URL in
4040+ * parentheses (e.g., `(https://doist.dev)`). This extension was inspired from the multiple
4141+ * implementations found in a Tiptap discussion at GitHub.
4242+ *
4343+ * @see https://github.com/ueberdosis/tiptap/discussions/1865
4444+ */
4545+function linkPasteRule(config: Parameters<typeof markPasteRule>[0]) {
4646+ const defaultMarkPasteRule = markPasteRule(config);
4747+4848+ return new PasteRule({
4949+ find: config.find,
5050+ handler(props) {
5151+ const { tr } = props.state;
5252+5353+ defaultMarkPasteRule.handler(props);
5454+ tr.setMeta('preventAutolink', true);
5555+ }
5656+ });
5757+}
5858+5959+/**
6060+ * The options available to customize the `RichTextLink` extension.
6161+ */
6262+type RichTextLinkOptions = LinkOptions;
6363+6464+/**
6565+ * Custom extension that extends the built-in `Link` extension to add additional input/paste rules
6666+ * for converting the Markdown link syntax (i.e. `[Doist](https://doist.com)`) into links, and also
6767+ * adds support for the `title` attribute.
6868+ */
6969+const RichTextLink = Link.extend<RichTextLinkOptions>({
7070+ inclusive: false,
7171+ addOptions() {
7272+ return {
7373+ ...this.parent?.(),
7474+ openOnClick: 'whenNotEditable'
7575+ };
7676+ },
7777+ addAttributes() {
7878+ return {
7979+ ...this.parent?.(),
8080+ title: {
8181+ default: null
8282+ }
8383+ };
8484+ },
8585+ addInputRules() {
8686+ return [
8787+ linkInputRule({
8888+ find: inputRegex,
8989+ type: this.type,
9090+9191+ // We need to use `pop()` to remove the last capture groups from the match to
9292+ // satisfy Tiptap's `markPasteRule` expectation of having the content as the last
9393+ // capture group in the match (this makes the attribute order important)
9494+ getAttributes(match) {
9595+ return {
9696+ title: match.pop()?.trim(),
9797+ href: match.pop()?.trim()
9898+ };
9999+ }
100100+ })
101101+ ];
102102+ },
103103+ addPasteRules() {
104104+ return [
105105+ linkPasteRule({
106106+ find: pasteRegex,
107107+ type: this.type,
108108+109109+ // We need to use `pop()` to remove the last capture groups from the match to
110110+ // satisfy Tiptap's `markInputRule` expectation of having the content as the last
111111+ // capture group in the match (this makes the attribute order important)
112112+ getAttributes(match) {
113113+ return {
114114+ title: match.pop()?.trim(),
115115+ href: match.pop()?.trim()
116116+ };
117117+ }
118118+ })
119119+ ];
120120+ }
121121+});
122122+123123+export { RichTextLink };
124124+125125+export type { RichTextLinkOptions };
···11+import type { Component } from 'svelte';
22+import type { BaseCardProps } from './BaseCard/BaseCard.svelte';
33+import type { Item } from '$lib/types';
44+import type { BaseEditingCardProps } from './BaseCard/BaseEditingCard.svelte';
55+66+export type CardDefinition = {
77+ cardComponent: Component<BaseCardProps>;
88+ editingCardComponent: Component<BaseEditingCardProps>;
99+ createNew?: (item: Item) => void;
1010+};
+2-1
src/lib/index.ts
···11// place files you want to import through the `$lib` alias in this folder.
22-export const margin = 16;22+export const margin = 16;
33+export const mobileMargin = 12;