Files
Graphite/frontend/src/utility-functions/icons.ts
2023-03-05 17:49:47 -08:00

305 lines
18 KiB
TypeScript

/* eslint-disable import/first */
// Graphics
import GraphiteLogotypeSolid from "@/../assets/graphics/graphite-logotype-solid.svg";
const GRAPHICS = {
GraphiteLogotypeSolid: { component: GraphiteLogotypeSolid, size: undefined },
} as const;
// 12px Solid
import Add from "@/../assets/icon-12px-solid/add.svg";
import Checkmark from "@/../assets/icon-12px-solid/checkmark.svg";
import CloseX from "@/../assets/icon-12px-solid/close-x.svg";
import DropdownArrow from "@/../assets/icon-12px-solid/dropdown-arrow.svg";
import Edit from "@/../assets/icon-12px-solid/edit.svg";
import Empty12px from "@/../assets/icon-12px-solid/empty-12px.svg";
import FullscreenEnter from "@/../assets/icon-12px-solid/fullscreen-enter.svg";
import FullscreenExit from "@/../assets/icon-12px-solid/fullscreen-exit.svg";
import Grid from "@/../assets/icon-12px-solid/grid.svg";
import Info from "@/../assets/icon-12px-solid/info.svg";
import KeyboardArrowDown from "@/../assets/icon-12px-solid/keyboard-arrow-down.svg";
import KeyboardArrowLeft from "@/../assets/icon-12px-solid/keyboard-arrow-left.svg";
import KeyboardArrowRight from "@/../assets/icon-12px-solid/keyboard-arrow-right.svg";
import KeyboardArrowUp from "@/../assets/icon-12px-solid/keyboard-arrow-up.svg";
import KeyboardBackspace from "@/../assets/icon-12px-solid/keyboard-backspace.svg";
import KeyboardCommand from "@/../assets/icon-12px-solid/keyboard-command.svg";
import KeyboardControl from "@/../assets/icon-12px-solid/keyboard-control.svg";
import KeyboardEnter from "@/../assets/icon-12px-solid/keyboard-enter.svg";
import KeyboardOption from "@/../assets/icon-12px-solid/keyboard-option.svg";
import KeyboardShift from "@/../assets/icon-12px-solid/keyboard-shift.svg";
import KeyboardSpace from "@/../assets/icon-12px-solid/keyboard-space.svg";
import KeyboardTab from "@/../assets/icon-12px-solid/keyboard-tab.svg";
import Link from "@/../assets/icon-12px-solid/link.svg";
import Overlays from "@/../assets/icon-12px-solid/overlays.svg";
import Remove from "@/../assets/icon-12px-solid/remove.svg";
import ResetColors from "@/../assets/icon-12px-solid/reset-colors.svg";
import Snapping from "@/../assets/icon-12px-solid/snapping.svg";
import Swap from "@/../assets/icon-12px-solid/swap.svg";
import VerticalEllipsis from "@/../assets/icon-12px-solid/vertical-ellipsis.svg";
import Warning from "@/../assets/icon-12px-solid/warning.svg";
import WindowButtonWinClose from "@/../assets/icon-12px-solid/window-button-win-close.svg";
import WindowButtonWinMaximize from "@/../assets/icon-12px-solid/window-button-win-maximize.svg";
import WindowButtonWinMinimize from "@/../assets/icon-12px-solid/window-button-win-minimize.svg";
import WindowButtonWinRestoreDown from "@/../assets/icon-12px-solid/window-button-win-restore-down.svg";
const SOLID_12PX = {
Add: { component: Add, size: 12 },
Checkmark: { component: Checkmark, size: 12 },
CloseX: { component: CloseX, size: 12 },
DropdownArrow: { component: DropdownArrow, size: 12 },
Edit: { component: Edit, size: 12 },
Empty12px: { component: Empty12px, size: 12 },
FullscreenEnter: { component: FullscreenEnter, size: 12 },
FullscreenExit: { component: FullscreenExit, size: 12 },
Grid: { component: Grid, size: 12 },
Info: { component: Info, size: 12 },
KeyboardArrowDown: { component: KeyboardArrowDown, size: 12 },
KeyboardArrowLeft: { component: KeyboardArrowLeft, size: 12 },
KeyboardArrowRight: { component: KeyboardArrowRight, size: 12 },
KeyboardArrowUp: { component: KeyboardArrowUp, size: 12 },
KeyboardBackspace: { component: KeyboardBackspace, size: 12 },
KeyboardCommand: { component: KeyboardCommand, size: 12 },
KeyboardControl: { component: KeyboardControl, size: 12 },
KeyboardEnter: { component: KeyboardEnter, size: 12 },
KeyboardOption: { component: KeyboardOption, size: 12 },
KeyboardShift: { component: KeyboardShift, size: 12 },
KeyboardSpace: { component: KeyboardSpace, size: 12 },
KeyboardTab: { component: KeyboardTab, size: 12 },
Link: { component: Link, size: 12 },
Overlays: { component: Overlays, size: 12 },
Remove: { component: Remove, size: 12 },
ResetColors: { component: ResetColors, size: 12 },
Snapping: { component: Snapping, size: 12 },
Swap: { component: Swap, size: 12 },
VerticalEllipsis: { component: VerticalEllipsis, size: 12 },
Warning: { component: Warning, size: 12 },
WindowButtonWinClose: { component: WindowButtonWinClose, size: 12 },
WindowButtonWinMaximize: { component: WindowButtonWinMaximize, size: 12 },
WindowButtonWinMinimize: { component: WindowButtonWinMinimize, size: 12 },
WindowButtonWinRestoreDown: { component: WindowButtonWinRestoreDown, size: 12 },
} as const;
// 16px Solid
import AlignBottom from "@/../assets/icon-16px-solid/align-bottom.svg";
import AlignHorizontalCenter from "@/../assets/icon-16px-solid/align-horizontal-center.svg";
import AlignLeft from "@/../assets/icon-16px-solid/align-left.svg";
import AlignRight from "@/../assets/icon-16px-solid/align-right.svg";
import AlignTop from "@/../assets/icon-16px-solid/align-top.svg";
import AlignVerticalCenter from "@/../assets/icon-16px-solid/align-vertical-center.svg";
import BooleanDifference from "@/../assets/icon-16px-solid/boolean-difference.svg";
import BooleanIntersect from "@/../assets/icon-16px-solid/boolean-intersect.svg";
import BooleanSubtractBack from "@/../assets/icon-16px-solid/boolean-subtract-back.svg";
import BooleanSubtractFront from "@/../assets/icon-16px-solid/boolean-subtract-front.svg";
import BooleanUnion from "@/../assets/icon-16px-solid/boolean-union.svg";
import CheckboxChecked from "@/../assets/icon-16px-solid/checkbox-checked.svg";
import CheckboxUnchecked from "@/../assets/icon-16px-solid/checkbox-unchecked.svg";
import Copy from "@/../assets/icon-16px-solid/copy.svg";
import EyeHidden from "@/../assets/icon-16px-solid/eye-hidden.svg";
import EyeVisible from "@/../assets/icon-16px-solid/eye-visible.svg";
import Eyedropper from "@/../assets/icon-16px-solid/eyedropper.svg";
import File from "@/../assets/icon-16px-solid/file.svg";
import FlipHorizontal from "@/../assets/icon-16px-solid/flip-horizontal.svg";
import FlipVertical from "@/../assets/icon-16px-solid/flip-vertical.svg";
import Folder from "@/../assets/icon-16px-solid/folder.svg";
import GraphiteLogo from "@/../assets/icon-16px-solid/graphite-logo.svg";
import NodeArtboard from "@/../assets/icon-16px-solid/node-artboard.svg";
import NodeBlur from "@/../assets/icon-16px-solid/node-blur.svg";
import NodeBrushwork from "@/../assets/icon-16px-solid/node-brushwork.svg";
import NodeColorCorrection from "@/../assets/icon-16px-solid/node-color-correction.svg";
import NodeFolder from "@/../assets/icon-16px-solid/node-folder.svg";
import NodeGradient from "@/../assets/icon-16px-solid/node-gradient.svg";
import NodeImage from "@/../assets/icon-16px-solid/node-image.svg";
import NodeImaginate from "@/../assets/icon-16px-solid/node-imaginate.svg";
import NodeMagicWand from "@/../assets/icon-16px-solid/node-magic-wand.svg";
import NodeMask from "@/../assets/icon-16px-solid/node-mask.svg";
import NodeMotionBlur from "@/../assets/icon-16px-solid/node-motion-blur.svg";
import NodeNodes from "@/../assets/icon-16px-solid/node-nodes.svg";
import NodeOutput from "@/../assets/icon-16px-solid/node-output.svg";
import NodeShape from "@/../assets/icon-16px-solid/node-shape.svg";
import NodeText from "@/../assets/icon-16px-solid/node-text.svg";
import NodeTransform from "@/../assets/icon-16px-solid/node-transform.svg";
import Paste from "@/../assets/icon-16px-solid/paste.svg";
import Random from "@/../assets/icon-16px-solid/random.svg";
import Regenerate from "@/../assets/icon-16px-solid/regenerate.svg";
import Reload from "@/../assets/icon-16px-solid/reload.svg";
import Rescale from "@/../assets/icon-16px-solid/rescale.svg";
import Reset from "@/../assets/icon-16px-solid/reset.svg";
import Settings from "@/../assets/icon-16px-solid/settings.svg";
import Trash from "@/../assets/icon-16px-solid/trash.svg";
import ViewModeNormal from "@/../assets/icon-16px-solid/view-mode-normal.svg";
import ViewModeOutline from "@/../assets/icon-16px-solid/view-mode-outline.svg";
import ViewModePixels from "@/../assets/icon-16px-solid/view-mode-pixels.svg";
import ViewportDesignMode from "@/../assets/icon-16px-solid/viewport-design-mode.svg";
import ViewportGuideMode from "@/../assets/icon-16px-solid/viewport-guide-mode.svg";
import ViewportSelectMode from "@/../assets/icon-16px-solid/viewport-select-mode.svg";
import ZoomIn from "@/../assets/icon-16px-solid/zoom-in.svg";
import ZoomOut from "@/../assets/icon-16px-solid/zoom-out.svg";
import ZoomReset from "@/../assets/icon-16px-solid/zoom-reset.svg";
const SOLID_16PX = {
AlignBottom: { component: AlignBottom, size: 16 },
AlignHorizontalCenter: { component: AlignHorizontalCenter, size: 16 },
AlignLeft: { component: AlignLeft, size: 16 },
AlignRight: { component: AlignRight, size: 16 },
AlignTop: { component: AlignTop, size: 16 },
AlignVerticalCenter: { component: AlignVerticalCenter, size: 16 },
BooleanDifference: { component: BooleanDifference, size: 16 },
BooleanIntersect: { component: BooleanIntersect, size: 16 },
BooleanSubtractBack: { component: BooleanSubtractBack, size: 16 },
BooleanSubtractFront: { component: BooleanSubtractFront, size: 16 },
BooleanUnion: { component: BooleanUnion, size: 16 },
CheckboxChecked: { component: CheckboxChecked, size: 16 },
CheckboxUnchecked: { component: CheckboxUnchecked, size: 16 },
Copy: { component: Copy, size: 16 },
Eyedropper: { component: Eyedropper, size: 16 },
EyeHidden: { component: EyeHidden, size: 16 },
EyeVisible: { component: EyeVisible, size: 16 },
File: { component: File, size: 16 },
FlipHorizontal: { component: FlipHorizontal, size: 16 },
FlipVertical: { component: FlipVertical, size: 16 },
Folder: { component: Folder, size: 16 },
GraphiteLogo: { component: GraphiteLogo, size: 16 },
NodeArtboard: { component: NodeArtboard, size: 16 },
NodeBlur: { component: NodeBlur, size: 16 },
NodeBrushwork: { component: NodeBrushwork, size: 16 },
NodeColorCorrection: { component: NodeColorCorrection, size: 16 },
NodeFolder: { component: NodeFolder, size: 16 },
NodeGradient: { component: NodeGradient, size: 16 },
NodeImage: { component: NodeImage, size: 16 },
NodeImaginate: { component: NodeImaginate, size: 16 },
NodeMagicWand: { component: NodeMagicWand, size: 16 },
NodeMask: { component: NodeMask, size: 16 },
NodeMotionBlur: { component: NodeMotionBlur, size: 16 },
NodeNodes: { component: NodeNodes, size: 16 },
NodeOutput: { component: NodeOutput, size: 16 },
NodeShape: { component: NodeShape, size: 16 },
NodeText: { component: NodeText, size: 16 },
NodeTransform: { component: NodeTransform, size: 16 },
Paste: { component: Paste, size: 16 },
Random: { component: Random, size: 16 },
Regenerate: { component: Regenerate, size: 16 },
Reload: { component: Reload, size: 16 },
Rescale: { component: Rescale, size: 16 },
Reset: { component: Reset, size: 16 },
Settings: { component: Settings, size: 16 },
Trash: { component: Trash, size: 16 },
ViewModeNormal: { component: ViewModeNormal, size: 16 },
ViewModeOutline: { component: ViewModeOutline, size: 16 },
ViewModePixels: { component: ViewModePixels, size: 16 },
ViewportDesignMode: { component: ViewportDesignMode, size: 16 },
ViewportGuideMode: { component: ViewportGuideMode, size: 16 },
ViewportSelectMode: { component: ViewportSelectMode, size: 16 },
ZoomIn: { component: ZoomIn, size: 16 },
ZoomOut: { component: ZoomOut, size: 16 },
ZoomReset: { component: ZoomReset, size: 16 },
} as const;
// 16px Two-Tone
import MouseHintDrag from "@/../assets/icon-16px-two-tone/mouse-hint-drag.svg";
import MouseHintLmbDouble from "@/../assets/icon-16px-two-tone/mouse-hint-lmb-double.svg";
import MouseHintLmbDrag from "@/../assets/icon-16px-two-tone/mouse-hint-lmb-drag.svg";
import MouseHintLmb from "@/../assets/icon-16px-two-tone/mouse-hint-lmb.svg";
import MouseHintMmbDrag from "@/../assets/icon-16px-two-tone/mouse-hint-mmb-drag.svg";
import MouseHintMmb from "@/../assets/icon-16px-two-tone/mouse-hint-mmb.svg";
import MouseHintNone from "@/../assets/icon-16px-two-tone/mouse-hint-none.svg";
import MouseHintRmbDouble from "@/../assets/icon-16px-two-tone/mouse-hint-rmb-double.svg";
import MouseHintRmbDrag from "@/../assets/icon-16px-two-tone/mouse-hint-rmb-drag.svg";
import MouseHintRmb from "@/../assets/icon-16px-two-tone/mouse-hint-rmb.svg";
import MouseHintScrollDown from "@/../assets/icon-16px-two-tone/mouse-hint-scroll-down.svg";
import MouseHintScrollUp from "@/../assets/icon-16px-two-tone/mouse-hint-scroll-up.svg";
const TWO_TONE_16PX = {
MouseHintDrag: { component: MouseHintDrag, size: 16 },
MouseHintLmb: { component: MouseHintLmb, size: 16 },
MouseHintLmbDouble: { component: MouseHintLmbDouble, size: 16 },
MouseHintLmbDrag: { component: MouseHintLmbDrag, size: 16 },
MouseHintMmb: { component: MouseHintMmb, size: 16 },
MouseHintMmbDrag: { component: MouseHintMmbDrag, size: 16 },
MouseHintNone: { component: MouseHintNone, size: 16 },
MouseHintRmb: { component: MouseHintRmb, size: 16 },
MouseHintRmbDouble: { component: MouseHintRmbDouble, size: 16 },
MouseHintRmbDrag: { component: MouseHintRmbDrag, size: 16 },
MouseHintScrollDown: { component: MouseHintScrollDown, size: 16 },
MouseHintScrollUp: { component: MouseHintScrollUp, size: 16 },
} as const;
// 24px Two-Tone
import GeneralArtboardTool from "@/../assets/icon-24px-two-tone/general-artboard-tool.svg";
import GeneralEyedropperTool from "@/../assets/icon-24px-two-tone/general-eyedropper-tool.svg";
import GeneralFillTool from "@/../assets/icon-24px-two-tone/general-fill-tool.svg";
import GeneralGradientTool from "@/../assets/icon-24px-two-tone/general-gradient-tool.svg";
import GeneralNavigateTool from "@/../assets/icon-24px-two-tone/general-navigate-tool.svg";
import GeneralSelectTool from "@/../assets/icon-24px-two-tone/general-select-tool.svg";
import RasterBrushTool from "@/../assets/icon-24px-two-tone/raster-brush-tool.svg";
import RasterCloneTool from "@/../assets/icon-24px-two-tone/raster-clone-tool.svg";
import RasterDetailTool from "@/../assets/icon-24px-two-tone/raster-detail-tool.svg";
import RasterHealTool from "@/../assets/icon-24px-two-tone/raster-heal-tool.svg";
import RasterImaginateTool from "@/../assets/icon-24px-two-tone/raster-imaginate-tool.svg";
import RasterNodesTool from "@/../assets/icon-24px-two-tone/raster-nodes-tool.svg";
import RasterPatchTool from "@/../assets/icon-24px-two-tone/raster-patch-tool.svg";
import RasterRelightTool from "@/../assets/icon-24px-two-tone/raster-relight-tool.svg";
import VectorEllipseTool from "@/../assets/icon-24px-two-tone/vector-ellipse-tool.svg";
import VectorFreehandTool from "@/../assets/icon-24px-two-tone/vector-freehand-tool.svg";
import VectorLineTool from "@/../assets/icon-24px-two-tone/vector-line-tool.svg";
import VectorPathTool from "@/../assets/icon-24px-two-tone/vector-path-tool.svg";
import VectorPenTool from "@/../assets/icon-24px-two-tone/vector-pen-tool.svg";
import VectorRectangleTool from "@/../assets/icon-24px-two-tone/vector-rectangle-tool.svg";
import VectorShapeTool from "@/../assets/icon-24px-two-tone/vector-shape-tool.svg";
import VectorSplineTool from "@/../assets/icon-24px-two-tone/vector-spline-tool.svg";
import VectorTextTool from "@/../assets/icon-24px-two-tone/vector-text-tool.svg";
const TWO_TONE_24PX = {
GeneralArtboardTool: { component: GeneralArtboardTool, size: 24 },
GeneralEyedropperTool: { component: GeneralEyedropperTool, size: 24 },
GeneralFillTool: { component: GeneralFillTool, size: 24 },
GeneralGradientTool: { component: GeneralGradientTool, size: 24 },
GeneralNavigateTool: { component: GeneralNavigateTool, size: 24 },
GeneralSelectTool: { component: GeneralSelectTool, size: 24 },
RasterImaginateTool: { component: RasterImaginateTool, size: 24 },
RasterNodesTool: { component: RasterNodesTool, size: 24 },
RasterBrushTool: { component: RasterBrushTool, size: 24 },
RasterCloneTool: { component: RasterCloneTool, size: 24 },
RasterDetailTool: { component: RasterDetailTool, size: 24 },
RasterHealTool: { component: RasterHealTool, size: 24 },
RasterPatchTool: { component: RasterPatchTool, size: 24 },
RasterRelightTool: { component: RasterRelightTool, size: 24 },
VectorEllipseTool: { component: VectorEllipseTool, size: 24 },
VectorFreehandTool: { component: VectorFreehandTool, size: 24 },
VectorLineTool: { component: VectorLineTool, size: 24 },
VectorPathTool: { component: VectorPathTool, size: 24 },
VectorPenTool: { component: VectorPenTool, size: 24 },
VectorRectangleTool: { component: VectorRectangleTool, size: 24 },
VectorShapeTool: { component: VectorShapeTool, size: 24 },
VectorSplineTool: { component: VectorSplineTool, size: 24 },
VectorTextTool: { component: VectorTextTool, size: 24 },
} as const;
// All icons
const ICON_LIST = {
...GRAPHICS,
...SOLID_12PX,
...SOLID_16PX,
...TWO_TONE_16PX,
...TWO_TONE_24PX,
} as const;
// Exported icons and types
export const ICONS: IconDefinitionType<typeof ICON_LIST> = ICON_LIST;
export const ICON_COMPONENTS = Object.fromEntries(Object.entries(ICONS).map(([name, data]) => [name, data.component]));
export type IconName = keyof typeof ICONS;
export type IconSize = undefined | 12 | 16 | 24 | 32;
// The following helper type declarations allow us to avoid manually maintaining the `IconName` type declaration as a string union paralleling the keys of the
// icon definitions. It lets TypeScript do that for us. Our goal is to define the big key-value pair of icons by constraining its values, but inferring its keys.
// Constraining its values means that TypeScript can make sure each icon definition has a valid size number from the union of numbers that is `IconSize`.
// Inferring its keys means we don't have to specify a supertype like `string` or `any` for the key-value pair's keys, which would prevent us from accessing
// the individual keys with `keyof typeof`. Absent a specified type for the keys, TypeScript falls back to inferring that the key-value pair's type is the
// map of all its individual entries. Having the full list of entries lets us automatically set the `IconName` type to the union of strings that is the full
// list of keys. The result is that we don't have to maintain a separate list of icon names since this scheme infers it from the keys of the icon definitions.
// Based on https://stackoverflow.com/a/64119715/775283
type IconDefinition = { component: string; size: IconSize };
type EvaluateType<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
type IconDefinitionType<T extends Record<string, IconDefinition>> = EvaluateType<{ [key in keyof T]: IconDefinition }>;