11import "./NoteColorPickerMenuItem.css" ;
2- import { useEffect , useRef , useState } from "preact/hooks" ;
2+ import { useCallback , useEffect , useRef , useState } from "preact/hooks" ;
33import { ComponentChildren } from "preact" ;
44import attributes from "../../services/attributes" ;
55import Color , { ColorInstance } from "color" ;
@@ -22,12 +22,13 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
2222
2323 const [ note , setNote ] = useState < FNote | null > ( null ) ;
2424 const [ currentColor , setCurrentColor ] = useState < string | null > ( null ) ;
25+ const [ isCustomColor , setIsCustomColor ] = useState < boolean > ( false ) ;
2526
2627 useEffect ( ( ) => {
2728 const retrieveNote = async ( noteId : string ) => {
28- const result = await froca . getNote ( noteId , true ) ;
29- if ( result ) {
30- setNote ( result ) ;
29+ const noteInstance = await froca . getNote ( noteId , true ) ;
30+ if ( noteInstance ) {
31+ setNote ( noteInstance ) ;
3132 }
3233 }
3334
@@ -39,10 +40,27 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
3940 } , [ ] ) ;
4041
4142 useEffect ( ( ) => {
42- setCurrentColor ( note ?. getLabel ( "color" ) ?. value ?? null ) ;
43+ const colorLabel = note ?. getLabel ( "color" ) ?. value ?? null ;
44+ if ( colorLabel ) {
45+ let color : ColorInstance | null = null ;
46+
47+ try {
48+ color = new Color ( colorLabel ) ;
49+ } catch ( ex ) {
50+ console . error ( ex ) ;
51+ }
52+
53+ if ( color ) {
54+ setCurrentColor ( color . hex ( ) . toLowerCase ( ) ) ;
55+ }
56+ }
4357 } , [ note ] ) ;
4458
45- const onColorCellClicked = ( color : string | null ) => {
59+ useEffect ( ( ) => {
60+ setIsCustomColor ( COLORS . indexOf ( currentColor ) === - 1 ) ;
61+ } , [ currentColor ] )
62+
63+ const onColorCellClicked = useCallback ( ( color : string | null ) => {
4664 if ( note ) {
4765 if ( color !== null ) {
4866 attributes . setLabel ( note . noteId , "color" , color ) ;
@@ -52,7 +70,7 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
5270
5371 setCurrentColor ( color ) ;
5472 }
55- }
73+ } , [ note , currentColor ] ) ;
5674
5775 return < div className = "color-picker-menu-item"
5876 onClick = { ( e ) => { e . stopPropagation ( ) } } >
@@ -65,7 +83,9 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
6583 onSelect = { ( ) => onColorCellClicked ( color ) } />
6684 ) ) }
6785
68- < CustomColorCell color = { currentColor } isSelected = { false } onSelect = { onColorCellClicked } />
86+ < CustomColorCell color = { currentColor }
87+ isSelected = { isCustomColor }
88+ onSelect = { onColorCellClicked } />
6989 </ div >
7090}
7191
@@ -87,28 +107,50 @@ function ColorCell(props: ColorCellProps) {
87107}
88108
89109function CustomColorCell ( props : ColorCellProps ) {
110+ const [ pickedColor , setPickedColor ] = useState < string | null > ( null ) ;
90111 const colorInput = useRef < HTMLInputElement > ( null ) ;
91- let colorInputDebouncer : Debouncer < string | null > ;
112+ const colorInputDebouncer = useRef < Debouncer < string | null > | null > ( null ) ;
113+ const callbackRef = useRef ( props . onSelect ) ;
92114
93115 useEffect ( ( ) => {
94- colorInputDebouncer = new Debouncer ( 500 , ( color ) => {
95- props . onSelect ?.( color ) ;
116+ colorInputDebouncer . current = new Debouncer ( 500 , ( color ) => {
117+ callbackRef . current ?.( color ) ;
118+ setPickedColor ( color ) ;
96119 } ) ;
97120
98121 return ( ) => {
99- colorInputDebouncer . destroy ( ) ;
122+ colorInputDebouncer . current ?. destroy ( ) ;
123+ }
124+ } , [ ] ) ;
125+
126+ useEffect ( ( ) => {
127+ if ( props . isSelected && pickedColor === null ) {
128+ setPickedColor ( props . color ) ;
129+ }
130+ } , [ props . isSelected ] )
131+
132+ useEffect ( ( ) => {
133+ callbackRef . current = props . onSelect ;
134+ } , [ props . onSelect ] ) ;
135+
136+ const onSelect = useCallback ( ( ) => {
137+ if ( pickedColor !== null ) {
138+ callbackRef . current ?.( pickedColor ) ;
100139 }
101- } ) ;
140+
141+ colorInput . current ?. click ( ) ;
142+ } , [ pickedColor ] ) ;
102143
103144 return < div style = { `--foreground: ${ ensureContrast ( props . color ) } ;` } >
104- < ColorCell { ...props }
105- className = "custom-color-cell"
106- onSelect = { ( ) => { colorInput . current ?. click ( ) } } >
145+ < ColorCell { ...props }
146+ color = { pickedColor }
147+ className = { `custom-color-cell ${ ( pickedColor === null ) ? "custom-color-cell-empty" : "" } ` }
148+ onSelect = { onSelect } >
107149
108150 < input ref = { colorInput }
109151 type = "color"
110- value = { props . color ?? "" }
111- onChange = { ( ) => { colorInputDebouncer . updateValue ( colorInput . current ?. value ?? null ) } }
152+ value = { pickedColor ?? props . color ?? "#40bfbf " }
153+ onChange = { ( ) => { colorInputDebouncer . current ?. updateValue ( colorInput . current ?. value ?? null ) } }
112154 style = "width: 0; height: 0; opacity: 0" />
113155 </ ColorCell >
114156 </ div >
0 commit comments