Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions packages/react/storybook/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import type {Preview} from '@storybook/react-vite'

import {withPlainValue} from '../src/shared/lib/withPlainValue'

const preview: Preview = {
decorators: [withPlainValue],
globalTypes: {
showPlainValue: {
name: 'Plain Value',
description: 'Toggle plain value panel',
defaultValue: 'show',
description: 'Plain value panel position',
defaultValue: 'right',
toolbar: {
icon: 'eye',
icon: 'sidebaralt',
items: [
{value: 'show', icon: 'eye'},
{value: 'hide', icon: 'eyeclose'},
{value: 'right', title: 'Show right', icon: 'sidebaralt'},
{value: 'bottom', title: 'Show bottom', icon: 'bottombar'},
{value: 'hide', title: 'Hide', icon: 'eyeclose'},
],
},
},
Expand Down
42 changes: 16 additions & 26 deletions packages/react/storybook/src/pages/Ant/Ant.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import type {MarkProps, MarkedInputProps} from '@markput/react'
import {MarkedInput} from '@markput/react'
import type {Meta, StoryObj} from '@storybook/react-vite'
import type {TagProps} from 'antd'
import {Tag} from 'antd'
import {useState} from 'react'

import {Text} from '../../shared/components/Text'
import type {ComponentType} from 'react'

export default {
title: 'Styled/Ant',
component: MarkedInput,
}

export const Tagged = () => {
const [value, setValue] = useState(
`We preset five different colors. You can set color property such as @(success), @(processing), @(error), @(default) and @(warning) to show specific status.`
)

return (
<>
<MarkedInput
Mark={Tag}
value={value}
onChange={setValue}
options={[
{
markup: '@(__value__)',
mark: ({value}) => ({children: value, color: value, style: {marginRight: 0}}),
},
]}
/>
} satisfies Meta<typeof MarkedInput>

<Text label="Plaint text:" value={value} />
</>
)
export const Tagged: StoryObj<MarkedInputProps<TagProps>> = {
args: {
Mark: Tag as ComponentType<TagProps>,
value: `We preset five different colors. You can set color property such as @(success), @(processing), @(error), @(default) and @(warning) to show specific status.`,
options: [
{
markup: '@(__value__)',
mark: ({value}: MarkProps) => ({children: value, color: value, style: {marginRight: 0}}),
},
],
},
}
3 changes: 2 additions & 1 deletion packages/react/storybook/src/pages/Base/Base.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import {render} from 'vitest-browser-react'
import {page, userEvent} from 'vitest/browser'

import {focusAtEnd, focusAtStart} from '../../shared/lib/focus'
import {Focusable, Removable} from '../Dynamic/Dynamic.stories'
import * as DynamicStories from '../Dynamic/Dynamic.stories'
import * as BaseStories from './Base.stories'

//createVisualTests(BaseStories)

const {Default} = composeStories(BaseStories)
const {Focusable, Removable} = composeStories(DynamicStories)

describe(`Component: MarkedInput`, () => {
it.todo('should set readOnly on selection')
Expand Down
57 changes: 21 additions & 36 deletions packages/react/storybook/src/pages/Base/Base.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type {MarkProps, MarkToken, Markup} from '@markput/react'
import {denote, MarkedInput} from '@markput/react'
import type {MarkProps, MarkedInputProps, Markup, Option} from '@markput/react'
import {MarkedInput} from '@markput/react'
import type {Meta, StoryObj} from '@storybook/react-vite'
import {useState} from 'react'

import {Button} from '../../shared/components/Button'
import {Text} from '../../shared/components/Text'
import type {ButtonProps} from '../../shared/components/Button'

export default {
title: 'MarkedInput',
Expand All @@ -25,7 +24,7 @@ export const Default: Story = {
const PrimaryMarkup: Markup = '@[__value__](primary:__meta__)'
const DefaultMarkup: Markup = '@[__value__](default:__meta__)'

const configuredOptions = [
const configuredOptions: Option<ButtonProps>[] = [
{
markup: PrimaryMarkup,
mark: ({value, meta}: MarkProps) => ({label: value || '', primary: true, onClick: () => alert(meta)}),
Expand All @@ -44,38 +43,24 @@ const configuredOptions = [
},
]

export const Configured: Story = {
render: () => {
const [value, setValue] = useState(
export const Configured: StoryObj<MarkedInputProps<ButtonProps>> = {
parameters: {plainValue: 'bottom'},
args: {
Mark: Button,
options: configuredOptions,
value:
"Enter the '@' for calling @[primary](primary:4) suggestions and '/' for @[default](default:7)!\n" +
'Mark is can be a any component with any logic. In this example it is the @[Button](primary:54): clickable primary or secondary.\n' +
'For found mark used @[annotations](default:123).'
)

const displayText = denote(value, (mark: MarkToken) => mark.value, [PrimaryMarkup, DefaultMarkup])

return (
<>
<MarkedInput
Mark={Button}
options={configuredOptions}
value={value}
onChange={setValue}
slotProps={{
container: {
onClick: _ => console.log('onCLick'),
onInput: _ => console.log('onInput'),
onBlur: _ => console.log('onBlur'),
onFocus: _ => console.log('onFocus'),
onKeyDown: _ => console.log('onKeyDown'),
},
}}
/>

<Text label="Plaint text:" value={value} />
<Text label="Display text (denoted):" value={displayText} />
</>
)
'Mark is can be a any component with any logic. In this example it is the @[Button](primary:54): clickable primary or secondary.\n' +
'For found mark used @[annotations](default:123).',
slotProps: {
container: {
onClick: _ => console.log('onCLick'),
onInput: _ => console.log('onInput'),
onBlur: _ => console.log('onBlur'),
onFocus: _ => console.log('onFocus'),
onKeyDown: _ => console.log('onKeyDown'),
},
},
},
}

Expand Down
4 changes: 2 additions & 2 deletions packages/react/storybook/src/pages/Drag/Drag.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ function getBlocks(container: Element) {
return Array.from(container.querySelectorAll<HTMLElement>('[data-testid="block"]'))
}

/** Read the raw value from the <pre> rendered by the Text component */
/** Read the raw value from the PlainValuePanel's data-value attribute */
function getRawValue(container: Element) {
return container.querySelector('pre')!.textContent!
return container.querySelector<HTMLElement>('pre[data-value]')!.dataset.value!
}

/**
Expand Down
100 changes: 38 additions & 62 deletions packages/react/storybook/src/pages/Drag/Drag.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import {MarkedInput, useMark} from '@markput/react'
import type {MarkProps, MarkedInputProps, Option} from '@markput/react'
import type {Meta, StoryObj} from '@storybook/react-vite'
import type {CSSProperties, ReactNode} from 'react'
import type {CSSProperties} from 'react'
import {useState} from 'react'

import {Text} from '../../shared/components/Text'
import {DRAG_MARKDOWN} from '../../shared/lib/sampleTexts'
import {withPlainValue} from '../../shared/lib/withPlainValue'
import {markdownOptions} from '../Nested/MarkdownOptions'

export default {
Expand All @@ -27,33 +25,21 @@ type Story = StoryObj<Meta<typeof MarkedInput>>

// ─── Markdown with block-level marks (headings + list) ────────────────────────

const MarkdownMark = ({
children,
value,
style,
}: {
value?: string
children?: ReactNode
style?: React.CSSProperties
}) => <span style={{...style, margin: '0 1px'}}>{children || value}</span>

export const Markdown: Story = {
render: () => {
const [value, setValue] = useState(DRAG_MARKDOWN)

return (
<div style={{maxWidth: 700, margin: '0 auto', paddingLeft: 52}}>
<MarkedInput
Mark={MarkdownMark}
options={markdownOptions}
value={value}
onChange={setValue}
drag
style={{minHeight: 300, padding: 12, border: '1px solid #e0e0e0', borderRadius: 8}}
/>
<Text label="Raw value:" value={value} />
</div>
)
interface MarkdownMarkProps extends MarkProps {
style?: CSSProperties
}

const MarkdownMark = ({children, value, style}: MarkdownMarkProps) => (
<span style={{...style, margin: '0 1px'}}>{children || value}</span>
)

export const Markdown: StoryObj<MarkedInputProps<MarkdownMarkProps>> = {
args: {
Mark: MarkdownMark,
options: markdownOptions,
value: DRAG_MARKDOWN,
drag: true,
style: {minHeight: 300, padding: 12, border: '1px solid #e0e0e0', borderRadius: 8},
},
}

Expand Down Expand Up @@ -193,55 +179,45 @@ const TODO_VALUE = `# \u{1F4CB} Project Launch Checklist
const testStyle: React.CSSProperties = {minHeight: 100, padding: 8, border: '1px solid #e0e0e0'}

export const PlainTextDrag: Story = {
parameters: {docs: {disable: true}},
render: () => {
const [value, setValue] = useState(
'First block of plain text\n\nSecond block of plain text\n\nThird block of plain text\n\nFourth block of plain text\n\nFifth block of plain text'
)
return (
<>
<MarkedInput value={value} onChange={setValue} drag style={testStyle} />
<Text value={value} />
</>
)
parameters: {docs: {disable: true}, plainValue: 'bottom'},
args: {
value: 'First block of plain text\n\nSecond block of plain text\n\nThird block of plain text\n\nFourth block of plain text\n\nFifth block of plain text',
drag: true,
style: testStyle,
},
}

export const MarkdownDrag: Story = {
parameters: {docs: {disable: true}},
render: () => {
const [value, setValue] = useState(
'# Welcome to Draggable Blocks\n\nThis is the first paragraph.\n\nThis is the second paragraph.\n\n## Features\n\n- Drag handles appear on hover'
)
return (
<>
<MarkedInput
Mark={MarkdownMark}
options={markdownOptions}
value={value}
onChange={setValue}
drag
style={testStyle}
/>
<Text value={value} />
</>
)
export const MarkdownDrag: StoryObj<MarkedInputProps<MarkdownMarkProps>> = {
parameters: {docs: {disable: true}, plainValue: 'bottom'},
args: {
Mark: MarkdownMark,
options: markdownOptions,
value: '# Welcome to Draggable Blocks\n\nThis is the first paragraph.\n\nThis is the second paragraph.\n\n## Features\n\n- Drag handles appear on hover',
drag: true,
style: testStyle,
},
}

export const ReadOnlyDrag: Story = {
parameters: {docs: {disable: true}},
render: () => <MarkedInput value="Read-Only Content\n\nSection A\n\nSection B" readOnly drag style={testStyle} />,
args: {
value: 'Read-Only Content\n\nSection A\n\nSection B',
readOnly: true,
drag: true,
style: testStyle,
},
}

// ─── Todo list (all marks include \n\n) ───────────────────────────────────────

export const TodoList: StoryObj<MarkedInputProps<TodoMarkProps>> = {
decorators: [withPlainValue],
args: {
Mark: TodoMark,
options: todoOptions,
value: TODO_VALUE,
drag: true,
},
parameters: {
plainValue: 'right',
},
}
Loading
Loading