mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-29 00:20:04 +01:00
feat: cache last used color
This commit is contained in:
@@ -23,7 +23,7 @@ export declare class PortalProvider extends React.Component<BasePortalProviderPr
|
||||
static displayName: string;
|
||||
portalProviderAPI: PortalProviderAPI;
|
||||
constructor(props: BasePortalProviderProps);
|
||||
render(): React.ReactChild | JSX.Element | null;
|
||||
render(): JSX.Element | React.ReactChild | null;
|
||||
componentDidUpdate(): void;
|
||||
}
|
||||
export declare class PortalRenderer extends React.Component<{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
export declare const DEFAULT_COLORS: string[];
|
||||
declare type ColorPickerProps = {
|
||||
colors?: string[];
|
||||
color: string;
|
||||
color?: string;
|
||||
onClear: () => void;
|
||||
expanded?: boolean;
|
||||
onChange: (color: string) => void;
|
||||
|
||||
@@ -55,7 +55,7 @@ export function ColorPicker(props) {
|
||||
var _a = props.colors, colors = _a === void 0 ? DEFAULT_COLORS : _a, color = props.color, onClear = props.onClear, onChange = props.onChange, title = props.title, onClose = props.onClose, expanded = props.expanded;
|
||||
var ref = useRef();
|
||||
var _b = __read(useState(expanded || false), 2), isPickerOpen = _b[0], setIsPickerOpen = _b[1];
|
||||
var _c = __read(useState(tinycolor(color).toHexString()), 2), currentColor = _c[0], setCurrentColor = _c[1];
|
||||
var _c = __read(useState(tinycolor(color || colors[0]).toHexString()), 2), currentColor = _c[0], setCurrentColor = _c[1];
|
||||
var tColor = tinycolor(currentColor);
|
||||
useEffect(function () {
|
||||
if (!ref.current)
|
||||
|
||||
@@ -3,9 +3,9 @@ import { Editor } from "@tiptap/core";
|
||||
import { ToolProps } from "../types";
|
||||
declare type ColorToolProps = ToolProps & {
|
||||
onColorChange: (editor: Editor, color?: string) => void;
|
||||
isActive: (editor: Editor) => boolean;
|
||||
getActiveColor: (editor: Editor) => string;
|
||||
title: string;
|
||||
cacheKey: string;
|
||||
};
|
||||
export declare function ColorTool(props: ColorToolProps): JSX.Element;
|
||||
export declare function Highlight(props: ToolProps): JSX.Element;
|
||||
|
||||
43
packages/editor/dist/toolbar/tools/colors.js
vendored
43
packages/editor/dist/toolbar/tools/colors.js
vendored
@@ -40,55 +40,46 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { useState } from "react";
|
||||
import tinycolor from "tinycolor2";
|
||||
import { PopupWrapper } from "../../components/popup-presenter";
|
||||
import { useEditorContext } from "../../components/popup-presenter/popuprenderer";
|
||||
import { config } from "../../utils/config";
|
||||
import { SplitButton } from "../components/split-button";
|
||||
import { ColorPicker } from "../popups/color-picker";
|
||||
import { useToolbarLocation } from "../stores/toolbar-store";
|
||||
import { getToolbarElement } from "../utils/dom";
|
||||
export function ColorTool(props) {
|
||||
var onColorChange = props.onColorChange, isActive = props.isActive, getActiveColor = props.getActiveColor, title = props.title, toolProps = __rest(props, ["onColorChange", "isActive", "getActiveColor", "title"]);
|
||||
var editor = useEditorContext();
|
||||
var activeColor = getActiveColor(editor);
|
||||
var _isActive = isActive(editor);
|
||||
var editor = props.editor, onColorChange = props.onColorChange, getActiveColor = props.getActiveColor, title = props.title, cacheKey = props.cacheKey, toolProps = __rest(props, ["editor", "onColorChange", "getActiveColor", "title", "cacheKey"]);
|
||||
var activeColor = getActiveColor(editor) || config.get(cacheKey);
|
||||
var tColor = tinycolor(activeColor);
|
||||
var toolbarLocation = useToolbarLocation();
|
||||
var isBottom = toolbarLocation === "bottom";
|
||||
var isBottom = useToolbarLocation() === "bottom";
|
||||
var _a = __read(useState(false), 2), isOpen = _a[0], setIsOpen = _a[1];
|
||||
// const { hide, isOpen, show } = usePopup({
|
||||
// id: title,
|
||||
// group: "color",
|
||||
// theme: editor?.storage.theme,
|
||||
// blocking: false,
|
||||
// focusOnRender: false,
|
||||
// });
|
||||
// console.log("Updating color", editor);
|
||||
return (_jsx(SplitButton, __assign({}, toolProps, { iconColor: _isActive && tColor.isDark() ? "static" : "icon", sx: {
|
||||
return (_jsx(SplitButton, __assign({}, toolProps, { iconColor: activeColor && tColor.isDark() ? "static" : "icon", sx: {
|
||||
mr: 0,
|
||||
bg: _isActive ? activeColor : "transparent",
|
||||
bg: activeColor || "transparent",
|
||||
":hover": {
|
||||
bg: _isActive && !isBottom
|
||||
? tColor.darken(5).toRgbString()
|
||||
: "transparent",
|
||||
bg: activeColor ? tColor.darken(5).toRgbString() : "transparent",
|
||||
},
|
||||
}, onOpen: function () {
|
||||
setIsOpen(function (s) { return !s; });
|
||||
}, toggled: isOpen }, { children: _jsx(PopupWrapper, { isOpen: isOpen, id: props.icon, group: "color", position: {
|
||||
}, onOpen: function () { return setIsOpen(function (s) { return !s; }); }, toggled: isOpen, onClick: function () { return onColorChange(editor, activeColor); } }, { children: _jsx(PopupWrapper, { isOpen: isOpen, id: props.icon, group: "color", position: {
|
||||
isTargetAbsolute: true,
|
||||
target: getToolbarElement(),
|
||||
align: isBottom ? "center" : "end",
|
||||
location: isBottom ? "top" : "below",
|
||||
yOffset: 10,
|
||||
}, focusOnRender: false, blocking: false, renderPopup: function (close) { return (_jsx(ColorPicker, { color: activeColor, onClear: function () { return onColorChange(editor); }, onChange: function (color) { return onColorChange(editor, color); }, onClose: close, title: title })); } }) })));
|
||||
}, focusOnRender: false, blocking: false, renderPopup: function (close) { return (_jsx(ColorPicker, { color: activeColor, onClear: function () {
|
||||
onColorChange(editor);
|
||||
config.set(cacheKey, null);
|
||||
}, onChange: function (color) {
|
||||
onColorChange(editor, color);
|
||||
config.set(cacheKey, color);
|
||||
}, onClose: close, title: title })); } }) })));
|
||||
}
|
||||
export function Highlight(props) {
|
||||
return (_jsx(ColorTool, __assign({}, props, { isActive: function (editor) { return editor.isActive("highlight", { color: /\W+/gm }); }, getActiveColor: function (editor) { return editor.getAttributes("highlight").color; }, title: "Background color", onColorChange: function (editor, color) {
|
||||
return (_jsx(ColorTool, __assign({}, props, { cacheKey: "highlight", getActiveColor: function (editor) { return editor.getAttributes("highlight").color; }, title: "Background color", onColorChange: function (editor, color) {
|
||||
return color
|
||||
? editor.chain().focus().toggleHighlight({ color: color }).run()
|
||||
: editor.chain().focus().unsetHighlight().run();
|
||||
} })));
|
||||
}
|
||||
export function TextColor(props) {
|
||||
return (_jsx(ColorTool, __assign({}, props, { isActive: function (editor) { return editor.isActive("textStyle", { color: /\W+/gm }); }, getActiveColor: function (editor) { return editor.getAttributes("textStyle").color; }, title: "Text color", onColorChange: function (editor, color) {
|
||||
return (_jsx(ColorTool, __assign({}, props, { cacheKey: "textColor", getActiveColor: function (editor) { return editor.getAttributes("textStyle").color; }, title: "Text color", onColorChange: function (editor, color) {
|
||||
return color
|
||||
? editor.chain().focus().setColor(color).run()
|
||||
: editor.chain().focus().unsetColor().run();
|
||||
|
||||
7
packages/editor/dist/utils/config.d.ts
vendored
Normal file
7
packages/editor/dist/utils/config.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
declare function set<T>(key: string, value: T | null): void;
|
||||
declare function get<T>(key: string, def?: T): T | undefined;
|
||||
export declare const config: {
|
||||
set: typeof set;
|
||||
get: typeof get;
|
||||
};
|
||||
export {};
|
||||
22
packages/editor/dist/utils/config.js
vendored
Normal file
22
packages/editor/dist/utils/config.js
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
function set(key, value) {
|
||||
if (!value)
|
||||
return window.localStorage.removeItem(key);
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
}
|
||||
function get(key, def) {
|
||||
var value = window.localStorage.getItem(key);
|
||||
if (!value)
|
||||
return def;
|
||||
return tryParse(value);
|
||||
}
|
||||
export var config = { set: set, get: get };
|
||||
function tryParse(val) {
|
||||
if (val === "undefined" || val === "null")
|
||||
return;
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
}
|
||||
catch (e) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export const DEFAULT_COLORS = [
|
||||
|
||||
type ColorPickerProps = {
|
||||
colors?: string[];
|
||||
color: string;
|
||||
color?: string;
|
||||
onClear: () => void;
|
||||
expanded?: boolean;
|
||||
onChange: (color: string) => void;
|
||||
@@ -47,7 +47,7 @@ export function ColorPicker(props: ColorPickerProps) {
|
||||
const ref = useRef<HTMLDivElement>();
|
||||
const [isPickerOpen, setIsPickerOpen] = useState(expanded || false);
|
||||
const [currentColor, setCurrentColor] = useState<string>(
|
||||
tinycolor(color).toHexString()
|
||||
tinycolor(color || colors[0]).toHexString()
|
||||
);
|
||||
const tColor = tinycolor(currentColor);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Editor } from "@tiptap/core";
|
||||
import { useState } from "react";
|
||||
import tinycolor from "tinycolor2";
|
||||
import { PopupWrapper } from "../../components/popup-presenter";
|
||||
import { useEditorContext } from "../../components/popup-presenter/popuprenderer";
|
||||
import { config } from "../../utils/config";
|
||||
import { SplitButton } from "../components/split-button";
|
||||
import { ColorPicker } from "../popups/color-picker";
|
||||
import { useToolbarLocation } from "../stores/toolbar-store";
|
||||
@@ -11,47 +11,38 @@ import { getToolbarElement } from "../utils/dom";
|
||||
|
||||
type ColorToolProps = ToolProps & {
|
||||
onColorChange: (editor: Editor, color?: string) => void;
|
||||
isActive: (editor: Editor) => boolean;
|
||||
getActiveColor: (editor: Editor) => string;
|
||||
title: string;
|
||||
cacheKey: string;
|
||||
};
|
||||
export function ColorTool(props: ColorToolProps) {
|
||||
const { onColorChange, isActive, getActiveColor, title, ...toolProps } =
|
||||
props;
|
||||
const editor = useEditorContext();
|
||||
const activeColor = getActiveColor(editor);
|
||||
const _isActive = isActive(editor);
|
||||
const {
|
||||
editor,
|
||||
onColorChange,
|
||||
getActiveColor,
|
||||
title,
|
||||
cacheKey,
|
||||
...toolProps
|
||||
} = props;
|
||||
const activeColor = getActiveColor(editor) || config.get(cacheKey);
|
||||
const tColor = tinycolor(activeColor);
|
||||
const toolbarLocation = useToolbarLocation();
|
||||
const isBottom = toolbarLocation === "bottom";
|
||||
const isBottom = useToolbarLocation() === "bottom";
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
// const { hide, isOpen, show } = usePopup({
|
||||
// id: title,
|
||||
// group: "color",
|
||||
// theme: editor?.storage.theme,
|
||||
// blocking: false,
|
||||
// focusOnRender: false,
|
||||
// });
|
||||
// console.log("Updating color", editor);
|
||||
|
||||
return (
|
||||
<SplitButton
|
||||
{...toolProps}
|
||||
iconColor={_isActive && tColor.isDark() ? "static" : "icon"}
|
||||
iconColor={activeColor && tColor.isDark() ? "static" : "icon"}
|
||||
sx={{
|
||||
mr: 0,
|
||||
bg: _isActive ? activeColor : "transparent",
|
||||
bg: activeColor || "transparent",
|
||||
":hover": {
|
||||
bg:
|
||||
_isActive && !isBottom
|
||||
? tColor.darken(5).toRgbString()
|
||||
: "transparent",
|
||||
bg: activeColor ? tColor.darken(5).toRgbString() : "transparent",
|
||||
},
|
||||
}}
|
||||
onOpen={() => {
|
||||
setIsOpen((s) => !s);
|
||||
}}
|
||||
onOpen={() => setIsOpen((s) => !s)}
|
||||
toggled={isOpen}
|
||||
onClick={() => onColorChange(editor, activeColor)}
|
||||
>
|
||||
<PopupWrapper
|
||||
isOpen={isOpen}
|
||||
@@ -69,8 +60,14 @@ export function ColorTool(props: ColorToolProps) {
|
||||
renderPopup={(close) => (
|
||||
<ColorPicker
|
||||
color={activeColor}
|
||||
onClear={() => onColorChange(editor)}
|
||||
onChange={(color) => onColorChange(editor, color)}
|
||||
onClear={() => {
|
||||
onColorChange(editor);
|
||||
config.set(cacheKey, null);
|
||||
}}
|
||||
onChange={(color) => {
|
||||
onColorChange(editor, color);
|
||||
config.set(cacheKey, color);
|
||||
}}
|
||||
onClose={close}
|
||||
title={title}
|
||||
/>
|
||||
@@ -84,7 +81,7 @@ export function Highlight(props: ToolProps) {
|
||||
return (
|
||||
<ColorTool
|
||||
{...props}
|
||||
isActive={(editor) => editor.isActive("highlight", { color: /\W+/gm })}
|
||||
cacheKey="highlight"
|
||||
getActiveColor={(editor) => editor.getAttributes("highlight").color}
|
||||
title={"Background color"}
|
||||
onColorChange={(editor, color) =>
|
||||
@@ -100,7 +97,7 @@ export function TextColor(props: ToolProps) {
|
||||
return (
|
||||
<ColorTool
|
||||
{...props}
|
||||
isActive={(editor) => editor.isActive("textStyle", { color: /\W+/gm })}
|
||||
cacheKey={"textColor"}
|
||||
getActiveColor={(editor) => editor.getAttributes("textStyle").color}
|
||||
title="Text color"
|
||||
onColorChange={(editor, color) =>
|
||||
|
||||
23
packages/editor/src/utils/config.ts
Normal file
23
packages/editor/src/utils/config.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
function set<T>(key: string, value: T | null) {
|
||||
if (!value) return window.localStorage.removeItem(key);
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
function get<T>(key: string, def?: T): T | undefined {
|
||||
const value = window.localStorage.getItem(key);
|
||||
if (!value) return def;
|
||||
|
||||
return tryParse(value) as T;
|
||||
}
|
||||
|
||||
export const config = { set, get };
|
||||
|
||||
function tryParse<T>(val: string): T | string | undefined {
|
||||
if (val === "undefined" || val === "null") return;
|
||||
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch (e) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user