import React from 'react'
import { IntlProvider } from 'react-intl'
import { ComposableEditor } from '@atlaskit/editor-core/composable-editor'
import { EditorContext } from '@atlaskit/editor-core/editor-context'
import { useUniversalPreset } from '@atlaskit/editor-core/preset-universal'
import { usePreset } from '@atlaskit/editor-core/use-preset'
import { codeBlockAdvancedPlugin } from '@atlaskit/editor-plugin-code-block-advanced'
import { editorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode'
import { selectionExtensionPlugin } from '@atlaskit/editor-plugin-selection-extension'
import { selectionMarkerPlugin } from '@atlaskit/editor-plugin-selection-marker'
import AppIcon from '@atlaskit/icon/core/app'
import { SmartCardProvider } from '@atlaskit/link-provider'
const mentionProvider: any = Promise.resolve({
shouldHighlightMention: () => true,
filter: () => Promise.resolve([])
})
const mediaProvider: any = Promise.resolve({
uploadMediaClientConfig: {
authProvider: () =>
Promise.resolve({
"clientId": 'latest',
token: '',
baseUrl: 'https://api.mock.com/api/attributes/v1/files/upload',
expiresAt: Date.now() + 1000000
})
},
viewMediaClientConfig: {
authProvider: () =>
Promise.resolve({
"client-id": 'latest',
token: '',
baseUrl: 'https://api.mock.com/api/attributes/v1/files/upload',
expiresAt: Date.now() + 1000000
})
},
uploadParams: {
collection: 'demo-collection'
}
})
const smartLinksProvider: any = {
resolve: () => Promise.resolve({}),
register: () => {},
unregister: () => {}
}
function ComposableEditorPage() {
let currentADF: any = null
const universalPreset = useUniversalPreset({
props: {
allowBorderMark: true,
allowStatus: true,
allowTasksAndDecisions: true,
allowAnalyticsGASV3: true,
allowExpand: {
allowInsertion: true,
allowInteractiveExpand: true
},
allowFragmentMark: true,
allowExtension: {
allowExtendFloatingToolbars: true
},
allowBreakout: true,
allowLayouts: { allowBreakout: true },
allowDate: true,
allowRule: true,
allowPanel: { allowCustomPanel: true, allowCustomPanelEdit: true },
allowFindReplace: true,
media: {
provider: mediaProvider,
allowMediaSingle: true,
enableDownloadButton: true,
allowResizing: true,
allowLinking: true,
allowResizingInTables: true,
allowAltTextOnImages: true,
allowCaptions: true,
allowMediaInlineImages: true,
allowImagePreview: true,
featureFlags: {
mediaInline: true
}
},
elementBrowser: {
showModal: true,
replacePlusMenu: true
},
linking: {
smartLinks: {
allowBlockCards: true,
allowEmbeds: true,
allowResizing: true,
provider: Promise.resolve(smartLinksProvider)
}
},
__livePage: true,
featureFlags: {
'nested-expand-in-expand-ex': true,
'table-drag-and-drop': true,
'quick-insert': true
},
allowTemplatePlaceholders: true
},
initialPluginConfiguration: {
tasksAndDecisionsPlugin: {
hasEditPermission: false
}
}
})
console.log(universalPreset)
const { preset } = usePreset(
() =>
universalPreset
.add([editorViewModePlugin, { initialContentMode: 'live-edit' }])
.add(selectionMarkerPlugin)
.add(codeBlockAdvancedPlugin)
.add([
selectionExtensionPlugin,
{
pageModes: ['view', 'live-view', 'edit', 'live-edit'],
extensions: {
firstParty: [
{
name: 'Create Jira Issue',
onClick: params => console.log('Clicked:', params)
}
],
external: [
{
name: 'App 1',
icon: AppIcon,
onClick: params => console.log('External App Clicked:', params)
}
]
}
}
]),
[universalPreset]
)
const onDocumentChanged = (adf: any) => {
currentADF = adf?.state?.doc || null
}
const handleSave = () => {
console.log('Document saved:', currentADF)
}
const handleCancel = () => {
alert('Edit canceled!')
}
return (
<div>
<SmartCardProvider client={smartLinksProvider}>
<IntlProvider locale={'en'}>
<ComposableEditor
preset={preset}
onChange={adf => onDocumentChanged(adf)}
mentionProvider={mentionProvider}
__livePage={true}
/>
</IntlProvider>
</SmartCardProvider>
{/* Save and Cancel Buttons */}
<div style={{ marginTop: '16px', display: 'flex', gap: '8px' }}>
<button
onClick={handleSave}
style={{
padding: '8px 16px',
backgroundColor: '#0052CC',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Save
</button>
<button
onClick={handleCancel}
style={{
padding: '8px 16px',
backgroundColor: '#FF5630',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Cancel
</button>
</div>
</div>
)
}
export default function ComposableEditorPageWrapper() {
return (
<EditorContext>
<ComposableEditorPage />
</EditorContext>
)
}
How do I create custom media plugin