From 7a254a9412f444032214f72e03b8fd368789f6b0 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 24 Apr 2026 02:15:08 +0100 Subject: [PATCH] feat(base): redesign formula editor popover with polished header, pills, and accordion --- .../components/formula/formula-editor.tsx | 177 ++++++++++++++---- .../base/components/formula/formula-input.tsx | 53 +++--- .../components/formula/function-palette.tsx | 90 ++++++--- .../components/formula/property-chip-row.tsx | 68 +++++-- .../property/create-property-popover.tsx | 3 +- 5 files changed, 292 insertions(+), 99 deletions(-) diff --git a/apps/client/src/features/base/components/formula/formula-editor.tsx b/apps/client/src/features/base/components/formula/formula-editor.tsx index b786e35b6..5f32e87db 100644 --- a/apps/client/src/features/base/components/formula/formula-editor.tsx +++ b/apps/client/src/features/base/components/formula/formula-editor.tsx @@ -1,5 +1,18 @@ import { useState } from "react"; -import { Button, Divider, Group, Paper, Stack, Text } from "@mantine/core"; +import { + Button, + Divider, + Group, + Kbd, + Paper, + Stack, + Text, +} from "@mantine/core"; +import { + IconAlertTriangle, + IconMathFunction, + IconPointFilled, +} from "@tabler/icons-react"; import { registry } from "@docmost/base-formula/client"; import { FormulaInput } from "./formula-input"; import { PropertyChipRow } from "./property-chip-row"; @@ -11,6 +24,7 @@ type Props = { properties: IBaseProperty[]; editingPropertyId: string | null; initialSource?: string; + name?: string; onSave: ( source: string, ast: unknown, @@ -24,6 +38,7 @@ export function FormulaEditor({ properties, editingPropertyId, initialSource = "", + name, onSave, onCancel, }: Props) { @@ -35,48 +50,136 @@ export function FormulaEditor({ registry, ); const canSave = parseState.state === "ok"; - const insertAtEnd = (snippet: string) => setSource((s) => `${s}${s ? " " : ""}${snippet}`); return ( - - - Formula - - - Properties - p.id !== editingPropertyId)} - onInsert={(name) => insertAtEnd(`prop("${name}")`)} - /> - - Functions - insertAtEnd(`${name}()`)} - /> - - - + + + + Formula + + {name && ( + + · {name} + + )} + + + + + + {parseState.state === "error" ? ( + + + {parseState.message} + + ) : parseState.state === "ok" ? ( + + + + Returns{" "} + + {parseState.resultType} + + + + ) : ( + + Click a property or function below to insert. + + )} + + + + + + + p.id !== editingPropertyId)} + onInsert={(name) => insertAtEnd(`prop("${name}")`)} + /> + + + + + + + Functions + + insertAtEnd(`${name}()`)} + /> + + + + + + + + to save + + + + + + diff --git a/apps/client/src/features/base/components/formula/formula-input.tsx b/apps/client/src/features/base/components/formula/formula-input.tsx index e165c8f17..11c3c12c0 100644 --- a/apps/client/src/features/base/components/formula/formula-input.tsx +++ b/apps/client/src/features/base/components/formula/formula-input.tsx @@ -1,35 +1,36 @@ -import { Textarea, Text } from "@mantine/core"; +import { Textarea } from "@mantine/core"; type Props = { value: string; onChange: (v: string) => void; - error?: { message: string; span?: { start: number; end: number } }; - resultType?: string; + hasError?: boolean; }; -export function FormulaInput({ value, onChange, error, resultType }: Props) { +export function FormulaInput({ value, onChange, hasError }: Props) { return ( -
-