Good point to make a commit
This commit is contained in:
24
.gowebbuild.yaml
Normal file
24
.gowebbuild.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
- esbuild:
|
||||
entryPoints:
|
||||
- demo/src/the-app.js
|
||||
outdir: demo/dist
|
||||
sourcemap: 1
|
||||
format: 3
|
||||
splitting: true
|
||||
platform: 0
|
||||
bundle: true
|
||||
write: true
|
||||
logLevel: 3
|
||||
purgeBeforeBuild: false
|
||||
watch:
|
||||
paths:
|
||||
- .
|
||||
exclude:
|
||||
- demo/
|
||||
injectLiveReload: demo/index.html
|
||||
serve:
|
||||
path: "demo"
|
||||
port: 8080
|
||||
# link:
|
||||
# from: ../../web/tp-elements
|
||||
# to: ./frontend
|
17440
demo/dist/the-app.js
vendored
Normal file
17440
demo/dist/the-app.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
demo/index.html
Normal file
18
demo/index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html><html lang="en"><head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>tp-rich-text-box demo</title>
|
||||
|
||||
<script type="module" src="./dist/the-app.js"></script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<the-app></the-app>
|
||||
|
||||
<script src="http://localhost:35729/livereload.js" type="text/javascript"></script></body></html>
|
54
demo/src/the-app.js
Normal file
54
demo/src/the-app.js
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
@license
|
||||
Copyright (c) 2025 trading_peter
|
||||
This program is available under Apache License Version 2.0
|
||||
*/
|
||||
|
||||
import '../../tp-rich-text-box.js';
|
||||
import '../../tp-rtb-bold.js';
|
||||
import '../../tp-rtb-italic.js';
|
||||
import '../../tp-rtb-strike.js';
|
||||
import '../../tp-rtb-underline.js';
|
||||
import '../../tp-rtb-code.js';
|
||||
import '../../tp-rtb-clear-format.js';
|
||||
import { LitElement, html, css } from 'lit';
|
||||
|
||||
class TheApp extends LitElement {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
`
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<tp-rich-text-box>
|
||||
<tp-rtb-bold></tp-rtb-bold>
|
||||
<tp-rtb-italic></tp-rtb-italic>
|
||||
<tp-rtb-strike></tp-rtb-strike>
|
||||
<tp-rtb-underline></tp-rtb-underline>
|
||||
<tp-rtb-code></tp-rtb-code>
|
||||
<tp-rtb-clear-format></tp-rtb-clear-format>
|
||||
</tp-rich-text-box>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('the-app', TheApp);
|
597
package-lock.json
generated
Normal file
597
package-lock.json
generated
Normal file
@ -0,0 +1,597 @@
|
||||
{
|
||||
"name": "@tp/tp-rich-text-box",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@tp/tp-rich-text-box",
|
||||
"version": "0.0.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^2.12.0",
|
||||
"@tiptap/extension-bold": "^2.12.0",
|
||||
"@tiptap/extension-code": "^2.24.2",
|
||||
"@tiptap/extension-document": "^2.24.2",
|
||||
"@tiptap/extension-hard-break": "^2.24.2",
|
||||
"@tiptap/extension-italic": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-paragraph": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-underline": "^2.0.0-beta.220",
|
||||
"lit": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lit-labs/ssr-dom-shim": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz",
|
||||
"integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@lit/reactive-element": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz",
|
||||
"integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@remirror/core-constants": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
|
||||
"integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.12.0.tgz",
|
||||
"integrity": "sha512-3qX8oGVKFFZzQ0vit+ZolR6AJIATBzmEmjAA0llFhWk4vf3v64p1YcXcJsOBsr5scizJu5L6RYWEFatFwqckRg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bold": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.12.0.tgz",
|
||||
"integrity": "sha512-lAUtoLDLRc5ofD2I9MFY6MQ7d1qBLLqS1rvpwaPjOaoQb/GPVnaHj9qXYG0SY9K3erMtto48bMFpAcscjZHzZQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.24.2.tgz",
|
||||
"integrity": "sha512-dK1jOm0Xe0h8SUXVUJPj3AxWb1N4zeBkdPZFoz+iUHacpymMinH1CuukN9UpwmSi0YPfrIMKkCaw5WOEzjV8RA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-document": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.24.2.tgz",
|
||||
"integrity": "sha512-w3q1JaWZlwK8aHmF4lrFqalLssNkZoS3rjL/iS0v69q/fTI9t0WmCx5Jx427eUlNITZ5XoCL8zguKmnSPbFovg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-hard-break": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.24.2.tgz",
|
||||
"integrity": "sha512-6TB9GBUTp3DIOptQubEVvL6BVKhxfLzAJwWYXjw0EkZHrK8TQPB3QIjLV/uZy29Ruji2k97ytxuxfrGoQXoXtA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-italic": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.24.2.tgz",
|
||||
"integrity": "sha512-gW9c0zJh4f9D2uZl13rhV8FFt7UgISLiRp4e+DynpKUkhjftDHmruii5Qw6fz9W5cf/vQcyMwCN3lO7Efqnyng==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-paragraph": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.12.0.tgz",
|
||||
"integrity": "sha512-QNK5cgewCunWFxpLlbvvoO1rrLgEtNKxiY79fctP9toV+e59R+1i1Q9lXC1O5mOfDgVxCb6uFDMsqmKhFjpPog==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.24.2.tgz",
|
||||
"integrity": "sha512-7JJ+IOTOoXlAqXDiUY9A+oRx01vRClvKuQzIDQoDtvd4Ut9rkZ+9L+Iv7AE/HzGkOOAVvfvLzYcyHiHDOpArDA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.12.0.tgz",
|
||||
"integrity": "sha512-0ytN9V1tZYTXdiYDQg4FB2SQ56JAJC9r/65snefb9ztl+gZzDrIvih7CflHs1ic9PgyjexfMLeH+VzuMccNyZw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-underline": {
|
||||
"version": "2.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.24.2.tgz",
|
||||
"integrity": "sha512-vzsGRGsHkoV43tnJKjb4aLzVYtJ531Puxjf3qToGP5kRqyuSl2FyCARTZUHgVhMmD7Yu6oXsrXvTR3pNaDuIrA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.12.0.tgz",
|
||||
"integrity": "sha512-TNzVwpeNzFfHAcYTOKqX9iU4fRxliyoZrCnERR+RRzeg7gWrXrCLubQt1WEx0sojMAfznshSL3M5HGsYjEbYwA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.3.0",
|
||||
"prosemirror-collab": "^1.3.1",
|
||||
"prosemirror-commands": "^1.6.2",
|
||||
"prosemirror-dropcursor": "^1.8.1",
|
||||
"prosemirror-gapcursor": "^1.3.2",
|
||||
"prosemirror-history": "^1.4.1",
|
||||
"prosemirror-inputrules": "^1.4.0",
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-markdown": "^1.13.1",
|
||||
"prosemirror-menu": "^1.2.4",
|
||||
"prosemirror-model": "^1.23.0",
|
||||
"prosemirror-schema-basic": "^1.2.3",
|
||||
"prosemirror-schema-list": "^1.4.1",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-tables": "^1.6.4",
|
||||
"prosemirror-trailing-node": "^3.0.0",
|
||||
"prosemirror-transform": "^1.10.2",
|
||||
"prosemirror-view": "^1.37.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/trusted-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"license": "Python-2.0",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lit": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz",
|
||||
"integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^2.1.0",
|
||||
"lit-element": "^4.2.0",
|
||||
"lit-html": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lit-element": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz",
|
||||
"integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.2.0",
|
||||
"@lit/reactive-element": "^2.1.0",
|
||||
"lit-html": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lit-html": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz",
|
||||
"integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/orderedmap": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
|
||||
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/prosemirror-changeset": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.0.tgz",
|
||||
"integrity": "sha512-8wRKhlEwEJ4I13Ju54q2NZR1pVKGTgJ/8XsQ8L5A5uUsQ/YQScQJuEAuh8Bn8i6IwAMjjLRABd9lVli+DlIiVw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-collab": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
|
||||
"integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-commands": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
|
||||
"integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-dropcursor": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
|
||||
"integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0",
|
||||
"prosemirror-view": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-gapcursor": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz",
|
||||
"integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.0.0",
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-view": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-history": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
|
||||
"integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-inputrules": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz",
|
||||
"integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-keymap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
|
||||
"integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"w3c-keyname": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz",
|
||||
"integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^14.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-menu": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz",
|
||||
"integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"crelt": "^1.0.0",
|
||||
"prosemirror-commands": "^1.0.0",
|
||||
"prosemirror-history": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-model": {
|
||||
"version": "1.25.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz",
|
||||
"integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-basic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
|
||||
"integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-list": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
|
||||
"integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-state": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
|
||||
"integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-tables": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz",
|
||||
"integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-model": "^1.25.0",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-transform": "^1.10.3",
|
||||
"prosemirror-view": "^1.39.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-trailing-node": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
|
||||
"integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@remirror/core-constants": "3.0.0",
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prosemirror-model": "^1.22.1",
|
||||
"prosemirror-state": "^1.4.2",
|
||||
"prosemirror-view": "^1.33.8"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-transform": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
|
||||
"integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-view": {
|
||||
"version": "1.39.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.39.3.tgz",
|
||||
"integrity": "sha512-bY/7kg0LzRE7ytR0zRdSMWX3sknEjw68l836ffLPMh0OG3OYnNuBDUSF3v0vjvnzgYjgY9ZH/RypbARURlcMFA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.20.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
16
package.json
16
package.json
@ -1,18 +1,28 @@
|
||||
{
|
||||
"name": "@tp/tp-element",
|
||||
"name": "@tp/tp-rich-text-box",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "tp-element.js",
|
||||
"main": "tp-rich-text-box.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitea.codeblob.work/tp-elements/tp-element.git"
|
||||
"url": "https://gitea.codeblob.work/tp-elements/tp-rich-text-box.git"
|
||||
},
|
||||
"author": "trading_peter",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^2.12.0",
|
||||
"@tiptap/extension-bold": "^2.12.0",
|
||||
"@tiptap/extension-code": "^2.24.2",
|
||||
"@tiptap/extension-document": "^2.24.2",
|
||||
"@tiptap/extension-hard-break": "^2.24.2",
|
||||
"@tiptap/extension-italic": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-paragraph": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.220",
|
||||
"@tiptap/extension-underline": "^2.0.0-beta.220",
|
||||
"lit": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
/**
|
||||
@license
|
||||
Copyright (c) 2024 trading_peter
|
||||
This program is available under Apache License Version 2.0
|
||||
*/
|
||||
|
||||
import { LitElement, html, css } from 'lit';
|
||||
|
||||
class TpElement extends LitElement {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
`
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
const { } = this;
|
||||
|
||||
return html`
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return { };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
window.customElements.define('tp-element', TpElement);
|
227
tp-rich-text-box.js
Normal file
227
tp-rich-text-box.js
Normal file
@ -0,0 +1,227 @@
|
||||
/**
|
||||
@license
|
||||
Copyright (c) 2025 trading_peter
|
||||
This program is available under Apache License Version 2.0
|
||||
*/
|
||||
|
||||
import { LitElement, html, css } from 'lit';
|
||||
import { Editor } from '@tiptap/core';
|
||||
import Document from '@tiptap/extension-document';
|
||||
import Paragraph from '@tiptap/extension-paragraph';
|
||||
import Text from '@tiptap/extension-text';
|
||||
import HardBreak from '@tiptap/extension-hard-break';
|
||||
|
||||
class TpRichTextBox extends LitElement {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #ccc;
|
||||
min-height: 100px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#editor {
|
||||
padding: 8px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.custom-floating-menu {
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.custom-floating-menu[hidden] {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.extensions = [];
|
||||
this._slotObserver = new MutationObserver(this._processSlotChanges.bind(this));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="custom-floating-menu" hidden>
|
||||
<slot @slotchange=${this._handleSlotChange}></slot>
|
||||
</div>
|
||||
<div id="editor"></div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
editor: { type: Object },
|
||||
extensions: { type: Array }
|
||||
};
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
// Get initial extensions from slot
|
||||
this._processChildExtensions();
|
||||
|
||||
// Initialize the editor with collected extensions
|
||||
this._initEditor();
|
||||
|
||||
// Observe future slot changes
|
||||
this._slotObserver.observe(this, {
|
||||
childList: true,
|
||||
subtree: false
|
||||
});
|
||||
}
|
||||
|
||||
_initEditor() {
|
||||
if (this.editor) {
|
||||
this.editor.destroy();
|
||||
}
|
||||
|
||||
this.editor = new Editor({
|
||||
element: this.shadowRoot.querySelector('#editor'),
|
||||
extensions: this.extensions,
|
||||
content: '<p>Hello World!</p>',
|
||||
});
|
||||
|
||||
// Notify child extensions that the editor is ready
|
||||
const children = Array.from(this.children);
|
||||
children.forEach(child => {
|
||||
if (child._editorReady && typeof child._editorReady === 'function') {
|
||||
child._editorReady(this.editor);
|
||||
}
|
||||
});
|
||||
|
||||
this.editor.on('selectionUpdate', this._handleSelectionUpdate.bind(this));
|
||||
this.editor.on('blur', this._handleSelectionUpdate.bind(this));
|
||||
}
|
||||
|
||||
_handleSelectionUpdate() {
|
||||
const { editor } = this;
|
||||
const menu = this.shadowRoot.querySelector('.custom-floating-menu');
|
||||
|
||||
if (!editor || !menu) {
|
||||
console.log('Editor or menu element not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
const { empty, from, to } = editor.state.selection;
|
||||
|
||||
if (empty || from === to) {
|
||||
menu.hidden = true;
|
||||
console.log('Selection is empty or a caret. Hiding menu.');
|
||||
return;
|
||||
}
|
||||
|
||||
menu.hidden = false;
|
||||
requestAnimationFrame(() => {
|
||||
this._positionMenu(menu, editor);
|
||||
console.log('Text selected. Showing menu.');
|
||||
});
|
||||
}
|
||||
|
||||
_positionMenu(menuElement, editorInstance) {
|
||||
const { view } = editorInstance;
|
||||
const { selection } = editorInstance.state;
|
||||
const { from, to } = selection;
|
||||
|
||||
// Get the coordinates of the selection
|
||||
const start = view.coordsAtPos(from);
|
||||
const end = view.coordsAtPos(to);
|
||||
|
||||
// Calculate the center of the selection
|
||||
let left = (start.left + end.left) / 2;
|
||||
console.log('Menu offsetHeight:', menuElement.offsetHeight);
|
||||
let top = start.top - menuElement.offsetHeight - 10; // 10px above selection
|
||||
|
||||
// If the calculated top is negative, position the menu below the selection
|
||||
if (top < 0) {
|
||||
top = end.bottom + 10; // 10px below selection
|
||||
}
|
||||
|
||||
// Adjust left position if it goes out of viewport on the right
|
||||
const viewportWidth = window.innerWidth;
|
||||
const menuWidth = menuElement.offsetWidth;
|
||||
if (left + menuWidth > viewportWidth) {
|
||||
left = viewportWidth - menuWidth - 10; // 10px padding from right edge
|
||||
}
|
||||
|
||||
// Ensure left is not negative
|
||||
if (left < 0) {
|
||||
left = 10; // 10px padding from left edge
|
||||
}
|
||||
|
||||
// Position the menu
|
||||
menuElement.style.left = `${left}px`;
|
||||
menuElement.style.top = `${top}px`;
|
||||
console.log(`Menu positioned at: left=${left}px, top=${top}px`);
|
||||
}
|
||||
|
||||
_handleSlotChange(e) {
|
||||
this._processChildExtensions();
|
||||
}
|
||||
|
||||
_processSlotChanges(mutations) {
|
||||
let needsUpdate = false;
|
||||
|
||||
mutations.forEach(mutation => {
|
||||
if (mutation.type === 'childList') {
|
||||
needsUpdate = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (needsUpdate) {
|
||||
this._processChildExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
_processChildExtensions() {
|
||||
this.extensions = [
|
||||
Document,
|
||||
Paragraph,
|
||||
Text,
|
||||
HardBreak
|
||||
];
|
||||
|
||||
// Get all extension components
|
||||
const children = Array.from(this.children);
|
||||
|
||||
children.forEach(child => {
|
||||
// If the child has a getExtension method, it's an extension component
|
||||
if (child.getExtension && typeof child.getExtension === 'function') {
|
||||
const extension = child.getExtension();
|
||||
if (extension) {
|
||||
this.extensions.push(extension);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Re-initialize the editor with new extensions if it already exists
|
||||
if (this.editor) {
|
||||
this._initEditor();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (this._slotObserver) {
|
||||
this._slotObserver.disconnect();
|
||||
}
|
||||
if (this.editor) {
|
||||
this.editor.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('tp-rich-text-box', TpRichTextBox);
|
76
tp-rtb-base-extension.js
Normal file
76
tp-rtb-base-extension.js
Normal file
@ -0,0 +1,76 @@
|
||||
import { LitElement, html, css } from 'lit';
|
||||
|
||||
export class TpRtbBaseExtension extends LitElement {
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0 2px;
|
||||
padding: 4px 8px;
|
||||
background: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
button.active {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
label: { type: String },
|
||||
active: { type: Boolean, reflect: true }
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.label = '';
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<button class="${this.active ? 'active' : ''}" @click=${this._handleClick}>
|
||||
${this.label}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._findParentEditor();
|
||||
}
|
||||
|
||||
_findParentEditor() {
|
||||
this.parentEditor = this.closest('tp-rich-text-box');
|
||||
}
|
||||
|
||||
_editorReady(editorInstance) {
|
||||
this.parentEditor.editor = editorInstance;
|
||||
this._setupEditorListeners();
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
// To be implemented by child classes
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
// To be implemented by child classes
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
// To be implemented by child classes
|
||||
return null;
|
||||
}
|
||||
}
|
34
tp-rtb-bold.js
Normal file
34
tp-rtb-bold.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Bold from '@tiptap/extension-bold';
|
||||
|
||||
class TpRtbBold extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Bold';
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Bold;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().toggleBold().run();
|
||||
}
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
// Update button state when selection changes
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('bold');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('bold');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-bold', TpRtbBold);
|
16
tp-rtb-clear-format.js
Normal file
16
tp-rtb-clear-format.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
|
||||
class TpRtbClearFormat extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Clear Format';
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().unsetAllMarks().run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-clear-format', TpRtbClearFormat);
|
34
tp-rtb-code.js
Normal file
34
tp-rtb-code.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Code from '@tiptap/extension-code';
|
||||
|
||||
class TpRtbCode extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Code';
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Code;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().toggleCode().run();
|
||||
}
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
// Update button state when selection changes
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('code');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('code');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-code', TpRtbCode);
|
34
tp-rtb-italic.js
Normal file
34
tp-rtb-italic.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Italic from '@tiptap/extension-italic';
|
||||
|
||||
class TpRtbItalic extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Italic';
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Italic;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().toggleItalic().run();
|
||||
}
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
// Update button state when selection changes
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('italic');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('italic');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-italic', TpRtbItalic);
|
34
tp-rtb-strike.js
Normal file
34
tp-rtb-strike.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Strike from '@tiptap/extension-strike';
|
||||
|
||||
class TpRtbStrike extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Strike';
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Strike;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().toggleStrike().run();
|
||||
}
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
// Update button state when selection changes
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('strike');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('strike');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-strike', TpRtbStrike);
|
34
tp-rtb-underline.js
Normal file
34
tp-rtb-underline.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { TpRtbBaseExtension } from './tp-rtb-base-extension.js';
|
||||
import Underline from '@tiptap/extension-underline';
|
||||
|
||||
class TpRtbUnderline extends TpRtbBaseExtension {
|
||||
constructor() {
|
||||
super();
|
||||
this.label = 'Underline';
|
||||
}
|
||||
|
||||
getExtension() {
|
||||
return Underline;
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.parentEditor && this.parentEditor.editor) {
|
||||
this.parentEditor.editor.chain().focus().toggleUnderline().run();
|
||||
}
|
||||
}
|
||||
|
||||
_setupEditorListeners() {
|
||||
const { editor } = this.parentEditor;
|
||||
|
||||
// Update button state when selection changes
|
||||
editor.on('selectionUpdate', () => {
|
||||
this.active = editor.isActive('underline');
|
||||
});
|
||||
|
||||
editor.on('focus', () => {
|
||||
this.active = editor.isActive('underline');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tp-rtb-underline', TpRtbUnderline);
|
Reference in New Issue
Block a user