Merge branch 'release/rc-v1.2.0' into feature/dialog-create-file
This commit is contained in:
commit
5d6e0ed554
@ -1,210 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import throttle from "lodash/throttle";
|
||||
import AvatarEditor from "react-avatar-editor";
|
||||
|
||||
import Slider from "@docspace/components/slider";
|
||||
import IconButton from "@docspace/components/icon-button";
|
||||
import { Base } from "@docspace/components/themes";
|
||||
|
||||
const StyledAvatarCropper = styled.div`
|
||||
max-width: 216px;
|
||||
|
||||
.icon_cropper-crop_area {
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
.icon_cropper-grid {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
svg {
|
||||
opacity: 0.2;
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.gridColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-delete_button {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.background};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.borderColor};
|
||||
border-radius: 3px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
transition: all 0.2s ease;
|
||||
&:hover {
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBackground};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBorderColor};
|
||||
}
|
||||
|
||||
&-text {
|
||||
user-select: none;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.color};
|
||||
}
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.iconColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-zoom-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&-slider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-button {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledAvatarCropper.defaultProps = { theme: Base };
|
||||
|
||||
const AvatarCropper = ({
|
||||
t,
|
||||
avatar,
|
||||
onChangeAvatar,
|
||||
uploadedFile,
|
||||
setUploadedFile,
|
||||
setPreviewAvatar,
|
||||
}) => {
|
||||
let editorRef = null;
|
||||
const setEditorRef = (editor) => (editorRef = editor);
|
||||
|
||||
const handlePositionChange = (position) =>
|
||||
onChangeAvatar({ ...avatar, x: position.x, y: position.y });
|
||||
|
||||
const handleSliderChange = (e, newZoom = null) =>
|
||||
onChangeAvatar({ ...avatar, zoom: newZoom ? newZoom : +e.target.value });
|
||||
|
||||
const handleZoomInClick = () =>
|
||||
handleSliderChange({}, avatar.zoom <= 4.5 ? avatar.zoom + 0.5 : 5);
|
||||
|
||||
const handleZoomOutClick = () =>
|
||||
handleSliderChange({}, avatar.zoom >= 1.5 ? avatar.zoom - 0.5 : 1);
|
||||
|
||||
const handleDeleteImage = () => setUploadedFile(null);
|
||||
|
||||
const handleImageChange = throttle(() => {
|
||||
try {
|
||||
if (!editorRef) return;
|
||||
const newPreveiwImage = editorRef.getImageScaledToCanvas()?.toDataURL();
|
||||
setPreviewAvatar(newPreveiwImage);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
useEffect(() => {
|
||||
handleImageChange();
|
||||
return () => {
|
||||
setPreviewAvatar("");
|
||||
};
|
||||
}, [avatar]);
|
||||
|
||||
return (
|
||||
<StyledAvatarCropper className="icon_cropper">
|
||||
<div className="icon_cropper-crop_area">
|
||||
<ReactSVG
|
||||
className="icon_cropper-grid"
|
||||
src="images/icon-cropper-grid.svg"
|
||||
/>
|
||||
<AvatarEditor
|
||||
ref={setEditorRef}
|
||||
image={uploadedFile}
|
||||
width={216}
|
||||
height={216}
|
||||
position={{ x: avatar.x, y: avatar.y }}
|
||||
scale={avatar.zoom}
|
||||
color={[6, 22, 38, 0.2]}
|
||||
border={0}
|
||||
rotate={0}
|
||||
borderRadius={108}
|
||||
onPositionChange={handlePositionChange}
|
||||
onImageReady={handleImageChange}
|
||||
disableHiDPIScaling
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="icon_cropper-delete_button"
|
||||
onClick={handleDeleteImage}
|
||||
title={t("Common:Delete")}
|
||||
>
|
||||
<ReactSVG src={"images/trash.react.svg"} />
|
||||
<div className="icon_cropper-delete_button-text">
|
||||
{t("Common:Delete")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="icon_cropper-zoom-container">
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomOutClick}
|
||||
iconName={"/static/images/zoom-minus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
/>
|
||||
<Slider
|
||||
className="icon_cropper-zoom-container-slider"
|
||||
max={5}
|
||||
min={1}
|
||||
onChange={handleSliderChange}
|
||||
step={0.01}
|
||||
value={avatar.zoom}
|
||||
/>
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomInClick}
|
||||
iconName={"/static/images/zoom-plus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
/>
|
||||
</div>
|
||||
</StyledAvatarCropper>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvatarCropper;
|
@ -1,56 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import AvatarCropper from "./avatar-cropper";
|
||||
import AvatarPreview from "./preview";
|
||||
import Dropzone from "./dropzone";
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
|
||||
.avatar-editor {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const AvatarEditor = ({
|
||||
t,
|
||||
profile,
|
||||
avatar,
|
||||
onChangeAvatar,
|
||||
preview,
|
||||
setPreview,
|
||||
}) => {
|
||||
const setUploadedFile = (file) =>
|
||||
onChangeAvatar({ ...avatar, uploadedFile: file });
|
||||
|
||||
const isDefaultAvatar =
|
||||
typeof avatar.uploadedFile === "string" &&
|
||||
avatar.uploadedFile.includes("default_user_photo");
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
{avatar.uploadedFile && !isDefaultAvatar && (
|
||||
<div className="avatar-editor">
|
||||
<AvatarCropper
|
||||
t={t}
|
||||
avatar={avatar}
|
||||
onChangeAvatar={onChangeAvatar}
|
||||
uploadedFile={avatar.uploadedFile}
|
||||
setUploadedFile={setUploadedFile}
|
||||
setPreviewAvatar={setPreview}
|
||||
/>
|
||||
<AvatarPreview avatar={preview} userName={profile.displayName} />
|
||||
</div>
|
||||
)}
|
||||
<Dropzone t={t} setUploadedFile={setUploadedFile} />
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvatarEditor;
|
@ -13,12 +13,32 @@ import {
|
||||
deleteAvatar,
|
||||
} from "@docspace/common/api/people";
|
||||
import { dataUrlToFile } from "@docspace/common/utils/dataUrlToFile";
|
||||
import AvatarEditor from "./editor";
|
||||
import ImageEditor from "@docspace/components/ImageEditor";
|
||||
import AvatarPreview from "@docspace/components/ImageEditor/AvatarPreview";
|
||||
|
||||
const StyledModalDialog = styled(ModalDialog)``;
|
||||
const StyledModalDialog = styled(ModalDialog)`
|
||||
.wrapper-image-editor {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
.avatar-editor {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const AvatarEditorDialog = (props) => {
|
||||
const { t } = useTranslation(["Profile", "PeopleTranslations", "ProfileAction", "Common"]);
|
||||
const { t } = useTranslation([
|
||||
"Profile",
|
||||
"PeopleTranslations",
|
||||
"ProfileAction",
|
||||
"Common",
|
||||
"CreateEditRoomDialog",
|
||||
]);
|
||||
|
||||
const {
|
||||
visible,
|
||||
onClose,
|
||||
@ -89,13 +109,16 @@ const AvatarEditorDialog = (props) => {
|
||||
</Text>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<AvatarEditor
|
||||
<ImageEditor
|
||||
t={t}
|
||||
avatar={avatar}
|
||||
onChangeAvatar={onChangeAvatar}
|
||||
profile={profile}
|
||||
preview={preview}
|
||||
className="wrapper-image-editor"
|
||||
classNameWrapperImageCropper="avatar-editor"
|
||||
image={avatar}
|
||||
setPreview={setPreview}
|
||||
onChangeImage={onChangeAvatar}
|
||||
Preview={
|
||||
<AvatarPreview avatar={preview} userName={profile.displayName} />
|
||||
}
|
||||
/>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
|
@ -1,118 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import resizeImage from "resize-image";
|
||||
import { Base } from "@docspace/components/themes";
|
||||
import { ColorTheme, ThemeType } from "@docspace/common/components/ColorTheme";
|
||||
|
||||
const StyledDropzone = styled.div`
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
border: 2px dashed
|
||||
${(props) => props.theme.createEditRoomDialog.dropzone.borderColor};
|
||||
border-radius: 6px;
|
||||
|
||||
.dropzone {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
|
||||
user-select: none;
|
||||
|
||||
&-link {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
&-main {
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dashed;
|
||||
text-underline-offset: 1px;
|
||||
}
|
||||
&-secondary {
|
||||
font-weight: 400;
|
||||
color: ${(props) =>
|
||||
props.theme.createEditRoomDialog.dropzone.linkSecondaryColor};
|
||||
}
|
||||
}
|
||||
|
||||
&-exsts {
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: ${(props) => props.theme.createEditRoomDialog.dropzone.exstsColor};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledDropzone.defaultProps = { theme: Base };
|
||||
|
||||
const Dropzone = ({ t, setUploadedFile, isDisabled }) => {
|
||||
const { acceptedFiles, getRootProps, getInputProps } = useDropzone({
|
||||
maxFiles: 1,
|
||||
noClick: isDisabled,
|
||||
noKeyboard: isDisabled,
|
||||
// maxSize: 1000000,
|
||||
accept: ["image/png", "image/jpeg"],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (acceptedFiles.length) {
|
||||
const fr = new FileReader();
|
||||
fr.readAsDataURL(acceptedFiles[0]);
|
||||
|
||||
fr.onload = () => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
const canvas = resizeImage.resize2Canvas(img, img.width, img.height);
|
||||
|
||||
const data = resizeImage.resize(
|
||||
canvas,
|
||||
img.width / 4,
|
||||
img.height / 4,
|
||||
resizeImage.JPEG
|
||||
);
|
||||
|
||||
fetch(data)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => {
|
||||
const file = new File([blob], "File name", {
|
||||
type: "image/jpg",
|
||||
});
|
||||
setUploadedFile(file);
|
||||
});
|
||||
};
|
||||
img.src = fr.result;
|
||||
};
|
||||
}
|
||||
}, [acceptedFiles]);
|
||||
|
||||
return (
|
||||
<StyledDropzone>
|
||||
<div {...getRootProps({ className: "dropzone" })}>
|
||||
<input {...getInputProps()} />
|
||||
<div className="dropzone-link">
|
||||
<ColorTheme className="dropzone-link-main" themeId={ThemeType.Link}>
|
||||
{t("DropzoneTitleLink")}
|
||||
</ColorTheme>
|
||||
<span className="dropzone-link-secondary">
|
||||
{t("DropzoneTitleSecondary")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="dropzone-exsts">{t("DropzoneTitleExsts")}</div>
|
||||
</div>
|
||||
</StyledDropzone>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dropzone;
|
@ -1,227 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import throttle from "lodash/throttle";
|
||||
import AvatarEditor from "react-avatar-editor";
|
||||
|
||||
import Slider from "@docspace/components/slider";
|
||||
import IconButton from "@docspace/components/icon-button";
|
||||
import { Base } from "@docspace/components/themes";
|
||||
|
||||
const StyledIconCropper = styled.div`
|
||||
max-width: 216px;
|
||||
|
||||
.icon_cropper-crop_area {
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
.icon_cropper-grid {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
svg {
|
||||
opacity: 0.2;
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.gridColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-delete_button {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.background};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.borderColor};
|
||||
border-radius: 3px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
transition: all 0.2s ease;
|
||||
&:hover {
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBackground};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBorderColor};
|
||||
}
|
||||
|
||||
&-text {
|
||||
user-select: none;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.color};
|
||||
}
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.iconColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-zoom-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&-slider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-button {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledIconCropper.defaultProps = { theme: Base };
|
||||
|
||||
const IconCropper = ({
|
||||
t,
|
||||
icon,
|
||||
onChangeIcon,
|
||||
uploadedFile,
|
||||
setUploadedFile,
|
||||
setPreviewIcon,
|
||||
isDisabled,
|
||||
}) => {
|
||||
let editorRef = null;
|
||||
const setEditorRef = (editor) => (editorRef = editor);
|
||||
|
||||
const handlePositionChange = (position) => {
|
||||
if (isDisabled) return;
|
||||
|
||||
onChangeIcon({ ...icon, x: position.x, y: position.y });
|
||||
};
|
||||
|
||||
const handleSliderChange = (e, newZoom = null) => {
|
||||
if (isDisabled) return;
|
||||
|
||||
onChangeIcon({ ...icon, zoom: newZoom ? newZoom : +e.target.value });
|
||||
};
|
||||
|
||||
const handleZoomInClick = () => {
|
||||
if (isDisabled) return;
|
||||
|
||||
handleSliderChange({}, icon.zoom <= 4.5 ? icon.zoom + 0.5 : 5);
|
||||
};
|
||||
const handleZoomOutClick = () => {
|
||||
if (isDisabled) return;
|
||||
|
||||
handleSliderChange({}, icon.zoom >= 1.5 ? icon.zoom - 0.5 : 1);
|
||||
};
|
||||
const handleDeleteImage = () => {
|
||||
if (isDisabled) return;
|
||||
setUploadedFile(null);
|
||||
};
|
||||
|
||||
const handleImageChange = throttle(() => {
|
||||
try {
|
||||
if (!editorRef) return;
|
||||
const newPreveiwImage = editorRef.getImageScaledToCanvas()?.toDataURL();
|
||||
setPreviewIcon(newPreveiwImage);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
useEffect(() => {
|
||||
handleImageChange();
|
||||
return () => {
|
||||
setPreviewIcon("");
|
||||
};
|
||||
}, [icon]);
|
||||
|
||||
return (
|
||||
<StyledIconCropper className="icon_cropper">
|
||||
<div className="icon_cropper-crop_area">
|
||||
<ReactSVG
|
||||
className="icon_cropper-grid"
|
||||
src="images/icon-cropper-grid.svg"
|
||||
/>
|
||||
<AvatarEditor
|
||||
ref={setEditorRef}
|
||||
image={uploadedFile}
|
||||
width={216}
|
||||
height={216}
|
||||
position={{ x: icon.x, y: icon.y }}
|
||||
scale={icon.zoom}
|
||||
color={[6, 22, 38, 0.2]}
|
||||
border={0}
|
||||
rotate={0}
|
||||
borderRadius={108}
|
||||
onPositionChange={handlePositionChange}
|
||||
onImageReady={handleImageChange}
|
||||
disableHiDPIScaling
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="icon_cropper-delete_button"
|
||||
onClick={handleDeleteImage}
|
||||
title={t("Common:Delete")}
|
||||
>
|
||||
<ReactSVG src={"images/trash.react.svg"} />
|
||||
<div className="icon_cropper-delete_button-text">
|
||||
{t("Common:Delete")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="icon_cropper-zoom-container">
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomOutClick}
|
||||
iconName={"/static/images/zoom-minus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
<Slider
|
||||
className="icon_cropper-zoom-container-slider"
|
||||
max={5}
|
||||
min={1}
|
||||
onChange={handleSliderChange}
|
||||
step={0.01}
|
||||
value={icon.zoom}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomInClick}
|
||||
iconName={"/static/images/zoom-plus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</StyledIconCropper>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconCropper;
|
@ -1,67 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import Dropzone from "./Dropzone";
|
||||
|
||||
const StyledIconEditor = styled.div`
|
||||
.icon-editor {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: start;
|
||||
gap: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
import IconCropper from "./IconCropper";
|
||||
import PreviewTile from "./PreviewTile";
|
||||
|
||||
const IconEditor = ({
|
||||
t,
|
||||
isEdit,
|
||||
title,
|
||||
tags,
|
||||
defaultTagLabel,
|
||||
icon,
|
||||
onChangeIcon,
|
||||
isDisabled,
|
||||
}) => {
|
||||
const [previewIcon, setPreviewIcon] = useState(null);
|
||||
|
||||
const setUploadedFile = (uploadedFile) =>
|
||||
onChangeIcon({ ...icon, uploadedFile });
|
||||
|
||||
return (
|
||||
<StyledIconEditor>
|
||||
{icon.uploadedFile && (
|
||||
<div className="icon-editor">
|
||||
<IconCropper
|
||||
t={t}
|
||||
icon={icon}
|
||||
onChangeIcon={onChangeIcon}
|
||||
uploadedFile={icon.uploadedFile}
|
||||
setUploadedFile={setUploadedFile}
|
||||
setPreviewIcon={setPreviewIcon}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
|
||||
<PreviewTile
|
||||
t={t}
|
||||
title={title || t("Files:NewRoom")}
|
||||
previewIcon={previewIcon}
|
||||
tags={tags.map((tag) => tag.name)}
|
||||
defaultTagLabel={defaultTagLabel}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Dropzone
|
||||
t={t}
|
||||
setUploadedFile={setUploadedFile}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</StyledIconEditor>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconEditor;
|
@ -6,7 +6,7 @@ import RoomTypeDropdown from "./RoomTypeDropdown";
|
||||
import ThirdPartyStorage from "./ThirdPartyStorage";
|
||||
import TagInput from "./TagInput";
|
||||
import RoomType from "./RoomType";
|
||||
import IconEditor from "./IconEditor";
|
||||
|
||||
import PermanentSettings from "./PermanentSettings";
|
||||
import InputParam from "./Params/InputParam";
|
||||
import IsPrivateParam from "./IsPrivateParam";
|
||||
@ -15,11 +15,22 @@ import withLoader from "@docspace/client/src/HOCs/withLoader";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
import { getRoomTypeDefaultTagTranslation } from "../data";
|
||||
|
||||
import ImageEditor from "@docspace/components/ImageEditor";
|
||||
import PreviewTile from "@docspace/components/ImageEditor/PreviewTile";
|
||||
|
||||
const StyledSetRoomParams = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 22px;
|
||||
|
||||
.icon-editor {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: start;
|
||||
gap: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const SetRoomParams = ({
|
||||
@ -35,6 +46,8 @@ const SetRoomParams = ({
|
||||
isValidTitle,
|
||||
setIsValidTitle,
|
||||
}) => {
|
||||
const [previewIcon, setPreviewIcon] = React.useState(null);
|
||||
|
||||
const onChangeName = (e) => {
|
||||
setIsValidTitle(true);
|
||||
setRoomParams({ ...roomParams, title: e.target.value });
|
||||
@ -111,14 +124,26 @@ const SetRoomParams = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
<IconEditor
|
||||
<ImageEditor
|
||||
t={t}
|
||||
title={roomParams.title}
|
||||
tags={roomParams.tags}
|
||||
defaultTagLabel={getRoomTypeDefaultTagTranslation(roomParams.type, t)}
|
||||
icon={roomParams.icon}
|
||||
onChangeIcon={onChangeIcon}
|
||||
isDisabled={isDisabled}
|
||||
image={roomParams.icon}
|
||||
setPreview={setPreviewIcon}
|
||||
onChangeImage={onChangeIcon}
|
||||
classNameWrapperImageCropper={"icon-editor"}
|
||||
Preview={
|
||||
<PreviewTile
|
||||
t={t}
|
||||
title={roomParams.title || t("Files:NewRoom")}
|
||||
previewIcon={previewIcon}
|
||||
tags={roomParams.tags.map((tag) => tag.name)}
|
||||
isDisabled={isDisabled}
|
||||
defaultTagLabel={getRoomTypeDefaultTagTranslation(
|
||||
roomParams.type,
|
||||
t
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</StyledSetRoomParams>
|
||||
);
|
||||
|
@ -87,7 +87,11 @@ class ContextHelper {
|
||||
this.selection.options || [],
|
||||
this.selection
|
||||
)
|
||||
: this.getContextOptionActions(this.selection, this.t);
|
||||
: this.getContextOptionActions(
|
||||
this.selection,
|
||||
this.t,
|
||||
this.selection.isSelectedFolder
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -493,7 +493,7 @@ class ContextOptionsStore {
|
||||
onSelectItem({ id: item.id, isFolder: item.isFolder }, true, false);
|
||||
};
|
||||
|
||||
getFilesContextOptions = (item, t) => {
|
||||
getFilesContextOptions = (item, t, isInfoPanel) => {
|
||||
const { contextOptions } = item;
|
||||
const { id, rootFolderId } = this.selectedFolderStore;
|
||||
const { enablePlugins } = this.authStore.settingsStore;
|
||||
@ -582,7 +582,7 @@ class ContextOptionsStore {
|
||||
},
|
||||
];
|
||||
const moveActions =
|
||||
!isMobile && !isMobileUtils() && !isTabletUtils()
|
||||
!isMobile && !isMobileUtils() && !isTabletUtils() && !isInfoPanel
|
||||
? [
|
||||
{
|
||||
id: "option_move-or-copy",
|
||||
|
@ -136,7 +136,10 @@ class TreeFoldersStore {
|
||||
}
|
||||
|
||||
get isPersonalRoom() {
|
||||
return this.myFolder && this.myFolder.id === this.selectedFolderStore.id;
|
||||
return (
|
||||
this.myFolder &&
|
||||
this.myFolder.rootFolderType === this.selectedFolderStore.rootFolderType
|
||||
);
|
||||
}
|
||||
|
||||
get isShareFolder() {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import Avatar from "@docspace/components/avatar";
|
||||
import Text from "@docspace/components/text";
|
||||
import Avatar from "../../avatar";
|
||||
import Text from "../../text";
|
||||
|
||||
import { hugeMobile } from "@docspace/components/utils/device";
|
||||
import { hugeMobile } from "../../utils/device";
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
width: 100%;
|
@ -1,7 +1,7 @@
|
||||
import styled from "styled-components";
|
||||
import { hugeMobile } from "@docspace/components/utils/device";
|
||||
import { hugeMobile } from "../../utils/device";
|
||||
|
||||
import { Base } from "@docspace/components/themes";
|
||||
import { Base } from "../../themes";
|
||||
|
||||
const StyledDropzone = styled.div`
|
||||
cursor: pointer;
|
||||
@ -16,10 +16,8 @@ const StyledDropzone = styled.div`
|
||||
|
||||
.dropzone_loader {
|
||||
position: absolute;
|
||||
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -43,8 +41,6 @@ const StyledDropzone = styled.div`
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
&-main {
|
||||
color: ${(props) =>
|
||||
props.theme.createEditRoomDialog.dropzone.linkMainColor};
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dashed;
|
@ -1,24 +1,22 @@
|
||||
import React, { useState, useRef, useMemo, useEffect } from "react";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
|
||||
import StyledDropzone from "./StyledDropzone";
|
||||
import Loader from "@docspace/components/loader";
|
||||
|
||||
import { toastr } from "@docspace/components";
|
||||
import resizeImage from "resize-image";
|
||||
|
||||
import Loader from "../../loader";
|
||||
|
||||
import { toastr } from "../../";
|
||||
|
||||
import { ColorTheme, ThemeType } from "@docspace/common/components/ColorTheme";
|
||||
import StyledDropzone from "./StyledDropzone";
|
||||
|
||||
const ONE_MEGABYTE = 1024 * 1024;
|
||||
const COMPRESSION_RATIO = 2;
|
||||
const NO_COMPRESSION_RATIO = 1;
|
||||
|
||||
const Dropzone = ({ setUploadedFile }) => {
|
||||
const Dropzone = ({ t, setUploadedFile, isDisabled }) => {
|
||||
const [loadingFile, setLoadingFile] = useState(false);
|
||||
const { t } = useTranslation("CreateEditRoomDialog");
|
||||
|
||||
const mount = useRef(false);
|
||||
|
||||
const timer = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
@ -99,7 +97,7 @@ const Dropzone = ({ setUploadedFile }) => {
|
||||
error instanceof Error &&
|
||||
error.message === "recursion depth exceeded"
|
||||
) {
|
||||
toastr.error(t("SizeImageLarge"));
|
||||
toastr.error(t("CreateEditRoomDialog:SizeImageLarge"));
|
||||
}
|
||||
console.error(error);
|
||||
})
|
||||
@ -113,6 +111,8 @@ const Dropzone = ({ setUploadedFile }) => {
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
maxFiles: 1,
|
||||
noClick: isDisabled,
|
||||
noKeyboard: isDisabled,
|
||||
// maxSize: 1000000,
|
||||
accept: ["image/png", "image/jpeg"],
|
||||
onDrop,
|
||||
@ -126,12 +126,16 @@ const Dropzone = ({ setUploadedFile }) => {
|
||||
<div {...getRootProps({ className: "dropzone" })}>
|
||||
<input {...getInputProps()} />
|
||||
<div className="dropzone-link">
|
||||
<span className="dropzone-link-main">{t("DropzoneTitleLink")}</span>
|
||||
<ColorTheme className="dropzone-link-main" themeId={ThemeType.Link}>
|
||||
{t("CreateEditRoomDialog:DropzoneTitleLink")}
|
||||
</ColorTheme>
|
||||
<span className="dropzone-link-secondary">
|
||||
{t("DropzoneTitleSecondary")}
|
||||
{t("CreateEditRoomDialog:DropzoneTitleSecondary")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="dropzone-exsts">{t("DropzoneTitleExsts")}</div>
|
||||
<div className="dropzone-exsts">
|
||||
{t("CreateEditRoomDialog:DropzoneTitleExsts")}
|
||||
</div>
|
||||
</div>
|
||||
</StyledDropzone>
|
||||
);
|
@ -0,0 +1,94 @@
|
||||
import styled from "styled-components";
|
||||
import { Base } from "../../themes";
|
||||
|
||||
const StyledImageCropper = styled.div`
|
||||
max-width: 216px;
|
||||
|
||||
.icon_cropper-crop_area {
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
.icon_cropper-grid {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
svg {
|
||||
opacity: 0.2;
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.gridColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-delete_button {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.background};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.borderColor};
|
||||
border-radius: 3px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
transition: all 0.2s ease;
|
||||
&:hover {
|
||||
background: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBackground};
|
||||
border: 1px solid
|
||||
${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton
|
||||
.hoverBorderColor};
|
||||
}
|
||||
|
||||
&-text {
|
||||
user-select: none;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.color};
|
||||
}
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) =>
|
||||
props.theme.createEditRoomDialog.iconCropper.deleteButton.iconColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_cropper-zoom-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&-slider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-button {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledImageCropper.defaultProps = { theme: Base };
|
||||
export default StyledImageCropper;
|
136
packages/components/ImageEditor/ImageCropper/index.js
Normal file
136
packages/components/ImageEditor/ImageCropper/index.js
Normal file
@ -0,0 +1,136 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import throttle from "lodash/throttle";
|
||||
import AvatarEditor from "react-avatar-editor";
|
||||
|
||||
import Slider from "../../slider";
|
||||
import IconButton from "../../icon-button";
|
||||
import StyledImageCropper from "./StyledImageCropper";
|
||||
|
||||
const ImageCropper = ({
|
||||
t,
|
||||
image,
|
||||
onChangeImage,
|
||||
uploadedFile,
|
||||
setUploadedFile,
|
||||
setPreviewImage,
|
||||
isDisabled,
|
||||
}) => {
|
||||
let editorRef = null;
|
||||
const setEditorRef = (editor) => (editorRef = editor);
|
||||
|
||||
const handlePositionChange = (position) => {
|
||||
if (isDisabled) return;
|
||||
|
||||
onChangeImage({ ...image, x: position.x, y: position.y });
|
||||
};
|
||||
|
||||
const handleSliderChange = (e, newZoom = null) => {
|
||||
if (isDisabled) return;
|
||||
|
||||
onChangeImage({ ...image, zoom: newZoom ? newZoom : +e.target.value });
|
||||
};
|
||||
|
||||
const handleZoomInClick = () => {
|
||||
if (isDisabled) return;
|
||||
|
||||
handleSliderChange({}, image.zoom <= 4.5 ? image.zoom + 0.5 : 5);
|
||||
};
|
||||
|
||||
const handleZoomOutClick = () => {
|
||||
if (isDisabled) return;
|
||||
|
||||
handleSliderChange({}, image.zoom >= 1.5 ? image.zoom - 0.5 : 1);
|
||||
};
|
||||
|
||||
const handleDeleteImage = () => {
|
||||
if (isDisabled) return;
|
||||
setUploadedFile(null);
|
||||
};
|
||||
|
||||
const handleImageChange = throttle(() => {
|
||||
try {
|
||||
if (!editorRef) return;
|
||||
const newPreveiwImage = editorRef.getImageScaledToCanvas()?.toDataURL();
|
||||
setPreviewImage(newPreveiwImage);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
useEffect(() => {
|
||||
handleImageChange();
|
||||
return () => {
|
||||
setPreviewImage("");
|
||||
};
|
||||
}, [image]);
|
||||
|
||||
return (
|
||||
<StyledImageCropper className="icon_cropper">
|
||||
<div className="icon_cropper-crop_area">
|
||||
<ReactSVG
|
||||
className="icon_cropper-grid"
|
||||
src="images/icon-cropper-grid.svg"
|
||||
/>
|
||||
<AvatarEditor
|
||||
ref={setEditorRef}
|
||||
image={uploadedFile}
|
||||
width={216}
|
||||
height={216}
|
||||
position={{ x: image.x, y: image.y }}
|
||||
scale={image.zoom}
|
||||
color={[6, 22, 38, 0.2]}
|
||||
border={0}
|
||||
rotate={0}
|
||||
borderRadius={108}
|
||||
onPositionChange={handlePositionChange}
|
||||
onImageReady={handleImageChange}
|
||||
disableHiDPIScaling
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="icon_cropper-delete_button"
|
||||
onClick={handleDeleteImage}
|
||||
title={t("Common:Delete")}
|
||||
>
|
||||
<ReactSVG src={"images/trash.react.svg"} />
|
||||
<div className="icon_cropper-delete_button-text">
|
||||
{t("Common:Delete")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="icon_cropper-zoom-container">
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomOutClick}
|
||||
iconName={"/static/images/zoom-minus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
<Slider
|
||||
className="icon_cropper-zoom-container-slider"
|
||||
max={5}
|
||||
min={1}
|
||||
onChange={handleSliderChange}
|
||||
step={0.01}
|
||||
value={image.zoom}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
<IconButton
|
||||
className="icon_cropper-zoom-container-button"
|
||||
size="16"
|
||||
onClick={handleZoomInClick}
|
||||
iconName={"/static/images/zoom-plus.react.svg"}
|
||||
isFill={true}
|
||||
isClickable={false}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</StyledImageCropper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageCropper;
|
@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
|
||||
import Tags from "@docspace/common/components/Tags";
|
||||
import Tag from "@docspace/components/tag";
|
||||
import { Base } from "@docspace/components/themes";
|
||||
|
||||
import { smallTablet } from "../../utils/device";
|
||||
import Tag from "../../tag";
|
||||
import { Base } from "../../themes";
|
||||
|
||||
const StyledPreviewTile = styled.div`
|
||||
background: ${(props) =>
|
||||
@ -73,7 +73,7 @@ const StyledPreviewTile = styled.div`
|
||||
`;
|
||||
StyledPreviewTile.defaultProps = { theme: Base };
|
||||
|
||||
const PreviewTile = ({ t, title, previewIcon, tags, defaultTagLabel }) => {
|
||||
const PreviewTile = ({ title, previewIcon, tags, defaultTagLabel }) => {
|
||||
return (
|
||||
<StyledPreviewTile>
|
||||
<div className="tile-header">
|
47
packages/components/ImageEditor/index.js
Normal file
47
packages/components/ImageEditor/index.js
Normal file
@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
import Dropzone from "./Dropzone";
|
||||
import ImageCropper from "./ImageCropper";
|
||||
|
||||
const ImageEditor = ({
|
||||
t,
|
||||
image,
|
||||
onChangeImage,
|
||||
Preview,
|
||||
setPreview,
|
||||
isDisabled,
|
||||
classNameWrapperImageCropper,
|
||||
className,
|
||||
}) => {
|
||||
const setUploadedFile = (uploadedFile) =>
|
||||
onChangeImage({ ...image, uploadedFile });
|
||||
|
||||
const isDefaultAvatar =
|
||||
typeof image.uploadedFile === "string" &&
|
||||
image.uploadedFile.includes("default_user_photo");
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{image.uploadedFile && !isDefaultAvatar && (
|
||||
<div className={classNameWrapperImageCropper}>
|
||||
<ImageCropper
|
||||
t={t}
|
||||
image={image}
|
||||
onChangeImage={onChangeImage}
|
||||
uploadedFile={image.uploadedFile}
|
||||
setUploadedFile={setUploadedFile}
|
||||
setPreviewImage={setPreview}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
{Preview}
|
||||
</div>
|
||||
)}
|
||||
<Dropzone
|
||||
t={t}
|
||||
setUploadedFile={setUploadedFile}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageEditor;
|
@ -1,6 +1,7 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import Base from "../themes/base";
|
||||
import { mobile, tablet, hugeMobile } from "../utils/device";
|
||||
import IconButton from "../icon-button";
|
||||
import Scrollbar from "../scrollbar";
|
||||
import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
|
||||
@ -412,6 +413,21 @@ const StyledScrollbar = styled(Scrollbar)`
|
||||
|
||||
StyledTableRow.defaultProps = { theme: Base };
|
||||
|
||||
const StyledSettingsIcon = styled(IconButton)`
|
||||
${(props) =>
|
||||
props.isDisabled &&
|
||||
css`
|
||||
svg {
|
||||
path {
|
||||
fill: ${props.theme.tableContainer.header
|
||||
.settingsIconDisableColor} !important;
|
||||
}
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
StyledSettingsIcon.defaultProps = { theme: Base };
|
||||
|
||||
export {
|
||||
StyledTableContainer,
|
||||
StyledTableRow,
|
||||
@ -424,4 +440,5 @@ export {
|
||||
StyledInfoPanelToggleWrapper,
|
||||
StyledEmptyTableContainer,
|
||||
StyledScrollbar,
|
||||
StyledSettingsIcon,
|
||||
};
|
||||
|
@ -1,8 +1,11 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import IconButton from "../icon-button";
|
||||
// import IconButton from "../icon-button";
|
||||
import DropDown from "../drop-down";
|
||||
import { StyledTableSettings } from "./StyledTableContainer";
|
||||
import {
|
||||
StyledTableSettings,
|
||||
StyledSettingsIcon,
|
||||
} from "./StyledTableContainer";
|
||||
import Checkbox from "../checkbox";
|
||||
|
||||
const TableSettings = ({ columns, infoPanelVisible }) => {
|
||||
@ -27,7 +30,7 @@ const TableSettings = ({ columns, infoPanelVisible }) => {
|
||||
className="table-container_header-settings-icon"
|
||||
ref={ref}
|
||||
>
|
||||
<IconButton
|
||||
<StyledSettingsIcon
|
||||
size={12}
|
||||
isFill
|
||||
iconName="/static/images/settings.desc.react.svg"
|
||||
|
@ -2211,6 +2211,8 @@ const Base = {
|
||||
borderImageSource: `linear-gradient(to right,${white} 21px,${grayLightMid} 21px,${grayLightMid} calc(100% - 20px),${white} calc(100% - 20px))`,
|
||||
lengthenBorderImageSource: `linear-gradient(to right, ${grayLightMid}, ${grayLightMid})`,
|
||||
hotkeyBorderBottom: `1px solid ${globalColors.blueMain}`,
|
||||
|
||||
settingsIconDisableColor: "#D0D5DA",
|
||||
},
|
||||
|
||||
tableCell: {
|
||||
@ -3105,8 +3107,8 @@ const Base = {
|
||||
},
|
||||
|
||||
itemIcon: {
|
||||
borderColor: grayLightMid
|
||||
}
|
||||
borderColor: grayLightMid,
|
||||
},
|
||||
};
|
||||
|
||||
export default Base;
|
||||
|
@ -2204,6 +2204,8 @@ const Dark = {
|
||||
borderImageSource: `linear-gradient(to right,${black} 21px,#474747 21px,#474747 calc(100% - 20px),${black} calc(100% - 20px))`,
|
||||
lengthenBorderImageSource: `linear-gradient(to right, #474747, #474747)`,
|
||||
hotkeyBorderBottom: `1px solid ${globalColors.blueMain}`,
|
||||
|
||||
settingsIconDisableColor: "#474747",
|
||||
},
|
||||
|
||||
tableCell: {
|
||||
@ -3104,8 +3106,8 @@ const Dark = {
|
||||
},
|
||||
|
||||
itemIcon: {
|
||||
borderColor: "#474747"
|
||||
}
|
||||
borderColor: "#474747",
|
||||
},
|
||||
};
|
||||
|
||||
export default Dark;
|
||||
|
Loading…
Reference in New Issue
Block a user