Skip to content

Commit

Permalink
enh(NcRichText): make checkbox interactive
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy committed Jan 18, 2024
1 parent 13b441e commit cf65011
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
34 changes: 31 additions & 3 deletions src/components/NcRichText/NcRichText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,17 @@ textarea {
This component can support [Github Flavored Markdown](https://github.github.com/gfm/).
It adds such elements, as tables, task lists, strikethrough, and supports autolinks by default

It is also possible to make a rendered content interactive and listen for events

```vue
<template>
<div>
<textarea v-model="text" />

<NcRichText :text="text" :use-extended-markdown="true"/>
<NcRichText :text="text"
:use-extended-markdown="true"
:interactive="true"
@interacted="handleInteraction"/>
</div>
</template>
<script>
Expand All @@ -109,6 +114,16 @@ Table row | value A | value B
`,
}
},
methods: {
handleInteraction(event) {
const uncheckedItem = '- [ ] ' + event.label + '\n'
const checkedItem = '- [x] ' + event.label + '\n'

this.text = event.value
? this.text.replace(uncheckedItem, checkedItem)
: this.text.replace(checkedItem, uncheckedItem)
},
},
}
</script>
<style lang="scss">
Expand Down Expand Up @@ -278,6 +293,7 @@ import NcReferenceList from './NcReferenceList.vue'
import NcCheckboxRadioSwitch from '../NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue'
import { remarkAutolink } from './autolink.js'
import { remarkPlaceholder, prepareTextNode } from './placeholder.js'
import GenRandomId from '../../utils/GenRandomId.js'

import { unified } from 'unified'
import remarkParse from 'remark-parse'
Expand Down Expand Up @@ -346,11 +362,17 @@ export default {
type: Boolean,
default: false,
},
/** Provide event from rendered markdown inputs */
interactive: {
type: Boolean,
default: false,
},
autolink: {
type: Boolean,
default: true,
},
},
emits: ['interacted'],
methods: {
renderPlaintext() {
const placeholders = this.text.split(/(\{[a-z\-_.0-9]+\})/ig).map((entry) => {
Expand Down Expand Up @@ -446,12 +468,18 @@ export default {
if (!String(type).startsWith('#')) {
if (this.useExtendedMarkdown) {
if (String(type) === 'li' && Array.isArray(children)
&& String(children[0].type) === 'input'
&& children[0].props?.type === 'checkbox') {
&& String(children?.[0]?.type) === 'input'
&& children?.[0]?.props?.type === 'checkbox') {
const [inputNode, , label] = children
const id = 'markdown-input-' + GenRandomId(5)
const inputComponent = h(NcCheckboxRadioSwitch, {
...inputNode.props,
id,
disabled: !this.interactive,
modelValue: inputNode.props.checked,
'onUpdate:model-value': (value) => {
this.$emit('interacted', { id, label, value })
},
}, label)
return h(type, props, inputComponent)
}
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/components/NcRichText/NcRichText.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,24 @@ describe('Foo', () => {
})
expect(wrapper.text()).toEqual('**Testwith** a ~~link~~ *to* [Link](https://example:1337) - go visit it')
})

it('formats interactive checkbox with extended markdown', async() => {
const wrapper = mount(NcRichText, {
props: {
text: '- [ ] task item',
useExtendedMarkdown: true,
interactive: true,
}
})
expect(wrapper.text()).toEqual('task item')
const checkbox = wrapper.findComponent({name: 'NcCheckboxRadioSwitch'})
expect(checkbox.exists()).toBeTruthy()
await checkbox.vm.$emit('update:model-value', true)
expect(wrapper.emitted().interacted).toBeTruthy()
expect(wrapper.emitted().interacted[0][0]).toMatchObject({
id: expect.anything(),
label: 'task item',
value: true,
})
})
})

0 comments on commit cf65011

Please sign in to comment.