You've already forked AstralRinth
forked from didirus/AstralRinth
fix: markdown editor scroll issues with max-height (#5031)
* add markdown editor stories to show scrolling bug * add story * update story content * fix markdown editor scroll * fix space * lint
This commit is contained in:
@@ -67,15 +67,6 @@ textarea,
|
|||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:focus-visible {
|
|
||||||
box-shadow:
|
|
||||||
inset 0 0 0 transparent,
|
|
||||||
0 0 0 0.25rem var(--color-brand-shadow);
|
|
||||||
color: var(--color-contrast);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled,
|
&:disabled,
|
||||||
&[disabled] {
|
&[disabled] {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<Button :action="() => linkModal?.hide()"><XIcon /> Cancel</Button>
|
<Button :action="() => linkModal?.hide()"><XIcon /> Cancel</Button>
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
:disabled="linkValidationErrorMessage || !linkUrl"
|
:disabled="!!linkValidationErrorMessage || !linkUrl"
|
||||||
:action="
|
:action="
|
||||||
() => {
|
() => {
|
||||||
if (editor) markdownCommands.replaceSelection(editor, linkMarkdown)
|
if (editor) markdownCommands.replaceSelection(editor, linkMarkdown)
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
<Button :action="() => videoModal?.hide()"><XIcon /> Cancel</Button>
|
<Button :action="() => videoModal?.hide()"><XIcon /> Cancel</Button>
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
:disabled="linkValidationErrorMessage || !linkUrl"
|
:disabled="!!linkValidationErrorMessage || !linkUrl"
|
||||||
:action="
|
:action="
|
||||||
() => {
|
() => {
|
||||||
if (editor) markdownCommands.replaceSelection(editor, videoMarkdown)
|
if (editor) markdownCommands.replaceSelection(editor, videoMarkdown)
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="editorRef" :class="{ hide: previewMode }" />
|
<div ref="editorRef" :class="{ hide: previewMode }" />
|
||||||
<div v-if="!previewMode" class="info-blurb">
|
<div v-if="!previewMode" class="info-blurb mt-2">
|
||||||
<div class="info-blurb">
|
<div class="info-blurb">
|
||||||
<InfoIcon />
|
<InfoIcon />
|
||||||
<span
|
<span
|
||||||
@@ -345,19 +345,32 @@ onMounted(() => {
|
|||||||
|
|
||||||
const theme = EditorView.theme({
|
const theme = EditorView.theme({
|
||||||
// in defaults.scss there's references to .cm-content and such to inherit global styles
|
// in defaults.scss there's references to .cm-content and such to inherit global styles
|
||||||
|
'&': {
|
||||||
|
borderRadius: 'var(--radius-md)',
|
||||||
|
background: 'var(--color-button-bg)',
|
||||||
|
border: '0.25rem solid transparent',
|
||||||
|
transition: 'border-color 0.1s ease-in-out',
|
||||||
|
},
|
||||||
|
'&.cm-focused': {
|
||||||
|
'box-shadow': 'inset 0 0 0 transparent, 0 0 0 0.25rem var(--color-brand-shadow)',
|
||||||
|
color: 'var(--color-contrast)',
|
||||||
|
outline: 'none',
|
||||||
|
},
|
||||||
|
'.cm-focused': {
|
||||||
|
border: 'none',
|
||||||
|
},
|
||||||
'.cm-content': {
|
'.cm-content': {
|
||||||
marginBlockEnd: '0.5rem',
|
marginBlockEnd: '0.5rem',
|
||||||
padding: '0.5rem',
|
padding: '0.5rem',
|
||||||
minHeight: '200px',
|
minHeight: '200px',
|
||||||
caretColor: 'var(--color-contrast)',
|
caretColor: 'var(--color-contrast)',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
overflowX: 'scroll',
|
|
||||||
maxHeight: props.maxHeight ? `${props.maxHeight}px` : 'unset',
|
|
||||||
overflowY: 'scroll',
|
|
||||||
},
|
},
|
||||||
'.cm-scroller': {
|
'.cm-scroller': {
|
||||||
|
borderRadius: 'var(--radius-md)',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
overflow: 'visible',
|
maxHeight: props.maxHeight ? `${props.maxHeight}px` : 'unset',
|
||||||
|
overflow: 'auto',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -581,23 +594,35 @@ watch(
|
|||||||
editorThemeCompartment.reconfigure(
|
editorThemeCompartment.reconfigure(
|
||||||
EditorView.theme({
|
EditorView.theme({
|
||||||
// in defaults.scss there's references to .cm-content and such to inherit global styles
|
// in defaults.scss there's references to .cm-content and such to inherit global styles
|
||||||
|
'&': {
|
||||||
|
borderRadius: 'var(--radius-md)',
|
||||||
|
background: 'var(--color-button-bg)',
|
||||||
|
border: '0.25rem solid transparent',
|
||||||
|
transition: 'border-color 0.1s ease-in-out',
|
||||||
|
},
|
||||||
|
'&.cm-focused': {
|
||||||
|
'box-shadow': 'inset 0 0 0 transparent, 0 0 0 0.25rem var(--color-brand-shadow)',
|
||||||
|
color: 'var(--color-contrast)',
|
||||||
|
outline: 'none',
|
||||||
|
},
|
||||||
|
'.cm-focused': {
|
||||||
|
border: 'none',
|
||||||
|
},
|
||||||
'.cm-content': {
|
'.cm-content': {
|
||||||
marginBlockEnd: '0.5rem',
|
marginBlockEnd: '0.5rem',
|
||||||
padding: '0.5rem',
|
padding: '0.5rem',
|
||||||
minHeight: '200px',
|
minHeight: '200px',
|
||||||
caretColor: 'var(--color-contrast)',
|
caretColor: 'var(--color-contrast)',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
overflowX: 'scroll',
|
|
||||||
maxHeight: props.maxHeight ? `${props.maxHeight}px` : 'unset',
|
|
||||||
overflowY: 'scroll',
|
|
||||||
|
|
||||||
opacity: newValue ? 0.6 : 1,
|
opacity: newValue ? 0.6 : 1,
|
||||||
pointerEvents: newValue ? 'none' : 'all',
|
pointerEvents: newValue ? 'none' : 'all',
|
||||||
cursor: newValue ? 'not-allowed' : 'auto',
|
cursor: newValue ? 'not-allowed' : 'auto',
|
||||||
},
|
},
|
||||||
'.cm-scroller': {
|
'.cm-scroller': {
|
||||||
|
borderRadius: 'var(--radius-md)',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
overflow: 'visible',
|
maxHeight: props.maxHeight ? `${props.maxHeight}px` : 'unset',
|
||||||
|
overflow: 'auto',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -957,8 +982,4 @@ function openVideoModal() {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.cm-content) {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,6 +10,48 @@ const meta = {
|
|||||||
|
|
||||||
export default meta
|
export default meta
|
||||||
|
|
||||||
|
const CONTENT = `# Sample Markdown Document
|
||||||
|
|
||||||
|
This is a demonstration of the markdown editor component.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
The editor supports various markdown formatting options:
|
||||||
|
|
||||||
|
- **Bold text** for emphasis
|
||||||
|
- *Italic text* for subtle emphasis
|
||||||
|
- \`Inline code\` for technical terms
|
||||||
|
- [Links](https://example.com) for references
|
||||||
|
|
||||||
|
## Code Blocks
|
||||||
|
|
||||||
|
\`\`\`javascript
|
||||||
|
function greet(name) {
|
||||||
|
return \`Hello, \${name}!\`;
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
1. First item
|
||||||
|
2. Second item
|
||||||
|
3. Third item
|
||||||
|
|
||||||
|
### Nested Lists
|
||||||
|
|
||||||
|
- Parent item
|
||||||
|
- Child item
|
||||||
|
- Another child
|
||||||
|
- Another parent
|
||||||
|
|
||||||
|
## Blockquotes
|
||||||
|
|
||||||
|
> This is a blockquote that can be used for callouts or citations.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
This content demonstrates the editor's capabilities.`
|
||||||
|
|
||||||
export const Default: StoryObj = {
|
export const Default: StoryObj = {
|
||||||
render: () => ({
|
render: () => ({
|
||||||
components: { MarkdownEditor },
|
components: { MarkdownEditor },
|
||||||
@@ -17,7 +59,7 @@ export const Default: StoryObj = {
|
|||||||
const content = ref('# Hello World\n\nThis is some **markdown** content.')
|
const content = ref('# Hello World\n\nThis is some **markdown** content.')
|
||||||
return { content }
|
return { content }
|
||||||
},
|
},
|
||||||
template: `
|
template: /*html*/ `
|
||||||
<div class="h-96">
|
<div class="h-96">
|
||||||
<MarkdownEditor v-model="content" />
|
<MarkdownEditor v-model="content" />
|
||||||
</div>
|
</div>
|
||||||
@@ -32,10 +74,40 @@ export const WithPlaceholder: StoryObj = {
|
|||||||
const content = ref('')
|
const content = ref('')
|
||||||
return { content }
|
return { content }
|
||||||
},
|
},
|
||||||
template: `
|
template: /*html*/ `
|
||||||
<div class="h-96">
|
<div class="h-96">
|
||||||
<MarkdownEditor v-model="content" placeholder="Write your description here..." />
|
<MarkdownEditor v-model="content" placeholder="Write your description here..." />
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const WithContent: StoryObj = {
|
||||||
|
render: () => ({
|
||||||
|
components: { MarkdownEditor },
|
||||||
|
setup() {
|
||||||
|
const content = ref(CONTENT)
|
||||||
|
return { content }
|
||||||
|
},
|
||||||
|
template: /*html*/ `
|
||||||
|
<div>
|
||||||
|
<MarkdownEditor v-model="content" />
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MaxHeightWithScroll: StoryObj = {
|
||||||
|
render: () => ({
|
||||||
|
components: { MarkdownEditor },
|
||||||
|
setup() {
|
||||||
|
const content = ref(CONTENT)
|
||||||
|
return { content }
|
||||||
|
},
|
||||||
|
template: /*html*/ `
|
||||||
|
<div>
|
||||||
|
<MarkdownEditor v-model="content" :max-height="300" />
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user