@material-ui/core#ButtonBase TypeScript Examples
The following examples show how to use
@material-ui/core#ButtonBase.
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: ActionButton.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
ActionButton = styled(ButtonBase).attrs({ disableRipple: true })`
${buttonBaseStyle};
background-color: ${({ theme }) => theme.actionButton.backgroundColor};
&:hover {
background-color: ${({ theme }) => theme.actionButton.backgroundHoverColor};
}
&:active {
${({ theme }) =>
pressed({
color: theme.actionButton.backgroundHoverColor,
backgroundColor: theme.actionButton.backgroundHoverColor,
distance: 1,
intensity: theme.intensity,
})};
}
&:disabled,
&[aria-disabled='true'] {
opacity: 0.3;
}
`
Example #2
Source File: BarChartSteps.tsx From backstage with Apache License 2.0 | 6 votes |
BarChartSteps = ({
steps,
activeStep,
onClick,
}: BarChartStepsProps) => {
const classes = useStyles();
const handleOnClick =
(index: number) =>
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.preventDefault();
onClick(index);
};
return (
<div className={classes.steps}>
{[...new Array(steps)].map((_, index) => (
<ButtonBase key={index} centerRipple onClick={handleOnClick(index)}>
<div
data-testid="bar-chart-step"
className={`${classes.step} ${
index === activeStep ? classes.stepActive : ''
}`}
/>
</ButtonBase>
))}
</div>
);
}
Example #3
Source File: BarChartStepperButton.tsx From backstage with Apache License 2.0 | 6 votes |
BarChartStepperButton = forwardRef(
(
{
name,
children,
...buttonBaseProps
}: PropsWithChildren<BarChartStepperButtonProps>,
ref: Ref<HTMLButtonElement>,
) => {
const classes = useStyles();
return (
<ButtonBase
ref={ref}
classes={classes}
disableRipple
data-testid={`bar-chart-stepper-button-${name}`}
{...buttonBaseProps}
>
{children}
</ButtonBase>
);
},
)
Example #4
Source File: InlineCell.tsx From firetable with Apache License 2.0 | 6 votes |
SingleSelect = React.forwardRef(function SingleSelect(
{ value, showPopoverCell, disabled }: IPopoverInlineCellProps,
ref: React.Ref<any>
) {
const classes = useStyles();
return (
<ButtonBase
className={clsx("cell-collapse-padding", classes.root)}
onClick={() => showPopoverCell(true)}
ref={ref}
disabled={disabled}
>
<div className={classes.value}>{sanitiseValue(value)}</div>
<ArrowDropDownIcon
className={clsx(classes.icon, disabled && classes.disabled)}
/>
</ButtonBase>
);
})
Example #5
Source File: InlineCell.tsx From firetable with Apache License 2.0 | 6 votes |
ConnectService = React.forwardRef(function ConnectService(
{ value, showPopoverCell, disabled, column }: IPopoverInlineCellProps,
ref: React.Ref<any>
) {
const classes = useStyles();
const config = column.config ?? {};
return (
<ButtonBase
className={clsx("cell-collapse-padding", classes.root)}
onClick={() => showPopoverCell(true)}
ref={ref}
disabled={disabled}
>
<Grid
container
wrap="nowrap"
alignItems="center"
spacing={1}
className={classes.value}
>
{Array.isArray(value) &&
value.map((doc: any) => (
<Grid item key={doc.primaryKey}>
<Chip
label={config.titleKey}
className={classes.chip}
size="small"
/>
</Grid>
))}
</Grid>
<ArrowDropDownIcon
className={clsx(classes.icon, disabled && classes.disabled)}
/>
</ButtonBase>
);
})
Example #6
Source File: InlineCell.tsx From firetable with Apache License 2.0 | 6 votes |
Color = React.forwardRef(function Color(
{ value, showPopoverCell, disabled }: IPopoverInlineCellProps,
ref: React.Ref<any>
) {
const classes = useStyles();
return (
<Grid
container
alignItems="center"
spacing={1}
className={clsx("cell-collapse-padding", classes.root)}
component={ButtonBase}
onClick={() => showPopoverCell(true)}
ref={ref}
disabled={disabled}
>
<Grid item>
<div
className={classes.colorIndicator}
style={{ backgroundColor: value?.hex }}
/>
</Grid>
<Grid item xs>
{value?.hex}
</Grid>
</Grid>
);
})
Example #7
Source File: TextButton.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
TextButton = styled(ButtonBase).attrs({ disableRipple: true })`
${buttonBaseStyle};
color: ${({ theme }) => theme.textButton.textColor};
${({ theme }) =>
flat({
color: theme.sectionBackgroundColor,
distance: 0.1,
intensity: theme.intensity,
})};
&:hover {
${({ theme }) =>
flat({
color: theme.sectionBackgroundColor,
distance: 1,
intensity: theme.intensity,
})};
background-color: ${({ theme }) => theme.hoverBackgroundColor};
}
&:active {
${({ theme }) =>
pressed({
color: theme.sectionBackgroundColor,
distance: 1,
intensity: theme.intensity,
})};
background-color: ${({ theme }) => theme.hoverBackgroundColor};
}
&:disabled {
color: ${({ theme }) => c(theme.textButton.textColor).alpha(0.3).string()};
}
`
Example #8
Source File: FlatButton.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
FlatButton = styled(ButtonBase).attrs({ disableRipple: true })`
${buttonBaseStyle};
background-color: ${({ theme }) => theme.actionButton.backgroundColor};
&:hover {
background-color: ${({ theme }) => theme.actionButton.backgroundHoverColor};
}
&:disabled {
opacity: 0.3;
}
`
Example #9
Source File: BorderButton.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
BorderButton = styled(ButtonBase).attrs({ disableRipple: true })`
${buttonBaseStyle};
color: ${({ theme }) => theme.borderButton.textColor};
border: 1px solid ${({ theme }) => theme.borderButton.borderColor};
&:hover {
border: 1px solid ${({ theme }) => theme.borderButton.borderHoverColor};
background-color: ${({ theme }) => theme.hoverBackgroundColor};
color: ${({ theme }) => theme.borderButton.hoverTextColor};
}
&:disabled {
opacity: 0.3;
}
`
Example #10
Source File: EmbossButton.tsx From anchor-web-app with Apache License 2.0 | 6 votes |
EmbossButton = styled(ButtonBase).attrs({ disableRipple: true })`
${buttonBaseStyle};
border-radius: 5px;
color: ${({ theme }) => theme.textColor};
${({ theme }) =>
flat({
color: theme.selector.backgroundColor,
backgroundColor: theme.backgroundColor,
distance: 1,
intensity: theme.intensity,
})};
&:active {
${({ theme }) =>
pressed({
color: theme.selector.backgroundColor,
backgroundColor: theme.backgroundColor,
distance: 1,
intensity: theme.intensity,
})};
}
&:disabled {
opacity: 0.3;
}
`
Example #11
Source File: MenuAction.tsx From parity-bridges-ui with GNU General Public License v3.0 | 5 votes |
MenuAction = ({ actions, changeMenu, action }: MenuActionProps) => {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
const [id, setId] = React.useState<string | undefined>(undefined);
const [open, setOpen] = React.useState<boolean>(false);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
setOpen(!open);
};
useEffect(() => {
setOpen(Boolean(anchorEl));
setId(anchorEl ? 'simple-popover' : undefined);
}, [anchorEl]);
const item = actions.find(({ type }) => type === action);
return (
<>
<ButtonBase className={`${classes.item} current`} onClick={handleClick}>
{item?.title || '-'}
<ArrowDropDownIcon />
</ButtonBase>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={() => setOpen(false)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right'
}}
transformOrigin={{
vertical: 'top',
horizontal: 24
}}
PaperProps={{
className: classes.menu
}}
>
{actions.map((i, n) => (
<ButtonBase
className={`${classes.item} ${!i.isEnabled && 'disabled'}`}
key={n}
onClick={() => {
setOpen(!open);
changeMenu(i.type);
}}
>
{i.title}
</ButtonBase>
))}
</Popover>
</>
);
}
Example #12
Source File: index.tsx From uno-game with MIT License | 5 votes |
ChooseColorModal: ChooseColorModalType & React.FC<ChooseColorModalProps> = (props) => {
const classes = useStyles()
const { callback } = props
const [opened, setOpened] = useState(true)
const handleClose = (color: CardColors) => {
callback(color)
setOpened(false)
}
return (
<ThemeProvider theme={theme}>
<Dialog
open={opened}
className={classes.dialog}
PaperProps={{
className: classes.dialogPaper,
}}
>
<Grid
container
alignItems="center"
justify="center"
direction="column"
className={classes.dialogContainer}
>
<Grid
container
justify="center"
>
<img
src={chooseColorTextImg}
alt="Choose a color!"
className={classes.chooseColorImg}
/>
</Grid>
<Divider orientation="horizontal" size={5} />
<Grid
container
alignItems="center"
justify="center"
wrap="wrap"
className={classes.colorSelectorContainer}
>
{Object.entries(coloredButtonMap)
.map(([colorName, info]) => (
<Grid
className={classes.colorSelectorButton}
component={ButtonBase}
style={{
backgroundColor: info?.color,
border: `8px solid ${info?.borderColor}`,
boxShadow: `0 0 16px ${info?.color}`,
}}
onClick={() => handleClose(colorName as CardColors)}
/>
))}
</Grid>
</Grid>
</Dialog>
</ThemeProvider>
)
}
Example #13
Source File: SideDrawerField.tsx From firetable with Apache License 2.0 | 5 votes |
export default function Checkbox({
column,
control,
disabled,
}: ISideDrawerFieldProps) {
const classes = useStyles();
const fieldClasses = useFieldStyles();
const switchClasses = useSwitchStyles();
return (
<Controller
control={control}
name={column.key}
render={({ onChange, onBlur, value }) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.checked);
};
return (
<ButtonBase
className={clsx(fieldClasses.root, classes.root)}
disabled={disabled}
>
<FormControlLabel
control={
<Switch
checked={value}
onChange={handleChange}
onBlur={onBlur}
disabled={disabled}
classes={switchClasses}
/>
}
label={column.name}
labelPlacement="start"
classes={{ root: classes.formControlLabel, label: classes.label }}
/>
</ButtonBase>
);
}}
/>
);
}
Example #14
Source File: SideDrawerField.tsx From firetable with Apache License 2.0 | 5 votes |
export default function Color({
column,
control,
disabled,
}: ISideDrawerFieldProps) {
const classes = useStyles();
const fieldClasses = useFieldStyles();
const [showPicker, setShowPicker] = useState(false);
const toggleOpen = () => setShowPicker((s) => !s);
return (
<Controller
control={control}
name={column.key}
render={({ onChange, onBlur, value }) => (
<>
<Grid
container
alignItems="center"
spacing={1}
className={classes.root}
onClick={() => {
toggleOpen();
onBlur();
}}
component={ButtonBase}
focusRipple
disabled={disabled}
>
<Grid item>
<div
className={classes.colorIndicator}
style={{ backgroundColor: value?.hex }}
/>
</Grid>
<Grid item xs>
<Typography
variant="body1"
color={value?.hex ? "textPrimary" : "textSecondary"}
>
{value?.hex ?? "Choose a color…"}
</Typography>
</Grid>
</Grid>
<Collapse in={showPicker}>
<ChromePicker color={value?.rgb} onChangeComplete={onChange} />
</Collapse>
</>
)}
/>
);
}
Example #15
Source File: InlineCell.tsx From firetable with Apache License 2.0 | 5 votes |
ConnectTable = React.forwardRef(function ConnectTable(
{ value, showPopoverCell, disabled, column }: IPopoverInlineCellProps,
ref: React.Ref<any>
) {
const classes = useStyles();
const config = column.config ?? {};
return (
<ButtonBase
className={clsx("cell-collapse-padding", classes.root)}
onClick={() => showPopoverCell(true)}
ref={ref}
disabled={disabled}
>
<Grid
container
wrap="nowrap"
alignItems="center"
spacing={1}
className={classes.value}
>
{Array.isArray(value) &&
value.map((doc: any) => (
<Grid item key={doc.docPath}>
<Chip
label={config.primaryKeys
.map((key: string) => doc.snapshot[key])
.join(" ")}
size="small"
className={classes.chip}
/>
</Grid>
))}
</Grid>
<ArrowDropDownIcon
className={clsx(classes.icon, disabled && classes.disabled)}
/>
</ButtonBase>
);
})
Example #16
Source File: InlineCell.tsx From firetable with Apache License 2.0 | 5 votes |
MultiSelect = React.forwardRef(function MultiSelect(
{ value, showPopoverCell, disabled, onSubmit }: IPopoverInlineCellProps,
ref: React.Ref<any>
) {
const classes = useStyles();
if (typeof value === "string" && value !== "")
return <ConvertStringToArray value={value} onSubmit={onSubmit} />;
return (
<ButtonBase
className={clsx("cell-collapse-padding", classes.root)}
onClick={() => showPopoverCell(true)}
ref={ref}
disabled={disabled}
>
<Grid
container
wrap="nowrap"
alignItems="center"
spacing={1}
className={classes.value}
>
{sanitiseValue(value).map(
(item) =>
typeof item === "string" && (
<Grid item key={item}>
<FormattedChip
label={item}
classes={{ root: classes.chip, label: classes.chipLabel }}
/>
</Grid>
)
)}
</Grid>
<ArrowDropDownIcon
className={clsx(classes.icon, disabled && classes.disabled)}
/>
</ButtonBase>
);
})
Example #17
Source File: SideDrawerField.tsx From firetable with Apache License 2.0 | 4 votes |
function ControlledImageUploader({
onChange,
value,
column,
docRef,
disabled,
}) {
const classes = useStyles();
const fieldClasses = useFieldStyles();
const { updateCell } = useFiretableContext();
const { requestConfirmation } = useConfirmation();
const { uploaderState, upload, deleteUpload } = useUploader();
const { progress } = uploaderState;
// Store a preview image locally while uploading
const [localImage, setLocalImage] = useState<string>("");
const onDrop = useCallback(
(acceptedFiles) => {
const imageFile = acceptedFiles[0];
if (docRef && imageFile) {
upload({
docRef,
fieldName: column.key,
files: [imageFile],
previousValue: value ?? [],
onComplete: (newValue) => {
if (updateCell) updateCell(docRef, column.key, newValue);
onChange(newValue);
setLocalImage("");
},
});
setLocalImage(URL.createObjectURL(imageFile));
}
},
[docRef, value]
);
const handleDelete = (index: number) => {
const newValue = [...value];
const toBeDeleted = newValue.splice(index, 1);
toBeDeleted.length && deleteUpload(toBeDeleted[0]);
onChange(newValue);
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
multiple: false,
accept: IMAGE_MIME_TYPES,
});
return (
<>
{!disabled && (
<ButtonBase
className={clsx(
fieldClasses.root,
classes.dropzoneButton,
isDragActive && classes.dropzoneDragActive
)}
{...getRootProps()}
>
<input id={`sidedrawer-field-${column.key}`} {...getInputProps()} />
<AddIcon />
<Typography variant="body1" color="inherit">
{isDragActive ? "Drop your image here" : "Upload image"}
</Typography>
</ButtonBase>
)}
<Grid container spacing={1} className={classes.imagesContainer}>
{Array.isArray(value) &&
value.map((image, i) => (
<Grid item key={image.downloadURL}>
{disabled ? (
<Tooltip title="Click to open">
<ButtonBase
className={classes.img}
onClick={() => window.open(image.downloadURL, "_blank")}
>
<Thumbnail
imageUrl={image.downloadURL}
size="200x200"
objectFit="contain"
className={classes.thumbnail}
/>
<Grid
container
justify="center"
alignItems="center"
className={clsx(classes.overlay, classes.deleteImgHover)}
>
{disabled ? <OpenIcon /> : <DeleteIcon color="inherit" />}
</Grid>
</ButtonBase>
</Tooltip>
) : (
<Tooltip title="Click to delete">
<div>
<ButtonBase
className={classes.img}
onClick={() =>
requestConfirmation({
title: "Delete Image",
body: "Are you sure you want to delete this image?",
confirm: "Delete",
handleConfirm: () => handleDelete(i),
})
}
>
<Thumbnail
imageUrl={image.downloadURL}
size="200x200"
objectFit="contain"
className={classes.thumbnail}
/>
<Grid
container
justify="center"
alignItems="center"
className={clsx(
classes.overlay,
classes.deleteImgHover
)}
>
<DeleteIcon color="inherit" />
</Grid>
</ButtonBase>
</div>
</Tooltip>
)}
</Grid>
))}
{localImage && (
<Grid item>
<ButtonBase
className={classes.img}
style={{ backgroundImage: `url("${localImage}")` }}
>
<Grid
container
justify="center"
alignItems="center"
className={classes.overlay}
>
<CircularProgress
color="inherit"
size={48}
variant={progress === 0 ? "indeterminate" : "static"}
value={progress}
/>
</Grid>
</ButtonBase>
</Grid>
)}
</Grid>
</>
);
}
Example #18
Source File: NoteCard.tsx From vscode-crossnote with GNU Affero General Public License v3.0 | 4 votes |
export default function NoteCard(props: Props) {
const classes = useStyles(props);
const note = props.note;
const [header, setHeader] = useState<string>("");
const [summary, setSummary] = useState<Summary>(null);
const [images, setImages] = useState<string[]>([]);
const { t } = useTranslation();
const duration = formatDistanceStrict(note.config.modifiedAt, Date.now())
.replace(/\sseconds?/, "s")
.replace(/\sminutes?/, "m")
.replace(/\shours?/, "h")
.replace(/\sdays?/, "d")
.replace(/\sweeks?/, "w")
.replace(/\smonths?/, "mo")
.replace(/\syears?/, "y");
const openNote = useCallback(() => {
if (!note) {
return;
}
const message: Message = {
action: MessageAction.OpenNote,
data: note,
};
vscode.postMessage(message);
props.setSelectedNote(note);
}, [note, props.setSelectedNote]);
useEffect(() => {
setHeader(
(note.config.encryption && note.config.encryption.title) ||
getHeaderFromMarkdown(note.markdown)
);
generateSummaryFromMarkdown(
note.config.encryption
? `? ${t("general/encrypted")}`
: note.markdown.trim() || t("general/this-note-is-empty")
)
.then((summary) => {
setSummary(summary);
// render images
const images = summary.images
.map((image) => {
return resolveNoteImageSrc(note, image);
})
.filter((x) => x)
.slice(0, 3); // TODO: Support local image
setImages(images);
})
.catch((error) => {});
}, [note.markdown, note.config.encryption, t]);
/*
useEffect(() => {
crossnoteContainer.crossnote.getStatus(note).then((status) => {
setGitStatus(status);
});
}, [
note.markdown,
note.config.modifiedAt,
note,
crossnoteContainer.crossnote,
]);
*/
return (
<ButtonBase
className={clsx(
classes.noteCard,
props.selectedNote &&
props.selectedNote.filePath === note.filePath &&
props.selectedNote.notebookPath === note.notebookPath
? classes.selected
: classes.unselected
)}
onClick={openNote}
>
<Box className={clsx(classes.leftPanel)}>
<Tooltip
title={
<>
<p>
{t("general/created-at") +
" " +
formatRelative(new Date(note.config.createdAt), new Date())}
</p>
<p>
{t("general/modified-at") +
" " +
formatRelative(new Date(note.config.modifiedAt), new Date())}
</p>
</>
}
arrow
>
<Typography className={clsx(classes.duration)}>{duration}</Typography>
</Tooltip>
{note.config.pinned && <Pin className={clsx(classes.pin)}></Pin>}
</Box>
<Box className={clsx(classes.rightPanel)}>
{header && (
<Typography
style={{ fontWeight: "bold" }}
variant={"body1"}
className={clsx(classes.header)}
>
{header}
</Typography>
)}
{summary && summary.summary.trim().length > 0 && (
<Typography className={clsx(classes.summary)}>
{summary && summary.summary}
</Typography>
)}
{images.length > 0 && (
<Box className={clsx(classes.images)}>
<Box className={clsx(classes.imagesWrapper)}>
{images.map((image, offset) => (
<div
key={`${image}-${offset}`}
className={clsx(classes.image)}
style={{
backgroundImage: `url(${image})`,
}}
></div>
))}
</Box>
</Box>
)}
<Typography variant={"caption"} className={clsx(classes.filePath)}>
{basename(note.filePath).startsWith("unnamed_") ? "" : note.filePath}
</Typography>
</Box>
</ButtonBase>
);
}
Example #19
Source File: tictactoe.tsx From Figurify with Apache License 2.0 | 4 votes |
export function TicTacToe(props: { size: number, onBoardChange: (x: number[][]) => void, onPlayerChange: (x: number) => void }) { // 0 = None // 1 = P1 // 2 = P2 const [board, setBoard] = useState(Array.from({length: props.size}, () => Array.from({length: props.size}, () => 0 ) ) as number[][]); const [current, setCurrent] = useState(1); const [ended, setEnded] = useState(false); function winningConditions(): number[][] { return props.size === 3 ? [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] : props.size === 4 ? [ [0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [0, 4, 8, 12], [1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15], [0, 5, 10, 15], [3, 6, 9, 12] ] : []; } useEffect(() => { props.onBoardChange(board); props.onPlayerChange(current); (() => { if (board.flat().filter(x => x === 0).length == 0) setEnded(null); let roundWon = false; let bo = board.flat(); for (let i = 0; i < winningConditions().length; i++) { const winCondition = winningConditions()[i]; let a = bo[winCondition[0]]; let b = bo[winCondition[1]]; let c = bo[winCondition[2]]; let d = props.size === 4 ? bo[winCondition[3]] : c; if (a === 0 || b === 0 || c === 0 || d == 0) { continue; } if (a === b && b === c && c == d && d == a) { roundWon = true; break; } } if (roundWon) { setEnded(true); } })(); }, [board]); return <div> { board.map( (x, row) => { let cols = x.map( (y, col) => ( <Grid key={col} item> <Tooltip title={"#" + String(props.size * row + col + 1)} arrow={true}> <ButtonBase style={{...noBorder, margin: "1vw"}} > <Paper onClick={() => { if (board[row][col] !== 0 || ended) return; let k = {...board}; k[row][col] = current; setBoard(Object.values(k) as unknown as number[][]); setCurrent(current ^ 3); // 1 -> 2, 2 -> 1 }} elevation={4} data-coord={row + ':' + col} style={{width: "6vw", height: "6vw", padding: "0.25vw"}} > <div> {[ <Typography variant={"h5"} style={{fontSize: "3vw", marginTop: "1.55vw"}}> {"#" + String(props.size * row + col + 1)} </Typography>, <FilterVintageIcon style={{fontSize: "5vw", marginTop: "0.25vw"}}/>, <StarsIcon style={{fontSize: "5vw", marginTop: "0.25vw"}}/> ][y]} </div> </Paper> </ButtonBase> </Tooltip> </Grid> ) ); return <Grid key={row} container justify="center" //spacing={4} > {cols} </Grid>; } ) as JSX.Element[] } <div className="text-center"> <br/> <br/> <Typography variant={"h5"}> { ended === null ? "Draw!" : ended === true ? <> Player {[ " ", <FilterVintageIcon style={{fontSize: "2vw"}}/>, <StarsIcon style={{fontSize: "2vw"}}/> ][current ^ 3]} Won! </> : <> Player {[ " ", <FilterVintageIcon style={{fontSize: "2vw"}}/>, <StarsIcon style={{fontSize: "2vw"}}/> ][current]}'s turn </> } <Tooltip title={"Reset Board"}> <IconButton style={{...noBorder}} onClick={() => { setBoard(Array.from({length: props.size}, () => Array.from({length: props.size}, () => 0 ))); setCurrent(1); setEnded(false); }}> <RotateLeftIcon/> </IconButton> </Tooltip> </Typography> </div> </div>; }
Example #20
Source File: ModTableRow.tsx From ow-mod-manager with MIT License | 4 votes |
ModTableRow: React.FunctionComponent<Props> = ({ mod }) => {
const styles = useStyles();
const theme = useTheme();
const missingDependencyNames = useRecoilValue(missingDependencyIdsState(mod));
const isModOutdated = isOutdated(mod);
const isModBroken = isBroken(mod);
const addonMods = useRecoilValue(addonModList);
const [isAddonsExpanded, setIsAddonsExpanded] = useState(false);
const isAddon = mod.parent && !mod.localVersion;
const enabledMods = useRecoilValue(enabledModList);
const forceExpandAddons = useRecoilValue(isFiltering);
const shouldExpandAddons = forceExpandAddons || isAddonsExpanded;
const rowRef = useRef<HTMLTableRowElement>(null);
const isLoading = useRecoilValue(modIsLoadingState(mod.uniqueName));
useEffect(() => {
if (!isLoading || !rowRef.current) return;
rowRef.current.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest',
});
}, [isLoading]);
const addons = useMemo(
() => addonMods.filter((addon) => addon.parent === mod.uniqueName),
[addonMods, mod.uniqueName]
);
const conflictingMods = useMemo(
() =>
mod.conflicts && mod.conflicts.length > 0
? enabledMods
.filter((enabledMod) =>
mod.conflicts?.includes(enabledMod.uniqueName)
)
.map((enabledMod) => enabledMod.name)
: [],
[enabledMods, mod.conflicts]
);
const isModConflicting = mod.isEnabled && conflictingMods.length > 0;
const handleExpandClick = () =>
setIsAddonsExpanded((isExpanded) => !isExpanded);
const getVersionColor = () => {
if (isModBroken) {
return 'default';
}
if (isModOutdated) {
return 'secondary';
}
if (isInstalled(mod)) {
return 'primary';
}
return 'default';
};
const getVersion = () => {
if (isInstalled(mod)) {
return mod.localVersion;
}
if (mod.remoteVersion) {
return mod.remoteVersion;
}
return modsText.versionNotAvailable;
};
const getClassName = () => {
let className = styles.tableRow;
if (isModBroken || isModConflicting) {
className += ` ${styles.brokenRow}`;
} else if (isLoading) {
className += ` ${styles.loading}`;
} else if (missingDependencyNames.length > 0) {
className += ` ${styles.missingDependencyRow}`;
} else if (isAddon) {
className += ` ${styles.addonRow}`;
}
return className;
};
const getModText = () => {
if (isModBroken) {
return modsText.modLoadError(mod.errors);
}
if (missingDependencyNames.length > 0) {
return modsText.missingDependencyWarning(
missingDependencyNames.join(', ')
);
}
if (isModConflicting) {
return modsText.conflictingModWarning(conflictingMods.join(', '));
}
return mod.description;
};
return (
<>
<TableRow className={getClassName()} key={mod.uniqueName} ref={rowRef}>
<TableCell className={styles.tableCell}>
<Box display="flex">
{isAddon && (
<Box
bgcolor={theme.palette.background.paper}
width="8px"
minWidth="8px"
marginRight={2}
marginLeft={1}
borderRadius="8px"
/>
)}
<Box width="100%">
<Typography variant="subtitle1">
<Box display="inline-block" mr={2}>
{mod.name}
</Box>
<Typography className={styles.modAuthor} variant="caption">
{' by '}
{mod.author}
</Typography>
<Typography variant="caption" />
</Typography>
<Box
color={
isModBroken || isModConflicting
? theme.palette.secondary.light
: theme.palette.text.secondary
}
>
<Typography className={styles.modText} variant="caption">
{getModText()}
</Typography>
</Box>
{addons.length > 0 && !forceExpandAddons && (
<ButtonBase
className={styles.addonExpander}
onClick={handleExpandClick}
>
<Box
display="flex"
alignItems="center"
borderRadius={theme.shape.borderRadius}
maxWidth="100%"
>
{shouldExpandAddons ? <ExpandLess /> : <ExpandMore />}
<Typography variant="caption" noWrap>
{addons.length}
{' addons available: '}
{addons.map((addon) => addon.name).join(', ')}
</Typography>
</Box>
</ButtonBase>
)}
</Box>
</Box>
</TableCell>
<TableCell className={styles.tableCell} align="right">
{mod.downloadCount || '-'}
</TableCell>
<TableCell className={styles.tableCell}>
<Chip
color={getVersionColor()}
label={getVersion()}
className={styles.versionChip}
/>
{!isModBroken && isModOutdated && (
<div className={styles.outdatedChip}>{modsText.outdated}</div>
)}
</TableCell>
<TableCell className={styles.tableCell}>
<ModActions mod={mod} />
</TableCell>
</TableRow>
{shouldExpandAddons &&
addons.map((addon) => (
<ModTableRow key={addon.uniqueName} mod={addon} />
))}
</>
);
}
Example #21
Source File: TableCell.tsx From firetable with Apache License 2.0 | 4 votes |
export default function Image_({
column,
row,
value,
onSubmit,
disabled,
}: IHeavyCellProps) {
const { tableState, updateCell } = useFiretableContext();
const { requestConfirmation } = useConfirmation();
const classes = useStyles({ rowHeight: tableState?.config?.rowHeight ?? 44 });
const { uploaderState, upload, deleteUpload } = useUploader();
const { progress, isLoading } = uploaderState;
// Store a preview image locally while uploading
const [localImage, setLocalImage] = useState<string>("");
const onDrop = useCallback(
(acceptedFiles) => {
const imageFile = acceptedFiles[0];
if (imageFile) {
upload({
docRef: row.ref,
fieldName: column.key as string,
files: [imageFile],
previousValue: value,
onComplete: (newValue) => {
if (updateCell) updateCell(row.ref, column.key, newValue);
setLocalImage("");
},
});
setLocalImage(URL.createObjectURL(imageFile));
}
},
[value]
);
const handleDelete = (ref: string) => () => {
const newValue = [...value];
const index = _findIndex(newValue, ["ref", ref]);
const toBeDeleted = newValue.splice(index, 1);
toBeDeleted.length && deleteUpload(toBeDeleted[0]);
onSubmit(newValue);
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
multiple: false,
accept: IMAGE_MIME_TYPES,
});
const dropzoneProps = getRootProps();
let thumbnailSize = "100x100";
if (tableState?.config?.rowHeight) {
if (tableState!.config!.rowHeight! > 50) thumbnailSize = "200x200";
if (tableState!.config!.rowHeight! > 100) thumbnailSize = "400x400";
}
return (
<Grid
container
className={clsx(
"cell-collapse-padding",
classes.root,
isDragActive && classes.dragActive
)}
wrap="nowrap"
alignItems="center"
spacing={1}
{...dropzoneProps}
onClick={undefined}
>
<input {...getInputProps()} />
<Grid item xs className={classes.imglistContainer}>
<Grid container spacing={1} wrap="nowrap">
{Array.isArray(value) &&
value.map((file: FileValue) => (
<Grid item key={file.downloadURL}>
{disabled ? (
<Tooltip title="Click to open">
<ButtonBase
className={classes.img}
onClick={() => window.open(file.downloadURL, "_blank")}
>
<Thumbnail
imageUrl={file.downloadURL}
size={thumbnailSize}
objectFit="contain"
className={classes.thumbnail}
/>
<Grid
container
justify="center"
alignItems="center"
className={classes.deleteImgHover}
>
{disabled ? (
<OpenIcon />
) : (
<DeleteIcon color="inherit" />
)}
</Grid>
</ButtonBase>
</Tooltip>
) : (
<Tooltip title="Click to delete">
<div>
<ButtonBase
className={classes.img}
onClick={() => {
requestConfirmation({
title: "Delete Image",
body: "Are you sure you want to delete this image?",
confirm: "Delete",
handleConfirm: handleDelete(file.ref),
});
}}
>
<Thumbnail
imageUrl={file.downloadURL}
size={thumbnailSize}
objectFit="contain"
className={classes.thumbnail}
/>
<Grid
container
justify="center"
alignItems="center"
className={classes.deleteImgHover}
>
<DeleteIcon color="inherit" />
</Grid>
</ButtonBase>
</div>
</Tooltip>
)}
</Grid>
))}
{localImage && (
<Grid item>
<div
className={clsx(classes.img, classes.localImgPreview)}
style={{ backgroundImage: `url("${localImage}")` }}
/>
</Grid>
)}
</Grid>
</Grid>
<Grid item className={classes.endButtonContainer}>
{!isLoading ? (
!disabled && (
<IconButton
size="small"
className="row-hover-iconButton"
onClick={(e) => {
dropzoneProps.onClick!(e);
e.stopPropagation();
}}
color="inherit"
>
<AddIcon />
</IconButton>
)
) : (
<CircularProgress
size={24}
variant={progress === 0 ? "indeterminate" : "static"}
value={progress}
thickness={4.6}
className={classes.circularProgress}
/>
)}
</Grid>
</Grid>
);
}
Example #22
Source File: Step2NewColumns.tsx From firetable with Apache License 2.0 | 4 votes |
export default function Step2NewColumns({
csvData,
config,
setConfig,
isXs,
}: IStepProps) {
const classes = useStyles();
const [fieldToEdit, setFieldToEdit] = useState(0);
const handleChange = (e) => {
const newColumns = [...config.newColumns];
newColumns[fieldToEdit].type = e.target.value;
setConfig((config) => ({ ...config, newColumns }));
};
const currentPair = _find(config.pairs, {
columnKey: config.newColumns[fieldToEdit]?.key,
});
const rowData = csvData.rows.map((row) => row[currentPair?.csvKey ?? ""]);
return (
<>
<div>
<Grid container spacing={2} className={classes.typeSelectRow}>
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
New Firetable Columns
</Typography>
<Divider />
<FadeList>
{config.newColumns.map(({ key, name, type }, i) => (
<li key={key}>
<ButtonBase
className={classes.buttonBase}
onClick={() => setFieldToEdit(i)}
aria-label={`Edit column ${key}`}
focusRipple
>
<Column
label={name}
type={type}
active={i === fieldToEdit}
secondaryItem={i === fieldToEdit && <ChevronRightIcon />}
/>
</ButtonBase>
</li>
))}
</FadeList>
</Grid>
<Grid item xs={12} sm={6}>
<Typography
variant="overline"
noWrap
component="h2"
className={classes.typeHeading}
>
Column Type: {config.newColumns[fieldToEdit].name}
</Typography>
<FieldsDropdown
value={config.newColumns[fieldToEdit].type}
onChange={handleChange}
hideLabel
options={SELECTABLE_TYPES}
/>
</Grid>
</Grid>
</div>
<div>
<Grid container spacing={3}>
{!isXs && (
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Raw Data
</Typography>
</Grid>
)}
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Column Preview
</Typography>
</Grid>
</Grid>
<Divider className={classes.previewDivider} />
<Grid container spacing={3}>
{!isXs && (
<Grid item xs={12} sm={6}>
<Column label={config.newColumns[fieldToEdit].key} />
</Grid>
)}
<Grid item xs={12} sm={6}>
<Column
label={config.newColumns[fieldToEdit].name}
type={config.newColumns[fieldToEdit].type}
/>
</Grid>
</Grid>
<FadeList classes={{ list: classes.previewList }}>
{rowData.slice(0, 20).map((cell, i) => (
<Grid container key={i} wrap="nowrap">
{!isXs && (
<Grid item xs className={classes.cellContainer}>
<Cell
field={config.newColumns[fieldToEdit].key}
value={(JSON.stringify(cell) || "")
.replace(/^"/, "")
.replace(/"$/, "")}
type={FieldType.shortText}
/>
</Grid>
)}
{!isXs && <Grid item className={classes.previewSpacer} />}
<Grid item xs className={classes.cellContainer}>
<Cell
field={config.newColumns[fieldToEdit].key}
value={
config.newColumns[fieldToEdit].type === FieldType.date ||
config.newColumns[fieldToEdit].type === FieldType.dateTime
? parseJSON(cell).getTime()
: cell
}
type={config.newColumns[fieldToEdit].type}
name={config.newColumns[fieldToEdit].name}
/>
</Grid>
</Grid>
))}
</FadeList>
</div>
</>
);
}
Example #23
Source File: SideDrawerField.tsx From firetable with Apache License 2.0 | 4 votes |
function ControlledFileUploader({
onChange,
value,
column,
docRef,
disabled,
}) {
const classes = useStyles();
const fieldClasses = useFieldStyles();
const { updateCell } = useFiretableContext();
const { uploaderState, upload, deleteUpload } = useUploader();
const { progress } = uploaderState;
// Store a preview image locally while uploading
const [localFile, setLocalFile] = useState<string>("");
const onDrop = useCallback(
(acceptedFiles: File[]) => {
const file = acceptedFiles[0];
if (docRef && file) {
upload({
docRef,
fieldName: column.key,
files: [file],
previousValue: value ?? [],
onComplete: (newValue) => {
if (updateCell) updateCell(docRef, column.key, newValue);
onChange(newValue);
setLocalFile("");
},
});
setLocalFile(file.name);
}
},
[docRef, value]
);
const handleDelete = (index: number) => {
const newValue = [...value];
const toBeDeleted = newValue.splice(index, 1);
toBeDeleted.length && deleteUpload(toBeDeleted[0]);
onChange(newValue);
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
multiple: false,
});
return (
<>
{!disabled && (
<ButtonBase
className={clsx(
fieldClasses.root,
classes.dropzoneButton,
isDragActive && classes.dropzoneDragActive
)}
{...getRootProps()}
>
<input id={`sidedrawer-field-${column.key}`} {...getInputProps()} />
<UploadIcon />
<Typography variant="body1" color="textSecondary">
Upload file
</Typography>
</ButtonBase>
)}
<Grid container spacing={1} className={classes.chipList}>
{Array.isArray(value) &&
value.map((file: FileValue, i) => (
<Grid item key={file.name} className={classes.chipGridItem}>
<Tooltip
title={`File last modified ${format(
file.lastModifiedTS,
DATE_TIME_FORMAT
)}`}
>
<div>
<Confirmation
message={{
title: "Delete File",
body: "Are you sure you want to delete this file?",
confirm: "Delete",
}}
functionName={!disabled ? "onDelete" : ""}
>
<Chip
size="medium"
icon={<FileIcon />}
label={file.name}
onClick={() => window.open(file.downloadURL)}
onDelete={!disabled ? () => handleDelete(i) : undefined}
className={classes.chip}
/>
</Confirmation>
</div>
</Tooltip>
</Grid>
))}
{localFile && (
<Grid item className={classes.chipGridItem}>
<Chip
size="medium"
icon={<FileIcon />}
label={localFile}
className={classes.chip}
//onDelete={() => {}}
deleteIcon={
<CircularProgress size={20} thickness={4.5} color="inherit" />
}
/>
</Grid>
)}
</Grid>
</>
);
}
Example #24
Source File: Step3Types.tsx From firetable with Apache License 2.0 | 4 votes |
export default function Step3Types({ config, updateConfig, isXs }: IStepProps) {
const classes = useStyles();
const [fieldToEdit, setFieldToEdit] = useState(Object.keys(config)[0]);
const handleChange = (e) =>
updateConfig({ [fieldToEdit]: { type: e.target.value } });
const { tableState } = useFiretableContext();
return (
<div>
<Grid container spacing={2} className={classes.typeSelectRow}>
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Firetable Columns
</Typography>
<Divider />
<FadeList>
{Object.entries(config).map(([field, { name, type }]) => (
<li key={field}>
<ButtonBase
className={classes.buttonBase}
onClick={() => setFieldToEdit(field)}
aria-label={`Edit column ${field}`}
focusRipple
>
<Column
label={name}
type={type}
active={field === fieldToEdit}
secondaryItem={
field === fieldToEdit && <ChevronRightIcon />
}
/>
</ButtonBase>
</li>
))}
</FadeList>
</Grid>
<Grid item xs={12} sm={6}>
<Typography
variant="overline"
noWrap
component="h2"
className={classes.typeHeading}
>
Column Type: {config[fieldToEdit].name}
</Typography>
<FieldsDropdown
value={config[fieldToEdit].type}
onChange={handleChange}
hideLabel
options={SELECTABLE_TYPES}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
{!isXs && (
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Raw Data
</Typography>
</Grid>
)}
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Column Preview
</Typography>
</Grid>
</Grid>
<Divider className={classes.previewDivider} />
<Grid container spacing={3}>
{!isXs && (
<Grid item xs={12} sm={6}>
<Column label={fieldToEdit} />
</Grid>
)}
<Grid item xs={12} sm={6}>
<Column
label={config[fieldToEdit].name}
type={config[fieldToEdit].type}
/>
</Grid>
</Grid>
<FadeList classes={{ list: classes.previewList }}>
{tableState!.rows!.slice(0, 20).map((row) => (
<Grid container key={row.id} wrap="nowrap">
{!isXs && (
<Grid item xs className={classes.cellContainer}>
<Cell
field={fieldToEdit}
value={(JSON.stringify(row[fieldToEdit]) || "")
.replace(/^"/, "")
.replace(/"$/, "")}
type={FieldType.shortText}
/>
</Grid>
)}
{!isXs && <Grid item className={classes.previewSpacer} />}
<Grid item xs className={classes.cellContainer}>
<Cell
field={fieldToEdit}
value={row[fieldToEdit]}
type={config[fieldToEdit].type}
name={config[fieldToEdit].name}
/>
</Grid>
</Grid>
))}
</FadeList>
</div>
);
}
Example #25
Source File: Step2Rename.tsx From firetable with Apache License 2.0 | 4 votes |
export default function Step2Rename({
config,
updateConfig,
isXs,
}: IStepProps) {
const classes = useStyles();
const [fieldToRename, setFieldToRename] = useState("");
const [renameTextField, setRenameTextField] = useState("");
const handleRename = () => {
updateConfig({ [fieldToRename]: { name: renameTextField } });
setFieldToRename("");
setRenameTextField("");
};
return (
<div>
<Grid container spacing={3}>
{!isXs && (
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Field Names
</Typography>
</Grid>
)}
<Grid item xs={12} sm={6}>
<Typography variant="overline" gutterBottom component="h2">
Set Column Names
</Typography>
</Grid>
</Grid>
<Divider />
<FadeList>
{Object.entries(config).map(([field, { name }]) => (
<Grid container key={field} component="li" wrap="nowrap">
{!isXs && (
<Grid item xs>
<Column label={field} />
</Grid>
)}
{!isXs && <Grid item className={classes.spacer} />}
<Grid item xs>
{fieldToRename === field ? (
<TextField
value={renameTextField}
onChange={(e) => setRenameTextField(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleRename();
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="Finished fieldToRename"
color="primary"
className={classes.doneButton}
onClick={handleRename}
>
<DoneIcon />
</IconButton>
</InputAdornment>
),
classes: {
root: classes.inputBaseRoot,
inputHiddenLabel: classes.inputHiddenLabel,
},
}}
hiddenLabel
fullWidth
autoFocus
classes={{ root: classes.textField }}
/>
) : (
<ButtonBase
className={classes.buttonBase}
onClick={() => {
setFieldToRename(field);
setRenameTextField(name);
}}
aria-label={`Rename column ${field}`}
focusRipple
>
<Column label={name} secondaryItem={<EditIcon />} />
</ButtonBase>
)}
</Grid>
</Grid>
))}
</FadeList>
</div>
);
}