webapp/src/components/Editor/Editor.stories.tsx

147 lines
3.9 KiB
TypeScript
Raw Normal View History

2024-09-19 16:51:56 +00:00
import { Editor, EditorOptions } from '@tiptap/core'
2024-09-15 23:41:48 +00:00
import { createSignal } from 'solid-js'
import { createStore } from 'solid-js/store'
import { Meta, StoryObj } from 'storybook-solidjs'
import { EditorContext, EditorContextType, ShoutForm } from '~/context/editor'
import { LocalizeContext, LocalizeContextType } from '~/context/localize'
import { SessionContext, SessionContextType } from '~/context/session'
import { SnackbarContext, SnackbarContextType } from '~/context/ui'
2024-09-16 00:09:07 +00:00
import { EditorComponent, EditorComponentProps } from './Editor'
2024-09-15 23:41:48 +00:00
2024-09-19 16:51:56 +00:00
// Mock data
2024-09-15 23:41:48 +00:00
const mockSession = {
session: () => ({
user: {
app_data: {
profile: {
name: 'Test User',
slug: 'test-user'
}
}
},
access_token: 'mock-access-token'
})
}
const mockLocalize = {
t: (key: string) => key,
lang: () => 'en'
}
const [_form, setForm] = createStore<ShoutForm>({
body: '',
slug: '',
shoutId: 0,
title: '',
selectedTopics: []
})
const [_formErrors, setFormErrors] = createStore({} as Record<keyof ShoutForm, string>)
const [editor, setEditor] = createSignal<Editor | undefined>()
2024-09-19 16:51:56 +00:00
2024-09-15 23:41:48 +00:00
const mockEditorContext: EditorContextType = {
countWords: () => 0,
2024-09-19 16:51:56 +00:00
isEditorPanelVisible: () => false,
wordCounter: () => ({ characters: 0, words: 0 }),
form: _form,
formErrors: _formErrors,
createEditor: (opts?: Partial<EditorOptions>) => {
const newEditor = new Editor(opts)
setEditor(newEditor)
return newEditor
2024-09-15 23:41:48 +00:00
},
editor,
2024-09-19 16:51:56 +00:00
saveShout: async (_form: ShoutForm) => {
// Simulate save
2024-09-15 23:41:48 +00:00
},
2024-09-19 16:51:56 +00:00
saveDraft: async (_form: ShoutForm) => {
// Simulate save draft
2024-09-15 23:41:48 +00:00
},
2024-09-19 16:51:56 +00:00
saveDraftToLocalStorage: (_form: ShoutForm) => {
// Simulate save to local storage
2024-09-15 23:41:48 +00:00
},
2024-09-19 16:51:56 +00:00
getDraftFromLocalStorage: (_shoutId: number): ShoutForm => _form,
publishShout: async (_form: ShoutForm) => {
// Simulate publish
2024-09-15 23:41:48 +00:00
},
2024-09-19 16:51:56 +00:00
publishShoutById: async (_shoutId: number) => {
// Simulate publish by ID
2024-09-15 23:41:48 +00:00
},
2024-09-19 16:51:56 +00:00
deleteShout: async (_shoutId: number): Promise<boolean> => true,
toggleEditorPanel: () => {
// Simulate toggle
2024-09-15 23:41:48 +00:00
},
setForm,
setFormErrors
}
const mockSnackbarContext = {
showSnackbar: console.log
}
const meta: Meta<typeof EditorComponent> = {
title: 'Components/Editor',
component: EditorComponent,
argTypes: {
shoutId: {
control: 'number',
description: 'Unique identifier for the shout (document)',
defaultValue: 1
},
initialContent: {
control: 'text',
description: 'Initial content for the editor',
defaultValue: ''
},
onChange: {
action: 'contentChanged',
description: 'Callback when the content changes'
},
disableCollaboration: {
control: 'boolean',
description: 'Disable collaboration features for Storybook',
defaultValue: true
}
}
}
export default meta
type Story = StoryObj<typeof EditorComponent>
export const Default: Story = {
2024-09-16 00:09:07 +00:00
render: (props: EditorComponentProps) => {
const [_content, setContent] = createSignal(props.initialContent || '')
2024-09-15 23:41:48 +00:00
return (
<SessionContext.Provider value={mockSession as SessionContextType}>
<LocalizeContext.Provider value={mockLocalize as LocalizeContextType}>
<SnackbarContext.Provider value={mockSnackbarContext as SnackbarContextType}>
<EditorContext.Provider value={mockEditorContext as EditorContextType}>
<EditorComponent
2024-09-16 00:09:07 +00:00
{...props}
2024-09-15 23:41:48 +00:00
onChange={(text: string) => {
2024-09-16 00:09:07 +00:00
props.onChange(text)
2024-09-15 23:41:48 +00:00
setContent(text)
}}
/>
</EditorContext.Provider>
</SnackbarContext.Provider>
</LocalizeContext.Provider>
</SessionContext.Provider>
)
},
args: {
shoutId: 1,
initialContent: '',
disableCollaboration: true
}
}
export const WithInitialContent: Story = {
...Default,
args: {
...Default.args,
initialContent: '<p>This is some initial content in the editor.</p>'
}
}