diff --git a/libs/@hashintel/ds-components/src/components/Switch/switch.tsx b/libs/@hashintel/ds-components/src/components/Switch/switch.tsx deleted file mode 100644 index f98335639db..00000000000 --- a/libs/@hashintel/ds-components/src/components/Switch/switch.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { Switch as BaseSwitch } from "@ark-ui/react/switch"; - -import { css } from "@hashintel/ds-helpers/css"; - -// Layout constants -const SLIDER_HEIGHT = 20; -const SLIDER_WIDTH = 34; -const SLIDER_RADIUS = SLIDER_HEIGHT / 2; - -const THUMB_WIDTH = 14; -const THUMB_HEIGHT = 14; -const THUMB_RADIUS = THUMB_HEIGHT / 2; - -const PADDING = SLIDER_RADIUS - THUMB_RADIUS; -const TRAVEL = SLIDER_WIDTH - THUMB_WIDTH - PADDING * 2; - -const THUMB_SCALE_ACTIVE = 2.5; - -const switchControlStyles = (disabled: boolean) => - css({ - position: "relative", - display: "inline-block", - cursor: disabled ? "not-allowed" : "pointer", - transition: "[all 0.2s ease]", - backgroundColor: "neutral.s40", - _checked: { - backgroundColor: "green.s80", - }, - }); - -const switchThumbStyles = css({ - position: "absolute", - top: "[50%]", - left: `[${PADDING}px]`, - transition: "[all 0.2s ease]", - _checked: { - transform: `translateY(-50%) translateX(${TRAVEL}px)`, - }, - "&[data-state='unchecked']": { - top: "[50%]", - transform: "translateY(-50%)", - }, - "& > div": { - background: - "[linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(245,247,250,0.92) 100%)]", - }, - "&[data-active] > div": { - transform: `scale(${THUMB_SCALE_ACTIVE})`, - background: "[rgba(255, 255, 255, 0.1)]", - shadow: - "[0 2px 4px rgba(0,0,0,0.1), inset 0 1px 3px rgba(0,0,0,0.1), inset 0 -1px 3px rgba(255,255,255,0.1)]", - }, -}); - -const switchThumbInnerStyles = css({ - display: "block", - width: `[${THUMB_WIDTH}px]`, - height: `[${THUMB_HEIGHT}px]`, - borderRadius: `[${THUMB_RADIUS}px]`, - border: "[1px solid rgba(255,255,255,0.55)]", - background: - "[linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(245,247,250,0.92) 100%)]", - boxShadow: "[0 4px 22px rgba(0,0,0,0.1)]", - transition: "[all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)]", -}); - -export interface SwitchProps { - checked?: boolean; - defaultChecked?: boolean; - disabled?: boolean; - onCheckedChange?: (checked: boolean) => void; -} - -const switchRootStyles = css({ - display: "inline-flex", - alignItems: "center", -}); - -export const Switch: React.FC = ({ - checked, - defaultChecked = false, - disabled = false, - onCheckedChange, -}) => { - return ( - { - onCheckedChange?.(details.checked); - }} - className={switchRootStyles} - > - - -
- - - - - ); -}; diff --git a/libs/@hashintel/ds-components/src/components/Toggle/toggle.recipe.ts b/libs/@hashintel/ds-components/src/components/Toggle/toggle.recipe.ts index a5b66258a1e..63d3a14b136 100644 --- a/libs/@hashintel/ds-components/src/components/Toggle/toggle.recipe.ts +++ b/libs/@hashintel/ds-components/src/components/Toggle/toggle.recipe.ts @@ -22,11 +22,10 @@ export const styles = sva({ flexShrink: "0", width: "var(--toggle-width)", height: "var(--toggle-height)", - padding: "var(--toggle-padding)", + padding: "[calc(var(--toggle-padding) + 1px)]", borderRadius: "full", - border: "[1px solid]", - borderColor: "black.a15", - boxShadow: "[inset 0 2px 4px rgba(0, 0, 0, 0.05)]", + boxShadow: + "[inset 0 2px 4px rgba(0, 0, 0, 0.05), inset 0 0 0 1px var(--colors-black-a10)]", outlineColor: "black.a40", transition: "[background-color 0.15s ease, outline 0.15s ease, box-shadow 0.15s ease]", @@ -87,7 +86,11 @@ export const styles = sva({ "--toggle-width": "[24px]", "--toggle-height": "[14px]", "--toggle-padding": "[2px]", - "--toggle-thumb-size": "[10px]", + "--toggle-thumb-size": "[9px]", + }, + thumb: { + boxShadow: + "[0 0.5px 2.5px 0 rgba(0, 0, 0, 0.1), 0 0.5px 1.5px -1px rgba(0, 0, 0, 0.1)]", }, label: { fontSize: "[12px]" }, }, @@ -96,9 +99,13 @@ export const styles = sva({ "--toggle-width": "[28px]", "--toggle-height": "[16px]", "--toggle-padding": "[2px]", - "--toggle-thumb-size": "[12px]", + "--toggle-thumb-size": "[11px]", }, label: { fontSize: "[12px]" }, + thumb: { + boxShadow: + "[0 0.5px 2.5px 0 rgba(0, 0, 0, 0.1), 0 0.5px 1.5px -1px rgba(0, 0, 0, 0.1)]", + }, }, sm: { control: { @@ -200,7 +207,8 @@ export const styles = sva({ invalid: { true: { control: { - borderColor: "red.s70", + boxShadow: + "[0 0 0 1px var(--colors-red-s70), inset 0 2px 4px rgba(0, 0, 0, 0.05)]", "&::after": { content: '""', position: "absolute", diff --git a/libs/@hashintel/ds-components/src/main.ts b/libs/@hashintel/ds-components/src/main.ts index 776070c67bf..a567917ee9d 100644 --- a/libs/@hashintel/ds-components/src/main.ts +++ b/libs/@hashintel/ds-components/src/main.ts @@ -32,7 +32,6 @@ export { type SelectProps, } from "./components/Select/select"; export { Slider, type SliderProps } from "./components/Slider/slider"; -export { Switch, type SwitchProps } from "./components/Switch/switch"; export { TextInput } from "./components/TextInput/text-input"; export { TextMark } from "./components/TextMark/text-mark"; export { Toggle, type ToggleProps } from "./components/Toggle/toggle"; diff --git a/libs/@hashintel/petrinaut/src/ui/components/switch.tsx b/libs/@hashintel/petrinaut/src/ui/components/switch.tsx deleted file mode 100644 index 02f29f6ea5b..00000000000 --- a/libs/@hashintel/petrinaut/src/ui/components/switch.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Switch as DsSwitch, Tooltip } from "@hashintel/ds-components"; - -import type { ComponentProps } from "react"; - -type SwitchProps = ComponentProps & { - tooltip?: string; - tooltipOptions?: Omit, "children" | "content">; -}; - -export const Switch = ({ tooltip, tooltipOptions, ...props }: SwitchProps) => { - const element = ; - - if (!tooltip) { - return element; - } - - return ( - - {element} - - ); -}; diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/BottomPanel/subviews/simulation-settings.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/BottomPanel/subviews/simulation-settings.tsx index 7e7be9e9180..e9f2c7bb45a 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/BottomPanel/subviews/simulation-settings.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/BottomPanel/subviews/simulation-settings.tsx @@ -1,6 +1,12 @@ import { use, useState } from "react"; -import { Button, Icon, NumberInput, Select } from "@hashintel/ds-components"; +import { + Button, + Icon, + NumberInput, + Select, + Toggle, +} from "@hashintel/ds-components"; import { css } from "@hashintel/ds-helpers/css"; import { SimulationContext } from "../../../../../../react/simulation/context"; @@ -8,7 +14,6 @@ import { EditorContext } from "../../../../../../react/state/editor-context"; import { SDCPNContext } from "../../../../../../react/state/sdcpn-context"; import { InfoIconTooltip } from "../../../../../components/info-icon-tooltip"; import { Slider } from "../../../../../components/slider"; -import { Switch } from "../../../../../components/switch"; import { CreateScenarioDrawer } from "../../SimulateView/scenarios/create-scenario-drawer"; import { ViewScenarioDrawer } from "../../SimulateView/scenarios/view-scenario-drawer"; @@ -303,12 +308,13 @@ const SimulationSettingsContent: React.FC = () => {
{param.type === "boolean" && selectedScenario ? ( - + onChange={(checked) => setScenarioParameterValue( param.variableName, checked ? "1" : "0", diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/main.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/main.tsx index 2e29b75348e..c83cb0604e6 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/main.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/main.tsx @@ -6,6 +6,7 @@ import { Icon, Select, TextInput, + Toggle, Tooltip, } from "@hashintel/ds-components"; import { css } from "@hashintel/ds-helpers/css"; @@ -15,7 +16,6 @@ import { usePetrinautMutations } from "../../../../../../../react"; import { EditorContext } from "../../../../../../../react/state/editor-context"; import { SDCPNContext } from "../../../../../../../react/state/sdcpn-context"; import { Section, SectionList } from "../../../../../../components/section"; -import { Switch } from "../../../../../../components/switch"; import { PlaceIcon } from "../../../../../../constants/entity-icons"; import { UI_MESSAGES } from "../../../../../../constants/ui-messages"; import { useDraftField } from "../../../../../../hooks/use-draft-field"; @@ -233,46 +233,55 @@ const PlaceMainContent: React.FC = () => {
( - { - const update: { - dynamicsEnabled: boolean; - differentialEquationId?: string | null; - } = { dynamicsEnabled: checked }; + renderHeaderAction={() => { + const dynamicsTooltip = isReadOnly + ? UI_MESSAGES.READ_ONLY_MODE + : place.colorId === null + ? UI_MESSAGES.DYNAMICS_REQUIRES_TYPE + : availableDiffEqs.length === 0 + ? "Create a differential equation for this type first" + : undefined; - if (checked) { - // Auto-select first available diff eq if none selected or previous no longer exists - const currentIsValid = availableDiffEqs.some( - (eq) => eq.id === place.differentialEquationId, - ); - if (!currentIsValid && availableDiffEqs.length > 0) { - update.differentialEquationId = availableDiffEqs[0]!.id; + return ( + + { + const update: { + dynamicsEnabled: boolean; + differentialEquationId?: string | null; + } = { dynamicsEnabled: checked }; - updatePlace({ - placeId: place.id, - update, - }); - }} - /> - )} + if (checked) { + // Auto-select first available diff eq if none selected or previous no longer exists + const currentIsValid = availableDiffEqs.some( + (eq) => eq.id === place.differentialEquationId, + ); + if (!currentIsValid && availableDiffEqs.length > 0) { + update.differentialEquationId = + availableDiffEqs[0]!.id; + } + } + + updatePlace({ + placeId: place.id, + update, + }); + }} + /> + + ); + }} > {place.colorId === null ? (
diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/place-visualizer/subview.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/place-visualizer/subview.tsx index 02d27be3072..3167e922915 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/place-visualizer/subview.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/PropertiesPanel/place-properties/subviews/place-visualizer/subview.tsx @@ -1,6 +1,6 @@ import { use, useState } from "react"; -import { Button, Icon, Menu, Tooltip } from "@hashintel/ds-components"; +import { Button, Icon, Menu, Toggle, Tooltip } from "@hashintel/ds-components"; import { css } from "@hashintel/ds-helpers/css"; import { DEFAULT_VISUALIZER_CODE, @@ -10,7 +10,6 @@ import { import { ExecutionFrameSourceContext } from "../../../../../../../../react/execution-frame/context"; import { EditorContext } from "../../../../../../../../react/state/editor-context"; import { SegmentGroup } from "../../../../../../../components/segment-group"; -import { Switch } from "../../../../../../../components/switch"; import { UI_MESSAGES } from "../../../../../../../constants/ui-messages"; import { CodeEditor } from "../../../../../../../monaco/code-editor"; import { PlaceStateVisualization } from "../../../../../../shared/place-state-visualization"; @@ -149,33 +148,39 @@ const VisualizerHeaderAction: React.FC = () => { return ( <> {globalMode === "edit" && ( - { - if (checked) { - updatePlace({ - placeId: place.id, - update: { - visualizerCode: - savedVisualizerCode ?? DEFAULT_VISUALIZER_CODE, - }, - }); - } else { - if (place.visualizerCode) { - setSavedVisualizerCodeState({ + + { + if (checked) { + updatePlace({ + placeId: place.id, + update: { + visualizerCode: + savedVisualizerCode ?? DEFAULT_VISUALIZER_CODE, + }, + }); + } else { + if (place.visualizerCode) { + setSavedVisualizerCodeState({ + placeId: place.id, + code: place.visualizerCode, + }); + } + updatePlace({ placeId: place.id, - code: place.visualizerCode, + update: { visualizerCode: undefined }, }); } - updatePlace({ - placeId: place.id, - update: { visualizerCode: undefined }, - }); - } - }} - /> + }} + /> + )} {hasVisualizer && globalMode === "edit" && ( {item.label} @@ -1441,9 +1443,10 @@ export const ExperimentMetricTimeline = ({
Aggregate runs -
{aggregateRuns ? ( @@ -1470,9 +1473,10 @@ export const ExperimentMetricTimeline = ({
Aggregate over time -
{aggregateTime ? ( diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/scenarios/scenario-form.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/scenarios/scenario-form.tsx index 7c83f8d6800..de4c08277e8 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/scenarios/scenario-form.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/scenarios/scenario-form.tsx @@ -6,13 +6,13 @@ import { NumberInput, Select, TextInput, + Toggle, } from "@hashintel/ds-components"; import { css } from "@hashintel/ds-helpers/css"; import { LanguageClientContext } from "../../../../../../react/lsp/context"; import { Section, SectionList } from "../../../../../components/section"; import { Spreadsheet } from "../../../../../components/spreadsheet"; -import { Switch } from "../../../../../components/switch"; import { CodeEditor } from "../../../../../monaco/code-editor"; import { getScenarioDocumentUri } from "../../../../../monaco/editor-paths"; @@ -715,9 +715,10 @@ const ScenarioFormSections = ({ Default {param.type === "boolean" ? (
- + updateScenarioParam(param._key, { default: checked ? 1 : 0, }) @@ -815,17 +816,21 @@ const ScenarioFormSections = ({ {!state.initialStateAsCode && (
Show all places -
)}
Define as code -
diff --git a/libs/@hashintel/petrinaut/src/ui/views/SDCPN/components/viewport-settings-dialog.tsx b/libs/@hashintel/petrinaut/src/ui/views/SDCPN/components/viewport-settings-dialog.tsx index c335ad0d8d2..0121a88a117 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/SDCPN/components/viewport-settings-dialog.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/SDCPN/components/viewport-settings-dialog.tsx @@ -1,10 +1,9 @@ import { use } from "react"; -import { Button, Dialog, Select } from "@hashintel/ds-components"; +import { Button, Dialog, Select, Toggle } from "@hashintel/ds-components"; import { css } from "@hashintel/ds-helpers/css"; import { UserSettingsContext } from "../../../../react/state/user-settings-context"; -import { Switch } from "../../../components/switch"; import type { ArcRendering } from "../../../../react/state/user-settings-context"; @@ -130,24 +129,25 @@ export const ViewportSettingsDialog: React.FC = ({ label="Minimap" description="Show an overview minimap in the top-right corner" > - + - + - + - @@ -172,18 +172,20 @@ export const ViewportSettingsDialog: React.FC = ({ label="Animations" description="Animate panel transitions and UI interactions" > - - = ({ } description="Show a unified tree of all entities in the left sidebar" > -