From 6271d0a5c2ca7fafe226be3a995aef7867431c09 Mon Sep 17 00:00:00 2001 From: jacovinus Date: Mon, 4 Apr 2022 19:14:20 +0200 Subject: [PATCH] fix: date picker mobile size --- package-lock.json | 65 ++++ package.json | 1 + .../components/AbsoluteSelector.js | 91 +++-- .../daterangepicker/components/Heading.js | 163 +++++---- .../daterangepicker/components/Nav.js | 324 +++++++++++++----- .../daterangepicker/components/Ranges.js | 72 ++-- src/components/StatusBar/index.js | 17 +- src/components/StatusBar/styled/index.js | 17 +- src/scss/modules/status-bar.scss | 107 +++--- 9 files changed, 582 insertions(+), 275 deletions(-) diff --git a/package-lock.json b/package-lock.json index ecd591eb..15dff982 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "react-dom": "^17.0.2", "react-flot": "^1.3.0", "react-redux": "^7.2.6", + "react-responsive": "^9.0.0-beta.6", "react-router-dom": "^6.2.1", "redux-thunk": "^2.4.1", "slate": "^0.73.1", @@ -7106,6 +7107,11 @@ "node": ">=10" } }, + "node_modules/css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=" + }, "node_modules/css-minimizer-webpack-plugin": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", @@ -13658,6 +13664,14 @@ "tmpl": "1.0.5" } }, + "node_modules/matchmediaquery": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz", + "integrity": "sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==", + "dependencies": { + "css-mediaquery": "^0.1.2" + } + }, "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -16386,6 +16400,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-responsive": { + "version": "9.0.0-beta.6", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-9.0.0-beta.6.tgz", + "integrity": "sha512-Flk6UrnpBBByreva6ja/TsbXiXq4BXOlDEKL6Ur+nshUs3CcN5W0BpGe6ClFWrKcORkMZAAYy7A4N4xlMmpgVw==", + "dependencies": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.2.1" + }, + "engines": { + "node": ">=0.10" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/react-router": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", @@ -17364,6 +17395,11 @@ "node": ">=8" } }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -25157,6 +25193,11 @@ } } }, + "css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=" + }, "css-minimizer-webpack-plugin": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", @@ -30065,6 +30106,14 @@ "tmpl": "1.0.5" } }, + "matchmediaquery": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz", + "integrity": "sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==", + "requires": { + "css-mediaquery": "^0.1.2" + } + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -31957,6 +32006,17 @@ "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "dev": true }, + "react-responsive": { + "version": "9.0.0-beta.6", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-9.0.0-beta.6.tgz", + "integrity": "sha512-Flk6UrnpBBByreva6ja/TsbXiXq4BXOlDEKL6Ur+nshUs3CcN5W0BpGe6ClFWrKcORkMZAAYy7A4N4xlMmpgVw==", + "requires": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.2.1" + } + }, "react-router": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", @@ -32704,6 +32764,11 @@ "kind-of": "^6.0.2" } }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", diff --git a/package.json b/package.json index 3c7a5bec..264282d2 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "react-dom": "^17.0.2", "react-flot": "^1.3.0", "react-redux": "^7.2.6", + "react-responsive": "^9.0.0-beta.6", "react-router-dom": "^6.2.1", "redux-thunk": "^2.4.1", "slate": "^0.73.1", diff --git a/src/components/StatusBar/components/daterangepicker/components/AbsoluteSelector.js b/src/components/StatusBar/components/daterangepicker/components/AbsoluteSelector.js index 92f31530..20fa9f30 100644 --- a/src/components/StatusBar/components/daterangepicker/components/AbsoluteSelector.js +++ b/src/components/StatusBar/components/daterangepicker/components/AbsoluteSelector.js @@ -1,11 +1,11 @@ import styled from "@emotion/styled"; import DateRangeIcon from "@mui/icons-material/DateRange"; const SelectorsContainer = styled.div` - display: flex; + display: ${(props) => (props.isDisplay ? "flex" : "none")}; flex-direction: column; margin: 4px; - .time-selector { - display: flex; + .time-selectors { + display: ${(props) => (props.isDisplay ? "flex" : "none")}; flex-direction: column; padding: 5px; @@ -18,7 +18,7 @@ const SelectorsContainer = styled.div` } .input-group { display: flex; - .date-time-range { + .date-time-ranged { font-size: 1em; width: 170px; line-height: 1.5; @@ -26,20 +26,19 @@ const SelectorsContainer = styled.div` color: #ddd; } button { - cursor:pointer; - display:flex; + cursor: pointer; + display: flex; align-items: center; justify-content: center; - border:none; - padding:0px 8px; - margin:3px; - border-radius: 3px; + border: none; + padding: 0px 8px; + margin: 3px; + border-radius: 3px; color: #eee; - background: #0c8181; - &:hover { - background: #159d9d; - } - + background: #0c8181; + &:hover { + background: #159d9d; + } } } } @@ -56,11 +55,11 @@ const AbsoluteSubmitButton = styled.button` border-radius: 3px; transition: 0.2s all; margin: 10px; - margin-top: 40px; + margin-top: {props => (props.isHorizontal && props.isMobile ? '20px':'40px')} cursor: pointer; &:hover { background: #159d9d; - } + } `; export default function AbsoluteSelector({ @@ -69,49 +68,75 @@ export default function AbsoluteSelector({ handleStart, handleStop, onTimeRangeSet, - calendarOpen, setCalendarOpen, + isFullCalendar, + setStopCalendar, + setStartCalendar, + calendarOpen, + startCalendarOpen, + stopCalendarOpen, + isHorizontal, + styles, + isMobile, }) { + function handleStartOpen() { + if (isFullCalendar) { + setCalendarOpen((open) => (open ? false : true)); + } else { + setCalendarOpen((open) => + open && startCalendarOpen ? false : true + ); + setStopCalendar(() => false); + setStartCalendar((open) => (open ? false : true)); + } + } + + function handleStopOpen() { + if (isFullCalendar) { + setCalendarOpen((open) => (open ? false : true)); + } else { + setCalendarOpen((open) => + open && stopCalendarOpen ? false : true + ); + setStartCalendar(() => false); + setStopCalendar((open) => (open ? false : true)); + } + } + return ( - -
+ +
{"From"}
handleStart(e, false)} onBlur={(e) => handleStart(e, true)} /> -
-
+
{"To"}
handleStop(e, false)} onBlur={(e) => handleStop(e, true)} /> -
{ onTimeRangeSet(e); }} diff --git a/src/components/StatusBar/components/daterangepicker/components/Heading.js b/src/components/StatusBar/components/daterangepicker/components/Heading.js index fce1f508..99e72c4a 100644 --- a/src/components/StatusBar/components/daterangepicker/components/Heading.js +++ b/src/components/StatusBar/components/daterangepicker/components/Heading.js @@ -1,85 +1,110 @@ -import { - Grid, - IconButton, - Select, - MenuItem, - -} from "@mui/material"; +import { Grid, IconButton } from "@mui/material"; -import { withStyles,ThemeProvider, } from '@mui/styles'; +import { withStyles, ThemeProvider } from "@mui/styles"; import ChevronLeft from "@mui/icons-material/ChevronLeft"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { setMonth, getMonth, setYear, getYear } from "date-fns"; import { MONTHS } from "../consts"; import { HeadingStyles, theme } from "./styles"; import { generateYears } from "../utils"; +import styled from "@emotion/styled"; +const DateSelect = styled.select` + cursor: pointer; -const Heading = ({ - date, - classes, - setDate, - nextDisabled, - prevDisabled, - onClickNext, - onClickPrevious -}) => { - const handleMonthChange = (event) => { - setDate(setMonth(date, parseInt(event.target.value))); - }; + position: relative; + font-size: 1em; + color: #ddd; + background: #121212; + border: none; + border-radius: 3px; + padding: 4px 8px; + line-height: 1.5; + + &::-webkit-scrollbar { + width: 5px; + background: black; + } - const handleYearChange = (event) => { - setDate(setYear(date, parseInt(event.target.value))); - }; + &::-webkit-scrollbar-thumb { + border-radius: 10px; + background: #444; + } +`; - return ( - - - - { + const handleMonthChange = (event) => { + setDate(setMonth(date, parseInt(event.target.value))); + }; - disabled={prevDisabled} - onClick={onClickPrevious}> - - - - - - + return ( + + + + + + + + + + {MONTHS.map((month, idx) => ( + + ))} + + - - - - - - - - - - - ); + + + {generateYears(date, 30).map((year) => ( + + ))} + + + + + + + + + + ); }; -export default withStyles(HeadingStyles)(Heading); \ No newline at end of file +export default withStyles(HeadingStyles)(Heading); diff --git a/src/components/StatusBar/components/daterangepicker/components/Nav.js b/src/components/StatusBar/components/daterangepicker/components/Nav.js index 5e8a5865..025a1027 100644 --- a/src/components/StatusBar/components/daterangepicker/components/Nav.js +++ b/src/components/StatusBar/components/daterangepicker/components/Nav.js @@ -9,6 +9,7 @@ import { createTheme } from "@mui/material/styles"; import { ThemeProvider } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import { withStyles } from "@mui/styles"; +import { css, jsx } from "@emotion/css"; import { format, differenceInCalendarMonths, @@ -28,22 +29,22 @@ import { setStopTime, setTimeRangeLabel, } from "../../../../../actions"; +import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; import { findRangeByLabel } from "../utils"; import AbsoluteSelector from "./AbsoluteSelector"; - +import { useMediaQuery } from "react-responsive"; const styles = (theme) => createStyles({ header: { padding: "10px", - justifyContent:"space-between" + justifyContent: "space-between", }, headerItem: { - textAlign: "center", }, - dateComplete:{ - fontSize:".85em", - }, + dateComplete: { + fontSize: ".85em", + }, divider: { borderLeft: `1px solid action`, marginBottom: 20, @@ -53,7 +54,8 @@ const styles = (theme) => zIndex: 1000, top: 95, right: 10, - display:'flex' + display: "flex", + overflowY: "auto", }, applyButton: { color: "white", @@ -87,14 +89,22 @@ const PickerNav = (props) => { handlers, } = props; - const [calendarOpen,setCalendarOpen] = useState(false) + const [calendarOpen, setCalendarOpen] = useState(false); const canNavigateCloser = differenceInCalendarMonths(secondMonth, firstMonth) >= 2; const commonProps = { dateRange, minDate, maxDate, helpers, handlers }; const dispatch = useDispatch(); const [editedStartDate, setEditedStartDate] = useState(dateRange.dateStart); const [editedEndDate, setEditedEndDate] = useState(dateRange.dateEnd); + const [relativeOpen, setRelativeOpen] = useState(true); const [rangeLabel] = useState(dateRange.label); + const isBigScreen = useMediaQuery({ query: "(min-width: 914px)" }); + const isTabletOrMobile = useMediaQuery({ query: "(max-width: 914px)" }); + const isPortrait = useMediaQuery({ query: "(orientation: portrait)" }); + const isRetina = useMediaQuery({ query: "(min-resolution: 2dppx)" }); + const [startCalendar, setStartCalendar] = useState(false); + const [stopCalendar, setStopCalendar] = useState(false); + useEffect(() => { if (rangeLabel) { const newRange = findRangeByLabel(rangeLabel); @@ -167,16 +177,35 @@ const PickerNav = (props) => { ? editedEndDate : ""; }; + const openRelative = () => { + setRelativeOpen((open) => (open ? false : true)); + }; return ( - { calendarOpen && ( + {calendarOpen && isBigScreen && ( + + +
+ + + )} + {calendarOpen && !isBigScreen && !isPortrait && !relativeOpen && ( + + {startCalendar && ( { navState={[true, canNavigateCloser]} marker={MARKERS.FIRST_MONTH} /> -
- - )} + )} + + {stopCalendar && ( + + )} + + )} + - - { - props.onClose(e); - }} - aria-label={"close"} + +
- - + { + props.onClose(e); + }} + aria-label={"close"} + > + + +
- -
-
+ {isTabletOrMobile && ( + <> +
- -
- {dateRange?.dateStart && - isValid(dateRange?.dateStart) - ? format( - dateRange?.dateStart, - "MMMM dd, yyyy" - ) - : "Start Date"} -
-
- - - - -
- {dateRange?.dateEnd && - isValid(dateRange?.dateEnd) - ? format( - dateRange?.dateEnd, - "MMMM dd, yyyy" - ) - : "End Date"} -
+ display: relativeOpen + ? "flex" + : "none", + flex: 1, + flexDirection: "column", + }} + > + +
+ + {isTabletOrMobile && ( + + )} + + )} + {!isTabletOrMobile && ( + + )} + + {calendarOpen && + isTabletOrMobile && + !relativeOpen && ( + + {startCalendar && ( + + )} + + {stopCalendar && ( + + )} + + )}
- - + {isBigScreen && ( + + +
+ {dateRange?.dateStart && + isValid(dateRange?.dateStart) + ? format( + dateRange?.dateStart, + "MMMM dd, yyyy" + ) + : "Start Date"} +
+
+ + + + +
+ {dateRange?.dateEnd && + isValid(dateRange?.dateEnd) + ? format( + dateRange?.dateEnd, + "MMMM dd, yyyy" + ) + : "End Date"} +
+
+
+ )}
- - - + {isBigScreen && ( + + + + )} diff --git a/src/components/StatusBar/components/daterangepicker/components/Ranges.js b/src/components/StatusBar/components/daterangepicker/components/Ranges.js index 5eca254e..81a9a3fe 100644 --- a/src/components/StatusBar/components/daterangepicker/components/Ranges.js +++ b/src/components/StatusBar/components/daterangepicker/components/Ranges.js @@ -1,29 +1,51 @@ -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemText from '@mui/material/ListItemText' +import styled from "@emotion/styled"; import { isSameRange } from "../utils"; -const Ranges = props => { - return ( - - {props.ranges.map((range, idx) => ( - {props.setRange(range); props.onClose()}}> - - {range.label} - - - ))} - - ); +const StyledList = styled.div` + display: flex; + flex-direction: column; + padding: 10px; + button { + background: none; + text-align: left; + border: none; + padding: 10px; + line-height: 1.5; + border-radius: 3px; + cursor: pointer; + &:hover { + background: #11111155; + } + } +`; + +const Ranges = (props) => { + return ( + + {props.ranges.map((range, idx) => ( + + ))} + + ); }; -export default Ranges; \ No newline at end of file +export default Ranges; diff --git a/src/components/StatusBar/index.js b/src/components/StatusBar/index.js index ce6fcd9e..d78a87e8 100644 --- a/src/components/StatusBar/index.js +++ b/src/components/StatusBar/index.js @@ -7,12 +7,18 @@ import { setSettingsMenuOpen } from "./actions/setMenuSettingsOpen"; import DisplaySettingsIcon from "@mui/icons-material/DisplaySettings"; import { MenuButton, StatusBarCont, StatusCont } from "./styled"; import TimePickerButton from "./components/timepickerbutton/TimePickerButton"; - +import { DateRangePicker } from "./components/daterangepicker"; +import { useState } from "react"; export default function StatusBar() { const dispatch = useDispatch(); const menuOpen = useSelector((store) => store.settingsMenuOpen); - + const [open, setOpen] = useState(); + + const isOpen = (e) => { + e?.preventDefault(); + setOpen(!open); + }; function openSettings() { const shouldOpen = menuOpen ? false : true; @@ -29,9 +35,7 @@ export default function StatusBar() { height={"28px"} className={"logo"} /> - - - + {/* */} @@ -39,6 +43,9 @@ export default function StatusBar() { + + + ); diff --git a/src/components/StatusBar/styled/index.js b/src/components/StatusBar/styled/index.js index ee01be72..41819f29 100644 --- a/src/components/StatusBar/styled/index.js +++ b/src/components/StatusBar/styled/index.js @@ -24,6 +24,8 @@ export const StatusBarCont = styled.div` `; export const StatusCont = styled.div` + display: flex; + align-items: center; input { color: orange; background: #121212; @@ -40,19 +42,17 @@ export const StatusCont = styled.div` } &.date-time-range { width: 120px; + color: orange; + background: #121212; } } - - @media screen and (max-width: 565px) { - display: none; - } `; export const ApiSelectorStyled = styled.div` display: flex; align-items: center; - @media screen and (max-width:850px) { - display: none; - } + @media screen and (max-width: 850px) { + display: none; + } .selector { margin-left: 10px; .label { @@ -74,7 +74,6 @@ export const ApiSelectorStyled = styled.div` } `; - export const UrlCopyButton = styled.button` display: flex; align-items: center; @@ -100,4 +99,4 @@ export const UrlCopyButton = styled.button` &:hover { background: #9e9e9e3b; } -`; \ No newline at end of file +`; diff --git a/src/scss/modules/status-bar.scss b/src/scss/modules/status-bar.scss index 6a6f656b..8db06fdc 100644 --- a/src/scss/modules/status-bar.scss +++ b/src/scss/modules/status-bar.scss @@ -29,6 +29,10 @@ display: flex; align-items: center; } + + @media screen and (max-width: 565px) { + display: none; + } } .date-selector { input { @@ -43,10 +47,12 @@ width: 50px; } &.url { - width:175px; + width: 175px; } &.date-time-range { width: 120px; + color: orange; + background: #121212; } } } @@ -57,9 +63,9 @@ .api-url-selector { margin-left: 20px; - display:flex; + display: flex; align-items: center; - transition:.2s all; + transition: 0.2s all; input { color: orange; background: #121212; @@ -69,15 +75,15 @@ font-size: 13px; border-radius: 3px; &.url { - width:175px; + width: 175px; } } button { - display:flex; + display: flex; align-items: center; - height:20px; + height: 20px; font-size: 18px; - border:none; + border: none; margin: 3px; padding: 5px 8px; border-radius: 3px; @@ -89,70 +95,65 @@ white-space: nowrap; text-overflow: ellipsis; transition: 0.2s all; - &:hover { - background:#9e9e9e3b; - } - + &:hover { + background: #9e9e9e3b; + } } - } .logo-section { - display:flex; + display: flex; align-items: center; - flex:1; + flex: 1; } .url-copy { - - display:flex; - align-items: center; - height:20px; - font-size: 18px; - border:none; - margin: 3px; - padding: 5px 8px; - border-radius: 3px; - background: #7b7b7b3b; - // color: #d1d1d1; - color:orange; - font-size: 0.9em; - cursor: pointer; - align-items: center; - white-space: nowrap; - text-overflow: ellipsis; - transition: 0.2s all; - span { - margin-left:4px; - text-transform:uppercase; - font-size: .85em; - color: #d1d1d1; - } - &:hover { - background:#9e9e9e3b; - } - &:disabled { - color:#7b7b7b; - cursor:not-allowed; - } - + display: flex; + align-items: center; + height: 20px; + font-size: 18px; + border: none; + margin: 3px; + padding: 5px 8px; + border-radius: 3px; + background: #7b7b7b3b; + // color: #d1d1d1; + color: orange; + font-size: 0.9em; + cursor: pointer; + align-items: center; + white-space: nowrap; + text-overflow: ellipsis; + transition: 0.2s all; + span { + margin-left: 4px; + text-transform: uppercase; + font-size: 0.85em; + color: #d1d1d1; + } + &:hover { + background: #9e9e9e3b; + } + &:disabled { + color: #7b7b7b; + cursor: not-allowed; + } } @media screen and (max-width: 950px) { .url-copy { span { display: none; } - } } .copied-warning { -transition:.2s all; - color:orange; - font-size:.8em; - text-transform: uppercase; - margin-right:10px; + transition: 0.2s all; + color: orange; + font-size: 0.8em; + text-transform: uppercase; + margin-right: 10px; } .submit-checkbox { - color:red; + color: red; background-color: green; }