@mui/material#SwipeableDrawer TypeScript Examples

The following examples show how to use @mui/material#SwipeableDrawer. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: NativesPage.tsx    From GTAV-NativeDB with MIT License 5 votes vote down vote up
function NativeInfoDrawer() {
  const { native: nativeHash } = useParams<{ native?: string }>()
  const history = useHistory()
  const theme = useTheme()

  const handleClose = useCallback(() => {
    history.replace(`/natives${history.location.search}`)
  }, [history])

  return (
    <SwipeableDrawer
      anchor="bottom"
      open={!!nativeHash}
      onOpen={() => { }}
      onClose={handleClose}
      PaperProps={{
        sx: {
          height: `calc(100vh - 5px)`,
          borderRadius: `${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0px 0px`
        }
      }}
      components={{
        Root: 'section'
      }}
    >
      <Paper 
        sx={{ 
          display: 'flex', 
          alignItems: 'center', 
          justifyContent: 'center',
          borderRadius: '0px',
          position: 'sticky',
          top: 0,
          p: 1,
          backdropFilter: 'blur(20px)',
          backgroundColor: alpha(theme.palette.background.default, 0.6),
          ...(theme.palette.mode === 'dark' && {
            backgroundImage: `linear-gradient(${alpha(
              '#fff',
              getOverlayAlpha(4),
            )}, ${alpha('#fff', getOverlayAlpha(4))})`,
          }),
          zIndex: 1
        }}
      >
        <Box sx={{ flexGrow: 1 }} />
        <Typography component="h1" variant="h6" align="center">
          Native Details
        </Typography>
        <Box sx={{ flexGrow: 1 }} />
        <IconButton onClick={handleClose}>
          <CloseIcon />
        </IconButton>
      </Paper>

      <NativeInfo />
    </SwipeableDrawer>
  )
}
Example #2
Source File: MobileNav.tsx    From frontend with MIT License 5 votes vote down vote up
export default function MobileNav({ mobileOpen, setMobileOpen }: NavDeckProps) {
  const router = useRouter()
  const { t } = useTranslation()
  const closeNavMenu = () => setMobileOpen(false)

  // Register route change event handlers
  useEffect(() => {
    router.events.on('routeChangeStart', closeNavMenu)

    return () => {
      router.events.off('routeChangeStart', closeNavMenu)
    }
  }, [])

  return (
    <Root className={classes.navMenuDrawer}>
      <Hidden mdUp implementation="css">
        <SwipeableDrawer
          anchor="right"
          open={mobileOpen}
          variant="temporary"
          ModalProps={{ keepMounted: true }}
          onOpen={() => setMobileOpen(true)}
          onClose={closeNavMenu}
          classes={{ paper: classes.navMenuPaper }}>
          <CloseModalButton edge="end" fontSize="inherit" onClose={closeNavMenu} />
          <Box display="flex" justifyContent="center" px={2}>
            <Grid container justifyContent="center" direction="column" spacing={2}>
              <Grid item>
                <Box width="100%" textAlign="center">
                  <PodkrepiIcon className={classes.icon} />
                </Box>
              </Grid>
              {navItems.map(({ href, label }, key) => (
                <Grid item key={key}>
                  <LinkButton fullWidth variant="outlined" href={href}>
                    {t(label)}
                  </LinkButton>
                </Grid>
              ))}
              <Grid item>
                <Button href={staticUrls.blog} target="_blank" fullWidth variant="outlined">
                  {t('nav.blog')}
                </Button>
              </Grid>
              <Grid item>
                <DonationMenuMobile />
              </Grid>
              <AuthLinks />

              <Box my={4} textAlign="center">
                <LocaleButton />
              </Box>
            </Grid>
          </Box>
        </SwipeableDrawer>
      </Hidden>
    </Root>
  )
}
Example #3
Source File: Filter.tsx    From Cromwell with MIT License 4 votes vote down vote up
render() {
    const { instanceSettings } = this.props;
    const { pluginSettings } = this.props.data ?? {};
    const { attributes, productCategory } = this.initialData ?? {};
    const { isMobileOpen, minPrice, maxPrice, collapsedItems, isLoading } = this.state;
    instanceSettings?.getInstance?.(this);

    if (isLoading) return (
      <div style={{ width: '100%', height: '100px' }}>
        <LoadBox size={60} />
      </div>
    );

    const isMobile = !instanceSettings?.disableMobile && this.props.isMobile;
    const pcCollapsedByDefault = pluginSettings?.collapsedByDefault ?? defaultSettings.collapsedByDefault
    const mobileCollapsedByDefault = pluginSettings?.mobileCollapsedByDefault ?? defaultSettings.mobileCollapsedByDefault;
    const _collapsedByDefault = isMobile ? mobileCollapsedByDefault : pcCollapsedByDefault;
    const productListId = instanceSettings?.listId ?? pluginSettings?.listId;

    if (this.collapsedByDefault !== _collapsedByDefault) {
      this.collapsedByDefault = _collapsedByDefault;
      this.setState({ collapsedItems: {} });
    }

    setListProps(productListId, productCategory, this.client, this.getFilterParams(), this.updateFilterMeta);

    const filterContent = (
      <div>
        {isMobile && (
          <div className="productFilter_mobileHeader">
            <p>Filter</p>
            <IconButton
              aria-label="Close filter"
              className="productFilter_mobileCloseBtn"
              onClick={this.handleMobileClose}>
              <CloseIcon />
            </IconButton>
          </div>
        )}
        {this.getFilterItem({
          title: 'Search',
          key: 'search',
          content: (
            <TextField
              style={{
                padding: '0 15px 15px 15px',
                width: '100%',
              }}
              placeholder="type to search..."
              variant="standard"
              onChange={e => this.onSearchChange(e.target.value)}
            />
          )
        })}
        {productCategory &&
          !!(productCategory.parent || productCategory.children?.length) &&
          this.getFilterItem({
            title: 'Categories',
            key: 'categories',
            content: (
              <div className={clsx('productFilter_categoryBox',
                'productFilter_styledScrollBar',
                'productFilter_list')}>
                {productCategory.parent && (
                  <Chip className="productFilter_category"
                    label={productCategory.parent.name}
                    onClick={this.handleCategoryClick(productCategory.parent)} />
                )}
                {productCategory && (
                  <Chip className="productFilter_category"
                    variant="outlined"
                    disabled
                    style={{ marginLeft: productCategory.parent ? '15px' : '' }}
                    label={productCategory.name}
                    onClick={this.handleCategoryClick(productCategory)} />
                )}
                {!!productCategory.children?.length && (
                  <>
                    {productCategory.children.map(child => (
                      <Chip key={child.id}
                        className="productFilter_category"
                        style={{ marginLeft: ((productCategory?.parent ? 15 : 0) + 15) + 'px' }}
                        label={child.name}
                        onClick={this.handleCategoryClick(child)} />
                    ))}
                  </>
                )}
              </div>
            )
          })}
        {this.getFilterItem({
          title: 'Price',
          key: 'price',
          content: (
            <Slider
              onChange={this.onPriceRangeChange}
              minPrice={minPrice}
              maxPrice={maxPrice}
            />
          )
        })}
        {attributes && (
          attributes.map(attr => {
            if (!attr.key || !attr.values) return null;
            const checked: string[] | undefined = this.checkedAttrs[attr.key];
            const numberOfChecked = () => checked ? checked.length : 0;
            const handleToggleAll = () => {
              if (attr.key && attr.values && attr.values?.length !== 0) {
                if (numberOfChecked() === attr.values?.length) {
                  this.handleSetAttribute(attr.key, [])
                } else {
                  this.handleSetAttribute(attr.key, attr.values.map(v => v.value))
                }
              }
            }
            if (collapsedItems[attr.key] === undefined) {
              collapsedItems[attr.key] = this.collapsedByDefault;
            }
            const isExpanded = !collapsedItems[attr.key];
            return (
              <Card key={attr.key} className="productFilter_card">
                <div className="productFilter_headerWrapper">
                  <CardHeader
                    className="productFilter_cardHeader"
                    avatar={
                      <Checkbox
                        color="primary"
                        onClick={handleToggleAll}
                        checked={numberOfChecked() === attr.values.length && attr.values.length !== 0}
                        indeterminate={numberOfChecked() !== attr.values.length && numberOfChecked() !== 0}
                        disabled={attr.values.length === 0}
                        inputProps={{ 'aria-label': 'all items selected' }}
                      />
                    }
                    title={attr.key}
                    subheader={`${numberOfChecked()}/${attr.values.length} selected`}
                  />
                  <IconButton
                    onClick={() => this.setState(prev => ({
                      collapsedItems: {
                        ...prev.collapsedItems,
                        [attr.key!]: !prev.collapsedItems[attr.key!]
                      }
                    }))}
                    className={clsx('productFilter_expand', {
                      'productFilter_expandOpen': isExpanded,
                    })}
                    aria-label="Toggle filter visibility"
                    aria-expanded={isExpanded}
                  >
                    <ExpandMoreIcon />
                  </IconButton>
                </div>
                <Collapse in={isExpanded} timeout="auto" unmountOnExit>
                  <Divider />
                  <List className={clsx('productFilter_list', 'productFilter_styledScrollBar')} dense component="div" role="list">
                    {attr.values.map((attrValue: TAttributeValue) => {
                      const value = attrValue.value
                      const labelId = `attribute-list-${attr.key}-${value}-label`;
                      return (
                        <ListItem key={value} role="listitem" button
                          onClick={() => {
                            const newChecked = checked ? [...checked] : [];
                            const currentIndex = newChecked.indexOf(value);
                            if (currentIndex === -1) {
                              newChecked.push(value);
                            } else {
                              newChecked.splice(currentIndex, 1);
                            }
                            this.handleSetAttribute(attr.key!, newChecked);
                          }}>
                          <ListItemIcon>
                            <Checkbox
                              color="primary"
                              checked={checked ? checked.indexOf(value) !== -1 : false}
                              tabIndex={-1}
                              disableRipple
                              inputProps={{ 'aria-labelledby': labelId }}
                            />
                          </ListItemIcon>
                          {attrValue.icon && (
                            <div
                              style={{ backgroundImage: `url(${attrValue.icon}` }}
                              className="productFilter_attrValueIcon"></div>
                          )}
                          <ListItemText id={labelId} primary={value} />
                        </ListItem>
                      );
                    })}
                    <ListItem />
                  </List>
                </Collapse>
              </Card>
            )
          })
        )}
      </div>
    );

    if (isMobile) {
      const onOpen = () => {

      }
      const mobileIconPosition = pluginSettings?.mobileIconPosition ?? defaultSettings.mobileIconPosition;

      return (
        <div>
          <IconButton
            aria-label="Open product filter"
            className="productFilter_mobileOpenBtn"
            style={{
              top: mobileIconPosition.top + 'px',
              left: mobileIconPosition.left + 'px'
            }}
            onClick={this.handleMobileOpen}>
            <FilterListIcon />
          </IconButton>
          <SwipeableDrawer
            open={isMobileOpen}
            onClose={this.handleMobileClose}
            onOpen={onOpen}
            classes={{ paper: 'productFilter_styledScrollBar' }}
          >
            <div className="productFilter_drawer">
              {filterContent}
            </div>
          </SwipeableDrawer>
        </div>
      );
    }

    return filterContent;
  }
