fix: Light icons are not responsive to dark theme

This commit is contained in:
Tom Moor
2024-07-07 21:06:04 -04:00
parent 07b6441655
commit 43cf33fc0a
8 changed files with 58 additions and 45 deletions

View File

@@ -178,8 +178,7 @@ const DocumentSquircle = ({
}) => {
const theme = useTheme();
const iconType = determineIconType(icon)!;
const squircleColor =
iconType === IconType.Outline ? color : theme.slateLight;
const squircleColor = iconType === IconType.SVG ? color : theme.slateLight;
return (
<Squircle color={squircleColor}>

View File

@@ -1,3 +1,4 @@
import { observer } from "mobx-react";
import { getLuminance } from "polished";
import * as React from "react";
import { randomElement } from "@shared/random";
@@ -9,12 +10,22 @@ import EmojiIcon from "~/components/Icons/EmojiIcon";
import useStores from "~/hooks/useStores";
import Logger from "~/utils/Logger";
type IconProps = {
export type Props = {
/** The icon to render */
value: string;
/** The color of the icon */
color?: string;
/** The size of the icon */
size?: number;
/** The initial to display if the icon is a letter icon */
initial?: string;
/** Optional additional class name */
className?: string;
/**
* Ensure the color does not change in response to theme and contrast. Should only be
* used in color picker UI.
*/
forceColor?: boolean;
};
const Icon = ({
@@ -22,8 +33,9 @@ const Icon = ({
color,
size = 24,
initial,
forceColor,
className,
}: IconProps) => {
}: Props) => {
const iconType = determineIconType(icon);
if (!iconType) {
@@ -34,14 +46,15 @@ const Icon = ({
}
try {
if (iconType === IconType.Outline) {
if (iconType === IconType.SVG) {
return (
<OutlineIcon
<SVGIcon
value={icon}
color={color}
size={size}
initial={initial}
className={className}
forceColor={forceColor}
/>
);
}
@@ -56,38 +69,39 @@ const Icon = ({
return null;
};
type OutlineIconProps = {
value: string;
color?: string;
size?: number;
initial?: string;
className?: string;
};
const SVGIcon = observer(
({
value: icon,
color: inputColor,
initial,
size,
className,
forceColor,
}: Props) => {
const { ui } = useStores();
const OutlineIcon = ({
value: icon,
color: inputColor,
initial,
size,
className,
}: OutlineIconProps) => {
const { ui } = useStores();
let color = inputColor ?? randomElement(colorPalette);
let color = inputColor ?? randomElement(colorPalette);
// If the chosen icon color is very dark then we invert it in dark mode
if (!forceColor) {
if (ui.resolvedTheme === "dark" && color !== "currentColor") {
color = getLuminance(color) > 0.09 ? color : "currentColor";
}
// If the chosen icon color is very dark then we invert it in dark mode
// otherwise it will be impossible to see against the dark background.
if (!inputColor && ui.resolvedTheme === "dark" && color !== "currentColor") {
color = getLuminance(color) > 0.09 ? color : "currentColor";
// If the chosen icon color is very light then we invert it in light mode
if (ui.resolvedTheme === "light" && color !== "currentColor") {
color = getLuminance(color) < 0.9 ? color : "currentColor";
}
}
const Component = IconLibrary.getComponent(icon);
return (
<Component color={color} size={size} className={className}>
{initial}
</Component>
);
}
const Component = IconLibrary.getComponent(icon);
return (
<Component color={color} size={size} className={className}>
{initial}
</Component>
);
};
);
export default Icon;

View File

@@ -16,7 +16,7 @@ import { IconButton } from "./IconButton";
const BUTTON_SIZE = 32;
type OutlineNode = {
type: IconType.Outline;
type: IconType.SVG;
name: string;
color: string;
initial: string;
@@ -66,7 +66,7 @@ const GridTemplate = (
);
const items = node.icons.map((item) => {
if (item.type === IconType.Outline) {
if (item.type === IconType.SVG) {
return (
<IconButton
key={item.name}

View File

@@ -129,7 +129,7 @@ const IconPanel = ({
const baseIcons: DataNode = {
category,
icons: filteredIcons.map((name, index) => ({
type: IconType.Outline,
type: IconType.SVG,
name,
color,
initial,
@@ -144,7 +144,7 @@ const IconPanel = ({
{
category: DisplayCategory.Frequent,
icons: freqIcons.map((name, index) => ({
type: IconType.Outline,
type: IconType.SVG,
name,
color,
initial,

View File

@@ -98,7 +98,7 @@ const IconPicker = ({
(ic: string) => {
popover.hide();
const icType = determineIconType(ic);
const finalColor = icType === IconType.Outline ? chosenColor : null;
const finalColor = icType === IconType.SVG ? chosenColor : null;
onChange(ic, finalColor);
},
[popover, onChange, chosenColor]
@@ -110,7 +110,7 @@ const IconPicker = ({
const icType = determineIconType(icon);
// Outline icon set; propagate color change
if (icType === IconType.Outline) {
if (icType === IconType.SVG) {
onChange(icon, c);
}
},

View File

@@ -133,8 +133,8 @@ const CollectionSquircle = ({ collection }: { collection: Collection }) => {
const theme = useTheme();
const iconType = determineIconType(collection.icon)!;
const squircleColor =
iconType === IconType.Outline ? collection.color! : theme.slateLight;
const iconSize = iconType === IconType.Outline ? 16 : 22;
iconType === IconType.SVG ? collection.color! : theme.slateLight;
const iconSize = iconType === IconType.SVG ? 16 : 22;
return (
<Squircle color={squircleColor} size={AvatarSize.Medium}>

View File

@@ -414,7 +414,7 @@ export type ProsemirrorDoc = {
};
export enum IconType {
Outline = "outline",
SVG = "svg",
Emoji = "emoji",
}

View File

@@ -9,5 +9,5 @@ export const determineIconType = (
if (!icon) {
return;
}
return outlineIconNames.has(icon) ? IconType.Outline : IconType.Emoji;
return outlineIconNames.has(icon) ? IconType.SVG : IconType.Emoji;
};