@mui/material#IconButton TypeScript Examples

The following examples show how to use @mui/material#IconButton. 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: FieldDescription.tsx    From firecms with MIT License 6 votes vote down vote up
/**
 * Render the field description for a property
 * @category Form custom fields
 */
export function FieldDescription<T extends CMSType>({ property }: FieldDescriptionPopoverProps<T>) {
    const disabledTooltip: string | undefined = typeof property.disabled === "object" ? property.disabled.disabledMessage : undefined;
    return (

        // <FormHelperText>{disabledTooltip ? disabledTooltip : property.description}</FormHelperText>
        <Box display="flex">

            <Box flexGrow={1}>
                <FormHelperText>{disabledTooltip || property.description}</FormHelperText>
            </Box>

            {property.longDescription &&
            <Tooltip title={
                <Typography
                    variant={"caption"}>{property.longDescription}</Typography>
            }
                     placement="bottom-start"
                     arrow>
                <IconButton
                    edge={"start"}
                    size={"small"}>

                    <InfoIcon color={"disabled"}
                              fontSize={"small"}/>
                </IconButton>
            </Tooltip>}

        </Box>
    );
}
Example #2
Source File: DraggableList.tsx    From Cromwell with MIT License 6 votes vote down vote up
render() {
        const ItemComponent = this.props.component;
        return (
            <div className={styles.DraggableList}>
                <ResponsiveGridLayout
                    margin={[0, 0]}
                    isResizable={false}
                    breakpoints={{ xs: 480, xxs: 0 }}
                    rowHeight={64}
                    layouts={this.getGridLayout(this.props.data)}
                    onLayoutChange={this.onLayoutChange(this.props.data)}
                    cols={{ xs: 1, xxs: 1 }}
                    draggableHandle='.draggableHandle'
                >
                    {this.props.data.map((item, index) => {
                        return (<div
                            key={(item?.id ?? index) + ''}
                            className={styles.item}
                        >
                            <IconButton style={{ cursor: 'move', marginRight: '10px' }}
                                className="draggableHandle">
                                <DragIndicatorIcon />
                            </IconButton>
                            <ItemComponent data={item} itemProps={this.props.itemProps} />
                        </div>)
                    })}
                </ResponsiveGridLayout>
            </div>
        );
    }
