Skip to content

Commit

Permalink
Web: Components: created the main button mobile component
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-sychugov committed Nov 2, 2021
1 parent d6544c0 commit da5c9bb
Show file tree
Hide file tree
Showing 3 changed files with 553 additions and 0 deletions.
225 changes: 225 additions & 0 deletions packages/asc-web-components/main-button-mobile/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import React, { useState, useRef, useEffect } from "react";
import PropTypes from "prop-types";
import {
StyledFloatingButton,
StyledDropDown,
StyledDropDownItem,
StyledContainerAction,
StyledProgressBarContainer,
StyledMobileProgressBar,
StyledProgressContainer,
StyledBar,
StyledButtonWrapper,
StyledButtonOptions,
} from "./styled-main-button";
import IconButton from "../icon-button";
import Button from "../button";
import Text from "../text";
import Scrollbar from "@appserver/components/scrollbar";

const ProgressBarMobile = ({
label,
status,
percent,
open,
onCancel,
icon,
onClick,
}) => {
const uploadPercent = percent > 100 ? 100 : percent;

return (
<StyledProgressBarContainer isUploading={open}>
<Text onClick={onClick} className="progress-header" color="#657077">
{label}
</Text>
<Text className="progress_count" color="#657077">
{status}
</Text>
<IconButton onClick={onCancel} iconName={icon} size={14} />
<StyledMobileProgressBar>
<StyledBar uploadPercent={uploadPercent} />
</StyledMobileProgressBar>
</StyledProgressBarContainer>
);
};

ProgressBarMobile.propTypes = {
label: PropTypes.string,
status: PropTypes.string,
percent: PropTypes.number,
open: PropTypes.bool,
onCancel: PropTypes.func,
icon: PropTypes.string,
/** The function that will be called after the progress header click */
onClick: PropTypes.func,
};

const MainButtonMobile = (props) => {
const {
className,
style,
opened,
onUploadClick,
actionOptions,
progressOptions,
buttonOptions,
percent,
title,
withButton,
manualWidth,
isOpenButton,
onClose,
} = props;

const [isOpen, setIsOpen] = useState(opened);

useEffect(() => {
if (opened !== isOpen) {
setIsOpen(opened);
}
}, [opened]);

const ref = useRef();

const dropDownRef = useRef();

const toggle = (isOpen) => {
return setIsOpen(isOpen);
};

const onMainButtonClick = (e) => {
if (isOpen && ref.current.contains(e.target)) return;
toggle(!isOpen);
};

const outsideClick = (e) => {
if (isOpen && ref.current.contains(e.target)) return;
toggle(false);
};

const isUploading = progressOptions
? progressOptions.filter((option) => option.open)
: [];

console.log(dropDownRef);

const renderDropDown = () => {
return (
<StyledDropDown
forwardedRef={dropDownRef}
open={isOpen}
clickOutsideAction={outsideClick}
manualWidth={manualWidth || "400px"}
directionY="top"
directionX="right"
>
<StyledContainerAction>
{actionOptions.map((option) => (
<StyledDropDownItem
key={option.key}
label={option.label}
className={option.className}
onClick={option.onClick}
icon={option.icon ? option.icon : ""}
/>
))}
</StyledContainerAction>
<StyledProgressContainer
isUploading={isUploading.length > 0 ? true : false}
isOpenButton={isOpenButton}
>
{progressOptions &&
progressOptions.map((option) => (
<ProgressBarMobile
key={option.key}
label={option.label}
icon={option.icon}
className={option.className}
percent={option.percent}
status={option.status}
open={option.open}
onCancel={option.onCancel}
/>
))}
</StyledProgressContainer>
<StyledButtonOptions isOpenButton={isOpenButton}>
{isOpenButton && buttonOptions
? buttonOptions.map((option) =>
option.isSeparator ? (
<div key={option.key} className="separator-wrapper">
<div className="is-separator" />
</div>
) : (
<StyledDropDownItem
className={`drop-down-item-button ${
option.isSeparator ? "is-separator" : ""
}`}
key={option.key}
label={option.label}
onClick={option.onClick}
icon={option.icon ? option.icon : ""}
/>
)
)
: ""}
</StyledButtonOptions>
{withButton && (
<StyledButtonWrapper
isUploading={isUploading.length > 0 ? true : false}
isOpenButton={isOpenButton}
>
<Button
label={title}
className="action-mobile-button"
primary
size="large"
onClick={onUploadClick}
/>
</StyledButtonWrapper>
)}
</StyledDropDown>
);
};

const children = renderDropDown();

return (
<div ref={ref} className={className} style={style}>
<StyledFloatingButton
icon={isOpen ? "minus" : "plus"}
onClick={onMainButtonClick}
percent={percent}
/>
{children}
</div>
);
};

