mirror of
https://github.com/zadam/trilium.git
synced 2025-11-21 08:04:24 +01:00
client/note color picker menu item: improve
Some checks are pending
Checks / main (push) Waiting to run
Some checks are pending
Checks / main (push) Waiting to run
This commit is contained in:
parent
c25859cee9
commit
828a786414
@ -4,18 +4,22 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.color-picker-menu-item .color-cell {
|
||||
.color-picker-menu-item .color-cell {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 4px;
|
||||
background: var(--color);
|
||||
background-color: var(--color);
|
||||
}
|
||||
|
||||
.color-picker-menu-item .color-cell.disabled-color-cell {
|
||||
.color-picker-menu-item .color-cell:not(.selected):hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.color-picker-menu-item .color-cell.disabled-color-cell {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.color-picker-menu-item .color-cell.selected {
|
||||
.color-picker-menu-item .color-cell.selected {
|
||||
outline: 2px solid var(--color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
@ -28,7 +32,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
font-size: 14px;
|
||||
font-size: 18px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: boxicons;
|
||||
@ -50,9 +54,16 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: var(--color);
|
||||
|
||||
}
|
||||
|
||||
.custom-color-cell.custom-color-cell-empty {
|
||||
background-image: url(./custom-culor.png);
|
||||
background-size: cover;
|
||||
--foreground: transparent;
|
||||
}
|
||||
|
||||
|
||||
.custom-color-cell::before {
|
||||
content: "\ed35";
|
||||
color: var(--foreground);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import "./NoteColorPickerMenuItem.css";
|
||||
import { useEffect, useRef, useState} from "preact/hooks";
|
||||
import { useCallback, useEffect, useRef, useState} from "preact/hooks";
|
||||
import {ComponentChildren} from "preact";
|
||||
import attributes from "../../services/attributes";
|
||||
import Color, { ColorInstance } from "color";
|
||||
@ -22,12 +22,13 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
|
||||
|
||||
const [note, setNote] = useState<FNote | null>(null);
|
||||
const [currentColor, setCurrentColor] = useState<string | null>(null);
|
||||
const [isCustomColor, setIsCustomColor] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const retrieveNote = async (noteId: string) => {
|
||||
const result = await froca.getNote(noteId, true);
|
||||
if (result) {
|
||||
setNote(result);
|
||||
const noteInstance = await froca.getNote(noteId, true);
|
||||
if (noteInstance) {
|
||||
setNote(noteInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +40,27 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentColor(note?.getLabel("color")?.value ?? null);
|
||||
const colorLabel = note?.getLabel("color")?.value ?? null;
|
||||
if (colorLabel) {
|
||||
let color: ColorInstance | null = null;
|
||||
|
||||
try {
|
||||
color = new Color(colorLabel);
|
||||
} catch(ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
|
||||
if (color) {
|
||||
setCurrentColor(color.hex().toLowerCase());
|
||||
}
|
||||
}
|
||||
}, [note]);
|
||||
|
||||
const onColorCellClicked = (color: string | null) => {
|
||||
useEffect(() => {
|
||||
setIsCustomColor(COLORS.indexOf(currentColor) === -1);
|
||||
}, [currentColor])
|
||||
|
||||
const onColorCellClicked = useCallback((color: string | null) => {
|
||||
if (note) {
|
||||
if (color !== null) {
|
||||
attributes.setLabel(note.noteId, "color", color);
|
||||
@ -52,7 +70,7 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
|
||||
|
||||
setCurrentColor(color);
|
||||
}
|
||||
}
|
||||
}, [note, currentColor]);
|
||||
|
||||
return <div className="color-picker-menu-item"
|
||||
onClick={(e) => {e.stopPropagation()}}>
|
||||
@ -65,7 +83,9 @@ export default function NoteColorPickerMenuItem(props: NoteColorPickerMenuItemPr
|
||||
onSelect={() => onColorCellClicked(color)} />
|
||||
))}
|
||||
|
||||
<CustomColorCell color={currentColor} isSelected={false} onSelect={onColorCellClicked} />
|
||||
<CustomColorCell color={currentColor}
|
||||
isSelected={isCustomColor}
|
||||
onSelect={onColorCellClicked} />
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -87,28 +107,50 @@ function ColorCell(props: ColorCellProps) {
|
||||
}
|
||||
|
||||
function CustomColorCell(props: ColorCellProps) {
|
||||
const [pickedColor, setPickedColor] = useState<string | null>(null);
|
||||
const colorInput = useRef<HTMLInputElement>(null);
|
||||
let colorInputDebouncer: Debouncer<string | null>;
|
||||
const colorInputDebouncer = useRef<Debouncer<string | null> | null>(null);
|
||||
const callbackRef = useRef(props.onSelect);
|
||||
|
||||
useEffect(() => {
|
||||
colorInputDebouncer = new Debouncer(500, (color) => {
|
||||
props.onSelect?.(color);
|
||||
colorInputDebouncer.current = new Debouncer(500, (color) => {
|
||||
callbackRef.current?.(color);
|
||||
setPickedColor(color);
|
||||
});
|
||||
|
||||
return () => {
|
||||
colorInputDebouncer.destroy();
|
||||
colorInputDebouncer.current?.destroy();
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isSelected && pickedColor === null) {
|
||||
setPickedColor(props.color);
|
||||
}
|
||||
}, [props.isSelected])
|
||||
|
||||
useEffect(() => {
|
||||
callbackRef.current = props.onSelect;
|
||||
}, [props.onSelect]);
|
||||
|
||||
const onSelect = useCallback(() => {
|
||||
if (pickedColor !== null) {
|
||||
callbackRef.current?.(pickedColor);
|
||||
}
|
||||
|
||||
colorInput.current?.click();
|
||||
}, [pickedColor]);
|
||||
|
||||
return <div style={`--foreground: ${ensureContrast(props.color)};`}>
|
||||
<ColorCell {...props}
|
||||
className="custom-color-cell"
|
||||
onSelect={() => {colorInput.current?.click()}}>
|
||||
<ColorCell {...props}
|
||||
color={pickedColor}
|
||||
className={`custom-color-cell ${(pickedColor === null) ? "custom-color-cell-empty" : ""}`}
|
||||
onSelect={onSelect}>
|
||||
|
||||
<input ref={colorInput}
|
||||
type="color"
|
||||
value={props.color ?? ""}
|
||||
onChange={() => {colorInputDebouncer.updateValue(colorInput.current?.value ?? null)}}
|
||||
value={pickedColor ?? props.color ?? "#40bfbf"}
|
||||
onChange={() => {colorInputDebouncer.current?.updateValue(colorInput.current?.value ?? null)}}
|
||||
style="width: 0; height: 0; opacity: 0" />
|
||||
</ColorCell>
|
||||
</div>
|
||||
|
||||
BIN
apps/client/src/menus/custom-items/custom-culor.png
Normal file
BIN
apps/client/src/menus/custom-items/custom-culor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Loading…
x
Reference in New Issue
Block a user