Skip to content

Commit

Permalink
Merge pull request #4909 from voxel51/patch/badge
Browse files Browse the repository at this point in the history
Add PillBadgeView to Python Panels
  • Loading branch information
Br2850 authored Oct 10, 2024
2 parents b402b8c + c672a05 commit fd70ada
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 0 deletions.
149 changes: 149 additions & 0 deletions app/packages/components/src/components/PillBadge/PillBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useState } from "react";
import CircleIcon from "@mui/icons-material/Circle";
import { Chip, FormControl, MenuItem, Select } from "@mui/material";

const PillBadge = ({
text,
color = "default",
variant = "filled",
showIcon = true,
}: {
text: string | string[] | [string, string][];
color?: string;
variant?: "filled" | "outlined";
showIcon?: boolean;
}) => {
const getInitialChipSelection = (
text: string | string[] | [string, string][]
) => {
if (typeof text === "string") return text;
if (Array.isArray(text)) {
if (Array.isArray(text[0])) return text[0][0];
return text[0];
}
return "";
};

const getInitialChipColor = (
text: string | string[] | [string, string][],
color?: string
) => {
if (typeof text === "string") return color;
if (Array.isArray(text)) {
if (Array.isArray(text[0])) return text[0][1];
return color || "default";
}
return "default";
};

const [chipSelection, setChipSelection] = useState(
getInitialChipSelection(text)
);
const [chipColor, setChipColor] = useState(getInitialChipColor(text, color));

const COLORS: { [key: string]: string } = {
default: "#999999",
primary: "#FFB682",
error: "error",
warning: "warning",
info: "info",
success: "#8BC18D",
};

const chipStyle: { [key: string]: string | number } = {
color: COLORS[chipColor || "default"] || COLORS.default,
fontWeight: 500,
paddingLeft: 1,
};

return (
<span>
{typeof text === "string" ? (
<Chip
icon={
showIcon ? (
<CircleIcon color={"inherit"} sx={{ fontSize: 10 }} />
) : undefined
}
label={text}
sx={{
...chipStyle,
"& .MuiChip-icon": {
marginRight: "-7px",
},
"& .MuiChip-label": {
marginBottom: "1px",
},
}}
variant={variant as "filled" | "outlined" | undefined}
/>
) : (
<FormControl fullWidth>
<Chip
icon={
showIcon ? (
<CircleIcon color={"inherit"} sx={{ fontSize: 10 }} />
) : undefined
}
label={
Array.isArray(text) && text.length > 0 && Array.isArray(text[0]) ? (
<Select
value={chipSelection}
variant={"standard"}
disableUnderline={true}
onChange={(event) => {
const selectedText = text.find(
(t) => t[0] === event.target.value
);
setChipSelection(event.target.value);
setChipColor(selectedText?.[1] ?? "default");
}}
sx={{
color: "inherit",
}}
>
{text.map((t, index) => (
<MenuItem key={index} value={t[0]}>
{t[0]}
</MenuItem>
))}
</Select>
) : (
<Select
value={chipSelection}
variant={"standard"}
disableUnderline={true}
onChange={(event) => setChipSelection(event.target.value)}
sx={{
color: "inherit",
}}
>
{text.map((t, index) => (
<MenuItem key={index} value={t}>
{t}
</MenuItem>
))}
</Select>
)
}
sx={{
...chipStyle,
"& .MuiChip-icon": {
marginRight: "-7px",
},
"& .MuiChip-label": {
marginBottom: "1px",
},
"& .MuiInput-input:focus": {
backgroundColor: "inherit",
},
}}
variant={variant as "filled" | "outlined" | undefined}
></Chip>
</FormControl>
)}
</span>
);
};

export default PillBadge;
1 change: 1 addition & 0 deletions app/packages/components/src/components/PillBadge/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as PillBadge } from "./PillBadge";
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Box } from "@mui/material";
import React from "react";
import { getComponentProps } from "../utils";
import PillBadge from "@fiftyone/components/src/components/PillBadge/PillBadge";

export default function PillBadgeView(props) {
const { schema } = props;
const { view = {} } = schema;
const { text, color, variant, showIcon } = view;

return (
<Box {...getComponentProps(props, "container")}>
<PillBadge
text={text}
color={color}
variant={variant}
showIcon={showIcon}
{...getComponentProps(props, "pillBadge")}
/>
</Box>
);
}
1 change: 1 addition & 0 deletions app/packages/core/src/plugins/SchemaIO/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ export { default as TextFieldView } from "./TextFieldView";
export { default as TupleView } from "./TupleView";
export { default as UnsupportedView } from "./UnsupportedView";
export { default as FrameLoaderView } from "./FrameLoaderView";
export { default as PillBadgeView } from "./PillBadgeView";
14 changes: 14 additions & 0 deletions fiftyone/operators/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,20 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)


class PillBadgeView(ReadOnlyView):
"""Displays a pill shaped badge.
Args:
text ("Reviewed" | ["Reviewed", "Not Reviewed"] | [["Not Started", "primary"], ["Reviewed", "success"], ["In Review", "warning"]): a label or set of label options with or without a color for the pill badge
color ("primary"): the color of the pill
variant ("outlined"): the variant of the pill
show_icon (False | True): whether to display indicator icon
"""

def __init__(self, **kwargs):
super().__init__(**kwargs)


class PlotlyView(View):
"""Displays a Plotly chart.
Expand Down

0 comments on commit fd70ada

Please sign in to comment.