/* Copyright 2026 Marimo. All rights reserved. */ import { InfoIcon, TriangleAlert } from "lucide-react"; import { useFormContext, useWatch } from "react-hook-form"; import { Accordion } from "@/components/ui/accordion"; import { Tooltip } from "@/components/ui/tooltip"; import { capitalize } from "@/utils/strings"; import { isFieldSet } from "../chart-spec/spec"; import { ColorByAxis, Facet, XAxis, YAxis } from "../components/chart-items"; import { BooleanField, ColorArrayField, InputField, SelectField, SliderField, TooltipSelect, } from "../components/form-fields"; import { AccordionFormContent, AccordionFormItem, AccordionFormTrigger, FormSectionHorizontalRule, Title, } from "../components/layouts"; import { COLOR_SCHEMES, DEFAULT_COLOR_SCHEME } from "../constants"; import { useChartFormContext } from "../context"; import type { ChartSchemaType } from "../schemas"; import { ChartType, COLOR_BY_FIELDS, NONE_VALUE } from "../types"; export const CommonChartForm: React.FC = () => { const form = useFormContext(); const formValues = useWatch({ control: form.control }); const yColumn = formValues.general?.yColumn; const groupByColumn = formValues.general?.colorByColumn; const yColumnExists = isFieldSet(yColumn?.field); const { chartType } = useChartFormContext(); const showStacking = isFieldSet(groupByColumn?.field) && (chartType === ChartType.BAR || chartType === ChartType.LINE); return ( <>

Charts are not saved.

{yColumnExists && ( <> {showStacking && (
)} )} ); }; export const StyleForm: React.FC = () => { const { chartType } = useChartFormContext(); return ( </AccordionFormTrigger> <AccordionFormContent> <InputField label="Plot title" fieldName="general.title" /> <BooleanField fieldName="style.gridLines" label="Show grid lines" defaultValue={chartType === ChartType.SCATTER} /> </AccordionFormContent> </AccordionFormItem> <AccordionFormItem value="xAxis"> <AccordionFormTrigger> <Title text="X-Axis" /> </AccordionFormTrigger> <AccordionFormContent> <InputField label="Label" fieldName="xAxis.label" /> <SliderField fieldName="xAxis.width" label="Width" defaultValue={400} start={200} stop={800} /> </AccordionFormContent> </AccordionFormItem> <AccordionFormItem value="yAxis"> <AccordionFormTrigger> <Title text="Y-Axis" /> </AccordionFormTrigger> <AccordionFormContent> <InputField label="Label" fieldName="yAxis.label" /> <SliderField fieldName="yAxis.height" label="Height" defaultValue={300} start={150} stop={600} /> </AccordionFormContent> </AccordionFormItem> <AccordionFormItem value="color"> <AccordionFormTrigger> <Title text="Color" /> </AccordionFormTrigger> <AccordionFormContent> <SelectField fieldName="color.field" label="Field" options={COLOR_BY_FIELDS.map((field) => ({ display: capitalize(field), value: field, }))} defaultValue={NONE_VALUE} /> <SelectField fieldName="color.scheme" label="Color scheme" defaultValue={DEFAULT_COLOR_SCHEME} options={COLOR_SCHEMES.map((scheme) => ({ display: capitalize(scheme), value: scheme, }))} /> <ColorArrayField fieldName="color.range" label="Color range" /> <p className="text-xs"> <InfoIcon className="w-2.5 h-2.5 inline mb-1 mr-1" /> If you are using color range, color scheme will be ignored. </p> </AccordionFormContent> </AccordionFormItem> </Accordion> ); }; export const OtherOptions: React.FC = () => { const { saveForm } = useChartFormContext(); const form = useFormContext<ChartSchemaType>(); const formValues = useWatch({ control: form.control }); const autoTooltips = formValues.tooltips?.auto; return ( <Accordion type="multiple"> <AccordionFormItem value="facet"> <AccordionFormTrigger className="pt-0"> <Title text="Faceting" tooltip="Repeat the chart for each unique field value" /> </AccordionFormTrigger> <AccordionFormContent> <Facet /> </AccordionFormContent> </AccordionFormItem> <AccordionFormItem value="tooltips"> <AccordionFormTrigger> <Title text="Tooltips" /> </AccordionFormTrigger> <AccordionFormContent wrapperClassName="flex-row justify-between"> <BooleanField fieldName="tooltips.auto" label="Include X, Y and Color" /> {!autoTooltips && ( <TooltipSelect fieldName="tooltips.fields" saveFunction={saveForm} /> )} </AccordionFormContent> </AccordionFormItem> </Accordion> ); };