mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
convert react to vanilla js
This commit is contained in:
Generated
+26
@@ -17,6 +17,7 @@
|
||||
"@codemirror/state": "^6.5.2",
|
||||
"@codemirror/view": "^6.36.6",
|
||||
"@danharrin/alpine-mousetrap": "^0.1.6",
|
||||
"@floating-ui/dom": "^1.7.0",
|
||||
"@fontsource-variable/inter": "^5.0.18",
|
||||
"@ryangjchandler/alpine-tooltip": "^2.0",
|
||||
"@tiptap/core": "3.0.0-beta.5",
|
||||
@@ -2197,6 +2198,31 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.0.tgz",
|
||||
"integrity": "sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.0.tgz",
|
||||
"integrity": "sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.0",
|
||||
"@floating-ui/utils": "^0.2.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@fontsource-variable/inter": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.5.tgz",
|
||||
|
||||
+2
-1
@@ -25,10 +25,10 @@
|
||||
"@codemirror/state": "^6.5.2",
|
||||
"@codemirror/view": "^6.36.6",
|
||||
"@danharrin/alpine-mousetrap": "^0.1.6",
|
||||
"@floating-ui/dom": "^1.7.0",
|
||||
"@fontsource-variable/inter": "^5.0.18",
|
||||
"@ryangjchandler/alpine-tooltip": "^2.0",
|
||||
"@tiptap/core": "3.0.0-beta.5",
|
||||
"@tiptap/extensions": "3.0.0-beta.5",
|
||||
"@tiptap/extension-blockquote": "3.0.0-beta.5",
|
||||
"@tiptap/extension-bold": "3.0.0-beta.5",
|
||||
"@tiptap/extension-code": "3.0.0-beta.5",
|
||||
@@ -46,6 +46,7 @@
|
||||
"@tiptap/extension-superscript": "3.0.0-beta.5",
|
||||
"@tiptap/extension-text": "3.0.0-beta.5",
|
||||
"@tiptap/extension-underline": "3.0.0-beta.5",
|
||||
"@tiptap/extensions": "3.0.0-beta.5",
|
||||
"@tiptap/pm": "3.0.0-beta.5",
|
||||
"@tiptap/suggestion": "3.0.0-beta.5",
|
||||
"alpine-lazy-load-assets": "^1.3.0",
|
||||
|
||||
+11
-11
File diff suppressed because one or more lines are too long
+17
-17
File diff suppressed because one or more lines are too long
@@ -125,7 +125,7 @@ export default Node.create({
|
||||
|
||||
// When there are multiple types of merge tags, this attribute helps distinguish them
|
||||
mergeTagSuggestionChar: {
|
||||
default: '{{ ',
|
||||
default: '@',
|
||||
parseHTML: element => element.getAttribute('data-merge-tag-suggestion-char'),
|
||||
renderHTML: attributes => {
|
||||
return {
|
||||
|
||||
@@ -48,10 +48,7 @@ export default async ({
|
||||
$wire: () => $wire,
|
||||
}),
|
||||
MergeTag.configure({
|
||||
HTMLAttributes: {
|
||||
class: 'merge-tag',
|
||||
},
|
||||
mergeTagSuggestions,
|
||||
suggestion: mergeTagSuggestions,
|
||||
}),
|
||||
OrderedList,
|
||||
Paragraph,
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
import { computePosition, flip, shift } from '@floating-ui/dom'
|
||||
import { posToDOMRect, ReactRenderer } from '@tiptap/react'
|
||||
|
||||
const updatePosition = (editor, element) => {
|
||||
const virtualElement = {
|
||||
getBoundingClientRect: () => posToDOMRect(editor.view, editor.state.selection.from, editor.state.selection.to),
|
||||
const referenceElement = {
|
||||
getBoundingClientRect: () => {
|
||||
const { from, to } = editor.state.selection
|
||||
const start = editor.view.coordsAtPos(from)
|
||||
const end = editor.view.coordsAtPos(to)
|
||||
|
||||
return {
|
||||
top: Math.min(start.top, end.top),
|
||||
bottom: Math.max(start.bottom, end.bottom),
|
||||
left: Math.min(start.left, end.left),
|
||||
right: Math.max(start.right, end.right),
|
||||
width: Math.abs(end.right - start.left),
|
||||
height: Math.abs(end.bottom - start.top),
|
||||
x: Math.min(start.left, end.left),
|
||||
y: Math.min(start.top, end.top),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
computePosition(virtualElement, element, {
|
||||
computePosition(referenceElement, element, {
|
||||
placement: 'bottom-start',
|
||||
strategy: 'absolute',
|
||||
middleware: [shift(), flip()],
|
||||
@@ -31,67 +45,149 @@ export default {
|
||||
},
|
||||
|
||||
render: () => {
|
||||
let element
|
||||
let selectedIndex = 0
|
||||
let currentProps = null
|
||||
|
||||
const createDropdown = () => {
|
||||
const dropdown = document.createElement('div')
|
||||
dropdown.className = 'dropdown-menu'
|
||||
return dropdown
|
||||
}
|
||||
|
||||
const renderItems = () => {
|
||||
if (!element || !currentProps) return
|
||||
|
||||
const items = currentProps.items || []
|
||||
|
||||
// Clear existing items
|
||||
element.innerHTML = ''
|
||||
|
||||
if (items.length) {
|
||||
items.forEach((item, index) => {
|
||||
const button = document.createElement('button')
|
||||
button.className = index === selectedIndex ? 'is-selected' : ''
|
||||
button.textContent = item
|
||||
button.addEventListener('click', () => selectItem(index))
|
||||
element.appendChild(button)
|
||||
})
|
||||
} else {
|
||||
const noResult = document.createElement('div')
|
||||
noResult.className = 'item'
|
||||
noResult.textContent = 'No result'
|
||||
element.appendChild(noResult)
|
||||
}
|
||||
}
|
||||
|
||||
const selectItem = (index) => {
|
||||
if (!currentProps) return
|
||||
|
||||
const items = currentProps.items || []
|
||||
const item = items[index]
|
||||
|
||||
if (item) {
|
||||
currentProps.command({ id: item })
|
||||
}
|
||||
}
|
||||
|
||||
const upHandler = () => {
|
||||
if (!currentProps) return
|
||||
|
||||
const items = currentProps.items || []
|
||||
if (items.length === 0) return
|
||||
|
||||
selectedIndex = (selectedIndex + items.length - 1) % items.length
|
||||
renderItems()
|
||||
}
|
||||
|
||||
const downHandler = () => {
|
||||
if (!currentProps) return
|
||||
|
||||
const items = currentProps.items || []
|
||||
if (items.length === 0) return
|
||||
|
||||
selectedIndex = (selectedIndex + 1) % items.length
|
||||
renderItems()
|
||||
}
|
||||
|
||||
const enterHandler = () => {
|
||||
selectItem(selectedIndex)
|
||||
}
|
||||
|
||||
return {
|
||||
onStart: props => {
|
||||
// Store current props
|
||||
currentProps = props
|
||||
|
||||
// Create dropdown element
|
||||
element = createDropdown()
|
||||
element.style.position = 'absolute'
|
||||
|
||||
// Render initial items
|
||||
renderItems()
|
||||
|
||||
// Append to DOM
|
||||
document.body.appendChild(element)
|
||||
|
||||
// Reset selected index when items change
|
||||
selectedIndex = 0
|
||||
|
||||
if (!props.clientRect) {
|
||||
return
|
||||
}
|
||||
|
||||
updatePosition(props.editor, element)
|
||||
},
|
||||
|
||||
onUpdate(props) {
|
||||
// Store current props
|
||||
currentProps = props
|
||||
|
||||
// Reset selected index when items change
|
||||
selectedIndex = 0
|
||||
|
||||
// Update dropdown items
|
||||
renderItems()
|
||||
|
||||
if (!props.clientRect) {
|
||||
return
|
||||
}
|
||||
|
||||
updatePosition(props.editor, element)
|
||||
},
|
||||
|
||||
onKeyDown(props) {
|
||||
if (props.event.key === 'Escape') {
|
||||
if (element && element.parentNode) {
|
||||
element.parentNode.removeChild(element)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if (props.event.key === 'ArrowUp') {
|
||||
upHandler()
|
||||
return true
|
||||
}
|
||||
|
||||
if (props.event.key === 'ArrowDown') {
|
||||
downHandler()
|
||||
return true
|
||||
}
|
||||
|
||||
if (props.event.key === 'Enter') {
|
||||
enterHandler()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
onExit() {
|
||||
|
||||
if (element && element.parentNode) {
|
||||
element.parentNode.removeChild(element)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// let component
|
||||
//
|
||||
// return {
|
||||
// onStart: props => {
|
||||
// component = new ReactRenderer(MentionList, {
|
||||
// props,
|
||||
// editor: props.editor,
|
||||
// })
|
||||
//
|
||||
// if (!props.clientRect) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// component.element.style.position = 'absolute'
|
||||
//
|
||||
// document.body.appendChild(component.element)
|
||||
//
|
||||
// updatePosition(props.editor, component.element)
|
||||
// },
|
||||
//
|
||||
// onUpdate(props) {
|
||||
// component.updateProps(props)
|
||||
//
|
||||
// if (!props.clientRect) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// updatePosition(props.editor, component.element)
|
||||
// },
|
||||
//
|
||||
// onKeyDown(props) {
|
||||
// if (props.event.key === 'Escape') {
|
||||
// component.destroy()
|
||||
//
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// return component.ref?.onKeyDown(props)
|
||||
// },
|
||||
//
|
||||
// onExit() {
|
||||
// component.destroy()
|
||||
// },
|
||||
// }
|
||||
},
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user