index.tsx
TLDR
This file defines a Checkbox component for the Demo Projects project. The component supports displaying and editing checkbox blocks in a block editor.
Classes
Checkbox
The Checkbox class represents a checkbox block in the block editor. It has the following properties:
-
name
: The name of the checkbox block -
displayName
: The display name of the checkbox block -
slashCommand
: The slash command associated with the checkbox block -
prefix
: The prefix text that appears before the checkbox -
nextType
: The type of the next block when creating a new block after the checkbox block -
runSlashCommand
: A function that handles running the slash command associated with the checkbox block -
editable
: A flag indicating whether the checkbox block is editable
The Checkbox class also defines two inner classes:
-
Display
: Renders the display view of the checkbox block. It includes an input checkbox and the checkbox value. -
Input
: Renders the input view of the checkbox block. It includes an input checkbox and an input text field for editing the checkbox value.
Methods
None
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useRef, useEffect} from 'react'
import {marked} from 'marked'
import {BlockInputProps, ContentType} from '../types'
import './checkbox.scss'
type ValueType = {
value: string
checked: boolean
}
const Checkbox: ContentType<ValueType> = {
name: 'checkbox',
displayName: 'Checkbox',
slashCommand: '/checkbox',
prefix: '[ ] ',
nextType: 'checkbox',
runSlashCommand: (): void => {},
editable: true,
Display: (props: BlockInputProps<ValueType>) => {
const renderer = new marked.Renderer()
const html = marked(props.value.value || '', {renderer, breaks: true})
return (
<div className='CheckboxView'>
<input
data-testid='checkbox-check'
type='checkbox'
onChange={(e) => {
const newValue = {checked: Boolean(e.target.checked), value: props.value.value || ''}
props.onSave(newValue)
}}
checked={props.value.checked || false}
onClick={(e) => e.stopPropagation()}
/>
<div
dangerouslySetInnerHTML={{__html: html.trim()}}
/>
</div>
)
},
Input: (props: BlockInputProps<ValueType>) => {
const ref = useRef<HTMLInputElement|null>(null)
useEffect(() => {
ref.current?.focus()
}, [])
return (
<div className='Checkbox'>
<input
type='checkbox'
data-testid='checkbox-check'
className='inputCheck'
onChange={(e) => {
let newValue = {checked: false, value: props.value.value || ''}
if (e.target.checked) {
newValue = {checked: true, value: props.value.value || ''}
}
props.onChange(newValue)
ref.current?.focus()
}}
checked={props.value.checked || false}
/>
<input
ref={ref}
data-testid='checkbox-input'
className='inputText'
onChange={(e) => {
props.onChange({checked: Boolean(props.value.checked), value: e.currentTarget.value})
}}
onKeyDown={(e) => {
if ((props.value.value || '') === '' && e.key === 'Backspace') {
props.onCancel()
}
if (e.key === 'Enter') {
props.onSave(props.value || {checked: false, value: ''})
}
}}
value={props.value.value || ''}
/>
</div>
)
},
}
Checkbox.runSlashCommand = (changeType: (contentType: ContentType<ValueType>) => void, changeValue: (value: ValueType) => void, ...args: string[]): void => {
changeType(Checkbox)
changeValue({checked: false, value: args.join(' ')})
}
export default Checkbox