1- import { ComponentChildren , h } from 'preact'
2- import { useCallback } from 'preact/hooks'
1+ import { MIXED_BOOLEAN } from '@create-figma-plugin/utilities'
2+ import { ComponentChildren , h , RefObject } from 'preact'
3+ import { useCallback , useEffect , useRef } from 'preact/hooks'
34
45import { IconCheck16 } from '../../icons/icon-16/icon-check-16.js'
6+ import { IconMixed16 } from '../../icons/icon-16/icon-mixed-16.js'
57import { Event , EventHandler } from '../../types/event-handler.js'
68import { FocusableComponentProps } from '../../types/focusable-component-props.js'
79import { createClassName } from '../../utilities/create-class-name.js'
810import { createComponent } from '../../utilities/create-component.js'
11+ import { getCurrentFromRef } from '../../utilities/get-current-from-ref.js'
912import { noop } from '../../utilities/no-op.js'
1013import styles from './checkbox.module.css'
1114
@@ -15,7 +18,7 @@ export interface CheckboxProps
1518 disabled ?: boolean
1619 onChange ?: EventHandler . onChange < HTMLInputElement >
1720 onValueChange ?: EventHandler . onValueChange < boolean >
18- value : boolean
21+ value : typeof MIXED_BOOLEAN | boolean
1922}
2023
2124export const Checkbox = createComponent < HTMLInputElement , CheckboxProps > (
@@ -32,6 +35,8 @@ export const Checkbox = createComponent<HTMLInputElement, CheckboxProps>(
3235 } ,
3336 ref
3437 ) {
38+ const inputElementRef : RefObject < HTMLInputElement > = useRef ( null )
39+
3540 const handleChange = useCallback (
3641 function ( event : Event . onChange < HTMLInputElement > ) {
3742 onChange ( event )
@@ -54,16 +59,40 @@ export const Checkbox = createComponent<HTMLInputElement, CheckboxProps>(
5459 [ onKeyDown , propagateEscapeKeyDown ]
5560 )
5661
62+ useEffect (
63+ function ( ) {
64+ const inputElement = getCurrentFromRef ( inputElementRef )
65+ inputElement . indeterminate = value === MIXED_BOOLEAN ? true : false
66+ } ,
67+ [ value ]
68+ )
69+
70+ const refCallback = useCallback (
71+ function ( inputElement : null | HTMLInputElement ) {
72+ inputElementRef . current = inputElement
73+ if ( ref === null ) {
74+ return
75+ }
76+ if ( typeof ref === 'function' ) {
77+ ref ( inputElement )
78+ return
79+ }
80+ ref . current = inputElement
81+ } ,
82+ [ ref ]
83+ )
84+
5785 return (
5886 < label
5987 class = { createClassName ( [
6088 styles . checkbox ,
61- disabled === true ? styles . disabled : null
89+ disabled === true ? styles . disabled : null ,
90+ value === MIXED_BOOLEAN ? styles . mixed : null
6291 ] ) }
6392 >
6493 < input
6594 { ...rest }
66- ref = { ref }
95+ ref = { refCallback }
6796 checked = { value === true }
6897 class = { styles . input }
6998 disabled = { disabled === true }
@@ -73,8 +102,12 @@ export const Checkbox = createComponent<HTMLInputElement, CheckboxProps>(
73102 type = "checkbox"
74103 />
75104 < div class = { styles . box } >
76- { value === true ? (
77- < div class = { styles . checkIcon } >
105+ { value === MIXED_BOOLEAN ? (
106+ < div class = { styles . icon } >
107+ < IconMixed16 />
108+ </ div >
109+ ) : value === true ? (
110+ < div class = { styles . icon } >
78111 < IconCheck16 />
79112 </ div >
80113 ) : null }
0 commit comments