Buckets:
| import { Tooltip as KobalteTooltip } from "@kobalte/core/tooltip" | |
| import { createEffect, Match, onCleanup, splitProps, Switch, type JSX } from "solid-js" | |
| import type { ComponentProps } from "solid-js" | |
| import { createStore } from "solid-js/store" | |
| import "./tooltip-v2.css" | |
| export interface TooltipV2Props extends ComponentProps<typeof KobalteTooltip> { | |
| value: JSX.Element | |
| class?: string | |
| contentClass?: string | |
| contentStyle?: JSX.CSSProperties | |
| inactive?: boolean | |
| forceOpen?: boolean | |
| } | |
| export function TooltipV2(props: TooltipV2Props) { | |
| let ref: HTMLDivElement | undefined | |
| const [state, setState] = createStore({ | |
| open: false, | |
| block: false, | |
| expand: false, | |
| }) | |
| const [local, others] = splitProps(props, [ | |
| "children", | |
| "class", | |
| "contentClass", | |
| "contentStyle", | |
| "inactive", | |
| "forceOpen", | |
| "ignoreSafeArea", | |
| "value", | |
| ]) | |
| const close = () => setState("open", false) | |
| const inside = () => { | |
| const active = document.activeElement | |
| if (!ref || !active) return false | |
| return ref.contains(active) | |
| } | |
| const drop = (expand = state.expand) => { | |
| if (expand) return | |
| if (ref?.matches(":hover")) return | |
| if (inside()) return | |
| setState("block", false) | |
| } | |
| const sync = () => { | |
| const expand = !!ref?.querySelector('[aria-expanded="true"], [data-expanded]') | |
| setState("expand", expand) | |
| if (expand) { | |
| setState("block", true) | |
| close() | |
| return | |
| } | |
| drop(expand) | |
| } | |
| const arm = () => { | |
| setState("block", true) | |
| close() | |
| } | |
| const leave = () => { | |
| if (!inside()) close() | |
| drop() | |
| } | |
| createEffect(() => { | |
| if (!ref) return | |
| sync() | |
| const obs = new MutationObserver(sync) | |
| obs.observe(ref, { | |
| subtree: true, | |
| childList: true, | |
| attributes: true, | |
| attributeFilter: ["aria-expanded", "data-expanded"], | |
| }) | |
| onCleanup(() => obs.disconnect()) | |
| }) | |
| let justClickedTrigger = false | |
| return ( | |
| <Switch> | |
| <Match when={local.inactive}>{local.children}</Match> | |
| <Match when={true}> | |
| <KobalteTooltip | |
| gutter={4} | |
| {...others} | |
| openDelay={0} | |
| closeDelay={0} | |
| ignoreSafeArea={local.ignoreSafeArea ?? true} | |
| open={local.forceOpen || state.open} | |
| onOpenChange={(open) => { | |
| if (local.forceOpen) return | |
| if (state.block && open) return | |
| if (justClickedTrigger) { | |
| justClickedTrigger = false | |
| return | |
| } | |
| setState("open", open) | |
| }} | |
| > | |
| <KobalteTooltip.Trigger | |
| ref={ref} | |
| as="div" | |
| data-component="tooltip-v2-trigger" | |
| class={local.class} | |
| onPointerDownCapture={arm} | |
| onKeyDownCapture={(event: KeyboardEvent) => { | |
| if (event.key !== "Enter" && event.key !== " ") return | |
| arm() | |
| }} | |
| onPointerLeave={leave} | |
| onFocusOut={() => requestAnimationFrame(() => drop())} | |
| > | |
| {local.children} | |
| </KobalteTooltip.Trigger> | |
| <KobalteTooltip.Portal> | |
| <KobalteTooltip.Content | |
| ref={(el) => { | |
| const theme = ref?.closest("[data-theme]")?.getAttribute("data-theme") | |
| if (theme) el.setAttribute("data-theme", theme) | |
| }} | |
| data-component="tooltip-v2" | |
| data-placement={props.placement} | |
| data-force-open={local.forceOpen} | |
| class={local.contentClass} | |
| style={local.contentStyle} | |
| onPointerDownOutside={(e) => { | |
| if (ref === e.target || (e.target instanceof Node && ref?.contains(e.target))) { | |
| justClickedTrigger = true | |
| } | |
| e.preventDefault() | |
| }} | |
| > | |
| {local.value} | |
| </KobalteTooltip.Content> | |
| </KobalteTooltip.Portal> | |
| </KobalteTooltip> | |
| </Match> | |
| </Switch> | |
| ) | |
| } | |
Xet Storage Details
- Size:
- 4.01 kB
- Xet hash:
- 9bdb44f60d779052a3adbc39a1e3ee65d14111bb2ffc39749b57ea4d4288079c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.