From 30183cb014c8bf69f263ee14c1807b139b50401d Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 30 Mar 2026 09:42:26 -0400 Subject: [PATCH 01/10] add FocusChin to the guide toolbar v2 with dedicated controls --- .../guide/components/Toolbar/V2/FocusChin.tsx | 174 ++++++++++++++++++ .../guide/components/Toolbar/V2/V2.tsx | 75 ++++---- .../guide/components/Toolbar/V2/helpers.ts | 2 + .../guide/components/Toolbar/styles.css | 2 +- 4 files changed, 214 insertions(+), 39 deletions(-) create mode 100644 packages/react/src/modules/guide/components/Toolbar/V2/FocusChin.tsx diff --git a/packages/react/src/modules/guide/components/Toolbar/V2/FocusChin.tsx b/packages/react/src/modules/guide/components/Toolbar/V2/FocusChin.tsx new file mode 100644 index 000000000..2ff3463ce --- /dev/null +++ b/packages/react/src/modules/guide/components/Toolbar/V2/FocusChin.tsx @@ -0,0 +1,174 @@ +import { useGuideContext, useStore } from "@knocklabs/react-core"; +import { Button } from "@telegraph/button"; +import { Box, Stack } from "@telegraph/layout"; +import { Tooltip } from "@telegraph/tooltip"; +import { Text } from "@telegraph/typography"; +import { ChevronLeft, ChevronRight, X } from "lucide-react"; + +import { DisplayOption } from "./helpers"; +// import React from "react"; + +import { InspectionResultOk } from "./useInspectGuideClientStore"; + +// const findNextPrevKey = ( +// currKey: string, +// guides: InspectionResultOk["guides"] +// ) => { +// const selectableGuides = guides.filter(g => !!g.annotation.selectable); +// const currIndex = selectableGuides.findIndex(g => g.key === currKey); +// +// const prevGuide = currIndex === 0 +// ? undefined +// : selectableGuides[currIndex - 1]; +// +// const nextGuide = currIndex + 1 > selectableGuides.length - 1 +// ? undefined +// : selectableGuides[currIndex + 1]; +// +// return { prev: prevGuide, next: nextGuide }; +// } +// const findNextGuideKey = ( +// currKey: string, +// guides: InspectionResultOk["guides"] +// ) => { +// const selectableGuides = guides.filter(g => !!g.annotation.selectable); +// const currIndex = selectableGuides.findIndex(g => g.key === currKey); +// +// const prevGuide = currIndex === 0 +// ? undefined +// : selectableGuides[currIndex - 1]; +// +// const nextGuide = currIndex + 1 > selectableGuides.length - 1 +// ? undefined +// : selectableGuides[currIndex + 1]; +// +// return { prev: prevGuide, next: nextGuide }; +// } + +type Props = { + guides: InspectionResultOk["guides"]; + displayOption: DisplayOption; +}; + +export const FocusChin = ({ guides, displayOption }: Props) => { + const { client } = useGuideContext(); + const { debugSettings } = useStore(client.store, (state) => ({ + debugSettings: state.debug || {}, + })); + + const focusedKeys = Object.keys(debugSettings.focusedGuideKeys || {}); + + // const { prev, next } = React.useMemo(() => { + // if (focusedKeys.length === 0) { + // return {} + // } + // const currentKey = focusedKeys[0]; + // + // return findNextAndPrevGuideKey(currentKey, guides) + // }, [displayOption, focusedKeys.length]); + + const isFocused = focusedKeys.length > 0; + if (!isFocused) { + return null; + } + + const currentKey = focusedKeys[0]; + + // const currentIndex = currentKey ? guideKeys.indexOf(currentKey) : -1; + + // const setFocus = (key: string) => { + // client.setDebug({ + // ...debugSettings, + // focusedGuideKeys: { [key]: true }, + // }); + // }; + // + // const hasPrev = currentIndex > 0; + // const hasNext = currentIndex >= 0 && currentIndex < guideKeys.length - 1; + + return ( + + + + Focus lock: {currentKey} + + + +