Merge branch 'develop' into bugfix/border-style
This commit is contained in:
commit
74ef2c3ad2
@ -10,8 +10,11 @@ const localesDir = join(
|
||||
"locales"
|
||||
);
|
||||
|
||||
//console.log("localesDir", localesDir);
|
||||
|
||||
const getFileList = (dirName) => {
|
||||
let files = [];
|
||||
|
||||
const items = readdirSync(dirName, { withFileTypes: true });
|
||||
|
||||
for (const item of items) {
|
||||
@ -29,6 +32,8 @@ const files = getFileList(localesDir);
|
||||
|
||||
files.forEach((filePath) => {
|
||||
try {
|
||||
if (filePath.endsWith(".DS_Store")) return;
|
||||
|
||||
let content = readFileSync(filePath);
|
||||
writeFileSync(filePath, minifyJson(content, filePath));
|
||||
//console.log(`File '${filePath}' minified`);
|
||||
|
16
build/start/change-service-timeout.bat
Normal file
16
build/start/change-service-timeout.bat
Normal file
@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..
|
||||
call runasadmin.bat "%~dpnx0"
|
||||
|
||||
POPD
|
||||
|
||||
if %errorlevel% == 0 (
|
||||
pwsh %~dp0/command.ps1 "increase-service-timeout"
|
||||
)
|
||||
|
||||
echo.
|
||||
|
||||
if "%1"=="nopause" goto start
|
||||
pause
|
||||
:start
|
@ -2,14 +2,29 @@ $PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object
|
||||
$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object {$_.minor}
|
||||
|
||||
if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) {
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2. Press Enter to exit."
|
||||
Pause
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2."
|
||||
exit
|
||||
}
|
||||
|
||||
$WorkDir = "$(Split-Path -Parent $PSScriptRoot)\run";
|
||||
$CommandName = "$($args[0])";
|
||||
|
||||
if ( $CommandName -eq "increase-service-timeout" ) {
|
||||
$RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control'
|
||||
$Name = 'ServicesPipeTimeout'
|
||||
$Value = '90000'
|
||||
|
||||
Write-Output "Changing service start timeout from default value (30000 ms ) to $($Value) ms"
|
||||
|
||||
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force
|
||||
|
||||
|
||||
Write-Warning "Please, restart the computer for the changes to take effect."
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
|
||||
#Write-Output "Starting $($CommandName) services at time: $(Get-Date -Format HH:mm:ss)"
|
||||
#Write-Output ""
|
||||
|
||||
|
@ -119,7 +119,7 @@ const RenameEvent = ({
|
||||
<Dialog
|
||||
t={t}
|
||||
visible={eventDialogVisible}
|
||||
title={t("Home: Rename")}
|
||||
title={t("Files:Rename")}
|
||||
startValue={startValue}
|
||||
onSave={onUpdate}
|
||||
onCancel={onCancel}
|
||||
|
@ -31,7 +31,7 @@ const StyledContainer = styled.div`
|
||||
`;
|
||||
|
||||
const Layout = (props) => {
|
||||
const { children, isTabletView, setIsTabletView, isBannerVisible } = props;
|
||||
const { children, isTabletView, setIsTabletView } = props;
|
||||
|
||||
const [contentHeight, setContentHeight] = useState();
|
||||
const [isPortrait, setIsPortrait] = useState();
|
||||
@ -74,10 +74,6 @@ const Layout = (props) => {
|
||||
};
|
||||
}, [isTabletView]);
|
||||
|
||||
useEffect(() => {
|
||||
changeRootHeight();
|
||||
}, [isBannerVisible]);
|
||||
|
||||
useEffect(() => {
|
||||
const htmlEl = document.getElementsByTagName("html")[0];
|
||||
const bodyEl = document.getElementsByTagName("body")[0];
|
||||
@ -141,8 +137,7 @@ const Layout = (props) => {
|
||||
// }
|
||||
// }
|
||||
|
||||
const bannerHeight = isBannerVisible ? 80 : 0;
|
||||
let vh = (windowHeight - bannerHeight) * 0.01;
|
||||
let vh = windowHeight * 0.01;
|
||||
document.documentElement.style.setProperty("--vh", `${vh}px`);
|
||||
setContentHeight(height);
|
||||
};
|
||||
@ -186,6 +181,5 @@ export default inject(({ auth, bannerStore }) => {
|
||||
return {
|
||||
isTabletView: auth.settingsStore.isTabletView,
|
||||
setIsTabletView: auth.settingsStore.setIsTabletView,
|
||||
isBannerVisible: bannerStore.isBannerVisible,
|
||||
};
|
||||
})(observer(Layout));
|
||||
|
@ -11,8 +11,8 @@ const StyledContainer = styled.div`
|
||||
|
||||
${isMobileOnly &&
|
||||
css`
|
||||
width: calc(100% + 16px);
|
||||
max-width: calc(100% + 16px);
|
||||
width: calc(100% + 8px);
|
||||
max-width: calc(100% + 8px);
|
||||
|
||||
margin-right: -16px;
|
||||
margin-top: 48px;
|
||||
|
@ -39,7 +39,8 @@ const ReactSmartBanner = (props) => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.location.pathname.toLowerCase().includes("rooms")) {
|
||||
const path = window.location.pathname.toLowerCase();
|
||||
if (path.includes("rooms") || path.includes("files")) {
|
||||
setIsDocuments(true);
|
||||
} else {
|
||||
setIsDocuments(false);
|
||||
|
@ -24,13 +24,13 @@ export const getFileTypeName = (fileType, t) => {
|
||||
case FileType.Image:
|
||||
return t("Common:Image");
|
||||
case FileType.Spreadsheet:
|
||||
return t("Home:Spreadsheet");
|
||||
return t("Files:Spreadsheet");
|
||||
case FileType.Presentation:
|
||||
return t("Home:Presentation");
|
||||
return t("Files:Presentation");
|
||||
case FileType.Document:
|
||||
return t("Home:Document");
|
||||
return t("Files:Document");
|
||||
default:
|
||||
return t("Home:Folder");
|
||||
return t("Files:Folder");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,6 +67,7 @@ class DetailsHelper {
|
||||
this.openUser = props.openUser;
|
||||
this.personal = props.personal;
|
||||
this.culture = props.culture;
|
||||
this.isVisitor = props.isVisitor;
|
||||
}
|
||||
|
||||
getPropertyList = () => {
|
||||
@ -191,10 +192,9 @@ class DetailsHelper {
|
||||
/// Property //
|
||||
|
||||
getItemOwner = () => {
|
||||
const onOpenUser = () =>
|
||||
this.openUser(this.item.createdBy.id, this.history);
|
||||
const onOpenUser = () => this.openUser(this.item.createdBy, this.history);
|
||||
|
||||
return this.personal
|
||||
return this.personal || this.isVisitor
|
||||
? text(decodeString(this.item.createdBy?.displayName))
|
||||
: link(decodeString(this.item.createdBy?.displayName), onOpenUser);
|
||||
};
|
||||
@ -244,10 +244,9 @@ class DetailsHelper {
|
||||
};
|
||||
|
||||
getItemLastModifiedBy = () => {
|
||||
const onOpenUser = () =>
|
||||
this.openUser(this.item.updatedBy.id, this.history);
|
||||
const onOpenUser = () => this.openUser(this.item.updatedBy, this.history);
|
||||
|
||||
return this.personal
|
||||
return this.personal || this.isVisitor
|
||||
? text(decodeString(this.item.updatedBy?.displayName))
|
||||
: link(decodeString(this.item.updatedBy?.displayName), onOpenUser);
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ const StyledUserNameLink = styled.span`
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: inline-block;
|
||||
${(props) => props.isVisitor && "cursor: default"};
|
||||
}
|
||||
|
||||
.link {
|
||||
|
@ -18,6 +18,7 @@ const Details = ({
|
||||
createThumbnail,
|
||||
getInfoPanelItemIcon,
|
||||
openUser,
|
||||
isVisitor,
|
||||
}) => {
|
||||
const [itemProperties, setItemProperties] = useState([]);
|
||||
|
||||
@ -27,6 +28,7 @@ const Details = ({
|
||||
const history = useHistory();
|
||||
|
||||
const detailsHelper = new DetailsHelper({
|
||||
isVisitor,
|
||||
t,
|
||||
item: selection,
|
||||
openUser,
|
||||
@ -95,9 +97,13 @@ const Details = ({
|
||||
};
|
||||
|
||||
export default inject(({ auth, filesStore }) => {
|
||||
const { userStore } = auth;
|
||||
const { selection, getInfoPanelItemIcon, openUser } = auth.infoPanelStore;
|
||||
const { createThumbnail } = filesStore;
|
||||
const { personal, culture } = auth.settingsStore;
|
||||
const { user } = userStore;
|
||||
|
||||
const isVisitor = user.isVisitor;
|
||||
|
||||
return {
|
||||
personal,
|
||||
@ -106,5 +112,6 @@ export default inject(({ auth, filesStore }) => {
|
||||
createThumbnail,
|
||||
getInfoPanelItemIcon,
|
||||
openUser,
|
||||
isVisitor,
|
||||
};
|
||||
})(withTranslation(["InfoPanel", "Common", "Translations"])(Details));
|
||||
})(withTranslation(["InfoPanel", "Common", "Translations", "Files"])(Details));
|
||||
|
@ -4,7 +4,7 @@ import { useHistory } from "react-router-dom";
|
||||
import Link from "@docspace/components/link";
|
||||
import { StyledUserNameLink } from "../../styles/history";
|
||||
|
||||
const HistoryBlockUser = ({ user, withComma, openUser }) => {
|
||||
const HistoryBlockUser = ({ user, withComma, openUser, isVisitor }) => {
|
||||
const username = user.displayName;
|
||||
const history = useHistory();
|
||||
|
||||
@ -12,9 +12,11 @@ const HistoryBlockUser = ({ user, withComma, openUser }) => {
|
||||
openUser(user, history);
|
||||
};
|
||||
|
||||
const onClickProp = isVisitor ? {} : { onClick: onUserClick };
|
||||
|
||||
return (
|
||||
<StyledUserNameLink key={user.id} className="user">
|
||||
<Link className="username link" onClick={onUserClick}>
|
||||
<StyledUserNameLink key={user.id} className="user" isVisitor={isVisitor}>
|
||||
<Link className="username link" {...onClickProp}>
|
||||
{username}
|
||||
</Link>
|
||||
{withComma ? "," : ""}
|
||||
|
@ -29,6 +29,7 @@ const History = ({
|
||||
getHistory,
|
||||
checkAndOpenLocationAction,
|
||||
openUser,
|
||||
isVisitor,
|
||||
}) => {
|
||||
const [history, setHistory] = useState(null);
|
||||
const [showLoader, setShowLoader] = useState(false);
|
||||
@ -149,6 +150,7 @@ const History = ({
|
||||
feed.target &&
|
||||
[feed.target, ...feed.groupedFeeds].map((user, i) => (
|
||||
<HistoryBlockUser
|
||||
isVisitor={isVisitor}
|
||||
key={user.id}
|
||||
user={user}
|
||||
withComma={i !== feed.groupedFeeds.length}
|
||||
@ -164,6 +166,7 @@ const History = ({
|
||||
};
|
||||
|
||||
export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
const { userStore } = auth;
|
||||
const {
|
||||
selection,
|
||||
selectionParentRoom,
|
||||
@ -176,6 +179,9 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
const { getHistory } = filesStore;
|
||||
const { checkAndOpenLocationAction } = filesActionsStore;
|
||||
|
||||
const { user } = userStore;
|
||||
const isVisitor = user.isVisitor;
|
||||
|
||||
return {
|
||||
personal,
|
||||
culture,
|
||||
@ -186,5 +192,6 @@ export default inject(({ auth, filesStore, filesActionsStore }) => {
|
||||
getHistory,
|
||||
checkAndOpenLocationAction,
|
||||
openUser,
|
||||
isVisitor,
|
||||
};
|
||||
})(withTranslation(["InfoPanel", "Common", "Translations"])(observer(History)));
|
||||
|
@ -31,10 +31,10 @@ const Article = ({
|
||||
|
||||
isGracePeriod,
|
||||
|
||||
isBannerVisible,
|
||||
hideProfileBlock,
|
||||
isFreeTariff,
|
||||
isAvailableArticlePaymentAlert,
|
||||
currentColorScheme,
|
||||
...rest
|
||||
}) => {
|
||||
const [articleHeaderContent, setArticleHeaderContent] = React.useState(null);
|
||||
@ -113,7 +113,6 @@ const Article = ({
|
||||
id={"article-container"}
|
||||
showText={showText}
|
||||
articleOpen={articleOpen}
|
||||
isBannerVisible={isBannerVisible}
|
||||
{...rest}
|
||||
>
|
||||
<SubArticleHeader showText={showText}>
|
||||
@ -132,6 +131,7 @@ const Article = ({
|
||||
<HideArticleMenuButton
|
||||
showText={showText}
|
||||
toggleShowText={toggleShowText}
|
||||
currentColorScheme={currentColorScheme}
|
||||
/>
|
||||
{!hideProfileBlock && !isMobileOnly && (
|
||||
<ArticleProfile showText={showText} />
|
||||
@ -180,7 +180,7 @@ Article.Body = () => {
|
||||
};
|
||||
Article.Body.displayName = "Body";
|
||||
|
||||
export default inject(({ auth, bannerStore }) => {
|
||||
export default inject(({ auth }) => {
|
||||
const {
|
||||
settingsStore,
|
||||
currentQuotaStore,
|
||||
@ -189,7 +189,6 @@ export default inject(({ auth, bannerStore }) => {
|
||||
} = auth;
|
||||
const { isFreeTariff } = currentQuotaStore;
|
||||
const { isGracePeriod } = currentTariffStatusStore;
|
||||
const { isBannerVisible } = bannerStore;
|
||||
|
||||
const { user } = userStore;
|
||||
|
||||
@ -202,6 +201,7 @@ export default inject(({ auth, bannerStore }) => {
|
||||
setIsMobileArticle,
|
||||
toggleShowText,
|
||||
toggleArticleOpen,
|
||||
currentColorScheme,
|
||||
} = settingsStore;
|
||||
|
||||
return {
|
||||
@ -212,8 +212,8 @@ export default inject(({ auth, bannerStore }) => {
|
||||
toggleShowText,
|
||||
toggleArticleOpen,
|
||||
isFreeTariff,
|
||||
isBannerVisible,
|
||||
isGracePeriod,
|
||||
isAvailableArticlePaymentAlert,
|
||||
currentColorScheme,
|
||||
};
|
||||
})(observer(Article));
|
||||
|
@ -42,6 +42,7 @@ const StyledHideArticleMenuButton = styled.div`
|
||||
|
||||
.article-hide-menu-text {
|
||||
margin-left: 8px;
|
||||
color: ${({ currentColorScheme }) => currentColorScheme.accentColor};
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
@ -71,14 +72,28 @@ const StyledHideArticleMenuButton = styled.div`
|
||||
.article-hide-menu-icon_svg,
|
||||
.article-show-menu-icon_svg {
|
||||
height: 28px;
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: ${({ currentColorScheme }) => currentColorScheme.accentColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const HideArticleMenuButton = ({ showText, toggleShowText }) => {
|
||||
const HideArticleMenuButton = ({
|
||||
showText,
|
||||
toggleShowText,
|
||||
currentColorScheme,
|
||||
}) => {
|
||||
const { t } = useTranslation("Common");
|
||||
|
||||
return (
|
||||
<StyledHideArticleMenuButton showText={showText} onClick={toggleShowText}>
|
||||
<StyledHideArticleMenuButton
|
||||
showText={showText}
|
||||
onClick={toggleShowText}
|
||||
currentColorScheme={currentColorScheme}
|
||||
>
|
||||
{showText ? (
|
||||
<div className="article-hide-menu-container">
|
||||
<ReactSVG
|
||||
@ -91,7 +106,6 @@ const HideArticleMenuButton = ({ showText, toggleShowText }) => {
|
||||
fontSize="12px"
|
||||
noSelect
|
||||
truncate
|
||||
color="#3B72A7"
|
||||
>
|
||||
{t("HideArticleMenu")}
|
||||
</Text>
|
||||
|
@ -1,29 +1,27 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Base from "../themes/base";
|
||||
import Loader from "../loader";
|
||||
import StyledButton from "./styled-button";
|
||||
import Base from "../themes/base";
|
||||
import { ColorTheme, ThemeType } from "@docspace/common/components/ColorTheme";
|
||||
|
||||
// eslint-disable-next-line no-unused-vars, react/prop-types
|
||||
const Button = React.forwardRef((props, ref) => {
|
||||
const { primary, size, isLoading, icon, label } = props;
|
||||
const { isLoading, icon, label, primary } = props;
|
||||
return (
|
||||
<ColorTheme {...props} innerRef={ref} themeId={ThemeType.Button}>
|
||||
<div className="button-content">
|
||||
{(isLoading || icon) &&
|
||||
(isLoading ? (
|
||||
<Loader
|
||||
type="oval"
|
||||
size={
|
||||
size === "medium" ? "20px" : size === "normal" ? "16px" : "12px"
|
||||
}
|
||||
color={primary ? "#FFFFFF" : "#333333"}
|
||||
className="loader"
|
||||
/>
|
||||
) : (
|
||||
<div className="icon">{icon}</div>
|
||||
))}
|
||||
{isLoading && (
|
||||
<Loader
|
||||
className="loader"
|
||||
size="20px"
|
||||
type="track"
|
||||
label={label}
|
||||
primary={primary}
|
||||
/>
|
||||
)}
|
||||
{icon && <div className="icon">{icon}</div>}
|
||||
{label}
|
||||
</div>
|
||||
</ColorTheme>
|
||||
@ -35,7 +33,7 @@ Button.propTypes = {
|
||||
label: PropTypes.string,
|
||||
/** Tells when the button should be primary */
|
||||
primary: PropTypes.bool,
|
||||
/** Size of button.
|
||||
/** Size of button.
|
||||
|
||||
The normal size equals 36px and 40px in height on the Desktop and Touchcreen devices. */
|
||||
size: PropTypes.oneOf([
|
||||
@ -43,8 +41,6 @@ Button.propTypes = {
|
||||
"small",
|
||||
"normal",
|
||||
"medium",
|
||||
"normalDesktop",
|
||||
"normalTouchscreen",
|
||||
]),
|
||||
/** Scale width of button to 100% */
|
||||
scale: PropTypes.bool,
|
||||
|
@ -3,7 +3,6 @@ import styled, { css } from "styled-components";
|
||||
import PropTypes from "prop-types";
|
||||
import NoUserSelect from "../utils/commonStyles";
|
||||
import Base from "../themes/base";
|
||||
import { isDesktop } from "../utils/device";
|
||||
|
||||
const activeCss = css`
|
||||
background-color: ${(props) =>
|
||||
@ -73,6 +72,29 @@ const hoverCss = css`
|
||||
}
|
||||
`;
|
||||
|
||||
const loadingCss = css`
|
||||
background-color: ${(props) =>
|
||||
props.primary
|
||||
? props.theme.button.backgroundColor.primaryLoading
|
||||
: props.theme.button.backgroundColor.grayLight};
|
||||
|
||||
color: ${(props) =>
|
||||
props.primary
|
||||
? props.theme.button.color.primary
|
||||
: props.theme.button.color.base};
|
||||
|
||||
${(props) =>
|
||||
props.primary
|
||||
? css`
|
||||
border: ${(props) => props.theme.button.border.primaryLoading};
|
||||
box-sizing: ${(props) => props.theme.button.boxSizing};
|
||||
`
|
||||
: css`
|
||||
border: ${(props) => props.theme.button.border.baseLoading};
|
||||
box-sizing: ${(props) => props.theme.button.boxSizing};
|
||||
`}
|
||||
`;
|
||||
|
||||
const disableCss = css`
|
||||
background-color: ${(props) =>
|
||||
props.primary
|
||||
@ -130,13 +152,8 @@ const ButtonWrapper = ({
|
||||
const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
disabled: props.isDisabled || props.isLoading ? "disabled" : "",
|
||||
tabIndex: props.tabIndex,
|
||||
size:
|
||||
props.size === "normal"
|
||||
? isDesktop()
|
||||
? "normalDesktop"
|
||||
: "normalTouchscreen"
|
||||
: props.size,
|
||||
}))`
|
||||
position: relative;
|
||||
height: ${(props) => heightStyle(props)};
|
||||
font-size: ${(props) => fontSizeStyle(props)};
|
||||
|
||||
@ -206,7 +223,7 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
`)}
|
||||
|
||||
${(props) => props.isDisabled && disableCss}
|
||||
|
||||
${(props) => props.isLoading && loadingCss}
|
||||
|
||||
&:focus {
|
||||
outline: ${(props) => props.theme.button.outline};
|
||||
@ -221,42 +238,38 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loader {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
stroke: ${(props) =>
|
||||
props.primary
|
||||
? props.theme.button.loader.primary
|
||||
: props.theme.button.loader.base};
|
||||
}
|
||||
vertical-align: ${(props) =>
|
||||
props.size === "normalTouchscreen" || props.size === "extraSmall"
|
||||
? props.theme.button.middleVerticalAlign
|
||||
: props.size === "small"
|
||||
? props.theme.button.bottomVerticalAlign
|
||||
: props.theme.button.topVerticalAlign};
|
||||
|
||||
position: absolute;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: ${(props) =>
|
||||
props.primary
|
||||
? props.theme.button.backgroundColor.primaryLoading
|
||||
: props.theme.button.backgroundColor.baseLoading};
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
ButtonWrapper.propTypes = {
|
||||
label: PropTypes.string,
|
||||
primary: PropTypes.bool,
|
||||
size: PropTypes.oneOf([
|
||||
"extraSmall",
|
||||
"small",
|
||||
"normal",
|
||||
"medium",
|
||||
"normalDesktop",
|
||||
"normalTouchscreen",
|
||||
]),
|
||||
size: PropTypes.oneOf(["extraSmall", "small", "normal", "medium"]),
|
||||
scale: PropTypes.bool,
|
||||
icon: PropTypes.node,
|
||||
|
||||
|
@ -4,10 +4,22 @@ import PropTypes from "prop-types";
|
||||
import { Oval } from "./types/oval";
|
||||
import { DualRing } from "./types/dual-ring";
|
||||
import { Rombs } from "./types/rombs";
|
||||
import { Track } from "./types/track";
|
||||
|
||||
import Text from "../text";
|
||||
|
||||
const Loader = (props) => {
|
||||
const { type, color, size, label, className, style, id, theme } = props;
|
||||
const {
|
||||
type,
|
||||
color,
|
||||
size,
|
||||
label,
|
||||
className,
|
||||
style,
|
||||
id,
|
||||
primary,
|
||||
theme,
|
||||
} = props;
|
||||
|
||||
const svgRenderer = (type) => {
|
||||
switch (type) {
|
||||
@ -17,6 +29,8 @@ const Loader = (props) => {
|
||||
return <DualRing {...props} />;
|
||||
case "rombs":
|
||||
return <Rombs {...props} />;
|
||||
case "track":
|
||||
return <Track {...props} />;
|
||||
default:
|
||||
return (
|
||||
<span style={{ ...style }}>
|
||||
@ -39,7 +53,7 @@ Loader.propTypes = {
|
||||
/** Font color */
|
||||
color: PropTypes.string,
|
||||
/** Type loader */
|
||||
type: PropTypes.oneOf(["base", "oval", "dual-ring", "rombs"]),
|
||||
type: PropTypes.oneOf(["base", "oval", "dual-ring", "rombs", "track"]),
|
||||
/** Font size */
|
||||
size: PropTypes.string,
|
||||
/** Text label */
|
||||
|
@ -38,7 +38,7 @@ const ExamplesTemplate = (args) => {
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr 1fr 1fr",
|
||||
gridTemplateColumns: "1fr 1fr 1fr 1fr 1fr",
|
||||
height: "100px",
|
||||
}}
|
||||
>
|
||||
@ -61,6 +61,7 @@ const ExamplesTemplate = (args) => {
|
||||
label={"Loading content, please wait."}
|
||||
/>
|
||||
<Loader type={"rombs"} size={"40px"} />
|
||||
<Loader type="track" style={{ width: "30px" }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -59,6 +59,18 @@ const StyledDualRing = styled.svg`
|
||||
`;
|
||||
StyledDualRing.defaultProps = { theme: Base };
|
||||
|
||||
const StyledTrack = styled.svg`
|
||||
width: ${(props) => (props.size ? props.size : "20px")};
|
||||
height: ${(props) => (props.size ? props.size : "20px")};
|
||||
color: ${({ color, primary, theme }) =>
|
||||
color
|
||||
? color
|
||||
: primary
|
||||
? theme.button.loader.primary
|
||||
: theme.button.loader.base};
|
||||
`;
|
||||
StyledTrack.defaultProps = { theme: Base };
|
||||
|
||||
export {
|
||||
LoadingLabel,
|
||||
LoadingWrapper,
|
||||
@ -66,4 +78,5 @@ export {
|
||||
Dot,
|
||||
StyledOval,
|
||||
StyledDualRing,
|
||||
StyledTrack,
|
||||
};
|
||||
|
128
packages/components/loader/types/track.js
Normal file
128
packages/components/loader/types/track.js
Normal file
@ -0,0 +1,128 @@
|
||||
import React from "react";
|
||||
import useId from "../../utils/useId";
|
||||
import { StyledTrack } from "../styled-loader";
|
||||
|
||||
const Track = ({ size, color, label, primary }) => {
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<StyledTrack
|
||||
viewBox="-10 -10 220 220"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
size={size}
|
||||
color={color}
|
||||
primary={primary}
|
||||
aria-label={label}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-1`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="1"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity="0" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity=".2" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-2`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="1"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity=".2" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity=".4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-3`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="1"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="1"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity=".4" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity=".6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-4`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="1"
|
||||
y1="1"
|
||||
x2="0"
|
||||
y2="0"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity=".6" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity=".8" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-5`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="0"
|
||||
y1="1"
|
||||
x2="0"
|
||||
y2="0"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity=".8" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={`spinner-color-${id}-6`}
|
||||
gradientUnits="objectBoundingBox"
|
||||
x1="0"
|
||||
y1="1"
|
||||
x2="1"
|
||||
y2="0"
|
||||
>
|
||||
<stop offset="0%" stopColor="currentColor" stopOpacity="1" />
|
||||
<stop offset="100%" stopColor="currentColor" stopOpacity="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
fill="none"
|
||||
strokeWidth="40"
|
||||
transform="translate(100,100) scale(0.75)"
|
||||
>
|
||||
<path
|
||||
d="M 0,-100 A 100,100 0 0,1 86.6,-50"
|
||||
stroke={`url(#spinner-color-${id}-1)`}
|
||||
/>
|
||||
<path
|
||||
d="M 86.6,-50 A 100,100 0 0,1 86.6,50"
|
||||
stroke={`url(#spinner-color-${id}-2)`}
|
||||
/>
|
||||
<path
|
||||
d="M 86.6,50 A 100,100 0 0,1 0,100"
|
||||
stroke={`url(#spinner-color-${id}-3)`}
|
||||
/>
|
||||
<path
|
||||
d="M 0,100 A 100,100 0 0,1 -86.6,50"
|
||||
stroke={`url(#spinner-color-${id}-4)`}
|
||||
/>
|
||||
<path
|
||||
d="M -86.6,50 A 100,100 0 0,1 -86.6,-50"
|
||||
stroke={`url(#spinner-color-${id}-5)`}
|
||||
/>
|
||||
<path
|
||||
d="M -86.6,-50 A 100,100 0 0,1 0,-100"
|
||||
stroke={`url(#spinner-color-${id}-6)`}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<animateTransform
|
||||
from="0 0 0"
|
||||
to="360 0 0"
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
repeatCount="indefinite"
|
||||
dur="1300ms"
|
||||
/>
|
||||
</StyledTrack>
|
||||
);
|
||||
};
|
||||
|
||||
export { Track };
|
@ -18,6 +18,11 @@ const {
|
||||
blueDisabled,
|
||||
blueCharcoal,
|
||||
|
||||
blueDenim,
|
||||
blueDenimTransparent,
|
||||
blueMaya,
|
||||
blueSky,
|
||||
|
||||
orangeMain,
|
||||
orangeHover,
|
||||
orangePressed,
|
||||
@ -99,32 +104,28 @@ const Base = {
|
||||
height: {
|
||||
extraSmall: "24px",
|
||||
small: "32px",
|
||||
normalDesktop: "36px",
|
||||
normalTouchscreen: "40px",
|
||||
normal: "40px",
|
||||
medium: "44px",
|
||||
},
|
||||
|
||||
lineHeight: {
|
||||
extraSmall: "15px",
|
||||
small: "20px",
|
||||
normalDesktop: "16px",
|
||||
normalTouchscreen: "16px",
|
||||
normal: "16px",
|
||||
medium: "22px",
|
||||
},
|
||||
|
||||
fontSize: {
|
||||
extraSmall: "12px",
|
||||
small: "13px",
|
||||
normalDesktop: "14px",
|
||||
normalTouchscreen: "14px",
|
||||
normal: "14px",
|
||||
medium: "16px",
|
||||
},
|
||||
|
||||
padding: {
|
||||
extraSmall: "0 12px",
|
||||
extraSmall: "0 11.5px",
|
||||
small: "0 28px",
|
||||
normalDesktop: "0 28px",
|
||||
normalTouchscreen: "0 28px",
|
||||
normal: "0 28px",
|
||||
medium: "0 32px",
|
||||
},
|
||||
|
||||
@ -132,7 +133,7 @@ const Base = {
|
||||
base: black,
|
||||
baseHover: black,
|
||||
baseActive: black,
|
||||
baseDisabled: grayLightMid,
|
||||
baseDisabled: grayMid,
|
||||
primary: white,
|
||||
primaryHover: white,
|
||||
primaryActive: white,
|
||||
@ -144,25 +145,30 @@ const Base = {
|
||||
baseHover: white,
|
||||
baseActive: grayLightMid,
|
||||
baseDisabled: grayLight,
|
||||
primary: blueMain,
|
||||
primaryHover: blueHover,
|
||||
primaryActive: blueActive,
|
||||
primaryDisabled: blueDisabled,
|
||||
baseLoading: grayLight,
|
||||
primary: blueDenim,
|
||||
primaryHover: blueDenimTransparent,
|
||||
primaryActive: blueMaya,
|
||||
primaryDisabled: blueSky,
|
||||
primaryLoading: blueSky,
|
||||
},
|
||||
|
||||
border: {
|
||||
base: `1px solid ${globalColors.grayMid}`,
|
||||
baseHover: `1px solid ${globalColors.blueMain}`,
|
||||
baseActive: `1px solid ${globalColors.blueMain}`,
|
||||
baseHover: `1px solid ${blueDenim}`,
|
||||
baseActive: `1px solid ${globalColors.grayMid}`,
|
||||
baseDisabled: `1px solid ${globalColors.grayLightMid}`,
|
||||
primary: `1px solid ${globalColors.blueMain}`,
|
||||
primaryHover: `1px solid ${globalColors.blueHover}`,
|
||||
primaryActive: `1px solid ${globalColors.blueActive}`,
|
||||
primaryDisabled: `1px solid ${globalColors.blueDisabled}`,
|
||||
baseLoading: `1px solid ${globalColors.grayLightMid}`,
|
||||
|
||||
primary: `1px solid ${blueDenim}`,
|
||||
primaryHover: `1px solid ${blueDenimTransparent}`,
|
||||
primaryActive: `1px solid ${blueMaya}`,
|
||||
primaryDisabled: `1px solid ${blueSky}`,
|
||||
primaryLoading: `1px solid ${blueSky}`,
|
||||
},
|
||||
|
||||
loader: {
|
||||
base: black,
|
||||
base: blueDenim,
|
||||
primary: white,
|
||||
},
|
||||
},
|
||||
|
@ -98,71 +98,74 @@ const Dark = {
|
||||
height: {
|
||||
extraSmall: "24px",
|
||||
small: "32px",
|
||||
normalDesktop: "36px",
|
||||
normalTouchscreen: "40px",
|
||||
normal: "40px",
|
||||
medium: "44px",
|
||||
},
|
||||
|
||||
lineHeight: {
|
||||
extraSmall: "15px",
|
||||
small: "20px",
|
||||
normalDesktop: "16px",
|
||||
normalTouchscreen: "16px",
|
||||
normal: "16px",
|
||||
medium: "22px",
|
||||
},
|
||||
|
||||
fontSize: {
|
||||
extraSmall: "12px",
|
||||
small: "13px",
|
||||
normalDesktop: "14px",
|
||||
normalTouchscreen: "14px",
|
||||
normal: "14px",
|
||||
medium: "16px",
|
||||
},
|
||||
|
||||
padding: {
|
||||
extraSmall: "0 12px",
|
||||
small: "0 28px",
|
||||
normalDesktop: "0 28px",
|
||||
normalTouchscreen: "0 28px",
|
||||
normal: "0 28px",
|
||||
medium: "0 32px",
|
||||
},
|
||||
|
||||
color: {
|
||||
base: "#CCCCCC",
|
||||
baseHover: "#FAFAFA",
|
||||
baseActive: "#858585",
|
||||
baseDisabled: "#545454",
|
||||
base: "#FFFFFF",
|
||||
baseHover: "#FFFFFF",
|
||||
baseActive: "#FFFFFF",
|
||||
baseDisabled: "#474747",
|
||||
|
||||
primary: "#FFFFFF",
|
||||
primaryHover: "#FFFFFF",
|
||||
primaryActive: "#FFFFFF",
|
||||
primaryDisabled: black,
|
||||
primaryDisabled: "#FFFFFF",
|
||||
},
|
||||
|
||||
backgroundColor: {
|
||||
base: "transparent",
|
||||
baseHover: black,
|
||||
baseActive: "#292929",
|
||||
baseDisabled: "#474747",
|
||||
primary: "#CCCCCC",
|
||||
primaryHover: "#FAFAFA",
|
||||
primaryActive: "#858585",
|
||||
primaryDisabled: "#545454",
|
||||
base: "#333333",
|
||||
baseHover: "#333333",
|
||||
baseActive: "#282828",
|
||||
baseDisabled: "#282828",
|
||||
baseLoading: "#282828",
|
||||
|
||||
primary: "#5299E0",
|
||||
primaryHover: "#4D8AC7",
|
||||
primaryActive: "#427CB7",
|
||||
primaryDisabled: "#45709B",
|
||||
primaryLoading: "#45709B",
|
||||
},
|
||||
|
||||
border: {
|
||||
base: `1px solid #CCCCCC`,
|
||||
baseHover: `1px solid #FAFAFA`,
|
||||
baseActive: `1px solid #FAFAFA`,
|
||||
baseDisabled: `1px solid #545454`,
|
||||
primary: `1px solid #CCCCCC`,
|
||||
primaryHover: `1px solid #FAFAFA`,
|
||||
primaryActive: `1px solid #FAFAFA`,
|
||||
primaryDisabled: `1px solid #545454`,
|
||||
base: `1px solid #474747`,
|
||||
baseHover: `1px solid #858585`,
|
||||
baseActive: `1px solid #CCCCCC`,
|
||||
baseDisabled: `1px solid #474747`,
|
||||
baseLoading: `1px solid #474747`,
|
||||
|
||||
primary: `1px solid #5299E0`,
|
||||
primaryHover: `1px solid #4D8AC7`,
|
||||
primaryActive: `1px solid #427CB7`,
|
||||
primaryDisabled: `1px solid #45709B`,
|
||||
primaryLoading: `1px solid #45709B`,
|
||||
},
|
||||
|
||||
loader: {
|
||||
base: grayMaxLight,
|
||||
primary: black,
|
||||
base: white,
|
||||
primary: white,
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -25,6 +25,11 @@ const globalColors = {
|
||||
blueLightMid: "#265A8F",
|
||||
strongBlue: "#316AC5",
|
||||
|
||||
blueDenim : "#5299E0",
|
||||
blueDenimTransparent: "rgba(82, 153, 224, 0.85)",
|
||||
blueMaya: "#4A8ACA",
|
||||
blueSky: "#96C1EC",
|
||||
|
||||
lightGrayishBlue: "#DEE2E6",
|
||||
lightGrayishStrongBlue: "#DFE2E3",
|
||||
cyanBlueDarkShade: "#555F65",
|
||||
|
28
packages/components/utils/useId.js
Normal file
28
packages/components/utils/useId.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
|
||||
let ID = 0;
|
||||
const genId = () => ID++;
|
||||
let serverHandoffComplete = false;
|
||||
|
||||
const usePassiveLayoutEffect =
|
||||
React[
|
||||
typeof document !== "undefined" && document.createElement !== void 0
|
||||
? "useLayoutEffect"
|
||||
: "useEffect"
|
||||
];
|
||||
|
||||
const useId = (fallbackId, prefix = "prefix") => {
|
||||
const [id, setId] = React.useState(serverHandoffComplete ? genId : void 0);
|
||||
|
||||
usePassiveLayoutEffect(() => {
|
||||
if (id === void 0) {
|
||||
setId(ID++);
|
||||
}
|
||||
|
||||
serverHandoffComplete = true;
|
||||
}, []);
|
||||
|
||||
return fallbackId ? fallbackId : id === void 0 ? id : prefix + id;
|
||||
};
|
||||
|
||||
export default useId;
|
Loading…
Reference in New Issue
Block a user