Good point to make a commit

This commit is contained in:
2025-07-06 19:03:59 +02:00
parent 365143c7db
commit 2895b917fc
16 changed files with 18636 additions and 39 deletions

24
.gowebbuild.yaml Normal file
View 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

View File

@ -1 +1 @@
# tp-element # tp-rich-text-box

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
View 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
View 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
View 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
}
}
}

View File

@ -1,18 +1,28 @@
{ {
"name": "@tp/tp-element", "name": "@tp/tp-rich-text-box",
"version": "0.0.1", "version": "0.0.1",
"description": "", "description": "",
"main": "tp-element.js", "main": "tp-rich-text-box.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"repository": { "repository": {
"type": "git", "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", "author": "trading_peter",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "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" "lit": "^3.0.0"
} }
} }

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);