diff --git a/bun.lockb b/bun.lockb index b1b27fe..79e1130 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index fe8b4f1..6958e2a 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "node-addon-api": "^8.2.1", "polished": "^4.3.1", "sharp": "^0.33.5", - "solid-focus-trap": "^0.1.7", "tailwind-merge": "^2.5.3" }, "devDependencies": { diff --git a/src/renderer/src/components/dropdown-list/DropdownListItem.tsx b/src/renderer/src/components/dropdown-list/DropdownListItem.tsx index ddab6ca..acece81 100644 --- a/src/renderer/src/components/dropdown-list/DropdownListItem.tsx +++ b/src/renderer/src/components/dropdown-list/DropdownListItem.tsx @@ -7,7 +7,7 @@ export type Props = JSX.IntrinsicElements["button"]; const DropdownListItem: Component = (props) => { const state = useDropdownList(); const value = state.namespace.create(); - const { attrs, tabIndex, isSelected } = state.item(value, { + const { attrs, tabIndex } = state.item(value, { onPointerMove: state.handleItemPointerMove, }); @@ -19,10 +19,7 @@ const DropdownListItem: Component = (props) => { ); diff --git a/src/renderer/src/components/popover/Popover.tsx b/src/renderer/src/components/popover/Popover.tsx index 1c4671d..1b2f253 100644 --- a/src/renderer/src/components/popover/Popover.tsx +++ b/src/renderer/src/components/popover/Popover.tsx @@ -30,6 +30,7 @@ import { } from "solid-js"; export const DEFAULT_POPOVER_OPEN = false; +export const DEFAULT_CUSTOM_POSITION_PLACEMENT: Placement = "bottom-start"; export type Props = { offset?: OffsetOptions; @@ -99,24 +100,6 @@ function useProviderValue(props: Props) { handleResize(); }; - let lastMousePos: [number, number]; - const useCustomCoords = { - name: "useCustomCoords", - fn() { - const position = props.position?.(); - if (position === undefined || position === lastMousePos) { - return {}; - } - - const [x, y] = position; - if (x === 0 || y === 0) { - return {}; - } - - return { x, y }; - }, - }; - const handleResize = () => { const trigger = triggerRef(); const content = contentRef(); @@ -125,9 +108,12 @@ function useProviderValue(props: Props) { return; } - const middleware: Middleware[] = [offset(props.offset)]; - if (typeof props.position !== "undefined") { - middleware.push(useCustomCoords); + const [x, y] = props.position?.() ?? []; + const hasCustomPosition = x !== undefined && y !== undefined; + + const middleware: Middleware[] = []; + if (!hasCustomPosition) { + middleware.push(offset(props.offset)); } if (typeof props.flip !== "undefined") { middleware.push(flip(props.flip === true ? undefined : props.flip)); @@ -136,10 +122,35 @@ function useProviderValue(props: Props) { middleware.push(shift(props.shift === true ? undefined : props.shift)); } - computePosition(trigger, content, { - placement: props.placement, - strategy: "fixed", + const getBoundingClientRect = () => { + const triggerRect = trigger.getBoundingClientRect(); + if (!hasCustomPosition) { + return triggerRect; + } + + return { + x, + y, + top: y, + right: x, + bottom: y, + left: x, + width: 0, + height: 0, + }; + }; + + const getPlacement = () => { + if (hasCustomPosition) { + return DEFAULT_CUSTOM_POSITION_PLACEMENT; + } + return props.placement; + }; + + computePosition({ getBoundingClientRect }, content, { middleware, + strategy: "fixed", + placement: getPlacement(), }).then(setPosition); }; diff --git a/src/renderer/src/components/popover/PopoverContent.tsx b/src/renderer/src/components/popover/PopoverContent.tsx index 75b28ef..ea66326 100644 --- a/src/renderer/src/components/popover/PopoverContent.tsx +++ b/src/renderer/src/components/popover/PopoverContent.tsx @@ -1,7 +1,7 @@ import { popoverStack, usePopover } from "./Popover"; import { ComputePositionReturn } from "@floating-ui/dom"; import { cn, sn } from "@renderer/lib/css.utils"; -import createFocusTrap from "solid-focus-trap"; +import createFocusTrap from "@renderer/lib/focus-trap"; import { Component, createMemo, onCleanup, onMount, Show } from "solid-js"; import { JSX } from "solid-js/jsx-runtime"; @@ -20,18 +20,18 @@ export type Props = JSX.IntrinsicElements["div"]; const PopoverContent: Component = (props) => { const state = usePopover(); - const isLastPopoupOpen = createMemo(() => { + const isLastPopupOpen = createMemo(() => { return state.isOpen() && popoverStack().at(-1) === state.id(); }); createFocusTrap({ element: state.contentRef, - enabled: isLastPopoupOpen, + enabled: () => isLastPopupOpen(), }); onMount(() => { const handleKeyUp = (e: KeyboardEvent) => { - if (!isLastPopoupOpen()) { + if (!isLastPopupOpen()) { return; } diff --git a/src/renderer/src/components/popover/PopoverTrigger.tsx b/src/renderer/src/components/popover/PopoverTrigger.tsx index ce8d2e5..2a3333f 100644 --- a/src/renderer/src/components/popover/PopoverTrigger.tsx +++ b/src/renderer/src/components/popover/PopoverTrigger.tsx @@ -1,20 +1,36 @@ import { usePopover } from "./Popover"; -import { Component } from "solid-js"; +import { Component, splitProps, Switch, Match } from "solid-js"; import { JSX } from "solid-js/jsx-runtime"; -export type Props = JSX.IntrinsicElements["button"]; -const PopoverTrigger: Component = (props) => { +type PartialButtonProps = Partial; +export type Props = Omit & { + children?: JSX.Element | ((props: PartialButtonProps) => JSX.Element); +}; + +const PopoverTrigger: Component = (_props) => { const state = usePopover(); + const [props, rest] = splitProps(_props, ["children"]); + + const triggerProps: PartialButtonProps = { + ref: state.setTriggerRef, + // it complains about "data-open" not being a string for some reason + // so we have to cast it to a string + ["data-open" as string]: state.isOpen(), + onClick: () => { + state?.open(); + }, + ...rest, + }; return ( - + + ); }; diff --git a/src/renderer/src/components/raw-list/RawList.tsx b/src/renderer/src/components/raw-list/RawList.tsx index de544a4..d11e30f 100644 --- a/src/renderer/src/components/raw-list/RawList.tsx +++ b/src/renderer/src/components/raw-list/RawList.tsx @@ -10,7 +10,7 @@ export const RawListItem: Component = (_props) return ( - + + {(triggerProps) => ( + + )} + @@ -234,9 +232,16 @@ const RightPart = () => {
- - {(amount) => {amount}} - + setSpeed(Number(newSpeed))} + > + + {(amount) => ( + {amount} + )} + + @@ -247,18 +252,4 @@ const RightPart = () => { ); }; -type SpeedOptionProps = { - amount: number; -}; -const SpeedOption: ParentComponent = (props) => { - return ( - - ); -}; - export default SongControls; diff --git a/src/renderer/src/components/song/song-list-search/SongListSearch.tsx b/src/renderer/src/components/song/song-list-search/SongListSearch.tsx index 874309a..ba643b2 100644 --- a/src/renderer/src/components/song/song-list-search/SongListSearch.tsx +++ b/src/renderer/src/components/song/song-list-search/SongListSearch.tsx @@ -6,7 +6,7 @@ import { SongListSearchTags } from "./SongListSearchTags"; import Button from "@renderer/components/button/Button"; import { Input } from "@renderer/components/input/Input"; import { FilterIcon, SearchIcon, FilterXIcon } from "lucide-solid"; -import { Accessor, Component, createSignal, Match, Setter, Signal, Switch } from "solid-js"; +import { Accessor, Component, createSignal, Match, Setter, Signal, Switch, Show } from "solid-js"; export type SearchProps = { tags: Signal; @@ -109,8 +109,10 @@ const SongListSearch: Component = (props) => { }} >
- - + + + +
diff --git a/src/renderer/src/components/tabs/TabsTrigger.tsx b/src/renderer/src/components/tabs/TabsTrigger.tsx index eb906d3..77fbd50 100644 --- a/src/renderer/src/components/tabs/TabsTrigger.tsx +++ b/src/renderer/src/components/tabs/TabsTrigger.tsx @@ -16,7 +16,7 @@ const TabsTrigger: Component = (_props) => { - + + {(triggerProps) => ( + + )} +