Example #3
Source File: Desktop.tsx    From GTAV-NativeDB with MIT License 6 votes vote down vote up
function AppBarAction({ text, desktopIcon, buttonProps }: AppBarActionProps) {
  if (!desktopIcon) {
    return (
      <Button {...buttonProps} color="inherit">
        {text}
      </Button>
    )
  }

  return (
    <Tooltip title={text}>
      <IconButton
        aria-label={text}
        {...buttonProps}
        color="inherit"
      >
        {React.createElement(desktopIcon)}
      </IconButton>
    </Tooltip>
  )
}
Example #4
Source File: Header.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 6 votes vote down vote up
Header: React.FC = () => {
    const [colorMode, setColorMode] = useRecoilState(GlobalState.theme)
    const {setVisible} = useVisibility()

    const handleExit = async () => {
        try {
            await fetchNui("exit")
            setVisible(false);
        } catch (e) {
            console.error(e)
        }
    }

    const handleThemeswitch = () => {
        colorMode === "light" ? setColorMode("dark") : setColorMode("light")
    }

    return (
        <AppBar position="sticky">
            <Toolbar sx={{backgroundColor: "primary.dark"}}>
                <Typography sx={{flex: 1}}>
                    <img src={logo} height="100px" alt=""/>
                </Typography>

                <CategorySelect/>
                <IconButton sx={{ml: 1}} onClick={handleThemeswitch} color="inherit">
                    {colorMode === 'dark' ? <Brightness7Icon/> : <Brightness4Icon/>}
                </IconButton>
                <IconButton sx={{ml: 1}} onClick={handleExit} color="inherit">
                    <CloseIcon/>
                </IconButton>
            </Toolbar>
        </AppBar>
    )
}
Example #5
Source File: LibraryOptions.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 6 votes vote down vote up
export default function LibraryOptions() {
    const [filtersOpen, setFiltersOpen] = React.useState(false);
    const { active } = useLibraryOptionsContext();
    return (
        <>
            <IconButton
                onClick={() => setFiltersOpen(!filtersOpen)}
                color={active ? 'warning' : 'default'}
            >
                <FilterListIcon />
            </IconButton>

            <Drawer
                anchor="bottom"
                open={filtersOpen}
                onClose={() => setFiltersOpen(false)}
                PaperProps={{
                    style: {
                        maxWidth: 600, padding: '1em', marginLeft: 'auto', marginRight: 'auto',
                    },
                }}
            >
                <Options />
            </Drawer>
        </>
    );
}
Example #6
Source File: Layout.tsx    From your_spotify with GNU General Public License v3.0 6 votes vote down vote up
export default function Layout({ children }: LayoutProps) {
  const [open, setOpen] = useState(false);
  const showSider = !useMediaQuery('(max-width: 900px)');
  const publicToken = useSelector(selectPublicToken);

  const drawer = useCallback(() => {
    setOpen((old) => !old);
  }, []);

  return (
    <div className={s.root}>
      {!showSider && (
        <Drawer open={open} anchor="left" onClose={() => setOpen(false)}>
          <Sider />
        </Drawer>
      )}
      <section className={s.sider}>{showSider && <Sider />}</section>
      <section
        className={clsx({
          [s.content]: true,
          [s.contentdrawer]: showSider,
        })}>
        {publicToken && (
          <div className={s.publictoken}>
            <Text>You are viewing as guest</Text>
          </div>
        )}
        {!showSider && (
          <IconButton onClick={drawer} className={s.drawerbutton}>
            <Menu />
          </IconButton>
        )}
        {children}
      </section>
    </div>
  );
}
Example #7
Source File: HomeScreen.tsx    From rewind with MIT License 6 votes vote down vote up
export function HomeScreen() {
  const { appVersion } = useAppInfo();
  return (
    <Stack gap={4} sx={{ justifyContent: "center", alignItems: "center", margin: "auto", height: "100%" }}>
      <Stack alignItems={"center"}>
        <FastRewind sx={{ height: "2em", width: "2em" }} />
        <Typography fontSize={"1em"} sx={{ userSelect: "none", marginBottom: 2 }}>
          REWIND
        </Typography>
        <Typography fontSize={"caption.fontSize"} color={"text.secondary"}>
          Rewind {appVersion} by{" "}
          <Link href={RewindLinks.OsuPpyShAbstrakt} target={"_blank"} color={"text.secondary"}>
            abstrakt
          </Link>
        </Typography>
        <Typography fontSize={"caption.fontSize"} color={"text.secondary"}>
          osu! University
          <IconButton href={discordUrl} target={"_blank"} size={"small"}>
            <FaDiscord />
          </IconButton>
          <IconButton href={twitterUrl} target={"_blank"} size={"small"}>
            <FaTwitter />
          </IconButton>
          <IconButton href={youtubeUrl} target={"_blank"} size={"small"}>
            <FaYoutube />
          </IconButton>
        </Typography>
      </Stack>
    </Stack>
  );
}
Example #8
Source File: DetailFrame.tsx    From airmessage-web with Apache License 2.0 6 votes vote down vote up
DetailFrame = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
	return (
		<div className={styles.root} ref={ref}>
			<Toolbar>
				<Typography className={styles.title} variant="h6" noWrap>{props.title}</Typography>
				
				{props.showCall && (
					<IconButton
						size="large"
						onClick={props.onClickCall}>
						<VideocamOutlined />
					</IconButton>
				)}
			</Toolbar>
			<SoftDivider />
			{props.children}
		</div>
	);
})
Example #9
Source File: index.tsx    From multi-downloader-nx with MIT License 6 votes vote down vote up
ReactDOM.render(
  <React.StrictMode>
    <ErrorHandler>
      <Store>
        <SnackbarProvider
          ref={notistackRef}
          action={(key) => (
            <IconButton onClick={onClickDismiss(key)} color="inherit">
              <CloseOutlined />
            </IconButton>
          )}
          >
          <Style>
            <MessageChannel>
              <ServiceProvider>
                <App />
              </ServiceProvider>
            </MessageChannel>
          </Style>
        </SnackbarProvider>
      </Store>
    </ErrorHandler>
  </React.StrictMode>,
  document.getElementById('root')
);
Example #10
Source File: Header.tsx    From fluttertemplates.dev with MIT License 6 votes vote down vote up
displayMobile = (isOpen: boolean, onToggle: any) => {
  return (
    <div>
      <IconButton onClick={onToggle}>
        <MenuRounded />
      </IconButton>
      <Drawer open={isOpen} anchor="bottom" onClose={onToggle}>
        {commonNav.map((item) => (
          <ListItem
            key={item.props.href}
            style={{
              padding: 16,
              justifyContent: "center",
            }}
          >
            {item}
          </ListItem>
        ))}
      </Drawer>
    </div>
  );
}
Example #11
Source File: PasswordElement.tsx    From react-hook-form-mui with MIT License 6 votes vote down vote up
export default function PasswordElement({iconColor, ...props}: PasswordElementProps): JSX.Element {
  const [password, setPassword] = useState<boolean>(true)
  return (
    <TextFieldElement
      {...props}
      InputProps={{
        endAdornment: (
          <InputAdornment position={'end'}>
            <IconButton
              onMouseDown={(e: MouseEvent<HTMLButtonElement>) =>
                e.preventDefault()
              }
              onClick={() => setPassword(!password)}
              tabIndex={-1}
              color={iconColor ?? 'default'}
            >
              {password ? <Visibility /> : <VisibilityOff />}
            </IconButton>
          </InputAdornment>
        )
      }}
      type={password ? 'password' : 'text'}
    />
  )
}
Example #12
Source File: CharacterSelectionModal.tsx    From genshin-optimizer with MIT License 6 votes vote down vote up
function CharacterBtn({ onClick, characterKey, characterSheet }: { onClick: () => void, characterKey: CharacterKey, characterSheet: CharacterSheet }) {
  const teamData = useTeamData(characterKey)
  const { database } = useContext(DatabaseContext)
  const characterDispatch = useCharacterReducer(characterKey)
  const favorite = database._getChar(characterKey)?.favorite
  const { target: data } = teamData?.[characterKey] ?? {}
  const rarity = characterSheet.rarity
  return <Suspense fallback={<Skeleton variant="rectangular" height={130} />}><Box>
    {favorite !== undefined && <Box display="flex" position="absolute" alignSelf="start" zIndex={1}>
      <IconButton sx={{ p: 0.5 }} onClick={() => characterDispatch({ favorite: !favorite })}>
        {favorite ? <Favorite /> : <FavoriteBorder />}
      </IconButton>
    </Box>}
    <CardActionArea onClick={onClick} >
      <CardLight sx={{ display: "flex", alignItems: "center" }}  >
        <Box component="img" src={characterSheet.thumbImg} sx={{ width: 130, height: "auto" }} className={`grad-${rarity}star`} />
        <Box sx={{ pl: 1 }}>
          <Typography><strong>{characterSheet.name}</strong></Typography>
          {data ? <>
            <Typography variant="h6"> {characterSheet.elementKey && StatIcon[characterSheet.elementKey]} <ImgIcon src={Assets.weaponTypes?.[characterSheet.weaponTypeKey]} />{` `}{CharacterSheet.getLevelString(data.get(input.lvl).value, data.get(input.asc).value)}</Typography>
            <Typography >
              <SqBadge color="success">{`C${data.get(input.constellation).value}`}</SqBadge>{` `}
              <SqBadge color={data.get(input.bonus.auto).value ? "info" : "secondary"}><strong >{data.get(input.total.auto).value}</strong></SqBadge>{` `}
              <SqBadge color={data.get(input.bonus.skill).value ? "info" : "secondary"}><strong >{data.get(input.total.skill).value}</strong></SqBadge>{` `}
              <SqBadge color={data.get(input.bonus.burst).value ? "info" : "secondary"}><strong >{data.get(input.total.burst).value}</strong></SqBadge>
            </Typography>
          </> : <>
            <Typography variant="h6"><SqBadge color="primary">NEW</SqBadge></Typography>
          </>}
          <small><Stars stars={rarity} colored /></small>
        </Box>
      </CardLight>
    </CardActionArea >
  </Box></Suspense>
}
Example #13
Source File: EditActionButton.tsx    From console with GNU Affero General Public License v3.0 6 votes vote down vote up
EditActionButton = ({
  disabled,
  onClick,
  ...restProps
}: EditActionButtonProps) => {
  return (
    <IconButton
      size={"small"}
      disabled={disabled}
      onClick={onClick}
      {...restProps}
    >
      <EditIcon />
    </IconButton>
  );
}
Example #14
Source File: index.tsx    From mui-toolpad with MIT License 6 votes vote down vote up
function HierarchyTreeItem(props: StyledTreeItemProps) {
  const { labelIcon, labelText, onCreate, onDelete, ...other } = props;

  return (
    <TreeItem
      label={
        <Box sx={{ display: 'flex', alignItems: 'center', p: 0.5, pr: 0 }}>
          {labelIcon}
          <Typography variant="body2" sx={{ fontWeight: 'inherit', flexGrow: 1 }}>
            {labelText}
          </Typography>
          {onCreate ? (
            <IconButton aria-label={`Create ${labelText}`} onClick={onCreate}>
              <AddIcon />
            </IconButton>
          ) : null}
          {onDelete ? (
            <IconButton aria-label={`Delete ${labelText}`} onClick={onDelete}>
              <DeleteIcon />
            </IconButton>
          ) : null}
        </Box>
      }
      {...other}
    />
  );
}
Example #15
Source File: App.tsx    From NekoMaid with MIT License 6 votes vote down vote up
LanguageSwitch: React.FC = React.memo(() => {
  const [anchorEl, setAnchorEl] = React.useState<HTMLElement | undefined>()
  return <>
    <IconButton onClick={e => setAnchorEl(e.currentTarget)} color='inherit'><Translate /></IconButton>
    <MenuComponent anchorEl={anchorEl} open={!!anchorEl} onClose={() => setAnchorEl(undefined)}>
      {Object.entries(languages).map(([key, value]) => <MenuItem
        key={key}
        selected={currentLanguage === key}
        onClick={() => {
          setAnchorEl(undefined)
          if (currentLanguage !== key) {
            localStorage.setItem('NekoMaid:language', key)
            location.reload()
          }
        }}
      >{value.minecraft['language.name']}</MenuItem>)}
    </MenuComponent>
  </>
})
Example #16
Source File: SearchBar.tsx    From firecms with MIT License 5 votes vote down vote up
export function SearchBar({ onTextSearch }: SearchBarProps) {

    const classes = useStyles();

    const [searchText, setSearchText] = useState<string>("");
    const [active, setActive] = useState<boolean>(false);

    /**
     * Debounce on Search text update
     */
    useEffect(
        () => {
            const handler = setTimeout(() => {
                if (searchText) {
                    onTextSearch(searchText);
                } else {
                    onTextSearch(undefined);
                }
            }, 250);

            return () => {
                clearTimeout(handler);
            };
        },
        [searchText]
    );

    const clearText = useCallback(() => {
        setSearchText("");
        onTextSearch(undefined);
    }, []);

    return (
        <FormControl>
            <div className={classes.search}>
                <div className={classes.searchIcon}>
                    <SearchIcon htmlColor={"#666"}/>
                </div>
                <InputBase
                    placeholder="Search"
                    value={searchText}
                    onChange={(event) => {
                        setSearchText(event.target.value);
                    }}
                    onFocus={() => setActive(true)}
                    onBlur={() => setActive(false)}
                    classes={{
                        root: classes.inputRoot,
                        input: clsx(classes.inputInput, {
                            [classes.inputActive]: active
                        })
                    }}
                    endAdornment={searchText
                        ? <IconButton
                            size={"small"}
                            onClick={clearText}>
                            <ClearIcon fontSize={"small"}/>
                        </IconButton>
                        : <div style={{ width: 26 }}/>
                    }
                    inputProps={{ "aria-label": "search" }}
                />
            </div>
        </FormControl>
    );
}
Example #17
Source File: SettingsPage.tsx    From Cromwell with MIT License 5 votes vote down vote up
export function SettingsPage(props: TPluginSettingsProps<TMainMenuSettings>) {
    const classes = useStyles();
    const forceUpdate = useForceUpdate();
    const [canReorder, setCanReorder] = useState(false);

    const onSave = () => {
        getRestApiClient().purgeRendererEntireCache();
    }

    return (
        <PluginSettingsLayout<TMainMenuSettings> {...props} onSave={onSave}>
            {({ pluginSettings, changeSetting }) => {
                const items = pluginSettings?.items;

                if (items) {
                    for (const item of items) {
                        if (!item.id) item.id = getRandStr(12);
                    }
                }

                const updateItems = (items: TMainMenuItem[]) => {
                    if (pluginSettings) pluginSettings.items = items;
                }

                return (
                    <>
                        <div onClick={() => setCanReorder(!canReorder)}
                            style={{ display: 'flex', alignItems: 'center' }}>
                            {canReorder ? (
                                <Tooltip title="Apply order">
                                    <IconButton><DoneIcon /></IconButton>
                                </Tooltip>
                            ) : (
                                <Tooltip title="Edit order">
                                    <IconButton><ReorderIcon /></IconButton>
                                </Tooltip>
                            )}
                        </div>
                        <div className={classes.itemList}>
                            {canReorder && items?.length && (
                                <DraggableList data={items}
                                    component={Item}
                                    onChange={updateItems}
                                    itemProps={{
                                        items,
                                        canReorder,
                                        refreshList: forceUpdate,
                                    }}
                                />
                            )}
                            {!canReorder && items?.map((data) => {
                                return <Item data={data}
                                    key={data.id}
                                    itemProps={{
                                        items,
                                        canReorder,
                                        refreshList: forceUpdate,
                                    }} />
                            })}
                        </div>
                        <div style={{ padding: '5px 10px' }}>
                            <div className={`${classes.card} PluginMainMenu-paper`}>
                                <MenuItem
                                    className={classes.addBtn}
                                    onClick={() => changeSetting('items',
                                        [...(items ?? []), {
                                            title: '',
                                            id: getRandStr(12),
                                        }]
                                    )}>
                                    <AddIcon />
                                </MenuItem>
                            </div>
                        </div>
                    </>
                )
            }}
        </PluginSettingsLayout>
    )
}
Example #18
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 #19
Source File: SidebarGroupList.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function SidebarGroupList({ group = null }) {
    const groups = useRecoilValue(groupList);
    const isGuest = useRecoilValue(isGuestUser);
    const [showGroupCreationModal, setShowGroupCreationModal] = useState(false);

    const openGroupCreateModal = () => {
        setShowGroupCreationModal(true);
    };

    const closeGroupCreateModal = (evt, reason) => {
        if (reason !== "backdropClick") {
            setShowGroupCreationModal(false);
        }
    };

    return (
        <>
            <List sx={{ pt: 0 }}>
                <ListItem sx={{ pt: 0, pb: 0 }}>
                    <ListItemText secondary="Groups" />
                </ListItem>
                {groups.map((it) => (
                    <ListItemLink key={it.id} to={`/groups/${it.id}`} selected={group && group.id === it.id}>
                        <ListItemText primary={it.name} />
                    </ListItemLink>
                ))}
                {!isGuest && (
                    <ListItem sx={{ padding: 0 }}>
                        <Grid container justifyContent="center">
                            <IconButton size="small" onClick={openGroupCreateModal}>
                                <Add />
                            </IconButton>
                        </Grid>
                    </ListItem>
                )}
            </List>
            {!isGuest && <GroupCreateModal show={showGroupCreationModal} onClose={closeGroupCreateModal} />}
        </>
    );
}
Example #20
Source File: AppbarSearch.tsx    From Tachidesk-WebUI with Mozilla Public License 2.0 5 votes vote down vote up
AppbarSearch: React.FunctionComponent<IProps> = (props) => {
    const { autoOpen } = props;
    const [query, setQuery] = useQueryParam('query', StringParam);
    const [searchOpen, setSearchOpen] = useState(!!query);
    const inputRef = React.useRef<HTMLInputElement>();

    function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
        setQuery(e.target.value === '' ? undefined : e.target.value);
    }
    const cancelSearch = () => {
        setQuery(null);
        setSearchOpen(false);
    };
    const handleBlur = () => { if (!query) setSearchOpen(false); };
    const openSearch = () => {
        setSearchOpen(true);
        // Put Focus Action at the end of the Callstack so Input actually exists on the dom
        setTimeout(() => {
            if (inputRef && inputRef.current) inputRef.current.focus();
        });
    };

    const handleSearchShortcut = (e: KeyboardEvent) => {
        if ((e.code === 'F3') || (e.ctrlKey && e.code === 'KeyF')) {
            e.preventDefault();
            openSearch();
        }
    };

    useEffect(() => {
        if (autoOpen) {
            openSearch();
        }
    }, []);

    useEffect(() => {
        window.addEventListener('keydown', handleSearchShortcut);

        return () => {
            window.removeEventListener('keydown', handleSearchShortcut);
        };
    }, [handleSearchShortcut]);

    return (
        <>
            {searchOpen
                ? (
                    <Input
                        value={query || ''}
                        onChange={handleChange}
                        onBlur={handleBlur}
                        inputRef={inputRef}
                        endAdornment={(
                            <IconButton
                                onClick={cancelSearch}
                            >
                                <CancelIcon />
                            </IconButton>
                        )}
                    />
                ) : (
                    <IconButton onClick={openSearch}>
                        <SearchIcon />
                    </IconButton>
                )}
        </>
    );
}
Example #21
Source File: Track.tsx    From your_spotify with GNU General Public License v3.0 5 votes vote down vote up
export default function Track(props: TrackProps | HeaderTrackProps) {
  const trackId = props.line ? null : props.track.id;
  const play = useCallback(async () => {
    if (!trackId) return;
    try {
      await api.play(trackId);
    } catch (e) {
      console.error(e);
    }
  }, [trackId]);

  const upmd = useMediaQuery('(min-width: 1150px)');

  if (props.line) {
    return (
      <div className={s.root}>
        <div className={clsx(s.name, s.header)}>
          <Text className={s.trackname}>Track name / Artist</Text>
        </div>
        {upmd && <Text className={clsx(s.albumname, s.header)}>Album name</Text>}
        {upmd && <Text className={clsx(s.duration, s.header)}>Duration</Text>}
        <Text className={clsx(s.sumcount, s.header)}>Count</Text>
        <Text className={clsx(s.sumduration, s.header)}>Total duration</Text>
      </div>
    );
  }

  const { track, album, artists, playable, duration, totalDuration, count, totalCount } = props;
  return (
    <div className={s.root}>
      {playable && (
        <IconButton className={s.play} size="small" onClick={play}>
          <PlayArrow />
        </IconButton>
      )}
      <img className={s.albumcover} src={getImage(album)} alt="Album cover" />
      <div className={s.name}>
        <Text className={s.trackname}>{track.name}</Text>
        <Text className={s.artistname}>
          {artists.map((art) => (
            <React.Fragment key={art.id}>
              <InlineArtist key={art.id} artist={art} />{' '}
            </React.Fragment>
          ))}
        </Text>
      </div>
      {upmd && <Text className={s.albumname}>{album.name}</Text>}
      {upmd && <Text className={s.duration}>{msToMinutesAndSeconds(track.duration_ms)}</Text>}
      <Text className={s.sumcount}>
        {count} {upmd && <Text>({Math.floor((count / totalCount) * 10000) / 100})</Text>}
      </Text>
      <Text className={s.sumduration}>
        {msToMinutesAndSeconds(duration)}{' '}
        {upmd && <Text>({Math.floor((duration / totalDuration) * 10000) / 100})</Text>}
      </Text>
    </div>
  );
}
Example #22
Source File: LeftMenuSidebar.tsx    From rewind with MIT License 5 votes vote down vote up
export function LeftMenuSidebar() {
  // const LinkBehavior = React.forwardRef((props, ref) => <Link ref={ref} to="/" {...props} role={undefined} />);
  const dispatch = useAppDispatch();
  const pathname = useAppSelector((state) => state.router.location.pathname);

  const handleLinkClick = (to: string) => () => dispatch(push(to));
  const buttonColor = (name: string) => (name === pathname ? "primary" : "default");
  const updateState = useCheckForUpdate();

  return (
    <Stack
      sx={{
        width: (theme) => theme.spacing(10),
        paddingBottom: 2,
      }}
      gap={1}
      p={1}
      alignItems={"center"}
      component={"nav"}
    >
      <Box onClick={handleLinkClick("/home")} sx={{ cursor: "pointer" }}>
        <RewindLogo />
      </Box>
      <Divider orientation={"horizontal"} sx={{ borderWidth: 1, width: "80%" }} />
      <Tooltip title={"Overview"} placement={"right"}>
        <IconButton color={buttonColor("/home")} onClick={handleLinkClick("/home")}>
          <Home />
        </IconButton>
      </Tooltip>
      <Tooltip title={"Analyzer"} placement={"right"}>
        <IconButton
          // These are not centered
          onClick={handleLinkClick("/analyzer")}
          color={buttonColor("/analyzer")}
        >
          <FaMicroscope height={"0.75em"} />
        </IconButton>
      </Tooltip>
      {/*Nothing*/}
      <Box flexGrow={1} />
      {updateState.hasNewUpdate && (
        <Tooltip title={`New version ${updateState.latestVersion} available!`} placement={"right"}>
          <IconButton onClick={() => window.open(latestReleaseUrl)}>
            <Badge variant={"dot"} color={"error"}>
              <UpdateIcon />
            </Badge>
          </IconButton>
        </Tooltip>
      )}
    </Stack>
  );
}
Example #23
Source File: MessageInput.tsx    From airmessage-web with Apache License 2.0 5 votes vote down vote up
export default function MessageInput(props: Props) {
	const theme = useTheme();
	const colorBG = theme.palette.messageIncoming.main;
	
	const {
		onMessageChange: propsOnMessageChange,
		onMessageSubmit: propsOnMessageSubmit,
		message: propsMessage,
		attachments: propsAttachments,
		onAttachmentAdd: propsOnAttachmentAdd
	} = props;
	
	const handleChange = useCallback((event: ChangeEvent<HTMLTextAreaElement>) => {
		propsOnMessageChange(event.target.value);
	}, [propsOnMessageChange]);
	
	const submitInput = useCallback(() => {
		propsOnMessageSubmit(propsMessage, propsAttachments);
	}, [propsOnMessageSubmit, propsMessage, propsAttachments]);
	
	const handleKeyPress = useCallback((event: React.KeyboardEvent<HTMLElement>) => {
		if(!event.shiftKey && event.key === "Enter") {
			event.preventDefault();
			submitInput();
		}
	}, [submitInput]);
	
	const handlePaste = useCallback((event: React.ClipboardEvent<HTMLElement>) => {
		propsOnAttachmentAdd(Array.from(event.clipboardData.files));
	}, [propsOnAttachmentAdd]);
	
	return (
		<div className={styles.root} style={{backgroundColor: colorBG}}>
			<Flipper flipKey={props.attachments.map(attachment => attachment.id).join(" ")}>
				{props.attachments.length > 0 &&
					<div className={styles.attachmentqueue}>
						{props.attachments.map((file) => {
							const queueData: QueuedAttachmentProps = {
								file: file.file,
								onRemove: () => props.onAttachmentRemove(file)
							};
							
							let component: React.ReactNode;
							if(file.file.type.startsWith("image/")) component = <QueuedAttachmentImage queueData={queueData} />;
							else component = <QueuedAttachmentGeneric queueData={queueData} />;
							
							return (<Flipped flipId={"attachmentqueue-" + file.id} key={file.id} onAppear={onAttachmentAppear} onExit={onAttachmentExit}>
								{component}
							</Flipped>);
						})}
					</div>
				}
				<div className={styles.control}>
					<InputBase className={styles.textfield} maxRows="5" multiline fullWidth autoFocus placeholder={props.placeholder} value={props.message} onChange={handleChange} onKeyPress={handleKeyPress} onPaste={handlePaste} />
					<IconButton size="small" color="primary" disabled={props.message.trim() === "" && props.attachments.length === 0} onClick={submitInput}><PushIcon /></IconButton>
				</div>
			</Flipper>
		</div>
	);
}
Example #24
Source File: CharacterCard.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
export default function CharacterCard({ characterKey, artifactChildren, weaponChildren, characterChildren, onClick, onClickHeader, footer, isTeammateCard }: CharacterCardProps) {
  const { teamData: teamDataContext } = useContext(DataContext)
  const teamData = useTeamData(teamDataContext ? "" : characterKey) ?? (teamDataContext as TeamData | undefined)
  const { character, characterSheet, target: data } = teamData?.[characterKey] ?? {}
  const onClickHandler = useCallback(() => characterKey && onClick?.(characterKey, "overview"), [characterKey, onClick])
  const actionWrapperFunc = useCallback(
    children => <CardActionArea onClick={onClickHandler} sx={{ flexGrow: 1, display: "flex", flexDirection: "column" }}>{children}</CardActionArea>,
    [onClickHandler],
  )
  const characterDispatch = useCharacterReducer(characterKey)
  if (!teamData || !character || !characterSheet || !data) return null;
  const dataContextObj: dataContextObj = {
    character,
    data,
    characterSheet,
    mainStatAssumptionLevel: 0,
    teamData,
    characterDispatch
  }

  return <Suspense fallback={<Skeleton variant="rectangular" sx={{ width: "100%", height: "100%", minHeight: 350 }} />}>
    <DataContext.Provider value={dataContextObj}>
      <CardLight sx={{ height: "100%", display: "flex", flexDirection: "column" }}>
        <Box sx={{ display: "flex", position: "absolute", zIndex: 2, opacity: 0.7 }}>
          <IconButton sx={{ p: 0.5 }} onClick={event => characterDispatch({ favorite: !character.favorite })}>
            {character.favorite ? <Favorite /> : <FavoriteBorder />}
          </IconButton>
        </Box>
        <ConditionalWrapper condition={!!onClick} wrapper={actionWrapperFunc} >
          <Header onClick={!onClick ? onClickHeader : undefined} />
          <CardContent sx={{ width: "100%", display: "flex", flexDirection: "column", gap: 1, flexGrow: 1 }}>
            <Artifacts />
            {!isTeammateCard && <Grid container columns={4} spacing={0.75}>
              <Grid item xs={1} height="100%">
                <WeaponCardPico weaponId={character.equippedWeapon} />
              </Grid>
              {range(0, 2).map(i => <Grid key={i} item xs={1} height="100%"><CharacterCardPico characterKey={character.team[i]} index={i} /></Grid>)}
            </Grid>}
            {isTeammateCard && <WeaponFullCard weaponId={character.equippedWeapon} />}
            {!isTeammateCard && <Stats />}
            {weaponChildren}
            {artifactChildren}
            {characterChildren}
          </CardContent>
        </ConditionalWrapper>
        {footer}
      </CardLight>
    </DataContext.Provider>
  </Suspense>
}
Example #25
Source File: CopyButton.tsx    From usehooks-ts with MIT License 5 votes vote down vote up
CopyButton = ({ value, classNames, hideText }: PropTypes) => {
  const [, setCopiedText] = useCopyToClipboard()
  const [open, setOpen] = useState(false)

  // Auto close tooltip
  useTimeout(() => setOpen(false), open ? 2000 : null)

  const handleCopy = () => setCopiedText(value).then(() => setOpen(true))

  return (
    <Tooltip
      PopperProps={{
        disablePortal: true,
      }}
      open={open}
      disableFocusListener
      disableHoverListener
      disableTouchListener
      title="Copied!"
    >
      {hideText ? (
        <IconButton
          aria-label="Copy"
          color="inherit"
          onClick={handleCopy}
          size="small"
          className={classNames}
        >
          <FileCopyIcon fontSize="small" />
        </IconButton>
      ) : (
        <Button
          color="inherit"
          onClick={handleCopy}
          size="small"
          startIcon={<FileCopyIcon />}
          className={classNames}
        >
          Copy
        </Button>
      )}
    </Tooltip>
  )
}
Example #26
Source File: ObjectManager.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
ObjectManager = ({ classes }: IObjectManager) => {
  const dispatch = useDispatch();

  const objects = useSelector(
    (state: AppState) => state.objectBrowser.objectManager.objectsToManage
  );
  const managerOpen = useSelector(
    (state: AppState) => state.objectBrowser.objectManager.managerOpen
  );
  return (
    <Fragment>
      {managerOpen && (
        <div
          className={`${classes.downloadContainer} ${
            managerOpen ? "open" : ""
          }`}
        >
          <div className={classes.cleanIcon}>
            <Tooltip title={"Clean Completed Objects"} placement="bottom-start">
              <IconButton
                aria-label={"Clear Completed List"}
                size={"small"}
                onClick={() => dispatch(cleanList())}
                className={classes.cleanButton}
              >
                <RemoveAllIcon />
              </IconButton>
            </Tooltip>
          </div>
          <div className={classes.title}>Downloads / Uploads</div>
          <div className={classes.actionsContainer}>
            {objects.map((object, key) => (
              <ObjectHandled
                objectToDisplay={object}
                key={`object-handled-${object.instanceID}`}
                deleteFromList={(instanceID) =>
                  dispatch(deleteFromList(instanceID))
                }
              />
            ))}
          </div>
        </div>
      )}
    </Fragment>
  );
}
Example #27
Source File: AppEditorShell.tsx    From mui-toolpad with MIT License 5 votes vote down vote up
export default function AppEditorShell({ appId, ...props }: ToolpadAppShellProps) {
  const domLoader = useDomLoader();

  const [createReleaseDialogOpen, setCreateReleaseDialogOpen] = React.useState(false);

  return (
    <ToolpadAppShell
      appId={appId}
      actions={
        <React.Fragment>
          {domLoader.saving ? (
            <Box display="flex" flexDirection="row" alignItems="center">
              <CircularProgress size={16} color="inherit" sx={{ mr: 1 }} />
            </Box>
          ) : null}
          <Typography>{domLoader.unsavedChanges} unsaved change(s).</Typography>
          <IconButton
            aria-label="Create release"
            color="inherit"
            sx={{ ml: 1 }}
            onClick={() => setCreateReleaseDialogOpen(true)}
          >
            <RocketLaunchIcon />
          </IconButton>
        </React.Fragment>
      }
      {...props}
    >
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'row',
          overflow: 'hidden',
          height: '100%',
        }}
      >
        <PagePanel
          appId={appId}
          sx={{
            width: 250,
            borderRight: 1,
            borderColor: 'divider',
          }}
        />
        <Box
          sx={{
            flex: 1,
            overflow: 'hidden',
            position: 'relative',
          }}
        >
          <Outlet />
        </Box>

        <CreateReleaseDialog
          appId={appId}
          open={createReleaseDialogOpen}
          onClose={() => setCreateReleaseDialogOpen(false)}
        />
      </Box>
    </ToolpadAppShell>
  );
}
Example #28
Source File: Dashboard.tsx    From NekoMaid with MIT License 5 votes vote down vote up
Players: React.FC<{ players?: CurrentStatus['players'] }> = React.memo(({ players }) => {
  const his = useHistory()
  const plugin = usePlugin()
  const globalData = useGlobalData()
  const [page, setPage] = useState(1)
  const [id, update] = useState(0)
  return <Card>
    <CardHeader title={lang.dashboard.onlinePlayers} />
    <Divider />
    <CardContent>
      {players?.length === 0
        ? <Empty />
        : <>
        <List sx={{ paddingTop: 0 }}>
          {players
            ? players.slice((page - 1) * 8, page * 8).map(p => {
              const name = typeof p === 'string' ? p : p.name
              return <Tooltip key={name} title={'IP: ' + ((p as any).ip || lang.unknown)}>
                <ListItem
                  secondaryAction={<>
                    <IconButton
                      edge='end'
                      size='small'
                      onClick={() => dialog(lang.dashboard.confirmKick(<span className='bold'>{name}</span>), lang.reason)
                        .then(it => it != null && plugin.emit('dashboard:kick', (res: boolean) => {
                          action(res)
                          if (!players) return
                          players.splice(players.indexOf(it!), 1)
                          update(id + 1)
                        }, name, it || null))
                      }
                    ><ExitToApp /></IconButton>
                    <IconButton edge='end' onClick={() => his.push('/NekoMaid/playerList/' + name)} size='small'><MoreHoriz /></IconButton>
                  </>
                  }
                >
                  <ListItemAvatar>
                    <Avatar
                      src={getSkin(globalData, name, true)}
                      imgProps={{ crossOrigin: 'anonymous', onClick () { his.push('/NekoMaid/playerList/' + name) }, style: { width: 40, height: 40 } }}
                      sx={{ cursor: 'pointer' }}
                      variant='rounded'
                    />
                  </ListItemAvatar>
                  <ListItemText primary={name} />
                </ListItem>
              </Tooltip>
            })
            : <LoadingList />
          }
        </List>
        {players && <Pagination
          page={page}
          onChange={(_, it) => setPage(it)}
          count={Math.max(Math.ceil(players.length / 8), 1)}
          sx={{ display: 'flex', justifyContent: 'flex-end' }}
        />}
      </>}
    </CardContent>
  </Card>
})
Example #29
Source File: SampleApp.tsx    From firecms with MIT License 4 votes vote down vote up
function SampleApp() {

    const localeCollection: EntityCollection<Locale> =
        buildCollection({
            name: "Locales",
            path: "locales",
            schema: localeSchema,
            defaultSize: "m"
        });

    const productsCollection = buildCollection<Product>({
        path: "products",
        schema: productSchema,
        // inlineEditing: false,
        callbacks: productCallbacks,
        name: "Products",
        group: "Main",
        description: "List of the products currently sold in our shop",
        textSearchEnabled: true,
        additionalColumns: [productAdditionalColumn],
        filterCombinations: [
            { category: "desc", currency: "asc" },
            { category: "desc", currency: "desc" },
            { category: "asc", currency: "asc" },
            { category: "asc", currency: "desc" }
        ],
        permissions: ({ authController }) => ({
            edit: true,
            create: true,
            // we use some custom logic by storing user data in the `extra`
            // field of the user
            delete: authController.extra?.roles.includes("admin")
        }),
        extraActions: productExtraActionBuilder,
        subcollections: [localeCollection],
        excludedProperties: ["images"]
    });

    const usersCollection = buildCollection({
        path: "users",
        schema: usersSchema,
        name: "Users",
        group: "Main",
        description: "Registered users",
        textSearchEnabled: true,
        additionalColumns: [
            {
                id: "sample_additional",
                title: "Sample additional",
                builder: ({entity}) => `Generated column: ${entity.values.first_name}`,
                dependencies: ["first_name"]
            }
        ],
        properties: ["first_name", "last_name", "email", "liked_products", "picture", "phone", "sample_additional"]
    });

    const blogCollection = buildCollection({
        path: "blog",
        schema: blogSchema,
        name: "Blog",
        group: "Content",
        exportable: {
            additionalColumns: [sampleAdditionalExportColumn]
        },
        defaultSize: "l",
        properties: ["name", "header_image", "status", "content", "reviewed", "gold_text"],
        description: "Collection of blog entries included in our [awesome blog](https://www.google.com)",
        textSearchEnabled: true,
        initialFilter: {
            "status": ["==", "published"]
        }
    });

    const testCollection = buildCollection({
        path: "test_entity",
        schema: testEntitySchema,
        callbacks: testCallbacks,
        name: "Test entity",
        permissions: ({ authController }) => ({
            edit: false,
            create: false,
        }),
        additionalColumns: [
            {
                id: "full_name",
                title: "Full Name",
                builder: ({entity}) => {
                    let values = entity.values;
                    return typeof values.name === "string" ? values.name.toUpperCase() : "Nope";
                },
                dependencies: ["name"]
            }
            ]
    });

    const githubLink = (
        <Tooltip
            title="See this project on GitHub. This button is only present in this demo">
            <IconButton
                href={"https://github.com/Camberi/firecms"}
                rel="noopener noreferrer"
                target="_blank"
                component={"a"}
                size="large">
                <GitHub/>
            </IconButton>
        </Tooltip>
    );

    const customViews: CMSView[] = [{
        path: ["additional", "additional/:id"],
        name: "Additional",
        group: "Content",
        description: "This is an example of an additional view that is defined by the user",
        view: <ExampleCMSView path={"users"} collection={usersCollection}/>
    }];


    const onFirebaseInit = (config: Object) => {
        // Just calling analytics enables screen tracking
        getAnalytics();
    };

    const myAuthenticator: Authenticator<FirebaseUser> = async ({
                                                                    user,
                                                                    authController
                                                                }) => {

        if(user?.email?.includes("flanders")){
            throw Error("Stupid Flanders!");
        }

        // This is an example of retrieving async data related to the user
        // and storing it in the user extra field
        const sampleUserData = await Promise.resolve({
            roles: ["admin"]
        });

        authController.setExtra(sampleUserData);
        console.log("Allowing access to", user);
        return true;
    };

    const navigation: NavigationBuilder<FirebaseUser> = async ({
                                                                   user,
                                                                   authController
                                                               }: NavigationBuilderProps) => {
        if (authController.extra)
            console.log("Custom data stored in the authController", authController.extra);

        const navigation: Navigation = {
            collections: [
                productsCollection,
                usersCollection,
                blogCollection
            ],
            views: customViews
        };

        if (process.env.NODE_ENV !== "production") {
            navigation.collections.push(buildCollection(testCollection));
        }

        return navigation;
    };

    return <FirebaseCMSApp
        name={"My Online Shop"}
        authentication={myAuthenticator}
        signInOptions={[
            'password',
            'google.com',
            // 'phone',
            // 'anonymous',
            // 'facebook.com',
            // 'github.com',
            // 'twitter.com',
            // 'microsoft.com',
            // 'apple.com'
        ]}
        textSearchController={textSearchController}
        allowSkipLogin={true}
        logo={logo}
        navigation={navigation}
        schemaOverrideHandler={customSchemaOverrideHandler}
        firebaseConfig={firebaseConfig}
        onFirebaseInit={onFirebaseInit}
        toolbarExtraWidget={githubLink}
        LoginViewProps={{
            NoUserComponent: <>Sample custom message when no user exists</>,
            disableSignupScreen: false,
        }}
    />;
}