Improved Links
This commit is contained in:
parent
7390bcbc01
commit
85f1ce262a
14 changed files with 461 additions and 315 deletions
|
@ -1,8 +1,9 @@
|
|||
import { Show } from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
|
||||
function DeviceTile(props: { href?: string; name: string; src: string }) {
|
||||
return (
|
||||
<a href={props.href ?? "/soon"}>
|
||||
<A href={props.href ?? "/soon"}>
|
||||
<div class="raster">
|
||||
<h3>{props.name}</h3>
|
||||
<Show when={props.src.startsWith("/images")}>
|
||||
|
@ -14,7 +15,7 @@ function DeviceTile(props: { href?: string; name: string; src: string }) {
|
|||
</video>
|
||||
</Show>
|
||||
</div>
|
||||
</a>
|
||||
</A>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
113
src/components/FontAwesomeIcon.tsx
Normal file
113
src/components/FontAwesomeIcon.tsx
Normal file
|
@ -0,0 +1,113 @@
|
|||
import { FaSymbol, FlipProp, IconDefinition, IconProp, PullProp, RotateProp, SizeProp, Transform } from "@fortawesome/fontawesome-svg-core";
|
||||
import { Show, type JSX } from "solid-js";
|
||||
|
||||
export interface FontAwesomeIconProps extends Omit<JSX.SvgSVGAttributes<SVGSVGElement>, "children" | "mask" | "transform"> {
|
||||
icon: IconDefinition;
|
||||
mask?: IconProp;
|
||||
maskId?: string;
|
||||
color?: string;
|
||||
spin?: boolean;
|
||||
spinPulse?: boolean;
|
||||
spinReverse?: boolean;
|
||||
pulse?: boolean;
|
||||
beat?: boolean;
|
||||
fade?: boolean;
|
||||
beatFade?: boolean;
|
||||
bounce?: boolean;
|
||||
shake?: boolean;
|
||||
flash?: boolean;
|
||||
border?: boolean;
|
||||
fixedWidth?: boolean;
|
||||
inverse?: boolean;
|
||||
listItem?: boolean;
|
||||
flip?: FlipProp;
|
||||
size?: SizeProp;
|
||||
pull?: PullProp;
|
||||
rotation?: RotateProp;
|
||||
transform?: string | Transform;
|
||||
symbol?: FaSymbol;
|
||||
style?: JSX.CSSProperties;
|
||||
tabIndex?: number;
|
||||
title?: string;
|
||||
titleId?: string;
|
||||
swapOpacity?: boolean;
|
||||
}
|
||||
|
||||
const idPool = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
function nextUniqueId() {
|
||||
let size = 12;
|
||||
let id = "";
|
||||
|
||||
while (size-- > 0) {
|
||||
id += idPool[(Math.random() * 62) | 0];
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
function Path(props: { d: string | string[] }) {
|
||||
return (
|
||||
<>
|
||||
{typeof props.d === "string" ? (
|
||||
<path fill="currentColor" d={props.d} />
|
||||
) : (
|
||||
<>
|
||||
<path class="fa-secondary" fill="currentColor" d={props.d[0]} />
|
||||
<path class="fa-primary" fill="currentColor" d={props.d[1]} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function FontAwesomeIcon(props: FontAwesomeIconProps) {
|
||||
const titleId = () => (props.title ? "svg-inline--fa-title-".concat(props.titleId || nextUniqueId()) : undefined);
|
||||
// Get CSS class list from the props object
|
||||
function attributes() {
|
||||
const defaultClasses = {
|
||||
"svg-inline--fa": true,
|
||||
[`fa-${props.icon.iconName}`]: true,
|
||||
[props.class ?? ""]: typeof props.class !== "undefined" && props.class !== null,
|
||||
...props.classList,
|
||||
};
|
||||
|
||||
// map of CSS class names to properties
|
||||
const faClasses = {
|
||||
"fa-beat": props.beat,
|
||||
"fa-fade": props.fade,
|
||||
"fa-beat-fade": props.beatFade,
|
||||
"fa-bounce": props.bounce,
|
||||
"fa-shake": props.shake,
|
||||
"fa-flash": props.flash,
|
||||
"fa-spin": props.spin,
|
||||
"fa-spin-reverse": props.spinReverse,
|
||||
"fa-spin-pulse": props.spinPulse,
|
||||
"fa-pulse": props.pulse,
|
||||
"fa-fw": props.fixedWidth,
|
||||
"fa-inverse": props.inverse,
|
||||
"fa-border": props.border,
|
||||
"fa-li": props.listItem,
|
||||
"fa-flip": typeof props.flip !== "undefined" && props.flip !== null,
|
||||
"fa-flip-horizontal": props.flip === "horizontal" || props.flip === "both",
|
||||
"fa-flip-vertical": props.flip === "vertical" || props.flip === "both",
|
||||
[`fa-${props.size}`]: typeof props.size !== "undefined" && props.size !== null,
|
||||
[`fa-rotate-${props.rotation}`]: typeof props.rotation !== "undefined" && props.size !== null,
|
||||
[`fa-pull-${props.pull}`]: typeof props.pull !== "undefined" && props.pull !== null,
|
||||
"fa-swap-opacity": props.swapOpacity,
|
||||
};
|
||||
|
||||
const attributes = { focusable: !!props.title, "aria-hidden": !props.title, role: "img", xmlns: "http://www.w3.org/2000/svg", "aria-labelledby": titleId(), "data-prefix": props.icon.prefix, "data-icon": props.icon.iconName, "data-fa-transform": props.transform, "data-fa-mask": props.mask, "data-fa-mask-id": props.maskId, "data-fa-symbol": props.symbol, tabIndex: props.tabIndex, classList: { ...defaultClasses, ...faClasses }, color: props.color, style: props.style, viewBox: `0 0 ${props.icon.icon[0]} ${props.icon.icon[1]}` } as const;
|
||||
|
||||
// return the complete class list
|
||||
return attributes;
|
||||
}
|
||||
|
||||
return (
|
||||
<svg {...attributes()}>
|
||||
<Show when={props.title}>
|
||||
<title id={titleId()}>{props.title}</title>
|
||||
</Show>
|
||||
<Path d={props.icon.icon[4]} />
|
||||
</svg>
|
||||
);
|
||||
}
|
42
src/components/Reference.tsx
Normal file
42
src/components/Reference.tsx
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { faArrowUpRightFromSquare, faBookOpen, faHashtag } from "@fortawesome/pro-regular-svg-icons";
|
||||
import { JSXElement, Show, createMemo } from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
import { FontAwesomeIcon } from "./FontAwesomeIcon";
|
||||
|
||||
const types = {
|
||||
external: faArrowUpRightFromSquare,
|
||||
page: faBookOpen,
|
||||
id: faHashtag,
|
||||
};
|
||||
|
||||
/**
|
||||
* References to local and external resouces
|
||||
*/
|
||||
function R(props: { href: string; children: JSXElement; class?: string; id?: string }) {
|
||||
const type = createMemo((): keyof typeof types => {
|
||||
switch (true) {
|
||||
case props.href.startsWith("http"):
|
||||
return "external";
|
||||
case props.href.startsWith("#"):
|
||||
return "id";
|
||||
case props.href.startsWith("/"):
|
||||
return "page";
|
||||
default:
|
||||
console.warn("StartsWith is unknown:", props.href);
|
||||
return "external";
|
||||
}
|
||||
});
|
||||
return (
|
||||
<A href={props.href} target={type() === "external" ? "_blank" : ""} rel={type() === "external" ? "noreferrer noopener" : ""} id={props.id} class={props.class}>
|
||||
<Show when={type() === "id"}>
|
||||
<FontAwesomeIcon class="left" icon={types["id"]} />
|
||||
</Show>
|
||||
{props.children}
|
||||
<Show when={type() !== "id"}>
|
||||
<FontAwesomeIcon class="right" icon={types[type()]} title={type()} />
|
||||
</Show>
|
||||
</A>
|
||||
);
|
||||
}
|
||||
|
||||
export default R;
|
Loading…
Add table
Add a link
Reference in a new issue