Skip to content

Commit

Permalink
visual tweaks for menu and views in menu
Browse files Browse the repository at this point in the history
  • Loading branch information
imanjra committed Jul 18, 2024
1 parent 1f71557 commit dc67397
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ let theme = extendMuiTheme({
viewBarButtons: "hsl(200, 0%, 100%)",
inactiveTab: "hsl(200, 0%, 90%)",
popup: "hsl(200, 0%, 95%)",
field: "hsl(200, 0%, 95%)",
},
divider: "hsl(200, 0%, 80%)",
dividerDisabled: "hsl(200, 0%, 85%)",
Expand Down Expand Up @@ -123,6 +124,7 @@ let theme = extendMuiTheme({
inactiveTab: "hsl(200, 0%, 18%)",
paper: "hsl(200, 0%, 10%)",
popup: "hsl(200, 0%, 20%)",
field: "hsl(200, 0%, 20%, 0.3)",
},
divider: "hsl(200, 0%, 20%)",
dividerDisabled: "hsl(200, 0%, 15%)",
Expand Down
56 changes: 36 additions & 20 deletions app/packages/core/src/plugins/SchemaIO/components/ButtonView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { usePanelId } from "@fiftyone/spaces";
import { isNullish } from "@fiftyone/utilities";
import { Box, ButtonProps, Typography } from "@mui/material";
import React from "react";
import { getComponentProps } from "../utils";
import { getComponentProps, getColorByCode } from "../utils";
import { ViewPropsType } from "../utils/types";
import Button from "./Button";
import TooltipProvider from "./TooltipProvider";

export default function ButtonView(props: ViewPropsType) {
const { schema, path } = props;
Expand All @@ -20,6 +21,7 @@ export default function ButtonView(props: ViewPropsType) {
operator,
params = {},
prompt,
title,
} = view;
const panelId = usePanelId();
const handleClick = usePanelEvent();
Expand All @@ -35,25 +37,31 @@ export default function ButtonView(props: ViewPropsType) {

return (
<Box {...getComponentProps(props, "container")}>
<Button
variant={variant}
href={href}
onClick={() => {
handleClick(panelId, { params: computedParams, operator, prompt });
}}
startIcon={icon_position === "left" ? Icon : undefined}
endIcon={icon_position === "right" ? Icon : undefined}
title={description}
{...getComponentProps(props, "button", getButtonProps(props))}
>
<Typography>{label}</Typography>
</Button>
<TooltipProvider title={title} {...getComponentProps(props, "tooltip")}>
<Button
variant={variant}
href={href}
onClick={() => {
handleClick(panelId, {
params: computedParams,
operator,
prompt,
});
}}
startIcon={icon_position === "left" ? Icon : undefined}
endIcon={icon_position === "right" ? Icon : undefined}
title={description}
{...getComponentProps(props, "button", getButtonProps(props))}
>
<Typography>{label}</Typography>
</Button>
</TooltipProvider>
</Box>
);
}

function getButtonProps(props: ViewPropsType): ButtonProps {
const { label, variant } = props.schema.view;
const { label, variant, color } = props.schema.view;
const baseProps: ButtonProps = getCommonProps(props);
if (isNullish(label)) {
baseProps.sx["& .MuiButton-startIcon"] = { mr: 0, ml: 0 };
Expand All @@ -66,10 +74,21 @@ function getButtonProps(props: ViewPropsType): ButtonProps {
}
if (variant === "square") {
baseProps.sx.borderRadius = "3px 3px 0 0";
baseProps.sx.backgroundColor = (theme) => theme.palette.neutral.softBg;
baseProps.sx.backgroundColor = (theme) => theme.palette.background.field;
baseProps.sx.borderBottom = "1px solid";
baseProps.sx.paddingBottom = "5px";
baseProps.sx.borderColor = (theme) => theme.palette.primary.main;
}
if (variant === "outlined") {
baseProps.sx.p = "5px";
}
if ((variant === "square" || variant === "outlined") && isNullish(color)) {
const borderColor =
"rgba(var(--fo-palette-common-onBackgroundChannel) / 0.23)";
baseProps.sx.borderColor = borderColor;
baseProps.sx.borderBottomColor = borderColor;
}

return baseProps;
}

Expand All @@ -95,10 +114,7 @@ function getCommonProps(props: ViewPropsType): ButtonProps {
function getColor(props: ViewPropsType) {
const color = props.schema.view.color;
if (color) {
if (color === "primary") return (theme) => theme.palette.text.primary;
if (color === "secondary") return (theme) => theme.palette.text.secondary;
if (color === "orange") return (theme) => theme.palette.primary.main;
return color;
return getColorByCode(color);
}
const variant = getVariant(props);
return (theme) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Box, Paper, PaperProps } from "@mui/material";
import React, { PropsWithChildren } from "react";
import { isCompositeView, overlayToSx } from "../utils";
import {
getMarginSx,
getPaddingSx,
isCompositeView,
overlayToSx,
} from "../utils";
import { ViewPropsType } from "../utils/types";

export default function ContainerizedComponent(props: ContainerizedComponent) {
Expand Down Expand Up @@ -29,9 +34,16 @@ export default function ContainerizedComponent(props: ContainerizedComponent) {
}

function PaperContainer(props: PaperContainerProps) {
const { elevation = 1, children, ...paperProps } = props;
const { elevation = 1, children, rounded = true, ...paperProps } = props;
const roundedSx = rounded ? {} : { borderRadius: 0 };
const paddingSx = getPaddingSx(props);
const marginSx = getMarginSx(props);
return (
<Paper sx={{ p: 1, m: 0.5 }} elevation={elevation} {...paperProps}>
<Paper
sx={{ p: 1, m: 0.5, ...roundedSx, ...paddingSx, ...marginSx }}
elevation={elevation}
{...paperProps}
>
{children}
</Paper>
);
Expand All @@ -45,4 +57,6 @@ const containersByName = { PaperContainer, OutlinedContainer };

type ContainerizedComponent = PropsWithChildren<ViewPropsType>;

type PaperContainerProps = PropsWithChildren<PaperProps>;
type PaperContainerProps = PropsWithChildren<
PaperProps & { rounded?: boolean }
>;
35 changes: 26 additions & 9 deletions app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { MenuItem, Select } from "@mui/material";
import React from "react";
import React, { useState } from "react";
import { useKey } from "../hooks";
import { getComponentProps } from "../utils";
import { getComponentProps, getFieldSx } from "../utils";
import autoFocus from "../utils/auto-focus";
import { ViewPropsType } from "../utils/types";
import AlertView from "./AlertView";
import ChoiceMenuItemBody from "./ChoiceMenuItemBody";
import FieldWrapper from "./FieldWrapper";
import { ViewPropsType } from "../utils/types";

const MULTI_SELECT_TYPES = ["string", "array"];

Expand All @@ -19,11 +19,14 @@ export default function DropdownView(props: ViewPropsType) {
placeholder = "",
separator = ",",
readOnly,
condensed,
compact,
label,
description,
color,
variant,
} = view;
const [key, setUserChanged] = useKey(path, schema, data, true);
const [selected, setSelected] = useState(false);

if (multiSelect && !MULTI_SELECT_TYPES.includes(type))
return (
Expand Down Expand Up @@ -53,10 +56,22 @@ export default function DropdownView(props: ViewPropsType) {
labels[choice.value] = choice.label;
return labels;
}, {});
const { MenuProps = {}, ...selectProps } = getComponentProps(props, "select");
const { MenuProps = {}, ...selectProps } = getComponentProps(
props,
"select",
{
sx: {
".MuiSelect-select": {
padding: "0.45rem 2rem 0.45rem 1rem",
opacity: selected ? 1 : 0.5,
},
...getFieldSx({ color, variant }),
},
}
);

return (
<FieldWrapper {...props} hideHeader={condensed}>
<FieldWrapper {...props} hideHeader={compact}>
<Select
key={key}
disabled={readOnly}
Expand All @@ -65,10 +80,12 @@ export default function DropdownView(props: ViewPropsType) {
size="small"
fullWidth
displayEmpty
title={condensed ? description : undefined}
title={compact ? description : undefined}
renderValue={(value) => {
if (value?.length === 0) {
if (condensed) {
const unselected = value?.length === 0;
setSelected(!unselected);
if (unselected) {
if (compact) {
return placeholder || label;
}
return placeholder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function schemaWithInheritedVariant(
) {
if (isNullish(get(schema, "view.variant"))) {
set(schema, "view.variant", get(parentSchema, "view.variant"));
set(schema, "view.condensed", true);
set(schema, "view.compact", true);
}
if (isNullish(get(schema, "view.color"))) {
set(schema, "view.color", get(parentSchema, "view.color"));
Expand Down
11 changes: 10 additions & 1 deletion app/packages/core/src/plugins/SchemaIO/components/GridView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Box, BoxProps } from "@mui/material";
import React from "react";
import { HeaderView } from ".";
import { getComponentProps, getPath, getProps, spaceToHeight } from "../utils";
import {
getComponentProps,
getMarginSx,
getPaddingSx,
getPath,
getProps,
spaceToHeight,
} from "../utils";
import { ObjectSchemaType, ViewPropsType } from "../utils/types";
import DynamicIO from "./DynamicIO";

Expand All @@ -26,6 +33,8 @@ export default function GridView(props: ViewPropsType) {
justifyContent: alignX || align_x || "start",
alignItems: alignY || align_y || "start",
gridAutoFlow: direction,
...getPaddingSx(view),
...getMarginSx(view),
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
import { TextField } from "@mui/material";
import React from "react";
import { useKey } from "../hooks";
import { getComponentProps } from "../utils";
import { getComponentProps, getFieldSx } from "../utils";
import autoFocus from "../utils/auto-focus";
import FieldWrapper from "./FieldWrapper";
import { NumberSchemaType, ViewPropsType } from "../utils/types";
import FieldWrapper from "./FieldWrapper";

export default function TextFieldView(props: ViewPropsType<NumberSchemaType>) {
const { schema, onChange, path, data } = props;
const { type, view = {}, min, max, multipleOf = 1 } = schema;
const { readOnly, placeholder, condensed, label } = view;
const { readOnly, placeholder, compact, label, color, variant } = view;

const { inputProps = {}, ...fieldProps } = getComponentProps(props, "field");
const { inputProps = {}, ...fieldProps } = getComponentProps(props, "field", {
sx: getFieldSx({ color, variant }),
});

const [key, setUserChanged] = useKey(path, schema, data, true);

return (
<FieldWrapper {...props} hideHeader={condensed}>
<FieldWrapper {...props} hideHeader={compact}>
<TextField
key={key}
disabled={readOnly}
autoFocus={autoFocus(props)}
defaultValue={data}
size="small"
fullWidth
placeholder={condensed ? placeholder || label : placeholder}
placeholder={compact ? placeholder || label : placeholder}
type={type}
onChange={(e) => {
const value = e.target.value;
onChange(path, type === "number" ? parseFloat(value) : value, schema);
setUserChanged();
}}
inputProps={{ min, max, step: multipleOf, ...inputProps }}
inputProps={{
min,
max,
step: multipleOf,
style: compact ? { padding: "0.45rem 1rem" } : {},
...inputProps,
}}
{...fieldProps}
/>
</FieldWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Box, Tooltip, TooltipProps } from "@mui/material";
import React from "react";

export default function TooltipProvider(props: TooltipProps) {
const { title, children, ...tooltipProps } = props;
if (!title) return children;
return (
<Tooltip title={title} {...tooltipProps}>
<Box>{children}</Box>
</Tooltip>
);
}
1 change: 1 addition & 0 deletions app/packages/core/src/plugins/SchemaIO/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export function getErrorsForView(props: ViewPropsType) {
export { default as autoFocus } from "./auto-focus";
export * from "./generate-schema";
export * from "./layout";
export * from "./style";

// Views that renders DynamicIO as a child component
const COMPOSITE_VIEWS = [
Expand Down
36 changes: 35 additions & 1 deletion app/packages/core/src/plugins/SchemaIO/utils/layout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ViewPropsType } from "./types";
import { SchemaViewType, ViewPropsType } from "./types";

const CSS_UNIT_PATTERN =
/(\d+)(cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|%)$/;
Expand Down Expand Up @@ -35,6 +35,30 @@ export function getLayoutProps(props: ViewPropsType) {
};
}

export function getPaddingSx(view: SchemaViewType = {}): PaddingSxType {
return {
p: view.pad,
px: view.pad_x || view.px || view.padX,
py: view.pad_y || view.py || view.padY,
pt: view.pad_t || view.pt || view.padT,
pr: view.pad_r || view.pr || view.padR,
pb: view.pad_b || view.pb || view.padB,
pl: view.pad_l || view.pl || view.padL,
};
}

export function getMarginSx(view: SchemaViewType = {}): PaddingSxType {
return {
m: view.margin,
mx: view.margin_x || view.mx || view.marginX,
my: view.margin_y || view.my || view.marginY,
mt: view.margin_t || view.mt || view.marginT,
mr: view.margin_r || view.mr || view.marginR,
mb: view.margin_b || view.mb || view.marginB,
ml: view.margin_l || view.ml || view.marginL,
};
}

export const overlayToSx = {
"top-left": {
position: "absolute",
Expand Down Expand Up @@ -85,3 +109,13 @@ export const overlayToSx = {
transform: "translateY(-50%)",
},
};

type PaddingSxType = {
p?: number;
px?: number;
py?: number;
pt?: number;
pr?: number;
pb?: number;
pl?: number;
};
Loading

0 comments on commit dc67397

Please sign in to comment.