Merge branch 'feature/modal-redesign' of https://github.com/ONLYOFFICE/AppServer into feature/add-17keys
This commit is contained in:
commit
fe993907ad
@ -7,11 +7,13 @@ import DropDownItem from "../drop-down-item";
|
||||
import {
|
||||
StyledSpan,
|
||||
StyledText,
|
||||
StyledTextWithExpander,
|
||||
StyledLinkWithDropdown,
|
||||
Caret,
|
||||
} from "./styled-link-with-dropdown";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
class LinkWithDropdown extends React.Component {
|
||||
constructor(props) {
|
||||
@ -101,6 +103,7 @@ class LinkWithDropdown extends React.Component {
|
||||
directionY,
|
||||
theme,
|
||||
hasScroll,
|
||||
withExpander,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
@ -118,15 +121,7 @@ class LinkWithDropdown extends React.Component {
|
||||
/>
|
||||
));
|
||||
|
||||
return (
|
||||
<StyledSpan className={className} id={id} style={style} ref={this.ref}>
|
||||
<span onClick={this.onOpen}>
|
||||
<StyledLinkWithDropdown
|
||||
isSemitransparent={isSemitransparent}
|
||||
dropdownType={dropdownType}
|
||||
color={color}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
const styledText = (
|
||||
<StyledText
|
||||
className="text"
|
||||
isTextOverflow={isTextOverflow}
|
||||
@ -138,15 +133,32 @@ class LinkWithDropdown extends React.Component {
|
||||
title={title}
|
||||
dropdownType={dropdownType}
|
||||
isDisabled={isDisabled}
|
||||
withTriangle
|
||||
>
|
||||
{this.props.children}
|
||||
</StyledText>
|
||||
<Caret
|
||||
color={color}
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledSpan className={className} id={id} style={style} ref={this.ref}>
|
||||
<span onClick={this.onOpen}>
|
||||
<StyledLinkWithDropdown
|
||||
isSemitransparent={isSemitransparent}
|
||||
dropdownType={dropdownType}
|
||||
isOpen={this.state.isOpen}
|
||||
color={color}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{withExpander ? (
|
||||
<StyledTextWithExpander isOpen={this.state.isOpen}>
|
||||
{styledText}
|
||||
<ReactSVG
|
||||
className="expander"
|
||||
src={"/static/images/expander-down.react.svg"}
|
||||
/>
|
||||
</StyledTextWithExpander>
|
||||
) : (
|
||||
styledText
|
||||
)}
|
||||
</StyledLinkWithDropdown>
|
||||
</span>
|
||||
<DropDown
|
||||
@ -156,6 +168,7 @@ class LinkWithDropdown extends React.Component {
|
||||
withArrow={false}
|
||||
forwardedRef={this.ref}
|
||||
directionY={directionY}
|
||||
isDropdown={false}
|
||||
clickOutsideAction={this.onClose}
|
||||
{...rest}
|
||||
>
|
||||
@ -185,6 +198,7 @@ LinkWithDropdown.propTypes = {
|
||||
/** Type of dropdown: alwaysDashed is always show dotted style and icon of arrow,
|
||||
* appearDashedAfterHover is show dotted style and icon arrow only after hover */
|
||||
dropdownType: PropTypes.oneOf(["alwaysDashed", "appearDashedAfterHover"]),
|
||||
withExpander: PropTypes.bool,
|
||||
/** Font size of link */
|
||||
fontSize: PropTypes.string,
|
||||
/** Font weight of link */
|
||||
@ -225,6 +239,7 @@ LinkWithDropdown.defaultProps = {
|
||||
className: "",
|
||||
isDisabled: false,
|
||||
hasScroll: false,
|
||||
withExpander: false,
|
||||
};
|
||||
|
||||
export default LinkWithDropdown;
|
||||
|
@ -5,6 +5,7 @@ import PropTypes from "prop-types";
|
||||
import Text from "../text";
|
||||
import Base from "../themes/base";
|
||||
import ExpanderDownIcon from "../../../public/images/expander-down.react.svg";
|
||||
import { transform } from "lodash";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const SimpleLinkWithDropdown = ({
|
||||
isBold,
|
||||
@ -123,6 +124,27 @@ const StyledLinkWithDropdown = styled(SimpleLinkWithDropdown)`
|
||||
}
|
||||
`;
|
||||
StyledLinkWithDropdown.defaultProps = { theme: Base };
|
||||
|
||||
const StyledTextWithExpander = styled.div`
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
.expander {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 6.35px;
|
||||
svg {
|
||||
transform: ${(props) => (props.isOpen ? "rotate(180deg)" : "rotate(0)")};
|
||||
width: 6.35px;
|
||||
height: auto;
|
||||
path {
|
||||
fill: ${(props) => props.theme.linkWithDropdown.expander.iconColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// eslint-disable-next-line react/prop-types, no-unused-vars
|
||||
const SimpleText = ({ color, ...props }) => <Text as="span" {...props} />;
|
||||
const StyledText = styled(SimpleText)`
|
||||
@ -150,4 +172,10 @@ const StyledSpan = styled.span`
|
||||
`;
|
||||
StyledSpan.defaultProps = { theme: Base };
|
||||
|
||||
export { StyledSpan, StyledText, StyledLinkWithDropdown, Caret };
|
||||
export {
|
||||
StyledSpan,
|
||||
StyledTextWithExpander,
|
||||
StyledText,
|
||||
StyledLinkWithDropdown,
|
||||
Caret,
|
||||
};
|
||||
|
@ -103,6 +103,8 @@ const StyledBody = styled(Box)`
|
||||
padding-bottom: ${(props) =>
|
||||
props.currentDisplayType === "aside" || props.hasFooter ? "8px" : "16px"};
|
||||
|
||||
margin-right: ${(props) => (props.withBodyScroll ? "-16px" : "0")};
|
||||
|
||||
${(props) =>
|
||||
props.currentDisplayType === "aside" &&
|
||||
css`
|
||||
|
@ -103,7 +103,7 @@ const Modal = ({
|
||||
)}
|
||||
{body && (
|
||||
<StyledBody
|
||||
withoutBodyScroll={true}
|
||||
withBodyScroll={withBodyScroll}
|
||||
hasFooter={1 && footer}
|
||||
currentDisplayType={currentDisplayType}
|
||||
{...body.props}
|
||||
|
@ -866,6 +866,10 @@ const Base = {
|
||||
|
||||
span: { maxWidth: "300px" },
|
||||
|
||||
expander: {
|
||||
iconColor: black,
|
||||
},
|
||||
|
||||
caret: {
|
||||
width: "5px",
|
||||
minWidth: "5px",
|
||||
|
@ -863,6 +863,10 @@ const Dark = {
|
||||
|
||||
span: { maxWidth: "300px" },
|
||||
|
||||
expander: {
|
||||
iconColor: white,
|
||||
},
|
||||
|
||||
caret: {
|
||||
width: "5px",
|
||||
minWidth: "5px",
|
||||
|
@ -106,7 +106,8 @@ const DownloadContent = (props) => {
|
||||
return (
|
||||
<StyledDownloadContent isOpen={showHeader ? isOpen : true} theme={theme}>
|
||||
{showHeader && (
|
||||
<div className="download-dialog_content-wrapper">
|
||||
<div className="download-dialog_content-wrapper download-dialog-row">
|
||||
<div className="download-dialog-main-content">
|
||||
<Checkbox
|
||||
data-item-id="All"
|
||||
data-type={type}
|
||||
@ -117,16 +118,18 @@ const DownloadContent = (props) => {
|
||||
/>
|
||||
<div
|
||||
onClick={onOpen}
|
||||
className="download-dialog-heading download-dialog_row-text"
|
||||
className="download-dialog-heading download-dialog-title"
|
||||
>
|
||||
<Text noSelect fontSize="16px" fontWeight={600}>
|
||||
{title}
|
||||
</Text>
|
||||
<ArrowIcon className="download-dialog-icon" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="download-dialog-actions">
|
||||
{(isChecked || isIndeterminate) && !isOther && (
|
||||
<LinkWithDropdown
|
||||
className="download-dialog-link"
|
||||
containerMinWidth="fit-content"
|
||||
data={titleData}
|
||||
directionX="left"
|
||||
@ -134,11 +137,13 @@ const DownloadContent = (props) => {
|
||||
dropdownType="alwaysDashed"
|
||||
fontSize="13px"
|
||||
fontWeight={600}
|
||||
withExpander
|
||||
>
|
||||
{titleFormat}
|
||||
</LinkWithDropdown>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="download-dialog_hidden-items">
|
||||
{items.map((file) => {
|
||||
|
@ -4,6 +4,8 @@ import { ReactSVG } from "react-svg";
|
||||
import Text from "@appserver/components/text";
|
||||
import Checkbox from "@appserver/components/checkbox";
|
||||
import LinkWithDropdown from "@appserver/components/link-with-dropdown";
|
||||
import DropDownItem from "@appserver/components/drop-down-item";
|
||||
import GroupButton from "@appserver/components/group-button";
|
||||
|
||||
const DownloadRow = (props) => {
|
||||
const {
|
||||
@ -42,7 +44,8 @@ const DownloadRow = (props) => {
|
||||
const element = getItemIcon(file);
|
||||
|
||||
return (
|
||||
<div className="download-dialog_row">
|
||||
<div className="download-dialog-row">
|
||||
<div className="download-dialog-main-content">
|
||||
<Checkbox
|
||||
className="download-dialog-checkbox"
|
||||
data-item-id={file.id}
|
||||
@ -50,9 +53,9 @@ const DownloadRow = (props) => {
|
||||
onChange={onRowSelect}
|
||||
isChecked={isChecked}
|
||||
/>
|
||||
{element}
|
||||
<div className="download-dialog-icon-contatiner">{element}</div>
|
||||
<Text
|
||||
className="download-dialog_row-text"
|
||||
className="download-dialog-title"
|
||||
truncate
|
||||
type="page"
|
||||
title={file.title}
|
||||
@ -62,6 +65,9 @@ const DownloadRow = (props) => {
|
||||
>
|
||||
{file.title}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div className="download-dialog-actions">
|
||||
{file.checked && !isOther && (
|
||||
<LinkWithDropdown
|
||||
className="download-dialog-link"
|
||||
@ -74,6 +80,7 @@ const DownloadRow = (props) => {
|
||||
fontSize="13px"
|
||||
fontWeight={600}
|
||||
hasScroll={true}
|
||||
withExpander
|
||||
>
|
||||
{file.format || t("OriginalFormat")}
|
||||
</LinkWithDropdown>
|
||||
@ -92,6 +99,7 @@ const DownloadRow = (props) => {
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -2,54 +2,17 @@ import styled, { css } from "styled-components";
|
||||
import ModalDialog from "@appserver/components/modal-dialog";
|
||||
|
||||
const StyledDownloadDialog = styled(ModalDialog)`
|
||||
.modal-dialog-content {
|
||||
padding: 0 0 0 16px;
|
||||
}
|
||||
|
||||
.download-dialog-description {
|
||||
margin-bottom: 18px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.modal-dialog-aside-footer {
|
||||
display: flex;
|
||||
padding-right: 32px;
|
||||
width: 100%;
|
||||
gap: 10px;
|
||||
.download-dialog-convert-message {
|
||||
margin-top: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledDownloadContent = styled.div`
|
||||
.download-dialog_row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
|
||||
.download-dialog-other-text {
|
||||
min-width: 141px;
|
||||
}
|
||||
}
|
||||
|
||||
.download-dialog-checkbox {
|
||||
padding: 8px 6px 8px 8px;
|
||||
}
|
||||
|
||||
.download-dialog_row-text {
|
||||
width: 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.download-dialog-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.download-dialog_content-wrapper {
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
${({ isOpen }) =>
|
||||
isOpen &&
|
||||
css`
|
||||
@ -58,12 +21,18 @@ const StyledDownloadContent = styled.div`
|
||||
padding: 0 16px;
|
||||
`}
|
||||
|
||||
.download-dialog-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.download-dialog-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
transform: ${({ isOpen }) =>
|
||||
isOpen ? "rotate(270deg)" : "rotate(90deg)"};
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: #333;
|
||||
@ -75,6 +44,54 @@ const StyledDownloadContent = styled.div`
|
||||
.download-dialog_hidden-items {
|
||||
display: ${({ isOpen }) => (isOpen ? "block" : "none")};
|
||||
}
|
||||
|
||||
.download-dialog-row {
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
height: 48px;
|
||||
|
||||
.download-dialog-main-content {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
width: 100%;
|
||||
|
||||
.checkbox,
|
||||
svg {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.download-dialog-checkbox {
|
||||
padding: 8px;
|
||||
}
|
||||
.download-dialog-icon-contatiner {
|
||||
padding: 0 8px;
|
||||
max-height: 32px;
|
||||
max-width: 32px;
|
||||
}
|
||||
.download-dialog-title {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.download-dialog-actions {
|
||||
.download-dialog-link {
|
||||
a {
|
||||
padding-right: 0;
|
||||
text-underline-offset: 1px;
|
||||
}
|
||||
}
|
||||
.download-dialog-other-text {
|
||||
text-align: end;
|
||||
color: #a3a9ae;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledDownloadDialog, StyledDownloadContent };
|
||||
|
@ -250,6 +250,16 @@ class DownloadDialogComponent extends React.Component {
|
||||
getItemIcon: this.getItemIcon,
|
||||
};
|
||||
|
||||
const totalItemsNum =
|
||||
this.state.documents.files.length +
|
||||
this.state.spreadsheets.files.length +
|
||||
this.state.presentations.files.length +
|
||||
this.state.other.files.length +
|
||||
(this.state.documents.files.length > 1 && 1) +
|
||||
(this.state.spreadsheets.files.length > 1 && 1) +
|
||||
(this.state.presentations.files.length > 1 && 1) +
|
||||
(this.state.other.files.length > 1 && 1);
|
||||
|
||||
return (
|
||||
<StyledDownloadDialog
|
||||
visible={visible}
|
||||
@ -259,6 +269,7 @@ class DownloadDialogComponent extends React.Component {
|
||||
autoMaxWidth
|
||||
isLarge
|
||||
isLoading={!tReady}
|
||||
withBodyScroll={totalItemsNum > 11}
|
||||
>
|
||||
<ModalDialog.Header>{t("Translations:DownloadAs")}</ModalDialog.Header>
|
||||
|
||||
@ -313,6 +324,10 @@ class DownloadDialogComponent extends React.Component {
|
||||
title={t("Other")}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="download-dialog-convert-message">
|
||||
<Text noSelect>{t("ConvertMessage")}</Text>
|
||||
</div>
|
||||
</ModalDialog.Body>
|
||||
|
||||
<ModalDialog.Footer>
|
||||
|
Loading…
Reference in New Issue
Block a user