@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
1 lines • 32.8 kB
Source Map (JSON)
{"version":3,"file":"link.cjs","names":["Solid","deepEqual","exactPathTest","functionalUpdate","isDangerousProtocol","preloadWarning","removeTrailingSlash","isServer","Dynamic","useRouter","useIntersectionObserver","useHydrated","AnyRouter","Constrain","LinkOptions","RegisteredRouter","RoutePaths","ValidateLinkOptions","ValidateLinkOptionsArray","mergeRefs","refs","Array","el","T","ref","splitProps","Record","props","keys","ReadonlyArray","TKey","Pick","Omit","_local","_rest","omit","timeoutMap","WeakMap","EventTarget","ReturnType","setTimeout","useLinkProps","TRouter","TFrom","options","UseLinkPropsOptions","TTo","TMaskFrom","TMaskTo","ComponentProps","router","isTransitioning","setIsTransitioning","createSignal","shouldHydrateHash","ssr","hasHydrated","hasRenderFetched","local","rest","merge","activeProps","STATIC_ACTIVE_PROPS_GET","inactiveProps","STATIC_INACTIVE_PROPS_GET","_","propsSafeToSpread","currentLocation","createMemo","stores","location","state","undefined","equals","prev","next","href","_options","_fromLocation","untrack","buildLocation","hrefOption","disabled","maskedLocation","publicHref","external","history","createHref","externalLink","_href","protocolAllowlist","process","env","NODE_ENV","console","warn","to","safeInternal","isSafeInternal","indexOf","URL","preload","reloadDocument","defaultPreload","preloadDelay","defaultPreloadDelay","isActive","activeOptions","current","nextLocation","exact","testExact","pathname","basepath","currentPath","nextPath","pathIsFuzzyEqual","startsWith","length","includeSearch","searchTest","search","partial","ignoreUndefined","explicitUndefined","includeHash","currentHash","hash","doPreload","preloadRoute","_builtLocation","catch","err","preloadViewportIoCallback","entry","IntersectionObserverEntry","isIntersecting","setRefSignal","Element","setRef","runWithOwner","rootMargin","createEffect","preloadValue","externalHref","handleClick","e","MouseEvent","elementTarget","currentTarget","HTMLAnchorElement","SVGAElement","getAttribute","effectiveTarget","target","isCtrlEvent","defaultPrevented","button","preventDefault","unsub","subscribe","navigate","replace","resetScroll","hashScrollIntoView","startTransition","viewTransition","ignoreBlocker","enqueueIntentPreload","FocusEvent","eventTarget","has","set","delete","handleTouchStart","TouchEvent","handleLeave","id","get","clearTimeout","simpleStyling","class","style","onClick","createComposedHandler","onBlur","onFocus","onMouseEnter","onMouseOver","onMouseLeave","onMouseOut","onTouchStart","ResolvedLinkStateProps","JSX","CSSProperties","resolvedProps","active","base","STATIC_DISABLED_PROPS","STATIC_TRANSITIONING_ATTRIBUTES","STATIC_DEFAULT_ACTIVE_ATTRIBUTES","EMPTY_OBJECT","className","filter","Boolean","join","Object","STATIC_ACTIVE_ATTRIBUTES","STATIC_ACTIVE_PROPS","role","callHandler","Event","event","TEvent","handler","EventHandlerUnion","getHandler","fallback","ActiveLinkOptions","ActiveLinkOptionProps","TComp","ActiveLinkProps","Partial","LinkComponentSolidProps","key","LinkProps","LinkPropsChildren","children","ValidComponent","CreateLinkProps","LinkComponentProps","LinkComponent","TDefaultFrom","LinkComponentRoute","defaultFrom","createLink","Comp","_$createComponent","Link","_$mergeProps","_asChild","linkProps","resolvedChildren","ch","Function","svgLinkProps","_el$","_tmpl$","_el$2","firstChild","_$spread","_$insert","_el$3","_tmpl$2","component","metaKey","altKey","ctrlKey","shiftKey","zero","charCodeAt","LinkOptionsFnOptions","TOptions","LinkOptionsFn","linkOptions"],"sources":["../../src/link.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\n\nimport {\n deepEqual,\n exactPathTest,\n functionalUpdate,\n isDangerousProtocol,\n preloadWarning,\n removeTrailingSlash,\n} from '@tanstack/router-core'\n\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { Dynamic } from '@solidjs/web'\nimport { useRouter } from './useRouter'\n\nimport { useIntersectionObserver } from './utils'\n\nimport { useHydrated } from './ClientOnly'\nimport type {\n AnyRouter,\n Constrain,\n LinkOptions,\n RegisteredRouter,\n RoutePaths,\n} from '@tanstack/router-core'\nimport type {\n ValidateLinkOptions,\n ValidateLinkOptionsArray,\n} from './typePrimitives'\n\nfunction mergeRefs<T>(\n ...refs: Array<((el: T) => void) | undefined>\n): (el: T) => void {\n return (el: T) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(el)\n }\n }\n }\n}\n\nfunction splitProps<T extends Record<string, any>, TKey extends keyof T>(\n props: T,\n keys: ReadonlyArray<TKey>,\n): [Pick<T, TKey>, Omit<T, TKey>] {\n const _local = {} as Pick<T, TKey>\n const _rest = {} as Omit<T, TKey>\n\n // A safe way to polyfill splitProps if native getter copy is too complex\n // is just to return [props, Solid.omit(props, keys)] but it modifies typing.\n // Actually, Solid.omit exists!\n // Note: Solid.omit uses rest params (...keys), so we must spread the array.\n return [props as any, Solid.omit(props, ...(keys as any)) as any]\n}\nconst timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()\n\nexport function useLinkProps<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Solid.ComponentProps<'a'> {\n const router = useRouter()\n const [isTransitioning, setIsTransitioning] = Solid.createSignal(false)\n const shouldHydrateHash = !isServer && !!router.options.ssr\n const hasHydrated = useHydrated()\n\n let hasRenderFetched = false\n\n const [local, rest] = splitProps(\n Solid.merge(\n {\n activeProps: STATIC_ACTIVE_PROPS_GET,\n inactiveProps: STATIC_INACTIVE_PROPS_GET,\n },\n options,\n ),\n [\n 'activeProps',\n 'inactiveProps',\n 'activeOptions',\n 'to',\n 'preload',\n 'preloadDelay',\n 'hashScrollIntoView',\n 'replace',\n 'startTransition',\n 'resetScroll',\n 'viewTransition',\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onTouchStart',\n 'ignoreBlocker',\n ],\n )\n\n const [_, propsSafeToSpread] = splitProps(rest, [\n 'params',\n 'search',\n 'hash',\n 'state',\n 'mask',\n 'reloadDocument',\n 'unsafeRelative',\n ] as any)\n\n const currentLocation = Solid.createMemo(\n () => router.stores.location.state,\n undefined,\n { equals: (prev, next) => prev?.href === next?.href },\n )\n\n const _options = () => options\n\n const next = Solid.createMemo(() => {\n // Rebuild when inherited search/hash or the current route context changes.\n const _fromLocation = currentLocation()\n const options = { _fromLocation, ..._options() } as any\n // untrack because router-core will also access stores, which are signals in solid\n return Solid.untrack(() => router.buildLocation(options))\n })\n\n const hrefOption = Solid.createMemo(() => {\n if (_options().disabled) return undefined\n // Use publicHref - it contains the correct href for display\n // When a rewrite changes the origin, publicHref is the full URL\n // Otherwise it's the origin-stripped path\n // This avoids constructing URL objects in the hot path\n const location = next().maskedLocation ?? next()\n const publicHref = location.publicHref\n const external = location.external\n\n if (external) {\n return { href: publicHref, external: true }\n }\n\n return {\n href: router.history.createHref(publicHref) || '/',\n external: false,\n }\n })\n\n const externalLink = Solid.createMemo(() => {\n const _href = hrefOption()\n if (_href?.external) {\n // Block dangerous protocols for external links\n if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${_href.href}`)\n }\n return undefined\n }\n return _href.href\n }\n const to = _options().to\n const safeInternal = isSafeInternal(to)\n if (safeInternal) return undefined\n if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined\n try {\n new URL(to as any)\n // Block dangerous protocols like javascript:, blob:, data:\n if (isDangerousProtocol(to, router.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`Blocked Link with dangerous protocol: ${to}`)\n }\n return undefined\n }\n return to\n } catch {}\n return undefined\n })\n\n const preload = Solid.createMemo(() => {\n if (_options().reloadDocument || externalLink()) {\n return false\n }\n return local.preload ?? router.options.defaultPreload\n })\n const preloadDelay = () =>\n local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = Solid.createMemo(() => {\n if (externalLink()) return false\n const activeOptions = local.activeOptions\n const current = currentLocation()\n const nextLocation = next()\n\n if (activeOptions?.exact) {\n const testExact = exactPathTest(\n current.pathname,\n nextLocation.pathname,\n router.basepath,\n )\n if (!testExact) {\n return false\n }\n } else {\n const currentPath = removeTrailingSlash(current.pathname, router.basepath)\n const nextPath = removeTrailingSlash(\n nextLocation.pathname,\n router.basepath,\n )\n\n const pathIsFuzzyEqual =\n currentPath.startsWith(nextPath) &&\n (currentPath.length === nextPath.length ||\n currentPath[nextPath.length] === '/')\n if (!pathIsFuzzyEqual) {\n return false\n }\n }\n\n if (activeOptions?.includeSearch ?? true) {\n const searchTest = deepEqual(current.search, nextLocation.search, {\n partial: !activeOptions?.exact,\n ignoreUndefined: !activeOptions?.explicitUndefined,\n })\n if (!searchTest) {\n return false\n }\n }\n\n if (activeOptions?.includeHash) {\n const currentHash =\n shouldHydrateHash && !hasHydrated() ? '' : current.hash\n return currentHash === nextLocation.hash\n }\n return true\n })\n\n const doPreload = () =>\n router\n .preloadRoute({ ..._options(), _builtLocation: next() } as any)\n .catch((err: any) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n\n const preloadViewportIoCallback = (\n entry: IntersectionObserverEntry | undefined,\n ) => {\n if (entry?.isIntersecting) {\n doPreload()\n }\n }\n\n const [ref, setRefSignal] = Solid.createSignal<Element | null>(null)\n\n const setRef = (el: Element | null) => {\n Solid.runWithOwner(null, () => {\n setRefSignal(el)\n })\n }\n\n useIntersectionObserver(\n ref,\n preloadViewportIoCallback,\n { rootMargin: '100px' },\n { disabled: !!local.disabled || !(Solid.untrack(preload) === 'viewport') },\n )\n\n Solid.createEffect(preload, (preloadValue) => {\n if (hasRenderFetched) {\n return\n }\n if (!local.disabled && preloadValue === 'render') {\n Solid.untrack(() => doPreload())\n hasRenderFetched = true\n }\n })\n\n if (Solid.untrack(externalLink)) {\n const externalHref = Solid.untrack(externalLink)\n return Solid.merge(\n propsSafeToSpread,\n {\n // ref: mergeRefs(setRef, _options().ref),\n href: externalHref,\n },\n splitProps(local, [\n 'target',\n 'disabled',\n 'style',\n 'class',\n 'onClick',\n 'onBlur',\n 'onFocus',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOut',\n 'onMouseOver',\n 'onTouchStart',\n ])[0],\n ) as any\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n // Check actual element's target attribute as fallback\n const elementTarget = (\n e.currentTarget as HTMLAnchorElement | SVGAElement\n ).getAttribute('target')\n const effectiveTarget =\n local.target !== undefined ? local.target : elementTarget\n\n if (\n !local.disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!effectiveTarget || effectiveTarget === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n Solid.runWithOwner(null, () => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n Solid.runWithOwner(null, () => {\n setIsTransitioning(false)\n })\n })\n\n // All is well? Navigate!\n // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing\n router.navigate({\n ..._options(),\n replace: local.replace,\n resetScroll: local.resetScroll,\n hashScrollIntoView: local.hashScrollIntoView,\n startTransition: local.startTransition,\n viewTransition: local.viewTransition,\n ignoreBlocker: local.ignoreBlocker,\n })\n }\n }\n\n const enqueueIntentPreload = (e: MouseEvent | FocusEvent) => {\n if (local.disabled || preload() !== 'intent') return\n\n if (!preloadDelay()) {\n doPreload()\n return\n }\n\n const eventTarget = e.currentTarget || e.target\n\n if (!eventTarget || timeoutMap.has(eventTarget)) return\n\n timeoutMap.set(\n eventTarget,\n setTimeout(() => {\n timeoutMap.delete(eventTarget)\n doPreload()\n }, preloadDelay()),\n )\n }\n\n const handleTouchStart = (_: TouchEvent) => {\n if (local.disabled || preload() !== 'intent') return\n doPreload()\n }\n\n const handleLeave = (e: MouseEvent | FocusEvent) => {\n if (local.disabled) return\n const eventTarget = e.currentTarget || e.target\n\n if (eventTarget) {\n const id = timeoutMap.get(eventTarget)\n clearTimeout(id)\n timeoutMap.delete(eventTarget)\n }\n }\n\n const simpleStyling = Solid.createMemo(\n () =>\n local.activeProps === STATIC_ACTIVE_PROPS_GET &&\n local.inactiveProps === STATIC_INACTIVE_PROPS_GET &&\n local.class === undefined &&\n local.style === undefined,\n )\n\n const onClick = createComposedHandler(() => local.onClick, handleClick)\n const onBlur = createComposedHandler(() => local.onBlur, handleLeave)\n const onFocus = createComposedHandler(\n () => local.onFocus,\n enqueueIntentPreload,\n )\n const onMouseEnter = createComposedHandler(\n () => local.onMouseEnter,\n enqueueIntentPreload,\n )\n const onMouseOver = createComposedHandler(\n () => local.onMouseOver,\n enqueueIntentPreload,\n )\n const onMouseLeave = createComposedHandler(\n () => local.onMouseLeave,\n handleLeave,\n )\n const onMouseOut = createComposedHandler(() => local.onMouseOut, handleLeave)\n const onTouchStart = createComposedHandler(\n () => local.onTouchStart,\n handleTouchStart,\n )\n\n type ResolvedLinkStateProps = Omit<Solid.ComponentProps<'a'>, 'style'> & {\n style?: Solid.JSX.CSSProperties\n }\n\n const resolvedProps = Solid.createMemo(() => {\n const active = isActive()\n\n const base = {\n href: hrefOption()?.href,\n ref: mergeRefs(setRef, _options().ref as any),\n onClick,\n onBlur,\n onFocus,\n onMouseEnter,\n onMouseOver,\n onMouseLeave,\n onMouseOut,\n onTouchStart,\n disabled: !!local.disabled,\n target: local.target,\n ...(local.disabled && STATIC_DISABLED_PROPS),\n ...(isTransitioning() && STATIC_TRANSITIONING_ATTRIBUTES),\n }\n\n if (simpleStyling()) {\n return {\n ...base,\n ...(active && STATIC_DEFAULT_ACTIVE_ATTRIBUTES),\n }\n }\n\n const activeProps: ResolvedLinkStateProps = active\n ? (functionalUpdate(local.activeProps as any, {}) ?? EMPTY_OBJECT)\n : EMPTY_OBJECT\n const inactiveProps: ResolvedLinkStateProps = active\n ? EMPTY_OBJECT\n : functionalUpdate(local.inactiveProps, {})\n const style = {\n ...local.style,\n ...activeProps.style,\n ...inactiveProps.style,\n }\n const className = [local.class, activeProps.class, inactiveProps.class]\n .filter(Boolean)\n .join(' ')\n\n return {\n ...activeProps,\n ...inactiveProps,\n ...base,\n ...(Object.keys(style).length ? { style } : undefined),\n ...(className ? { class: className } : undefined),\n ...(active && STATIC_ACTIVE_ATTRIBUTES),\n } as ResolvedLinkStateProps\n })\n\n return Solid.merge(propsSafeToSpread, resolvedProps) as any\n}\n\nconst STATIC_ACTIVE_PROPS = { class: 'active' }\nconst STATIC_ACTIVE_PROPS_GET = () => STATIC_ACTIVE_PROPS\nconst EMPTY_OBJECT = {}\nconst STATIC_INACTIVE_PROPS_GET = () => EMPTY_OBJECT\nconst STATIC_DEFAULT_ACTIVE_ATTRIBUTES = {\n class: 'active',\n 'data-status': 'active',\n 'aria-current': 'page',\n}\nconst STATIC_DISABLED_PROPS = {\n role: 'link',\n 'aria-disabled': 'true',\n}\nconst STATIC_ACTIVE_ATTRIBUTES = {\n 'data-status': 'active',\n 'aria-current': 'page',\n}\nconst STATIC_TRANSITIONING_ATTRIBUTES = {\n 'data-transitioning': 'transitioning',\n}\n\n/** Call a JSX.EventHandlerUnion with the event. */\nfunction callHandler<T, TEvent extends Event>(\n event: TEvent & { currentTarget: T; target: Element },\n handler: Solid.JSX.EventHandlerUnion<T, TEvent>,\n) {\n if (typeof handler === 'function') {\n handler(event)\n } else {\n handler[0](handler[1], event)\n }\n return event.defaultPrevented\n}\n\nfunction createComposedHandler<T, TEvent extends Event>(\n getHandler: () => Solid.JSX.EventHandlerUnion<T, TEvent> | undefined,\n fallback: (event: TEvent) => void,\n) {\n return (event: TEvent & { currentTarget: T; target: Element }) => {\n const handler = getHandler()\n if (!handler || !callHandler(event, handler)) fallback(event)\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<'a', TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n Omit<Solid.ComponentProps<'a'>, 'style'> & { style?: Solid.JSX.CSSProperties }\n\nexport type ActiveLinkOptions<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n ActiveLinkOptionProps<TComp>\n\ntype ActiveLinkProps<TComp> = Partial<\n LinkComponentSolidProps<TComp> & {\n [key: `data-${string}`]: unknown\n }\n>\n\nexport interface ActiveLinkOptionProps<TComp = 'a'> {\n /**\n * A function that returns additional props for the `active` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n activeProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n /**\n * A function that returns additional props for the `inactive` state of this link.\n * These props override other props passed to the link (`style`'s are merged, `class`'s are concatenated)\n */\n inactiveProps?: ActiveLinkProps<TComp> | (() => ActiveLinkProps<TComp>)\n}\n\nexport type LinkProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = ActiveLinkOptions<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkPropsChildren\n\nexport interface LinkPropsChildren {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | Solid.JSX.Element\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => Solid.JSX.Element)\n}\n\ntype LinkComponentSolidProps<TComp> = TComp extends Solid.ValidComponent\n ? Omit<Solid.ComponentProps<TComp>, keyof CreateLinkProps>\n : never\n\nexport type LinkComponentProps<\n TComp = 'a',\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = '.',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = LinkComponentSolidProps<TComp> &\n LinkProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type CreateLinkProps = LinkProps<\n any,\n any,\n string,\n string,\n string,\n string\n>\n\nexport type LinkComponent<\n in out TComp,\n in out TDefaultFrom extends string = string,\n> = <\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string = TDefaultFrom,\n const TTo extends string | undefined = undefined,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n props: LinkComponentProps<TComp, TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => Solid.JSX.Element\n\nexport interface LinkComponentRoute<\n in out TDefaultFrom extends string = string,\n> {\n defaultFrom: TDefaultFrom;\n <\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = undefined,\n const TMaskTo extends string = '',\n >(\n props: LinkComponentProps<\n 'a',\n TRouter,\n this['defaultFrom'],\n TTo,\n this['defaultFrom'],\n TMaskTo\n >,\n ): Solid.JSX.Element\n}\n\nexport function createLink<const TComp>(\n Comp: Constrain<TComp, any, (props: CreateLinkProps) => Solid.JSX.Element>,\n): LinkComponent<TComp> {\n return (props) => <Link {...props} _asChild={Comp} />\n}\n\nexport const Link: LinkComponent<'a'> = (props) => {\n const [local, rest] = splitProps(props as typeof props & { _asChild: any }, [\n '_asChild',\n 'children',\n ])\n\n const [_, linkProps] = splitProps(useLinkProps(rest as unknown as any), [\n 'type',\n ])\n\n // Resolve children once using Solid.children to avoid\n // re-accessing the children getter (which in Solid 2.0 would\n // re-invoke createComponent each time for JSX children).\n const resolvedChildren = Solid.children(\n () => local.children as Solid.JSX.Element,\n )\n\n const children = () => {\n const ch = resolvedChildren()\n if (typeof ch === 'function') {\n return (ch as Function)({\n get isActive() {\n return (linkProps as any)['data-status'] === 'active'\n },\n get isTransitioning() {\n return (linkProps as any)['data-transitioning'] === 'transitioning'\n },\n })\n }\n\n return ch\n }\n\n if (local._asChild === 'svg') {\n const [_, svgLinkProps] = splitProps(linkProps as any, ['class'])\n return (\n <svg>\n <a {...svgLinkProps}>{children()}</a>\n </svg>\n )\n }\n\n if (!local._asChild) {\n return <a {...linkProps}>{children()}</a>\n }\n\n return (\n <Dynamic component={local._asChild as Solid.ValidComponent} {...linkProps}>\n {children()}\n </Dynamic>\n )\n}\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n\nfunction isSafeInternal(to: unknown) {\n if (typeof to !== 'string') return false\n const zero = to.charCodeAt(0)\n if (zero === 47) return to.charCodeAt(1) !== 47 // '/' but not '//'\n return zero === 46 // '.', '..', './', '../'\n}\n\nexport type LinkOptionsFnOptions<\n TOptions,\n TComp,\n TRouter extends AnyRouter = RegisteredRouter,\n> =\n TOptions extends ReadonlyArray<any>\n ? ValidateLinkOptionsArray<TRouter, TOptions, string, TComp>\n : ValidateLinkOptions<TRouter, TOptions, string, TComp>\n\nexport type LinkOptionsFn<TComp> = <\n const TOptions,\n TRouter extends AnyRouter = RegisteredRouter,\n>(\n options: LinkOptionsFnOptions<TOptions, TComp, TRouter>,\n) => TOptions\n\nexport const linkOptions: LinkOptionsFn<'a'> = (options) => {\n return options as any\n}\n"],"mappings":"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"}