Skip to content

Commit

Permalink
enhancements for ButtonView and IconButtonView
Browse files Browse the repository at this point in the history
  • Loading branch information
imanjra committed Jun 11, 2024
1 parent a3ae1e5 commit c6d0052
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 30 deletions.
2 changes: 2 additions & 0 deletions app/packages/core/src/plugins/SchemaIO/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import React from "react";
import { ButtonProps, Button as MUIButton } from "@mui/material";

export default function Button(props: ButtonProps) {
const { variant } = props;
return (
<MUIButton
color={variant === "outlined" ? "secondary" : undefined}
{...props}
sx={{ textTransform: "none", ...(props?.sx || {}) }}
/>
Expand Down
14 changes: 6 additions & 8 deletions app/packages/core/src/plugins/SchemaIO/components/ButtonView.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from "react";
import usePanelEvent from "@fiftyone/operators/src/usePanelEvent";
import { usePanelId } from "@fiftyone/spaces";
import { Box } from "@mui/material";
import { useOperatorExecutor } from "@fiftyone/operators";
import Button from "./Button";
import React from "react";
import { getComponentProps } from "../utils";
import { useCustomPanelState, usePanelId } from "@fiftyone/spaces";
import { usePromptOperatorInput } from "@fiftyone/operators/src/state";
import usePanelEvent from "@fiftyone/operators/src/usePanelEvent";
import Button from "./Button";

export default function ButtonView(props) {
return props?.schema?.view?.operator ? (
Expand All @@ -18,11 +16,11 @@ export default function ButtonView(props) {
function BaseButtonView(props) {
const { schema, onClick } = props;
const { view = {} } = schema;
const { label, href } = view;
const { label, href, variant } = view;
return (
<Box {...getComponentProps(props, "container")}>
<Button
variant="contained"
variant={variant || "contained"}
href={href}
onClick={onClick}
{...getComponentProps(props, "button")}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { MuiIconFont, PillButton } from "@fiftyone/components";
import usePanelEvent from "@fiftyone/operators/src/usePanelEvent";
import { usePanelId } from "@fiftyone/spaces";
import { IconButton, Link } from "@mui/material";
import { IconButton, Link, SxProps } from "@mui/material";
import React, { useCallback } from "react";
import styled from "styled-components";
import { getComponentProps } from "../utils";
import Button from "./Button";

export default function IconButtonView(props) {
const { schema } = props;
const { view = {} } = schema;
const { icon, operator, params = {}, prompt, variant, label } = view;
const { icon, operator, params = {}, prompt, variant, href, label } = view;
const panelId = usePanelId();
const handleClick = usePanelEvent();

const Icon = icon ? (
<MuiIconFont
name={icon}
sx={
variant === "round"
? {}
: { color: (theme) => theme.palette.primary.main }
}
sx={getVariantSx(variant)}
{...getComponentProps(props, "icon")}
/>
) : null;
Expand All @@ -30,14 +27,18 @@ export default function IconButtonView(props) {
}, [panelId, params, operator, prompt, handleClick]);

if (variant === "round") {
const Wrapper = href ? Link : React.Fragment;
return (
<PillButton
icon={Icon || label}
title={label}
highlight
onClick={onClick}
aria-label={`Button for ${icon}`}
/>
<Wrapper href={href}>
<PillButton
icon={Icon || label}
title={label}
highlight
onClick={onClick}
aria-label={`Button for ${icon}`}
{...getComponentProps(props, "button")}
/>
</Wrapper>
);
}

Expand All @@ -47,20 +48,35 @@ export default function IconButtonView(props) {
title={label}
aria-label={`Button for ${icon}`}
onClick={onClick}
href={href}
{...getComponentProps(props, "button")}
>
{Icon || label}
</SquareButton>
);
}

if (variant === "contained" || variant === "outlined") {
return (
<Button
variant={variant}
href={href}
onClick={onClick}
{...getComponentProps(props, "button")}
>
{Icon || label}
</Button>
);
}

return (
<IconButton
title={label}
aria-label={`Button for ${icon}`}
size="small"
{...getComponentProps(props, "button")}
href={href}
onClick={onClick}
{...getComponentProps(props, "button")}
>
{Icon || label}
</IconButton>
Expand All @@ -78,3 +94,21 @@ const SquareButton = styled(Link)`
border-top-right-radius: 3px;
padding: 0.25rem;
`;

function getVariantSx(variant: VariantType): SxProps {
if (variant === "round") return {};
if (variant === "contained") {
return {
color: (theme) => theme.palette.common.white,
};
}
if (variant === "outlined") {
return {
color: (theme) => theme.palette.secondary.main,
};
}
return {
color: (theme) => theme.palette.primary.main,
};
}
type VariantType = "round" | "square" | "contained" | "outlined" | "default";
34 changes: 27 additions & 7 deletions fiftyone/operators/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,11 @@ def btn(
name,
label,
icon=None,
icon_variant=None,
variant=None,
on_click=None,
prompt=False,
params=None,
href=None,
):
"""Defines a button or icon button to display to the user as a :class:`Button`.
Expand All @@ -268,22 +269,30 @@ def btn(
"greet",
label="Say Hi!",
icon="waving_hand",
variant="round",
on_click="print_stdout",
params={"msg": "Hi!"},
)
Args:
name: the name of the property
label: the label of the button
variant (None): the variant of the button. Can be ``"contained"``, ``"outlined"``,
``"text"``. Additionally, when ``"icon"`` is provided, the variant can also be
``"round"`` or ``"square"``
icon (None): the name of the icon to display
icon_variant (None): the optional variant of the icon. Can be ``"round"`` or
``"square"``
on_click (None): the name of the operator to execute when the button is clicked
prompt (False): whether to prompt the user before executing the operator
params (None): the parameters to pass to the operator
href (None): the URL to navigate to when the button is clicked
"""
btn = Button(
label=label, operator=on_click, prompt=prompt, params=params
label=label,
operator=on_click,
prompt=prompt,
params=params,
variant=variant,
href=href,
)
if icon:
btn = IconButtonView(
Expand All @@ -292,7 +301,8 @@ def btn(
prompt=prompt,
params=params,
icon=icon,
variant=icon_variant,
variant=variant,
href=href,
)
return self.view(name, btn)

Expand Down Expand Up @@ -1111,6 +1121,7 @@ class Button(View):
operator (None): the name of the operator to execute when the button is
clicked
params (None): the parameters to pass to the operator
href (None): the URL to navigate to when the button is clicked
"""

def __init__(self, **kwargs):
Expand All @@ -1119,6 +1130,7 @@ def __init__(self, **kwargs):
self.operator = kwargs.get("operator", None)
self.prompt = kwargs.get("prompt", False)
self.params = kwargs.get("params", None)
self.href = kwargs.get("href", None)

def to_json(self):
return _convert_callables_to_operator_uris(
Expand All @@ -1128,6 +1140,7 @@ def to_json(self):
"operator": self.operator,
"params": self.params,
"prompt": self.prompt,
"href": self.href,
}
)

Expand Down Expand Up @@ -2021,8 +2034,15 @@ class IconButtonView(Button):
Args:
icon (None): a icon for the button. See https://marella.me/material-icons/demo/
variant (None): the optional variant of the icon button. Can be either ``"round"``
or ``"square"``.
variant (None): the optional variant of the icon button. Can be ``"round"``, ``"square"``,
``"outlined"``, or ``"contained"``.
label (None): a label for the button
description (None): a description for the button
caption (None): a caption for the button
operator (None): the name of the operator to execute when the button is
clicked
params (None): the parameters to pass to the operator
href (None): the URL to navigate to when the button is clicked
"""

def __init__(self, **kwargs):
Expand Down

0 comments on commit c6d0052

Please sign in to comment.