@synerise/ds-rich-text 0.1.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/CHANGELOG.md +10 -0
- package/LICENSE.md +21 -0
- package/README.md +173 -0
- package/dist/RichText.d.ts +4 -0
- package/dist/RichText.js +179 -0
- package/dist/RichText.styles.d.ts +31 -0
- package/dist/RichText.styles.js +87 -0
- package/dist/RichText.types.d.ts +139 -0
- package/dist/RichText.types.js +44 -0
- package/dist/blockModel/blockModel.types.d.ts +130 -0
- package/dist/blockModel/blockModel.types.js +1 -0
- package/dist/blockModel/index.d.ts +2 -0
- package/dist/blockModel/index.js +14 -0
- package/dist/blockModel/serializers/documentToHtml.d.ts +2 -0
- package/dist/blockModel/serializers/documentToHtml.js +101 -0
- package/dist/blockModel/serializers/documentToMarkdown.d.ts +2 -0
- package/dist/blockModel/serializers/documentToMarkdown.js +84 -0
- package/dist/blockModel/serializers/documentToTiptap.d.ts +2 -0
- package/dist/blockModel/serializers/documentToTiptap.js +133 -0
- package/dist/blockModel/serializers/htmlToDocument.d.ts +2 -0
- package/dist/blockModel/serializers/htmlToDocument.js +242 -0
- package/dist/blockModel/serializers/index.d.ts +6 -0
- package/dist/blockModel/serializers/index.js +14 -0
- package/dist/blockModel/serializers/markdownToDocument.d.ts +10 -0
- package/dist/blockModel/serializers/markdownToDocument.js +11 -0
- package/dist/blockModel/serializers/tiptapToDocument.d.ts +2 -0
- package/dist/blockModel/serializers/tiptapToDocument.js +189 -0
- package/dist/components/ImagePopover.d.ts +3 -0
- package/dist/components/ImagePopover.js +89 -0
- package/dist/components/LinkPopover.d.ts +3 -0
- package/dist/components/LinkPopover.js +57 -0
- package/dist/components/Toolbar.d.ts +3 -0
- package/dist/components/Toolbar.js +436 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +8 -0
- package/dist/extensions/CodeSnippet.d.ts +19 -0
- package/dist/extensions/CodeSnippet.js +76 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +52 -0
- package/dist/modules.d.js +1 -0
- package/dist/modules.d.ts +4 -0
- package/dist/utils/computeVisibleCount.d.ts +6 -0
- package/dist/utils/computeVisibleCount.js +19 -0
- package/dist/utils/getExtensions.d.ts +13 -0
- package/dist/utils/getExtensions.js +80 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/normalizeUrl.d.ts +7 -0
- package/dist/utils/normalizeUrl.js +13 -0
- package/dist/utils/sanitizeUrl.d.ts +9 -0
- package/dist/utils/sanitizeUrl.js +30 -0
- package/package.json +75 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import Image from "@tiptap/extension-image";
|
|
2
|
+
import Link from "@tiptap/extension-link";
|
|
3
|
+
import Placeholder from "@tiptap/extension-placeholder";
|
|
4
|
+
import Table from "@tiptap/extension-table";
|
|
5
|
+
import TableCell from "@tiptap/extension-table-cell";
|
|
6
|
+
import TableHeader from "@tiptap/extension-table-header";
|
|
7
|
+
import TableRow from "@tiptap/extension-table-row";
|
|
8
|
+
import TextAlign from "@tiptap/extension-text-align";
|
|
9
|
+
import Underline from "@tiptap/extension-underline";
|
|
10
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
11
|
+
import { CodeSnippet } from "../extensions/CodeSnippet.js";
|
|
12
|
+
const getExtensions = ({
|
|
13
|
+
features,
|
|
14
|
+
headingLevels,
|
|
15
|
+
placeholder,
|
|
16
|
+
copyText,
|
|
17
|
+
copiedText,
|
|
18
|
+
alwaysShowPlaceholder = false
|
|
19
|
+
}) => {
|
|
20
|
+
const extensions = [StarterKit.configure({
|
|
21
|
+
heading: features.includes("heading") ? {
|
|
22
|
+
levels: headingLevels
|
|
23
|
+
} : false,
|
|
24
|
+
bulletList: features.includes("bulletList") ? {} : false,
|
|
25
|
+
orderedList: features.includes("orderedList") ? {} : false,
|
|
26
|
+
strike: features.includes("strikethrough") ? {} : false,
|
|
27
|
+
bold: features.includes("bold") ? {} : false,
|
|
28
|
+
italic: features.includes("italic") ? {} : false,
|
|
29
|
+
codeBlock: features.includes("codeBlock") ? {} : false
|
|
30
|
+
})];
|
|
31
|
+
if (features.includes("underline")) {
|
|
32
|
+
extensions.push(Underline);
|
|
33
|
+
}
|
|
34
|
+
if (features.includes("link")) {
|
|
35
|
+
extensions.push(Link.configure({
|
|
36
|
+
openOnClick: true,
|
|
37
|
+
HTMLAttributes: {
|
|
38
|
+
rel: "noopener noreferrer",
|
|
39
|
+
target: "_blank"
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
if (features.includes("textAlign")) {
|
|
44
|
+
extensions.push(TextAlign.configure({
|
|
45
|
+
types: ["heading", "paragraph"]
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
if (features.includes("codeSnippet")) {
|
|
49
|
+
extensions.push(CodeSnippet.configure({
|
|
50
|
+
copyText: copyText ?? "Copy",
|
|
51
|
+
copiedText: copiedText ?? "Copied"
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
if (features.includes("image")) {
|
|
55
|
+
extensions.push(Image.configure({
|
|
56
|
+
inline: false,
|
|
57
|
+
allowBase64: true
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
if (features.includes("table")) {
|
|
61
|
+
extensions.push(Table.configure({
|
|
62
|
+
resizable: false
|
|
63
|
+
}), TableRow, TableHeader, TableCell);
|
|
64
|
+
}
|
|
65
|
+
if (placeholder) {
|
|
66
|
+
extensions.push(Placeholder.configure({
|
|
67
|
+
placeholder,
|
|
68
|
+
showOnlyWhenEditable: !alwaysShowPlaceholder,
|
|
69
|
+
// Default `showOnlyCurrent: true` renders the placeholder only in the node holding
|
|
70
|
+
// the cursor, so a freshly-opened, never-focused editor shows nothing. When the
|
|
71
|
+
// placeholder must be visible without focus (subtle preview), show it on any empty
|
|
72
|
+
// node instead.
|
|
73
|
+
showOnlyCurrent: !alwaysShowPlaceholder
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
return extensions;
|
|
77
|
+
};
|
|
78
|
+
export {
|
|
79
|
+
getExtensions
|
|
80
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepends https:// to URLs typed without a protocol (e.g. "www.google.com"),
|
|
3
|
+
* which the browser would otherwise resolve relative to the current origin.
|
|
4
|
+
* Absolute URLs and other schemes (mailto:, tel:, data:), protocol-relative
|
|
5
|
+
* URLs, in-page anchors, and site-relative paths are left untouched.
|
|
6
|
+
*/
|
|
7
|
+
export declare const normalizeUrl: (raw: string) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const normalizeUrl = (raw) => {
|
|
2
|
+
const url = raw.trim();
|
|
3
|
+
if (!url) {
|
|
4
|
+
return url;
|
|
5
|
+
}
|
|
6
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith("//") || url.startsWith("#") || url.startsWith("/")) {
|
|
7
|
+
return url;
|
|
8
|
+
}
|
|
9
|
+
return `https://${url}`;
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
normalizeUrl
|
|
13
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns `raw` when it is safe to use as a link `href`, otherwise `''`.
|
|
3
|
+
*
|
|
4
|
+
* Schemeless URLs (`www.foo.com`), protocol-relative (`//cdn/x`), site-relative
|
|
5
|
+
* (`/path`) and in-page anchors (`#id`) carry no scheme and are always allowed.
|
|
6
|
+
* Detection runs on a stripped copy while the original string is returned
|
|
7
|
+
* untouched when safe.
|
|
8
|
+
*/
|
|
9
|
+
export declare const sanitizeUrl: (raw: string) => string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const SAFE_HREF_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
|
|
2
|
+
const stripIgnoredChars = (value) => {
|
|
3
|
+
let out = "";
|
|
4
|
+
for (const ch of value) {
|
|
5
|
+
const code = ch.charCodeAt(0);
|
|
6
|
+
if (code <= 32 || code >= 127 && code <= 159) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
out += ch;
|
|
10
|
+
}
|
|
11
|
+
return out;
|
|
12
|
+
};
|
|
13
|
+
const sanitizeUrl = (raw) => {
|
|
14
|
+
const url = raw.trim();
|
|
15
|
+
if (!url) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
const stripped = stripIgnoredChars(url);
|
|
19
|
+
if (stripped.startsWith("//") || stripped.startsWith("/") || stripped.startsWith("#")) {
|
|
20
|
+
return url;
|
|
21
|
+
}
|
|
22
|
+
const scheme = stripped.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
23
|
+
if (!scheme) {
|
|
24
|
+
return url;
|
|
25
|
+
}
|
|
26
|
+
return SAFE_HREF_SCHEMES.has(`${scheme[1].toLowerCase()}:`) ? url : "";
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
sanitizeUrl
|
|
30
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@synerise/ds-rich-text",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "RichText UI Component for the Synerise Design System",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"repository": "Synerise/synerise-design",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"/dist",
|
|
10
|
+
"CHANGELOG.md",
|
|
11
|
+
"README.md",
|
|
12
|
+
"package.json",
|
|
13
|
+
"LICENSE.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "vite build",
|
|
20
|
+
"build:watch": "vite build --watch",
|
|
21
|
+
"prepublish": "pnpm run build",
|
|
22
|
+
"types": "tsc --noEmit",
|
|
23
|
+
"pack:ci": "pnpm pack --pack-destination ../../storybook/storybook-static/static",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"check:circular-dependencies": "madge --circular --extensions ts,tsx,js,jsx --ts-config tsconfig.json src/ --exclude '/dist/'",
|
|
27
|
+
"upgrade:ds": "ncu -f \"@synerise/ds-*\" -u"
|
|
28
|
+
},
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"types": "dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./dist/*.js": "./dist/*.js",
|
|
38
|
+
"./dist/*": "./dist/*.js"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@synerise/ds-button": "^1.5.35",
|
|
42
|
+
"@synerise/ds-copy-icon": "^1.2.16",
|
|
43
|
+
"@synerise/ds-form-field": "^1.3.24",
|
|
44
|
+
"@synerise/ds-icon": "^1.18.5",
|
|
45
|
+
"@synerise/ds-input": "^1.7.13",
|
|
46
|
+
"@synerise/ds-popover": "^1.6.2",
|
|
47
|
+
"@synerise/ds-toolbar": "^1.1.64",
|
|
48
|
+
"@synerise/ds-tooltip": "^1.5.4",
|
|
49
|
+
"@synerise/ds-utils": "^1.10.2",
|
|
50
|
+
"@tiptap/core": "^2.11.0",
|
|
51
|
+
"@tiptap/extension-image": "^2.11.0",
|
|
52
|
+
"@tiptap/extension-link": "^2.11.0",
|
|
53
|
+
"@tiptap/extension-placeholder": "^2.11.0",
|
|
54
|
+
"@tiptap/extension-table": "^2.11.0",
|
|
55
|
+
"@tiptap/extension-table-cell": "^2.11.0",
|
|
56
|
+
"@tiptap/extension-table-header": "^2.11.0",
|
|
57
|
+
"@tiptap/extension-table-row": "^2.11.0",
|
|
58
|
+
"@tiptap/extension-text-align": "^2.11.0",
|
|
59
|
+
"@tiptap/extension-underline": "^2.11.0",
|
|
60
|
+
"@tiptap/pm": "^2.11.0",
|
|
61
|
+
"@tiptap/react": "^2.11.0",
|
|
62
|
+
"@tiptap/starter-kit": "^2.11.0",
|
|
63
|
+
"markdown-it": "14.1.0"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@synerise/ds-core": "*",
|
|
67
|
+
"react": ">=16.9.0 <= 18.3.1",
|
|
68
|
+
"styled-components": "^5.3.3"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/markdown-it": "14.1.2",
|
|
72
|
+
"vitest": "4"
|
|
73
|
+
},
|
|
74
|
+
"gitHead": "6fcfd8345a1522b7e4ccd34337d5d25d1ca4e2ce"
|
|
75
|
+
}
|