Some checks failed
ci / changes (push) Has been cancelled
ci / lint (push) Has been cancelled
ci / build (push) Has been cancelled
ci / tests-unit (push) Has been cancelled
ci / tests-types (push) Has been cancelled
ci / int-cosmosdb (push) Has been cancelled
ci / int-documentdb (push) Has been cancelled
ci / int-firestore (push) Has been cancelled
ci / int-mongodb (push) Has been cancelled
ci / int-postgres (push) Has been cancelled
ci / int-postgres-custom-schema (push) Has been cancelled
ci / int-postgres-uuid (push) Has been cancelled
ci / int-sqlite (push) Has been cancelled
ci / int-sqlite-uuid (push) Has been cancelled
ci / int-supabase (push) Has been cancelled
ci / e2e-_community (push) Has been cancelled
ci / e2e-access-control (push) Has been cancelled
ci / e2e-admin-bar (push) Has been cancelled
ci / e2e-admin-root (push) Has been cancelled
ci / e2e-admin__e2e__document-view (push) Has been cancelled
ci / e2e-admin__e2e__general (push) Has been cancelled
ci / e2e-admin__e2e__list-view (push) Has been cancelled
ci / e2e-auth (push) Has been cancelled
ci / e2e-auth-basic (push) Has been cancelled
ci / e2e-bulk-edit (push) Has been cancelled
ci / e2e-field-error-states (push) Has been cancelled
ci / e2e-fields-relationship (push) Has been cancelled
ci / e2e-fields__collections__Array (push) Has been cancelled
ci / e2e-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-fields__collections__Blocks (push) Has been cancelled
ci / e2e-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-fields__collections__CustomID (push) Has been cancelled
ci / e2e-fields__collections__Date (push) Has been cancelled
ci / e2e-fields__collections__Email (push) Has been cancelled
ci / e2e-fields__collections__Indexed (push) Has been cancelled
ci / e2e-fields__collections__JSON (push) Has been cancelled
ci / e2e-fields__collections__Number (push) Has been cancelled
ci / e2e-fields__collections__Point (push) Has been cancelled
ci / e2e-fields__collections__Radio (push) Has been cancelled
ci / e2e-fields__collections__Relationship (push) Has been cancelled
ci / e2e-fields__collections__Row (push) Has been cancelled
ci / e2e-fields__collections__Select (push) Has been cancelled
ci / e2e-fields__collections__Tabs (push) Has been cancelled
ci / e2e-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-fields__collections__Text (push) Has been cancelled
ci / e2e-fields__collections__UI (push) Has been cancelled
ci / e2e-fields__collections__Upload (push) Has been cancelled
ci / e2e-folders (push) Has been cancelled
ci / e2e-form-state (push) Has been cancelled
ci / e2e-group-by (push) Has been cancelled
ci / e2e-hooks (push) Has been cancelled
ci / e2e-i18n (push) Has been cancelled
ci / e2e-joins (push) Has been cancelled
ci / e2e-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-lexical__collections__RichText (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-live-preview (push) Has been cancelled
ci / e2e-localization (push) Has been cancelled
ci / e2e-locked-documents (push) Has been cancelled
ci / e2e-plugin-cloud-storage (push) Has been cancelled
ci / e2e-plugin-form-builder (push) Has been cancelled
ci / e2e-plugin-import-export (push) Has been cancelled
ci / e2e-plugin-multi-tenant (push) Has been cancelled
ci / e2e-plugin-nested-docs (push) Has been cancelled
ci / e2e-plugin-seo (push) Has been cancelled
ci / e2e-query-presets (push) Has been cancelled
ci / e2e-sort (push) Has been cancelled
ci / e2e-trash (push) Has been cancelled
ci / e2e-uploads (push) Has been cancelled
ci / e2e-versions (push) Has been cancelled
ci / e2e-turbo-_community (push) Has been cancelled
ci / e2e-turbo-access-control (push) Has been cancelled
ci / e2e-turbo-admin-bar (push) Has been cancelled
ci / e2e-turbo-admin-root (push) Has been cancelled
ci / e2e-turbo-admin__e2e__document-view (push) Has been cancelled
ci / e2e-turbo-admin__e2e__general (push) Has been cancelled
ci / e2e-turbo-admin__e2e__list-view (push) Has been cancelled
ci / e2e-turbo-auth (push) Has been cancelled
ci / e2e-turbo-auth-basic (push) Has been cancelled
ci / e2e-turbo-bulk-edit (push) Has been cancelled
ci / e2e-turbo-field-error-states (push) Has been cancelled
ci / e2e-turbo-fields-relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Array (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks (push) Has been cancelled
ci / e2e-turbo-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-turbo-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-turbo-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-turbo-fields__collections__CustomID (push) Has been cancelled
ci / e2e-turbo-fields__collections__Date (push) Has been cancelled
ci / e2e-turbo-fields__collections__Email (push) Has been cancelled
ci / e2e-turbo-fields__collections__Indexed (push) Has been cancelled
ci / e2e-turbo-fields__collections__JSON (push) Has been cancelled
ci / e2e-turbo-fields__collections__Number (push) Has been cancelled
ci / e2e-turbo-fields__collections__Point (push) Has been cancelled
ci / e2e-turbo-fields__collections__Radio (push) Has been cancelled
ci / e2e-turbo-fields__collections__Relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Row (push) Has been cancelled
ci / e2e-turbo-fields__collections__Select (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-turbo-fields__collections__Text (push) Has been cancelled
ci / e2e-turbo-fields__collections__UI (push) Has been cancelled
ci / e2e-turbo-fields__collections__Upload (push) Has been cancelled
ci / e2e-turbo-folders (push) Has been cancelled
ci / e2e-turbo-form-state (push) Has been cancelled
ci / e2e-turbo-group-by (push) Has been cancelled
ci / e2e-turbo-hooks (push) Has been cancelled
ci / e2e-turbo-i18n (push) Has been cancelled
ci / e2e-turbo-joins (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-turbo-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-turbo-lexical__collections__RichText (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-turbo-live-preview (push) Has been cancelled
ci / e2e-turbo-localization (push) Has been cancelled
ci / e2e-turbo-locked-documents (push) Has been cancelled
ci / e2e-turbo-plugin-cloud-storage (push) Has been cancelled
ci / e2e-turbo-plugin-form-builder (push) Has been cancelled
ci / e2e-turbo-plugin-import-export (push) Has been cancelled
ci / e2e-turbo-plugin-multi-tenant (push) Has been cancelled
ci / e2e-turbo-plugin-nested-docs (push) Has been cancelled
ci / e2e-turbo-plugin-seo (push) Has been cancelled
ci / e2e-turbo-query-presets (push) Has been cancelled
ci / e2e-turbo-sort (push) Has been cancelled
ci / e2e-turbo-trash (push) Has been cancelled
ci / e2e-turbo-uploads (push) Has been cancelled
ci / e2e-turbo-versions (push) Has been cancelled
ci / build-template-blank-mongodb (push) Has been cancelled
ci / build-template-website-mongodb (push) Has been cancelled
ci / build-template-with-payload-cloud-mongodb (push) Has been cancelled
ci / build-template-with-vercel-mongodb-mongodb (push) Has been cancelled
ci / build-template-plugin- (push) Has been cancelled
ci / build-template-with-postgres-postgres (push) Has been cancelled
ci / build-template-with-vercel-postgres-postgres (push) Has been cancelled
ci / tests-type-generation (push) Has been cancelled
ci / All Green (push) Has been cancelled
ci / Publish Canary (push) Has been cancelled
ci / analyze (push) Has been cancelled
publish-prerelease / publish-prerelease-${{ github.ref_name }}-${{ github.sha }} (push) Has been cancelled
lock-issues / lock_issues (push) Has been cancelled
stale / stale (push) Has been cancelled
audit-dependencies / audit (push) Has been cancelled
activity-notifications / run (push) Has been cancelled
137 lines
4.2 KiB
TypeScript
137 lines
4.2 KiB
TypeScript
'use client'
|
|
|
|
import type { FormState } from 'tbsh-cms'
|
|
|
|
import {
|
|
useDocumentInfo,
|
|
useDrawerSlug,
|
|
useModal,
|
|
useServerFunctions,
|
|
useTranslation,
|
|
} from '@tabshiftcms/ui'
|
|
import { reduceFieldsToValues } from 'tbsh-cms/shared'
|
|
import React, { Fragment, useState } from 'react'
|
|
import { Editor, Range, Transforms } from 'slate'
|
|
import { ReactEditor, useSlate } from 'slate-react'
|
|
|
|
import { LinkIcon } from '../../../icons/Link/index.js'
|
|
import { useElementButton } from '../../../providers/ElementButtonProvider.js'
|
|
import { ElementButton } from '../../Button.js'
|
|
import { isElementActive } from '../../isActive.js'
|
|
import { LinkDrawer } from '../LinkDrawer/index.js'
|
|
import { linkFieldsSchemaPath } from '../shared.js'
|
|
import { unwrapLink } from '../utilities.js'
|
|
|
|
/**
|
|
* This function is called when a new link is created - not when an existing link is edited.
|
|
*/
|
|
const insertLink = (editor, fields) => {
|
|
const isCollapsed = editor.selection && Range.isCollapsed(editor.selection)
|
|
const data = reduceFieldsToValues(fields, true)
|
|
|
|
const newLink = {
|
|
type: 'link',
|
|
children: [],
|
|
doc: data.doc,
|
|
fields: data.fields, // Any custom user-added fields are part of data.fields
|
|
linkType: data.linkType,
|
|
newTab: data.newTab,
|
|
url: data.url,
|
|
}
|
|
|
|
if (isCollapsed || !editor.selection) {
|
|
// If selection anchor and focus are the same,
|
|
// Just inject a new node with children already set
|
|
Transforms.insertNodes(editor, {
|
|
...newLink,
|
|
children: [{ text: String(data.text) }],
|
|
})
|
|
} else if (editor.selection) {
|
|
// Otherwise we need to wrap the selected node in a link,
|
|
// Delete its old text,
|
|
// Move the selection one position forward into the link,
|
|
// And insert the text back into the new link
|
|
Transforms.wrapNodes(editor, newLink, { split: true })
|
|
Transforms.delete(editor, { at: editor.selection.focus.path, unit: 'word' })
|
|
Transforms.move(editor, { distance: 1, unit: 'offset' })
|
|
Transforms.insertText(editor, String(data.text), { at: editor.selection.focus.path })
|
|
}
|
|
|
|
ReactEditor.focus(editor)
|
|
}
|
|
|
|
export const LinkButton: React.FC<{
|
|
schemaPath: string
|
|
}> = ({ schemaPath }) => {
|
|
const { fieldProps } = useElementButton()
|
|
const [initialState, setInitialState] = useState<FormState>({})
|
|
|
|
const { t } = useTranslation()
|
|
const editor = useSlate()
|
|
const { getFormState } = useServerFunctions()
|
|
const { collectionSlug, getDocPreferences, globalSlug } = useDocumentInfo()
|
|
|
|
const { closeModal, openModal } = useModal()
|
|
const drawerSlug = useDrawerSlug('rich-text-link')
|
|
|
|
const { componentMap } = fieldProps
|
|
|
|
const fields = componentMap[linkFieldsSchemaPath]
|
|
|
|
return (
|
|
<Fragment>
|
|
<ElementButton
|
|
className="link"
|
|
format="link"
|
|
onClick={async () => {
|
|
if (isElementActive(editor, 'link')) {
|
|
unwrapLink(editor)
|
|
} else {
|
|
openModal(drawerSlug)
|
|
const isCollapsed = editor.selection && Range.isCollapsed(editor.selection)
|
|
|
|
if (!isCollapsed) {
|
|
const data = {
|
|
text: editor.selection ? Editor.string(editor, editor.selection) : '',
|
|
}
|
|
|
|
const { state } = await getFormState({
|
|
collectionSlug,
|
|
data,
|
|
docPermissions: {
|
|
fields: true,
|
|
},
|
|
docPreferences: await getDocPreferences(),
|
|
globalSlug,
|
|
operation: 'update',
|
|
renderAllFields: true,
|
|
schemaPath: [...schemaPath.split('.'), ...linkFieldsSchemaPath.split('.')].join(
|
|
'.',
|
|
),
|
|
})
|
|
|
|
setInitialState(state)
|
|
}
|
|
}
|
|
}}
|
|
tooltip={t('fields:addLink')}
|
|
>
|
|
<LinkIcon />
|
|
</ElementButton>
|
|
<LinkDrawer
|
|
drawerSlug={drawerSlug}
|
|
fields={Array.isArray(fields) ? fields : []}
|
|
handleClose={() => {
|
|
closeModal(drawerSlug)
|
|
}}
|
|
handleModalSubmit={(fields) => {
|
|
insertLink(editor, fields)
|
|
closeModal(drawerSlug)
|
|
}}
|
|
initialState={initialState}
|
|
schemaPath={schemaPath}
|
|
/>
|
|
</Fragment>
|
|
)
|
|
}
|