fix: resolve TypeScript errors in frontend build

This commit is contained in:
Hiro
2026-03-30 23:16:07 +00:00
parent b733306773
commit 24925e1acb
2941 changed files with 418042 additions and 49 deletions

1
node_modules/.bin/markdown-it generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../markdown-it/bin/markdown-it.mjs

860
node_modules/.package-lock.json generated vendored
View File

@@ -67,12 +67,43 @@
"node": ">=12"
}
},
"node_modules/@floating-ui/core": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
"integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.11"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
"integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.7.5",
"@floating-ui/utils": "^0.2.11"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
"license": "MIT"
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"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"
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.60.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz",
@@ -90,6 +121,450 @@
"linux"
]
},
"node_modules/@tiptap/core": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.21.0.tgz",
"integrity": "sha512-IfnQiuEeabDSPr1C/zHFTbnvlTf5z0DE/d/xz4C6bkL4ZBDJ3rr99h2qsaV0l8F+kbNswZMlQdM8rxNlMy95fQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-blockquote": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.21.0.tgz",
"integrity": "sha512-JDM/RR6rM0dMCZ1UnEf7eqmN6pAdIa2llhN+E24HdTGNJCklMFhLAGE/OT8/1r7M0WWA9GVO7/PTe4EdGh6+lQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-bold": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.21.0.tgz",
"integrity": "sha512-iyEJRzG7XTCPlHwEDzUw3HnuYYCfL7lNpcCHmxcpYMrIUA8rv7EUxerIwApT6xY8hQ/07ljuJKgOyPvnJOOzuA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-bubble-menu": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.21.0.tgz",
"integrity": "sha512-/fabRRhhf8i4LAx9e8xz9ppqN5KgdJk3TxMuxAD5vAWGsejvhSoPa8O8H/QwwyntXm1Vue8aQiMHsUk48b2hGQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"@floating-ui/dom": "^1.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-bullet-list": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.21.0.tgz",
"integrity": "sha512-PWNF+xwxgOeXYGD88sCQLKL0eBoQqjUnZNALxBjN3Y7x4llalh42rHOp2Nt2t6UbQgqTBtBzU/uFcussTpxreQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extension-list": "^3.21.0"
}
},
"node_modules/@tiptap/extension-code": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.21.0.tgz",
"integrity": "sha512-D7wA9jp+4X2r1f3FIoga73s6Rn4rmZY57Jes6a4rK3HY+3yHk1r057pPIZSY8Drfs97jxHQVFdfUYUomLSFYBA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-code-block": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.21.0.tgz",
"integrity": "sha512-zrVOcOzDCjHQ8NJcC+qHmZZKiwnP/NMSb3qVJlSMN8TzuHept1MZCDa2Mbo70O6I0txo456SGuXB9sqV1vHmGg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-code-block-lowlight": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-3.21.0.tgz",
"integrity": "sha512-79sS0tqoGVX6wq30ejzohpUVLeGOkTTUn5hCqjsniyYPTEtrn4tHyBnS4Du2TbrDV4SqcwgisWExhuB8pfEdYQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/extension-code-block": "^3.21.0",
"@tiptap/pm": "^3.21.0",
"highlight.js": "^11",
"lowlight": "^2 || ^3"
}
},
"node_modules/@tiptap/extension-document": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.21.0.tgz",
"integrity": "sha512-7oCyzXI9ChvJQUlr23AURdfVar4OIsrYUvqdhEwo3bjcI/Q/j0KJiXfuh6ZzL5eVaINSailH53sZaGg4THQtUg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-dropcursor": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.21.0.tgz",
"integrity": "sha512-6fsDSVAM2iz7eElvT6iivMrGBGjIP/oPigVZ/SPm6f31phaYhz6TIOEgV/Lr2jaPIOgyK4U0cU4Yd4KUBCmhzQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extensions": "^3.21.0"
}
},
"node_modules/@tiptap/extension-floating-menu": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.21.0.tgz",
"integrity": "sha512-n2HzTB+I/5rAl8R/1sKMv92JiY1oDK1hroXizxEKYa6dskJcAMW0CfYyPcPOZWQQEe7qoeOvQISr2ooLAKW+Mw==",
"license": "MIT",
"optional": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@floating-ui/dom": "^1.0.0",
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-gapcursor": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.21.0.tgz",
"integrity": "sha512-wGjgAoYBTvPAe9QYMI5px355XcNeMkaUrMY9IHbMqgqdmHcDxqooxM4H6sYVX2CRcHwXy4I8NQAoOhSYrQJDMg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extensions": "^3.21.0"
}
},
"node_modules/@tiptap/extension-hard-break": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.21.0.tgz",
"integrity": "sha512-6JFVSAOQ1qhQHi9mVcdn2/XO8YIMgYV8zjarzNUzP6Sf2waeE5BLXjlg6rIH/945sY1J+FndTojLru6gQ07a5A==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-heading": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.21.0.tgz",
"integrity": "sha512-ji6VJmoRnDzAHYflEYEZohMHRi77UGLW1o3ua7UhI32iJ9nuYssbPNuzEeE4SvENMQwZRszad5+a+dKAa+NC7g==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-horizontal-rule": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.21.0.tgz",
"integrity": "sha512-vNBnOfFEY62CoJPGo4nonRM7RiOvhII1vhoO+WFr1GxDqCAfmEFjToflt7JT1UJdo6lMVcD+aaaAgOiuSz5p6g==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-italic": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.21.0.tgz",
"integrity": "sha512-2I8oPvwyXhRn1k8lbDFIutzvhtLEjoO5mmQCNX4TnT4PdxxaSrK9+ihYg12VeqhUeO7dg1MKiFqws0HVBrwzWg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-link": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.21.0.tgz",
"integrity": "sha512-oMU7Yve1sbgBsaFAUc2R0GPf4d3ZPVJeMUFC6b6X9rJIvx/IhEUEn9toQcSBGfp02uWK9NdQyIFYFdWlVXH++w==",
"license": "MIT",
"dependencies": {
"linkifyjs": "^4.3.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-list": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.21.0.tgz",
"integrity": "sha512-KeBlEtLrGce2d3dgL89hmwWEtREuzlW4XY5bYWpKNvCbFqvdSb3n7vkdkw32YclZmMWxAcABgW6ucCStkE0rsQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/extension-list-item": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.21.0.tgz",
"integrity": "sha512-1ZymZmlQVbAoC4q5x3cro0v5+3I6l+BHqbhIMQLjQFlAOJfcE0pvqRzAFW7PduxUj41tXEtsYqp2NREvO9F5Fg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extension-list": "^3.21.0"
}
},
"node_modules/@tiptap/extension-list-keymap": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.21.0.tgz",
"integrity": "sha512-EzrfW3ASNFPWKhR8sNOq7Kqw4hvaTAOn4dlI7chB8HIANSrlyPOUn+eKAnO6HQgsUgsbjg2GbTUrGrxcoLykUg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extension-list": "^3.21.0"
}
},
"node_modules/@tiptap/extension-ordered-list": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.21.0.tgz",
"integrity": "sha512-+d+0orokMfqaBfvr9tUBgGvo2ZCV+fR3JzsJTmnLBWOkhBSJN7H4pnfXPTue0qwspUwRmkLJxdIlU+J7HkMrng==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/extension-list": "^3.21.0"
}
},
"node_modules/@tiptap/extension-paragraph": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.21.0.tgz",
"integrity": "sha512-cMPG/jCoZ9NmLZ5ctFziILaxJGfDtMTb5OLBhifMFZeMVwF1pEJIygDEfnX/HSruv507weZSQG4pERO2tRszMg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-strike": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.21.0.tgz",
"integrity": "sha512-easnVaN11Wl+5fOtfvzJ10J762S9TRXZaMj5rLBGavgf82DCYHqhGhBqpLQrJ41r4nPABGlYvTRoxfvBLB74Lg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-text": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.21.0.tgz",
"integrity": "sha512-Zx8QdB8a5iBuE4uO21c3BjmpBfaJEr2Jd1QFnsdgx11fm6P7dGgZaGko1FaINhfOPRGTN6O/kiF02cDMdOHa/w==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extension-underline": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.21.0.tgz",
"integrity": "sha512-gGmBEymbWnr8AIS8bI/bPw5rcwo7wAFcBw/TsLd1nAanu1dDqSRNDBrit3m02Ru+D88u2SfNvmbOPI1pz+1f5w==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0"
}
},
"node_modules/@tiptap/extensions": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.21.0.tgz",
"integrity": "sha512-MN1uh5PmHT1F2BNsbc21MIS0AMFFA73oODlp/4ckpBR4o5AxRwV+8f43Cd52UL4MgMkKj/A+QfZ7iK9IDb0h5A==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0"
}
},
"node_modules/@tiptap/pm": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.21.0.tgz",
"integrity": "sha512-I3sNo7oMMsR6FFz1ecvPb9uCF0VQuS2WV67j8Io2M7DJicRWCE/GM5DaiYjTeWBbnByk6BuG0txoJATAqPVliQ==",
"license": "MIT",
"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.24.1",
"prosemirror-schema-basic": "^1.2.3",
"prosemirror-schema-list": "^1.5.0",
"prosemirror-state": "^1.4.3",
"prosemirror-tables": "^1.6.4",
"prosemirror-trailing-node": "^3.0.0",
"prosemirror-transform": "^1.10.2",
"prosemirror-view": "^1.38.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
}
},
"node_modules/@tiptap/starter-kit": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.21.0.tgz",
"integrity": "sha512-w7fWxglDtqXFBgRYH+LforJyUboSAQllnWQbGVSTyX4rsICqZjkb3f6CTSUWpGoGKmlmbb2ZpEuoik7tur9d8Q==",
"license": "MIT",
"dependencies": {
"@tiptap/core": "^3.21.0",
"@tiptap/extension-blockquote": "^3.21.0",
"@tiptap/extension-bold": "^3.21.0",
"@tiptap/extension-bullet-list": "^3.21.0",
"@tiptap/extension-code": "^3.21.0",
"@tiptap/extension-code-block": "^3.21.0",
"@tiptap/extension-document": "^3.21.0",
"@tiptap/extension-dropcursor": "^3.21.0",
"@tiptap/extension-gapcursor": "^3.21.0",
"@tiptap/extension-hard-break": "^3.21.0",
"@tiptap/extension-heading": "^3.21.0",
"@tiptap/extension-horizontal-rule": "^3.21.0",
"@tiptap/extension-italic": "^3.21.0",
"@tiptap/extension-link": "^3.21.0",
"@tiptap/extension-list": "^3.21.0",
"@tiptap/extension-list-item": "^3.21.0",
"@tiptap/extension-list-keymap": "^3.21.0",
"@tiptap/extension-ordered-list": "^3.21.0",
"@tiptap/extension-paragraph": "^3.21.0",
"@tiptap/extension-strike": "^3.21.0",
"@tiptap/extension-text": "^3.21.0",
"@tiptap/extension-underline": "^3.21.0",
"@tiptap/extensions": "^3.21.0",
"@tiptap/pm": "^3.21.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
}
},
"node_modules/@tiptap/vue-3": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/@tiptap/vue-3/-/vue-3-3.21.0.tgz",
"integrity": "sha512-dfjxBwxg9+GNvsgkCbxLnj/vmG+YZMdcD/qF7bKM710bANWfqzimRUhH5W2KZcxqlYzqpz0u/P0zi7dUMR5IZA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"optionalDependencies": {
"@tiptap/extension-bubble-menu": "^3.21.0",
"@tiptap/extension-floating-menu": "^3.21.0"
},
"peerDependencies": {
"@floating-ui/dom": "^1.0.0",
"@tiptap/core": "^3.21.0",
"@tiptap/pm": "^3.21.0",
"vue": "^3.0.0"
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -97,6 +572,43 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
"integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
}
},
"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"
},
"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",
"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"
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
@@ -289,6 +801,12 @@
"dev": true,
"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"
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -306,6 +824,12 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/crelt": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
"license": "MIT"
},
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -319,6 +843,28 @@
"dev": true,
"license": "MIT"
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/devlop": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
"license": "MIT",
"dependencies": {
"dequal": "^2.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/entities": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
@@ -370,6 +916,18 @@
"@esbuild/win32-x64": "0.21.5"
}
},
"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",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -386,6 +944,45 @@
"he": "bin/he"
}
},
"node_modules/highlight.js": {
"version": "11.11.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
"integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=12.0.0"
}
},
"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",
"dependencies": {
"uc.micro": "^2.0.0"
}
},
"node_modules/linkifyjs": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz",
"integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==",
"license": "MIT"
},
"node_modules/lowlight": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz",
"integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"devlop": "^1.0.0",
"highlight.js": "~11.11.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -395,6 +992,41 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/markdown-it": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz",
"integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==",
"license": "MIT",
"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/markdown-it/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",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"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"
},
"node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
@@ -436,6 +1068,12 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"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"
},
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -499,6 +1137,210 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/prosemirror-changeset": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.0.tgz",
"integrity": "sha512-LvqH2v7Q2SF6yxatuPP2e8vSUKS/L+xAU7dPDC4RMyHMhZoGDfBC74mYuyYF4gLqOEG758wajtyhNnsTkuhvng==",
"license": "MIT",
"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",
"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",
"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",
"dependencies": {
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.1.0",
"prosemirror-view": "^1.1.0"
}
},
"node_modules/prosemirror-gapcursor": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz",
"integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==",
"license": "MIT",
"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.5.0",
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz",
"integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==",
"license": "MIT",
"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.1",
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz",
"integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==",
"license": "MIT",
"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",
"dependencies": {
"prosemirror-state": "^1.0.0",
"w3c-keyname": "^2.2.0"
}
},
"node_modules/prosemirror-markdown": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz",
"integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==",
"license": "MIT",
"dependencies": {
"@types/markdown-it": "^14.0.0",
"markdown-it": "^14.0.0",
"prosemirror-model": "^1.25.0"
}
},
"node_modules/prosemirror-menu": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.3.0.tgz",
"integrity": "sha512-TImyPXCHPcDsSka2/lwJ6WjTASr4re/qWq1yoTTuLOqfXucwF6VcRa2LWCkM/EyTD1UO3CUwiH8qURJoWJRxwg==",
"license": "MIT",
"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.4",
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz",
"integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==",
"license": "MIT",
"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",
"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",
"dependencies": {
"prosemirror-model": "^1.0.0",
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.7.3"
}
},
"node_modules/prosemirror-state": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
"integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
"license": "MIT",
"dependencies": {
"prosemirror-model": "^1.0.0",
"prosemirror-transform": "^1.0.0",
"prosemirror-view": "^1.27.0"
}
},
"node_modules/prosemirror-tables": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz",
"integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==",
"license": "MIT",
"dependencies": {
"prosemirror-keymap": "^1.2.3",
"prosemirror-model": "^1.25.4",
"prosemirror-state": "^1.4.4",
"prosemirror-transform": "^1.10.5",
"prosemirror-view": "^1.41.4"
}
},
"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",
"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.12.0",
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz",
"integrity": "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==",
"license": "MIT",
"dependencies": {
"prosemirror-model": "^1.21.0"
}
},
"node_modules/prosemirror-view": {
"version": "1.41.7",
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.7.tgz",
"integrity": "sha512-jUwKNCEIGiqdvhlS91/2QAg21e4dfU5bH2iwmSDQeosXJgKF7smG0YSplOWK0cjSNgIqXe7VXqo7EIfUFJdt3w==",
"license": "MIT",
"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",
"engines": {
"node": ">=6"
}
},
"node_modules/rollup": {
"version": "4.60.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz",
@@ -544,6 +1386,12 @@
"fsevents": "~2.3.2"
}
},
"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"
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -567,6 +1415,12 @@
"node": ">=14.17"
}
},
"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"
},
"node_modules/vite": {
"version": "5.4.21",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
@@ -712,6 +1566,12 @@
"peerDependencies": {
"typescript": ">=5.0.0"
}
},
"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"
}
}
}

20
node_modules/@floating-ui/core/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright (c) 2021-present Floating UI contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4
node_modules/@floating-ui/core/README.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
# @floating-ui/core
This is the platform-agnostic core of Floating UI, exposing the main
`computePosition` function but no platform interface logic.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,531 @@
import { AlignedPlacement } from '@floating-ui/utils';
import { Alignment } from '@floating-ui/utils';
import { Axis } from '@floating-ui/utils';
import { ClientRectObject } from '@floating-ui/utils';
import { Coords } from '@floating-ui/utils';
import { Dimensions } from '@floating-ui/utils';
import { ElementRects } from '@floating-ui/utils';
import { Length } from '@floating-ui/utils';
import { Padding } from '@floating-ui/utils';
import { Placement } from '@floating-ui/utils';
import { Rect } from '@floating-ui/utils';
import { rectToClientRect } from '@floating-ui/utils';
import { Side } from '@floating-ui/utils';
import { SideObject } from '@floating-ui/utils';
import { Strategy } from '@floating-ui/utils';
import { VirtualElement } from '@floating-ui/utils';
export { AlignedPlacement }
export { Alignment }
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
export declare const arrow: (options: ArrowOptions | Derivable<ArrowOptions>) => Middleware;
export declare interface ArrowOptions {
/**
* The arrow element to be positioned.
* @default undefined
*/
element: any;
/**
* The padding between the arrow element and the floating element edges.
* Useful when the floating element has rounded corners.
* @default 0
*/
padding?: Padding;
}
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
export declare const autoPlacement: (options?: AutoPlacementOptions | Derivable<AutoPlacementOptions>) => Middleware;
export declare interface AutoPlacementOptions extends DetectOverflowOptions {
/**
* The axis that runs along the alignment of the floating element. Determines
* whether to check for most space along this axis.
* @default false
*/
crossAxis?: boolean;
/**
* Choose placements with a particular alignment.
* @default undefined
*/
alignment?: Alignment | null;
/**
* Whether to choose placements with the opposite alignment if the preferred
* alignment does not fit.
* @default true
*/
autoAlignment?: boolean;
/**
* Which placements are allowed to be chosen. Placements must be within the
* `alignment` option if explicitly set.
* @default allPlacements (variable)
*/
allowedPlacements?: Array<Placement>;
}
export { Axis }
export declare type Boundary = any;
export { ClientRectObject }
export declare type ComputePosition = (reference: unknown, floating: unknown, config: ComputePositionConfig) => Promise<ComputePositionReturn>;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*
* This export does not have any `platform` interface logic. You will need to
* write one for the platform you are using Floating UI with.
*/
export declare const computePosition: ComputePosition;
export declare interface ComputePositionConfig {
/**
* Object to interface with the current platform.
*/
platform: Platform;
/**
* Where to place the floating element relative to the reference element.
*/
placement?: Placement;
/**
* The strategy to use when positioning the floating element.
*/
strategy?: Strategy;
/**
* Array of middleware objects to modify the positioning or provide data for
* rendering.
*/
middleware?: Array<Middleware | null | undefined | false>;
}
export declare interface ComputePositionReturn extends Coords {
/**
* The final chosen placement of the floating element.
*/
placement: Placement;
/**
* The strategy used to position the floating element.
*/
strategy: Strategy;
/**
* Object containing data returned from all middleware, keyed by their name.
*/
middlewareData: MiddlewareData;
}
export { Coords }
/**
* Function option to derive middleware options from state.
*/
export declare type Derivable<T> = (state: MiddlewareState) => T;
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
export declare function detectOverflow(state: MiddlewareState, options?: DetectOverflowOptions | Derivable<DetectOverflowOptions>): Promise<SideObject>;
export declare interface DetectOverflowOptions {
/**
* The clipping element(s) or area in which overflow will be checked.
* @default 'clippingAncestors'
*/
boundary?: Boundary;
/**
* The root clipping area in which overflow will be checked.
* @default 'viewport'
*/
rootBoundary?: RootBoundary;
/**
* The element in which overflow is being checked relative to a boundary.
* @default 'floating'
*/
elementContext?: ElementContext;
/**
* Whether to check for overflow using the alternate element's boundary
* (`clippingAncestors` boundary only).
* @default false
*/
altBoundary?: boolean;
/**
* Virtual padding for the resolved overflow detection offsets.
* @default 0
*/
padding?: Padding;
}
export { Dimensions }
export declare type ElementContext = 'reference' | 'floating';
export { ElementRects }
export declare interface Elements {
reference: ReferenceElement;
floating: FloatingElement;
}
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
export declare const flip: (options?: FlipOptions | Derivable<FlipOptions>) => Middleware;
export declare interface FlipOptions extends DetectOverflowOptions {
/**
* The axis that runs along the side of the floating element. Determines
* whether overflow along this axis is checked to perform a flip.
* @default true
*/
mainAxis?: boolean;
/**
* The axis that runs along the alignment of the floating element. Determines
* whether overflow along this axis is checked to perform a flip.
* - `true`: Whether to check cross axis overflow for both side and alignment flipping.
* - `false`: Whether to disable all cross axis overflow checking.
* - `'alignment'`: Whether to check cross axis overflow for alignment flipping only.
* @default true
*/
crossAxis?: boolean | 'alignment';
/**
* Placements to try sequentially if the preferred `placement` does not fit.
* @default [oppositePlacement] (computed)
*/
fallbackPlacements?: Array<Placement>;
/**
* What strategy to use when no placements fit.
* @default 'bestFit'
*/
fallbackStrategy?: 'bestFit' | 'initialPlacement';
/**
* Whether to allow fallback to the perpendicular axis of the preferred
* placement, and if so, which side direction along the axis to prefer.
* @default 'none' (disallow fallback)
*/
fallbackAxisSideDirection?: 'none' | 'start' | 'end';
/**
* Whether to flip to placements with the opposite alignment if they fit
* better.
* @default true
*/
flipAlignment?: boolean;
}
export declare type FloatingElement = any;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
export declare const hide: (options?: HideOptions | Derivable<HideOptions>) => Middleware;
export declare interface HideOptions extends DetectOverflowOptions {
/**
* The strategy used to determine when to hide the floating element.
*/
strategy?: 'referenceHidden' | 'escaped';
}
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
export declare const inline: (options?: InlineOptions | Derivable<InlineOptions>) => Middleware;
export declare interface InlineOptions {
/**
* Viewport-relative `x` coordinate to choose a `ClientRect`.
* @default undefined
*/
x?: number;
/**
* Viewport-relative `y` coordinate to choose a `ClientRect`.
* @default undefined
*/
y?: number;
/**
* Represents the padding around a disjoined rect when choosing it.
* @default 2
*/
padding?: Padding;
}
export { Length }
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
export declare const limitShift: (options?: LimitShiftOptions | Derivable<LimitShiftOptions>) => {
options: any;
fn: (state: MiddlewareState) => Coords;
};
declare type LimitShiftOffset = number | {
/**
* Offset the limiting of the axis that runs along the alignment of the
* floating element.
*/
mainAxis?: number;
/**
* Offset the limiting of the axis that runs along the side of the
* floating element.
*/
crossAxis?: number;
};
export declare interface LimitShiftOptions {
/**
* Offset when limiting starts. `0` will limit when the opposite edges of the
* reference and floating elements are aligned.
* - positive = start limiting earlier
* - negative = start limiting later
*/
offset?: LimitShiftOffset | Derivable<LimitShiftOffset>;
/**
* Whether to limit the axis that runs along the alignment of the floating
* element.
*/
mainAxis?: boolean;
/**
* Whether to limit the axis that runs along the side of the floating element.
*/
crossAxis?: boolean;
}
export declare type Middleware = {
name: string;
options?: any;
fn: (state: MiddlewareState) => Promisable<MiddlewareReturn>;
};
/**
* @deprecated use `MiddlewareState` instead.
*/
export declare type MiddlewareArguments = MiddlewareState;
export declare interface MiddlewareData {
[key: string]: any;
arrow?: Partial<Coords> & {
centerOffset: number;
alignmentOffset?: number;
};
autoPlacement?: {
index?: number;
overflows: Array<{
placement: Placement;
overflows: Array<number>;
}>;
};
flip?: {
index?: number;
overflows: Array<{
placement: Placement;
overflows: Array<number>;
}>;
};
hide?: {
referenceHidden?: boolean;
escaped?: boolean;
referenceHiddenOffsets?: SideObject;
escapedOffsets?: SideObject;
};
offset?: Coords & {
placement: Placement;
};
shift?: Coords & {
enabled: {
[key in Axis]: boolean;
};
};
}
export declare interface MiddlewareReturn extends Partial<Coords> {
data?: {
[key: string]: any;
};
reset?: boolean | {
placement?: Placement;
rects?: boolean | ElementRects;
};
}
export declare interface MiddlewareState extends Coords {
initialPlacement: Placement;
placement: Placement;
strategy: Strategy;
middlewareData: MiddlewareData;
elements: Elements;
rects: ElementRects;
platform: {
detectOverflow: typeof detectOverflow;
} & Platform;
}
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
export declare const offset: (options?: OffsetOptions) => Middleware;
export declare type OffsetOptions = OffsetValue | Derivable<OffsetValue>;
declare type OffsetValue = number | {
/**
* The axis that runs along the side of the floating element. Represents
* the distance (gutter or margin) between the reference and floating
* element.
* @default 0
*/
mainAxis?: number;
/**
* The axis that runs along the alignment of the floating element.
* Represents the skidding between the reference and floating element.
* @default 0
*/
crossAxis?: number;
/**
* The same axis as `crossAxis` but applies only to aligned placements
* and inverts the `end` alignment. When set to a number, it overrides the
* `crossAxis` value.
*
* A positive number will move the floating element in the direction of
* the opposite edge to the one that is aligned, while a negative number
* the reverse.
* @default null
*/
alignmentAxis?: number | null;
};
export { Padding }
export { Placement }
/**
* Platform interface methods to work with the current platform.
* @see https://floating-ui.com/docs/platform
*/
export declare interface Platform {
getElementRects: (args: {
reference: ReferenceElement;
floating: FloatingElement;
strategy: Strategy;
}) => Promisable<ElementRects>;
getClippingRect: (args: {
element: any;
boundary: Boundary;
rootBoundary: RootBoundary;
strategy: Strategy;
}) => Promisable<Rect>;
getDimensions: (element: any) => Promisable<Dimensions>;
convertOffsetParentRelativeRectToViewportRelativeRect?: (args: {
elements?: Elements;
rect: Rect;
offsetParent: any;
strategy: Strategy;
}) => Promisable<Rect>;
getOffsetParent?: (element: any) => Promisable<any>;
isElement?: (value: any) => Promisable<boolean>;
getDocumentElement?: (element: any) => Promisable<any>;
getClientRects?: (element: any) => Promisable<Array<ClientRectObject>>;
isRTL?: (element: any) => Promisable<boolean>;
getScale?: (element: any) => Promisable<{
x: number;
y: number;
}>;
detectOverflow?: typeof detectOverflow;
}
declare type Promisable<T> = T | Promise<T>;
export { Rect }
export { rectToClientRect }
export declare type ReferenceElement = any;
export declare type RootBoundary = 'viewport' | 'document' | Rect;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
export declare const shift: (options?: ShiftOptions | Derivable<ShiftOptions>) => Middleware;
export declare interface ShiftOptions extends DetectOverflowOptions {
/**
* The axis that runs along the alignment of the floating element. Determines
* whether overflow along this axis is checked to perform shifting.
* @default true
*/
mainAxis?: boolean;
/**
* The axis that runs along the side of the floating element. Determines
* whether overflow along this axis is checked to perform shifting.
* @default false
*/
crossAxis?: boolean;
/**
* Accepts a function that limits the shifting done in order to prevent
* detachment.
*/
limiter?: {
fn: (state: MiddlewareState) => Coords;
options?: any;
};
}
export { Side }
export { SideObject }
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
export declare const size: (options?: SizeOptions | Derivable<SizeOptions>) => Middleware;
export declare interface SizeOptions extends DetectOverflowOptions {
/**
* Function that is called to perform style mutations to the floating element
* to change its size.
* @default undefined
*/
apply?(args: MiddlewareState & {
availableWidth: number;
availableHeight: number;
}): void | Promise<void>;
}
export { Strategy }
export { VirtualElement }
export { }

View File

@@ -0,0 +1,531 @@
import { AlignedPlacement } from '@floating-ui/utils';
import { Alignment } from '@floating-ui/utils';
import { Axis } from '@floating-ui/utils';
import { ClientRectObject } from '@floating-ui/utils';
import { Coords } from '@floating-ui/utils';
import { Dimensions } from '@floating-ui/utils';
import { ElementRects } from '@floating-ui/utils';
import { Length } from '@floating-ui/utils';
import { Padding } from '@floating-ui/utils';
import { Placement } from '@floating-ui/utils';
import { Rect } from '@floating-ui/utils';
import { rectToClientRect } from '@floating-ui/utils';
import { Side } from '@floating-ui/utils';
import { SideObject } from '@floating-ui/utils';
import { Strategy } from '@floating-ui/utils';
import { VirtualElement } from '@floating-ui/utils';
export { AlignedPlacement }
export { Alignment }
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
export declare const arrow: (options: ArrowOptions | Derivable<ArrowOptions>) => Middleware;
export declare interface ArrowOptions {
/**
* The arrow element to be positioned.
* @default undefined
*/
element: any;
/**
* The padding between the arrow element and the floating element edges.
* Useful when the floating element has rounded corners.
* @default 0
*/
padding?: Padding;
}
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
export declare const autoPlacement: (options?: AutoPlacementOptions | Derivable<AutoPlacementOptions>) => Middleware;
export declare interface AutoPlacementOptions extends DetectOverflowOptions {
/**
* The axis that runs along the alignment of the floating element. Determines
* whether to check for most space along this axis.
* @default false
*/
crossAxis?: boolean;
/**
* Choose placements with a particular alignment.
* @default undefined
*/
alignment?: Alignment | null;
/**
* Whether to choose placements with the opposite alignment if the preferred
* alignment does not fit.
* @default true
*/
autoAlignment?: boolean;
/**
* Which placements are allowed to be chosen. Placements must be within the
* `alignment` option if explicitly set.
* @default allPlacements (variable)
*/
allowedPlacements?: Array<Placement>;
}
export { Axis }
export declare type Boundary = any;
export { ClientRectObject }
export declare type ComputePosition = (reference: unknown, floating: unknown, config: ComputePositionConfig) => Promise<ComputePositionReturn>;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*
* This export does not have any `platform` interface logic. You will need to
* write one for the platform you are using Floating UI with.
*/
export declare const computePosition: ComputePosition;
export declare interface ComputePositionConfig {
/**
* Object to interface with the current platform.
*/
platform: Platform;
/**
* Where to place the floating element relative to the reference element.
*/
placement?: Placement;
/**
* The strategy to use when positioning the floating element.
*/
strategy?: Strategy;
/**
* Array of middleware objects to modify the positioning or provide data for
* rendering.
*/
middleware?: Array<Middleware | null | undefined | false>;
}
export declare interface ComputePositionReturn extends Coords {
/**
* The final chosen placement of the floating element.
*/
placement: Placement;
/**
* The strategy used to position the floating element.
*/
strategy: Strategy;
/**
* Object containing data returned from all middleware, keyed by their name.
*/
middlewareData: MiddlewareData;
}
export { Coords }
/**
* Function option to derive middleware options from state.
*/
export declare type Derivable<T> = (state: MiddlewareState) => T;
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
export declare function detectOverflow(state: MiddlewareState, options?: DetectOverflowOptions | Derivable<DetectOverflowOptions>): Promise<SideObject>;
export declare interface DetectOverflowOptions {
/**
* The clipping element(s) or area in which overflow will be checked.
* @default 'clippingAncestors'
*/
boundary?: Boundary;
/**
* The root clipping area in which overflow will be checked.
* @default 'viewport'
*/
rootBoundary?: RootBoundary;
/**
* The element in which overflow is being checked relative to a boundary.
* @default 'floating'
*/
elementContext?: ElementContext;
/**
* Whether to check for overflow using the alternate element's boundary
* (`clippingAncestors` boundary only).
* @default false
*/
altBoundary?: boolean;
/**
* Virtual padding for the resolved overflow detection offsets.
* @default 0
*/
padding?: Padding;
}
export { Dimensions }
export declare type ElementContext = 'reference' | 'floating';
export { ElementRects }
export declare interface Elements {
reference: ReferenceElement;
floating: FloatingElement;
}
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
export declare const flip: (options?: FlipOptions | Derivable<FlipOptions>) => Middleware;
export declare interface FlipOptions extends DetectOverflowOptions {
/**
* The axis that runs along the side of the floating element. Determines
* whether overflow along this axis is checked to perform a flip.
* @default true
*/
mainAxis?: boolean;
/**
* The axis that runs along the alignment of the floating element. Determines
* whether overflow along this axis is checked to perform a flip.
* - `true`: Whether to check cross axis overflow for both side and alignment flipping.
* - `false`: Whether to disable all cross axis overflow checking.
* - `'alignment'`: Whether to check cross axis overflow for alignment flipping only.
* @default true
*/
crossAxis?: boolean | 'alignment';
/**
* Placements to try sequentially if the preferred `placement` does not fit.
* @default [oppositePlacement] (computed)
*/
fallbackPlacements?: Array<Placement>;
/**
* What strategy to use when no placements fit.
* @default 'bestFit'
*/
fallbackStrategy?: 'bestFit' | 'initialPlacement';
/**
* Whether to allow fallback to the perpendicular axis of the preferred
* placement, and if so, which side direction along the axis to prefer.
* @default 'none' (disallow fallback)
*/
fallbackAxisSideDirection?: 'none' | 'start' | 'end';
/**
* Whether to flip to placements with the opposite alignment if they fit
* better.
* @default true
*/
flipAlignment?: boolean;
}
export declare type FloatingElement = any;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
export declare const hide: (options?: HideOptions | Derivable<HideOptions>) => Middleware;
export declare interface HideOptions extends DetectOverflowOptions {
/**
* The strategy used to determine when to hide the floating element.
*/
strategy?: 'referenceHidden' | 'escaped';
}
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
export declare const inline: (options?: InlineOptions | Derivable<InlineOptions>) => Middleware;
export declare interface InlineOptions {
/**
* Viewport-relative `x` coordinate to choose a `ClientRect`.
* @default undefined
*/
x?: number;
/**
* Viewport-relative `y` coordinate to choose a `ClientRect`.
* @default undefined
*/
y?: number;
/**
* Represents the padding around a disjoined rect when choosing it.
* @default 2
*/
padding?: Padding;
}
export { Length }
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
export declare const limitShift: (options?: LimitShiftOptions | Derivable<LimitShiftOptions>) => {
options: any;
fn: (state: MiddlewareState) => Coords;
};
declare type LimitShiftOffset = number | {
/**
* Offset the limiting of the axis that runs along the alignment of the
* floating element.
*/
mainAxis?: number;
/**
* Offset the limiting of the axis that runs along the side of the
* floating element.
*/
crossAxis?: number;
};
export declare interface LimitShiftOptions {
/**
* Offset when limiting starts. `0` will limit when the opposite edges of the
* reference and floating elements are aligned.
* - positive = start limiting earlier
* - negative = start limiting later
*/
offset?: LimitShiftOffset | Derivable<LimitShiftOffset>;
/**
* Whether to limit the axis that runs along the alignment of the floating
* element.
*/
mainAxis?: boolean;
/**
* Whether to limit the axis that runs along the side of the floating element.
*/
crossAxis?: boolean;
}
export declare type Middleware = {
name: string;
options?: any;
fn: (state: MiddlewareState) => Promisable<MiddlewareReturn>;
};
/**
* @deprecated use `MiddlewareState` instead.
*/
export declare type MiddlewareArguments = MiddlewareState;
export declare interface MiddlewareData {
[key: string]: any;
arrow?: Partial<Coords> & {
centerOffset: number;
alignmentOffset?: number;
};
autoPlacement?: {
index?: number;
overflows: Array<{
placement: Placement;
overflows: Array<number>;
}>;
};
flip?: {
index?: number;
overflows: Array<{
placement: Placement;
overflows: Array<number>;
}>;
};
hide?: {
referenceHidden?: boolean;
escaped?: boolean;
referenceHiddenOffsets?: SideObject;
escapedOffsets?: SideObject;
};
offset?: Coords & {
placement: Placement;
};
shift?: Coords & {
enabled: {
[key in Axis]: boolean;
};
};
}
export declare interface MiddlewareReturn extends Partial<Coords> {
data?: {
[key: string]: any;
};
reset?: boolean | {
placement?: Placement;
rects?: boolean | ElementRects;
};
}
export declare interface MiddlewareState extends Coords {
initialPlacement: Placement;
placement: Placement;
strategy: Strategy;
middlewareData: MiddlewareData;
elements: Elements;
rects: ElementRects;
platform: {
detectOverflow: typeof detectOverflow;
} & Platform;
}
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
export declare const offset: (options?: OffsetOptions) => Middleware;
export declare type OffsetOptions = OffsetValue | Derivable<OffsetValue>;
declare type OffsetValue = number | {
/**
* The axis that runs along the side of the floating element. Represents
* the distance (gutter or margin) between the reference and floating
* element.
* @default 0
*/
mainAxis?: number;
/**
* The axis that runs along the alignment of the floating element.
* Represents the skidding between the reference and floating element.
* @default 0
*/
crossAxis?: number;
/**
* The same axis as `crossAxis` but applies only to aligned placements
* and inverts the `end` alignment. When set to a number, it overrides the
* `crossAxis` value.
*
* A positive number will move the floating element in the direction of
* the opposite edge to the one that is aligned, while a negative number
* the reverse.
* @default null
*/
alignmentAxis?: number | null;
};
export { Padding }
export { Placement }
/**
* Platform interface methods to work with the current platform.
* @see https://floating-ui.com/docs/platform
*/
export declare interface Platform {
getElementRects: (args: {
reference: ReferenceElement;
floating: FloatingElement;
strategy: Strategy;
}) => Promisable<ElementRects>;
getClippingRect: (args: {
element: any;
boundary: Boundary;
rootBoundary: RootBoundary;
strategy: Strategy;
}) => Promisable<Rect>;
getDimensions: (element: any) => Promisable<Dimensions>;
convertOffsetParentRelativeRectToViewportRelativeRect?: (args: {
elements?: Elements;
rect: Rect;
offsetParent: any;
strategy: Strategy;
}) => Promisable<Rect>;
getOffsetParent?: (element: any) => Promisable<any>;
isElement?: (value: any) => Promisable<boolean>;
getDocumentElement?: (element: any) => Promisable<any>;
getClientRects?: (element: any) => Promisable<Array<ClientRectObject>>;
isRTL?: (element: any) => Promisable<boolean>;
getScale?: (element: any) => Promisable<{
x: number;
y: number;
}>;
detectOverflow?: typeof detectOverflow;
}
declare type Promisable<T> = T | Promise<T>;
export { Rect }
export { rectToClientRect }
export declare type ReferenceElement = any;
export declare type RootBoundary = 'viewport' | 'document' | Rect;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
export declare const shift: (options?: ShiftOptions | Derivable<ShiftOptions>) => Middleware;
export declare interface ShiftOptions extends DetectOverflowOptions {
/**
* The axis that runs along the alignment of the floating element. Determines
* whether overflow along this axis is checked to perform shifting.
* @default true
*/
mainAxis?: boolean;
/**
* The axis that runs along the side of the floating element. Determines
* whether overflow along this axis is checked to perform shifting.
* @default false
*/
crossAxis?: boolean;
/**
* Accepts a function that limits the shifting done in order to prevent
* detachment.
*/
limiter?: {
fn: (state: MiddlewareState) => Coords;
options?: any;
};
}
export { Side }
export { SideObject }
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
export declare const size: (options?: SizeOptions | Derivable<SizeOptions>) => Middleware;
export declare interface SizeOptions extends DetectOverflowOptions {
/**
* Function that is called to perform style mutations to the floating element
* to change its size.
* @default undefined
*/
apply?(args: MiddlewareState & {
availableWidth: number;
availableHeight: number;
}): void | Promise<void>;
}
export { Strategy }
export { VirtualElement }
export { }

File diff suppressed because it is too large Load Diff

1058
node_modules/@floating-ui/core/dist/floating-ui.core.mjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

63
node_modules/@floating-ui/core/package.json generated vendored Normal file
View File

@@ -0,0 +1,63 @@
{
"name": "@floating-ui/core",
"version": "1.7.5",
"description": "Positioning library for floating elements: tooltips, popovers, dropdowns, and more",
"publishConfig": {
"access": "public"
},
"main": "./dist/floating-ui.core.umd.js",
"module": "./dist/floating-ui.core.esm.js",
"unpkg": "./dist/floating-ui.core.umd.min.js",
"types": "./dist/floating-ui.core.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/floating-ui.core.d.mts",
"default": "./dist/floating-ui.core.mjs"
},
"types": "./dist/floating-ui.core.d.ts",
"module": "./dist/floating-ui.core.esm.js",
"default": "./dist/floating-ui.core.umd.js"
}
},
"sideEffects": false,
"files": [
"dist"
],
"author": "atomiks",
"license": "MIT",
"bugs": "https://github.com/floating-ui/floating-ui",
"repository": {
"type": "git",
"url": "https://github.com/floating-ui/floating-ui.git",
"directory": "packages/core"
},
"homepage": "https://floating-ui.com",
"keywords": [
"tooltip",
"popover",
"dropdown",
"menu",
"popup",
"positioning"
],
"dependencies": {
"@floating-ui/utils": "^0.2.11"
},
"devDependencies": {
"config": "0.0.0"
},
"scripts": {
"test": "vitest run",
"test:watch": "vitest watch",
"lint": "eslint .",
"format": "prettier --write .",
"clean": "rimraf dist out-tsc",
"dev": "rollup -c -w",
"build": "rollup -c",
"build:api": "build-api --tsc tsconfig.lib.json",
"publint": "publint",
"typecheck": "tsc -b"
}
}

20
node_modules/@floating-ui/dom/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright (c) 2021-present Floating UI contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4
node_modules/@floating-ui/dom/README.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
# @floating-ui/dom
This is the library to use Floating UI on the web, wrapping `@floating-ui/core`
with DOM interface logic.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,956 @@
import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle$1(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle$1(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
function getCssDimensions(element) {
const css = getComputedStyle$1(element);
// In testing environments, the `width` and `height` properties are empty
// strings for SVG elements, returning NaN. Fallback to `0` in this case.
let width = parseFloat(css.width) || 0;
let height = parseFloat(css.height) || 0;
const hasOffset = isHTMLElement(element);
const offsetWidth = hasOffset ? element.offsetWidth : width;
const offsetHeight = hasOffset ? element.offsetHeight : height;
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
if (shouldFallback) {
width = offsetWidth;
height = offsetHeight;
}
return {
width,
height,
$: shouldFallback
};
}
function unwrapElement(element) {
return !isElement(element) ? element.contextElement : element;
}
function getScale(element) {
const domElement = unwrapElement(element);
if (!isHTMLElement(domElement)) {
return createCoords(1);
}
const rect = domElement.getBoundingClientRect();
const {
width,
height,
$
} = getCssDimensions(domElement);
let x = ($ ? round(rect.width) : rect.width) / width;
let y = ($ ? round(rect.height) : rect.height) / height;
// 0, NaN, or Infinity should always fallback to 1.
if (!x || !Number.isFinite(x)) {
x = 1;
}
if (!y || !Number.isFinite(y)) {
y = 1;
}
return {
x,
y
};
}
const noOffsets = /*#__PURE__*/createCoords(0);
function getVisualOffsets(element) {
const win = getWindow(element);
if (!isWebKit() || !win.visualViewport) {
return noOffsets;
}
return {
x: win.visualViewport.offsetLeft,
y: win.visualViewport.offsetTop
};
}
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
if (isFixed === void 0) {
isFixed = false;
}
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
return false;
}
return isFixed;
}
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
const clientRect = element.getBoundingClientRect();
const domElement = unwrapElement(element);
let scale = createCoords(1);
if (includeScale) {
if (offsetParent) {
if (isElement(offsetParent)) {
scale = getScale(offsetParent);
}
} else {
scale = getScale(element);
}
}
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
let x = (clientRect.left + visualOffsets.x) / scale.x;
let y = (clientRect.top + visualOffsets.y) / scale.y;
let width = clientRect.width / scale.x;
let height = clientRect.height / scale.y;
if (domElement) {
const win = getWindow(domElement);
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
let currentWin = win;
let currentIFrame = getFrameElement(currentWin);
while (currentIFrame && offsetParent && offsetWin !== currentWin) {
const iframeScale = getScale(currentIFrame);
const iframeRect = currentIFrame.getBoundingClientRect();
const css = getComputedStyle$1(currentIFrame);
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
x *= iframeScale.x;
y *= iframeScale.y;
width *= iframeScale.x;
height *= iframeScale.y;
x += left;
y += top;
currentWin = getWindow(currentIFrame);
currentIFrame = getFrameElement(currentWin);
}
}
return rectToClientRect({
width,
height,
x,
y
});
}
// If <html> has a CSS width greater than the viewport, then this will be
// incorrect for RTL.
function getWindowScrollBarX(element, rect) {
const leftScroll = getNodeScroll(element).scrollLeft;
if (!rect) {
return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
}
return rect.left + leftScroll;
}
function getHTMLOffset(documentElement, scroll) {
const htmlRect = documentElement.getBoundingClientRect();
const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
const y = htmlRect.top + scroll.scrollTop;
return {
x,
y
};
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
let {
elements,
rect,
offsetParent,
strategy
} = _ref;
const isFixed = strategy === 'fixed';
const documentElement = getDocumentElement(offsetParent);
const topLayer = elements ? isTopLayer(elements.floating) : false;
if (offsetParent === documentElement || topLayer && isFixed) {
return rect;
}
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
let scale = createCoords(1);
const offsets = createCoords(0);
const isOffsetParentAnElement = isHTMLElement(offsetParent);
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent);
scale = getScale(offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
}
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
};
}
function getClientRects(element) {
return Array.from(element.getClientRects());
}
// Gets the entire size of the scrollable document area, even extending outside
// of the `<html>` and `<body>` rect bounds if horizontally scrollable.
function getDocumentRect(element) {
const html = getDocumentElement(element);
const scroll = getNodeScroll(element);
const body = element.ownerDocument.body;
const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
const y = -scroll.scrollTop;
if (getComputedStyle$1(body).direction === 'rtl') {
x += max(html.clientWidth, body.clientWidth) - width;
}
return {
width,
height,
x,
y
};
}
// Safety check: ensure the scrollbar space is reasonable in case this
// calculation is affected by unusual styles.
// Most scrollbars leave 15-18px of space.
const SCROLLBAR_MAX = 25;
function getViewportRect(element, strategy) {
const win = getWindow(element);
const html = getDocumentElement(element);
const visualViewport = win.visualViewport;
let width = html.clientWidth;
let height = html.clientHeight;
let x = 0;
let y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
const visualViewportBased = isWebKit();
if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
const windowScrollbarX = getWindowScrollBarX(html);
// <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
// visual width of the <html> but this is not considered in the size
// of `html.clientWidth`.
if (windowScrollbarX <= 0) {
const doc = html.ownerDocument;
const body = doc.body;
const bodyStyles = getComputedStyle(body);
const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
width -= clippingStableScrollbarWidth;
}
} else if (windowScrollbarX <= SCROLLBAR_MAX) {
// If the <body> scrollbar is on the left, the width needs to be extended
// by the scrollbar amount so there isn't extra space on the right.
width += windowScrollbarX;
}
return {
width,
height,
x,
y
};
}
// Returns the inner client rect, subtracting scrollbars if present.
function getInnerBoundingClientRect(element, strategy) {
const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
const top = clientRect.top + element.clientTop;
const left = clientRect.left + element.clientLeft;
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
const width = element.clientWidth * scale.x;
const height = element.clientHeight * scale.y;
const x = left * scale.x;
const y = top * scale.y;
return {
width,
height,
x,
y
};
}
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
let rect;
if (clippingAncestor === 'viewport') {
rect = getViewportRect(element, strategy);
} else if (clippingAncestor === 'document') {
rect = getDocumentRect(getDocumentElement(element));
} else if (isElement(clippingAncestor)) {
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
} else {
const visualOffsets = getVisualOffsets(element);
rect = {
x: clippingAncestor.x - visualOffsets.x,
y: clippingAncestor.y - visualOffsets.y,
width: clippingAncestor.width,
height: clippingAncestor.height
};
}
return rectToClientRect(rect);
}
function hasFixedPositionAncestor(element, stopNode) {
const parentNode = getParentNode(element);
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
return false;
}
return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
}
// A "clipping ancestor" is an `overflow` element with the characteristic of
// clipping (or hiding) child elements. This returns all clipping ancestors
// of the given element up the tree.
function getClippingElementAncestors(element, cache) {
const cachedResult = cache.get(element);
if (cachedResult) {
return cachedResult;
}
let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
let currentContainingBlockComputedStyle = null;
const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
let currentNode = elementIsFixed ? getParentNode(element) : element;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
const computedStyle = getComputedStyle$1(currentNode);
const currentNodeIsContaining = isContainingBlock(currentNode);
if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
currentContainingBlockComputedStyle = null;
}
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
if (shouldDropCurrentNode) {
// Drop non-containing blocks.
result = result.filter(ancestor => ancestor !== currentNode);
} else {
// Record last containing block for next iteration.
currentContainingBlockComputedStyle = computedStyle;
}
currentNode = getParentNode(currentNode);
}
cache.set(element, result);
return result;
}
// Gets the maximum area that the element is visible in due to any number of
// clipping ancestors.
function getClippingRect(_ref) {
let {
element,
boundary,
rootBoundary,
strategy
} = _ref;
const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
let top = firstRect.top;
let right = firstRect.right;
let bottom = firstRect.bottom;
let left = firstRect.left;
for (let i = 1; i < clippingAncestors.length; i++) {
const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
top = max(rect.top, top);
right = min(rect.right, right);
bottom = min(rect.bottom, bottom);
left = max(rect.left, left);
}
return {
width: right - left,
height: bottom - top,
x: left,
y: top
};
}
function getDimensions(element) {
const {
width,
height
} = getCssDimensions(element);
return {
width,
height
};
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
const isFixed = strategy === 'fixed';
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
const offsets = createCoords(0);
// If the <body> scrollbar appears on the left (e.g. RTL systems). Use
// Firefox with layout.scrollbar.side = 3 in about:config to test this.
function setLeftRTLScrollbarOffset() {
offsets.x = getWindowScrollBarX(documentElement);
}
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
} else if (documentElement) {
setLeftRTLScrollbarOffset();
}
}
if (isFixed && !isOffsetParentAnElement && documentElement) {
setLeftRTLScrollbarOffset();
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
return {
x,
y,
width: rect.width,
height: rect.height
};
}
function isStaticPositioned(element) {
return getComputedStyle$1(element).position === 'static';
}
function getTrueOffsetParent(element, polyfill) {
if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
return null;
}
if (polyfill) {
return polyfill(element);
}
let rawOffsetParent = element.offsetParent;
// Firefox returns the <html> element as the offsetParent if it's non-static,
// while Chrome and Safari return the <body> element. The <body> element must
// be used to perform the correct calculations even if the <html> element is
// non-static.
if (getDocumentElement(element) === rawOffsetParent) {
rawOffsetParent = rawOffsetParent.ownerDocument.body;
}
return rawOffsetParent;
}
// Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.
function getOffsetParent(element, polyfill) {
const win = getWindow(element);
if (isTopLayer(element)) {
return win;
}
if (!isHTMLElement(element)) {
let svgOffsetParent = getParentNode(element);
while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
return svgOffsetParent;
}
svgOffsetParent = getParentNode(svgOffsetParent);
}
return win;
}
let offsetParent = getTrueOffsetParent(element, polyfill);
while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
}
if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
return win;
}
return offsetParent || getContainingBlock(element) || win;
}
const getElementRects = async function (data) {
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
const getDimensionsFn = this.getDimensions;
const floatingDimensions = await getDimensionsFn(data.floating);
return {
reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
floating: {
x: 0,
y: 0,
width: floatingDimensions.width,
height: floatingDimensions.height
}
};
};
function isRTL(element) {
return getComputedStyle$1(element).direction === 'rtl';
}
const platform = {
convertOffsetParentRelativeRectToViewportRelativeRect,
getDocumentElement,
getClippingRect,
getOffsetParent,
getElementRects,
getClientRects,
getDimensions,
getScale,
isElement,
isRTL
};
function rectsAreEqual(a, b) {
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
}
// https://samthor.au/2021/observing-dom/
function observeMove(element, onMove) {
let io = null;
let timeoutId;
const root = getDocumentElement(element);
function cleanup() {
var _io;
clearTimeout(timeoutId);
(_io = io) == null || _io.disconnect();
io = null;
}
function refresh(skip, threshold) {
if (skip === void 0) {
skip = false;
}
if (threshold === void 0) {
threshold = 1;
}
cleanup();
const elementRectForRootMargin = element.getBoundingClientRect();
const {
left,
top,
width,
height
} = elementRectForRootMargin;
if (!skip) {
onMove();
}
if (!width || !height) {
return;
}
const insetTop = floor(top);
const insetRight = floor(root.clientWidth - (left + width));
const insetBottom = floor(root.clientHeight - (top + height));
const insetLeft = floor(left);
const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
const options = {
rootMargin,
threshold: max(0, min(1, threshold)) || 1
};
let isFirstUpdate = true;
function handleObserve(entries) {
const ratio = entries[0].intersectionRatio;
if (ratio !== threshold) {
if (!isFirstUpdate) {
return refresh();
}
if (!ratio) {
// If the reference is clipped, the ratio is 0. Throttle the refresh
// to prevent an infinite loop of updates.
timeoutId = setTimeout(() => {
refresh(false, 1e-7);
}, 1000);
} else {
refresh(false, ratio);
}
}
if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
// It's possible that even though the ratio is reported as 1, the
// element is not actually fully within the IntersectionObserver's root
// area anymore. This can happen under performance constraints. This may
// be a bug in the browser's IntersectionObserver implementation. To
// work around this, we compare the element's bounding rect now with
// what it was at the time we created the IntersectionObserver. If they
// are not equal then the element moved, so we refresh.
refresh();
}
isFirstUpdate = false;
}
// Older browsers don't support a `document` as the root and will throw an
// error.
try {
io = new IntersectionObserver(handleObserve, {
...options,
// Handle <iframe>s
root: root.ownerDocument
});
} catch (_e) {
io = new IntersectionObserver(handleObserve, options);
}
io.observe(element);
}
refresh(true);
return cleanup;
}
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
function autoUpdate(reference, floating, update, options) {
if (options === void 0) {
options = {};
}
const {
ancestorScroll = true,
ancestorResize = true,
elementResize = typeof ResizeObserver === 'function',
layoutShift = typeof IntersectionObserver === 'function',
animationFrame = false
} = options;
const referenceEl = unwrapElement(reference);
const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.addEventListener('scroll', update, {
passive: true
});
ancestorResize && ancestor.addEventListener('resize', update);
});
const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
let reobserveFrame = -1;
let resizeObserver = null;
if (elementResize) {
resizeObserver = new ResizeObserver(_ref => {
let [firstEntry] = _ref;
if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
// Prevent update loops when using the `size` middleware.
// https://github.com/floating-ui/floating-ui/issues/1740
resizeObserver.unobserve(floating);
cancelAnimationFrame(reobserveFrame);
reobserveFrame = requestAnimationFrame(() => {
var _resizeObserver;
(_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
});
}
update();
});
if (referenceEl && !animationFrame) {
resizeObserver.observe(referenceEl);
}
if (floating) {
resizeObserver.observe(floating);
}
}
let frameId;
let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
if (animationFrame) {
frameLoop();
}
function frameLoop() {
const nextRefRect = getBoundingClientRect(reference);
if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
update();
}
prevRefRect = nextRefRect;
frameId = requestAnimationFrame(frameLoop);
}
update();
return () => {
var _resizeObserver2;
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.removeEventListener('scroll', update);
ancestorResize && ancestor.removeEventListener('resize', update);
});
cleanupIo == null || cleanupIo();
(_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
resizeObserver = null;
if (animationFrame) {
cancelAnimationFrame(frameId);
}
};
}
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
const detectOverflow = detectOverflow$1;
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
const offset = offset$1;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
const autoPlacement = autoPlacement$1;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
const shift = shift$1;
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
const flip = flip$1;
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
const size = size$1;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
const hide = hide$1;
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
const arrow = arrow$1;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
const inline = inline$1;
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
const limitShift = limitShift$1;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
const computePosition = (reference, floating, options) => {
// This caches the expensive `getClippingElementAncestors` function so that
// multiple lifecycle resets re-use the same result. It only lives for a
// single call. If other functions become expensive, we can add them as well.
const cache = new Map();
const mergedOptions = {
platform,
...options
};
const platformWithCache = {
...mergedOptions.platform,
_c: cache
};
return computePosition$1(reference, floating, {
...mergedOptions,
platform: platformWithCache
});
};
export { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, getOverflowAncestors, hide, inline, limitShift, offset, platform, shift, size };

View File

@@ -0,0 +1,358 @@
import { AlignedPlacement } from '@floating-ui/core';
import { Alignment } from '@floating-ui/core';
import type { ArrowOptions as ArrowOptions_2 } from '@floating-ui/core';
import type { AutoPlacementOptions as AutoPlacementOptions_2 } from '@floating-ui/core';
import { Axis } from '@floating-ui/core';
import { ClientRectObject } from '@floating-ui/core';
import type { ComputePositionConfig as ComputePositionConfig_2 } from '@floating-ui/core';
import { ComputePositionReturn } from '@floating-ui/core';
import { Coords } from '@floating-ui/core';
import type { detectOverflow as detectOverflow_2 } from '@floating-ui/core';
import type { DetectOverflowOptions as DetectOverflowOptions_2 } from '@floating-ui/core';
import { Dimensions } from '@floating-ui/core';
import { ElementContext } from '@floating-ui/core';
import { ElementRects } from '@floating-ui/core';
import type { FlipOptions as FlipOptions_2 } from '@floating-ui/core';
import { getOverflowAncestors } from '@floating-ui/utils/dom';
import type { HideOptions as HideOptions_2 } from '@floating-ui/core';
import { InlineOptions } from '@floating-ui/core';
import { Length } from '@floating-ui/core';
import { LimitShiftOptions } from '@floating-ui/core';
import type { Middleware as Middleware_2 } from '@floating-ui/core';
import { MiddlewareData } from '@floating-ui/core';
import { MiddlewareReturn } from '@floating-ui/core';
import type { MiddlewareState as MiddlewareState_2 } from '@floating-ui/core';
import { Padding } from '@floating-ui/core';
import { Placement } from '@floating-ui/core';
import { Rect } from '@floating-ui/core';
import { RootBoundary } from '@floating-ui/core';
import type { ShiftOptions as ShiftOptions_2 } from '@floating-ui/core';
import { Side } from '@floating-ui/core';
import { SideObject } from '@floating-ui/core';
import type { SizeOptions as SizeOptions_2 } from '@floating-ui/core';
import { Strategy } from '@floating-ui/core';
export { AlignedPlacement }
export { Alignment }
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
export declare const arrow: (options: ArrowOptions | Derivable<ArrowOptions>) => Middleware;
export declare type ArrowOptions = Prettify<Omit<ArrowOptions_2, 'element'> & {
element: Element;
}>;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
export declare const autoPlacement: (options?: AutoPlacementOptions | Derivable<AutoPlacementOptions>) => Middleware;
export declare type AutoPlacementOptions = Prettify<Omit<AutoPlacementOptions_2, 'boundary'> & DetectOverflowOptions>;
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
export declare function autoUpdate(reference: ReferenceElement, floating: FloatingElement | null, update: () => void, options?: AutoUpdateOptions): () => void;
export declare interface AutoUpdateOptions {
/**
* Whether to update the position when an overflow ancestor is scrolled.
* @default true
*/
ancestorScroll?: boolean;
/**
* Whether to update the position when an overflow ancestor is resized. This
* uses the native `resize` event.
* @default true
*/
ancestorResize?: boolean;
/**
* Whether to update the position when either the reference or floating
* elements resized. This uses a `ResizeObserver`.
* @default true
*/
elementResize?: boolean;
/**
* Whether to update the position when the reference relocated on the screen
* due to layout shift.
* @default true
*/
layoutShift?: boolean;
/**
* Whether to update on every animation frame if necessary. Only use if you
* need to update the position in response to an animation using transforms.
* @default false
*/
animationFrame?: boolean;
}
export { Axis }
/**
* The clipping boundary area of the floating element.
*/
export declare type Boundary = 'clippingAncestors' | Element | Array<Element> | Rect;
export { ClientRectObject }
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
export declare const computePosition: (reference: ReferenceElement, floating: FloatingElement, options?: Partial<ComputePositionConfig>) => Promise<ComputePositionReturn>;
export declare type ComputePositionConfig = Prettify<Omit<ComputePositionConfig_2, 'middleware' | 'platform'> & {
/**
* Array of middleware objects to modify the positioning or provide data for
* rendering.
*/
middleware?: Array<Middleware | null | undefined | false>;
/**
* Custom or extended platform object.
*/
platform?: Platform;
}>;
export { ComputePositionReturn }
export { Coords }
export declare type Derivable<T> = (state: MiddlewareState) => T;
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
export declare const detectOverflow: (state: MiddlewareState, options?: DetectOverflowOptions | Derivable<DetectOverflowOptions>) => Promise<SideObject>;
export declare type DetectOverflowOptions = Prettify<Omit<DetectOverflowOptions_2, 'boundary'> & {
boundary?: Boundary;
}>;
export { Dimensions }
export { ElementContext }
export { ElementRects }
export declare interface Elements {
reference: ReferenceElement;
floating: FloatingElement;
}
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
export declare const flip: (options?: FlipOptions | Derivable<FlipOptions>) => Middleware;
export declare type FlipOptions = Prettify<Omit<FlipOptions_2, 'boundary'> & DetectOverflowOptions>;
export declare type FloatingElement = HTMLElement;
export { getOverflowAncestors }
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
export declare const hide: (options?: HideOptions | Derivable<HideOptions>) => Middleware;
export declare type HideOptions = Prettify<Omit<HideOptions_2, 'boundary'> & DetectOverflowOptions>;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
export declare const inline: (options?: InlineOptions | Derivable<InlineOptions>) => Middleware;
export { InlineOptions }
export { Length }
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
export declare const limitShift: (options?: LimitShiftOptions | Derivable<LimitShiftOptions>) => {
options: any;
fn: (state: MiddlewareState) => Coords;
};
export { LimitShiftOptions }
export declare type Middleware = Prettify<Omit<Middleware_2, 'fn'> & {
fn(state: MiddlewareState): Promisable<MiddlewareReturn>;
}>;
/**
* @deprecated use `MiddlewareState` instead.
*/
export declare type MiddlewareArguments = MiddlewareState;
export { MiddlewareData }
export { MiddlewareReturn }
export declare type MiddlewareState = Prettify<Omit<MiddlewareState_2, 'elements'> & {
elements: Elements;
}>;
export declare interface NodeScroll {
scrollLeft: number;
scrollTop: number;
}
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
export declare const offset: (options?: OffsetOptions) => Middleware;
export declare type OffsetOptions = OffsetValue | Derivable<OffsetValue>;
declare type OffsetValue = number | {
/**
* The axis that runs along the side of the floating element. Represents
* the distance (gutter or margin) between the reference and floating
* element.
* @default 0
*/
mainAxis?: number;
/**
* The axis that runs along the alignment of the floating element.
* Represents the skidding between the reference and floating element.
* @default 0
*/
crossAxis?: number;
/**
* The same axis as `crossAxis` but applies only to aligned placements
* and inverts the `end` alignment. When set to a number, it overrides the
* `crossAxis` value.
*
* A positive number will move the floating element in the direction of
* the opposite edge to the one that is aligned, while a negative number
* the reverse.
* @default null
*/
alignmentAxis?: number | null;
};
export { Padding }
export { Placement }
export declare interface Platform {
getElementRects: (args: {
reference: ReferenceElement;
floating: FloatingElement;
strategy: Strategy;
}) => Promisable<ElementRects>;
getClippingRect: (args: {
element: Element;
boundary: Boundary;
rootBoundary: RootBoundary;
strategy: Strategy;
}) => Promisable<Rect>;
getDimensions: (element: Element) => Promisable<Dimensions>;
convertOffsetParentRelativeRectToViewportRelativeRect: (args: {
elements?: Elements;
rect: Rect;
offsetParent: Element;
strategy: Strategy;
}) => Promisable<Rect>;
getOffsetParent: (element: Element, polyfill?: (element: HTMLElement) => Element | null) => Promisable<Element | Window>;
isElement: (value: unknown) => Promisable<boolean>;
getDocumentElement: (element: Element) => Promisable<HTMLElement>;
getClientRects: (element: Element) => Promisable<Array<ClientRectObject>>;
isRTL: (element: Element) => Promisable<boolean>;
getScale: (element: HTMLElement) => Promisable<{
x: number;
y: number;
}>;
detectOverflow?: typeof detectOverflow_2;
}
export declare const platform: Platform;
declare type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
declare type Promisable<T> = T | Promise<T>;
export { Rect }
export declare type ReferenceElement = Element | VirtualElement;
export { RootBoundary }
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
export declare const shift: (options?: ShiftOptions | Derivable<ShiftOptions>) => Middleware;
export declare type ShiftOptions = Prettify<Omit<ShiftOptions_2, 'boundary'> & DetectOverflowOptions>;
export { Side }
export { SideObject }
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
export declare const size: (options?: SizeOptions | Derivable<SizeOptions>) => Middleware;
export declare type SizeOptions = Prettify<Omit<SizeOptions_2, 'apply' | 'boundary'> & DetectOverflowOptions & {
/**
* Function that is called to perform style mutations to the floating element
* to change its size.
* @default undefined
*/
apply?(args: MiddlewareState & {
availableWidth: number;
availableHeight: number;
}): Promisable<void>;
}>;
export { Strategy }
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
export declare interface VirtualElement {
getBoundingClientRect(): ClientRectObject;
getClientRects?(): Array<ClientRectObject> | DOMRectList;
contextElement?: Element;
}
export { }

358
node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts generated vendored Normal file
View File

@@ -0,0 +1,358 @@
import { AlignedPlacement } from '@floating-ui/core';
import { Alignment } from '@floating-ui/core';
import type { ArrowOptions as ArrowOptions_2 } from '@floating-ui/core';
import type { AutoPlacementOptions as AutoPlacementOptions_2 } from '@floating-ui/core';
import { Axis } from '@floating-ui/core';
import { ClientRectObject } from '@floating-ui/core';
import type { ComputePositionConfig as ComputePositionConfig_2 } from '@floating-ui/core';
import { ComputePositionReturn } from '@floating-ui/core';
import { Coords } from '@floating-ui/core';
import type { detectOverflow as detectOverflow_2 } from '@floating-ui/core';
import type { DetectOverflowOptions as DetectOverflowOptions_2 } from '@floating-ui/core';
import { Dimensions } from '@floating-ui/core';
import { ElementContext } from '@floating-ui/core';
import { ElementRects } from '@floating-ui/core';
import type { FlipOptions as FlipOptions_2 } from '@floating-ui/core';
import { getOverflowAncestors } from '@floating-ui/utils/dom';
import type { HideOptions as HideOptions_2 } from '@floating-ui/core';
import { InlineOptions } from '@floating-ui/core';
import { Length } from '@floating-ui/core';
import { LimitShiftOptions } from '@floating-ui/core';
import type { Middleware as Middleware_2 } from '@floating-ui/core';
import { MiddlewareData } from '@floating-ui/core';
import { MiddlewareReturn } from '@floating-ui/core';
import type { MiddlewareState as MiddlewareState_2 } from '@floating-ui/core';
import { Padding } from '@floating-ui/core';
import { Placement } from '@floating-ui/core';
import { Rect } from '@floating-ui/core';
import { RootBoundary } from '@floating-ui/core';
import type { ShiftOptions as ShiftOptions_2 } from '@floating-ui/core';
import { Side } from '@floating-ui/core';
import { SideObject } from '@floating-ui/core';
import type { SizeOptions as SizeOptions_2 } from '@floating-ui/core';
import { Strategy } from '@floating-ui/core';
export { AlignedPlacement }
export { Alignment }
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
export declare const arrow: (options: ArrowOptions | Derivable<ArrowOptions>) => Middleware;
export declare type ArrowOptions = Prettify<Omit<ArrowOptions_2, 'element'> & {
element: Element;
}>;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
export declare const autoPlacement: (options?: AutoPlacementOptions | Derivable<AutoPlacementOptions>) => Middleware;
export declare type AutoPlacementOptions = Prettify<Omit<AutoPlacementOptions_2, 'boundary'> & DetectOverflowOptions>;
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
export declare function autoUpdate(reference: ReferenceElement, floating: FloatingElement | null, update: () => void, options?: AutoUpdateOptions): () => void;
export declare interface AutoUpdateOptions {
/**
* Whether to update the position when an overflow ancestor is scrolled.
* @default true
*/
ancestorScroll?: boolean;
/**
* Whether to update the position when an overflow ancestor is resized. This
* uses the native `resize` event.
* @default true
*/
ancestorResize?: boolean;
/**
* Whether to update the position when either the reference or floating
* elements resized. This uses a `ResizeObserver`.
* @default true
*/
elementResize?: boolean;
/**
* Whether to update the position when the reference relocated on the screen
* due to layout shift.
* @default true
*/
layoutShift?: boolean;
/**
* Whether to update on every animation frame if necessary. Only use if you
* need to update the position in response to an animation using transforms.
* @default false
*/
animationFrame?: boolean;
}
export { Axis }
/**
* The clipping boundary area of the floating element.
*/
export declare type Boundary = 'clippingAncestors' | Element | Array<Element> | Rect;
export { ClientRectObject }
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
export declare const computePosition: (reference: ReferenceElement, floating: FloatingElement, options?: Partial<ComputePositionConfig>) => Promise<ComputePositionReturn>;
export declare type ComputePositionConfig = Prettify<Omit<ComputePositionConfig_2, 'middleware' | 'platform'> & {
/**
* Array of middleware objects to modify the positioning or provide data for
* rendering.
*/
middleware?: Array<Middleware | null | undefined | false>;
/**
* Custom or extended platform object.
*/
platform?: Platform;
}>;
export { ComputePositionReturn }
export { Coords }
export declare type Derivable<T> = (state: MiddlewareState) => T;
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
export declare const detectOverflow: (state: MiddlewareState, options?: DetectOverflowOptions | Derivable<DetectOverflowOptions>) => Promise<SideObject>;
export declare type DetectOverflowOptions = Prettify<Omit<DetectOverflowOptions_2, 'boundary'> & {
boundary?: Boundary;
}>;
export { Dimensions }
export { ElementContext }
export { ElementRects }
export declare interface Elements {
reference: ReferenceElement;
floating: FloatingElement;
}
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
export declare const flip: (options?: FlipOptions | Derivable<FlipOptions>) => Middleware;
export declare type FlipOptions = Prettify<Omit<FlipOptions_2, 'boundary'> & DetectOverflowOptions>;
export declare type FloatingElement = HTMLElement;
export { getOverflowAncestors }
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
export declare const hide: (options?: HideOptions | Derivable<HideOptions>) => Middleware;
export declare type HideOptions = Prettify<Omit<HideOptions_2, 'boundary'> & DetectOverflowOptions>;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
export declare const inline: (options?: InlineOptions | Derivable<InlineOptions>) => Middleware;
export { InlineOptions }
export { Length }
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
export declare const limitShift: (options?: LimitShiftOptions | Derivable<LimitShiftOptions>) => {
options: any;
fn: (state: MiddlewareState) => Coords;
};
export { LimitShiftOptions }
export declare type Middleware = Prettify<Omit<Middleware_2, 'fn'> & {
fn(state: MiddlewareState): Promisable<MiddlewareReturn>;
}>;
/**
* @deprecated use `MiddlewareState` instead.
*/
export declare type MiddlewareArguments = MiddlewareState;
export { MiddlewareData }
export { MiddlewareReturn }
export declare type MiddlewareState = Prettify<Omit<MiddlewareState_2, 'elements'> & {
elements: Elements;
}>;
export declare interface NodeScroll {
scrollLeft: number;
scrollTop: number;
}
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
export declare const offset: (options?: OffsetOptions) => Middleware;
export declare type OffsetOptions = OffsetValue | Derivable<OffsetValue>;
declare type OffsetValue = number | {
/**
* The axis that runs along the side of the floating element. Represents
* the distance (gutter or margin) between the reference and floating
* element.
* @default 0
*/
mainAxis?: number;
/**
* The axis that runs along the alignment of the floating element.
* Represents the skidding between the reference and floating element.
* @default 0
*/
crossAxis?: number;
/**
* The same axis as `crossAxis` but applies only to aligned placements
* and inverts the `end` alignment. When set to a number, it overrides the
* `crossAxis` value.
*
* A positive number will move the floating element in the direction of
* the opposite edge to the one that is aligned, while a negative number
* the reverse.
* @default null
*/
alignmentAxis?: number | null;
};
export { Padding }
export { Placement }
export declare interface Platform {
getElementRects: (args: {
reference: ReferenceElement;
floating: FloatingElement;
strategy: Strategy;
}) => Promisable<ElementRects>;
getClippingRect: (args: {
element: Element;
boundary: Boundary;
rootBoundary: RootBoundary;
strategy: Strategy;
}) => Promisable<Rect>;
getDimensions: (element: Element) => Promisable<Dimensions>;
convertOffsetParentRelativeRectToViewportRelativeRect: (args: {
elements?: Elements;
rect: Rect;
offsetParent: Element;
strategy: Strategy;
}) => Promisable<Rect>;
getOffsetParent: (element: Element, polyfill?: (element: HTMLElement) => Element | null) => Promisable<Element | Window>;
isElement: (value: unknown) => Promisable<boolean>;
getDocumentElement: (element: Element) => Promisable<HTMLElement>;
getClientRects: (element: Element) => Promisable<Array<ClientRectObject>>;
isRTL: (element: Element) => Promisable<boolean>;
getScale: (element: HTMLElement) => Promisable<{
x: number;
y: number;
}>;
detectOverflow?: typeof detectOverflow_2;
}
export declare const platform: Platform;
declare type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
declare type Promisable<T> = T | Promise<T>;
export { Rect }
export declare type ReferenceElement = Element | VirtualElement;
export { RootBoundary }
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
export declare const shift: (options?: ShiftOptions | Derivable<ShiftOptions>) => Middleware;
export declare type ShiftOptions = Prettify<Omit<ShiftOptions_2, 'boundary'> & DetectOverflowOptions>;
export { Side }
export { SideObject }
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
export declare const size: (options?: SizeOptions | Derivable<SizeOptions>) => Middleware;
export declare type SizeOptions = Prettify<Omit<SizeOptions_2, 'apply' | 'boundary'> & DetectOverflowOptions & {
/**
* Function that is called to perform style mutations to the floating element
* to change its size.
* @default undefined
*/
apply?(args: MiddlewareState & {
availableWidth: number;
availableHeight: number;
}): Promisable<void>;
}>;
export { Strategy }
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
export declare interface VirtualElement {
getBoundingClientRect(): ClientRectObject;
getClientRects?(): Array<ClientRectObject> | DOMRectList;
contextElement?: Element;
}
export { }

View File

@@ -0,0 +1,781 @@
import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';
import { round, createCoords, max, min, floor } from '@floating-ui/utils';
import { getComputedStyle as getComputedStyle$1, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom';
export { getOverflowAncestors } from '@floating-ui/utils/dom';
function getCssDimensions(element) {
const css = getComputedStyle$1(element);
// In testing environments, the `width` and `height` properties are empty
// strings for SVG elements, returning NaN. Fallback to `0` in this case.
let width = parseFloat(css.width) || 0;
let height = parseFloat(css.height) || 0;
const hasOffset = isHTMLElement(element);
const offsetWidth = hasOffset ? element.offsetWidth : width;
const offsetHeight = hasOffset ? element.offsetHeight : height;
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
if (shouldFallback) {
width = offsetWidth;
height = offsetHeight;
}
return {
width,
height,
$: shouldFallback
};
}
function unwrapElement(element) {
return !isElement(element) ? element.contextElement : element;
}
function getScale(element) {
const domElement = unwrapElement(element);
if (!isHTMLElement(domElement)) {
return createCoords(1);
}
const rect = domElement.getBoundingClientRect();
const {
width,
height,
$
} = getCssDimensions(domElement);
let x = ($ ? round(rect.width) : rect.width) / width;
let y = ($ ? round(rect.height) : rect.height) / height;
// 0, NaN, or Infinity should always fallback to 1.
if (!x || !Number.isFinite(x)) {
x = 1;
}
if (!y || !Number.isFinite(y)) {
y = 1;
}
return {
x,
y
};
}
const noOffsets = /*#__PURE__*/createCoords(0);
function getVisualOffsets(element) {
const win = getWindow(element);
if (!isWebKit() || !win.visualViewport) {
return noOffsets;
}
return {
x: win.visualViewport.offsetLeft,
y: win.visualViewport.offsetTop
};
}
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
if (isFixed === void 0) {
isFixed = false;
}
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
return false;
}
return isFixed;
}
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
const clientRect = element.getBoundingClientRect();
const domElement = unwrapElement(element);
let scale = createCoords(1);
if (includeScale) {
if (offsetParent) {
if (isElement(offsetParent)) {
scale = getScale(offsetParent);
}
} else {
scale = getScale(element);
}
}
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
let x = (clientRect.left + visualOffsets.x) / scale.x;
let y = (clientRect.top + visualOffsets.y) / scale.y;
let width = clientRect.width / scale.x;
let height = clientRect.height / scale.y;
if (domElement) {
const win = getWindow(domElement);
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
let currentWin = win;
let currentIFrame = getFrameElement(currentWin);
while (currentIFrame && offsetParent && offsetWin !== currentWin) {
const iframeScale = getScale(currentIFrame);
const iframeRect = currentIFrame.getBoundingClientRect();
const css = getComputedStyle$1(currentIFrame);
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
x *= iframeScale.x;
y *= iframeScale.y;
width *= iframeScale.x;
height *= iframeScale.y;
x += left;
y += top;
currentWin = getWindow(currentIFrame);
currentIFrame = getFrameElement(currentWin);
}
}
return rectToClientRect({
width,
height,
x,
y
});
}
// If <html> has a CSS width greater than the viewport, then this will be
// incorrect for RTL.
function getWindowScrollBarX(element, rect) {
const leftScroll = getNodeScroll(element).scrollLeft;
if (!rect) {
return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
}
return rect.left + leftScroll;
}
function getHTMLOffset(documentElement, scroll) {
const htmlRect = documentElement.getBoundingClientRect();
const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
const y = htmlRect.top + scroll.scrollTop;
return {
x,
y
};
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
let {
elements,
rect,
offsetParent,
strategy
} = _ref;
const isFixed = strategy === 'fixed';
const documentElement = getDocumentElement(offsetParent);
const topLayer = elements ? isTopLayer(elements.floating) : false;
if (offsetParent === documentElement || topLayer && isFixed) {
return rect;
}
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
let scale = createCoords(1);
const offsets = createCoords(0);
const isOffsetParentAnElement = isHTMLElement(offsetParent);
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent);
scale = getScale(offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
}
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
};
}
function getClientRects(element) {
return Array.from(element.getClientRects());
}
// Gets the entire size of the scrollable document area, even extending outside
// of the `<html>` and `<body>` rect bounds if horizontally scrollable.
function getDocumentRect(element) {
const html = getDocumentElement(element);
const scroll = getNodeScroll(element);
const body = element.ownerDocument.body;
const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
const y = -scroll.scrollTop;
if (getComputedStyle$1(body).direction === 'rtl') {
x += max(html.clientWidth, body.clientWidth) - width;
}
return {
width,
height,
x,
y
};
}
// Safety check: ensure the scrollbar space is reasonable in case this
// calculation is affected by unusual styles.
// Most scrollbars leave 15-18px of space.
const SCROLLBAR_MAX = 25;
function getViewportRect(element, strategy) {
const win = getWindow(element);
const html = getDocumentElement(element);
const visualViewport = win.visualViewport;
let width = html.clientWidth;
let height = html.clientHeight;
let x = 0;
let y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
const visualViewportBased = isWebKit();
if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
const windowScrollbarX = getWindowScrollBarX(html);
// <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
// visual width of the <html> but this is not considered in the size
// of `html.clientWidth`.
if (windowScrollbarX <= 0) {
const doc = html.ownerDocument;
const body = doc.body;
const bodyStyles = getComputedStyle(body);
const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
width -= clippingStableScrollbarWidth;
}
} else if (windowScrollbarX <= SCROLLBAR_MAX) {
// If the <body> scrollbar is on the left, the width needs to be extended
// by the scrollbar amount so there isn't extra space on the right.
width += windowScrollbarX;
}
return {
width,
height,
x,
y
};
}
// Returns the inner client rect, subtracting scrollbars if present.
function getInnerBoundingClientRect(element, strategy) {
const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
const top = clientRect.top + element.clientTop;
const left = clientRect.left + element.clientLeft;
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
const width = element.clientWidth * scale.x;
const height = element.clientHeight * scale.y;
const x = left * scale.x;
const y = top * scale.y;
return {
width,
height,
x,
y
};
}
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
let rect;
if (clippingAncestor === 'viewport') {
rect = getViewportRect(element, strategy);
} else if (clippingAncestor === 'document') {
rect = getDocumentRect(getDocumentElement(element));
} else if (isElement(clippingAncestor)) {
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
} else {
const visualOffsets = getVisualOffsets(element);
rect = {
x: clippingAncestor.x - visualOffsets.x,
y: clippingAncestor.y - visualOffsets.y,
width: clippingAncestor.width,
height: clippingAncestor.height
};
}
return rectToClientRect(rect);
}
function hasFixedPositionAncestor(element, stopNode) {
const parentNode = getParentNode(element);
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
return false;
}
return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
}
// A "clipping ancestor" is an `overflow` element with the characteristic of
// clipping (or hiding) child elements. This returns all clipping ancestors
// of the given element up the tree.
function getClippingElementAncestors(element, cache) {
const cachedResult = cache.get(element);
if (cachedResult) {
return cachedResult;
}
let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
let currentContainingBlockComputedStyle = null;
const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
let currentNode = elementIsFixed ? getParentNode(element) : element;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
const computedStyle = getComputedStyle$1(currentNode);
const currentNodeIsContaining = isContainingBlock(currentNode);
if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
currentContainingBlockComputedStyle = null;
}
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
if (shouldDropCurrentNode) {
// Drop non-containing blocks.
result = result.filter(ancestor => ancestor !== currentNode);
} else {
// Record last containing block for next iteration.
currentContainingBlockComputedStyle = computedStyle;
}
currentNode = getParentNode(currentNode);
}
cache.set(element, result);
return result;
}
// Gets the maximum area that the element is visible in due to any number of
// clipping ancestors.
function getClippingRect(_ref) {
let {
element,
boundary,
rootBoundary,
strategy
} = _ref;
const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
let top = firstRect.top;
let right = firstRect.right;
let bottom = firstRect.bottom;
let left = firstRect.left;
for (let i = 1; i < clippingAncestors.length; i++) {
const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
top = max(rect.top, top);
right = min(rect.right, right);
bottom = min(rect.bottom, bottom);
left = max(rect.left, left);
}
return {
width: right - left,
height: bottom - top,
x: left,
y: top
};
}
function getDimensions(element) {
const {
width,
height
} = getCssDimensions(element);
return {
width,
height
};
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
const isFixed = strategy === 'fixed';
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
const offsets = createCoords(0);
// If the <body> scrollbar appears on the left (e.g. RTL systems). Use
// Firefox with layout.scrollbar.side = 3 in about:config to test this.
function setLeftRTLScrollbarOffset() {
offsets.x = getWindowScrollBarX(documentElement);
}
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
} else if (documentElement) {
setLeftRTLScrollbarOffset();
}
}
if (isFixed && !isOffsetParentAnElement && documentElement) {
setLeftRTLScrollbarOffset();
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
return {
x,
y,
width: rect.width,
height: rect.height
};
}
function isStaticPositioned(element) {
return getComputedStyle$1(element).position === 'static';
}
function getTrueOffsetParent(element, polyfill) {
if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
return null;
}
if (polyfill) {
return polyfill(element);
}
let rawOffsetParent = element.offsetParent;
// Firefox returns the <html> element as the offsetParent if it's non-static,
// while Chrome and Safari return the <body> element. The <body> element must
// be used to perform the correct calculations even if the <html> element is
// non-static.
if (getDocumentElement(element) === rawOffsetParent) {
rawOffsetParent = rawOffsetParent.ownerDocument.body;
}
return rawOffsetParent;
}
// Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.
function getOffsetParent(element, polyfill) {
const win = getWindow(element);
if (isTopLayer(element)) {
return win;
}
if (!isHTMLElement(element)) {
let svgOffsetParent = getParentNode(element);
while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
return svgOffsetParent;
}
svgOffsetParent = getParentNode(svgOffsetParent);
}
return win;
}
let offsetParent = getTrueOffsetParent(element, polyfill);
while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
}
if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
return win;
}
return offsetParent || getContainingBlock(element) || win;
}
const getElementRects = async function (data) {
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
const getDimensionsFn = this.getDimensions;
const floatingDimensions = await getDimensionsFn(data.floating);
return {
reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
floating: {
x: 0,
y: 0,
width: floatingDimensions.width,
height: floatingDimensions.height
}
};
};
function isRTL(element) {
return getComputedStyle$1(element).direction === 'rtl';
}
const platform = {
convertOffsetParentRelativeRectToViewportRelativeRect,
getDocumentElement,
getClippingRect,
getOffsetParent,
getElementRects,
getClientRects,
getDimensions,
getScale,
isElement,
isRTL
};
function rectsAreEqual(a, b) {
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
}
// https://samthor.au/2021/observing-dom/
function observeMove(element, onMove) {
let io = null;
let timeoutId;
const root = getDocumentElement(element);
function cleanup() {
var _io;
clearTimeout(timeoutId);
(_io = io) == null || _io.disconnect();
io = null;
}
function refresh(skip, threshold) {
if (skip === void 0) {
skip = false;
}
if (threshold === void 0) {
threshold = 1;
}
cleanup();
const elementRectForRootMargin = element.getBoundingClientRect();
const {
left,
top,
width,
height
} = elementRectForRootMargin;
if (!skip) {
onMove();
}
if (!width || !height) {
return;
}
const insetTop = floor(top);
const insetRight = floor(root.clientWidth - (left + width));
const insetBottom = floor(root.clientHeight - (top + height));
const insetLeft = floor(left);
const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
const options = {
rootMargin,
threshold: max(0, min(1, threshold)) || 1
};
let isFirstUpdate = true;
function handleObserve(entries) {
const ratio = entries[0].intersectionRatio;
if (ratio !== threshold) {
if (!isFirstUpdate) {
return refresh();
}
if (!ratio) {
// If the reference is clipped, the ratio is 0. Throttle the refresh
// to prevent an infinite loop of updates.
timeoutId = setTimeout(() => {
refresh(false, 1e-7);
}, 1000);
} else {
refresh(false, ratio);
}
}
if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
// It's possible that even though the ratio is reported as 1, the
// element is not actually fully within the IntersectionObserver's root
// area anymore. This can happen under performance constraints. This may
// be a bug in the browser's IntersectionObserver implementation. To
// work around this, we compare the element's bounding rect now with
// what it was at the time we created the IntersectionObserver. If they
// are not equal then the element moved, so we refresh.
refresh();
}
isFirstUpdate = false;
}
// Older browsers don't support a `document` as the root and will throw an
// error.
try {
io = new IntersectionObserver(handleObserve, {
...options,
// Handle <iframe>s
root: root.ownerDocument
});
} catch (_e) {
io = new IntersectionObserver(handleObserve, options);
}
io.observe(element);
}
refresh(true);
return cleanup;
}
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
function autoUpdate(reference, floating, update, options) {
if (options === void 0) {
options = {};
}
const {
ancestorScroll = true,
ancestorResize = true,
elementResize = typeof ResizeObserver === 'function',
layoutShift = typeof IntersectionObserver === 'function',
animationFrame = false
} = options;
const referenceEl = unwrapElement(reference);
const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.addEventListener('scroll', update, {
passive: true
});
ancestorResize && ancestor.addEventListener('resize', update);
});
const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
let reobserveFrame = -1;
let resizeObserver = null;
if (elementResize) {
resizeObserver = new ResizeObserver(_ref => {
let [firstEntry] = _ref;
if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
// Prevent update loops when using the `size` middleware.
// https://github.com/floating-ui/floating-ui/issues/1740
resizeObserver.unobserve(floating);
cancelAnimationFrame(reobserveFrame);
reobserveFrame = requestAnimationFrame(() => {
var _resizeObserver;
(_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
});
}
update();
});
if (referenceEl && !animationFrame) {
resizeObserver.observe(referenceEl);
}
if (floating) {
resizeObserver.observe(floating);
}
}
let frameId;
let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
if (animationFrame) {
frameLoop();
}
function frameLoop() {
const nextRefRect = getBoundingClientRect(reference);
if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
update();
}
prevRefRect = nextRefRect;
frameId = requestAnimationFrame(frameLoop);
}
update();
return () => {
var _resizeObserver2;
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.removeEventListener('scroll', update);
ancestorResize && ancestor.removeEventListener('resize', update);
});
cleanupIo == null || cleanupIo();
(_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
resizeObserver = null;
if (animationFrame) {
cancelAnimationFrame(frameId);
}
};
}
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
const detectOverflow = detectOverflow$1;
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
const offset = offset$1;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
const autoPlacement = autoPlacement$1;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
const shift = shift$1;
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
const flip = flip$1;
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
const size = size$1;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
const hide = hide$1;
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
const arrow = arrow$1;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
const inline = inline$1;
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
const limitShift = limitShift$1;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
const computePosition = (reference, floating, options) => {
// This caches the expensive `getClippingElementAncestors` function so that
// multiple lifecycle resets re-use the same result. It only lives for a
// single call. If other functions become expensive, we can add them as well.
const cache = new Map();
const mergedOptions = {
platform,
...options
};
const platformWithCache = {
...mergedOptions.platform,
_c: cache
};
return computePosition$1(reference, floating, {
...mergedOptions,
platform: platformWithCache
});
};
export { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };

781
node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs generated vendored Normal file
View File

@@ -0,0 +1,781 @@
import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';
import { round, createCoords, max, min, floor } from '@floating-ui/utils';
import { getComputedStyle as getComputedStyle$1, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom';
export { getOverflowAncestors } from '@floating-ui/utils/dom';
function getCssDimensions(element) {
const css = getComputedStyle$1(element);
// In testing environments, the `width` and `height` properties are empty
// strings for SVG elements, returning NaN. Fallback to `0` in this case.
let width = parseFloat(css.width) || 0;
let height = parseFloat(css.height) || 0;
const hasOffset = isHTMLElement(element);
const offsetWidth = hasOffset ? element.offsetWidth : width;
const offsetHeight = hasOffset ? element.offsetHeight : height;
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
if (shouldFallback) {
width = offsetWidth;
height = offsetHeight;
}
return {
width,
height,
$: shouldFallback
};
}
function unwrapElement(element) {
return !isElement(element) ? element.contextElement : element;
}
function getScale(element) {
const domElement = unwrapElement(element);
if (!isHTMLElement(domElement)) {
return createCoords(1);
}
const rect = domElement.getBoundingClientRect();
const {
width,
height,
$
} = getCssDimensions(domElement);
let x = ($ ? round(rect.width) : rect.width) / width;
let y = ($ ? round(rect.height) : rect.height) / height;
// 0, NaN, or Infinity should always fallback to 1.
if (!x || !Number.isFinite(x)) {
x = 1;
}
if (!y || !Number.isFinite(y)) {
y = 1;
}
return {
x,
y
};
}
const noOffsets = /*#__PURE__*/createCoords(0);
function getVisualOffsets(element) {
const win = getWindow(element);
if (!isWebKit() || !win.visualViewport) {
return noOffsets;
}
return {
x: win.visualViewport.offsetLeft,
y: win.visualViewport.offsetTop
};
}
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
if (isFixed === void 0) {
isFixed = false;
}
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
return false;
}
return isFixed;
}
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
const clientRect = element.getBoundingClientRect();
const domElement = unwrapElement(element);
let scale = createCoords(1);
if (includeScale) {
if (offsetParent) {
if (isElement(offsetParent)) {
scale = getScale(offsetParent);
}
} else {
scale = getScale(element);
}
}
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
let x = (clientRect.left + visualOffsets.x) / scale.x;
let y = (clientRect.top + visualOffsets.y) / scale.y;
let width = clientRect.width / scale.x;
let height = clientRect.height / scale.y;
if (domElement) {
const win = getWindow(domElement);
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
let currentWin = win;
let currentIFrame = getFrameElement(currentWin);
while (currentIFrame && offsetParent && offsetWin !== currentWin) {
const iframeScale = getScale(currentIFrame);
const iframeRect = currentIFrame.getBoundingClientRect();
const css = getComputedStyle$1(currentIFrame);
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
x *= iframeScale.x;
y *= iframeScale.y;
width *= iframeScale.x;
height *= iframeScale.y;
x += left;
y += top;
currentWin = getWindow(currentIFrame);
currentIFrame = getFrameElement(currentWin);
}
}
return rectToClientRect({
width,
height,
x,
y
});
}
// If <html> has a CSS width greater than the viewport, then this will be
// incorrect for RTL.
function getWindowScrollBarX(element, rect) {
const leftScroll = getNodeScroll(element).scrollLeft;
if (!rect) {
return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
}
return rect.left + leftScroll;
}
function getHTMLOffset(documentElement, scroll) {
const htmlRect = documentElement.getBoundingClientRect();
const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
const y = htmlRect.top + scroll.scrollTop;
return {
x,
y
};
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
let {
elements,
rect,
offsetParent,
strategy
} = _ref;
const isFixed = strategy === 'fixed';
const documentElement = getDocumentElement(offsetParent);
const topLayer = elements ? isTopLayer(elements.floating) : false;
if (offsetParent === documentElement || topLayer && isFixed) {
return rect;
}
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
let scale = createCoords(1);
const offsets = createCoords(0);
const isOffsetParentAnElement = isHTMLElement(offsetParent);
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent);
scale = getScale(offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
}
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
};
}
function getClientRects(element) {
return Array.from(element.getClientRects());
}
// Gets the entire size of the scrollable document area, even extending outside
// of the `<html>` and `<body>` rect bounds if horizontally scrollable.
function getDocumentRect(element) {
const html = getDocumentElement(element);
const scroll = getNodeScroll(element);
const body = element.ownerDocument.body;
const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
const y = -scroll.scrollTop;
if (getComputedStyle$1(body).direction === 'rtl') {
x += max(html.clientWidth, body.clientWidth) - width;
}
return {
width,
height,
x,
y
};
}
// Safety check: ensure the scrollbar space is reasonable in case this
// calculation is affected by unusual styles.
// Most scrollbars leave 15-18px of space.
const SCROLLBAR_MAX = 25;
function getViewportRect(element, strategy) {
const win = getWindow(element);
const html = getDocumentElement(element);
const visualViewport = win.visualViewport;
let width = html.clientWidth;
let height = html.clientHeight;
let x = 0;
let y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
const visualViewportBased = isWebKit();
if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
const windowScrollbarX = getWindowScrollBarX(html);
// <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
// visual width of the <html> but this is not considered in the size
// of `html.clientWidth`.
if (windowScrollbarX <= 0) {
const doc = html.ownerDocument;
const body = doc.body;
const bodyStyles = getComputedStyle(body);
const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
width -= clippingStableScrollbarWidth;
}
} else if (windowScrollbarX <= SCROLLBAR_MAX) {
// If the <body> scrollbar is on the left, the width needs to be extended
// by the scrollbar amount so there isn't extra space on the right.
width += windowScrollbarX;
}
return {
width,
height,
x,
y
};
}
// Returns the inner client rect, subtracting scrollbars if present.
function getInnerBoundingClientRect(element, strategy) {
const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
const top = clientRect.top + element.clientTop;
const left = clientRect.left + element.clientLeft;
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
const width = element.clientWidth * scale.x;
const height = element.clientHeight * scale.y;
const x = left * scale.x;
const y = top * scale.y;
return {
width,
height,
x,
y
};
}
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
let rect;
if (clippingAncestor === 'viewport') {
rect = getViewportRect(element, strategy);
} else if (clippingAncestor === 'document') {
rect = getDocumentRect(getDocumentElement(element));
} else if (isElement(clippingAncestor)) {
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
} else {
const visualOffsets = getVisualOffsets(element);
rect = {
x: clippingAncestor.x - visualOffsets.x,
y: clippingAncestor.y - visualOffsets.y,
width: clippingAncestor.width,
height: clippingAncestor.height
};
}
return rectToClientRect(rect);
}
function hasFixedPositionAncestor(element, stopNode) {
const parentNode = getParentNode(element);
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
return false;
}
return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
}
// A "clipping ancestor" is an `overflow` element with the characteristic of
// clipping (or hiding) child elements. This returns all clipping ancestors
// of the given element up the tree.
function getClippingElementAncestors(element, cache) {
const cachedResult = cache.get(element);
if (cachedResult) {
return cachedResult;
}
let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
let currentContainingBlockComputedStyle = null;
const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
let currentNode = elementIsFixed ? getParentNode(element) : element;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
const computedStyle = getComputedStyle$1(currentNode);
const currentNodeIsContaining = isContainingBlock(currentNode);
if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
currentContainingBlockComputedStyle = null;
}
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
if (shouldDropCurrentNode) {
// Drop non-containing blocks.
result = result.filter(ancestor => ancestor !== currentNode);
} else {
// Record last containing block for next iteration.
currentContainingBlockComputedStyle = computedStyle;
}
currentNode = getParentNode(currentNode);
}
cache.set(element, result);
return result;
}
// Gets the maximum area that the element is visible in due to any number of
// clipping ancestors.
function getClippingRect(_ref) {
let {
element,
boundary,
rootBoundary,
strategy
} = _ref;
const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
let top = firstRect.top;
let right = firstRect.right;
let bottom = firstRect.bottom;
let left = firstRect.left;
for (let i = 1; i < clippingAncestors.length; i++) {
const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
top = max(rect.top, top);
right = min(rect.right, right);
bottom = min(rect.bottom, bottom);
left = max(rect.left, left);
}
return {
width: right - left,
height: bottom - top,
x: left,
y: top
};
}
function getDimensions(element) {
const {
width,
height
} = getCssDimensions(element);
return {
width,
height
};
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
const isFixed = strategy === 'fixed';
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
const offsets = createCoords(0);
// If the <body> scrollbar appears on the left (e.g. RTL systems). Use
// Firefox with layout.scrollbar.side = 3 in about:config to test this.
function setLeftRTLScrollbarOffset() {
offsets.x = getWindowScrollBarX(documentElement);
}
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
} else if (documentElement) {
setLeftRTLScrollbarOffset();
}
}
if (isFixed && !isOffsetParentAnElement && documentElement) {
setLeftRTLScrollbarOffset();
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
return {
x,
y,
width: rect.width,
height: rect.height
};
}
function isStaticPositioned(element) {
return getComputedStyle$1(element).position === 'static';
}
function getTrueOffsetParent(element, polyfill) {
if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
return null;
}
if (polyfill) {
return polyfill(element);
}
let rawOffsetParent = element.offsetParent;
// Firefox returns the <html> element as the offsetParent if it's non-static,
// while Chrome and Safari return the <body> element. The <body> element must
// be used to perform the correct calculations even if the <html> element is
// non-static.
if (getDocumentElement(element) === rawOffsetParent) {
rawOffsetParent = rawOffsetParent.ownerDocument.body;
}
return rawOffsetParent;
}
// Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.
function getOffsetParent(element, polyfill) {
const win = getWindow(element);
if (isTopLayer(element)) {
return win;
}
if (!isHTMLElement(element)) {
let svgOffsetParent = getParentNode(element);
while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
return svgOffsetParent;
}
svgOffsetParent = getParentNode(svgOffsetParent);
}
return win;
}
let offsetParent = getTrueOffsetParent(element, polyfill);
while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
}
if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
return win;
}
return offsetParent || getContainingBlock(element) || win;
}
const getElementRects = async function (data) {
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
const getDimensionsFn = this.getDimensions;
const floatingDimensions = await getDimensionsFn(data.floating);
return {
reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
floating: {
x: 0,
y: 0,
width: floatingDimensions.width,
height: floatingDimensions.height
}
};
};
function isRTL(element) {
return getComputedStyle$1(element).direction === 'rtl';
}
const platform = {
convertOffsetParentRelativeRectToViewportRelativeRect,
getDocumentElement,
getClippingRect,
getOffsetParent,
getElementRects,
getClientRects,
getDimensions,
getScale,
isElement,
isRTL
};
function rectsAreEqual(a, b) {
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
}
// https://samthor.au/2021/observing-dom/
function observeMove(element, onMove) {
let io = null;
let timeoutId;
const root = getDocumentElement(element);
function cleanup() {
var _io;
clearTimeout(timeoutId);
(_io = io) == null || _io.disconnect();
io = null;
}
function refresh(skip, threshold) {
if (skip === void 0) {
skip = false;
}
if (threshold === void 0) {
threshold = 1;
}
cleanup();
const elementRectForRootMargin = element.getBoundingClientRect();
const {
left,
top,
width,
height
} = elementRectForRootMargin;
if (!skip) {
onMove();
}
if (!width || !height) {
return;
}
const insetTop = floor(top);
const insetRight = floor(root.clientWidth - (left + width));
const insetBottom = floor(root.clientHeight - (top + height));
const insetLeft = floor(left);
const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
const options = {
rootMargin,
threshold: max(0, min(1, threshold)) || 1
};
let isFirstUpdate = true;
function handleObserve(entries) {
const ratio = entries[0].intersectionRatio;
if (ratio !== threshold) {
if (!isFirstUpdate) {
return refresh();
}
if (!ratio) {
// If the reference is clipped, the ratio is 0. Throttle the refresh
// to prevent an infinite loop of updates.
timeoutId = setTimeout(() => {
refresh(false, 1e-7);
}, 1000);
} else {
refresh(false, ratio);
}
}
if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
// It's possible that even though the ratio is reported as 1, the
// element is not actually fully within the IntersectionObserver's root
// area anymore. This can happen under performance constraints. This may
// be a bug in the browser's IntersectionObserver implementation. To
// work around this, we compare the element's bounding rect now with
// what it was at the time we created the IntersectionObserver. If they
// are not equal then the element moved, so we refresh.
refresh();
}
isFirstUpdate = false;
}
// Older browsers don't support a `document` as the root and will throw an
// error.
try {
io = new IntersectionObserver(handleObserve, {
...options,
// Handle <iframe>s
root: root.ownerDocument
});
} catch (_e) {
io = new IntersectionObserver(handleObserve, options);
}
io.observe(element);
}
refresh(true);
return cleanup;
}
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
function autoUpdate(reference, floating, update, options) {
if (options === void 0) {
options = {};
}
const {
ancestorScroll = true,
ancestorResize = true,
elementResize = typeof ResizeObserver === 'function',
layoutShift = typeof IntersectionObserver === 'function',
animationFrame = false
} = options;
const referenceEl = unwrapElement(reference);
const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.addEventListener('scroll', update, {
passive: true
});
ancestorResize && ancestor.addEventListener('resize', update);
});
const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
let reobserveFrame = -1;
let resizeObserver = null;
if (elementResize) {
resizeObserver = new ResizeObserver(_ref => {
let [firstEntry] = _ref;
if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
// Prevent update loops when using the `size` middleware.
// https://github.com/floating-ui/floating-ui/issues/1740
resizeObserver.unobserve(floating);
cancelAnimationFrame(reobserveFrame);
reobserveFrame = requestAnimationFrame(() => {
var _resizeObserver;
(_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
});
}
update();
});
if (referenceEl && !animationFrame) {
resizeObserver.observe(referenceEl);
}
if (floating) {
resizeObserver.observe(floating);
}
}
let frameId;
let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
if (animationFrame) {
frameLoop();
}
function frameLoop() {
const nextRefRect = getBoundingClientRect(reference);
if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
update();
}
prevRefRect = nextRefRect;
frameId = requestAnimationFrame(frameLoop);
}
update();
return () => {
var _resizeObserver2;
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.removeEventListener('scroll', update);
ancestorResize && ancestor.removeEventListener('resize', update);
});
cleanupIo == null || cleanupIo();
(_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
resizeObserver = null;
if (animationFrame) {
cancelAnimationFrame(frameId);
}
};
}
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
const detectOverflow = detectOverflow$1;
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
const offset = offset$1;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
const autoPlacement = autoPlacement$1;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
const shift = shift$1;
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
const flip = flip$1;
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
const size = size$1;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
const hide = hide$1;
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
const arrow = arrow$1;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
const inline = inline$1;
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
const limitShift = limitShift$1;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
const computePosition = (reference, floating, options) => {
// This caches the expensive `getClippingElementAncestors` function so that
// multiple lifecycle resets re-use the same result. It only lives for a
// single call. If other functions become expensive, we can add them as well.
const cache = new Map();
const mergedOptions = {
platform,
...options
};
const platformWithCache = {
...mergedOptions.platform,
_c: cache
};
return computePosition$1(reference, floating, {
...mergedOptions,
platform: platformWithCache
});
};
export { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };

View File

@@ -0,0 +1,975 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@floating-ui/core')) :
typeof define === 'function' && define.amd ? define(['exports', '@floating-ui/core'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIDOM = {}, global.FloatingUICore));
})(this, (function (exports, core) { 'use strict';
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle$1(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle$1(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
function getCssDimensions(element) {
const css = getComputedStyle$1(element);
// In testing environments, the `width` and `height` properties are empty
// strings for SVG elements, returning NaN. Fallback to `0` in this case.
let width = parseFloat(css.width) || 0;
let height = parseFloat(css.height) || 0;
const hasOffset = isHTMLElement(element);
const offsetWidth = hasOffset ? element.offsetWidth : width;
const offsetHeight = hasOffset ? element.offsetHeight : height;
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
if (shouldFallback) {
width = offsetWidth;
height = offsetHeight;
}
return {
width,
height,
$: shouldFallback
};
}
function unwrapElement(element) {
return !isElement(element) ? element.contextElement : element;
}
function getScale(element) {
const domElement = unwrapElement(element);
if (!isHTMLElement(domElement)) {
return createCoords(1);
}
const rect = domElement.getBoundingClientRect();
const {
width,
height,
$
} = getCssDimensions(domElement);
let x = ($ ? round(rect.width) : rect.width) / width;
let y = ($ ? round(rect.height) : rect.height) / height;
// 0, NaN, or Infinity should always fallback to 1.
if (!x || !Number.isFinite(x)) {
x = 1;
}
if (!y || !Number.isFinite(y)) {
y = 1;
}
return {
x,
y
};
}
const noOffsets = /*#__PURE__*/createCoords(0);
function getVisualOffsets(element) {
const win = getWindow(element);
if (!isWebKit() || !win.visualViewport) {
return noOffsets;
}
return {
x: win.visualViewport.offsetLeft,
y: win.visualViewport.offsetTop
};
}
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
if (isFixed === void 0) {
isFixed = false;
}
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
return false;
}
return isFixed;
}
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
const clientRect = element.getBoundingClientRect();
const domElement = unwrapElement(element);
let scale = createCoords(1);
if (includeScale) {
if (offsetParent) {
if (isElement(offsetParent)) {
scale = getScale(offsetParent);
}
} else {
scale = getScale(element);
}
}
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
let x = (clientRect.left + visualOffsets.x) / scale.x;
let y = (clientRect.top + visualOffsets.y) / scale.y;
let width = clientRect.width / scale.x;
let height = clientRect.height / scale.y;
if (domElement) {
const win = getWindow(domElement);
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
let currentWin = win;
let currentIFrame = getFrameElement(currentWin);
while (currentIFrame && offsetParent && offsetWin !== currentWin) {
const iframeScale = getScale(currentIFrame);
const iframeRect = currentIFrame.getBoundingClientRect();
const css = getComputedStyle$1(currentIFrame);
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
x *= iframeScale.x;
y *= iframeScale.y;
width *= iframeScale.x;
height *= iframeScale.y;
x += left;
y += top;
currentWin = getWindow(currentIFrame);
currentIFrame = getFrameElement(currentWin);
}
}
return core.rectToClientRect({
width,
height,
x,
y
});
}
// If <html> has a CSS width greater than the viewport, then this will be
// incorrect for RTL.
function getWindowScrollBarX(element, rect) {
const leftScroll = getNodeScroll(element).scrollLeft;
if (!rect) {
return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
}
return rect.left + leftScroll;
}
function getHTMLOffset(documentElement, scroll) {
const htmlRect = documentElement.getBoundingClientRect();
const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
const y = htmlRect.top + scroll.scrollTop;
return {
x,
y
};
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
let {
elements,
rect,
offsetParent,
strategy
} = _ref;
const isFixed = strategy === 'fixed';
const documentElement = getDocumentElement(offsetParent);
const topLayer = elements ? isTopLayer(elements.floating) : false;
if (offsetParent === documentElement || topLayer && isFixed) {
return rect;
}
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
let scale = createCoords(1);
const offsets = createCoords(0);
const isOffsetParentAnElement = isHTMLElement(offsetParent);
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent);
scale = getScale(offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
}
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
};
}
function getClientRects(element) {
return Array.from(element.getClientRects());
}
// Gets the entire size of the scrollable document area, even extending outside
// of the `<html>` and `<body>` rect bounds if horizontally scrollable.
function getDocumentRect(element) {
const html = getDocumentElement(element);
const scroll = getNodeScroll(element);
const body = element.ownerDocument.body;
const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
const y = -scroll.scrollTop;
if (getComputedStyle$1(body).direction === 'rtl') {
x += max(html.clientWidth, body.clientWidth) - width;
}
return {
width,
height,
x,
y
};
}
// Safety check: ensure the scrollbar space is reasonable in case this
// calculation is affected by unusual styles.
// Most scrollbars leave 15-18px of space.
const SCROLLBAR_MAX = 25;
function getViewportRect(element, strategy) {
const win = getWindow(element);
const html = getDocumentElement(element);
const visualViewport = win.visualViewport;
let width = html.clientWidth;
let height = html.clientHeight;
let x = 0;
let y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
const visualViewportBased = isWebKit();
if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
const windowScrollbarX = getWindowScrollBarX(html);
// <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
// visual width of the <html> but this is not considered in the size
// of `html.clientWidth`.
if (windowScrollbarX <= 0) {
const doc = html.ownerDocument;
const body = doc.body;
const bodyStyles = getComputedStyle(body);
const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
width -= clippingStableScrollbarWidth;
}
} else if (windowScrollbarX <= SCROLLBAR_MAX) {
// If the <body> scrollbar is on the left, the width needs to be extended
// by the scrollbar amount so there isn't extra space on the right.
width += windowScrollbarX;
}
return {
width,
height,
x,
y
};
}
// Returns the inner client rect, subtracting scrollbars if present.
function getInnerBoundingClientRect(element, strategy) {
const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
const top = clientRect.top + element.clientTop;
const left = clientRect.left + element.clientLeft;
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
const width = element.clientWidth * scale.x;
const height = element.clientHeight * scale.y;
const x = left * scale.x;
const y = top * scale.y;
return {
width,
height,
x,
y
};
}
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
let rect;
if (clippingAncestor === 'viewport') {
rect = getViewportRect(element, strategy);
} else if (clippingAncestor === 'document') {
rect = getDocumentRect(getDocumentElement(element));
} else if (isElement(clippingAncestor)) {
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
} else {
const visualOffsets = getVisualOffsets(element);
rect = {
x: clippingAncestor.x - visualOffsets.x,
y: clippingAncestor.y - visualOffsets.y,
width: clippingAncestor.width,
height: clippingAncestor.height
};
}
return core.rectToClientRect(rect);
}
function hasFixedPositionAncestor(element, stopNode) {
const parentNode = getParentNode(element);
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
return false;
}
return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
}
// A "clipping ancestor" is an `overflow` element with the characteristic of
// clipping (or hiding) child elements. This returns all clipping ancestors
// of the given element up the tree.
function getClippingElementAncestors(element, cache) {
const cachedResult = cache.get(element);
if (cachedResult) {
return cachedResult;
}
let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
let currentContainingBlockComputedStyle = null;
const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
let currentNode = elementIsFixed ? getParentNode(element) : element;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
const computedStyle = getComputedStyle$1(currentNode);
const currentNodeIsContaining = isContainingBlock(currentNode);
if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
currentContainingBlockComputedStyle = null;
}
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
if (shouldDropCurrentNode) {
// Drop non-containing blocks.
result = result.filter(ancestor => ancestor !== currentNode);
} else {
// Record last containing block for next iteration.
currentContainingBlockComputedStyle = computedStyle;
}
currentNode = getParentNode(currentNode);
}
cache.set(element, result);
return result;
}
// Gets the maximum area that the element is visible in due to any number of
// clipping ancestors.
function getClippingRect(_ref) {
let {
element,
boundary,
rootBoundary,
strategy
} = _ref;
const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
let top = firstRect.top;
let right = firstRect.right;
let bottom = firstRect.bottom;
let left = firstRect.left;
for (let i = 1; i < clippingAncestors.length; i++) {
const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
top = max(rect.top, top);
right = min(rect.right, right);
bottom = min(rect.bottom, bottom);
left = max(rect.left, left);
}
return {
width: right - left,
height: bottom - top,
x: left,
y: top
};
}
function getDimensions(element) {
const {
width,
height
} = getCssDimensions(element);
return {
width,
height
};
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
const isFixed = strategy === 'fixed';
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
const offsets = createCoords(0);
// If the <body> scrollbar appears on the left (e.g. RTL systems). Use
// Firefox with layout.scrollbar.side = 3 in about:config to test this.
function setLeftRTLScrollbarOffset() {
offsets.x = getWindowScrollBarX(documentElement);
}
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isOffsetParentAnElement) {
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
} else if (documentElement) {
setLeftRTLScrollbarOffset();
}
}
if (isFixed && !isOffsetParentAnElement && documentElement) {
setLeftRTLScrollbarOffset();
}
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
return {
x,
y,
width: rect.width,
height: rect.height
};
}
function isStaticPositioned(element) {
return getComputedStyle$1(element).position === 'static';
}
function getTrueOffsetParent(element, polyfill) {
if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
return null;
}
if (polyfill) {
return polyfill(element);
}
let rawOffsetParent = element.offsetParent;
// Firefox returns the <html> element as the offsetParent if it's non-static,
// while Chrome and Safari return the <body> element. The <body> element must
// be used to perform the correct calculations even if the <html> element is
// non-static.
if (getDocumentElement(element) === rawOffsetParent) {
rawOffsetParent = rawOffsetParent.ownerDocument.body;
}
return rawOffsetParent;
}
// Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.
function getOffsetParent(element, polyfill) {
const win = getWindow(element);
if (isTopLayer(element)) {
return win;
}
if (!isHTMLElement(element)) {
let svgOffsetParent = getParentNode(element);
while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
return svgOffsetParent;
}
svgOffsetParent = getParentNode(svgOffsetParent);
}
return win;
}
let offsetParent = getTrueOffsetParent(element, polyfill);
while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
}
if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
return win;
}
return offsetParent || getContainingBlock(element) || win;
}
const getElementRects = async function (data) {
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
const getDimensionsFn = this.getDimensions;
const floatingDimensions = await getDimensionsFn(data.floating);
return {
reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
floating: {
x: 0,
y: 0,
width: floatingDimensions.width,
height: floatingDimensions.height
}
};
};
function isRTL(element) {
return getComputedStyle$1(element).direction === 'rtl';
}
const platform = {
convertOffsetParentRelativeRectToViewportRelativeRect,
getDocumentElement,
getClippingRect,
getOffsetParent,
getElementRects,
getClientRects,
getDimensions,
getScale,
isElement,
isRTL
};
function rectsAreEqual(a, b) {
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
}
// https://samthor.au/2021/observing-dom/
function observeMove(element, onMove) {
let io = null;
let timeoutId;
const root = getDocumentElement(element);
function cleanup() {
var _io;
clearTimeout(timeoutId);
(_io = io) == null || _io.disconnect();
io = null;
}
function refresh(skip, threshold) {
if (skip === void 0) {
skip = false;
}
if (threshold === void 0) {
threshold = 1;
}
cleanup();
const elementRectForRootMargin = element.getBoundingClientRect();
const {
left,
top,
width,
height
} = elementRectForRootMargin;
if (!skip) {
onMove();
}
if (!width || !height) {
return;
}
const insetTop = floor(top);
const insetRight = floor(root.clientWidth - (left + width));
const insetBottom = floor(root.clientHeight - (top + height));
const insetLeft = floor(left);
const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
const options = {
rootMargin,
threshold: max(0, min(1, threshold)) || 1
};
let isFirstUpdate = true;
function handleObserve(entries) {
const ratio = entries[0].intersectionRatio;
if (ratio !== threshold) {
if (!isFirstUpdate) {
return refresh();
}
if (!ratio) {
// If the reference is clipped, the ratio is 0. Throttle the refresh
// to prevent an infinite loop of updates.
timeoutId = setTimeout(() => {
refresh(false, 1e-7);
}, 1000);
} else {
refresh(false, ratio);
}
}
if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
// It's possible that even though the ratio is reported as 1, the
// element is not actually fully within the IntersectionObserver's root
// area anymore. This can happen under performance constraints. This may
// be a bug in the browser's IntersectionObserver implementation. To
// work around this, we compare the element's bounding rect now with
// what it was at the time we created the IntersectionObserver. If they
// are not equal then the element moved, so we refresh.
refresh();
}
isFirstUpdate = false;
}
// Older browsers don't support a `document` as the root and will throw an
// error.
try {
io = new IntersectionObserver(handleObserve, {
...options,
// Handle <iframe>s
root: root.ownerDocument
});
} catch (_e) {
io = new IntersectionObserver(handleObserve, options);
}
io.observe(element);
}
refresh(true);
return cleanup;
}
/**
* Automatically updates the position of the floating element when necessary.
* Should only be called when the floating element is mounted on the DOM or
* visible on the screen.
* @returns cleanup function that should be invoked when the floating element is
* removed from the DOM or hidden from the screen.
* @see https://floating-ui.com/docs/autoUpdate
*/
function autoUpdate(reference, floating, update, options) {
if (options === void 0) {
options = {};
}
const {
ancestorScroll = true,
ancestorResize = true,
elementResize = typeof ResizeObserver === 'function',
layoutShift = typeof IntersectionObserver === 'function',
animationFrame = false
} = options;
const referenceEl = unwrapElement(reference);
const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.addEventListener('scroll', update, {
passive: true
});
ancestorResize && ancestor.addEventListener('resize', update);
});
const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
let reobserveFrame = -1;
let resizeObserver = null;
if (elementResize) {
resizeObserver = new ResizeObserver(_ref => {
let [firstEntry] = _ref;
if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
// Prevent update loops when using the `size` middleware.
// https://github.com/floating-ui/floating-ui/issues/1740
resizeObserver.unobserve(floating);
cancelAnimationFrame(reobserveFrame);
reobserveFrame = requestAnimationFrame(() => {
var _resizeObserver;
(_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
});
}
update();
});
if (referenceEl && !animationFrame) {
resizeObserver.observe(referenceEl);
}
if (floating) {
resizeObserver.observe(floating);
}
}
let frameId;
let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
if (animationFrame) {
frameLoop();
}
function frameLoop() {
const nextRefRect = getBoundingClientRect(reference);
if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
update();
}
prevRefRect = nextRefRect;
frameId = requestAnimationFrame(frameLoop);
}
update();
return () => {
var _resizeObserver2;
ancestors.forEach(ancestor => {
ancestorScroll && ancestor.removeEventListener('scroll', update);
ancestorResize && ancestor.removeEventListener('resize', update);
});
cleanupIo == null || cleanupIo();
(_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
resizeObserver = null;
if (animationFrame) {
cancelAnimationFrame(frameId);
}
};
}
/**
* Resolves with an object of overflow side offsets that determine how much the
* element is overflowing a given clipping boundary on each side.
* - positive = overflowing the boundary by that number of pixels
* - negative = how many pixels left before it will overflow
* - 0 = lies flush with the boundary
* @see https://floating-ui.com/docs/detectOverflow
*/
const detectOverflow = core.detectOverflow;
/**
* Modifies the placement by translating the floating element along the
* specified axes.
* A number (shorthand for `mainAxis` or distance), or an axes configuration
* object may be passed.
* @see https://floating-ui.com/docs/offset
*/
const offset = core.offset;
/**
* Optimizes the visibility of the floating element by choosing the placement
* that has the most space available automatically, without needing to specify a
* preferred placement. Alternative to `flip`.
* @see https://floating-ui.com/docs/autoPlacement
*/
const autoPlacement = core.autoPlacement;
/**
* Optimizes the visibility of the floating element by shifting it in order to
* keep it in view when it will overflow the clipping boundary.
* @see https://floating-ui.com/docs/shift
*/
const shift = core.shift;
/**
* Optimizes the visibility of the floating element by flipping the `placement`
* in order to keep it in view when the preferred placement(s) will overflow the
* clipping boundary. Alternative to `autoPlacement`.
* @see https://floating-ui.com/docs/flip
*/
const flip = core.flip;
/**
* Provides data that allows you to change the size of the floating element —
* for instance, prevent it from overflowing the clipping boundary or match the
* width of the reference element.
* @see https://floating-ui.com/docs/size
*/
const size = core.size;
/**
* Provides data to hide the floating element in applicable situations, such as
* when it is not in the same clipping context as the reference element.
* @see https://floating-ui.com/docs/hide
*/
const hide = core.hide;
/**
* Provides data to position an inner element of the floating element so that it
* appears centered to the reference element.
* @see https://floating-ui.com/docs/arrow
*/
const arrow = core.arrow;
/**
* Provides improved positioning for inline reference elements that can span
* over multiple lines, such as hyperlinks or range selections.
* @see https://floating-ui.com/docs/inline
*/
const inline = core.inline;
/**
* Built-in `limiter` that will stop `shift()` at a certain point.
*/
const limitShift = core.limitShift;
/**
* Computes the `x` and `y` coordinates that will place the floating element
* next to a given reference element.
*/
const computePosition = (reference, floating, options) => {
// This caches the expensive `getClippingElementAncestors` function so that
// multiple lifecycle resets re-use the same result. It only lives for a
// single call. If other functions become expensive, we can add them as well.
const cache = new Map();
const mergedOptions = {
platform,
...options
};
const platformWithCache = {
...mergedOptions.platform,
_c: cache
};
return core.computePosition(reference, floating, {
...mergedOptions,
platform: platformWithCache
});
};
exports.arrow = arrow;
exports.autoPlacement = autoPlacement;
exports.autoUpdate = autoUpdate;
exports.computePosition = computePosition;
exports.detectOverflow = detectOverflow;
exports.flip = flip;
exports.getOverflowAncestors = getOverflowAncestors;
exports.hide = hide;
exports.inline = inline;
exports.limitShift = limitShift;
exports.offset = offset;
exports.platform = platform;
exports.shift = shift;
exports.size = size;
}));

File diff suppressed because one or more lines are too long

71
node_modules/@floating-ui/dom/package.json generated vendored Normal file
View File

@@ -0,0 +1,71 @@
{
"name": "@floating-ui/dom",
"version": "1.7.6",
"description": "Floating UI for the web",
"publishConfig": {
"access": "public"
},
"main": "./dist/floating-ui.dom.umd.js",
"module": "./dist/floating-ui.dom.esm.js",
"unpkg": "./dist/floating-ui.dom.umd.min.js",
"types": "./dist/floating-ui.dom.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/floating-ui.dom.d.mts",
"default": "./dist/floating-ui.dom.mjs"
},
"types": "./dist/floating-ui.dom.d.ts",
"module": "./dist/floating-ui.dom.esm.js",
"default": "./dist/floating-ui.dom.umd.js"
}
},
"sideEffects": false,
"files": [
"dist"
],
"author": "atomiks",
"license": "MIT",
"bugs": "https://github.com/floating-ui/floating-ui",
"repository": {
"type": "git",
"url": "https://github.com/floating-ui/floating-ui.git",
"directory": "packages/dom"
},
"homepage": "https://floating-ui.com",
"keywords": [
"tooltip",
"popover",
"dropdown",
"menu",
"popup",
"positioning"
],
"dependencies": {
"@floating-ui/core": "^1.7.5",
"@floating-ui/utils": "^0.2.11"
},
"devDependencies": {
"@types/react": "^18.3.19",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.1",
"config": "0.0.0"
},
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"clean": "rimraf dist out-tsc test-results",
"dev": "vite",
"build": "rollup -c",
"build:api": "build-api --tsc tsconfig.lib.json",
"test": "vitest run",
"test:watch": "vitest watch",
"publint": "publint",
"playwright": "playwright test ./test/functional",
"typecheck": "tsc -b"
}
}

20
node_modules/@floating-ui/utils/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright (c) 2021-present Floating UI contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4
node_modules/@floating-ui/utils/README.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
# @floating-ui/utils
Utility functions shared across Floating UI packages. You may use these
functions in your own projects, but are subject to breaking changes.

View File

@@ -0,0 +1,103 @@
export declare type AlignedPlacement = `${Side}-${Alignment}`;
export declare type Alignment = 'start' | 'end';
export declare const alignments: Alignment[];
export declare type Axis = 'x' | 'y';
export declare function clamp(start: number, value: number, end: number): number;
export declare type ClientRectObject = Prettify<Rect & SideObject>;
export declare type Coords = {
[key in Axis]: number;
};
export declare const createCoords: (v: number) => {
x: number;
y: number;
};
export declare type Dimensions = {
[key in Length]: number;
};
export declare interface ElementRects {
reference: Rect;
floating: Rect;
}
export declare function evaluate<T, P>(value: T | ((param: P) => T), param: P): T;
export declare function expandPaddingObject(padding: Partial<SideObject>): SideObject;
export declare const floor: (x: number) => number;
export declare function getAlignment(placement: Placement): Alignment | undefined;
export declare function getAlignmentAxis(placement: Placement): Axis;
export declare function getAlignmentSides(placement: Placement, rects: ElementRects, rtl?: boolean): [Side, Side];
export declare function getAxisLength(axis: Axis): Length;
export declare function getExpandedPlacements(placement: Placement): Array<Placement>;
export declare function getOppositeAlignmentPlacement<T extends string>(placement: T): T;
export declare function getOppositeAxis(axis: Axis): Axis;
export declare function getOppositeAxisPlacements(placement: Placement, flipAlignment: boolean, direction: 'none' | Alignment, rtl?: boolean): Placement[];
export declare function getOppositePlacement<T extends string>(placement: T): T;
export declare function getPaddingObject(padding: Padding): SideObject;
export declare function getSide(placement: Placement): Side;
export declare function getSideAxis(placement: Placement): Axis;
export declare type Length = 'width' | 'height';
export declare const max: (...values: number[]) => number;
export declare const min: (...values: number[]) => number;
export declare type Padding = number | Prettify<Partial<SideObject>>;
export declare type Placement = Prettify<Side | AlignedPlacement>;
export declare const placements: Placement[];
declare type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
export declare type Rect = Prettify<Coords & Dimensions>;
export declare function rectToClientRect(rect: Rect): ClientRectObject;
export declare const round: (x: number) => number;
export declare type Side = 'top' | 'right' | 'bottom' | 'left';
export declare type SideObject = {
[key in Side]: number;
};
export declare const sides: Side[];
export declare type Strategy = 'absolute' | 'fixed';
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
export declare interface VirtualElement {
getBoundingClientRect(): ClientRectObject;
getClientRects?(): Array<ClientRectObject>;
contextElement?: any;
}
export { }

View File

@@ -0,0 +1,103 @@
export declare type AlignedPlacement = `${Side}-${Alignment}`;
export declare type Alignment = 'start' | 'end';
export declare const alignments: Alignment[];
export declare type Axis = 'x' | 'y';
export declare function clamp(start: number, value: number, end: number): number;
export declare type ClientRectObject = Prettify<Rect & SideObject>;
export declare type Coords = {
[key in Axis]: number;
};
export declare const createCoords: (v: number) => {
x: number;
y: number;
};
export declare type Dimensions = {
[key in Length]: number;
};
export declare interface ElementRects {
reference: Rect;
floating: Rect;
}
export declare function evaluate<T, P>(value: T | ((param: P) => T), param: P): T;
export declare function expandPaddingObject(padding: Partial<SideObject>): SideObject;
export declare const floor: (x: number) => number;
export declare function getAlignment(placement: Placement): Alignment | undefined;
export declare function getAlignmentAxis(placement: Placement): Axis;
export declare function getAlignmentSides(placement: Placement, rects: ElementRects, rtl?: boolean): [Side, Side];
export declare function getAxisLength(axis: Axis): Length;
export declare function getExpandedPlacements(placement: Placement): Array<Placement>;
export declare function getOppositeAlignmentPlacement<T extends string>(placement: T): T;
export declare function getOppositeAxis(axis: Axis): Axis;
export declare function getOppositeAxisPlacements(placement: Placement, flipAlignment: boolean, direction: 'none' | Alignment, rtl?: boolean): Placement[];
export declare function getOppositePlacement<T extends string>(placement: T): T;
export declare function getPaddingObject(padding: Padding): SideObject;
export declare function getSide(placement: Placement): Side;
export declare function getSideAxis(placement: Placement): Axis;
export declare type Length = 'width' | 'height';
export declare const max: (...values: number[]) => number;
export declare const min: (...values: number[]) => number;
export declare type Padding = number | Prettify<Partial<SideObject>>;
export declare type Placement = Prettify<Side | AlignedPlacement>;
export declare const placements: Placement[];
declare type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
export declare type Rect = Prettify<Coords & Dimensions>;
export declare function rectToClientRect(rect: Rect): ClientRectObject;
export declare const round: (x: number) => number;
export declare type Side = 'top' | 'right' | 'bottom' | 'left';
export declare type SideObject = {
[key in Side]: number;
};
export declare const sides: Side[];
export declare type Strategy = 'absolute' | 'fixed';
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
export declare interface VirtualElement {
getBoundingClientRect(): ClientRectObject;
getClientRects?(): Array<ClientRectObject>;
contextElement?: any;
}
export { }

View File

@@ -0,0 +1,47 @@
declare function getComputedStyle_2(element: Element): CSSStyleDeclaration;
export { getComputedStyle_2 as getComputedStyle }
export declare function getContainingBlock(element: Element): HTMLElement | null;
export declare function getDocumentElement(node: Node | Window): HTMLElement;
export declare function getFrameElement(win: Window): Element | null;
export declare function getNearestOverflowAncestor(node: Node): HTMLElement;
export declare function getNodeName(node: Node | Window): string;
export declare function getNodeScroll(element: Element | Window): {
scrollLeft: number;
scrollTop: number;
};
export declare function getOverflowAncestors(node: Node, list?: OverflowAncestors, traverseIframes?: boolean): OverflowAncestors;
export declare function getParentNode(node: Node): Node;
export declare function getWindow(node: any): typeof window;
export declare function isContainingBlock(elementOrCss: Element | CSSStyleDeclaration): boolean;
export declare function isElement(value: unknown): value is Element;
export declare function isHTMLElement(value: unknown): value is HTMLElement;
export declare function isLastTraversableNode(node: Node): boolean;
export declare function isNode(value: unknown): value is Node;
export declare function isOverflowElement(element: Element): boolean;
export declare function isShadowRoot(value: unknown): value is ShadowRoot;
export declare function isTableElement(element: Element): boolean;
export declare function isTopLayer(element: Element): boolean;
export declare function isWebKit(): boolean;
declare type OverflowAncestors = Array<Element | Window | VisualViewport>;
export { }

View File

@@ -0,0 +1,47 @@
declare function getComputedStyle_2(element: Element): CSSStyleDeclaration;
export { getComputedStyle_2 as getComputedStyle }
export declare function getContainingBlock(element: Element): HTMLElement | null;
export declare function getDocumentElement(node: Node | Window): HTMLElement;
export declare function getFrameElement(win: Window): Element | null;
export declare function getNearestOverflowAncestor(node: Node): HTMLElement;
export declare function getNodeName(node: Node | Window): string;
export declare function getNodeScroll(element: Element | Window): {
scrollLeft: number;
scrollTop: number;
};
export declare function getOverflowAncestors(node: Node, list?: OverflowAncestors, traverseIframes?: boolean): OverflowAncestors;
export declare function getParentNode(node: Node): Node;
export declare function getWindow(node: any): typeof window;
export declare function isContainingBlock(elementOrCss: Element | CSSStyleDeclaration): boolean;
export declare function isElement(value: unknown): value is Element;
export declare function isHTMLElement(value: unknown): value is HTMLElement;
export declare function isLastTraversableNode(node: Node): boolean;
export declare function isNode(value: unknown): value is Node;
export declare function isOverflowElement(element: Element): boolean;
export declare function isShadowRoot(value: unknown): value is ShadowRoot;
export declare function isTableElement(element: Element): boolean;
export declare function isTopLayer(element: Element): boolean;
export declare function isWebKit(): boolean;
declare type OverflowAncestors = Array<Element | Window | VisualViewport>;
export { }

View File

@@ -0,0 +1,165 @@
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
export { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };

View File

@@ -0,0 +1,165 @@
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
export { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };

View File

@@ -0,0 +1,192 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIUtilsDOM = {}));
})(this, (function (exports) { 'use strict';
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
exports.getComputedStyle = getComputedStyle;
exports.getContainingBlock = getContainingBlock;
exports.getDocumentElement = getDocumentElement;
exports.getFrameElement = getFrameElement;
exports.getNearestOverflowAncestor = getNearestOverflowAncestor;
exports.getNodeName = getNodeName;
exports.getNodeScroll = getNodeScroll;
exports.getOverflowAncestors = getOverflowAncestors;
exports.getParentNode = getParentNode;
exports.getWindow = getWindow;
exports.isContainingBlock = isContainingBlock;
exports.isElement = isElement;
exports.isHTMLElement = isHTMLElement;
exports.isLastTraversableNode = isLastTraversableNode;
exports.isNode = isNode;
exports.isOverflowElement = isOverflowElement;
exports.isShadowRoot = isShadowRoot;
exports.isTableElement = isTableElement;
exports.isTopLayer = isTopLayer;
exports.isWebKit = isWebKit;
}));

View File

@@ -0,0 +1 @@
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).FloatingUIUtilsDOM={})}(this,(function(t){"use strict";function e(){return"undefined"!=typeof window}function n(t){return i(t)?(t.nodeName||"").toLowerCase():"#document"}function o(t){var e;return(null==t||null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function r(t){var e;return null==(e=(i(t)?t.ownerDocument:t.document)||window.document)?void 0:e.documentElement}function i(t){return!!e()&&(t instanceof Node||t instanceof o(t).Node)}function l(t){return!!e()&&(t instanceof Element||t instanceof o(t).Element)}function c(t){return!!e()&&(t instanceof HTMLElement||t instanceof o(t).HTMLElement)}function u(t){return!(!e()||"undefined"==typeof ShadowRoot)&&(t instanceof ShadowRoot||t instanceof o(t).ShadowRoot)}function s(t){const{overflow:e,overflowX:n,overflowY:o,display:r}=g(t);return/auto|scroll|overlay|hidden|clip/.test(e+o+n)&&"inline"!==r&&"contents"!==r}function f(t){try{if(t.matches(":popover-open"))return!0}catch(t){}try{return t.matches(":modal")}catch(t){return!1}}const a=/transform|translate|scale|rotate|perspective|filter/,d=/paint|layout|strict|content/,m=t=>!!t&&"none"!==t;let p;function w(t){const e=l(t)?g(t):t;return m(e.transform)||m(e.translate)||m(e.scale)||m(e.rotate)||m(e.perspective)||!v()&&(m(e.backdropFilter)||m(e.filter))||a.test(e.willChange||"")||d.test(e.contain||"")}function v(){return null==p&&(p="undefined"!=typeof CSS&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),p}function y(t){return/^(html|body|#document)$/.test(n(t))}function g(t){return o(t).getComputedStyle(t)}function h(t){if("html"===n(t))return t;const e=t.assignedSlot||t.parentNode||u(t)&&t.host||r(t);return u(e)?e.host:e}function b(t){const e=h(t);return y(e)?t.ownerDocument?t.ownerDocument.body:t.body:c(e)&&s(e)?e:b(e)}function S(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameElement:null}t.getComputedStyle=g,t.getContainingBlock=function(t){let e=h(t);for(;c(e)&&!y(e);){if(w(e))return e;if(f(e))return null;e=h(e)}return null},t.getDocumentElement=r,t.getFrameElement=S,t.getNearestOverflowAncestor=b,t.getNodeName=n,t.getNodeScroll=function(t){return l(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.scrollX,scrollTop:t.scrollY}},t.getOverflowAncestors=function t(e,n,r){var i;void 0===n&&(n=[]),void 0===r&&(r=!0);const l=b(e),c=l===(null==(i=e.ownerDocument)?void 0:i.body),u=o(l);if(c){const e=S(u);return n.concat(u,u.visualViewport||[],s(l)?l:[],e&&r?t(e):[])}return n.concat(l,t(l,[],r))},t.getParentNode=h,t.getWindow=o,t.isContainingBlock=w,t.isElement=l,t.isHTMLElement=c,t.isLastTraversableNode=y,t.isNode=i,t.isOverflowElement=s,t.isShadowRoot=u,t.isTableElement=function(t){return/^(table|td|th)$/.test(n(t))},t.isTopLayer=f,t.isWebKit=v}));

View File

@@ -0,0 +1,136 @@
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const sides = ['top', 'right', 'bottom', 'left'];
const alignments = ['start', 'end'];
const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
const oppositeSideMap = {
left: 'right',
right: 'left',
bottom: 'top',
top: 'bottom'
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === 'function' ? value(param) : value;
}
function getSide(placement) {
return placement.split('-')[0];
}
function getAlignment(placement) {
return placement.split('-')[1];
}
function getOppositeAxis(axis) {
return axis === 'x' ? 'y' : 'x';
}
function getAxisLength(axis) {
return axis === 'y' ? 'height' : 'width';
}
function getSideAxis(placement) {
const firstChar = placement[0];
return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');
}
const lrPlacement = ['left', 'right'];
const rlPlacement = ['right', 'left'];
const tbPlacement = ['top', 'bottom'];
const btPlacement = ['bottom', 'top'];
function getSideList(side, isStart, rtl) {
switch (side) {
case 'top':
case 'bottom':
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case 'left':
case 'right':
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === 'start', rtl);
if (alignment) {
list = list.map(side => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
const side = getSide(placement);
return oppositeSideMap[side] + placement.slice(side.length);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x,
right: x + width,
bottom: y + height,
x,
y
};
}
export { alignments, clamp, createCoords, evaluate, expandPaddingObject, floor, getAlignment, getAlignmentAxis, getAlignmentSides, getAxisLength, getExpandedPlacements, getOppositeAlignmentPlacement, getOppositeAxis, getOppositeAxisPlacements, getOppositePlacement, getPaddingObject, getSide, getSideAxis, max, min, placements, rectToClientRect, round, sides };

View File

@@ -0,0 +1,136 @@
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const sides = ['top', 'right', 'bottom', 'left'];
const alignments = ['start', 'end'];
const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
const oppositeSideMap = {
left: 'right',
right: 'left',
bottom: 'top',
top: 'bottom'
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === 'function' ? value(param) : value;
}
function getSide(placement) {
return placement.split('-')[0];
}
function getAlignment(placement) {
return placement.split('-')[1];
}
function getOppositeAxis(axis) {
return axis === 'x' ? 'y' : 'x';
}
function getAxisLength(axis) {
return axis === 'y' ? 'height' : 'width';
}
function getSideAxis(placement) {
const firstChar = placement[0];
return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');
}
const lrPlacement = ['left', 'right'];
const rlPlacement = ['right', 'left'];
const tbPlacement = ['top', 'bottom'];
const btPlacement = ['bottom', 'top'];
function getSideList(side, isStart, rtl) {
switch (side) {
case 'top':
case 'bottom':
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case 'left':
case 'right':
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === 'start', rtl);
if (alignment) {
list = list.map(side => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
const side = getSide(placement);
return oppositeSideMap[side] + placement.slice(side.length);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x,
right: x + width,
bottom: y + height,
x,
y
};
}
export { alignments, clamp, createCoords, evaluate, expandPaddingObject, floor, getAlignment, getAlignmentAxis, getAlignmentSides, getAxisLength, getExpandedPlacements, getOppositeAlignmentPlacement, getOppositeAxis, getOppositeAxisPlacements, getOppositePlacement, getPaddingObject, getSide, getSideAxis, max, min, placements, rectToClientRect, round, sides };

View File

@@ -0,0 +1,167 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIUtils = {}));
})(this, (function (exports) { 'use strict';
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const sides = ['top', 'right', 'bottom', 'left'];
const alignments = ['start', 'end'];
const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
const oppositeSideMap = {
left: 'right',
right: 'left',
bottom: 'top',
top: 'bottom'
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === 'function' ? value(param) : value;
}
function getSide(placement) {
return placement.split('-')[0];
}
function getAlignment(placement) {
return placement.split('-')[1];
}
function getOppositeAxis(axis) {
return axis === 'x' ? 'y' : 'x';
}
function getAxisLength(axis) {
return axis === 'y' ? 'height' : 'width';
}
function getSideAxis(placement) {
const firstChar = placement[0];
return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');
}
const lrPlacement = ['left', 'right'];
const rlPlacement = ['right', 'left'];
const tbPlacement = ['top', 'bottom'];
const btPlacement = ['bottom', 'top'];
function getSideList(side, isStart, rtl) {
switch (side) {
case 'top':
case 'bottom':
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case 'left':
case 'right':
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === 'start', rtl);
if (alignment) {
list = list.map(side => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
const side = getSide(placement);
return oppositeSideMap[side] + placement.slice(side.length);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x,
right: x + width,
bottom: y + height,
x,
y
};
}
exports.alignments = alignments;
exports.clamp = clamp;
exports.createCoords = createCoords;
exports.evaluate = evaluate;
exports.expandPaddingObject = expandPaddingObject;
exports.floor = floor;
exports.getAlignment = getAlignment;
exports.getAlignmentAxis = getAlignmentAxis;
exports.getAlignmentSides = getAlignmentSides;
exports.getAxisLength = getAxisLength;
exports.getExpandedPlacements = getExpandedPlacements;
exports.getOppositeAlignmentPlacement = getOppositeAlignmentPlacement;
exports.getOppositeAxis = getOppositeAxis;
exports.getOppositeAxisPlacements = getOppositeAxisPlacements;
exports.getOppositePlacement = getOppositePlacement;
exports.getPaddingObject = getPaddingObject;
exports.getSide = getSide;
exports.getSideAxis = getSideAxis;
exports.max = max;
exports.min = min;
exports.placements = placements;
exports.rectToClientRect = rectToClientRect;
exports.round = round;
exports.sides = sides;
}));

View File

@@ -0,0 +1 @@
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).FloatingUIUtils={})}(this,(function(t){"use strict";const e=["top","right","bottom","left"],n=["start","end"],o=e.reduce(((t,e)=>t.concat(e,e+"-"+n[0],e+"-"+n[1])),[]),i=Math.min,r=Math.max,c=Math.round,s=Math.floor,u={left:"right",right:"left",bottom:"top",top:"bottom"};function f(t){return t.split("-")[0]}function l(t){return t.split("-")[1]}function a(t){return"x"===t?"y":"x"}function g(t){return"y"===t?"height":"width"}function p(t){const e=t[0];return"t"===e||"b"===e?"y":"x"}function d(t){return a(p(t))}function m(t){return t.includes("start")?t.replace("start","end"):t.replace("end","start")}const h=["left","right"],x=["right","left"],b=["top","bottom"],y=["bottom","top"];function A(t){const e=f(t);return u[e]+t.slice(e.length)}function O(t){return{top:0,right:0,bottom:0,left:0,...t}}t.alignments=n,t.clamp=function(t,e,n){return r(t,i(e,n))},t.createCoords=t=>({x:t,y:t}),t.evaluate=function(t,e){return"function"==typeof t?t(e):t},t.expandPaddingObject=O,t.floor=s,t.getAlignment=l,t.getAlignmentAxis=d,t.getAlignmentSides=function(t,e,n){void 0===n&&(n=!1);const o=l(t),i=d(t),r=g(i);let c="x"===i?o===(n?"end":"start")?"right":"left":"start"===o?"bottom":"top";return e.reference[r]>e.floating[r]&&(c=A(c)),[c,A(c)]},t.getAxisLength=g,t.getExpandedPlacements=function(t){const e=A(t);return[m(t),e,m(e)]},t.getOppositeAlignmentPlacement=m,t.getOppositeAxis=a,t.getOppositeAxisPlacements=function(t,e,n,o){const i=l(t);let r=function(t,e,n){switch(t){case"top":case"bottom":return n?e?x:h:e?h:x;case"left":case"right":return e?b:y;default:return[]}}(f(t),"start"===n,o);return i&&(r=r.map((t=>t+"-"+i)),e&&(r=r.concat(r.map(m)))),r},t.getOppositePlacement=A,t.getPaddingObject=function(t){return"number"!=typeof t?O(t):{top:t,right:t,bottom:t,left:t}},t.getSide=f,t.getSideAxis=p,t.max=r,t.min=i,t.placements=o,t.rectToClientRect=function(t){const{x:e,y:n,width:o,height:i}=t;return{width:o,height:i,top:n,left:e,right:e+o,bottom:n+i,x:e,y:n}},t.round=c,t.sides=e}));

View File

@@ -0,0 +1,47 @@
declare function getComputedStyle_2(element: Element): CSSStyleDeclaration;
export { getComputedStyle_2 as getComputedStyle }
export declare function getContainingBlock(element: Element): HTMLElement | null;
export declare function getDocumentElement(node: Node | Window): HTMLElement;
export declare function getFrameElement(win: Window): Element | null;
export declare function getNearestOverflowAncestor(node: Node): HTMLElement;
export declare function getNodeName(node: Node | Window): string;
export declare function getNodeScroll(element: Element | Window): {
scrollLeft: number;
scrollTop: number;
};
export declare function getOverflowAncestors(node: Node, list?: OverflowAncestors, traverseIframes?: boolean): OverflowAncestors;
export declare function getParentNode(node: Node): Node;
export declare function getWindow(node: any): typeof window;
export declare function isContainingBlock(elementOrCss: Element | CSSStyleDeclaration): boolean;
export declare function isElement(value: unknown): value is Element;
export declare function isHTMLElement(value: unknown): value is HTMLElement;
export declare function isLastTraversableNode(node: Node): boolean;
export declare function isNode(value: unknown): value is Node;
export declare function isOverflowElement(element: Element): boolean;
export declare function isShadowRoot(value: unknown): value is ShadowRoot;
export declare function isTableElement(element: Element): boolean;
export declare function isTopLayer(element: Element): boolean;
export declare function isWebKit(): boolean;
declare type OverflowAncestors = Array<Element | Window | VisualViewport>;
export { }

View File

@@ -0,0 +1,165 @@
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
export { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };

View File

@@ -0,0 +1,192 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIUtilsDOM = {}));
})(this, (function (exports) { 'use strict';
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
exports.getComputedStyle = getComputedStyle;
exports.getContainingBlock = getContainingBlock;
exports.getDocumentElement = getDocumentElement;
exports.getFrameElement = getFrameElement;
exports.getNearestOverflowAncestor = getNearestOverflowAncestor;
exports.getNodeName = getNodeName;
exports.getNodeScroll = getNodeScroll;
exports.getOverflowAncestors = getOverflowAncestors;
exports.getParentNode = getParentNode;
exports.getWindow = getWindow;
exports.isContainingBlock = isContainingBlock;
exports.isElement = isElement;
exports.isHTMLElement = isHTMLElement;
exports.isLastTraversableNode = isLastTraversableNode;
exports.isNode = isNode;
exports.isOverflowElement = isOverflowElement;
exports.isShadowRoot = isShadowRoot;
exports.isTableElement = isTableElement;
exports.isTopLayer = isTopLayer;
exports.isWebKit = isWebKit;
}));

6
node_modules/@floating-ui/utils/dom/package.json generated vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"sideEffects": false,
"main": "floating-ui.utils.dom.umd.js",
"module": "floating-ui.utils.dom.esm.js",
"types": "floating-ui.utils.dom.d.ts"
}

70
node_modules/@floating-ui/utils/package.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "@floating-ui/utils",
"version": "0.2.11",
"description": "Utilities for Floating UI",
"publishConfig": {
"access": "public"
},
"main": "./dist/floating-ui.utils.umd.js",
"module": "./dist/floating-ui.utils.esm.js",
"types": "./dist/floating-ui.utils.d.ts",
"sideEffects": false,
"files": [
"dist",
"dom"
],
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/floating-ui.utils.d.mts",
"default": "./dist/floating-ui.utils.mjs"
},
"types": "./dist/floating-ui.utils.d.ts",
"module": "./dist/floating-ui.utils.esm.js",
"default": "./dist/floating-ui.utils.umd.js"
},
"./dom": {
"import": {
"types": "./dist/floating-ui.utils.dom.d.mts",
"default": "./dist/floating-ui.utils.dom.mjs"
},
"types": "./dist/floating-ui.utils.dom.d.ts",
"module": "./dist/floating-ui.utils.dom.esm.js",
"default": "./dist/floating-ui.utils.dom.umd.js"
}
},
"author": "atomiks",
"license": "MIT",
"bugs": "https://github.com/floating-ui/floating-ui",
"repository": {
"type": "git",
"url": "https://github.com/floating-ui/floating-ui.git",
"directory": "packages/utils"
},
"homepage": "https://floating-ui.com",
"keywords": [
"tooltip",
"popover",
"dropdown",
"menu",
"popup",
"positioning"
],
"devDependencies": {
"@testing-library/jest-dom": "^6.1.6",
"config": "0.0.0"
},
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"clean": "rimraf dist out-tsc dom react",
"test": "vitest run --globals",
"test:watch": "vitest watch --globals",
"dev": "rollup -c -w",
"build": "rollup -c",
"build:api": "build-api --tsc tsconfig.lib.json --aec api-extractor.json --aec api-extractor.dom.json --aec api-extractor.react.json",
"publint": "publint",
"typecheck": "tsc -b"
}
}

21
node_modules/@remirror/core-constants/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-2022, Remirror Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,431 @@
/**
* The css class added to a node that is selected.
*/
export declare const SELECTED_NODE_CLASS_NAME = "ProseMirror-selectednode";
/**
* The css selector for a selected node.
*/
export declare const SELECTED_NODE_CLASS_SELECTOR: string;
/**
* ProseMirror uses the Unicode Character 'OBJECT REPLACEMENT CHARACTER'
* (U+FFFC) as text representation for leaf nodes, i.e. nodes that don't have
* any content or text property (e.g. hardBreak, emoji, mention, rule) It was
* introduced because of https://github.com/ProseMirror/prosemirror/issues/262
* This can be used in an input rule regex to be able to include or exclude such
* nodes.
*/
export declare const LEAF_NODE_REPLACING_CHARACTER = "\uFFFC";
/**
* The null character.
*
* See {@link https://stackoverflow.com/a/6380172}
*/
export declare const NULL_CHARACTER = "\0";
/**
* Indicates that a state update was caused by an override and not via
* transactions or user commands.
*
* This is the case when `setContent` is called and for all `controlled` updates
* within a `react` editor instance.
*/
export declare const STATE_OVERRIDE = "__state_override__";
/**
* The global name for the module exported by the remirror webview bundle.
*/
export declare const REMIRROR_WEBVIEW_NAME = "$$__REMIRROR_WEBVIEW_BUNDLE__$$";
/**
* A character useful for separating inline nodes.
*
* @remarks
* Typically used in decorations as follows.
*
* ```ts
* document.createTextNode(ZERO_WIDTH_SPACE_CHAR);
* ```
*
* This produces the html entity '8203'
*/
export declare const ZERO_WIDTH_SPACE_CHAR = "\u200B";
/**
* The non breaking space character.
*/
export declare const NON_BREAKING_SPACE_CHAR = "\u00A0";
/**
* A default empty object node. Useful for resetting the content of a
* prosemirror document.
*/
export declare const EMPTY_PARAGRAPH_NODE: {
type: string;
content: {
type: string;
}[];
};
export declare const EMPTY_NODE: {
type: string;
content: never[];
};
/**
* The type for the extension tags..
*/
export type ExtensionTag = Remirror.ExtensionTags & typeof BaseExtensionTag;
/**
* A method for updating the extension tags.
*
* ```tsx
* import { ExtensionTag, mutateTag } from 'remirror';
*
* mutateTag((tag) => {
* tag.SuperCustom = 'superCustom';
* });
*
* declare global {
* namespace Remirror {
* interface ExtensionTag {
* SuperCustom: 'superCustom';
* }
* }
* }
*
*
* log(ExtensionTag.SuperCustom); // This is fine ✅
* log(ExtensionTag.NotDefined); // This will throw ❌
* ```
*/
export declare function mutateTag(mutator: (Tag: ExtensionTag) => void): void;
declare const BaseExtensionTag: {
/**
* Describes a node that can be used as the last node of a document and
* doesn't need to have anything else rendered after itself.
*
* @remarks
*
* e.g. `paragraph`
*/
readonly LastNodeCompatible: "lastNodeCompatible";
/**
* A mark that is used to change the formatting of the node it wraps.
*
* @remarks
*
* e.g. `bold`, `italic`
*/
readonly FormattingMark: "formattingMark";
/**
* A node that formats text in a non-standard way.
*
* @remarks
*
* e.g. `codeBlock`, `heading`, `blockquote`
*/
readonly FormattingNode: "formattingNode";
/**
* Identifies a node which has problems with cursor navigation.
*
* @remarks
*
* When this tag is added to an extension this will be picked up by
* behavioural extensions such as the NodeCursorExtension which makes hard to
* reach nodes reachable using keyboard arrows.
*/
readonly NodeCursor: "nodeCursor";
/**
* Mark group for font styling (e.g. bold, italic, underline, superscript).
*/
readonly FontStyle: "fontStyle";
/**
* Mark groups for links.
*/
readonly Link: "link";
/**
* Mark groups for colors (text-color, background-color, etc).
*/
readonly Color: "color";
/**
* Mark group for alignment.
*/
readonly Alignment: "alignment";
/**
* Mark group for indentation.
*/
readonly Indentation: "indentation";
/**
* Extension which affect the behaviour of the content. Can be nodes marks or
* plain.
*/
readonly Behavior: "behavior";
/**
* Marks and nodes which contain code.
*/
readonly Code: "code";
/**
* Whether this node is an inline node.
*
* - `text` is an inline node, but `paragraph` is a block node.
*/
readonly InlineNode: "inline";
/**
* This is a node that can contain list items.
*/
readonly ListContainerNode: "listContainer";
/**
* Tags the extension as a list item node which can be contained by
* [[`ExtensionTag.ListNode`]].
*/
readonly ListItemNode: "listItemNode";
/**
* Sets this as a block level node.
*/
readonly Block: "block";
/**
* @deprecate use `ExtensionTags.Block` instead.
*/
readonly BlockNode: "block";
/**
* Set this as a text block
*/
readonly TextBlock: "textBlock";
/**
* A tag that excludes this from input rules.
*/
readonly ExcludeInputRules: "excludeFromInputRules";
/**
* A mark or node that can't be exited when at the end and beginning of the
* document with an arrow key or backspace key.
*/
readonly PreventExits: "preventsExits";
/**
* Represents a media compatible node.
*/
readonly Media: "media";
};
/**
* These are the default supported tag strings which help categorize different
* behaviors that extensions can exhibit.
*
* @remarks
*
* Any extension can register itself with multiple such behaviors and these
* categorizations can be used by other extensions when running commands and
* updating the document.
*/
export declare const ExtensionTag: ExtensionTag;
/**
* The string values which can be used as extension tags.
*/
export type ExtensionTagType = ExtensionTag[keyof ExtensionTag];
/**
* The identifier key which is used to check objects for whether they are a
* certain type.
*
* @remarks
*
* Just pretend you don't know this exists.
*
* @internal
*/
export declare const __INTERNAL_REMIRROR_IDENTIFIER_KEY__: unique symbol;
/**
* These constants are stored on the `REMIRROR_IDENTIFIER_KEY` property of
* `remirror` related constructors and instances in order to identify them as
* being internal to Remirror.
*
* @remarks
*
* This helps to prevent issues around check types via `instanceof` which can
* lead to false negatives.
*
* @internal
*/
export declare enum RemirrorIdentifier {
/**
* Identifies `PlainExtension`s.
*/
PlainExtension = "RemirrorPlainExtension",
/**
* Identifies `NodeExtension`s.
*/
NodeExtension = "RemirrorNodeExtension",
/**
* Identifies `MarkExtension`s.
*/
MarkExtension = "RemirrorMarkExtension",
/**
* Identifies `PlainExtensionConstructor`s.
*/
PlainExtensionConstructor = "RemirrorPlainExtensionConstructor",
/**
* Identifies `NodeExtensionConstructor`s.
*/
NodeExtensionConstructor = "RemirrorNodeExtensionConstructor",
/**
* Identifies `MarkExtensionConstructor`s.
*/
MarkExtensionConstructor = "RemirrorMarkExtensionConstructor",
/**
* The string used to identify an instance of the `Manager`
*/
Manager = "RemirrorManager",
/**
* The preset type identifier.
*/
Preset = "RemirrorPreset",
/**
* The preset type identifier.
*/
PresetConstructor = "RemirrorPresetConstructor"
}
/**
* The priority of extension which determines what order it is loaded into the
* editor.
*
* @remarks
*
* Higher priority extension (higher numberic value) will ensure the extension
* has a higher preference in your editor. In the case where you load two
* identical extensions into your editor (same name, or same constructor), the
* extension with the higher priority is the one that will be loaded.
*
* The higher the numeric value the higher the priority. The priority can also
* be passed a number but naming things in this `enum` should help provide some
* context to the numbers.
*
* By default all extensions are created with a `ExtensionPriority.Default`.
*/
export declare enum ExtensionPriority {
/**
* Use this **never** 😉
*/
Critical = 1000000,
/**
* A, like super duper, high priority.
*/
Highest = 100000,
/**
* The highest priority level that should be used in a publicly shared
* extension (to allow some wiggle room for downstream users overriding
* priorities).
*/
High = 10000,
/**
* A medium priority extension. This is typically all you need to take
* priority over built in extensions.
*/
Medium = 1000,
/**
* This is the **default** priority for most extensions.
*/
Default = 100,
/**
* This is the **default** priority for builtin behavior changing extensions.
*/
Low = 10,
/**
* This is useful for extensions that exist to be overridden.
*/
Lowest = 0
}
/**
* Identifies the stage the extension manager is at.
*/
export declare enum ManagerPhase {
/**
* The initial value for the manager phase.
*/
None = 0,
/**
* When the extension manager is being created and the onCreate methods are
* being called.
*
* This happens within the RemirrorManager constructor.
*/
Create = 1,
/**
* When the view is being added and all `onView` lifecycle methods are being
* called. The view is typically added before the dom is ready for it.
*/
EditorView = 2,
/**
* The phases of creating this manager are completed and `onTransaction` is
* called every time the state updates.
*/
Runtime = 3,
/**
* The manager is being destroyed.
*/
Destroy = 4
}
/**
* The named shortcuts that can be used to update multiple commands.
*/
export declare enum NamedShortcut {
Undo = "_|undo|_",
Redo = "_|redo|_",
Bold = "_|bold|_",
Italic = "_|italic|_",
Underline = "_|underline|_",
Strike = "_|strike|_",
Code = "_|code|_",
Paragraph = "_|paragraph|_",
H1 = "_|h1|_",
H2 = "_|h2|_",
H3 = "_|h3|_",
H4 = "_|h4|_",
H5 = "_|h5|_",
H6 = "_|h6|_",
TaskList = "_|task|_",
BulletList = "_|bullet|_",
OrderedList = "_|number|_",
Quote = "_|quote|_",
Divider = "_|divider|_",
Codeblock = "_|codeblock|_",
ClearFormatting = "_|clear|_",
Superscript = "_|sup|_",
Subscript = "_|sub|_",
LeftAlignment = "_|left-align|_",
CenterAlignment = "_|center-align|_",
RightAlignment = "_|right-align|_",
JustifyAlignment = "_|justify-align|_",
InsertLink = "_|link|_",
/** @deprecated */
Find = "_|find|_",
/** @deprecated */
FindBackwards = "_|find-backwards|_",
/** @deprecated */
FindReplace = "_|find-replace|_",
AddFootnote = "_|footnote|_",
AddComment = "_|comment|_",
ContextMenu = "_|context-menu|_",
IncreaseFontSize = "_|inc-font-size|_",
DecreaseFontSize = "_|dec-font-size|_",
IncreaseIndent = "_|indent|_",
DecreaseIndent = "_|dedent|_",
Shortcuts = "_|shortcuts|_",
Copy = "_|copy|_",
Cut = "_|cut|_",
Paste = "_|paste|_",
PastePlain = "_|paste-plain|_",
SelectAll = "_|select-all|_",
/**
* A keyboard shortcut to trigger formatting the current block.
*
* @defaultValue 'Alt-Shift-F' (Mac) | 'Shift-Ctrl-F' (PC)
*/
Format = "_|format|_"
}
/**
* Helpful empty array for use when a default array value is needed.
*
* DO NOT MUTATE!
*/
export declare const EMPTY_ARRAY: never[];
declare global {
namespace Remirror {
/**
* This interface is for extending the default `ExtensionTag`'s in your
* codebase with full type checking support.
*/
interface ExtensionTags {
}
}
}
export {};

View File

@@ -0,0 +1,119 @@
/**
* The error codes for errors used throughout the codebase.
*
* @remarks
*
* They can be removed but should never be changed since they are also used to
* reference the errors within search engines.
*/
export declare enum ErrorConstant {
/** An error happened but we're not quite sure why. */
UNKNOWN = "RMR0001",
/** The arguments passed to the command method were invalid. */
INVALID_COMMAND_ARGUMENTS = "RMR0002",
/** This is a custom error possibly thrown by an external library. */
CUSTOM = "RMR0003",
/**
* An error occurred in a function called from the `@remirror/core-helpers`
* library.
*/
CORE_HELPERS = "RMR0004",
/** You have attempted to change a value that shouldn't be changed. */
MUTATION = "RMR0005",
/**
* This is an error which should not occur and is internal to the remirror
* codebase.
*/
INTERNAL = "RMR0006",
/** You're editor is missing a required extension. */
MISSING_REQUIRED_EXTENSION = "RMR0007",
/**
* Called a method event at the wrong time. Please make sure getter functions
* are only called with within the scope of the returned functions. They
* should not be called in the outer scope of your method.
*/
MANAGER_PHASE_ERROR = "RMR0008",
/**
* The user requested an invalid extension from the getExtensions method.
* Please check the `createExtensions` return method is returning an extension
* with the defined constructor.
*/
INVALID_GET_EXTENSION = "RMR0010",
/**
* Invalid value passed into `Manager constructor`. Only and
* `Extensions` are supported.
*/
INVALID_MANAGER_ARGUMENTS = "RMR0011",
/**
* There is a problem with the schema or you are trying to access a node /
* mark that doesn't exists.
*/
SCHEMA = "RMR0012",
/**
* The `helpers` method which is passed into the ``create*` method should only
* be called within returned method since it relies on an active view (not
* present in the outer scope).
*/
HELPERS_CALLED_IN_OUTER_SCOPE = "RMR0013",
/** The user requested an invalid extension from the manager. */
INVALID_MANAGER_EXTENSION = "RMR0014",
/** Command method names must be unique within the editor. */
DUPLICATE_COMMAND_NAMES = "RMR0016",
/** Helper method names must be unique within the editor. */
DUPLICATE_HELPER_NAMES = "RMR0017",
/** Attempted to chain a non chainable command. */
NON_CHAINABLE_COMMAND = "RMR0018",
/** The provided extension is invalid. */
INVALID_EXTENSION = "RMR0019",
/** The content provided to the editor is not supported. */
INVALID_CONTENT = "RMR0021",
/** An invalid name was used for the extension. */
INVALID_NAME = "RMR0050",
/** An error occurred within an extension. */
EXTENSION = "RMR0100",
/** The spec was defined without calling the `defaults`, `parse` or `dom` methods. */
EXTENSION_SPEC = "RMR0101",
/** Extra attributes must either be a string or an object. */
EXTENSION_EXTRA_ATTRIBUTES = "RMR0102",
/** A call to `extension.setOptions` was made with invalid keys. */
INVALID_SET_EXTENSION_OPTIONS = "RMR0103",
/**
* `useRemirror` was called outside of the remirror context. It can only be used
* within an active remirror context created by the `<Remirror />`.
*/
REACT_PROVIDER_CONTEXT = "RMR0200",
/**
* `getRootProps` has been called MULTIPLE times. It should only be called ONCE during render.
*/
REACT_GET_ROOT_PROPS = "RMR0201",
/**
* A problem occurred adding the editor view to the dom.
*/
REACT_EDITOR_VIEW = "RMR0202",
/**
* There is a problem with your controlled editor setup.
*/
REACT_CONTROLLED = "RMR0203",
/**
* Something went wrong with your custom ReactNodeView Component.
*/
REACT_NODE_VIEW = "RMR0204",
/**
* You attempted to call `getContext` provided by the `useRemirror` prop
* during the first render of the editor. This is not possible and should only
* be after the editor first mounts.
*/
REACT_GET_CONTEXT = "RMR0205",
/**
* An error occurred when rendering the react components.
*/
REACT_COMPONENTS = "RMR0206",
/**
* An error occurred within a remirror hook.
*/
REACT_HOOKS = "RMR0207",
/**
* There is something wrong with your i18n setup.
*/
I18N_CONTEXT = "RMR0300"
}

View File

@@ -0,0 +1,2 @@
export * from './core-constants';
export { ErrorConstant } from './error-constants';

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,612 @@
/**
* The identifier key which is used to check objects for whether they are a
* certain type.
*
* @remarks
*
* Just pretend you don't know this exists.
*
* @internal
*/
declare const __INTERNAL_REMIRROR_IDENTIFIER_KEY__: unique symbol;
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY__ }
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY__ as __INTERNAL_REMIRROR_IDENTIFIER_KEY___alias_1 }
declare const BaseExtensionTag: {
/**
* Describes a node that can be used as the last node of a document and
* doesn't need to have anything else rendered after itself.
*
* @remarks
*
* e.g. `paragraph`
*/
readonly LastNodeCompatible: "lastNodeCompatible";
/**
* A mark that is used to change the formatting of the node it wraps.
*
* @remarks
*
* e.g. `bold`, `italic`
*/
readonly FormattingMark: "formattingMark";
/**
* A node that formats text in a non-standard way.
*
* @remarks
*
* e.g. `codeBlock`, `heading`, `blockquote`
*/
readonly FormattingNode: "formattingNode";
/**
* Identifies a node which has problems with cursor navigation.
*
* @remarks
*
* When this tag is added to an extension this will be picked up by
* behavioural extensions such as the NodeCursorExtension which makes hard to
* reach nodes reachable using keyboard arrows.
*/
readonly NodeCursor: "nodeCursor";
/**
* Mark group for font styling (e.g. bold, italic, underline, superscript).
*/
readonly FontStyle: "fontStyle";
/**
* Mark groups for links.
*/
readonly Link: "link";
/**
* Mark groups for colors (text-color, background-color, etc).
*/
readonly Color: "color";
/**
* Mark group for alignment.
*/
readonly Alignment: "alignment";
/**
* Mark group for indentation.
*/
readonly Indentation: "indentation";
/**
* Extension which affect the behaviour of the content. Can be nodes marks or
* plain.
*/
readonly Behavior: "behavior";
/**
* Marks and nodes which contain code.
*/
readonly Code: "code";
/**
* Whether this node is an inline node.
*
* - `text` is an inline node, but `paragraph` is a block node.
*/
readonly InlineNode: "inline";
/**
* This is a node that can contain list items.
*/
readonly ListContainerNode: "listContainer";
/**
* Tags the extension as a list item node which can be contained by
* [[`ExtensionTag.ListNode`]].
*/
readonly ListItemNode: "listItemNode";
/**
* Sets this as a block level node.
*/
readonly Block: "block";
/**
* @deprecate use `ExtensionTags.Block` instead.
*/
readonly BlockNode: "block";
/**
* Set this as a text block
*/
readonly TextBlock: "textBlock";
/**
* A tag that excludes this from input rules.
*/
readonly ExcludeInputRules: "excludeFromInputRules";
/**
* A mark or node that can't be exited when at the end and beginning of the
* document with an arrow key or backspace key.
*/
readonly PreventExits: "preventsExits";
/**
* Represents a media compatible node.
*/
readonly Media: "media";
};
/**
* Helpful empty array for use when a default array value is needed.
*
* DO NOT MUTATE!
*/
declare const EMPTY_ARRAY: never[];
export { EMPTY_ARRAY }
export { EMPTY_ARRAY as EMPTY_ARRAY_alias_1 }
declare const EMPTY_NODE: {
type: string;
content: never[];
};
export { EMPTY_NODE }
export { EMPTY_NODE as EMPTY_NODE_alias_1 }
/**
* A default empty object node. Useful for resetting the content of a
* prosemirror document.
*/
declare const EMPTY_PARAGRAPH_NODE: {
type: string;
content: {
type: string;
}[];
};
export { EMPTY_PARAGRAPH_NODE }
export { EMPTY_PARAGRAPH_NODE as EMPTY_PARAGRAPH_NODE_alias_1 }
/**
* The error codes for errors used throughout the codebase.
*
* @remarks
*
* They can be removed but should never be changed since they are also used to
* reference the errors within search engines.
*/
declare enum ErrorConstant {
/** An error happened but we're not quite sure why. */
UNKNOWN = "RMR0001",
/** The arguments passed to the command method were invalid. */
INVALID_COMMAND_ARGUMENTS = "RMR0002",
/** This is a custom error possibly thrown by an external library. */
CUSTOM = "RMR0003",
/**
* An error occurred in a function called from the `@remirror/core-helpers`
* library.
*/
CORE_HELPERS = "RMR0004",
/** You have attempted to change a value that shouldn't be changed. */
MUTATION = "RMR0005",
/**
* This is an error which should not occur and is internal to the remirror
* codebase.
*/
INTERNAL = "RMR0006",
/** You're editor is missing a required extension. */
MISSING_REQUIRED_EXTENSION = "RMR0007",
/**
* Called a method event at the wrong time. Please make sure getter functions
* are only called with within the scope of the returned functions. They
* should not be called in the outer scope of your method.
*/
MANAGER_PHASE_ERROR = "RMR0008",
/**
* The user requested an invalid extension from the getExtensions method.
* Please check the `createExtensions` return method is returning an extension
* with the defined constructor.
*/
INVALID_GET_EXTENSION = "RMR0010",
/**
* Invalid value passed into `Manager constructor`. Only and
* `Extensions` are supported.
*/
INVALID_MANAGER_ARGUMENTS = "RMR0011",
/**
* There is a problem with the schema or you are trying to access a node /
* mark that doesn't exists.
*/
SCHEMA = "RMR0012",
/**
* The `helpers` method which is passed into the ``create*` method should only
* be called within returned method since it relies on an active view (not
* present in the outer scope).
*/
HELPERS_CALLED_IN_OUTER_SCOPE = "RMR0013",
/** The user requested an invalid extension from the manager. */
INVALID_MANAGER_EXTENSION = "RMR0014",
/** Command method names must be unique within the editor. */
DUPLICATE_COMMAND_NAMES = "RMR0016",
/** Helper method names must be unique within the editor. */
DUPLICATE_HELPER_NAMES = "RMR0017",
/** Attempted to chain a non chainable command. */
NON_CHAINABLE_COMMAND = "RMR0018",
/** The provided extension is invalid. */
INVALID_EXTENSION = "RMR0019",
/** The content provided to the editor is not supported. */
INVALID_CONTENT = "RMR0021",
/** An invalid name was used for the extension. */
INVALID_NAME = "RMR0050",
/** An error occurred within an extension. */
EXTENSION = "RMR0100",
/** The spec was defined without calling the `defaults`, `parse` or `dom` methods. */
EXTENSION_SPEC = "RMR0101",
/** Extra attributes must either be a string or an object. */
EXTENSION_EXTRA_ATTRIBUTES = "RMR0102",
/** A call to `extension.setOptions` was made with invalid keys. */
INVALID_SET_EXTENSION_OPTIONS = "RMR0103",
/**
* `useRemirror` was called outside of the remirror context. It can only be used
* within an active remirror context created by the `<Remirror />`.
*/
REACT_PROVIDER_CONTEXT = "RMR0200",
/**
* `getRootProps` has been called MULTIPLE times. It should only be called ONCE during render.
*/
REACT_GET_ROOT_PROPS = "RMR0201",
/**
* A problem occurred adding the editor view to the dom.
*/
REACT_EDITOR_VIEW = "RMR0202",
/**
* There is a problem with your controlled editor setup.
*/
REACT_CONTROLLED = "RMR0203",
/**
* Something went wrong with your custom ReactNodeView Component.
*/
REACT_NODE_VIEW = "RMR0204",
/**
* You attempted to call `getContext` provided by the `useRemirror` prop
* during the first render of the editor. This is not possible and should only
* be after the editor first mounts.
*/
REACT_GET_CONTEXT = "RMR0205",
/**
* An error occurred when rendering the react components.
*/
REACT_COMPONENTS = "RMR0206",
/**
* An error occurred within a remirror hook.
*/
REACT_HOOKS = "RMR0207",
/**
* There is something wrong with your i18n setup.
*/
I18N_CONTEXT = "RMR0300"
}
export { ErrorConstant }
export { ErrorConstant as ErrorConstant_alias_1 }
/**
* The priority of extension which determines what order it is loaded into the
* editor.
*
* @remarks
*
* Higher priority extension (higher numberic value) will ensure the extension
* has a higher preference in your editor. In the case where you load two
* identical extensions into your editor (same name, or same constructor), the
* extension with the higher priority is the one that will be loaded.
*
* The higher the numeric value the higher the priority. The priority can also
* be passed a number but naming things in this `enum` should help provide some
* context to the numbers.
*
* By default all extensions are created with a `ExtensionPriority.Default`.
*/
declare enum ExtensionPriority {
/**
* Use this **never** 😉
*/
Critical = 1000000,
/**
* A, like super duper, high priority.
*/
Highest = 100000,
/**
* The highest priority level that should be used in a publicly shared
* extension (to allow some wiggle room for downstream users overriding
* priorities).
*/
High = 10000,
/**
* A medium priority extension. This is typically all you need to take
* priority over built in extensions.
*/
Medium = 1000,
/**
* This is the **default** priority for most extensions.
*/
Default = 100,
/**
* This is the **default** priority for builtin behavior changing extensions.
*/
Low = 10,
/**
* This is useful for extensions that exist to be overridden.
*/
Lowest = 0
}
export { ExtensionPriority }
export { ExtensionPriority as ExtensionPriority_alias_1 }
/**
* The type for the extension tags..
*/
declare type ExtensionTag = Remirror.ExtensionTags & typeof BaseExtensionTag;
/**
* These are the default supported tag strings which help categorize different
* behaviors that extensions can exhibit.
*
* @remarks
*
* Any extension can register itself with multiple such behaviors and these
* categorizations can be used by other extensions when running commands and
* updating the document.
*/
declare const ExtensionTag: ExtensionTag;
export { ExtensionTag }
export { ExtensionTag as ExtensionTag_alias_1 }
/**
* The string values which can be used as extension tags.
*/
declare type ExtensionTagType = ExtensionTag[keyof ExtensionTag];
export { ExtensionTagType }
export { ExtensionTagType as ExtensionTagType_alias_1 }
/**
* ProseMirror uses the Unicode Character 'OBJECT REPLACEMENT CHARACTER'
* (U+FFFC) as text representation for leaf nodes, i.e. nodes that don't have
* any content or text property (e.g. hardBreak, emoji, mention, rule) It was
* introduced because of https://github.com/ProseMirror/prosemirror/issues/262
* This can be used in an input rule regex to be able to include or exclude such
* nodes.
*/
declare const LEAF_NODE_REPLACING_CHARACTER = "\uFFFC";
export { LEAF_NODE_REPLACING_CHARACTER }
export { LEAF_NODE_REPLACING_CHARACTER as LEAF_NODE_REPLACING_CHARACTER_alias_1 }
/**
* Identifies the stage the extension manager is at.
*/
declare enum ManagerPhase {
/**
* The initial value for the manager phase.
*/
None = 0,
/**
* When the extension manager is being created and the onCreate methods are
* being called.
*
* This happens within the RemirrorManager constructor.
*/
Create = 1,
/**
* When the view is being added and all `onView` lifecycle methods are being
* called. The view is typically added before the dom is ready for it.
*/
EditorView = 2,
/**
* The phases of creating this manager are completed and `onTransaction` is
* called every time the state updates.
*/
Runtime = 3,
/**
* The manager is being destroyed.
*/
Destroy = 4
}
export { ManagerPhase }
export { ManagerPhase as ManagerPhase_alias_1 }
/**
* A method for updating the extension tags.
*
* ```tsx
* import { ExtensionTag, mutateTag } from 'remirror';
*
* mutateTag((tag) => {
* tag.SuperCustom = 'superCustom';
* });
*
* declare global {
* namespace Remirror {
* interface ExtensionTag {
* SuperCustom: 'superCustom';
* }
* }
* }
*
*
* log(ExtensionTag.SuperCustom); // This is fine ✅
* log(ExtensionTag.NotDefined); // This will throw ❌
* ```
*/
declare function mutateTag(mutator: (Tag: ExtensionTag) => void): void;
export { mutateTag }
export { mutateTag as mutateTag_alias_1 }
/**
* The named shortcuts that can be used to update multiple commands.
*/
declare enum NamedShortcut {
Undo = "_|undo|_",
Redo = "_|redo|_",
Bold = "_|bold|_",
Italic = "_|italic|_",
Underline = "_|underline|_",
Strike = "_|strike|_",
Code = "_|code|_",
Paragraph = "_|paragraph|_",
H1 = "_|h1|_",
H2 = "_|h2|_",
H3 = "_|h3|_",
H4 = "_|h4|_",
H5 = "_|h5|_",
H6 = "_|h6|_",
TaskList = "_|task|_",
BulletList = "_|bullet|_",
OrderedList = "_|number|_",
Quote = "_|quote|_",
Divider = "_|divider|_",
Codeblock = "_|codeblock|_",
ClearFormatting = "_|clear|_",
Superscript = "_|sup|_",
Subscript = "_|sub|_",
LeftAlignment = "_|left-align|_",
CenterAlignment = "_|center-align|_",
RightAlignment = "_|right-align|_",
JustifyAlignment = "_|justify-align|_",
InsertLink = "_|link|_",
/** @deprecated */
Find = "_|find|_",
/** @deprecated */
FindBackwards = "_|find-backwards|_",
/** @deprecated */
FindReplace = "_|find-replace|_",
AddFootnote = "_|footnote|_",
AddComment = "_|comment|_",
ContextMenu = "_|context-menu|_",
IncreaseFontSize = "_|inc-font-size|_",
DecreaseFontSize = "_|dec-font-size|_",
IncreaseIndent = "_|indent|_",
DecreaseIndent = "_|dedent|_",
Shortcuts = "_|shortcuts|_",
Copy = "_|copy|_",
Cut = "_|cut|_",
Paste = "_|paste|_",
PastePlain = "_|paste-plain|_",
SelectAll = "_|select-all|_",
/**
* A keyboard shortcut to trigger formatting the current block.
*
* @defaultValue 'Alt-Shift-F' (Mac) | 'Shift-Ctrl-F' (PC)
*/
Format = "_|format|_"
}
export { NamedShortcut }
export { NamedShortcut as NamedShortcut_alias_1 }
/**
* The non breaking space character.
*/
declare const NON_BREAKING_SPACE_CHAR = "\u00A0";
export { NON_BREAKING_SPACE_CHAR }
export { NON_BREAKING_SPACE_CHAR as NON_BREAKING_SPACE_CHAR_alias_1 }
/**
* The null character.
*
* See {@link https://stackoverflow.com/a/6380172}
*/
declare const NULL_CHARACTER = "\0";
export { NULL_CHARACTER }
export { NULL_CHARACTER as NULL_CHARACTER_alias_1 }
/**
* The global name for the module exported by the remirror webview bundle.
*/
declare const REMIRROR_WEBVIEW_NAME = "$$__REMIRROR_WEBVIEW_BUNDLE__$$";
export { REMIRROR_WEBVIEW_NAME }
export { REMIRROR_WEBVIEW_NAME as REMIRROR_WEBVIEW_NAME_alias_1 }
/**
* These constants are stored on the `REMIRROR_IDENTIFIER_KEY` property of
* `remirror` related constructors and instances in order to identify them as
* being internal to Remirror.
*
* @remarks
*
* This helps to prevent issues around check types via `instanceof` which can
* lead to false negatives.
*
* @internal
*/
declare enum RemirrorIdentifier {
/**
* Identifies `PlainExtension`s.
*/
PlainExtension = "RemirrorPlainExtension",
/**
* Identifies `NodeExtension`s.
*/
NodeExtension = "RemirrorNodeExtension",
/**
* Identifies `MarkExtension`s.
*/
MarkExtension = "RemirrorMarkExtension",
/**
* Identifies `PlainExtensionConstructor`s.
*/
PlainExtensionConstructor = "RemirrorPlainExtensionConstructor",
/**
* Identifies `NodeExtensionConstructor`s.
*/
NodeExtensionConstructor = "RemirrorNodeExtensionConstructor",
/**
* Identifies `MarkExtensionConstructor`s.
*/
MarkExtensionConstructor = "RemirrorMarkExtensionConstructor",
/**
* The string used to identify an instance of the `Manager`
*/
Manager = "RemirrorManager",
/**
* The preset type identifier.
*/
Preset = "RemirrorPreset",
/**
* The preset type identifier.
*/
PresetConstructor = "RemirrorPresetConstructor"
}
export { RemirrorIdentifier }
export { RemirrorIdentifier as RemirrorIdentifier_alias_1 }
/**
* The css class added to a node that is selected.
*/
declare const SELECTED_NODE_CLASS_NAME = "ProseMirror-selectednode";
export { SELECTED_NODE_CLASS_NAME }
export { SELECTED_NODE_CLASS_NAME as SELECTED_NODE_CLASS_NAME_alias_1 }
/**
* The css selector for a selected node.
*/
declare const SELECTED_NODE_CLASS_SELECTOR: string;
export { SELECTED_NODE_CLASS_SELECTOR }
export { SELECTED_NODE_CLASS_SELECTOR as SELECTED_NODE_CLASS_SELECTOR_alias_1 }
/**
* Indicates that a state update was caused by an override and not via
* transactions or user commands.
*
* This is the case when `setContent` is called and for all `controlled` updates
* within a `react` editor instance.
*/
declare const STATE_OVERRIDE = "__state_override__";
export { STATE_OVERRIDE }
export { STATE_OVERRIDE as STATE_OVERRIDE_alias_1 }
/**
* A character useful for separating inline nodes.
*
* @remarks
* Typically used in decorations as follows.
*
* ```ts
* document.createTextNode(ZERO_WIDTH_SPACE_CHAR);
* ```
*
* This produces the html entity '8203'
*/
declare const ZERO_WIDTH_SPACE_CHAR = "\u200B";
export { ZERO_WIDTH_SPACE_CHAR }
export { ZERO_WIDTH_SPACE_CHAR as ZERO_WIDTH_SPACE_CHAR_alias_1 }
export { }
declare global {
namespace Remirror {
/**
* This interface is for extending the default `ExtensionTag`'s in your
* codebase with full type checking support.
*/
interface ExtensionTags {}
}
}

View File

@@ -0,0 +1,612 @@
/**
* The identifier key which is used to check objects for whether they are a
* certain type.
*
* @remarks
*
* Just pretend you don't know this exists.
*
* @internal
*/
declare const __INTERNAL_REMIRROR_IDENTIFIER_KEY__: unique symbol;
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY__ }
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY__ as __INTERNAL_REMIRROR_IDENTIFIER_KEY___alias_1 }
declare const BaseExtensionTag: {
/**
* Describes a node that can be used as the last node of a document and
* doesn't need to have anything else rendered after itself.
*
* @remarks
*
* e.g. `paragraph`
*/
readonly LastNodeCompatible: "lastNodeCompatible";
/**
* A mark that is used to change the formatting of the node it wraps.
*
* @remarks
*
* e.g. `bold`, `italic`
*/
readonly FormattingMark: "formattingMark";
/**
* A node that formats text in a non-standard way.
*
* @remarks
*
* e.g. `codeBlock`, `heading`, `blockquote`
*/
readonly FormattingNode: "formattingNode";
/**
* Identifies a node which has problems with cursor navigation.
*
* @remarks
*
* When this tag is added to an extension this will be picked up by
* behavioural extensions such as the NodeCursorExtension which makes hard to
* reach nodes reachable using keyboard arrows.
*/
readonly NodeCursor: "nodeCursor";
/**
* Mark group for font styling (e.g. bold, italic, underline, superscript).
*/
readonly FontStyle: "fontStyle";
/**
* Mark groups for links.
*/
readonly Link: "link";
/**
* Mark groups for colors (text-color, background-color, etc).
*/
readonly Color: "color";
/**
* Mark group for alignment.
*/
readonly Alignment: "alignment";
/**
* Mark group for indentation.
*/
readonly Indentation: "indentation";
/**
* Extension which affect the behaviour of the content. Can be nodes marks or
* plain.
*/
readonly Behavior: "behavior";
/**
* Marks and nodes which contain code.
*/
readonly Code: "code";
/**
* Whether this node is an inline node.
*
* - `text` is an inline node, but `paragraph` is a block node.
*/
readonly InlineNode: "inline";
/**
* This is a node that can contain list items.
*/
readonly ListContainerNode: "listContainer";
/**
* Tags the extension as a list item node which can be contained by
* [[`ExtensionTag.ListNode`]].
*/
readonly ListItemNode: "listItemNode";
/**
* Sets this as a block level node.
*/
readonly Block: "block";
/**
* @deprecate use `ExtensionTags.Block` instead.
*/
readonly BlockNode: "block";
/**
* Set this as a text block
*/
readonly TextBlock: "textBlock";
/**
* A tag that excludes this from input rules.
*/
readonly ExcludeInputRules: "excludeFromInputRules";
/**
* A mark or node that can't be exited when at the end and beginning of the
* document with an arrow key or backspace key.
*/
readonly PreventExits: "preventsExits";
/**
* Represents a media compatible node.
*/
readonly Media: "media";
};
/**
* Helpful empty array for use when a default array value is needed.
*
* DO NOT MUTATE!
*/
declare const EMPTY_ARRAY: never[];
export { EMPTY_ARRAY }
export { EMPTY_ARRAY as EMPTY_ARRAY_alias_1 }
declare const EMPTY_NODE: {
type: string;
content: never[];
};
export { EMPTY_NODE }
export { EMPTY_NODE as EMPTY_NODE_alias_1 }
/**
* A default empty object node. Useful for resetting the content of a
* prosemirror document.
*/
declare const EMPTY_PARAGRAPH_NODE: {
type: string;
content: {
type: string;
}[];
};
export { EMPTY_PARAGRAPH_NODE }
export { EMPTY_PARAGRAPH_NODE as EMPTY_PARAGRAPH_NODE_alias_1 }
/**
* The error codes for errors used throughout the codebase.
*
* @remarks
*
* They can be removed but should never be changed since they are also used to
* reference the errors within search engines.
*/
declare enum ErrorConstant {
/** An error happened but we're not quite sure why. */
UNKNOWN = "RMR0001",
/** The arguments passed to the command method were invalid. */
INVALID_COMMAND_ARGUMENTS = "RMR0002",
/** This is a custom error possibly thrown by an external library. */
CUSTOM = "RMR0003",
/**
* An error occurred in a function called from the `@remirror/core-helpers`
* library.
*/
CORE_HELPERS = "RMR0004",
/** You have attempted to change a value that shouldn't be changed. */
MUTATION = "RMR0005",
/**
* This is an error which should not occur and is internal to the remirror
* codebase.
*/
INTERNAL = "RMR0006",
/** You're editor is missing a required extension. */
MISSING_REQUIRED_EXTENSION = "RMR0007",
/**
* Called a method event at the wrong time. Please make sure getter functions
* are only called with within the scope of the returned functions. They
* should not be called in the outer scope of your method.
*/
MANAGER_PHASE_ERROR = "RMR0008",
/**
* The user requested an invalid extension from the getExtensions method.
* Please check the `createExtensions` return method is returning an extension
* with the defined constructor.
*/
INVALID_GET_EXTENSION = "RMR0010",
/**
* Invalid value passed into `Manager constructor`. Only and
* `Extensions` are supported.
*/
INVALID_MANAGER_ARGUMENTS = "RMR0011",
/**
* There is a problem with the schema or you are trying to access a node /
* mark that doesn't exists.
*/
SCHEMA = "RMR0012",
/**
* The `helpers` method which is passed into the ``create*` method should only
* be called within returned method since it relies on an active view (not
* present in the outer scope).
*/
HELPERS_CALLED_IN_OUTER_SCOPE = "RMR0013",
/** The user requested an invalid extension from the manager. */
INVALID_MANAGER_EXTENSION = "RMR0014",
/** Command method names must be unique within the editor. */
DUPLICATE_COMMAND_NAMES = "RMR0016",
/** Helper method names must be unique within the editor. */
DUPLICATE_HELPER_NAMES = "RMR0017",
/** Attempted to chain a non chainable command. */
NON_CHAINABLE_COMMAND = "RMR0018",
/** The provided extension is invalid. */
INVALID_EXTENSION = "RMR0019",
/** The content provided to the editor is not supported. */
INVALID_CONTENT = "RMR0021",
/** An invalid name was used for the extension. */
INVALID_NAME = "RMR0050",
/** An error occurred within an extension. */
EXTENSION = "RMR0100",
/** The spec was defined without calling the `defaults`, `parse` or `dom` methods. */
EXTENSION_SPEC = "RMR0101",
/** Extra attributes must either be a string or an object. */
EXTENSION_EXTRA_ATTRIBUTES = "RMR0102",
/** A call to `extension.setOptions` was made with invalid keys. */
INVALID_SET_EXTENSION_OPTIONS = "RMR0103",
/**
* `useRemirror` was called outside of the remirror context. It can only be used
* within an active remirror context created by the `<Remirror />`.
*/
REACT_PROVIDER_CONTEXT = "RMR0200",
/**
* `getRootProps` has been called MULTIPLE times. It should only be called ONCE during render.
*/
REACT_GET_ROOT_PROPS = "RMR0201",
/**
* A problem occurred adding the editor view to the dom.
*/
REACT_EDITOR_VIEW = "RMR0202",
/**
* There is a problem with your controlled editor setup.
*/
REACT_CONTROLLED = "RMR0203",
/**
* Something went wrong with your custom ReactNodeView Component.
*/
REACT_NODE_VIEW = "RMR0204",
/**
* You attempted to call `getContext` provided by the `useRemirror` prop
* during the first render of the editor. This is not possible and should only
* be after the editor first mounts.
*/
REACT_GET_CONTEXT = "RMR0205",
/**
* An error occurred when rendering the react components.
*/
REACT_COMPONENTS = "RMR0206",
/**
* An error occurred within a remirror hook.
*/
REACT_HOOKS = "RMR0207",
/**
* There is something wrong with your i18n setup.
*/
I18N_CONTEXT = "RMR0300"
}
export { ErrorConstant }
export { ErrorConstant as ErrorConstant_alias_1 }
/**
* The priority of extension which determines what order it is loaded into the
* editor.
*
* @remarks
*
* Higher priority extension (higher numberic value) will ensure the extension
* has a higher preference in your editor. In the case where you load two
* identical extensions into your editor (same name, or same constructor), the
* extension with the higher priority is the one that will be loaded.
*
* The higher the numeric value the higher the priority. The priority can also
* be passed a number but naming things in this `enum` should help provide some
* context to the numbers.
*
* By default all extensions are created with a `ExtensionPriority.Default`.
*/
declare enum ExtensionPriority {
/**
* Use this **never** 😉
*/
Critical = 1000000,
/**
* A, like super duper, high priority.
*/
Highest = 100000,
/**
* The highest priority level that should be used in a publicly shared
* extension (to allow some wiggle room for downstream users overriding
* priorities).
*/
High = 10000,
/**
* A medium priority extension. This is typically all you need to take
* priority over built in extensions.
*/
Medium = 1000,
/**
* This is the **default** priority for most extensions.
*/
Default = 100,
/**
* This is the **default** priority for builtin behavior changing extensions.
*/
Low = 10,
/**
* This is useful for extensions that exist to be overridden.
*/
Lowest = 0
}
export { ExtensionPriority }
export { ExtensionPriority as ExtensionPriority_alias_1 }
/**
* The type for the extension tags..
*/
declare type ExtensionTag = Remirror.ExtensionTags & typeof BaseExtensionTag;
/**
* These are the default supported tag strings which help categorize different
* behaviors that extensions can exhibit.
*
* @remarks
*
* Any extension can register itself with multiple such behaviors and these
* categorizations can be used by other extensions when running commands and
* updating the document.
*/
declare const ExtensionTag: ExtensionTag;
export { ExtensionTag }
export { ExtensionTag as ExtensionTag_alias_1 }
/**
* The string values which can be used as extension tags.
*/
declare type ExtensionTagType = ExtensionTag[keyof ExtensionTag];
export { ExtensionTagType }
export { ExtensionTagType as ExtensionTagType_alias_1 }
/**
* ProseMirror uses the Unicode Character 'OBJECT REPLACEMENT CHARACTER'
* (U+FFFC) as text representation for leaf nodes, i.e. nodes that don't have
* any content or text property (e.g. hardBreak, emoji, mention, rule) It was
* introduced because of https://github.com/ProseMirror/prosemirror/issues/262
* This can be used in an input rule regex to be able to include or exclude such
* nodes.
*/
declare const LEAF_NODE_REPLACING_CHARACTER = "\uFFFC";
export { LEAF_NODE_REPLACING_CHARACTER }
export { LEAF_NODE_REPLACING_CHARACTER as LEAF_NODE_REPLACING_CHARACTER_alias_1 }
/**
* Identifies the stage the extension manager is at.
*/
declare enum ManagerPhase {
/**
* The initial value for the manager phase.
*/
None = 0,
/**
* When the extension manager is being created and the onCreate methods are
* being called.
*
* This happens within the RemirrorManager constructor.
*/
Create = 1,
/**
* When the view is being added and all `onView` lifecycle methods are being
* called. The view is typically added before the dom is ready for it.
*/
EditorView = 2,
/**
* The phases of creating this manager are completed and `onTransaction` is
* called every time the state updates.
*/
Runtime = 3,
/**
* The manager is being destroyed.
*/
Destroy = 4
}
export { ManagerPhase }
export { ManagerPhase as ManagerPhase_alias_1 }
/**
* A method for updating the extension tags.
*
* ```tsx
* import { ExtensionTag, mutateTag } from 'remirror';
*
* mutateTag((tag) => {
* tag.SuperCustom = 'superCustom';
* });
*
* declare global {
* namespace Remirror {
* interface ExtensionTag {
* SuperCustom: 'superCustom';
* }
* }
* }
*
*
* log(ExtensionTag.SuperCustom); // This is fine ✅
* log(ExtensionTag.NotDefined); // This will throw ❌
* ```
*/
declare function mutateTag(mutator: (Tag: ExtensionTag) => void): void;
export { mutateTag }
export { mutateTag as mutateTag_alias_1 }
/**
* The named shortcuts that can be used to update multiple commands.
*/
declare enum NamedShortcut {
Undo = "_|undo|_",
Redo = "_|redo|_",
Bold = "_|bold|_",
Italic = "_|italic|_",
Underline = "_|underline|_",
Strike = "_|strike|_",
Code = "_|code|_",
Paragraph = "_|paragraph|_",
H1 = "_|h1|_",
H2 = "_|h2|_",
H3 = "_|h3|_",
H4 = "_|h4|_",
H5 = "_|h5|_",
H6 = "_|h6|_",
TaskList = "_|task|_",
BulletList = "_|bullet|_",
OrderedList = "_|number|_",
Quote = "_|quote|_",
Divider = "_|divider|_",
Codeblock = "_|codeblock|_",
ClearFormatting = "_|clear|_",
Superscript = "_|sup|_",
Subscript = "_|sub|_",
LeftAlignment = "_|left-align|_",
CenterAlignment = "_|center-align|_",
RightAlignment = "_|right-align|_",
JustifyAlignment = "_|justify-align|_",
InsertLink = "_|link|_",
/** @deprecated */
Find = "_|find|_",
/** @deprecated */
FindBackwards = "_|find-backwards|_",
/** @deprecated */
FindReplace = "_|find-replace|_",
AddFootnote = "_|footnote|_",
AddComment = "_|comment|_",
ContextMenu = "_|context-menu|_",
IncreaseFontSize = "_|inc-font-size|_",
DecreaseFontSize = "_|dec-font-size|_",
IncreaseIndent = "_|indent|_",
DecreaseIndent = "_|dedent|_",
Shortcuts = "_|shortcuts|_",
Copy = "_|copy|_",
Cut = "_|cut|_",
Paste = "_|paste|_",
PastePlain = "_|paste-plain|_",
SelectAll = "_|select-all|_",
/**
* A keyboard shortcut to trigger formatting the current block.
*
* @defaultValue 'Alt-Shift-F' (Mac) | 'Shift-Ctrl-F' (PC)
*/
Format = "_|format|_"
}
export { NamedShortcut }
export { NamedShortcut as NamedShortcut_alias_1 }
/**
* The non breaking space character.
*/
declare const NON_BREAKING_SPACE_CHAR = "\u00A0";
export { NON_BREAKING_SPACE_CHAR }
export { NON_BREAKING_SPACE_CHAR as NON_BREAKING_SPACE_CHAR_alias_1 }
/**
* The null character.
*
* See {@link https://stackoverflow.com/a/6380172}
*/
declare const NULL_CHARACTER = "\0";
export { NULL_CHARACTER }
export { NULL_CHARACTER as NULL_CHARACTER_alias_1 }
/**
* The global name for the module exported by the remirror webview bundle.
*/
declare const REMIRROR_WEBVIEW_NAME = "$$__REMIRROR_WEBVIEW_BUNDLE__$$";
export { REMIRROR_WEBVIEW_NAME }
export { REMIRROR_WEBVIEW_NAME as REMIRROR_WEBVIEW_NAME_alias_1 }
/**
* These constants are stored on the `REMIRROR_IDENTIFIER_KEY` property of
* `remirror` related constructors and instances in order to identify them as
* being internal to Remirror.
*
* @remarks
*
* This helps to prevent issues around check types via `instanceof` which can
* lead to false negatives.
*
* @internal
*/
declare enum RemirrorIdentifier {
/**
* Identifies `PlainExtension`s.
*/
PlainExtension = "RemirrorPlainExtension",
/**
* Identifies `NodeExtension`s.
*/
NodeExtension = "RemirrorNodeExtension",
/**
* Identifies `MarkExtension`s.
*/
MarkExtension = "RemirrorMarkExtension",
/**
* Identifies `PlainExtensionConstructor`s.
*/
PlainExtensionConstructor = "RemirrorPlainExtensionConstructor",
/**
* Identifies `NodeExtensionConstructor`s.
*/
NodeExtensionConstructor = "RemirrorNodeExtensionConstructor",
/**
* Identifies `MarkExtensionConstructor`s.
*/
MarkExtensionConstructor = "RemirrorMarkExtensionConstructor",
/**
* The string used to identify an instance of the `Manager`
*/
Manager = "RemirrorManager",
/**
* The preset type identifier.
*/
Preset = "RemirrorPreset",
/**
* The preset type identifier.
*/
PresetConstructor = "RemirrorPresetConstructor"
}
export { RemirrorIdentifier }
export { RemirrorIdentifier as RemirrorIdentifier_alias_1 }
/**
* The css class added to a node that is selected.
*/
declare const SELECTED_NODE_CLASS_NAME = "ProseMirror-selectednode";
export { SELECTED_NODE_CLASS_NAME }
export { SELECTED_NODE_CLASS_NAME as SELECTED_NODE_CLASS_NAME_alias_1 }
/**
* The css selector for a selected node.
*/
declare const SELECTED_NODE_CLASS_SELECTOR: string;
export { SELECTED_NODE_CLASS_SELECTOR }
export { SELECTED_NODE_CLASS_SELECTOR as SELECTED_NODE_CLASS_SELECTOR_alias_1 }
/**
* Indicates that a state update was caused by an override and not via
* transactions or user commands.
*
* This is the case when `setContent` is called and for all `controlled` updates
* within a `react` editor instance.
*/
declare const STATE_OVERRIDE = "__state_override__";
export { STATE_OVERRIDE }
export { STATE_OVERRIDE as STATE_OVERRIDE_alias_1 }
/**
* A character useful for separating inline nodes.
*
* @remarks
* Typically used in decorations as follows.
*
* ```ts
* document.createTextNode(ZERO_WIDTH_SPACE_CHAR);
* ```
*
* This produces the html entity '8203'
*/
declare const ZERO_WIDTH_SPACE_CHAR = "\u200B";
export { ZERO_WIDTH_SPACE_CHAR }
export { ZERO_WIDTH_SPACE_CHAR as ZERO_WIDTH_SPACE_CHAR_alias_1 }
export { }
declare global {
namespace Remirror {
/**
* This interface is for extending the default `ExtensionTag`'s in your
* codebase with full type checking support.
*/
interface ExtensionTags {}
}
}

View File

@@ -0,0 +1,314 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
EMPTY_ARRAY: () => EMPTY_ARRAY,
EMPTY_NODE: () => EMPTY_NODE,
EMPTY_PARAGRAPH_NODE: () => EMPTY_PARAGRAPH_NODE,
ErrorConstant: () => ErrorConstant,
ExtensionPriority: () => ExtensionPriority,
ExtensionTag: () => ExtensionTag,
LEAF_NODE_REPLACING_CHARACTER: () => LEAF_NODE_REPLACING_CHARACTER,
ManagerPhase: () => ManagerPhase,
NON_BREAKING_SPACE_CHAR: () => NON_BREAKING_SPACE_CHAR,
NULL_CHARACTER: () => NULL_CHARACTER,
NamedShortcut: () => NamedShortcut,
REMIRROR_WEBVIEW_NAME: () => REMIRROR_WEBVIEW_NAME,
RemirrorIdentifier: () => RemirrorIdentifier,
SELECTED_NODE_CLASS_NAME: () => SELECTED_NODE_CLASS_NAME,
SELECTED_NODE_CLASS_SELECTOR: () => SELECTED_NODE_CLASS_SELECTOR,
STATE_OVERRIDE: () => STATE_OVERRIDE,
ZERO_WIDTH_SPACE_CHAR: () => ZERO_WIDTH_SPACE_CHAR,
__INTERNAL_REMIRROR_IDENTIFIER_KEY__: () => __INTERNAL_REMIRROR_IDENTIFIER_KEY__,
mutateTag: () => mutateTag
});
module.exports = __toCommonJS(src_exports);
// src/core-constants.ts
var SELECTED_NODE_CLASS_NAME = "ProseMirror-selectednode";
var SELECTED_NODE_CLASS_SELECTOR = ".".concat(SELECTED_NODE_CLASS_NAME);
var LEAF_NODE_REPLACING_CHARACTER = "\uFFFC";
var NULL_CHARACTER = "\0";
var STATE_OVERRIDE = "__state_override__";
var REMIRROR_WEBVIEW_NAME = "$$__REMIRROR_WEBVIEW_BUNDLE__$$";
var ZERO_WIDTH_SPACE_CHAR = "\u200B";
var NON_BREAKING_SPACE_CHAR = "\xA0";
var EMPTY_PARAGRAPH_NODE = {
type: "doc",
content: [
{
type: "paragraph"
}
]
};
var EMPTY_NODE = {
type: "doc",
content: []
};
function mutateTag(mutator) {
mutator(BaseExtensionTag);
}
var BaseExtensionTag = {
/**
* Describes a node that can be used as the last node of a document and
* doesn't need to have anything else rendered after itself.
*
* @remarks
*
* e.g. `paragraph`
*/
LastNodeCompatible: "lastNodeCompatible",
/**
* A mark that is used to change the formatting of the node it wraps.
*
* @remarks
*
* e.g. `bold`, `italic`
*/
FormattingMark: "formattingMark",
/**
* A node that formats text in a non-standard way.
*
* @remarks
*
* e.g. `codeBlock`, `heading`, `blockquote`
*/
FormattingNode: "formattingNode",
/**
* Identifies a node which has problems with cursor navigation.
*
* @remarks
*
* When this tag is added to an extension this will be picked up by
* behavioural extensions such as the NodeCursorExtension which makes hard to
* reach nodes reachable using keyboard arrows.
*/
NodeCursor: "nodeCursor",
/**
* Mark group for font styling (e.g. bold, italic, underline, superscript).
*/
FontStyle: "fontStyle",
/**
* Mark groups for links.
*/
Link: "link",
/**
* Mark groups for colors (text-color, background-color, etc).
*/
Color: "color",
/**
* Mark group for alignment.
*/
Alignment: "alignment",
/**
* Mark group for indentation.
*/
Indentation: "indentation",
/**
* Extension which affect the behaviour of the content. Can be nodes marks or
* plain.
*/
Behavior: "behavior",
/**
* Marks and nodes which contain code.
*/
Code: "code",
/**
* Whether this node is an inline node.
*
* - `text` is an inline node, but `paragraph` is a block node.
*/
InlineNode: "inline",
/**
* This is a node that can contain list items.
*/
ListContainerNode: "listContainer",
/**
* Tags the extension as a list item node which can be contained by
* [[`ExtensionTag.ListNode`]].
*/
ListItemNode: "listItemNode",
/**
* Sets this as a block level node.
*/
Block: "block",
/**
* @deprecate use `ExtensionTags.Block` instead.
*/
BlockNode: "block",
/**
* Set this as a text block
*/
TextBlock: "textBlock",
/**
* A tag that excludes this from input rules.
*/
ExcludeInputRules: "excludeFromInputRules",
/**
* A mark or node that can't be exited when at the end and beginning of the
* document with an arrow key or backspace key.
*/
PreventExits: "preventsExits",
/**
* Represents a media compatible node.
*/
Media: "media"
};
var ExtensionTag = BaseExtensionTag;
var __INTERNAL_REMIRROR_IDENTIFIER_KEY__ = Symbol.for("__remirror__");
var RemirrorIdentifier = /* @__PURE__ */ ((RemirrorIdentifier2) => {
RemirrorIdentifier2["PlainExtension"] = "RemirrorPlainExtension";
RemirrorIdentifier2["NodeExtension"] = "RemirrorNodeExtension";
RemirrorIdentifier2["MarkExtension"] = "RemirrorMarkExtension";
RemirrorIdentifier2["PlainExtensionConstructor"] = "RemirrorPlainExtensionConstructor";
RemirrorIdentifier2["NodeExtensionConstructor"] = "RemirrorNodeExtensionConstructor";
RemirrorIdentifier2["MarkExtensionConstructor"] = "RemirrorMarkExtensionConstructor";
RemirrorIdentifier2["Manager"] = "RemirrorManager";
RemirrorIdentifier2["Preset"] = "RemirrorPreset";
RemirrorIdentifier2["PresetConstructor"] = "RemirrorPresetConstructor";
return RemirrorIdentifier2;
})(RemirrorIdentifier || {});
var ExtensionPriority = /* @__PURE__ */ ((ExtensionPriority2) => {
ExtensionPriority2[ExtensionPriority2["Critical"] = 1e6] = "Critical";
ExtensionPriority2[ExtensionPriority2["Highest"] = 1e5] = "Highest";
ExtensionPriority2[ExtensionPriority2["High"] = 1e4] = "High";
ExtensionPriority2[ExtensionPriority2["Medium"] = 1e3] = "Medium";
ExtensionPriority2[ExtensionPriority2["Default"] = 100] = "Default";
ExtensionPriority2[ExtensionPriority2["Low"] = 10] = "Low";
ExtensionPriority2[ExtensionPriority2["Lowest"] = 0] = "Lowest";
return ExtensionPriority2;
})(ExtensionPriority || {});
var ManagerPhase = /* @__PURE__ */ ((ManagerPhase2) => {
ManagerPhase2[ManagerPhase2["None"] = 0] = "None";
ManagerPhase2[ManagerPhase2["Create"] = 1] = "Create";
ManagerPhase2[ManagerPhase2["EditorView"] = 2] = "EditorView";
ManagerPhase2[ManagerPhase2["Runtime"] = 3] = "Runtime";
ManagerPhase2[ManagerPhase2["Destroy"] = 4] = "Destroy";
return ManagerPhase2;
})(ManagerPhase || {});
var NamedShortcut = /* @__PURE__ */ ((NamedShortcut2) => {
NamedShortcut2["Undo"] = "_|undo|_";
NamedShortcut2["Redo"] = "_|redo|_";
NamedShortcut2["Bold"] = "_|bold|_";
NamedShortcut2["Italic"] = "_|italic|_";
NamedShortcut2["Underline"] = "_|underline|_";
NamedShortcut2["Strike"] = "_|strike|_";
NamedShortcut2["Code"] = "_|code|_";
NamedShortcut2["Paragraph"] = "_|paragraph|_";
NamedShortcut2["H1"] = "_|h1|_";
NamedShortcut2["H2"] = "_|h2|_";
NamedShortcut2["H3"] = "_|h3|_";
NamedShortcut2["H4"] = "_|h4|_";
NamedShortcut2["H5"] = "_|h5|_";
NamedShortcut2["H6"] = "_|h6|_";
NamedShortcut2["TaskList"] = "_|task|_";
NamedShortcut2["BulletList"] = "_|bullet|_";
NamedShortcut2["OrderedList"] = "_|number|_";
NamedShortcut2["Quote"] = "_|quote|_";
NamedShortcut2["Divider"] = "_|divider|_";
NamedShortcut2["Codeblock"] = "_|codeblock|_";
NamedShortcut2["ClearFormatting"] = "_|clear|_";
NamedShortcut2["Superscript"] = "_|sup|_";
NamedShortcut2["Subscript"] = "_|sub|_";
NamedShortcut2["LeftAlignment"] = "_|left-align|_";
NamedShortcut2["CenterAlignment"] = "_|center-align|_";
NamedShortcut2["RightAlignment"] = "_|right-align|_";
NamedShortcut2["JustifyAlignment"] = "_|justify-align|_";
NamedShortcut2["InsertLink"] = "_|link|_";
NamedShortcut2["Find"] = "_|find|_";
NamedShortcut2["FindBackwards"] = "_|find-backwards|_";
NamedShortcut2["FindReplace"] = "_|find-replace|_";
NamedShortcut2["AddFootnote"] = "_|footnote|_";
NamedShortcut2["AddComment"] = "_|comment|_";
NamedShortcut2["ContextMenu"] = "_|context-menu|_";
NamedShortcut2["IncreaseFontSize"] = "_|inc-font-size|_";
NamedShortcut2["DecreaseFontSize"] = "_|dec-font-size|_";
NamedShortcut2["IncreaseIndent"] = "_|indent|_";
NamedShortcut2["DecreaseIndent"] = "_|dedent|_";
NamedShortcut2["Shortcuts"] = "_|shortcuts|_";
NamedShortcut2["Copy"] = "_|copy|_";
NamedShortcut2["Cut"] = "_|cut|_";
NamedShortcut2["Paste"] = "_|paste|_";
NamedShortcut2["PastePlain"] = "_|paste-plain|_";
NamedShortcut2["SelectAll"] = "_|select-all|_";
NamedShortcut2["Format"] = "_|format|_";
return NamedShortcut2;
})(NamedShortcut || {});
var EMPTY_ARRAY = [];
// src/error-constants.ts
var ErrorConstant = /* @__PURE__ */ ((ErrorConstant2) => {
ErrorConstant2["UNKNOWN"] = "RMR0001";
ErrorConstant2["INVALID_COMMAND_ARGUMENTS"] = "RMR0002";
ErrorConstant2["CUSTOM"] = "RMR0003";
ErrorConstant2["CORE_HELPERS"] = "RMR0004";
ErrorConstant2["MUTATION"] = "RMR0005";
ErrorConstant2["INTERNAL"] = "RMR0006";
ErrorConstant2["MISSING_REQUIRED_EXTENSION"] = "RMR0007";
ErrorConstant2["MANAGER_PHASE_ERROR"] = "RMR0008";
ErrorConstant2["INVALID_GET_EXTENSION"] = "RMR0010";
ErrorConstant2["INVALID_MANAGER_ARGUMENTS"] = "RMR0011";
ErrorConstant2["SCHEMA"] = "RMR0012";
ErrorConstant2["HELPERS_CALLED_IN_OUTER_SCOPE"] = "RMR0013";
ErrorConstant2["INVALID_MANAGER_EXTENSION"] = "RMR0014";
ErrorConstant2["DUPLICATE_COMMAND_NAMES"] = "RMR0016";
ErrorConstant2["DUPLICATE_HELPER_NAMES"] = "RMR0017";
ErrorConstant2["NON_CHAINABLE_COMMAND"] = "RMR0018";
ErrorConstant2["INVALID_EXTENSION"] = "RMR0019";
ErrorConstant2["INVALID_CONTENT"] = "RMR0021";
ErrorConstant2["INVALID_NAME"] = "RMR0050";
ErrorConstant2["EXTENSION"] = "RMR0100";
ErrorConstant2["EXTENSION_SPEC"] = "RMR0101";
ErrorConstant2["EXTENSION_EXTRA_ATTRIBUTES"] = "RMR0102";
ErrorConstant2["INVALID_SET_EXTENSION_OPTIONS"] = "RMR0103";
ErrorConstant2["REACT_PROVIDER_CONTEXT"] = "RMR0200";
ErrorConstant2["REACT_GET_ROOT_PROPS"] = "RMR0201";
ErrorConstant2["REACT_EDITOR_VIEW"] = "RMR0202";
ErrorConstant2["REACT_CONTROLLED"] = "RMR0203";
ErrorConstant2["REACT_NODE_VIEW"] = "RMR0204";
ErrorConstant2["REACT_GET_CONTEXT"] = "RMR0205";
ErrorConstant2["REACT_COMPONENTS"] = "RMR0206";
ErrorConstant2["REACT_HOOKS"] = "RMR0207";
ErrorConstant2["I18N_CONTEXT"] = "RMR0300";
return ErrorConstant2;
})(ErrorConstant || {});
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
EMPTY_ARRAY,
EMPTY_NODE,
EMPTY_PARAGRAPH_NODE,
ErrorConstant,
ExtensionPriority,
ExtensionTag,
LEAF_NODE_REPLACING_CHARACTER,
ManagerPhase,
NON_BREAKING_SPACE_CHAR,
NULL_CHARACTER,
NamedShortcut,
REMIRROR_WEBVIEW_NAME,
RemirrorIdentifier,
SELECTED_NODE_CLASS_NAME,
SELECTED_NODE_CLASS_SELECTOR,
STATE_OVERRIDE,
ZERO_WIDTH_SPACE_CHAR,
__INTERNAL_REMIRROR_IDENTIFIER_KEY__,
mutateTag
});

View File

@@ -0,0 +1,20 @@
export { ErrorConstant_alias_1 as ErrorConstant } from './_tsup-dts-rollup';
export { mutateTag_alias_1 as mutateTag } from './_tsup-dts-rollup';
export { SELECTED_NODE_CLASS_NAME_alias_1 as SELECTED_NODE_CLASS_NAME } from './_tsup-dts-rollup';
export { SELECTED_NODE_CLASS_SELECTOR_alias_1 as SELECTED_NODE_CLASS_SELECTOR } from './_tsup-dts-rollup';
export { LEAF_NODE_REPLACING_CHARACTER_alias_1 as LEAF_NODE_REPLACING_CHARACTER } from './_tsup-dts-rollup';
export { NULL_CHARACTER_alias_1 as NULL_CHARACTER } from './_tsup-dts-rollup';
export { STATE_OVERRIDE_alias_1 as STATE_OVERRIDE } from './_tsup-dts-rollup';
export { REMIRROR_WEBVIEW_NAME_alias_1 as REMIRROR_WEBVIEW_NAME } from './_tsup-dts-rollup';
export { ZERO_WIDTH_SPACE_CHAR_alias_1 as ZERO_WIDTH_SPACE_CHAR } from './_tsup-dts-rollup';
export { NON_BREAKING_SPACE_CHAR_alias_1 as NON_BREAKING_SPACE_CHAR } from './_tsup-dts-rollup';
export { EMPTY_PARAGRAPH_NODE_alias_1 as EMPTY_PARAGRAPH_NODE } from './_tsup-dts-rollup';
export { EMPTY_NODE_alias_1 as EMPTY_NODE } from './_tsup-dts-rollup';
export { ExtensionTag_alias_1 as ExtensionTag } from './_tsup-dts-rollup';
export { ExtensionTagType_alias_1 as ExtensionTagType } from './_tsup-dts-rollup';
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY___alias_1 as __INTERNAL_REMIRROR_IDENTIFIER_KEY__ } from './_tsup-dts-rollup';
export { RemirrorIdentifier_alias_1 as RemirrorIdentifier } from './_tsup-dts-rollup';
export { ExtensionPriority_alias_1 as ExtensionPriority } from './_tsup-dts-rollup';
export { ManagerPhase_alias_1 as ManagerPhase } from './_tsup-dts-rollup';
export { NamedShortcut_alias_1 as NamedShortcut } from './_tsup-dts-rollup';
export { EMPTY_ARRAY_alias_1 as EMPTY_ARRAY } from './_tsup-dts-rollup';

View File

@@ -0,0 +1,20 @@
export { ErrorConstant_alias_1 as ErrorConstant } from './_tsup-dts-rollup';
export { mutateTag_alias_1 as mutateTag } from './_tsup-dts-rollup';
export { SELECTED_NODE_CLASS_NAME_alias_1 as SELECTED_NODE_CLASS_NAME } from './_tsup-dts-rollup';
export { SELECTED_NODE_CLASS_SELECTOR_alias_1 as SELECTED_NODE_CLASS_SELECTOR } from './_tsup-dts-rollup';
export { LEAF_NODE_REPLACING_CHARACTER_alias_1 as LEAF_NODE_REPLACING_CHARACTER } from './_tsup-dts-rollup';
export { NULL_CHARACTER_alias_1 as NULL_CHARACTER } from './_tsup-dts-rollup';
export { STATE_OVERRIDE_alias_1 as STATE_OVERRIDE } from './_tsup-dts-rollup';
export { REMIRROR_WEBVIEW_NAME_alias_1 as REMIRROR_WEBVIEW_NAME } from './_tsup-dts-rollup';
export { ZERO_WIDTH_SPACE_CHAR_alias_1 as ZERO_WIDTH_SPACE_CHAR } from './_tsup-dts-rollup';
export { NON_BREAKING_SPACE_CHAR_alias_1 as NON_BREAKING_SPACE_CHAR } from './_tsup-dts-rollup';
export { EMPTY_PARAGRAPH_NODE_alias_1 as EMPTY_PARAGRAPH_NODE } from './_tsup-dts-rollup';
export { EMPTY_NODE_alias_1 as EMPTY_NODE } from './_tsup-dts-rollup';
export { ExtensionTag_alias_1 as ExtensionTag } from './_tsup-dts-rollup';
export { ExtensionTagType_alias_1 as ExtensionTagType } from './_tsup-dts-rollup';
export { __INTERNAL_REMIRROR_IDENTIFIER_KEY___alias_1 as __INTERNAL_REMIRROR_IDENTIFIER_KEY__ } from './_tsup-dts-rollup';
export { RemirrorIdentifier_alias_1 as RemirrorIdentifier } from './_tsup-dts-rollup';
export { ExtensionPriority_alias_1 as ExtensionPriority } from './_tsup-dts-rollup';
export { ManagerPhase_alias_1 as ManagerPhase } from './_tsup-dts-rollup';
export { NamedShortcut_alias_1 as NamedShortcut } from './_tsup-dts-rollup';
export { EMPTY_ARRAY_alias_1 as EMPTY_ARRAY } from './_tsup-dts-rollup';

View File

@@ -0,0 +1,269 @@
// src/core-constants.ts
var SELECTED_NODE_CLASS_NAME = "ProseMirror-selectednode";
var SELECTED_NODE_CLASS_SELECTOR = ".".concat(SELECTED_NODE_CLASS_NAME);
var LEAF_NODE_REPLACING_CHARACTER = "\uFFFC";
var NULL_CHARACTER = "\0";
var STATE_OVERRIDE = "__state_override__";
var REMIRROR_WEBVIEW_NAME = "$$__REMIRROR_WEBVIEW_BUNDLE__$$";
var ZERO_WIDTH_SPACE_CHAR = "\u200B";
var NON_BREAKING_SPACE_CHAR = "\xA0";
var EMPTY_PARAGRAPH_NODE = {
type: "doc",
content: [
{
type: "paragraph"
}
]
};
var EMPTY_NODE = {
type: "doc",
content: []
};
function mutateTag(mutator) {
mutator(BaseExtensionTag);
}
var BaseExtensionTag = {
/**
* Describes a node that can be used as the last node of a document and
* doesn't need to have anything else rendered after itself.
*
* @remarks
*
* e.g. `paragraph`
*/
LastNodeCompatible: "lastNodeCompatible",
/**
* A mark that is used to change the formatting of the node it wraps.
*
* @remarks
*
* e.g. `bold`, `italic`
*/
FormattingMark: "formattingMark",
/**
* A node that formats text in a non-standard way.
*
* @remarks
*
* e.g. `codeBlock`, `heading`, `blockquote`
*/
FormattingNode: "formattingNode",
/**
* Identifies a node which has problems with cursor navigation.
*
* @remarks
*
* When this tag is added to an extension this will be picked up by
* behavioural extensions such as the NodeCursorExtension which makes hard to
* reach nodes reachable using keyboard arrows.
*/
NodeCursor: "nodeCursor",
/**
* Mark group for font styling (e.g. bold, italic, underline, superscript).
*/
FontStyle: "fontStyle",
/**
* Mark groups for links.
*/
Link: "link",
/**
* Mark groups for colors (text-color, background-color, etc).
*/
Color: "color",
/**
* Mark group for alignment.
*/
Alignment: "alignment",
/**
* Mark group for indentation.
*/
Indentation: "indentation",
/**
* Extension which affect the behaviour of the content. Can be nodes marks or
* plain.
*/
Behavior: "behavior",
/**
* Marks and nodes which contain code.
*/
Code: "code",
/**
* Whether this node is an inline node.
*
* - `text` is an inline node, but `paragraph` is a block node.
*/
InlineNode: "inline",
/**
* This is a node that can contain list items.
*/
ListContainerNode: "listContainer",
/**
* Tags the extension as a list item node which can be contained by
* [[`ExtensionTag.ListNode`]].
*/
ListItemNode: "listItemNode",
/**
* Sets this as a block level node.
*/
Block: "block",
/**
* @deprecate use `ExtensionTags.Block` instead.
*/
BlockNode: "block",
/**
* Set this as a text block
*/
TextBlock: "textBlock",
/**
* A tag that excludes this from input rules.
*/
ExcludeInputRules: "excludeFromInputRules",
/**
* A mark or node that can't be exited when at the end and beginning of the
* document with an arrow key or backspace key.
*/
PreventExits: "preventsExits",
/**
* Represents a media compatible node.
*/
Media: "media"
};
var ExtensionTag = BaseExtensionTag;
var __INTERNAL_REMIRROR_IDENTIFIER_KEY__ = Symbol.for("__remirror__");
var RemirrorIdentifier = /* @__PURE__ */ ((RemirrorIdentifier2) => {
RemirrorIdentifier2["PlainExtension"] = "RemirrorPlainExtension";
RemirrorIdentifier2["NodeExtension"] = "RemirrorNodeExtension";
RemirrorIdentifier2["MarkExtension"] = "RemirrorMarkExtension";
RemirrorIdentifier2["PlainExtensionConstructor"] = "RemirrorPlainExtensionConstructor";
RemirrorIdentifier2["NodeExtensionConstructor"] = "RemirrorNodeExtensionConstructor";
RemirrorIdentifier2["MarkExtensionConstructor"] = "RemirrorMarkExtensionConstructor";
RemirrorIdentifier2["Manager"] = "RemirrorManager";
RemirrorIdentifier2["Preset"] = "RemirrorPreset";
RemirrorIdentifier2["PresetConstructor"] = "RemirrorPresetConstructor";
return RemirrorIdentifier2;
})(RemirrorIdentifier || {});
var ExtensionPriority = /* @__PURE__ */ ((ExtensionPriority2) => {
ExtensionPriority2[ExtensionPriority2["Critical"] = 1e6] = "Critical";
ExtensionPriority2[ExtensionPriority2["Highest"] = 1e5] = "Highest";
ExtensionPriority2[ExtensionPriority2["High"] = 1e4] = "High";
ExtensionPriority2[ExtensionPriority2["Medium"] = 1e3] = "Medium";
ExtensionPriority2[ExtensionPriority2["Default"] = 100] = "Default";
ExtensionPriority2[ExtensionPriority2["Low"] = 10] = "Low";
ExtensionPriority2[ExtensionPriority2["Lowest"] = 0] = "Lowest";
return ExtensionPriority2;
})(ExtensionPriority || {});
var ManagerPhase = /* @__PURE__ */ ((ManagerPhase2) => {
ManagerPhase2[ManagerPhase2["None"] = 0] = "None";
ManagerPhase2[ManagerPhase2["Create"] = 1] = "Create";
ManagerPhase2[ManagerPhase2["EditorView"] = 2] = "EditorView";
ManagerPhase2[ManagerPhase2["Runtime"] = 3] = "Runtime";
ManagerPhase2[ManagerPhase2["Destroy"] = 4] = "Destroy";
return ManagerPhase2;
})(ManagerPhase || {});
var NamedShortcut = /* @__PURE__ */ ((NamedShortcut2) => {
NamedShortcut2["Undo"] = "_|undo|_";
NamedShortcut2["Redo"] = "_|redo|_";
NamedShortcut2["Bold"] = "_|bold|_";
NamedShortcut2["Italic"] = "_|italic|_";
NamedShortcut2["Underline"] = "_|underline|_";
NamedShortcut2["Strike"] = "_|strike|_";
NamedShortcut2["Code"] = "_|code|_";
NamedShortcut2["Paragraph"] = "_|paragraph|_";
NamedShortcut2["H1"] = "_|h1|_";
NamedShortcut2["H2"] = "_|h2|_";
NamedShortcut2["H3"] = "_|h3|_";
NamedShortcut2["H4"] = "_|h4|_";
NamedShortcut2["H5"] = "_|h5|_";
NamedShortcut2["H6"] = "_|h6|_";
NamedShortcut2["TaskList"] = "_|task|_";
NamedShortcut2["BulletList"] = "_|bullet|_";
NamedShortcut2["OrderedList"] = "_|number|_";
NamedShortcut2["Quote"] = "_|quote|_";
NamedShortcut2["Divider"] = "_|divider|_";
NamedShortcut2["Codeblock"] = "_|codeblock|_";
NamedShortcut2["ClearFormatting"] = "_|clear|_";
NamedShortcut2["Superscript"] = "_|sup|_";
NamedShortcut2["Subscript"] = "_|sub|_";
NamedShortcut2["LeftAlignment"] = "_|left-align|_";
NamedShortcut2["CenterAlignment"] = "_|center-align|_";
NamedShortcut2["RightAlignment"] = "_|right-align|_";
NamedShortcut2["JustifyAlignment"] = "_|justify-align|_";
NamedShortcut2["InsertLink"] = "_|link|_";
NamedShortcut2["Find"] = "_|find|_";
NamedShortcut2["FindBackwards"] = "_|find-backwards|_";
NamedShortcut2["FindReplace"] = "_|find-replace|_";
NamedShortcut2["AddFootnote"] = "_|footnote|_";
NamedShortcut2["AddComment"] = "_|comment|_";
NamedShortcut2["ContextMenu"] = "_|context-menu|_";
NamedShortcut2["IncreaseFontSize"] = "_|inc-font-size|_";
NamedShortcut2["DecreaseFontSize"] = "_|dec-font-size|_";
NamedShortcut2["IncreaseIndent"] = "_|indent|_";
NamedShortcut2["DecreaseIndent"] = "_|dedent|_";
NamedShortcut2["Shortcuts"] = "_|shortcuts|_";
NamedShortcut2["Copy"] = "_|copy|_";
NamedShortcut2["Cut"] = "_|cut|_";
NamedShortcut2["Paste"] = "_|paste|_";
NamedShortcut2["PastePlain"] = "_|paste-plain|_";
NamedShortcut2["SelectAll"] = "_|select-all|_";
NamedShortcut2["Format"] = "_|format|_";
return NamedShortcut2;
})(NamedShortcut || {});
var EMPTY_ARRAY = [];
// src/error-constants.ts
var ErrorConstant = /* @__PURE__ */ ((ErrorConstant2) => {
ErrorConstant2["UNKNOWN"] = "RMR0001";
ErrorConstant2["INVALID_COMMAND_ARGUMENTS"] = "RMR0002";
ErrorConstant2["CUSTOM"] = "RMR0003";
ErrorConstant2["CORE_HELPERS"] = "RMR0004";
ErrorConstant2["MUTATION"] = "RMR0005";
ErrorConstant2["INTERNAL"] = "RMR0006";
ErrorConstant2["MISSING_REQUIRED_EXTENSION"] = "RMR0007";
ErrorConstant2["MANAGER_PHASE_ERROR"] = "RMR0008";
ErrorConstant2["INVALID_GET_EXTENSION"] = "RMR0010";
ErrorConstant2["INVALID_MANAGER_ARGUMENTS"] = "RMR0011";
ErrorConstant2["SCHEMA"] = "RMR0012";
ErrorConstant2["HELPERS_CALLED_IN_OUTER_SCOPE"] = "RMR0013";
ErrorConstant2["INVALID_MANAGER_EXTENSION"] = "RMR0014";
ErrorConstant2["DUPLICATE_COMMAND_NAMES"] = "RMR0016";
ErrorConstant2["DUPLICATE_HELPER_NAMES"] = "RMR0017";
ErrorConstant2["NON_CHAINABLE_COMMAND"] = "RMR0018";
ErrorConstant2["INVALID_EXTENSION"] = "RMR0019";
ErrorConstant2["INVALID_CONTENT"] = "RMR0021";
ErrorConstant2["INVALID_NAME"] = "RMR0050";
ErrorConstant2["EXTENSION"] = "RMR0100";
ErrorConstant2["EXTENSION_SPEC"] = "RMR0101";
ErrorConstant2["EXTENSION_EXTRA_ATTRIBUTES"] = "RMR0102";
ErrorConstant2["INVALID_SET_EXTENSION_OPTIONS"] = "RMR0103";
ErrorConstant2["REACT_PROVIDER_CONTEXT"] = "RMR0200";
ErrorConstant2["REACT_GET_ROOT_PROPS"] = "RMR0201";
ErrorConstant2["REACT_EDITOR_VIEW"] = "RMR0202";
ErrorConstant2["REACT_CONTROLLED"] = "RMR0203";
ErrorConstant2["REACT_NODE_VIEW"] = "RMR0204";
ErrorConstant2["REACT_GET_CONTEXT"] = "RMR0205";
ErrorConstant2["REACT_COMPONENTS"] = "RMR0206";
ErrorConstant2["REACT_HOOKS"] = "RMR0207";
ErrorConstant2["I18N_CONTEXT"] = "RMR0300";
return ErrorConstant2;
})(ErrorConstant || {});
export {
EMPTY_ARRAY,
EMPTY_NODE,
EMPTY_PARAGRAPH_NODE,
ErrorConstant,
ExtensionPriority,
ExtensionTag,
LEAF_NODE_REPLACING_CHARACTER,
ManagerPhase,
NON_BREAKING_SPACE_CHAR,
NULL_CHARACTER,
NamedShortcut,
REMIRROR_WEBVIEW_NAME,
RemirrorIdentifier,
SELECTED_NODE_CLASS_NAME,
SELECTED_NODE_CLASS_SELECTOR,
STATE_OVERRIDE,
ZERO_WIDTH_SPACE_CHAR,
__INTERNAL_REMIRROR_IDENTIFIER_KEY__,
mutateTag
};

45
node_modules/@remirror/core-constants/package.json generated vendored Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "@remirror/core-constants",
"version": "3.0.0",
"description": "The core constants used throughout the remirror codebase",
"homepage": "https://github.com/remirror/remirror/tree/HEAD/packages/remirror__core-constants",
"repository": {
"type": "git",
"url": "https://github.com/remirror/remirror.git",
"directory": "packages/remirror__core-constants"
},
"license": "MIT",
"contributors": [
"Ifiok Jr. <ifiokotung@gmail.com>"
],
"sideEffects": false,
"type": "module",
"exports": {
".": {
"types": "./dist/remirror-core-constants.d.ts",
"import": "./dist/remirror-core-constants.js",
"require": "./dist/remirror-core-constants.cjs"
},
"./package.json": "./package.json"
},
"main": "./dist/remirror-core-constants.cjs",
"module": "./dist/remirror-core-constants.js",
"types": "./dist/remirror-core-constants.d.ts",
"files": [
"dist",
"dist-types"
],
"dependencies": {},
"devDependencies": {
"@remirror/cli": "1.1.0"
},
"publishConfig": {
"access": "public"
},
"@remirror": {
"sizeLimit": "2 KB"
},
"scripts": {
"build": "remirror-cli build"
}
}

17
node_modules/@remirror/core-constants/readme.md generated vendored Normal file
View File

@@ -0,0 +1,17 @@
# @remirror/core-constants
> core constants used throughout the `remirror` codebase.
[![Version][version]][npm] [![Weekly Downloads][downloads-badge]][npm] [![Bundled size][size-badge]][size] [![Typed Codebase][typescript]](#) [![MIT License][license]](#)
[version]: https://flat.badgen.net/npm/v/@remirror/core-constants
[npm]: https://npmjs.com/package/@remirror/core-constants
[license]: https://flat.badgen.net/badge/license/MIT/purple
[size]: https://bundlephobia.com/result?p=@remirror/core-constants
[size-badge]: https://flat.badgen.net/bundlephobia/minzip/@remirror/core-constants
[typescript]: https://flat.badgen.net/badge/icon/TypeScript?icon=typescript&label
[downloads-badge]: https://badgen.net/npm/dw/@remirror/core-constants/red?icon=npm
## Installation
This is included by default when you install the recommended `remirror` package. All exports are also available via `remirror/core/constants` and `remirror/core`.

21
node_modules/@tiptap/core/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025, Tiptap GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

18
node_modules/@tiptap/core/README.md generated vendored Normal file
View File

@@ -0,0 +1,18 @@
# @tiptap/core
[![Version](https://img.shields.io/npm/v/@tiptap/core.svg?label=version)](https://www.npmjs.com/package/@tiptap/core)
[![Downloads](https://img.shields.io/npm/dm/@tiptap/core.svg)](https://npmcharts.com/compare/tiptap?minimal=true)
[![License](https://img.shields.io/npm/l/@tiptap/core.svg)](https://www.npmjs.com/package/@tiptap/core)
[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis)
## Introduction
Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as _New York Times_, _The Guardian_ or _Atlassian_.
## Official Documentation
Documentation can be found on the [Tiptap website](https://tiptap.dev).
## License
Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).

7126
node_modules/@tiptap/core/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@tiptap/core/dist/index.cjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

4954
node_modules/@tiptap/core/dist/index.d.cts generated vendored Normal file

File diff suppressed because one or more lines are too long

4954
node_modules/@tiptap/core/dist/index.d.ts generated vendored Normal file

File diff suppressed because one or more lines are too long

6992
node_modules/@tiptap/core/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@tiptap/core/dist/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,56 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/jsx-runtime.ts
var jsx_runtime_exports = {};
__export(jsx_runtime_exports, {
Fragment: () => Fragment,
createElement: () => h,
h: () => h,
jsx: () => h,
jsxDEV: () => h,
jsxs: () => h
});
module.exports = __toCommonJS(jsx_runtime_exports);
function Fragment(props) {
return props.children;
}
var h = (tag, attributes) => {
if (tag === "slot") {
return 0;
}
if (tag instanceof Function) {
return tag(attributes);
}
const { children, ...rest } = attributes != null ? attributes : {};
if (tag === "svg") {
throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
}
return [tag, rest, children];
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Fragment,
createElement,
h,
jsx,
jsxDEV,
jsxs
});
//# sourceMappingURL=jsx-runtime.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../src/jsx-runtime.ts"],"sourcesContent":["export type Attributes = Record<string, any>\n\nexport type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray\n/**\n * Better describes the output of a `renderHTML` function in prosemirror\n * @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec\n */\nexport type DOMOutputSpecArray =\n | [string]\n | [string, Attributes]\n | [string, 0]\n | [string, Attributes, 0]\n | [string, Attributes, DOMOutputSpecArray | 0]\n | [string, DOMOutputSpecArray]\n\n// JSX types for Tiptap's JSX runtime\n// These types only apply when using @jsxImportSource @tiptap/core\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace JSX {\n export type Element = DOMOutputSpecArray\n export interface IntrinsicElements {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n }\n export interface ElementChildrenAttribute {\n children: unknown\n }\n}\n\nexport type JSXRenderer = (\n tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement),\n props?: Attributes,\n ...children: JSXRenderer[]\n) => DOMOutputSpecArray | DOMOutputSpecElement\n\nexport function Fragment(props: { children: JSXRenderer[] }) {\n return props.children\n}\n\nexport const h: JSXRenderer = (tag, attributes) => {\n // Treat the slot tag as the Prosemirror hole to render content into\n if (tag === 'slot') {\n return 0\n }\n\n // If the tag is a function, call it with the props\n if (tag instanceof Function) {\n return tag(attributes)\n }\n\n const { children, ...rest } = attributes ?? {}\n\n if (tag === 'svg') {\n throw new Error('SVG elements are not supported in the JSX syntax, use the array syntax instead')\n }\n\n // Otherwise, return the tag, attributes, and children\n return [tag, rest, children]\n}\n\n// See\n// https://esbuild.github.io/api/#jsx-import-source\n// https://www.typescriptlang.org/tsconfig/#jsxImportSource\n\nexport { h as createElement, h as jsx, h as jsxDEV, h as jsxs }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCO,SAAS,SAAS,OAAoC;AAC3D,SAAO,MAAM;AACf;AAEO,IAAM,IAAiB,CAAC,KAAK,eAAe;AAEjD,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AAGA,MAAI,eAAe,UAAU;AAC3B,WAAO,IAAI,UAAU;AAAA,EACvB;AAEA,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI,kCAAc,CAAC;AAE7C,MAAI,QAAQ,OAAO;AACjB,UAAM,IAAI,MAAM,gFAAgF;AAAA,EAClG;AAGA,SAAO,CAAC,KAAK,MAAM,QAAQ;AAC7B;","names":[]}

View File

@@ -0,0 +1,23 @@
type Attributes = Record<string, any>;
type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray;
/**
* Better describes the output of a `renderHTML` function in prosemirror
* @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec
*/
type DOMOutputSpecArray = [string] | [string, Attributes] | [string, 0] | [string, Attributes, 0] | [string, Attributes, DOMOutputSpecArray | 0] | [string, DOMOutputSpecArray];
declare namespace JSX {
type Element = DOMOutputSpecArray;
interface IntrinsicElements {
[key: string]: any;
}
interface ElementChildrenAttribute {
children: unknown;
}
}
type JSXRenderer = (tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement), props?: Attributes, ...children: JSXRenderer[]) => DOMOutputSpecArray | DOMOutputSpecElement;
declare function Fragment(props: {
children: JSXRenderer[];
}): JSXRenderer[];
declare const h: JSXRenderer;
export { type Attributes, type DOMOutputSpecArray, type DOMOutputSpecElement, Fragment, JSX, type JSXRenderer, h as createElement, h, h as jsx, h as jsxDEV, h as jsxs };

View File

@@ -0,0 +1,23 @@
type Attributes = Record<string, any>;
type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray;
/**
* Better describes the output of a `renderHTML` function in prosemirror
* @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec
*/
type DOMOutputSpecArray = [string] | [string, Attributes] | [string, 0] | [string, Attributes, 0] | [string, Attributes, DOMOutputSpecArray | 0] | [string, DOMOutputSpecArray];
declare namespace JSX {
type Element = DOMOutputSpecArray;
interface IntrinsicElements {
[key: string]: any;
}
interface ElementChildrenAttribute {
children: unknown;
}
}
type JSXRenderer = (tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement), props?: Attributes, ...children: JSXRenderer[]) => DOMOutputSpecArray | DOMOutputSpecElement;
declare function Fragment(props: {
children: JSXRenderer[];
}): JSXRenderer[];
declare const h: JSXRenderer;
export { type Attributes, type DOMOutputSpecArray, type DOMOutputSpecElement, Fragment, JSX, type JSXRenderer, h as createElement, h, h as jsx, h as jsxDEV, h as jsxs };

View File

@@ -0,0 +1,26 @@
// src/jsx-runtime.ts
function Fragment(props) {
return props.children;
}
var h = (tag, attributes) => {
if (tag === "slot") {
return 0;
}
if (tag instanceof Function) {
return tag(attributes);
}
const { children, ...rest } = attributes != null ? attributes : {};
if (tag === "svg") {
throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
}
return [tag, rest, children];
};
export {
Fragment,
h as createElement,
h,
h as jsx,
h as jsxDEV,
h as jsxs
};
//# sourceMappingURL=jsx-runtime.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../src/jsx-runtime.ts"],"sourcesContent":["export type Attributes = Record<string, any>\n\nexport type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray\n/**\n * Better describes the output of a `renderHTML` function in prosemirror\n * @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec\n */\nexport type DOMOutputSpecArray =\n | [string]\n | [string, Attributes]\n | [string, 0]\n | [string, Attributes, 0]\n | [string, Attributes, DOMOutputSpecArray | 0]\n | [string, DOMOutputSpecArray]\n\n// JSX types for Tiptap's JSX runtime\n// These types only apply when using @jsxImportSource @tiptap/core\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace JSX {\n export type Element = DOMOutputSpecArray\n export interface IntrinsicElements {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n }\n export interface ElementChildrenAttribute {\n children: unknown\n }\n}\n\nexport type JSXRenderer = (\n tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement),\n props?: Attributes,\n ...children: JSXRenderer[]\n) => DOMOutputSpecArray | DOMOutputSpecElement\n\nexport function Fragment(props: { children: JSXRenderer[] }) {\n return props.children\n}\n\nexport const h: JSXRenderer = (tag, attributes) => {\n // Treat the slot tag as the Prosemirror hole to render content into\n if (tag === 'slot') {\n return 0\n }\n\n // If the tag is a function, call it with the props\n if (tag instanceof Function) {\n return tag(attributes)\n }\n\n const { children, ...rest } = attributes ?? {}\n\n if (tag === 'svg') {\n throw new Error('SVG elements are not supported in the JSX syntax, use the array syntax instead')\n }\n\n // Otherwise, return the tag, attributes, and children\n return [tag, rest, children]\n}\n\n// See\n// https://esbuild.github.io/api/#jsx-import-source\n// https://www.typescriptlang.org/tsconfig/#jsxImportSource\n\nexport { h as createElement, h as jsx, h as jsxDEV, h as jsxs }\n"],"mappings":";AAmCO,SAAS,SAAS,OAAoC;AAC3D,SAAO,MAAM;AACf;AAEO,IAAM,IAAiB,CAAC,KAAK,eAAe;AAEjD,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AAGA,MAAI,eAAe,UAAU;AAC3B,WAAO,IAAI,UAAU;AAAA,EACvB;AAEA,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI,kCAAc,CAAC;AAE7C,MAAI,QAAQ,OAAO;AACjB,UAAM,IAAI,MAAM,gFAAgF;AAAA,EAClG;AAGA,SAAO,CAAC,KAAK,MAAM,QAAQ;AAC7B;","names":[]}

1
node_modules/@tiptap/core/jsx-dev-runtime/index.cjs generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('../dist/jsx-runtime/jsx-runtime.cjs')

View File

@@ -0,0 +1 @@
export * from '../src/jsx-runtime.ts'

1
node_modules/@tiptap/core/jsx-dev-runtime/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export type * from '../src/jsx-runtime.js'

1
node_modules/@tiptap/core/jsx-dev-runtime/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from '../dist/jsx-runtime/jsx-runtime.js'

1
node_modules/@tiptap/core/jsx-runtime/index.cjs generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('../dist/jsx-runtime/jsx-runtime.cjs')

1
node_modules/@tiptap/core/jsx-runtime/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from '../src/jsx-runtime.ts'

1
node_modules/@tiptap/core/jsx-runtime/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export type * from '../src/jsx-runtime.ts'

1
node_modules/@tiptap/core/jsx-runtime/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from '../dist/jsx-runtime/jsx-runtime.js'

70
node_modules/@tiptap/core/package.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "@tiptap/core",
"description": "headless rich text editor",
"version": "3.21.0",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
"headless",
"wysiwyg",
"text editor",
"prosemirror"
],
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"type": "module",
"exports": {
".": {
"types": {
"import": "./dist/index.d.ts",
"require": "./dist/index.d.cts"
},
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./jsx-runtime": {
"types": {
"import": "./jsx-runtime/index.d.ts",
"require": "./jsx-runtime/index.d.cts"
},
"import": "./jsx-runtime/index.js",
"require": "./jsx-runtime/index.cjs"
},
"./jsx-dev-runtime": {
"types": {
"import": "./jsx-dev-runtime/index.d.ts",
"require": "./jsx-dev-runtime/index.d.cts"
},
"import": "./jsx-dev-runtime/index.js",
"require": "./jsx-dev-runtime/index.cjs"
}
},
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"src",
"dist",
"jsx-runtime",
"jsx-dev-runtime"
],
"devDependencies": {
"@tiptap/pm": "^3.21.0"
},
"peerDependencies": {
"@tiptap/pm": "^3.21.0"
},
"repository": {
"type": "git",
"url": "https://github.com/ueberdosis/tiptap",
"directory": "packages/core"
},
"sideEffects": false,
"scripts": {
"build": "tsup",
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
}
}

138
node_modules/@tiptap/core/src/CommandManager.ts generated vendored Normal file
View File

@@ -0,0 +1,138 @@
import type { EditorState, Transaction } from '@tiptap/pm/state'
import type { Editor } from './Editor.js'
import { createChainableState } from './helpers/createChainableState.js'
import type { AnyCommands, CanCommands, ChainedCommands, CommandProps, SingleCommands } from './types.js'
export class CommandManager {
editor: Editor
rawCommands: AnyCommands
customState?: EditorState
constructor(props: { editor: Editor; state?: EditorState }) {
this.editor = props.editor
this.rawCommands = this.editor.extensionManager.commands
this.customState = props.state
}
get hasCustomState(): boolean {
return !!this.customState
}
get state(): EditorState {
return this.customState || this.editor.state
}
get commands(): SingleCommands {
const { rawCommands, editor, state } = this
const { view } = editor
const { tr } = state
const props = this.buildProps(tr)
return Object.fromEntries(
Object.entries(rawCommands).map(([name, command]) => {
const method = (...args: any[]) => {
const callback = command(...args)(props)
if (!tr.getMeta('preventDispatch') && !this.hasCustomState) {
view.dispatch(tr)
}
return callback
}
return [name, method]
}),
) as unknown as SingleCommands
}
get chain(): () => ChainedCommands {
return () => this.createChain()
}
get can(): () => CanCommands {
return () => this.createCan()
}
public createChain(startTr?: Transaction, shouldDispatch = true): ChainedCommands {
const { rawCommands, editor, state } = this
const { view } = editor
const callbacks: boolean[] = []
const hasStartTransaction = !!startTr
const tr = startTr || state.tr
const run = () => {
if (!hasStartTransaction && shouldDispatch && !tr.getMeta('preventDispatch') && !this.hasCustomState) {
view.dispatch(tr)
}
return callbacks.every(callback => callback === true)
}
const chain = {
...Object.fromEntries(
Object.entries(rawCommands).map(([name, command]) => {
const chainedCommand = (...args: never[]) => {
const props = this.buildProps(tr, shouldDispatch)
const callback = command(...args)(props)
callbacks.push(callback)
return chain
}
return [name, chainedCommand]
}),
),
run,
} as unknown as ChainedCommands
return chain
}
public createCan(startTr?: Transaction): CanCommands {
const { rawCommands, state } = this
const dispatch = false
const tr = startTr || state.tr
const props = this.buildProps(tr, dispatch)
const formattedCommands = Object.fromEntries(
Object.entries(rawCommands).map(([name, command]) => {
return [name, (...args: never[]) => command(...args)({ ...props, dispatch: undefined })]
}),
) as unknown as SingleCommands
return {
...formattedCommands,
chain: () => this.createChain(tr, dispatch),
} as CanCommands
}
public buildProps(tr: Transaction, shouldDispatch = true): CommandProps {
const { rawCommands, editor, state } = this
const { view } = editor
const props: CommandProps = {
tr,
editor,
view,
state: createChainableState({
state,
transaction: tr,
}),
dispatch: shouldDispatch ? () => undefined : undefined,
chain: () => this.createChain(tr, shouldDispatch),
can: () => this.createCan(tr),
get commands() {
return Object.fromEntries(
Object.entries(rawCommands).map(([name, command]) => {
return [name, (...args: never[]) => command(...args)(props)]
}),
) as unknown as SingleCommands
},
}
return props
}
}

806
node_modules/@tiptap/core/src/Editor.ts generated vendored Normal file
View File

@@ -0,0 +1,806 @@
/* eslint-disable @typescript-eslint/no-empty-object-type */
import type { MarkType, Node as ProseMirrorNode, NodeType, Schema } from '@tiptap/pm/model'
import type { Plugin, PluginKey, Transaction } from '@tiptap/pm/state'
import { EditorState } from '@tiptap/pm/state'
import { type DirectEditorProps, EditorView } from '@tiptap/pm/view'
import { CommandManager } from './CommandManager.js'
import { EventEmitter } from './EventEmitter.js'
import { ExtensionManager } from './ExtensionManager.js'
import {
ClipboardTextSerializer,
Commands,
Delete,
Drop,
Editable,
FocusEvents,
Keymap,
Paste,
Tabindex,
TextDirection,
} from './extensions/index.js'
import { createDocument } from './helpers/createDocument.js'
import { getAttributes } from './helpers/getAttributes.js'
import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'
import { getText } from './helpers/getText.js'
import { getTextSerializersFromSchema } from './helpers/getTextSerializersFromSchema.js'
import { isActive } from './helpers/isActive.js'
import { isNodeEmpty } from './helpers/isNodeEmpty.js'
import { createMappablePosition, getUpdatedPosition } from './helpers/MappablePosition.js'
import { resolveFocusPosition } from './helpers/resolveFocusPosition.js'
import type { Storage } from './index.js'
import { NodePos } from './NodePos.js'
import { style } from './style.js'
import type {
CanCommands,
ChainedCommands,
DocumentType,
EditorEvents,
EditorOptions,
NodeType as TNodeType,
SingleCommands,
TextSerializer,
TextType as TTextType,
Utils,
} from './types.js'
import { createStyleTag } from './utilities/createStyleTag.js'
import { isFunction } from './utilities/isFunction.js'
export * as extensions from './extensions/index.js'
// @ts-ignore
export interface TiptapEditorHTMLElement extends HTMLElement {
editor?: Editor
}
export class Editor extends EventEmitter<EditorEvents> {
private commandManager!: CommandManager
public extensionManager!: ExtensionManager
private css: HTMLStyleElement | null = null
private className = 'tiptap'
public schema!: Schema
private editorView: EditorView | null = null
public isFocused = false
private editorState!: EditorState
/**
* The editor is considered initialized after the `create` event has been emitted.
*/
public isInitialized = false
public extensionStorage: Storage = {} as Storage
/**
* A unique ID for this editor instance.
*/
public instanceId = Math.random().toString(36).slice(2, 9)
public options: EditorOptions = {
element: typeof document !== 'undefined' ? document.createElement('div') : null,
content: '',
injectCSS: true,
injectNonce: undefined,
extensions: [],
autofocus: false,
editable: true,
textDirection: undefined,
editorProps: {},
parseOptions: {},
coreExtensionOptions: {},
enableInputRules: true,
enablePasteRules: true,
enableCoreExtensions: true,
enableContentCheck: false,
emitContentError: false,
onBeforeCreate: () => null,
onCreate: () => null,
onMount: () => null,
onUnmount: () => null,
onUpdate: () => null,
onSelectionUpdate: () => null,
onTransaction: () => null,
onFocus: () => null,
onBlur: () => null,
onDestroy: () => null,
onContentError: ({ error }) => {
throw error
},
onPaste: () => null,
onDrop: () => null,
onDelete: () => null,
enableExtensionDispatchTransaction: true,
}
constructor(options: Partial<EditorOptions> = {}) {
super()
this.setOptions(options)
this.createExtensionManager()
this.createCommandManager()
this.createSchema()
this.on('beforeCreate', this.options.onBeforeCreate)
this.emit('beforeCreate', { editor: this })
this.on('mount', this.options.onMount)
this.on('unmount', this.options.onUnmount)
this.on('contentError', this.options.onContentError)
this.on('create', this.options.onCreate)
this.on('update', this.options.onUpdate)
this.on('selectionUpdate', this.options.onSelectionUpdate)
this.on('transaction', this.options.onTransaction)
this.on('focus', this.options.onFocus)
this.on('blur', this.options.onBlur)
this.on('destroy', this.options.onDestroy)
this.on('drop', ({ event, slice, moved }) => this.options.onDrop(event, slice, moved))
this.on('paste', ({ event, slice }) => this.options.onPaste(event, slice))
this.on('delete', this.options.onDelete)
const initialDoc = this.createDoc()
const selection = resolveFocusPosition(initialDoc, this.options.autofocus)
// Set editor state immediately, so that it's available independently from the view
this.editorState = EditorState.create({
doc: initialDoc,
schema: this.schema,
selection: selection || undefined,
})
if (this.options.element) {
this.mount(this.options.element)
}
}
/**
* Attach the editor to the DOM, creating a new editor view.
*/
public mount(el: NonNullable<EditorOptions['element']> & {}) {
if (typeof document === 'undefined') {
throw new Error(
`[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.`,
)
}
this.createView(el)
this.emit('mount', { editor: this })
if (this.css && !document.head.contains(this.css)) {
document.head.appendChild(this.css)
}
window.setTimeout(() => {
if (this.isDestroyed) {
return
}
if (this.options.autofocus !== false && this.options.autofocus !== null) {
this.commands.focus(this.options.autofocus)
}
this.emit('create', { editor: this })
this.isInitialized = true
}, 0)
}
/**
* Remove the editor from the DOM, but still allow remounting at a different point in time
*/
public unmount() {
if (this.editorView) {
// Cleanup our reference to prevent circular references which caused memory leaks
// @ts-ignore
const dom = this.editorView.dom as TiptapEditorHTMLElement
if (dom?.editor) {
delete dom.editor
}
this.editorView.destroy()
}
this.editorView = null
this.isInitialized = false
// Safely remove CSS element with fallback for test environments
// Only remove CSS if no other editors exist in the document after unmount
if (this.css && !document.querySelectorAll(`.${this.className}`).length) {
try {
if (typeof this.css.remove === 'function') {
this.css.remove()
} else if (this.css.parentNode) {
this.css.parentNode.removeChild(this.css)
}
} catch (error) {
// Silently handle any unexpected DOM removal errors in test environments
console.warn('Failed to remove CSS element:', error)
}
}
this.css = null
this.emit('unmount', { editor: this })
}
/**
* Returns the editor storage.
*/
public get storage(): Storage {
return this.extensionStorage
}
/**
* An object of all registered commands.
*/
public get commands(): SingleCommands {
return this.commandManager.commands
}
/**
* Create a command chain to call multiple commands at once.
*/
public chain(): ChainedCommands {
return this.commandManager.chain()
}
/**
* Check if a command or a command chain can be executed. Without executing it.
*/
public can(): CanCommands {
return this.commandManager.can()
}
/**
* Inject CSS styles.
*/
private injectCSS(): void {
if (this.options.injectCSS && typeof document !== 'undefined') {
this.css = createStyleTag(style, this.options.injectNonce)
}
}
/**
* Update editor options.
*
* @param options A list of options
*/
public setOptions(options: Partial<EditorOptions> = {}): void {
this.options = {
...this.options,
...options,
}
if (!this.editorView || !this.state || this.isDestroyed) {
return
}
if (this.options.editorProps) {
this.view.setProps(this.options.editorProps)
}
this.view.updateState(this.state)
}
/**
* Update editable state of the editor.
*/
public setEditable(editable: boolean, emitUpdate = true): void {
this.setOptions({ editable })
if (emitUpdate) {
this.emit('update', { editor: this, transaction: this.state.tr, appendedTransactions: [] })
}
}
/**
* Returns whether the editor is editable.
*/
public get isEditable(): boolean {
// since plugins are applied after creating the view
// `editable` is always `true` for one tick.
// thats why we also have to check for `options.editable`
return this.options.editable && this.view && this.view.editable
}
/**
* Returns the editor view.
*/
public get view(): EditorView {
if (this.editorView) {
return this.editorView
}
return new Proxy(
{
state: this.editorState,
updateState: (state: EditorState): ReturnType<EditorView['updateState']> => {
this.editorState = state
},
dispatch: (tr: Transaction): ReturnType<EditorView['dispatch']> => {
this.dispatchTransaction(tr)
},
// Stub some commonly accessed properties to prevent errors
composing: false,
dragging: null,
editable: true,
isDestroyed: false,
} as EditorView,
{
get: (obj, key) => {
if (this.editorView) {
// If the editor view is available, but the caller has a stale reference to the proxy,
// Just return what the editor view has.
return this.editorView[key as keyof EditorView]
}
// Specifically always return the most recent editorState
if (key === 'state') {
return this.editorState
}
if (key in obj) {
return Reflect.get(obj, key)
}
// We throw an error here, because we know the view is not available
throw new Error(
`[tiptap error]: The editor view is not available. Cannot access view['${key as string}']. The editor may not be mounted yet.`,
)
},
},
) as EditorView
}
/**
* Returns the editor state.
*/
public get state(): EditorState {
if (this.editorView) {
this.editorState = this.view.state
}
return this.editorState
}
/**
* Register a ProseMirror plugin.
*
* @param plugin A ProseMirror plugin
* @param handlePlugins Control how to merge the plugin into the existing plugins.
* @returns The new editor state
*/
public registerPlugin(
plugin: Plugin,
handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],
): EditorState {
const plugins = isFunction(handlePlugins)
? handlePlugins(plugin, [...this.state.plugins])
: [...this.state.plugins, plugin]
const state = this.state.reconfigure({ plugins })
this.view.updateState(state)
return state
}
/**
* Unregister a ProseMirror plugin.
*
* @param nameOrPluginKeyToRemove The plugins name
* @returns The new editor state or undefined if the editor is destroyed
*/
public unregisterPlugin(
nameOrPluginKeyToRemove: string | PluginKey | (string | PluginKey)[],
): EditorState | undefined {
if (this.isDestroyed) {
return undefined
}
const prevPlugins = this.state.plugins
let plugins = prevPlugins
;([] as (string | PluginKey)[]).concat(nameOrPluginKeyToRemove).forEach(nameOrPluginKey => {
// @ts-ignore
const name = typeof nameOrPluginKey === 'string' ? `${nameOrPluginKey}$` : nameOrPluginKey.key
// @ts-ignore
plugins = plugins.filter(plugin => !plugin.key.startsWith(name))
})
if (prevPlugins.length === plugins.length) {
// No plugin was removed, so we dont need to update the state
return undefined
}
const state = this.state.reconfigure({
plugins,
})
this.view.updateState(state)
return state
}
/**
* Creates an extension manager.
*/
private createExtensionManager(): void {
const coreExtensions = this.options.enableCoreExtensions
? [
Editable,
ClipboardTextSerializer.configure({
blockSeparator: this.options.coreExtensionOptions?.clipboardTextSerializer?.blockSeparator,
}),
Commands,
FocusEvents,
Keymap,
Tabindex,
Drop,
Paste,
Delete,
TextDirection.configure({
direction: this.options.textDirection,
}),
].filter(ext => {
if (typeof this.options.enableCoreExtensions === 'object') {
return (
this.options.enableCoreExtensions[ext.name as keyof typeof this.options.enableCoreExtensions] !== false
)
}
return true
})
: []
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
return ['extension', 'node', 'mark'].includes(extension?.type)
})
this.extensionManager = new ExtensionManager(allExtensions, this)
}
/**
* Creates an command manager.
*/
private createCommandManager(): void {
this.commandManager = new CommandManager({
editor: this,
})
}
/**
* Creates a ProseMirror schema.
*/
private createSchema(): void {
this.schema = this.extensionManager.schema
}
/**
* Creates the initial document.
*/
private createDoc(): ProseMirrorNode {
let doc: ProseMirrorNode
try {
doc = createDocument(this.options.content, this.schema, this.options.parseOptions, {
errorOnInvalidContent: this.options.enableContentCheck,
})
} catch (e) {
if (
!(e instanceof Error) ||
!['[tiptap error]: Invalid JSON content', '[tiptap error]: Invalid HTML content'].includes(e.message)
) {
// Not the content error we were expecting
throw e
}
this.emit('contentError', {
editor: this,
error: e as Error,
disableCollaboration: () => {
if (
'collaboration' in this.storage &&
typeof this.storage.collaboration === 'object' &&
this.storage.collaboration
) {
;(this.storage.collaboration as any).isDisabled = true
}
// To avoid syncing back invalid content, reinitialize the extensions without the collaboration extension
this.options.extensions = this.options.extensions.filter(extension => extension.name !== 'collaboration')
// Restart the initialization process by recreating the extension manager with the new set of extensions
this.createExtensionManager()
},
})
// Content is invalid, but attempt to create it anyway, stripping out the invalid parts
doc = createDocument(this.options.content, this.schema, this.options.parseOptions, {
errorOnInvalidContent: false,
})
}
return doc
}
/**
* Creates a ProseMirror view.
*/
private createView(element: NonNullable<EditorOptions['element']>): void {
const { editorProps, enableExtensionDispatchTransaction } = this.options
// If a user provided a custom `dispatchTransaction` through `editorProps`,
// we use that as the base dispatch function.
// Otherwise, we use Tiptap's internal `dispatchTransaction` method.
const baseDispatch = (editorProps as DirectEditorProps).dispatchTransaction || this.dispatchTransaction.bind(this)
const dispatch = enableExtensionDispatchTransaction
? this.extensionManager.dispatchTransaction(baseDispatch)
: baseDispatch
// Compose transformPastedHTML from extensions and user-provided editorProps
const baseTransformPastedHTML = (editorProps as DirectEditorProps).transformPastedHTML
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML)
this.editorView = new EditorView(element, {
...editorProps,
attributes: {
// add `role="textbox"` to the editor element
role: 'textbox',
...editorProps?.attributes,
},
dispatchTransaction: dispatch,
transformPastedHTML,
state: this.editorState,
markViews: this.extensionManager.markViews,
nodeViews: this.extensionManager.nodeViews,
})
// `editor.view` is not yet available at this time.
// Therefore we will add all plugins and node views directly afterwards.
const newState = this.state.reconfigure({
plugins: this.extensionManager.plugins,
})
this.view.updateState(newState)
this.prependClass()
this.injectCSS()
// Lets store the editor instance in the DOM element.
// So well have access to it for tests.
// @ts-ignore
const dom = this.view.dom as TiptapEditorHTMLElement
dom.editor = this
}
/**
* Creates all node and mark views.
*/
public createNodeViews(): void {
if (this.view.isDestroyed) {
return
}
this.view.setProps({
markViews: this.extensionManager.markViews,
nodeViews: this.extensionManager.nodeViews,
})
}
/**
* Prepend class name to element.
*/
public prependClass(): void {
this.view.dom.className = `${this.className} ${this.view.dom.className}`
}
public isCapturingTransaction = false
private capturedTransaction: Transaction | null = null
public captureTransaction(fn: () => void) {
this.isCapturingTransaction = true
fn()
this.isCapturingTransaction = false
const tr = this.capturedTransaction
this.capturedTransaction = null
return tr
}
/**
* The callback over which to send transactions (state updates) produced by the view.
*
* @param transaction An editor state transaction
*/
private dispatchTransaction(transaction: Transaction): void {
// if the editor / the view of the editor was destroyed
// the transaction should not be dispatched as there is no view anymore.
if (this.view.isDestroyed) {
return
}
if (this.isCapturingTransaction) {
if (!this.capturedTransaction) {
this.capturedTransaction = transaction
return
}
transaction.steps.forEach(step => this.capturedTransaction?.step(step))
return
}
// Apply transaction and get resulting state and transactions
const { state, transactions } = this.state.applyTransaction(transaction)
const selectionHasChanged = !this.state.selection.eq(state.selection)
const rootTrWasApplied = transactions.includes(transaction)
const prevState = this.state
this.emit('beforeTransaction', {
editor: this,
transaction,
nextState: state,
})
// If transaction was filtered out, we can return early
if (!rootTrWasApplied) {
return
}
this.view.updateState(state)
// Emit transaction event with appended transactions info
this.emit('transaction', {
editor: this,
transaction,
appendedTransactions: transactions.slice(1),
})
if (selectionHasChanged) {
this.emit('selectionUpdate', {
editor: this,
transaction,
})
}
// Only emit the latest between focus and blur events
const mostRecentFocusTr = transactions.findLast(tr => tr.getMeta('focus') || tr.getMeta('blur'))
const focus = mostRecentFocusTr?.getMeta('focus')
const blur = mostRecentFocusTr?.getMeta('blur')
if (focus) {
this.emit('focus', {
editor: this,
event: focus.event,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
transaction: mostRecentFocusTr!,
})
}
if (blur) {
this.emit('blur', {
editor: this,
event: blur.event,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
transaction: mostRecentFocusTr!,
})
}
// Compare states for update event
if (
transaction.getMeta('preventUpdate') ||
!transactions.some(tr => tr.docChanged) ||
prevState.doc.eq(state.doc)
) {
return
}
this.emit('update', {
editor: this,
transaction,
appendedTransactions: transactions.slice(1),
})
}
/**
* Get attributes of the currently selected node or mark.
*/
public getAttributes(nameOrType: string | NodeType | MarkType): Record<string, any> {
return getAttributes(this.state, nameOrType)
}
/**
* Returns if the currently selected node or mark is active.
*
* @param name Name of the node or mark
* @param attributes Attributes of the node or mark
*/
public isActive(name: string, attributes?: {}): boolean
public isActive(attributes: {}): boolean
public isActive(nameOrAttributes: string, attributesOrUndefined?: {}): boolean {
const name = typeof nameOrAttributes === 'string' ? nameOrAttributes : null
const attributes = typeof nameOrAttributes === 'string' ? attributesOrUndefined : nameOrAttributes
return isActive(this.state, name, attributes)
}
/**
* Get the document as JSON.
*/
public getJSON(): DocumentType<
Record<string, any> | undefined,
TNodeType<string, undefined | Record<string, any>, any, (TNodeType | TTextType)[]>[]
> {
return this.state.doc.toJSON()
}
/**
* Get the document as HTML.
*/
public getHTML(): string {
return getHTMLFromFragment(this.state.doc.content, this.schema)
}
/**
* Get the document as text.
*/
public getText(options?: { blockSeparator?: string; textSerializers?: Record<string, TextSerializer> }): string {
const { blockSeparator = '\n\n', textSerializers = {} } = options || {}
return getText(this.state.doc, {
blockSeparator,
textSerializers: {
...getTextSerializersFromSchema(this.schema),
...textSerializers,
},
})
}
/**
* Check if there is no content.
*/
public get isEmpty(): boolean {
return isNodeEmpty(this.state.doc)
}
/**
* Destroy the editor.
*/
public destroy(): void {
this.emit('destroy')
this.unmount()
this.removeAllListeners()
}
/**
* Check if the editor is already destroyed.
*/
public get isDestroyed(): boolean {
return this.editorView?.isDestroyed ?? true
}
public $node(selector: string, attributes?: { [key: string]: any }): NodePos | null {
return this.$doc?.querySelector(selector, attributes) || null
}
public $nodes(selector: string, attributes?: { [key: string]: any }): NodePos[] | null {
return this.$doc?.querySelectorAll(selector, attributes) || null
}
public $pos(pos: number) {
const $pos = this.state.doc.resolve(pos)
return new NodePos($pos, this)
}
get $doc() {
return this.$pos(0)
}
/**
* Returns a set of utilities for working with positions and ranges.
*/
public utils: Utils = {
getUpdatedPosition,
createMappablePosition,
}
}

58
node_modules/@tiptap/core/src/EventEmitter.ts generated vendored Normal file
View File

@@ -0,0 +1,58 @@
type StringKeyOf<T> = Extract<keyof T, string>
type CallbackType<T extends Record<string, any>, EventName extends StringKeyOf<T>> = T[EventName] extends any[]
? T[EventName]
: [T[EventName]]
type CallbackFunction<T extends Record<string, any>, EventName extends StringKeyOf<T>> = (
...props: CallbackType<T, EventName>
) => any
export class EventEmitter<T extends Record<string, any>> {
private callbacks: { [key: string]: Array<(...args: any[]) => void> } = {}
public on<EventName extends StringKeyOf<T>>(event: EventName, fn: CallbackFunction<T, EventName>): this {
if (!this.callbacks[event]) {
this.callbacks[event] = []
}
this.callbacks[event].push(fn)
return this
}
public emit<EventName extends StringKeyOf<T>>(event: EventName, ...args: CallbackType<T, EventName>): this {
const callbacks = this.callbacks[event]
if (callbacks) {
callbacks.forEach(callback => callback.apply(this, args))
}
return this
}
public off<EventName extends StringKeyOf<T>>(event: EventName, fn?: CallbackFunction<T, EventName>): this {
const callbacks = this.callbacks[event]
if (callbacks) {
if (fn) {
this.callbacks[event] = callbacks.filter(callback => callback !== fn)
} else {
delete this.callbacks[event]
}
}
return this
}
public once<EventName extends StringKeyOf<T>>(event: EventName, fn: CallbackFunction<T, EventName>): this {
const onceFn = (...args: CallbackType<T, EventName>) => {
this.off(event, onceFn)
fn.apply(this, args)
}
return this.on(event, onceFn)
}
public removeAllListeners(): void {
this.callbacks = {}
}
}

602
node_modules/@tiptap/core/src/Extendable.ts generated vendored Normal file
View File

@@ -0,0 +1,602 @@
import type { Plugin } from '@tiptap/pm/state'
import type { Editor } from './Editor.js'
import { getExtensionField } from './helpers/getExtensionField.js'
import type { ExtensionConfig, MarkConfig, NodeConfig } from './index.js'
import type { InputRule } from './InputRule.js'
import type { Mark } from './Mark.js'
import type { Node } from './Node.js'
import type { PasteRule } from './PasteRule.js'
import type {
AnyConfig,
DispatchTransactionProps,
EditorEvents,
Extensions,
GlobalAttributes,
JSONContent,
KeyboardShortcutCommand,
MarkdownParseHelpers,
MarkdownParseResult,
MarkdownRendererHelpers,
MarkdownToken,
MarkdownTokenizer,
ParentConfig,
RawCommands,
RenderContext,
} from './types.js'
import { callOrReturn } from './utilities/callOrReturn.js'
import { mergeDeep } from './utilities/mergeDeep.js'
export interface ExtendableConfig<
Options = any,
Storage = any,
Config extends
| ExtensionConfig<Options, Storage>
| NodeConfig<Options, Storage>
| MarkConfig<Options, Storage>
| ExtendableConfig<Options, Storage> = ExtendableConfig<Options, Storage, any, any>,
PMType = any,
> {
/**
* The extension name - this must be unique.
* It will be used to identify the extension.
*
* @example 'myExtension'
*/
name: string
/**
* The priority of your extension. The higher, the earlier it will be called
* and will take precedence over other extensions with a lower priority.
* @default 100
* @example 101
*/
priority?: number
/**
* This method will add options to this extension
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#settings
* @example
* addOptions() {
* return {
* myOption: 'foo',
* myOtherOption: 10,
* }
*/
addOptions?: (this: { name: string; parent: ParentConfig<Config>['addOptions'] }) => Options
/**
* The default storage this extension can save data to.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#storage
* @example
* defaultStorage: {
* prefetchedUsers: [],
* loading: false,
* }
*/
addStorage?: (this: { name: string; options: Options; parent: ParentConfig<Config>['addStorage'] }) => Storage
/**
* This function adds globalAttributes to specific nodes.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#global-attributes
* @example
* addGlobalAttributes() {
* return [
* {
// Extend the following extensions
* types: [
* 'heading',
* 'paragraph',
* ],
* // … with those attributes
* attributes: {
* textAlign: {
* default: 'left',
* renderHTML: attributes => ({
* style: `text-align: ${attributes.textAlign}`,
* }),
* parseHTML: element => element.style.textAlign || 'left',
* },
* },
* },
* ]
* }
*/
addGlobalAttributes?: (this: {
name: string
options: Options
storage: Storage
extensions: (Node | Mark)[]
parent: ParentConfig<Config>['addGlobalAttributes']
}) => GlobalAttributes
/**
* This function adds commands to the editor
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#commands
* @example
* addCommands() {
* return {
* myCommand: () => ({ chain }) => chain().setMark('type', 'foo').run(),
* }
* }
*/
addCommands?: (this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['addCommands']
}) => Partial<RawCommands>
/**
* This function registers keyboard shortcuts.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#keyboard-shortcuts
* @example
* addKeyboardShortcuts() {
* return {
* 'Mod-l': () => this.editor.commands.toggleBulletList(),
* }
* },
*/
addKeyboardShortcuts?: (this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['addKeyboardShortcuts']
}) => {
[key: string]: KeyboardShortcutCommand
}
/**
* This function adds input rules to the editor.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#input-rules
* @example
* addInputRules() {
* return [
* markInputRule({
* find: inputRegex,
* type: this.type,
* }),
* ]
* },
*/
addInputRules?: (this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['addInputRules']
}) => InputRule[]
/**
* This function adds paste rules to the editor.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#paste-rules
* @example
* addPasteRules() {
* return [
* markPasteRule({
* find: pasteRegex,
* type: this.type,
* }),
* ]
* },
*/
addPasteRules?: (this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['addPasteRules']
}) => PasteRule[]
/**
* This function adds Prosemirror plugins to the editor
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#prosemirror-plugins
* @example
* addProseMirrorPlugins() {
* return [
* customPlugin(),
* ]
* }
*/
addProseMirrorPlugins?: (this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['addProseMirrorPlugins']
}) => Plugin[]
/**
* This function transforms pasted HTML content before it's parsed.
* Extensions can use this to modify or clean up pasted HTML.
* The transformations are chained - each extension's transform receives
* the output from the previous extension's transform.
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#transform-pasted-html
* @example
* transformPastedHTML(html) {
* // Remove all style attributes
* return html.replace(/style="[^"]*"/g, '')
* }
*/
transformPastedHTML?: (
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['transformPastedHTML']
},
html: string,
) => string
/**
* This function adds additional extensions to the editor. This is useful for
* building extension kits.
* @example
* addExtensions() {
* return [
* BulletList,
* OrderedList,
* ListItem
* ]
* }
*/
addExtensions?: (this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<Config>['addExtensions']
}) => Extensions
/**
* The markdown token name
*
* This is the name of the token that this extension uses to parse and render markdown and comes from the Marked Lexer.
*
* @see https://github.com/markedjs/marked/blob/master/src/Tokens.ts
*
*/
markdownTokenName?: string
/**
* The parse function used by the markdown parser to convert markdown tokens to ProseMirror nodes.
*/
parseMarkdown?: (token: MarkdownToken, helpers: MarkdownParseHelpers) => MarkdownParseResult
/**
* The serializer function used by the markdown serializer to convert ProseMirror nodes to markdown tokens.
*/
renderMarkdown?: (node: JSONContent, helpers: MarkdownRendererHelpers, ctx: RenderContext) => string
/**
* The markdown tokenizer responsible for turning a markdown string into tokens
*
* Custom tokenizers are only needed when you want to parse non-standard markdown token.
*/
markdownTokenizer?: MarkdownTokenizer
/**
* Optional markdown options for indentation
*/
markdownOptions?: {
/**
* Defines if this markdown element should indent it's child elements
*/
indentsContent?: boolean
/**
* Lets a mark tell the Markdown serializer which inline HTML tags it can
* safely use when plain markdown delimiters would become ambiguous.
*
* This is mainly useful for overlapping marks. For example, bold followed
* by bold+italic followed by italic cannot always be written back with only
* `*` and `**` in a way that still parses correctly. In that case, the
* serializer can close the overlapping section with markdown and reopen the
* remaining tail with HTML instead.
*
* Example:
* - desired formatting: `**123` + `*456*` + `789 italic`
* - serialized result: `**123*456***<em>789</em>`
*
* If your extension defines custom mark names, set `htmlReopen` on that
* extension so the serializer can reuse its HTML form for overlap cases.
*/
htmlReopen?: {
open: string
close: string
}
}
/**
* This function extends the schema of the node.
* @example
* extendNodeSchema() {
* return {
* group: 'inline',
* selectable: false,
* }
* }
*/
extendNodeSchema?:
| ((
this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<Config>['extendNodeSchema']
},
extension: Node,
) => Record<string, any>)
| null
/**
* This function extends the schema of the mark.
* @example
* extendMarkSchema() {
* return {
* group: 'inline',
* selectable: false,
* }
* }
*/
extendMarkSchema?:
| ((
this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<Config>['extendMarkSchema']
},
extension: Mark,
) => Record<string, any>)
| null
/**
* The editor is not ready yet.
*/
onBeforeCreate?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onBeforeCreate']
},
event: EditorEvents['beforeCreate'],
) => void)
| null
/**
* The editor is ready.
*/
onCreate?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onCreate']
},
event: EditorEvents['create'],
) => void)
| null
/**
* The content has changed.
*/
onUpdate?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onUpdate']
},
event: EditorEvents['update'],
) => void)
| null
/**
* The selection has changed.
*/
onSelectionUpdate?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onSelectionUpdate']
},
event: EditorEvents['selectionUpdate'],
) => void)
| null
/**
* The editor state has changed.
*/
onTransaction?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onTransaction']
},
event: EditorEvents['transaction'],
) => void)
| null
/**
* The editor is focused.
*/
onFocus?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onFocus']
},
event: EditorEvents['focus'],
) => void)
| null
/**
* The editor isnt focused anymore.
*/
onBlur?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onBlur']
},
event: EditorEvents['blur'],
) => void)
| null
/**
* The editor is destroyed.
*/
onDestroy?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['onDestroy']
},
event: EditorEvents['destroy'],
) => void)
| null
/**
* This hook allows you to intercept and modify transactions before they are dispatched.
*
* Example
* ```ts
* dispatchTransaction({ transaction, next }) {
* console.log('Dispatching transaction:', transaction)
* next(transaction)
* }
* ```
*
* @param props - The dispatch transaction props
*/
dispatchTransaction?:
| ((
this: {
name: string
options: Options
storage: Storage
editor: Editor
type: PMType
parent: ParentConfig<Config>['dispatchTransaction']
},
props: DispatchTransactionProps,
) => void)
| null
}
export class Extendable<
Options = any,
Storage = any,
Config = ExtensionConfig<Options, Storage> | NodeConfig<Options, Storage> | MarkConfig<Options, Storage>,
> {
type = 'extendable'
parent: Extendable | null = null
child: Extendable | null = null
name = ''
config: Config = {
name: this.name,
} as Config
constructor(config: Partial<Config> = {}) {
this.config = {
...this.config,
...config,
}
this.name = (this.config as any).name
}
get options(): Options {
return {
...(callOrReturn(
getExtensionField<AnyConfig['addOptions']>(this as any, 'addOptions', {
name: this.name,
}),
) || {}),
}
}
get storage(): Readonly<Storage> {
return {
...(callOrReturn(
getExtensionField<AnyConfig['addStorage']>(this as any, 'addStorage', {
name: this.name,
options: this.options,
}),
) || {}),
}
}
configure(options: Partial<Options> = {}) {
const extension = this.extend<Options, Storage, Config>({
...this.config,
addOptions: () => {
return mergeDeep(this.options as Record<string, any>, options) as Options
},
})
extension.name = this.name
extension.parent = this.parent
return extension
}
extend<
ExtendedOptions = Options,
ExtendedStorage = Storage,
ExtendedConfig =
| ExtensionConfig<ExtendedOptions, ExtendedStorage>
| NodeConfig<ExtendedOptions, ExtendedStorage>
| MarkConfig<ExtendedOptions, ExtendedStorage>,
>(extendedConfig: Partial<ExtendedConfig> = {}): Extendable<ExtendedOptions, ExtendedStorage> {
const extension = new (this.constructor as any)({ ...this.config, ...extendedConfig })
extension.parent = this
this.child = extension
extension.name = 'name' in extendedConfig ? extendedConfig.name : extension.parent.name
return extension
}
}

55
node_modules/@tiptap/core/src/Extension.ts generated vendored Normal file
View File

@@ -0,0 +1,55 @@
import type { Editor } from './Editor.js'
import { type ExtendableConfig, Extendable } from './Extendable.js'
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface ExtensionConfig<Options = any, Storage = any>
extends ExtendableConfig<Options, Storage, ExtensionConfig<Options, Storage>, null> {}
/**
* The Extension class is the base class for all extensions.
* @see https://tiptap.dev/api/extensions#create-a-new-extension
*/
export class Extension<Options = any, Storage = any> extends Extendable<
Options,
Storage,
ExtensionConfig<Options, Storage>
> {
type = 'extension'
/**
* Create a new Extension instance
* @param config - Extension configuration object or a function that returns a configuration object
*/
static create<O = any, S = any>(
config: Partial<ExtensionConfig<O, S>> | (() => Partial<ExtensionConfig<O, S>>) = {},
) {
// If the config is a function, execute it to get the configuration object
const resolvedConfig = typeof config === 'function' ? config() : config
return new Extension<O, S>(resolvedConfig)
}
configure(options?: Partial<Options>) {
return super.configure(options) as Extension<Options, Storage>
}
extend<
ExtendedOptions = Options,
ExtendedStorage = Storage,
ExtendedConfig = ExtensionConfig<ExtendedOptions, ExtendedStorage>,
>(
extendedConfig?:
| (() => Partial<ExtendedConfig>)
| (Partial<ExtendedConfig> &
ThisType<{
name: string
options: ExtendedOptions
storage: ExtendedStorage
editor: Editor
type: null
}>),
): Extension<ExtendedOptions, ExtendedStorage> {
// If the extended config is a function, execute it to get the configuration object
const resolvedConfig = typeof extendedConfig === 'function' ? extendedConfig() : extendedConfig
return super.extend(resolvedConfig) as Extension<ExtendedOptions, ExtendedStorage>
}
}

440
node_modules/@tiptap/core/src/ExtensionManager.ts generated vendored Normal file
View File

@@ -0,0 +1,440 @@
import { keymap } from '@tiptap/pm/keymap'
import type { Schema } from '@tiptap/pm/model'
import type { Plugin, Transaction } from '@tiptap/pm/state'
import type { EditorView, MarkViewConstructor, NodeViewConstructor } from '@tiptap/pm/view'
import type { Editor } from './Editor.js'
import {
flattenExtensions,
getAttributesFromExtensions,
getExtensionField,
getNodeType,
getRenderedAttributes,
getSchemaByResolvedExtensions,
getSchemaTypeByName,
isExtensionRulesEnabled,
resolveExtensions,
sortExtensions,
splitExtensions,
} from './helpers/index.js'
import { type MarkConfig, type NodeConfig, type Storage, getMarkType, updateMarkViewAttributes } from './index.js'
import { inputRulesPlugin } from './InputRule.js'
import { Mark } from './Mark.js'
import { pasteRulesPlugin } from './PasteRule.js'
import type { AnyConfig, Extensions, RawCommands } from './types.js'
import { callOrReturn } from './utilities/callOrReturn.js'
export class ExtensionManager {
editor: Editor
schema: Schema
/**
* A flattened and sorted array of all extensions
*/
extensions: Extensions
/**
* A non-flattened array of base extensions (no sub-extensions)
*/
baseExtensions: Extensions
splittableMarks: string[] = []
constructor(extensions: Extensions, editor: Editor) {
this.editor = editor
this.baseExtensions = extensions
this.extensions = resolveExtensions(extensions)
this.schema = getSchemaByResolvedExtensions(this.extensions, editor)
this.setupExtensions()
}
static resolve = resolveExtensions
static sort = sortExtensions
static flatten = flattenExtensions
/**
* Get all commands from the extensions.
* @returns An object with all commands where the key is the command name and the value is the command function
*/
get commands(): RawCommands {
return this.extensions.reduce((commands, extension) => {
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
const addCommands = getExtensionField<AnyConfig['addCommands']>(extension, 'addCommands', context)
if (!addCommands) {
return commands
}
return {
...commands,
...addCommands(),
}
}, {} as RawCommands)
}
/**
* Get all registered Prosemirror plugins from the extensions.
* @returns An array of Prosemirror plugins
*/
get plugins(): Plugin[] {
const { editor } = this
// With ProseMirror, first plugins within an array are executed first.
// In Tiptap, we provide the ability to override plugins,
// so it feels more natural to run plugins at the end of an array first.
// Thats why we have to reverse the `extensions` array and sort again
// based on the `priority` option.
const extensions = sortExtensions([...this.extensions].reverse())
const allPlugins = extensions.flatMap(extension => {
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
const plugins: Plugin[] = []
const addKeyboardShortcuts = getExtensionField<AnyConfig['addKeyboardShortcuts']>(
extension,
'addKeyboardShortcuts',
context,
)
let defaultBindings: Record<string, () => boolean> = {}
// bind exit handling
if (extension.type === 'mark' && getExtensionField<MarkConfig['exitable']>(extension, 'exitable', context)) {
defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension as Mark })
}
if (addKeyboardShortcuts) {
const bindings = Object.fromEntries(
Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => {
return [shortcut, () => method({ editor })]
}),
)
defaultBindings = { ...defaultBindings, ...bindings }
}
const keyMapPlugin = keymap(defaultBindings)
plugins.push(keyMapPlugin)
const addInputRules = getExtensionField<AnyConfig['addInputRules']>(extension, 'addInputRules', context)
if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
const rules = addInputRules()
if (rules && rules.length) {
const inputResult = inputRulesPlugin({
editor,
rules,
})
const inputPlugins = Array.isArray(inputResult) ? inputResult : [inputResult]
plugins.push(...inputPlugins)
}
}
const addPasteRules = getExtensionField<AnyConfig['addPasteRules']>(extension, 'addPasteRules', context)
if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
const rules = addPasteRules()
if (rules && rules.length) {
const pasteRules = pasteRulesPlugin({ editor, rules })
plugins.push(...pasteRules)
}
}
const addProseMirrorPlugins = getExtensionField<AnyConfig['addProseMirrorPlugins']>(
extension,
'addProseMirrorPlugins',
context,
)
if (addProseMirrorPlugins) {
const proseMirrorPlugins = addProseMirrorPlugins()
plugins.push(...proseMirrorPlugins)
}
return plugins
})
return allPlugins
}
/**
* Get all attributes from the extensions.
* @returns An array of attributes
*/
get attributes() {
return getAttributesFromExtensions(this.extensions)
}
/**
* Get all node views from the extensions.
* @returns An object with all node views where the key is the node name and the value is the node view function
*/
get nodeViews(): Record<string, NodeViewConstructor> {
const { editor } = this
const { nodeExtensions } = splitExtensions(this.extensions)
return Object.fromEntries(
nodeExtensions
.filter(extension => !!getExtensionField(extension, 'addNodeView'))
.map(extension => {
const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.name)
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor,
type: getNodeType(extension.name, this.schema),
}
const addNodeView = getExtensionField<NodeConfig['addNodeView']>(extension, 'addNodeView', context)
if (!addNodeView) {
return []
}
const nodeViewResult = addNodeView()
if (!nodeViewResult) {
return []
}
const nodeview: NodeViewConstructor = (node, view, getPos, decorations, innerDecorations) => {
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes)
return nodeViewResult({
// pass-through
node,
view,
getPos: getPos as () => number,
decorations,
innerDecorations,
// tiptap-specific
editor,
extension,
HTMLAttributes,
})
}
return [extension.name, nodeview]
}),
)
}
/**
* Get the composed dispatchTransaction function from all extensions.
* @param baseDispatch The base dispatch function (e.g. from the editor or user props)
* @returns A composed dispatch function
*/
dispatchTransaction(baseDispatch: (tr: Transaction) => void): (tr: Transaction) => void {
const { editor } = this
const extensions = sortExtensions([...this.extensions].reverse())
return extensions.reduceRight((next, extension) => {
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
const dispatchTransaction = getExtensionField<AnyConfig['dispatchTransaction']>(
extension,
'dispatchTransaction',
context,
)
if (!dispatchTransaction) {
return next
}
return (transaction: Transaction) => {
dispatchTransaction.call(context, { transaction, next })
}
}, baseDispatch)
}
/**
* Get the composed transformPastedHTML function from all extensions.
* @param baseTransform The base transform function (e.g. from the editor props)
* @returns A composed transform function that chains all extension transforms
*/
transformPastedHTML(
baseTransform?: (html: string, view?: any) => string,
): (html: string, view?: EditorView) => string {
const { editor } = this
const extensions = sortExtensions([...this.extensions])
return extensions.reduce(
(transform, extension) => {
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
const extensionTransform = getExtensionField<AnyConfig['transformPastedHTML']>(
extension,
'transformPastedHTML',
context,
)
if (!extensionTransform) {
return transform
}
return (html: string, view?: any) => {
// Chain the transforms: pass the result of the previous transform to the next
const transformedHtml = transform(html, view)
return extensionTransform.call(context, transformedHtml)
}
},
baseTransform || ((html: string) => html),
)
}
get markViews(): Record<string, MarkViewConstructor> {
const { editor } = this
const { markExtensions } = splitExtensions(this.extensions)
return Object.fromEntries(
markExtensions
.filter(extension => !!getExtensionField(extension, 'addMarkView'))
.map(extension => {
const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.name)
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor,
type: getMarkType(extension.name, this.schema),
}
const addMarkView = getExtensionField<MarkConfig['addMarkView']>(extension, 'addMarkView', context)
if (!addMarkView) {
return []
}
const markView: MarkViewConstructor = (mark, view, inline) => {
const HTMLAttributes = getRenderedAttributes(mark, extensionAttributes)
return addMarkView()({
// pass-through
mark,
view,
inline,
// tiptap-specific
editor,
extension,
HTMLAttributes,
updateAttributes: (attrs: Record<string, any>) => {
updateMarkViewAttributes(mark, editor, attrs)
},
})
}
return [extension.name, markView]
}),
)
}
/**
* Go through all extensions, create extension storages & setup marks
* & bind editor event listener.
*/
private setupExtensions() {
const extensions = this.extensions
// re-initialize the extension storage object instance
this.editor.extensionStorage = Object.fromEntries(
extensions.map(extension => [extension.name, extension.storage]),
) as unknown as Storage
extensions.forEach(extension => {
const context = {
name: extension.name,
options: extension.options,
storage: this.editor.extensionStorage[extension.name as keyof Storage],
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
if (extension.type === 'mark') {
const keepOnSplit = callOrReturn(getExtensionField(extension, 'keepOnSplit', context)) ?? true
if (keepOnSplit) {
this.splittableMarks.push(extension.name)
}
}
const onBeforeCreate = getExtensionField<AnyConfig['onBeforeCreate']>(extension, 'onBeforeCreate', context)
const onCreate = getExtensionField<AnyConfig['onCreate']>(extension, 'onCreate', context)
const onUpdate = getExtensionField<AnyConfig['onUpdate']>(extension, 'onUpdate', context)
const onSelectionUpdate = getExtensionField<AnyConfig['onSelectionUpdate']>(
extension,
'onSelectionUpdate',
context,
)
const onTransaction = getExtensionField<AnyConfig['onTransaction']>(extension, 'onTransaction', context)
const onFocus = getExtensionField<AnyConfig['onFocus']>(extension, 'onFocus', context)
const onBlur = getExtensionField<AnyConfig['onBlur']>(extension, 'onBlur', context)
const onDestroy = getExtensionField<AnyConfig['onDestroy']>(extension, 'onDestroy', context)
if (onBeforeCreate) {
this.editor.on('beforeCreate', onBeforeCreate)
}
if (onCreate) {
this.editor.on('create', onCreate)
}
if (onUpdate) {
this.editor.on('update', onUpdate)
}
if (onSelectionUpdate) {
this.editor.on('selectionUpdate', onSelectionUpdate)
}
if (onTransaction) {
this.editor.on('transaction', onTransaction)
}
if (onFocus) {
this.editor.on('focus', onFocus)
}
if (onBlur) {
this.editor.on('blur', onBlur)
}
if (onDestroy) {
this.editor.on('destroy', onDestroy)
}
})
}
}

290
node_modules/@tiptap/core/src/InputRule.ts generated vendored Normal file
View File

@@ -0,0 +1,290 @@
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
import { Fragment } from '@tiptap/pm/model'
import type { EditorState, TextSelection } from '@tiptap/pm/state'
import { Plugin } from '@tiptap/pm/state'
import { CommandManager } from './CommandManager.js'
import type { Editor } from './Editor.js'
import { createChainableState } from './helpers/createChainableState.js'
import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'
import { getTextContentFromNodes } from './helpers/getTextContentFromNodes.js'
import type { CanCommands, ChainedCommands, ExtendedRegExpMatchArray, Range, SingleCommands } from './types.js'
import { isRegExp } from './utilities/isRegExp.js'
export type InputRuleMatch = {
index: number
text: string
replaceWith?: string
match?: RegExpMatchArray
data?: Record<string, any>
}
export type InputRuleFinder = RegExp | ((text: string) => InputRuleMatch | null)
export class InputRule {
find: InputRuleFinder
handler: (props: {
state: EditorState
range: Range
match: ExtendedRegExpMatchArray
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
}) => void | null
undoable: boolean
constructor(config: {
find: InputRuleFinder
handler: (props: {
state: EditorState
range: Range
match: ExtendedRegExpMatchArray
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
}) => void | null
undoable?: boolean
}) {
this.find = config.find
this.handler = config.handler
this.undoable = config.undoable ?? true
}
}
const inputRuleMatcherHandler = (text: string, find: InputRuleFinder): ExtendedRegExpMatchArray | null => {
if (isRegExp(find)) {
return find.exec(text)
}
const inputRuleMatch = find(text)
if (!inputRuleMatch) {
return null
}
const result: ExtendedRegExpMatchArray = [inputRuleMatch.text]
result.index = inputRuleMatch.index
result.input = text
result.data = inputRuleMatch.data
if (inputRuleMatch.replaceWith) {
if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".')
}
result.push(inputRuleMatch.replaceWith)
}
return result
}
function run(config: {
editor: Editor
from: number
to: number
text: string
rules: InputRule[]
plugin: Plugin
}): boolean {
const { editor, from, to, text, rules, plugin } = config
const { view } = editor
if (view.composing) {
return false
}
const $from = view.state.doc.resolve(from)
if (
// check for code node
$from.parent.type.spec.code ||
// check for code mark
!!($from.nodeBefore || $from.nodeAfter)?.marks.find(mark => mark.type.spec.code)
) {
return false
}
let matched = false
const textBefore = getTextContentFromNodes($from) + text
rules.forEach(rule => {
if (matched) {
return
}
const match = inputRuleMatcherHandler(textBefore, rule.find)
if (!match) {
return
}
const tr = view.state.tr
const state = createChainableState({
state: view.state,
transaction: tr,
})
const range = {
from: from - (match[0].length - text.length),
to,
}
const { commands, chain, can } = new CommandManager({
editor,
state,
})
const handler = rule.handler({
state,
range,
match,
commands,
chain,
can,
})
// stop if there are no changes
if (handler === null || !tr.steps.length) {
return
}
// store transform as meta data
// so we can undo input rules within the `undoInputRules` command
if (rule.undoable) {
tr.setMeta(plugin, {
transform: tr,
from,
to,
text,
})
}
view.dispatch(tr)
matched = true
})
return matched
}
/**
* Create an input rules plugin. When enabled, it will cause text
* input that matches any of the given rules to trigger the rules
* action.
*/
export function inputRulesPlugin(props: { editor: Editor; rules: InputRule[] }): Plugin {
const { editor, rules } = props
const plugin = new Plugin({
state: {
init() {
return null
},
apply(tr, prev, state) {
const stored = tr.getMeta(plugin)
if (stored) {
return stored
}
// if InputRule is triggered by insertContent()
const simulatedInputMeta = tr.getMeta('applyInputRules') as
| undefined
| {
from: number
text: string | ProseMirrorNode | Fragment
}
const isSimulatedInput = !!simulatedInputMeta
if (isSimulatedInput) {
setTimeout(() => {
let { text } = simulatedInputMeta
if (typeof text === 'string') {
text = text as string
} else {
text = getHTMLFromFragment(Fragment.from(text), state.schema)
}
const { from } = simulatedInputMeta
const to = from + text.length
run({
editor,
from,
to,
text,
rules,
plugin,
})
})
}
return tr.selectionSet || tr.docChanged ? null : prev
},
},
props: {
handleTextInput(view, from, to, text) {
return run({
editor,
from,
to,
text,
rules,
plugin,
})
},
handleDOMEvents: {
compositionend: view => {
setTimeout(() => {
const { $cursor } = view.state.selection as TextSelection
if ($cursor) {
run({
editor,
from: $cursor.pos,
to: $cursor.pos,
text: '',
rules,
plugin,
})
}
})
return false
},
},
// add support for input rules to trigger on enter
// this is useful for example for code blocks
handleKeyDown(view, event) {
if (event.key !== 'Enter') {
return false
}
const { $cursor } = view.state.selection as TextSelection
if ($cursor) {
return run({
editor,
from: $cursor.pos,
to: $cursor.pos,
text: '\n',
rules,
plugin,
})
}
return false
},
},
// @ts-ignore
isInputRules: true,
}) as Plugin
return plugin
}

211
node_modules/@tiptap/core/src/Mark.ts generated vendored Normal file
View File

@@ -0,0 +1,211 @@
import type { DOMOutputSpec, Mark as ProseMirrorMark, MarkSpec, MarkType } from '@tiptap/pm/model'
import type { Editor } from './Editor.js'
import type { ExtendableConfig } from './Extendable.js'
import { Extendable } from './Extendable.js'
import type { Attributes, MarkViewRenderer, ParentConfig } from './types.js'
export interface MarkConfig<Options = any, Storage = any>
extends ExtendableConfig<Options, Storage, MarkConfig<Options, Storage>, MarkType> {
/**
* Mark View
*/
addMarkView?:
| ((this: {
name: string
options: Options
storage: Storage
editor: Editor
type: MarkType
parent: ParentConfig<MarkConfig<Options, Storage>>['addMarkView']
}) => MarkViewRenderer)
| null
/**
* Keep mark after split node
*/
keepOnSplit?: boolean | (() => boolean)
/**
* Inclusive
*/
inclusive?:
| MarkSpec['inclusive']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['inclusive']
editor?: Editor
}) => MarkSpec['inclusive'])
/**
* Excludes
*/
excludes?:
| MarkSpec['excludes']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['excludes']
editor?: Editor
}) => MarkSpec['excludes'])
/**
* Marks this Mark as exitable
*/
exitable?: boolean | (() => boolean)
/**
* Group
*/
group?:
| MarkSpec['group']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['group']
editor?: Editor
}) => MarkSpec['group'])
/**
* Spanning
*/
spanning?:
| MarkSpec['spanning']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['spanning']
editor?: Editor
}) => MarkSpec['spanning'])
/**
* Code
*/
code?:
| boolean
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['code']
editor?: Editor
}) => boolean)
/**
* Parse HTML
*/
parseHTML?: (this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['parseHTML']
editor?: Editor
}) => MarkSpec['parseDOM']
/**
* Render HTML
*/
renderHTML?:
| ((
this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['renderHTML']
editor?: Editor
},
props: {
mark: ProseMirrorMark
HTMLAttributes: Record<string, any>
},
) => DOMOutputSpec)
| null
/**
* Attributes
*/
addAttributes?: (this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<MarkConfig<Options, Storage>>['addAttributes']
editor?: Editor
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
}) => Attributes | {}
}
/**
* The Mark class is used to create custom mark extensions.
* @see https://tiptap.dev/api/extensions#create-a-new-extension
*/
export class Mark<Options = any, Storage = any> extends Extendable<Options, Storage, MarkConfig<Options, Storage>> {
type = 'mark'
/**
* Create a new Mark instance
* @param config - Mark configuration object or a function that returns a configuration object
*/
static create<O = any, S = any>(config: Partial<MarkConfig<O, S>> | (() => Partial<MarkConfig<O, S>>) = {}) {
// If the config is a function, execute it to get the configuration object
const resolvedConfig = typeof config === 'function' ? config() : config
return new Mark<O, S>(resolvedConfig)
}
static handleExit({ editor, mark }: { editor: Editor; mark: Mark }) {
const { tr } = editor.state
const currentPos = editor.state.selection.$from
const isAtEnd = currentPos.pos === currentPos.end()
if (isAtEnd) {
const currentMarks = currentPos.marks()
const isInMark = !!currentMarks.find(m => m?.type.name === mark.name)
if (!isInMark) {
return false
}
const removeMark = currentMarks.find(m => m?.type.name === mark.name)
if (removeMark) {
tr.removeStoredMark(removeMark)
}
tr.insertText(' ', currentPos.pos)
editor.view.dispatch(tr)
return true
}
return false
}
configure(options?: Partial<Options>) {
return super.configure(options) as Mark<Options, Storage>
}
extend<
ExtendedOptions = Options,
ExtendedStorage = Storage,
ExtendedConfig extends MarkConfig<ExtendedOptions, ExtendedStorage> = MarkConfig<ExtendedOptions, ExtendedStorage>,
>(
extendedConfig?:
| (() => Partial<ExtendedConfig>)
| (Partial<ExtendedConfig> &
ThisType<{
name: string
options: ExtendedOptions
storage: ExtendedStorage
editor: Editor
type: MarkType
}>),
): Mark<ExtendedOptions, ExtendedStorage> {
// If the extended config is a function, execute it to get the configuration object
const resolvedConfig = typeof extendedConfig === 'function' ? extendedConfig() : extendedConfig
return super.extend(resolvedConfig) as Mark<ExtendedOptions, ExtendedStorage>
}
}

122
node_modules/@tiptap/core/src/MarkView.ts generated vendored Normal file
View File

@@ -0,0 +1,122 @@
import type { Mark } from '@tiptap/pm/model'
import type { ViewMutationRecord } from '@tiptap/pm/view'
import type { Editor } from './Editor.js'
import type { MarkViewProps, MarkViewRendererOptions } from './types.js'
import { isAndroid, isiOS } from './utilities/index.js'
export function updateMarkViewAttributes(checkMark: Mark, editor: Editor, attrs: Record<string, any> = {}): void {
const { state } = editor
const { doc, tr } = state
const thisMark = checkMark
doc.descendants((node, pos) => {
const from = tr.mapping.map(pos)
const to = tr.mapping.map(pos) + node.nodeSize
let foundMark: Mark | null = null
// find the mark on the current node
node.marks.forEach(mark => {
if (mark !== thisMark) {
return false
}
foundMark = mark
})
if (!foundMark) {
return
}
// check if we need to update given the attributes
let needsUpdate = false
Object.keys(attrs).forEach(k => {
if (attrs[k] !== foundMark!.attrs[k]) {
needsUpdate = true
}
})
if (needsUpdate) {
const updatedMark = checkMark.type.create({
...checkMark.attrs,
...attrs,
})
tr.removeMark(from, to, checkMark.type)
tr.addMark(from, to, updatedMark)
}
})
if (tr.docChanged) {
editor.view.dispatch(tr)
}
}
export class MarkView<Component, Options extends MarkViewRendererOptions = MarkViewRendererOptions> {
component: Component
editor: Editor
options: Options
mark: MarkViewProps['mark']
HTMLAttributes: MarkViewProps['HTMLAttributes']
constructor(component: Component, props: MarkViewProps, options?: Partial<Options>) {
this.component = component
this.editor = props.editor
this.options = { ...options } as Options
this.mark = props.mark
this.HTMLAttributes = props.HTMLAttributes
}
get dom(): HTMLElement {
return this.editor.view.dom
}
get contentDOM(): HTMLElement | null {
return null
}
/**
* Update the attributes of the mark in the document.
* @param attrs The attributes to update.
*/
updateAttributes(attrs: Record<string, any>, checkMark?: Mark): void {
updateMarkViewAttributes(checkMark || this.mark, this.editor, attrs)
}
ignoreMutation(mutation: ViewMutationRecord): boolean {
if (!this.dom || !this.contentDOM) {
return true
}
if (typeof this.options.ignoreMutation === 'function') {
return this.options.ignoreMutation({ mutation })
}
if (mutation.type === 'selection') {
return false
}
if (
this.dom.contains(mutation.target) &&
mutation.type === 'childList' &&
(isiOS() || isAndroid()) &&
this.editor.isFocused
) {
const changedNodes = [...Array.from(mutation.addedNodes), ...Array.from(mutation.removedNodes)] as HTMLElement[]
if (changedNodes.every(node => node.isContentEditable)) {
return false
}
}
if (this.contentDOM === mutation.target && mutation.type === 'attributes') {
return true
}
if (this.contentDOM.contains(mutation.target)) {
return false
}
return true
}
}

377
node_modules/@tiptap/core/src/Node.ts generated vendored Normal file
View File

@@ -0,0 +1,377 @@
import type { DOMOutputSpec, Node as ProseMirrorNode, NodeSpec, NodeType } from '@tiptap/pm/model'
import type { Editor } from './Editor.js'
import type { ExtendableConfig } from './Extendable.js'
import { Extendable } from './Extendable.js'
import type { Attributes, NodeViewRenderer, ParentConfig } from './types.js'
export interface NodeConfig<Options = any, Storage = any>
extends ExtendableConfig<Options, Storage, NodeConfig<Options, Storage>, NodeType> {
/**
* Node View
*/
addNodeView?:
| ((this: {
name: string
options: Options
storage: Storage
editor: Editor
type: NodeType
parent: ParentConfig<NodeConfig<Options, Storage>>['addNodeView']
}) => NodeViewRenderer | null)
| null
/**
* Defines if this node should be a top level node (doc)
* @default false
* @example true
*/
topNode?: boolean
/**
* The content expression for this node, as described in the [schema
* guide](/docs/guide/#schema.content_expressions). When not given,
* the node does not allow any content.
*
* You can read more about it on the Prosemirror documentation here
* @see https://prosemirror.net/docs/guide/#schema.content_expressions
* @default undefined
* @example content: 'block+'
* @example content: 'headline paragraph block*'
*/
content?:
| NodeSpec['content']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['content']
editor?: Editor
}) => NodeSpec['content'])
/**
* The marks that are allowed inside of this node. May be a
* space-separated string referring to mark names or groups, `"_"`
* to explicitly allow all marks, or `""` to disallow marks. When
* not given, nodes with inline content default to allowing all
* marks, other nodes default to not allowing marks.
*
* @example marks: 'strong em'
*/
marks?:
| NodeSpec['marks']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['marks']
editor?: Editor
}) => NodeSpec['marks'])
/**
* The group or space-separated groups to which this node belongs,
* which can be referred to in the content expressions for the
* schema.
*
* By default Tiptap uses the groups 'block' and 'inline' for nodes. You
* can also use custom groups if you want to group specific nodes together
* and handle them in your schema.
* @example group: 'block'
* @example group: 'inline'
* @example group: 'customBlock' // this uses a custom group
*/
group?:
| NodeSpec['group']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['group']
editor?: Editor
}) => NodeSpec['group'])
/**
* Should be set to true for inline nodes. (Implied for text nodes.)
*/
inline?:
| NodeSpec['inline']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['inline']
editor?: Editor
}) => NodeSpec['inline'])
/**
* Can be set to true to indicate that, though this isn't a [leaf
* node](https://prosemirror.net/docs/ref/#model.NodeType.isLeaf), it doesn't have directly editable
* content and should be treated as a single unit in the view.
*
* @example atom: true
*/
atom?:
| NodeSpec['atom']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['atom']
editor?: Editor
}) => NodeSpec['atom'])
/**
* Controls whether nodes of this type can be selected as a [node
* selection](https://prosemirror.net/docs/ref/#state.NodeSelection). Defaults to true for non-text
* nodes.
*
* @default true
* @example selectable: false
*/
selectable?:
| NodeSpec['selectable']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['selectable']
editor?: Editor
}) => NodeSpec['selectable'])
/**
* Determines whether nodes of this type can be dragged without
* being selected. Defaults to false.
*
* @default: false
* @example: draggable: true
*/
draggable?:
| NodeSpec['draggable']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['draggable']
editor?: Editor
}) => NodeSpec['draggable'])
/**
* Can be used to indicate that this node contains code, which
* causes some commands to behave differently.
*/
code?:
| NodeSpec['code']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['code']
editor?: Editor
}) => NodeSpec['code'])
/**
* Controls way whitespace in this a node is parsed. The default is
* `"normal"`, which causes the [DOM parser](https://prosemirror.net/docs/ref/#model.DOMParser) to
* collapse whitespace in normal mode, and normalize it (replacing
* newlines and such with spaces) otherwise. `"pre"` causes the
* parser to preserve spaces inside the node. When this option isn't
* given, but [`code`](https://prosemirror.net/docs/ref/#model.NodeSpec.code) is true, `whitespace`
* will default to `"pre"`. Note that this option doesn't influence
* the way the node is rendered—that should be handled by `toDOM`
* and/or styling.
*/
whitespace?:
| NodeSpec['whitespace']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['whitespace']
editor?: Editor
}) => NodeSpec['whitespace'])
/**
* Allows a **single** node to be set as linebreak equivalent (e.g. hardBreak).
* When converting between block types that have whitespace set to "pre"
* and don't support the linebreak node (e.g. codeBlock) and other block types
* that do support the linebreak node (e.g. paragraphs) - this node will be used
* as the linebreak instead of stripping the newline.
*
* See [linebreakReplacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement).
*/
linebreakReplacement?:
| NodeSpec['linebreakReplacement']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['linebreakReplacement']
editor?: Editor
}) => NodeSpec['linebreakReplacement'])
/**
* When enabled, enables both
* [`definingAsContext`](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext) and
* [`definingForContent`](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent).
*
* @default false
* @example isolating: true
*/
defining?:
| NodeSpec['defining']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['defining']
editor?: Editor
}) => NodeSpec['defining'])
/**
* When enabled (default is false), the sides of nodes of this type
* count as boundaries that regular editing operations, like
* backspacing or lifting, won't cross. An example of a node that
* should probably have this enabled is a table cell.
*/
isolating?:
| NodeSpec['isolating']
| ((this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['isolating']
editor?: Editor
}) => NodeSpec['isolating'])
/**
* Associates DOM parser information with this node, which can be
* used by [`DOMParser.fromSchema`](https://prosemirror.net/docs/ref/#model.DOMParser^fromSchema) to
* automatically derive a parser. The `node` field in the rules is
* implied (the name of this node will be filled in automatically).
* If you supply your own parser, you do not need to also specify
* parsing rules in your schema.
*
* @example parseHTML: [{ tag: 'div', attrs: { 'data-id': 'my-block' } }]
*/
parseHTML?: (this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['parseHTML']
editor?: Editor
}) => NodeSpec['parseDOM']
/**
* A description of a DOM structure. Can be either a string, which is
* interpreted as a text node, a DOM node, which is interpreted as
* itself, a `{dom, contentDOM}` object, or an array.
*
* An array describes a DOM element. The first value in the array
* should be a string—the name of the DOM element, optionally prefixed
* by a namespace URL and a space. If the second element is plain
* object, it is interpreted as a set of attributes for the element.
* Any elements after that (including the 2nd if it's not an attribute
* object) are interpreted as children of the DOM elements, and must
* either be valid `DOMOutputSpec` values, or the number zero.
*
* The number zero (pronounced “hole”) is used to indicate the place
* where a node's child nodes should be inserted. If it occurs in an
* output spec, it should be the only child element in its parent
* node.
*
* @example toDOM: ['div[data-id="my-block"]', { class: 'my-block' }, 0]
*/
renderHTML?:
| ((
this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['renderHTML']
editor?: Editor
},
props: {
node: ProseMirrorNode
HTMLAttributes: Record<string, any>
},
) => DOMOutputSpec)
| null
/**
* renders the node as text
* @example renderText: () => 'foo
*/
renderText?:
| ((
this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['renderText']
editor?: Editor
},
props: {
node: ProseMirrorNode
pos: number
parent: ProseMirrorNode
index: number
},
) => string)
| null
/**
* Add attributes to the node
* @example addAttributes: () => ({ class: 'foo' })
*/
addAttributes?: (this: {
name: string
options: Options
storage: Storage
parent: ParentConfig<NodeConfig<Options, Storage>>['addAttributes']
editor?: Editor
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
}) => Attributes | {}
}
/**
* The Node class is used to create custom node extensions.
* @see https://tiptap.dev/api/extensions#create-a-new-extension
*/
export class Node<Options = any, Storage = any> extends Extendable<Options, Storage, NodeConfig<Options, Storage>> {
type = 'node'
/**
* Create a new Node instance
* @param config - Node configuration object or a function that returns a configuration object
*/
static create<O = any, S = any>(config: Partial<NodeConfig<O, S>> | (() => Partial<NodeConfig<O, S>>) = {}) {
// If the config is a function, execute it to get the configuration object
const resolvedConfig = typeof config === 'function' ? config() : config
return new Node<O, S>(resolvedConfig)
}
configure(options?: Partial<Options>) {
return super.configure(options) as Node<Options, Storage>
}
extend<
ExtendedOptions = Options,
ExtendedStorage = Storage,
ExtendedConfig extends NodeConfig<ExtendedOptions, ExtendedStorage> = NodeConfig<ExtendedOptions, ExtendedStorage>,
>(
extendedConfig?:
| (() => Partial<ExtendedConfig>)
| (Partial<ExtendedConfig> &
ThisType<{
name: string
options: ExtendedOptions
storage: ExtendedStorage
editor: Editor
type: NodeType
}>),
): Node<ExtendedOptions, ExtendedStorage> {
// If the extended config is a function, execute it to get the configuration object
const resolvedConfig = typeof extendedConfig === 'function' ? extendedConfig() : extendedConfig
return super.extend(resolvedConfig) as Node<ExtendedOptions, ExtendedStorage>
}
}

257
node_modules/@tiptap/core/src/NodePos.ts generated vendored Normal file
View File

@@ -0,0 +1,257 @@
import type { Fragment, Node, ResolvedPos } from '@tiptap/pm/model'
import type { Editor } from './Editor.js'
import type { Content, Range } from './types.js'
export class NodePos {
private resolvedPos: ResolvedPos
private isBlock: boolean
private editor: Editor
private get name(): string {
return this.node.type.name
}
constructor(pos: ResolvedPos, editor: Editor, isBlock = false, node: Node | null = null) {
this.isBlock = isBlock
this.resolvedPos = pos
this.editor = editor
this.currentNode = node
}
private currentNode: Node | null = null
get node(): Node {
return this.currentNode || this.resolvedPos.node()
}
get element(): HTMLElement {
return this.editor.view.domAtPos(this.pos).node as HTMLElement
}
public actualDepth: number | null = null
get depth(): number {
return this.actualDepth ?? this.resolvedPos.depth
}
get pos(): number {
return this.resolvedPos.pos
}
get content(): Fragment {
return this.node.content
}
set content(content: Content) {
let from = this.from
let to = this.to
if (this.isBlock) {
if (this.content.size === 0) {
console.error(`You cant set content on a block node. Tried to set content on ${this.name} at ${this.pos}`)
return
}
from = this.from + 1
to = this.to - 1
}
this.editor.commands.insertContentAt({ from, to }, content)
}
get attributes(): { [key: string]: any } {
return this.node.attrs
}
get textContent(): string {
return this.node.textContent
}
get size(): number {
return this.node.nodeSize
}
get from(): number {
if (this.isBlock) {
return this.pos
}
return this.resolvedPos.start(this.resolvedPos.depth)
}
get range(): Range {
return {
from: this.from,
to: this.to,
}
}
get to(): number {
if (this.isBlock) {
return this.pos + this.size
}
return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1)
}
get parent(): NodePos | null {
if (this.depth === 0) {
return null
}
const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1)
const $pos = this.resolvedPos.doc.resolve(parentPos)
return new NodePos($pos, this.editor)
}
get before(): NodePos | null {
let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2))
if ($pos.depth !== this.depth) {
$pos = this.resolvedPos.doc.resolve(this.from - 3)
}
return new NodePos($pos, this.editor)
}
get after(): NodePos | null {
let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1))
if ($pos.depth !== this.depth) {
$pos = this.resolvedPos.doc.resolve(this.to + 3)
}
return new NodePos($pos, this.editor)
}
get children(): NodePos[] {
const children: NodePos[] = []
this.node.content.forEach((node, offset) => {
const isBlock = node.isBlock && !node.isTextblock
const isNonTextAtom = node.isAtom && !node.isText
const isInline = node.isInline
const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1)
// Check if targetPos is within valid document range
if (targetPos < 0 || targetPos > this.resolvedPos.doc.nodeSize - 2) {
return
}
const $pos = this.resolvedPos.doc.resolve(targetPos)
// Only apply depth check for non-block, non-inline nodes (i.e., textblocks)
// Inline nodes should always be included as children since we're iterating
// over direct children via this.node.content
if (!isBlock && !isInline && $pos.depth <= this.depth) {
return
}
// Pass the node for both block and inline nodes to ensure correct node reference
const childNodePos = new NodePos($pos, this.editor, isBlock, isBlock || isInline ? node : null)
if (isBlock) {
childNodePos.actualDepth = this.depth + 1
}
children.push(childNodePos)
})
return children
}
get firstChild(): NodePos | null {
return this.children[0] || null
}
get lastChild(): NodePos | null {
const children = this.children
return children[children.length - 1] || null
}
closest(selector: string, attributes: { [key: string]: any } = {}): NodePos | null {
let node: NodePos | null = null
let currentNode = this.parent
while (currentNode && !node) {
if (currentNode.node.type.name === selector) {
if (Object.keys(attributes).length > 0) {
const nodeAttributes = currentNode.node.attrs
const attrKeys = Object.keys(attributes)
for (let index = 0; index < attrKeys.length; index += 1) {
const key = attrKeys[index]
if (nodeAttributes[key] !== attributes[key]) {
break
}
}
} else {
node = currentNode
}
}
currentNode = currentNode.parent
}
return node
}
querySelector(selector: string, attributes: { [key: string]: any } = {}): NodePos | null {
return this.querySelectorAll(selector, attributes, true)[0] || null
}
querySelectorAll(selector: string, attributes: { [key: string]: any } = {}, firstItemOnly = false): NodePos[] {
let nodes: NodePos[] = []
if (!this.children || this.children.length === 0) {
return nodes
}
const attrKeys = Object.keys(attributes)
/**
* Finds all children recursively that match the selector and attributes
* If firstItemOnly is true, it will return the first item found
*/
this.children.forEach(childPos => {
// If we already found a node and we only want the first item, we dont need to keep going
if (firstItemOnly && nodes.length > 0) {
return
}
if (childPos.node.type.name === selector) {
const doesAllAttributesMatch = attrKeys.every(key => attributes[key] === childPos.node.attrs[key])
if (doesAllAttributesMatch) {
nodes.push(childPos)
}
}
// If we already found a node and we only want the first item, we can stop here and skip the recursion
if (firstItemOnly && nodes.length > 0) {
return
}
nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly))
})
return nodes
}
setAttribute(attributes: { [key: string]: any }) {
const { tr } = this.editor.state
tr.setNodeMarkup(this.from, undefined, {
...this.node.attrs,
...attributes,
})
this.editor.view.dispatch(tr)
}
}

339
node_modules/@tiptap/core/src/NodeView.ts generated vendored Normal file
View File

@@ -0,0 +1,339 @@
import { NodeSelection } from '@tiptap/pm/state'
import type { NodeView as ProseMirrorNodeView, ViewMutationRecord } from '@tiptap/pm/view'
import type { Editor as CoreEditor } from './Editor.js'
import type { DecorationWithType, NodeViewRendererOptions, NodeViewRendererProps } from './types.js'
import { isAndroid } from './utilities/isAndroid.js'
import { isiOS } from './utilities/isiOS.js'
/**
* Node views are used to customize the rendered DOM structure of a node.
* @see https://tiptap.dev/guide/node-views
*/
export class NodeView<
Component,
NodeEditor extends CoreEditor = CoreEditor,
Options extends NodeViewRendererOptions = NodeViewRendererOptions,
> implements ProseMirrorNodeView
{
component: Component
editor: NodeEditor
options: Options
extension: NodeViewRendererProps['extension']
node: NodeViewRendererProps['node']
decorations: NodeViewRendererProps['decorations']
innerDecorations: NodeViewRendererProps['innerDecorations']
view: NodeViewRendererProps['view']
getPos: NodeViewRendererProps['getPos']
HTMLAttributes: NodeViewRendererProps['HTMLAttributes']
isDragging = false
constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>) {
this.component = component
this.editor = props.editor as NodeEditor
this.options = {
stopEvent: null,
ignoreMutation: null,
...options,
} as Options
this.extension = props.extension
this.node = props.node
this.decorations = props.decorations as DecorationWithType[]
this.innerDecorations = props.innerDecorations
this.view = props.view
this.HTMLAttributes = props.HTMLAttributes
this.getPos = props.getPos
this.mount()
}
mount() {
// eslint-disable-next-line
return
}
get dom(): HTMLElement {
return this.editor.view.dom as HTMLElement
}
get contentDOM(): HTMLElement | null {
return null
}
onDragStart(event: DragEvent) {
const { view } = this.editor
const target = event.target as HTMLElement
// get the drag handle element
// `closest` is not available for text nodes so we may have to use its parent
const dragHandle =
target.nodeType === 3 ? target.parentElement?.closest('[data-drag-handle]') : target.closest('[data-drag-handle]')
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
return
}
let x = 0
let y = 0
// calculate offset for drag element if we use a different drag handle element
if (this.dom !== dragHandle) {
const domBox = this.dom.getBoundingClientRect()
const handleBox = dragHandle.getBoundingClientRect()
// In React, we have to go through nativeEvent to reach offsetX/offsetY.
const offsetX = event.offsetX ?? (event as any).nativeEvent?.offsetX
const offsetY = event.offsetY ?? (event as any).nativeEvent?.offsetY
x = handleBox.x - domBox.x + offsetX
y = handleBox.y - domBox.y + offsetY
}
const clonedNode = this.dom.cloneNode(true) as HTMLElement
// Preserve the visual size of the original when using the clone as
// the drag image.
try {
const domBox = this.dom.getBoundingClientRect()
clonedNode.style.width = `${Math.round(domBox.width)}px`
clonedNode.style.height = `${Math.round(domBox.height)}px`
clonedNode.style.boxSizing = 'border-box'
// Ensure the clone doesn't capture pointer events while offscreen
clonedNode.style.pointerEvents = 'none'
} catch {
// ignore measurement errors (e.g. if element not in DOM)
}
// Some browsers (notably Safari) require the element passed to
// setDragImage to be present in the DOM. Using a detached node can
// cause the drag to immediately end.
let dragImageWrapper: HTMLElement | null = null
try {
dragImageWrapper = document.createElement('div')
dragImageWrapper.style.position = 'absolute'
dragImageWrapper.style.top = '-9999px'
dragImageWrapper.style.left = '-9999px'
dragImageWrapper.style.pointerEvents = 'none'
dragImageWrapper.appendChild(clonedNode)
document.body.appendChild(dragImageWrapper)
event.dataTransfer?.setDragImage(clonedNode, x, y)
} finally {
// Remove the wrapper on the next tick so the browser can use the
// element as the drag image. A 0ms timeout is enough in practice.
if (dragImageWrapper) {
setTimeout(() => {
try {
dragImageWrapper?.remove()
} catch {
// ignore removal errors
}
}, 0)
}
}
const pos = this.getPos()
if (typeof pos !== 'number') {
return
}
// we need to tell ProseMirror that we want to move the whole node
// so we create a NodeSelection
const selection = NodeSelection.create(view.state.doc, pos)
const transaction = view.state.tr.setSelection(selection)
view.dispatch(transaction)
}
stopEvent(event: Event) {
if (!this.dom) {
return false
}
if (typeof this.options.stopEvent === 'function') {
return this.options.stopEvent({ event })
}
const target = event.target as HTMLElement
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)
// any event from child nodes should be handled by ProseMirror
if (!isInElement) {
return false
}
const isDragEvent = event.type.startsWith('drag')
const isDropEvent = event.type === 'drop'
const isInput = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'].includes(target.tagName) || target.isContentEditable
// any input event within node views should be ignored by ProseMirror
if (isInput && !isDropEvent && !isDragEvent) {
return true
}
const { isEditable } = this.editor
const { isDragging } = this
const isDraggable = !!this.node.type.spec.draggable
const isSelectable = NodeSelection.isSelectable(this.node)
const isCopyEvent = event.type === 'copy'
const isPasteEvent = event.type === 'paste'
const isCutEvent = event.type === 'cut'
const isClickEvent = event.type === 'mousedown'
// ProseMirror tries to drag selectable nodes
// even if `draggable` is set to `false`
// this fix prevents that
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
event.preventDefault()
}
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
event.preventDefault()
return false
}
// we have to store that dragging started
if (isDraggable && isEditable && !isDragging && isClickEvent) {
const dragHandle = target.closest('[data-drag-handle]')
const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle))
if (isValidDragHandle) {
this.isDragging = true
document.addEventListener(
'dragend',
() => {
this.isDragging = false
},
{ once: true },
)
document.addEventListener(
'drop',
() => {
this.isDragging = false
},
{ once: true },
)
document.addEventListener(
'mouseup',
() => {
this.isDragging = false
},
{ once: true },
)
}
}
// these events are handled by prosemirror
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || (isClickEvent && isSelectable)) {
return false
}
return true
}
/**
* Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.
* @return `false` if the editor should re-read the selection or re-parse the range around the mutation
* @return `true` if it can safely be ignored.
*/
ignoreMutation(mutation: ViewMutationRecord) {
if (!this.dom || !this.contentDOM) {
return true
}
if (typeof this.options.ignoreMutation === 'function') {
return this.options.ignoreMutation({ mutation })
}
// a leaf/atom node is like a black box for ProseMirror
// and should be fully handled by the node view
if (this.node.isLeaf || this.node.isAtom) {
return true
}
// ProseMirror should handle any selections
if (mutation.type === 'selection') {
return false
}
// try to prevent a bug on iOS and Android that will break node views on enter
// this is because ProseMirror cant preventDispatch on enter
// this will lead to a re-render of the node view on enter
// see: https://github.com/ueberdosis/tiptap/issues/1214
// see: https://github.com/ueberdosis/tiptap/issues/2534
if (
this.dom.contains(mutation.target) &&
mutation.type === 'childList' &&
(isiOS() || isAndroid()) &&
this.editor.isFocused
) {
const changedNodes = [...Array.from(mutation.addedNodes), ...Array.from(mutation.removedNodes)] as HTMLElement[]
// well check if every changed node is contentEditable
// to make sure its probably mutated by ProseMirror
if (changedNodes.every(node => node.isContentEditable)) {
return false
}
}
// we will allow mutation contentDOM with attributes
// so we can for example adding classes within our node view
if (this.contentDOM === mutation.target && mutation.type === 'attributes') {
return true
}
// ProseMirror should handle any changes within contentDOM
if (this.contentDOM.contains(mutation.target)) {
return false
}
return true
}
/**
* Update the attributes of the prosemirror node.
*/
updateAttributes(attributes: Record<string, any>): void {
this.editor.commands.command(({ tr }) => {
const pos = this.getPos()
if (typeof pos !== 'number') {
return false
}
tr.setNodeMarkup(pos, undefined, {
...this.node.attrs,
...attributes,
})
return true
})
}
/**
* Delete the node.
*/
deleteNode(): void {
const from = this.getPos()
if (typeof from !== 'number') {
return
}
const to = from + this.node.nodeSize
this.editor.commands.deleteRange({ from, to })
}
}

373
node_modules/@tiptap/core/src/PasteRule.ts generated vendored Normal file
View File

@@ -0,0 +1,373 @@
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
import { Fragment } from '@tiptap/pm/model'
import type { EditorState } from '@tiptap/pm/state'
import { Plugin } from '@tiptap/pm/state'
import { CommandManager } from './CommandManager.js'
import type { Editor } from './Editor.js'
import { createChainableState } from './helpers/createChainableState.js'
import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'
import type { CanCommands, ChainedCommands, ExtendedRegExpMatchArray, Range, SingleCommands } from './types.js'
import { isNumber } from './utilities/isNumber.js'
import { isRegExp } from './utilities/isRegExp.js'
export type PasteRuleMatch = {
index: number
text: string
replaceWith?: string
match?: RegExpMatchArray
data?: Record<string, any>
}
export type PasteRuleFinder =
| RegExp
| ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined)
/**
* Paste rules are used to react to pasted content.
* @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
*/
export class PasteRule {
find: PasteRuleFinder
handler: (props: {
state: EditorState
range: Range
match: ExtendedRegExpMatchArray
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
pasteEvent: ClipboardEvent | null
dropEvent: DragEvent | null
}) => void | null
constructor(config: {
find: PasteRuleFinder
handler: (props: {
can: () => CanCommands
chain: () => ChainedCommands
commands: SingleCommands
dropEvent: DragEvent | null
match: ExtendedRegExpMatchArray
pasteEvent: ClipboardEvent | null
range: Range
state: EditorState
}) => void | null
}) {
this.find = config.find
this.handler = config.handler
}
}
const pasteRuleMatcherHandler = (
text: string,
find: PasteRuleFinder,
event?: ClipboardEvent | null,
): ExtendedRegExpMatchArray[] => {
if (isRegExp(find)) {
return [...text.matchAll(find)]
}
const matches = find(text, event)
if (!matches) {
return []
}
return matches.map(pasteRuleMatch => {
const result: ExtendedRegExpMatchArray = [pasteRuleMatch.text]
result.index = pasteRuleMatch.index
result.input = text
result.data = pasteRuleMatch.data
if (pasteRuleMatch.replaceWith) {
if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".')
}
result.push(pasteRuleMatch.replaceWith)
}
return result
})
}
function run(config: {
editor: Editor
state: EditorState
from: number
to: number
rule: PasteRule
pasteEvent: ClipboardEvent | null
dropEvent: DragEvent | null
}): boolean {
const { editor, state, from, to, rule, pasteEvent, dropEvent } = config
const { commands, chain, can } = new CommandManager({
editor,
state,
})
const handlers: (void | null)[] = []
state.doc.nodesBetween(from, to, (node, pos) => {
// Skip code blocks and non-textual nodes.
// Be defensive: `node` may be a Fragment without a `type`. Only text,
// inline, or textblock nodes are processed by paste rules.
if (node.type?.spec?.code || !(node.isText || node.isTextblock || node.isInline)) {
return
}
// For textblock and inline/text nodes, compute the range relative to the node.
// Prefer `node.nodeSize` when available (some Node shapes expose this),
// otherwise fall back to `node.content?.size`. Default to 0 if neither exists.
const contentSize = node.content?.size ?? node.nodeSize ?? 0
const resolvedFrom = Math.max(from, pos)
const resolvedTo = Math.min(to, pos + contentSize)
// If the resolved range is empty or invalid for this node, skip it. This
// avoids calling `textBetween` with start > end which can cause internal
// Fragment/Node traversal to access undefined `nodeSize` values.
if (resolvedFrom >= resolvedTo) {
return
}
const textToMatch = node.isText
? node.text || ''
: node.textBetween(resolvedFrom - pos, resolvedTo - pos, undefined, '\ufffc')
const matches = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent)
matches.forEach(match => {
if (match.index === undefined) {
return
}
const start = resolvedFrom + match.index + 1
const end = start + match[0].length
const range = {
from: state.tr.mapping.map(start),
to: state.tr.mapping.map(end),
}
const handler = rule.handler({
state,
range,
match,
commands,
chain,
can,
pasteEvent,
dropEvent,
})
handlers.push(handler)
})
})
const success = handlers.every(handler => handler !== null)
return success
}
// When dragging across editors, must get another editor instance to delete selection content.
let tiptapDragFromOtherEditor: Editor | null = null
const createClipboardPasteEvent = (text: string) => {
const event = new ClipboardEvent('paste', {
clipboardData: new DataTransfer(),
})
event.clipboardData?.setData('text/html', text)
return event
}
/**
* Create an paste rules plugin. When enabled, it will cause pasted
* text that matches any of the given rules to trigger the rules
* action.
*/
export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }): Plugin[] {
const { editor, rules } = props
let dragSourceElement: Element | null = null
let isPastedFromProseMirror = false
let isDroppedFromProseMirror = false
let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
let dropEvent: DragEvent | null
try {
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
} catch {
dropEvent = null
}
const processEvent = ({
state,
from,
to,
rule,
pasteEvt,
}: {
state: EditorState
from: number
to: { b: number }
rule: PasteRule
pasteEvt: ClipboardEvent | null
}) => {
const tr = state.tr
const chainableState = createChainableState({
state,
transaction: tr,
})
const handler = run({
editor,
state: chainableState,
from: Math.max(from - 1, 0),
to: to.b - 1,
rule,
pasteEvent: pasteEvt,
dropEvent,
})
if (!handler || !tr.steps.length) {
return
}
try {
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
} catch {
dropEvent = null
}
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
return tr
}
const plugins = rules.map(rule => {
return new Plugin({
// we register a global drag handler to track the current drag source element
view(view) {
const handleDragstart = (event: DragEvent) => {
dragSourceElement = view.dom.parentElement?.contains(event.target as Element) ? view.dom.parentElement : null
if (dragSourceElement) {
tiptapDragFromOtherEditor = editor
}
}
const handleDragend = () => {
if (tiptapDragFromOtherEditor) {
tiptapDragFromOtherEditor = null
}
}
window.addEventListener('dragstart', handleDragstart)
window.addEventListener('dragend', handleDragend)
return {
destroy() {
window.removeEventListener('dragstart', handleDragstart)
window.removeEventListener('dragend', handleDragend)
},
}
},
props: {
handleDOMEvents: {
drop: (view, event: Event) => {
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement
dropEvent = event as DragEvent
if (!isDroppedFromProseMirror) {
const dragFromOtherEditor = tiptapDragFromOtherEditor
if (dragFromOtherEditor?.isEditable) {
// setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
setTimeout(() => {
const selection = dragFromOtherEditor.state.selection
if (selection) {
dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to })
}
}, 10)
}
}
return false
},
paste: (_view, event: Event) => {
const html = (event as ClipboardEvent).clipboardData?.getData('text/html')
pasteEvent = event as ClipboardEvent
isPastedFromProseMirror = !!html?.includes('data-pm-slice')
return false
},
},
},
appendTransaction: (transactions, oldState, state) => {
const transaction = transactions[0]
const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror
const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror
// if PasteRule is triggered by insertContent()
const simulatedPasteMeta = transaction.getMeta('applyPasteRules') as
| undefined
| { from: number; text: string | ProseMirrorNode | Fragment }
const isSimulatedPaste = !!simulatedPasteMeta
if (!isPaste && !isDrop && !isSimulatedPaste) {
return
}
// Handle simulated paste
if (isSimulatedPaste) {
let { text } = simulatedPasteMeta
if (typeof text === 'string') {
text = text as string
} else {
text = getHTMLFromFragment(Fragment.from(text), state.schema)
}
const { from } = simulatedPasteMeta
const to = from + text.length
const pasteEvt = createClipboardPasteEvent(text)
return processEvent({
rule,
state,
from,
to: { b: to },
pasteEvt,
})
}
// handle actual paste/drop
const from = oldState.doc.content.findDiffStart(state.doc.content)
const to = oldState.doc.content.findDiffEnd(state.doc.content)
// stop if there is no changed range
if (!isNumber(from) || !to || from === to.b) {
return
}
return processEvent({
rule,
state,
from,
to,
pasteEvt: pasteEvent,
})
},
})
})
return plugins
}

36
node_modules/@tiptap/core/src/Tracker.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
import type { Transaction } from '@tiptap/pm/state'
export interface TrackerResult {
position: number
deleted: boolean
}
export class Tracker {
transaction: Transaction
currentStep: number
constructor(transaction: Transaction) {
this.transaction = transaction
this.currentStep = this.transaction.steps.length
}
map(position: number): TrackerResult {
let deleted = false
const mappedPosition = this.transaction.steps.slice(this.currentStep).reduce((newPosition, step) => {
const mapResult = step.getMap().mapResult(newPosition)
if (mapResult.deleted) {
deleted = true
}
return mapResult.pos
}, position)
return {
position: mappedPosition,
deleted,
}
}
}

View File

@@ -0,0 +1,575 @@
import { Editor, Extension } from '@tiptap/core'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { describe, expect, it } from 'vitest'
describe('transformPastedHTML', () => {
describe('priority ordering', () => {
it('should execute transforms in priority order (higher priority first)', () => {
const executionOrder: number[] = []
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'low-priority',
priority: 50,
transformPastedHTML(html) {
executionOrder.push(3)
return html
},
}),
Extension.create({
name: 'high-priority',
priority: 200,
transformPastedHTML(html) {
executionOrder.push(1)
return html
},
}),
Extension.create({
name: 'medium-priority',
priority: 100,
transformPastedHTML(html) {
executionOrder.push(2)
return html
},
}),
],
})
editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(executionOrder).toEqual([1, 2, 3])
editor.destroy()
})
it('should execute transforms in default priority order when priorities are equal', () => {
const executionOrder: string[] = []
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'first',
transformPastedHTML(html) {
executionOrder.push('first')
return html
},
}),
Extension.create({
name: 'second',
transformPastedHTML(html) {
executionOrder.push('second')
return html
},
}),
],
})
editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(executionOrder).toEqual(['first', 'second'])
editor.destroy()
})
})
describe('transform chaining', () => {
it('should chain transforms correctly', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'first-transform',
priority: 100,
transformPastedHTML(html) {
return html.replace(/foo/g, 'bar')
},
}),
Extension.create({
name: 'second-transform',
priority: 90,
transformPastedHTML(html) {
return html.replace(/bar/g, 'baz')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>foo</p>')
expect(result).toBe('<p>baz</p>')
editor.destroy()
})
it('should pass transformed HTML through entire chain', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'add-prefix',
priority: 100,
transformPastedHTML(html) {
return `PREFIX-${html}`
},
}),
Extension.create({
name: 'add-suffix',
priority: 90,
transformPastedHTML(html) {
return `${html}-SUFFIX`
},
}),
Extension.create({
name: 'add-wrapper',
priority: 80,
transformPastedHTML(html) {
return `[${html}]`
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('TEST')
expect(result).toBe('[PREFIX-TEST-SUFFIX]')
editor.destroy()
})
})
describe('baseTransform integration', () => {
it('should run baseTransform before extension transforms', () => {
const editor = new Editor({
editorProps: {
transformPastedHTML(html) {
return html.replace(/original/g, 'base')
},
},
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'extension-transform',
transformPastedHTML(html) {
return html.replace(/base/g, 'final')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>original</p>')
expect(result).toBe('<p>final</p>')
editor.destroy()
})
it('should work when baseTransform is undefined', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'extension-transform',
transformPastedHTML(html) {
return html.replace(/test/g, 'success')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(result).toBe('<p>success</p>')
editor.destroy()
})
})
describe('extensions without transforms', () => {
it('should skip extensions without transformPastedHTML', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'no-transform',
// No transformPastedHTML defined
}),
Extension.create({
name: 'with-transform',
transformPastedHTML(html) {
return html.replace(/test/g, 'success')
},
}),
Extension.create({
name: 'another-no-transform',
// No transformPastedHTML defined
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(result).toBe('<p>success</p>')
editor.destroy()
})
it('should return original HTML when no transforms are defined', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'extension-1',
}),
Extension.create({
name: 'extension-2',
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>unchanged</p>')
expect(result).toBe('<p>unchanged</p>')
editor.destroy()
})
})
describe('extension context', () => {
it('should provide correct context to transformPastedHTML', () => {
let capturedContext: any = null
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'test-extension',
addOptions() {
return {
customOption: 'value',
}
},
addStorage() {
return {
customStorage: 'stored',
}
},
transformPastedHTML(html) {
capturedContext = {
name: this.name,
options: this.options,
storage: this.storage,
editor: this.editor,
}
return html
},
}),
],
})
editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(capturedContext).toBeDefined()
expect(capturedContext.name).toBe('test-extension')
expect(capturedContext.options).toMatchObject({ customOption: 'value' })
expect(capturedContext.storage).toMatchObject({ customStorage: 'stored' })
expect(capturedContext.editor).toBe(editor)
editor.destroy()
})
it('should allow accessing editor state in transformPastedHTML', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'state-aware',
transformPastedHTML(html) {
const isEmpty = this.editor.isEmpty
return isEmpty ? `${html}<!-- empty -->` : html
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(result).toContain('<!-- empty -->')
editor.destroy()
})
})
describe('edge cases', () => {
it('should handle empty HTML string', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'transform',
transformPastedHTML(html) {
return html || '<p>default</p>'
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('')
expect(result).toBe('<p>default</p>')
editor.destroy()
})
it('should handle HTML with special characters', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'preserve-special',
transformPastedHTML(html) {
return html.replace(/&amp;/g, '&')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>&amp;test&amp;</p>')
expect(result).toBe('<p>&test&</p>')
editor.destroy()
})
it('should handle very long HTML strings', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'transform',
transformPastedHTML(html) {
return html.replace(/test/g, 'success')
},
}),
],
})
const longHtml = `<p>${'test '.repeat(10000)}</p>`
const result = editor.view.props.transformPastedHTML?.(longHtml)
expect(result).toContain('success')
expect(result).not.toContain('test')
editor.destroy()
})
it('should handle malformed HTML gracefully', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'transform',
transformPastedHTML(html) {
return html.replace(/test/g, 'success')
},
}),
],
})
const malformedHtml = '<p>test</span>'
const result = editor.view.props.transformPastedHTML?.(malformedHtml)
expect(result).toBe('<p>success</span>')
editor.destroy()
})
})
describe('view parameter', () => {
it('should pass view parameter to baseTransform', () => {
let viewReceived: any = null
const editor = new Editor({
editorProps: {
transformPastedHTML(html, view) {
viewReceived = view
return html
},
},
extensions: [Document, Paragraph, Text],
})
editor.view.props.transformPastedHTML?.('<p>test</p>', editor.view)
expect(viewReceived).toBe(editor.view)
editor.destroy()
})
it('should work when view parameter is undefined', () => {
const editor = new Editor({
editorProps: {
transformPastedHTML(html, view) {
return view ? html : `${html}<!-- no view -->`
},
},
extensions: [Document, Paragraph, Text],
})
const result = editor.view.props.transformPastedHTML?.('<p>test</p>')
expect(result).toContain('<!-- no view -->')
editor.destroy()
})
})
describe('real-world scenarios', () => {
it('should remove inline styles and dangerous attributes', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'security',
priority: 100,
transformPastedHTML(html) {
return html.replace(/\s+style="[^"]*"/gi, '').replace(/\s+on\w+="[^"]*"/gi, '')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p style="color: red;" onclick="alert(\'xss\')">test</p>')
expect(result).toBe('<p>test</p>')
editor.destroy()
})
it('should normalize whitespace from word processors', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'normalize-whitespace',
transformPastedHTML(html) {
return html
.replace(/\t/g, ' ')
.replace(/\u00a0/g, ' ')
.replace(/\s+/g, ' ')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p>test\t\u00a0 multiple spaces</p>')
expect(result).toBe('<p>test multiple spaces</p>')
editor.destroy()
})
it('should chain multiple practical transforms', () => {
const editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Extension.create({
name: 'remove-styles',
priority: 100,
transformPastedHTML(html) {
return html.replace(/\s+style="[^"]*"/gi, '')
},
}),
Extension.create({
name: 'normalize-tags',
priority: 90,
transformPastedHTML(html) {
return html.replace(/<b>/g, '<strong>').replace(/<\/b>/g, '</strong>')
},
}),
Extension.create({
name: 'add-classes',
priority: 80,
transformPastedHTML(html) {
return html.replace(/<p>/g, '<p class="editor-paragraph">')
},
}),
],
})
const result = editor.view.props.transformPastedHTML?.('<p style="color: red;"><b>test</b></p>')
expect(result).toBe('<p class="editor-paragraph"><strong>test</strong></p>')
editor.destroy()
})
})
describe('performance', () => {
it('should handle many extensions efficiently', () => {
const extensions = [Document, Paragraph, Text]
// Add 50 extensions with transforms
for (let i = 0; i < 50; i += 1) {
extensions.push(
Extension.create({
name: `extension-${i}`,
priority: 1000 - i,
transformPastedHTML(html) {
return html // Pass through
},
}),
)
}
const editor = new Editor({ extensions })
const start = Date.now()
const result = editor.view.props.transformPastedHTML?.('<p>test</p>')
const duration = Date.now() - start
expect(result).toBe('<p>test</p>')
expect(duration).toBeLessThan(100) // Should complete quickly
editor.destroy()
})
})
})

29
node_modules/@tiptap/core/src/commands/blur.ts generated vendored Normal file
View File

@@ -0,0 +1,29 @@
import type { RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
blur: {
/**
* Removes focus from the editor.
* @example editor.commands.blur()
*/
blur: () => ReturnType
}
}
}
export const blur: RawCommands['blur'] =
() =>
({ editor, view }) => {
requestAnimationFrame(() => {
if (!editor.isDestroyed) {
;(view.dom as HTMLElement).blur()
// Browsers should remove the caret on blur but safari does not.
// See: https://github.com/ueberdosis/tiptap/issues/2405
window?.getSelection()?.removeAllRanges()
}
})
return true
}

25
node_modules/@tiptap/core/src/commands/clearContent.ts generated vendored Normal file
View File

@@ -0,0 +1,25 @@
import type { RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
clearContent: {
/**
* Clear the whole document.
* @example editor.commands.clearContent()
*/
clearContent: (
/**
* Whether to emit an update event.
* @default true
*/
emitUpdate?: boolean,
) => ReturnType
}
}
}
export const clearContent: RawCommands['clearContent'] =
(emitUpdate = true) =>
({ commands }) => {
return commands.setContent('', { emitUpdate })
}

57
node_modules/@tiptap/core/src/commands/clearNodes.ts generated vendored Normal file
View File

@@ -0,0 +1,57 @@
import { liftTarget } from '@tiptap/pm/transform'
import type { RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
clearNodes: {
/**
* Normalize nodes to a simple paragraph.
* @example editor.commands.clearNodes()
*/
clearNodes: () => ReturnType
}
}
}
export const clearNodes: RawCommands['clearNodes'] =
() =>
({ state, tr, dispatch }) => {
const { selection } = tr
const { ranges } = selection
if (!dispatch) {
return true
}
ranges.forEach(({ $from, $to }) => {
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
if (node.type.isText) {
return
}
const { doc, mapping } = tr
const $mappedFrom = doc.resolve(mapping.map(pos))
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize))
const nodeRange = $mappedFrom.blockRange($mappedTo)
if (!nodeRange) {
return
}
const targetLiftDepth = liftTarget(nodeRange)
if (node.type.isTextblock) {
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index())
tr.setNodeMarkup(nodeRange.start, defaultType)
}
if (targetLiftDepth || targetLiftDepth === 0) {
tr.lift(nodeRange, targetLiftDepth)
}
})
})
return true
}

22
node_modules/@tiptap/core/src/commands/command.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import type { Command, RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
command: {
/**
* Define a command inline.
* @param fn The command function.
* @example
* editor.commands.command(({ tr, state }) => {
* ...
* return true
* })
*/
command: (fn: (props: Parameters<Command>[0]) => boolean) => ReturnType
}
}
}
export const command: RawCommands['command'] = fn => props => {
return fn(props)
}

View File

@@ -0,0 +1,21 @@
import { createParagraphNear as originalCreateParagraphNear } from '@tiptap/pm/commands'
import type { RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
createParagraphNear: {
/**
* Create a paragraph nearby.
* @example editor.commands.createParagraphNear()
*/
createParagraphNear: () => ReturnType
}
}
}
export const createParagraphNear: RawCommands['createParagraphNear'] =
() =>
({ state, dispatch }) => {
return originalCreateParagraphNear(state, dispatch)
}

36
node_modules/@tiptap/core/src/commands/cut.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
import { TextSelection } from '@tiptap/pm/state'
import type { RawCommands } from '../types.js'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
cut: {
/**
* Cuts content from a range and inserts it at a given position.
* @param range The range to cut.
* @param range.from The start position of the range.
* @param range.to The end position of the range.
* @param targetPos The position to insert the content at.
* @example editor.commands.cut({ from: 1, to: 3 }, 5)
*/
cut: ({ from, to }: { from: number; to: number }, targetPos: number) => ReturnType
}
}
}
export const cut: RawCommands['cut'] =
(originRange, targetPos) =>
({ editor, tr }) => {
const { state } = editor
const contentSlice = state.doc.slice(originRange.from, originRange.to)
tr.deleteRange(originRange.from, originRange.to)
const newPos = tr.mapping.map(targetPos)
tr.insert(newPos, contentSlice.content)
tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))))
return true
}

Some files were not shown because too many files have changed in this diff Show More