Example #4
Source File: Sidebar.tsx    From Cromwell with MIT License 4 votes vote down vote up
export default function Sidebar() {
    const pageInfos = getPageInfos();
    const currentInfo = pageInfos.find(i => i.route === window.location.pathname.replace('/admin', ''));
    const currentLink = getLinkByInfo(currentInfo);
    const [expanded, setExpanded] = useState<string | false>(currentLink?.parentId ?? false);
    const [optionsOpen, setOptionsOpen] = useState<boolean>(false);
    const [mobileOpen, setMobileOpen] = useState(false);
    const [cmsInfoOpen, setCmsInfoOpen] = useState(false);
    const [systemMonitorOpen, setSystemMonitorOpen] = useState(false);
    const popperAnchorEl = useRef<HTMLDivElement | null>(null);
    const history = useHistory?.();
    const forceUpdate = useForceUpdate();

    const userInfo: TUser | undefined = getStoreItem('userInfo');
    const toggleSubMenu = (panel: string) => (event: React.ChangeEvent<any>, isExpanded: boolean) => {
        setExpanded(isExpanded ? panel : false);
    };
    const handleCloseMenu = () => {
        setMobileOpen(false);
    }
    const handleOpenMenu = () => {
        setMobileOpen(true);
    }

    useEffect(() => {
        onStoreChange('userInfo', () => {
            setTimeout(forceUpdate, 100);
        });
        history?.listen(() => {
            const currentInfo = pageInfos.find(i => i.route === window.location.pathname.replace('/admin', ''));
            const newCurrentLink = getLinkByInfo(currentInfo);
            if (newCurrentLink && newCurrentLink !== currentLink) {
                // setActiveId(newCurrentLink.id);
                if (newCurrentLink.parentId) setExpanded(newCurrentLink.parentId)
            }
            setTimeout(forceUpdate, 100);
        });

        store.setStateProp({
            prop: 'forceUpdateSidebar',
            payload: forceUpdate,
        });
    }, []);

    const handleLogout = async () => {
        setOptionsOpen(false);
        await getRestApiClient()?.logOut();
        forceUpdate();
        history?.push(loginPageInfo.route);
    }

    const handleOptionsToggle = () => {
        setOptionsOpen(!optionsOpen);
    }

    const openFileManager = () => {
        getFileManager()?.open();
    }

    const openCmsInfo = () => {
        setCmsInfoOpen(true);
    }

    const openDocs = () => {
        window.open('https://cromwellcms.com/docs/overview/intro', '_blank')
    }

    // check for disabled sidebar
    if (currentInfo?.disableSidebar) return <></>;

    const sidebarContent = (
        <div className={styles.sidebarContent}>
            <div className={styles.sidebarTop}>
                <div className={styles.sidebarHeader}>
                    <div className={styles.logo}
                        style={{ backgroundImage: `url("/admin/static/logo_small_white.svg")` }}
                    ></div>
                    {/* <p className={commonStyles.text} style={{ color: '#fff', opacity: 0.7 }}>Admin Panel</p> */}
                    <div>
                        <NotificationCenter color="#fff" />
                    </div>
                    <div className={styles.sidebarMobileActions}>
                        <IconButton onClick={handleCloseMenu} >
                            <CloseIcon htmlColor="#999" />
                        </IconButton>
                    </div>
                </div>
                {getSideBarLinks().map(link => <SidebarLink data={link}
                    key={link.id}
                    toggleSubMenu={toggleSubMenu}
                    expanded={expanded}
                    forceUpdate={forceUpdate}
                    activeId={currentLink?.id}
                    userInfo={userInfo}
                />)}
            </div>
            <div className={styles.sidebarBottom}>
                <div className={styles.bottomBlock} style={{ overflow: 'hidden' }}>
                    {(userInfo?.avatar && userInfo?.avatar !== '') ? (
                        <div className={styles.avatar} style={{ backgroundImage: `url(${userInfo.avatar})` }}></div>
                    ) : <AccountCircleIcon className={styles.avatar} />}
                    <div className={styles.textBlock}>
                        <p className={styles.nameText}>{userInfo?.fullName ?? ''}</p>
                        <p className={styles.emailText}>{userInfo?.email ?? ''}</p>
                    </div>
                </div>
                <div className={styles.bottomBlock}
                    style={{ marginRight: '-10px' }}
                    ref={popperAnchorEl}>
                    <Tooltip title="Options">
                        <IconButton
                            style={{ marginLeft: '-10px' }}
                            onClick={handleOptionsToggle}
                            className={styles.actionBtn}
                            aria-label="Options"
                        >
                            <MoreVertOutlinedIcon />
                        </IconButton>
                    </Tooltip>
                    <Popover open={optionsOpen} anchorEl={popperAnchorEl.current}
                        style={{ zIndex: 9999 }}
                        onClose={() => setOptionsOpen(false)}
                        anchorOrigin={{
                            vertical: 'top',
                            horizontal: 'right',
                        }}
                        transformOrigin={{
                            vertical: 'bottom',
                            horizontal: 'right',
                        }}
                    >
                        <div onClick={() => setOptionsOpen(false)}>
                            <Link to={`${userPageInfo.baseRoute}/${userInfo?.id}`}>
                                <MenuItem className={styles.optionsItem}>
                                    <AccountCircleOutlinedIcon />
                                    <p>Your profile</p>
                                </MenuItem>
                            </Link>
                            <MenuItem className={styles.optionsItem} onClick={openFileManager}>
                                <PermMediaOutlinedIcon />
                                <p>Media</p>
                            </MenuItem>
                            <MenuItem className={styles.optionsItem} onClick={() => setSystemMonitorOpen(true)}>
                                <DnsRoundedIcon />
                                <p>System monitor</p>
                            </MenuItem>
                            <MenuItem className={styles.optionsItem} onClick={openCmsInfo}>
                                <InfoOutlinedIcon />
                                <p>CMS specs</p>
                            </MenuItem>
                            <MenuItem className={styles.optionsItem} onClick={openDocs}>
                                <HelpOutlineIcon />
                                <p>Documentation</p>
                            </MenuItem>
                            <MenuItem onClick={handleLogout} className={styles.optionsItem}>
                                <ExitToAppIcon />
                                <p>Log out</p>
                            </MenuItem>
                        </div>
                    </Popover>
                </div>
            </div>
        </div>
    )

    return (
        <div className={styles.Sidebar}>
            <div className={styles.mobileContent}>
                <HideOnScroll>
                    <AppBar
                        className={styles.appBar}
                        color="transparent"
                    >
                        <Toolbar
                            className={styles.toolbar}
                        >
                            <div className={styles.sidebarMobileHeader}>
                                <div className={styles.logoMobile}
                                    style={{ backgroundImage: `url("/admin/static/logo_small_white.svg")` }}
                                ></div>
                                {/* <p className={commonStyles.text} style={{ color: '#fff', opacity: 0.7 }}>Admin Panel</p> */}
                                <div className={styles.mobileActions}>
                                    <NotificationCenter />
                                    <IconButton onClick={handleOpenMenu}>
                                        <MenuIcon />
                                    </IconButton>
                                </div>
                            </div>
                        </Toolbar>
                    </AppBar>
                </HideOnScroll>
                <SwipeableDrawer
                    open={mobileOpen}
                    onClose={handleCloseMenu}
                    onOpen={handleOpenMenu}
                >
                    <div className={styles.drawer}>{sidebarContent}</div>
                </SwipeableDrawer>
            </div>
            <CmsInfo
                open={cmsInfoOpen}
                onClose={() => setCmsInfoOpen(false)}
            />
            <SystemMonitor
                open={systemMonitorOpen}
                onClose={() => setSystemMonitorOpen(false)}
            />
            <div className={styles.desktopContent}>{sidebarContent}</div>
        </div>
    )
}
Example #5
Source File: Header.tsx    From Cromwell with MIT License 4 votes vote down vote up
Header = () => {
    const cmsConfig = useCmsSettings();
    const [menuOpen, setMenuOpen] = useState(false);
    const handleCloseMenu = () => {
        setMenuOpen(false);
    }
    const handleOpenMenu = () => {
        setMenuOpen(true);
    }

    return (
        <CContainer global id="header-01">
            <Toolbar className={styles.dummyToolbar} />
            <HideOnScroll>
                <AppBar
                    className={styles.appBar}
                    color="transparent"
                >
                    <Toolbar>
                        <CContainer className={`${styles.Header} ${commonStyles.text}`} id="header-02">
                            <CContainer className={`${commonStyles.content} ${styles.headerContent}`} id="header-03">
                                <CContainer className={styles.logoWrapper} id="header-06">
                                    <Link href="/">
                                        <img className={styles.logo} src={cmsConfig?.logo} alt="logo" />
                                    </Link>
                                </CContainer>
                                <CPlugin
                                    className={styles.mainMenu}
                                    id="header_main_menu"
                                    pluginName={"@cromwell/plugin-main-menu"}
                                    blockName="Main menu"
                                />
                                <CContainer className={styles.search} id="header-04">
                                    <HeaderSearch />
                                </CContainer>
                                <CContainer className={styles.mobileActions} id="header-05">
                                    <IconButton
                                        aria-label={"Open main menu"}
                                        onClick={handleOpenMenu}>
                                        <MenuIcon color="#111" />
                                    </IconButton>
                                </CContainer>
                            </CContainer>
                        </CContainer>
                    </Toolbar>
                </AppBar>
            </HideOnScroll>
            <SwipeableDrawer
                open={menuOpen}
                onClose={handleCloseMenu}
                onOpen={handleOpenMenu}
            >
                <div className={styles.drawer}>
                    <div className={styles.menuActions}>
                        <div></div>
                        <IconButton
                            aria-label="Close main menu"
                            onClick={handleCloseMenu}>
                            <CloseIcon color="#111" />
                        </IconButton>
                    </div>
                    <div className={styles.mobileSearch}>
                        <HeaderSearch />
                    </div>
                    <div>
                        <CPlugin
                            id="header_main_menu"
                            plugin={{
                                instanceSettings: {
                                    mobile: true
                                },
                                pluginName: "@cromwell/plugin-main-menu"
                            }}
                            blockName="Main menu"
                        />
                    </div>
                </div>
            </SwipeableDrawer>
        </CContainer>
    )
}
Example #6
Source File: MobileHeader.tsx    From Cromwell with MIT License 4 votes vote down vote up
MobileHeader = () => {
  const [menuOpen, setMenuOpen] = useState(false);
  const cmsConfig = getCmsSettings();

  const handleCloseMenu = () => {
    setMenuOpen(false);
  }
  const handleOpenMenu = () => {
    setMenuOpen(true);
    globalCloseMenu = () => setMenuOpen(false);
  }

  const handleOpenCart = () => {
    appState.isCartOpen = true;
  }

  const handleOpenWishlist = () => {
    appState.isWishlistOpen = true;
  }

  const handleOpenWatched = () => {
    appState.isWatchedOpen = true;
  }

  return (
    <>
      <Toolbar className={styles.dummyToolbar} />
      <HideOnScroll>
        <AppBar
          className={styles.appBar}
          color="transparent"
        >
          <Toolbar>
            <div className={styles.appBarContent}>
              <div className={styles.leftActions}>
                <div className={styles.logo}>
                  <Link href="/">
                    <img className={styles.logo} src={cmsConfig?.logo} alt="logo" />
                  </Link>
                </div>

              </div>
              <div className={styles.rightActions}>
                <IconButton
                  aria-label="Open wishlist"
                  onClick={handleOpenWishlist}>
                  <FavoriteIcon />
                </IconButton>
                <IconButton
                  aria-label="Open cart"
                  onClick={handleOpenCart}>
                  <ShoppingCartIcon />
                </IconButton>
                <IconButton
                  aria-label="Open main menu"
                  onClick={handleOpenMenu}>
                  <MenuIcon />
                </IconButton>
              </div>
            </div>
          </Toolbar>
        </AppBar>
      </HideOnScroll>
      <SwipeableDrawer
        open={menuOpen}
        onClose={handleCloseMenu}
        onOpen={handleOpenMenu}
      >
        <div className={styles.drawer}>
          <div className={styles.menuActions}>
            <div className={styles.currencyOption}>
              <MuiCurrencySwitch />
            </div>
            <IconButton
              aria-label="Open recently viewed items"
              onClick={handleOpenWatched}>
              <VisibilityIcon />
            </IconButton>
            {/* <IconButton onClick={handleOpenCompare}>
                            <EqualizerIcon />
                        </IconButton> */}
            <IconButton
              aria-label="Open wishlist"
              onClick={handleOpenWishlist}>
              <FavoriteIcon />
            </IconButton>
            <IconButton
              aria-label="Open shopping cart"
              onClick={handleOpenCart}>
              <ShoppingCartIcon />
            </IconButton>
            <IconButton
              aria-label="Close main menu"
              onClick={handleCloseMenu}>
              <CloseIcon />
            </IconButton>
          </div>

          <div className={styles.mobileSearch}>
            <MuiProductSearch />
          </div>
          <CContainer id="mobile_header_13">
            <CPlugin id="header_main_menu"
              plugin={{
                instanceSettings: {
                  mobile: true
                },
                pluginName: "@cromwell/plugin-main-menu"
              }}
              blockName="Main menu"
            />
          </CContainer>
        </div>
      </SwipeableDrawer>
    </>
  );
}