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 <antreesy.web@gmail.com>
  • Loading branch information
Antreesy committed Jan 23, 2024
1 parent 772be39 commit ce2389d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
4 changes: 4 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@
const ignorePatterns = [
'ansi-regex',
'bail',
'ccount', // ESM dependency of remark-gfm
'char-regex',
'comma-separated-tokens',
'decode-named-character-reference',
'devlop', // ESM dependency of unified
'escape-string-regexp',
'hast-*',
'is-*',
'longest-streak', // ESM dependency of remark-gfm
'markdown-table', // ESM dependency of remark-gfm
'mdast-util-*',
'micromark',
'property-information',
Expand All @@ -46,6 +49,7 @@ const ignorePatterns = [
'vfile',
'vue-material-design-icons',
'web-namespaces',
'zwitch', // ESM dependency of remark-gfm
]

module.exports = {
Expand Down
40 changes: 36 additions & 4 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"
@interact:todo="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 @@ -345,11 +361,17 @@ export default {
type: Boolean,
default: false,
},
/** Provide event from rendered markdown inputs */
interactive: {
type: Boolean,
default: false,
},
autolink: {
type: Boolean,
default: true,
},
},
emits: ['interact:todo'],
methods: {
renderPlaintext(h) {
const context = this
Expand Down Expand Up @@ -420,9 +442,19 @@ export default {
&& children[0].tag === 'input'
&& children[0].data.attrs.type === 'checkbox') {
const [inputNode, , label] = children
const inputComponent = h(NcCheckboxRadioSwitch,
{ attrs: inputNode.data.attrs },
[label])
const id = 'markdown-input-' + GenRandomId(5)
const inputComponent = h(NcCheckboxRadioSwitch, {
attrs: {
...inputNode.data.attrs,
id,
disabled: !this.interactive,
},
on: {
'update:checked': (value) => {
this.$emit('interact:todo', { id, label, value })
},
},
}, [label])
return h(tag, attrs, [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 @@ -187,4 +187,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, {
propsData: {
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:checked', true)
expect(wrapper.emitted()['interact:todo']).toBeTruthy()
expect(wrapper.emitted()['interact:todo'][0][0]).toMatchObject({
id: expect.anything(),
label: 'task item',
value: true,
})
})
})

0 comments on commit ce2389d

Please sign in to comment.