@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +173 -0
  4. package/dist/RichText.d.ts +4 -0
  5. package/dist/RichText.js +179 -0
  6. package/dist/RichText.styles.d.ts +31 -0
  7. package/dist/RichText.styles.js +87 -0
  8. package/dist/RichText.types.d.ts +139 -0
  9. package/dist/RichText.types.js +44 -0
  10. package/dist/blockModel/blockModel.types.d.ts +130 -0
  11. package/dist/blockModel/blockModel.types.js +1 -0
  12. package/dist/blockModel/index.d.ts +2 -0
  13. package/dist/blockModel/index.js +14 -0
  14. package/dist/blockModel/serializers/documentToHtml.d.ts +2 -0
  15. package/dist/blockModel/serializers/documentToHtml.js +101 -0
  16. package/dist/blockModel/serializers/documentToMarkdown.d.ts +2 -0
  17. package/dist/blockModel/serializers/documentToMarkdown.js +84 -0
  18. package/dist/blockModel/serializers/documentToTiptap.d.ts +2 -0
  19. package/dist/blockModel/serializers/documentToTiptap.js +133 -0
  20. package/dist/blockModel/serializers/htmlToDocument.d.ts +2 -0
  21. package/dist/blockModel/serializers/htmlToDocument.js +242 -0
  22. package/dist/blockModel/serializers/index.d.ts +6 -0
  23. package/dist/blockModel/serializers/index.js +14 -0
  24. package/dist/blockModel/serializers/markdownToDocument.d.ts +10 -0
  25. package/dist/blockModel/serializers/markdownToDocument.js +11 -0
  26. package/dist/blockModel/serializers/tiptapToDocument.d.ts +2 -0
  27. package/dist/blockModel/serializers/tiptapToDocument.js +189 -0
  28. package/dist/components/ImagePopover.d.ts +3 -0
  29. package/dist/components/ImagePopover.js +89 -0
  30. package/dist/components/LinkPopover.d.ts +3 -0
  31. package/dist/components/LinkPopover.js +57 -0
  32. package/dist/components/Toolbar.d.ts +3 -0
  33. package/dist/components/Toolbar.js +436 -0
  34. package/dist/components/index.d.ts +3 -0
  35. package/dist/components/index.js +8 -0
  36. package/dist/extensions/CodeSnippet.d.ts +19 -0
  37. package/dist/extensions/CodeSnippet.js +76 -0
  38. package/dist/index.d.ts +6 -0
  39. package/dist/index.js +52 -0
  40. package/dist/modules.d.js +1 -0
  41. package/dist/modules.d.ts +4 -0
  42. package/dist/utils/computeVisibleCount.d.ts +6 -0
  43. package/dist/utils/computeVisibleCount.js +19 -0
  44. package/dist/utils/getExtensions.d.ts +13 -0
  45. package/dist/utils/getExtensions.js +80 -0
  46. package/dist/utils/index.d.ts +3 -0
  47. package/dist/utils/index.js +8 -0
  48. package/dist/utils/normalizeUrl.d.ts +7 -0
  49. package/dist/utils/normalizeUrl.js +13 -0
  50. package/dist/utils/sanitizeUrl.d.ts +9 -0
  51. package/dist/utils/sanitizeUrl.js +30 -0
  52. 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,3 @@
1
+ export { getExtensions } from './getExtensions';
2
+ export { normalizeUrl } from './normalizeUrl';
3
+ export { sanitizeUrl } from './sanitizeUrl';
@@ -0,0 +1,8 @@
1
+ import { getExtensions } from "./getExtensions.js";
2
+ import { normalizeUrl } from "./normalizeUrl.js";
3
+ import { sanitizeUrl } from "./sanitizeUrl.js";
4
+ export {
5
+ getExtensions,
6
+ normalizeUrl,
7
+ sanitizeUrl
8
+ };
@@ -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
+ }