feat: select the export bcg image and bcg color from appState

This commit is contained in:
Arnošt Pleskot 2023-07-28 23:45:01 +02:00
parent f15417f864
commit f57cd7e2d5
No known key found for this signature in database
20 changed files with 491 additions and 97 deletions

View file

@ -9,6 +9,7 @@ import {
actionChangeExportEmbedScene,
actionChangeExportScale,
actionChangeProjectName,
actionChangeExportBackgroundImage,
} from "../actions/actionExport";
import { probablySupportsClipboardBlob } from "../clipboard";
import {
@ -16,6 +17,8 @@ import {
EXPORT_IMAGE_TYPES,
isFirefox,
EXPORT_SCALES,
EXPORT_BACKGROUND_IMAGES,
DEFAULT_EXPORT_BACKGROUND_IMAGE,
} from "../constants";
import { canvasToBlob } from "../data/blob";
@ -34,6 +37,7 @@ import { Tooltip } from "./Tooltip";
import "./ImageExportDialog.scss";
import { useAppProps } from "./App";
import { FilledButton } from "./FilledButton";
import Select from "./Select";
const supportsContextFilters =
"filter" in document.createElement("canvas").getContext("2d")!;
@ -74,6 +78,10 @@ const ImageExportModal = ({
const [exportWithBackground, setExportWithBackground] = useState(
appState.exportBackground,
);
const [exportBackgroundImage, setExportBackgroundImage] = useState<string>(
DEFAULT_EXPORT_BACKGROUND_IMAGE,
);
const [exportDarkMode, setExportDarkMode] = useState(
appState.exportWithDarkMode,
);
@ -169,6 +177,20 @@ const ImageExportModal = ({
label={t("imageExportDialog.label.withBackground")}
name="exportBackgroundSwitch"
>
<Select
items={EXPORT_BACKGROUND_IMAGES}
ariaLabel={t("imageExportDialog.label.backgroundImage")}
placeholder={t("imageExportDialog.label.backgroundImage")}
value={exportBackgroundImage}
onChange={(value) => {
setExportBackgroundImage(value);
actionManager.executeAction(
actionChangeExportBackgroundImage,
"ui",
value,
);
}}
/>
<Switch
name="exportBackgroundSwitch"
checked={exportWithBackground}

View file

@ -0,0 +1,69 @@
.Select {
&__trigger {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0 15px;
line-height: 1;
gap: 5px;
background: transparent;
border: none;
font-weight: 600;
font-size: 0.8rem;
color: var(--text-primary-color);
}
&__trigger-icon {
width: 15px;
height: 15px;
}
&__content {
overflow: hidden;
box-shadow: var(--shadow-island);
border-radius: var(--border-radius-md);
padding: calc(var(--padding) * var(--space-factor));
background-color: var(--input-bg-color);
z-index: 1;
}
&__viewport {
padding: 0.5rem;
}
&__item {
font-size: 0.8rem;
line-height: 1;
border-radius: var(--border-radius-md);
display: flex;
align-items: center;
padding: 0.5rem 1rem;
position: relative;
user-select: none;
font-weight: 600;
color: var(--text-primary-color);
&[data-highlighted] {
outline: none;
background-color: var(--button-hover-bg);
}
&[data-state="checked"] {
background-color: var(--color-primary);
color: var(--input-bg-color);
}
&[data-highlighted][data-state="checked"] {
background-color: var(--color-primary-darker);
}
}
&__scroll-button {
display: flex;
align-items: center;
justify-content: center;
height: 25px;
background-color: white;
cursor: default;
}
}

77
src/components/Select.tsx Normal file
View file

@ -0,0 +1,77 @@
import React, { forwardRef } from "react";
import clxs from "clsx";
import * as RadixSelect from "@radix-ui/react-select";
import "./Select.scss";
import { tablerChevronDownIcon, tablerChevronUpIcon } from "./icons";
type SelectItems = Record<string, string>;
export type SelectProps = {
items: SelectItems;
value: keyof SelectItems;
onChange: (value: keyof SelectItems) => void;
placeholder?: string;
ariaLabel?: string;
};
const Select = ({
items,
value,
onChange,
placeholder,
ariaLabel,
}: SelectProps) => (
<RadixSelect.Root value={value} onValueChange={onChange}>
<RadixSelect.Trigger
className="Select__trigger"
aria-label={ariaLabel ?? placeholder}
>
{placeholder && <RadixSelect.Value placeholder={placeholder} />}
<RadixSelect.Icon className="Select__trigger-icon">
{tablerChevronDownIcon}
</RadixSelect.Icon>
</RadixSelect.Trigger>
<RadixSelect.Content
className="Select__content"
position="popper"
align="center"
>
<RadixSelect.ScrollUpButton className="Select__scroll-button">
{tablerChevronUpIcon}
</RadixSelect.ScrollUpButton>
<RadixSelect.Viewport className="Select__viewport">
{Object.entries(items).map(([itemValue, itemLabel]) => (
<SelectItem value={itemValue} key={itemValue}>
{itemLabel}
</SelectItem>
))}
</RadixSelect.Viewport>
<RadixSelect.ScrollDownButton className="Select__scroll-button">
{tablerChevronDownIcon}
</RadixSelect.ScrollDownButton>
</RadixSelect.Content>
</RadixSelect.Root>
);
type SelectItemProps = React.ComponentProps<typeof RadixSelect.Item>;
const SelectItem = forwardRef(
(
{ children, className, ...props }: SelectItemProps,
forwardedRef: React.ForwardedRef<HTMLDivElement>,
) => {
return (
<RadixSelect.Item
className={clxs("Select__item", className)}
{...props}
ref={forwardedRef}
>
<RadixSelect.ItemText>{children}</RadixSelect.ItemText>
</RadixSelect.Item>
);
},
);
export default Select;

View file

@ -1655,3 +1655,19 @@ export const frameToolIcon = createIcon(
</g>,
tablerIconProps,
);
export const tablerChevronDownIcon = createIcon(
<>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 9l6 6l6 -6"></path>
</>,
tablerIconProps,
);
export const tablerChevronUpIcon = createIcon(
<>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 15l6 -6l6 6"></path>
</>,
tablerIconProps,
);