MainButtonMobile.propTypes = {
/** Accepts css style */
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
/** Options for drop down items */
actionOptions: PropTypes.array.isRequired,
/** If you need display progress bar components */
progressOptions: PropTypes.array,
/** Menu that opens by clicking on the button */
buttonOptions: PropTypes.array,
/** The function that will be called after the button click */
onUploadClick: PropTypes.func,
/** Show button inside drop down */
withButton: PropTypes.bool,
/** The parameter that is used with buttonOptions is needed to open the menu by clicking on the button */
isOpenButton: PropTypes.bool,
/** The name of the button in the drop down */
title: PropTypes.string,
/** Loading indicator */
percent: PropTypes.number,
/** Required if you need to specify the exact width of the drop down component */
manualWidth: PropTypes.string,
className: PropTypes.string,
/** Tells when the dropdown should be opened */
opened: PropTypes.bool,
};

export default MainButtonMobile;
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import React from "react";
import MainButtonMobile from ".";
import { useEffect, useReducer, useState } from "react";

export default {
title: "Components/MainButtonMobile",
component: MainButtonMobile,
};

const Template = () => {
const maxUploads = 10;
const maxOperations = 7;

const [isOpenUploads, setIsOpenUploads] = useState(false);
const [isOpenOperations, setIsOpenOperations] = useState(false);

const [isOpenButton, setIsOpenButton] = useState(false);
const [opened, setOpened] = useState(null);

const [isUploading, setIsUploading] = useState(false);

const [initialState, setInitialState] = useState({
uploads: 0,
operations: 0,
});
const onUploadClick = () => {
setInitialState({ uploads: 0, operations: 0 });
setIsUploading(true);
setIsOpenUploads(true);
setIsOpenOperations(true);
setIsOpenButton(true);
// setOpened(false);
};

function reducer(state, action) {
switch (action.type) {
case "start":
if (
state.uploads === maxUploads &&
state.operations === maxOperations
) {
setIsUploading(false);
return {
...state,
uploads: state.uploads,
operations: state.operations,
};
}
return {
...state,
uploads:
state.uploads !== maxUploads ? state.uploads + 1 : state.uploads,
operations:
state.operations !== maxOperations
? state.operations + 1
: state.operations,
};
default:
return state;
}
}

const [state, dispatch] = useReducer(reducer, initialState);

useEffect(() => {
setOpened(null);
if (isUploading) {
const id = setInterval(() => {
dispatch({ type: "start" });
}, 1000);

return () => clearInterval(id);
}
}, [dispatch, isUploading]);

const uploadPercent = (state.uploads / maxUploads) * 100;
const operationPercent = (state.operations / maxOperations) * 100;

const actionOptions = [
{
key: "1",
label: "New document",
icon: "static/images/mobile.actions.document.react.svg",
},
{
key: "2",
label: "New presentation",
icon: "static/images/mobile.actions.presentation.react.svg",
},
{
key: "3",
label: "New spreadsheet",
icon: "static/images/mobile.actions.spreadsheet.react.svg",
},
{
key: "4",
label: "New folder",
icon: "static/images/mobile.actions.folder.react.svg",
},
];

const progressOptions = [
{
key: "1",
label: "Uploads",
icon: "/static/images/mobile.actions.remove.react.svg",
percent: uploadPercent,
status: `${state.uploads}/${maxUploads}`,
open: isOpenUploads,
onCancel: () => setIsOpenUploads(false),
},
{
key: "2",
label: "Other operations",
icon: "/static/images/mobile.actions.remove.react.svg",
percent: operationPercent,
status: `${state.operations}/${maxOperations}`,
open: isOpenOperations,
onCancel: () => setIsOpenOperations(false),
},
];

const buttonOptions = [
{
key: "1",
label: "Import point",
icon: "static/images/mobile.star.react.svg",
onClick: () => setIsOpenButton(false),
},
{
key: "2",
label: "Import point",
icon: "static/images/mobile.star.react.svg",
onClick: () => setIsOpenButton(false),
},
{
key: "3",
label: "Import point",
isSeparator: true,
},
{
key: "4",
label: "Import point",
icon: "static/images/mobile.star.react.svg",
onClick: () => setIsOpenButton(false),
},
];

return (
<MainButtonMobile
style={{ position: "absolute", top: "85%", left: "50%" }}
actionOptions={actionOptions}
progressOptions={progressOptions}
buttonOptions={buttonOptions}
onUploadClick={onUploadClick}
withButton={true}
isOpenButton={isOpenButton}
title="Upload"
percent={uploadPercent}
opened={opened}
/>
);
};

export const Default = Template.bind({});

0 comments on commit da5c9bb

Please sign in to comment.