FontAwesomeIcon react-free

This commit is contained in:
aronmal 2023-10-19 12:31:41 +02:00
parent 8b179b5e65
commit 44bf98e88e
Signed by: aronmal
GPG key ID: 816B7707426FC612
4 changed files with 128 additions and 136 deletions

View file

@ -20,7 +20,6 @@
"@fortawesome/pro-regular-svg-icons": "^6.4.2",
"@fortawesome/pro-solid-svg-icons": "^6.4.2",
"@fortawesome/pro-thin-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@fortawesome/sharp-solid-svg-icons": "^6.4.2",
"@paralleldrive/cuid2": "^2.2.2",
"@solidjs/meta": "^0.28.6",

View file

@ -36,9 +36,6 @@ dependencies:
'@fortawesome/pro-thin-svg-icons':
specifier: ^6.4.2
version: 6.4.2
'@fortawesome/react-fontawesome':
specifier: ^0.2.0
version: 0.2.0(@fortawesome/fontawesome-svg-core@6.4.2)(react@18.2.0)
'@fortawesome/sharp-solid-svg-icons':
specifier: ^6.4.2
version: 6.4.2
@ -1797,17 +1794,6 @@ packages:
'@fortawesome/fontawesome-common-types': 6.4.2
dev: false
/@fortawesome/react-fontawesome@0.2.0(@fortawesome/fontawesome-svg-core@6.4.2)(react@18.2.0):
resolution: {integrity: sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==, tarball: https://npm.fontawesome.com/@fortawesome/react-fontawesome/-/0.2.0/react-fontawesome-0.2.0.tgz}
peerDependencies:
'@fortawesome/fontawesome-svg-core': ~1 || ~6
react: '>=16.3'
dependencies:
'@fortawesome/fontawesome-svg-core': 6.4.2
prop-types: 15.8.1
react: 18.2.0
dev: false
/@fortawesome/sharp-solid-svg-icons@6.4.2:
resolution: {integrity: sha512-b8kA9CxRPmdgoOrELrYHokbF5f0C80SJg9NA+dYcny3SHMsUQCSUacEX1OOIERwRyb1t5ncB2XI9CAPDTQ8wVg==, tarball: https://npm.fontawesome.com/@fortawesome/sharp-solid-svg-icons/-/6.4.2/sharp-solid-svg-icons-6.4.2.tgz}
engines: {node: '>=6'}
@ -4115,13 +4101,6 @@ packages:
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
dependencies:
js-tokens: 4.0.0
dev: false
/lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
dependencies:
@ -4721,14 +4700,6 @@ packages:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
dev: false
/prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react-is: 16.13.1
dev: false
/punycode@2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
@ -4737,17 +4708,6 @@ packages:
/queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
/react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: false
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
dependencies:
loose-envify: 1.4.0
dev: false
/read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies:

View file

@ -1,8 +1,62 @@
import { IconDefinition } from "@fortawesome/fontawesome-svg-core"
import { FontAwesomeIconProps } from "@fortawesome/react-fontawesome"
import classNames from "classnames"
import { Show } from "solid-js"
import classList from "~/lib/utils/get-class-list-from-props"
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 (
@ -19,38 +73,77 @@ function Path(props: { d: string | string[] }) {
)
}
export function FontAwesomeIcon(
props: {
icon: IconDefinition
class?: string
className?: never
} & FontAwesomeIconProps,
) {
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
aria-hidden="true"
role="img"
xmlns="http://www.w3.org/2000/svg"
aria-labelledby={props.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}
class={classNames(
"svg-inline--fa",
"fa-".concat(props.icon.iconName),
classList(props),
props.class,
)}
color={props.color}
style={props.style}
viewBox={`0 0 ${props.icon.icon[0]} ${props.icon.icon[1]}`}
>
<svg {...attributes()}>
<Show when={props.title}>
<title id={props.titleId}>{props.title}</title>
<title id={titleId()}>{props.title}</title>
</Show>
<Path d={props.icon.icon[4]} />
</svg>

View file

@ -1,60 +0,0 @@
/* eslint-disable solid/reactivity */
import { FontAwesomeIconProps } from "@fortawesome/react-fontawesome"
// Get CSS class list from a props object
export default function classList(props: FontAwesomeIconProps) {
const {
beat,
fade,
beatFade,
bounce,
shake,
flash,
spin,
spinPulse,
spinReverse,
pulse,
fixedWidth,
inverse,
border,
listItem,
flip,
size,
rotation,
pull,
} = props
// map of CSS class names to properties
const classes = {
"fa-beat": beat,
"fa-fade": fade,
"fa-beat-fade": beatFade,
"fa-bounce": bounce,
"fa-shake": shake,
"fa-flash": flash,
"fa-spin": spin,
"fa-spin-reverse": spinReverse,
"fa-spin-pulse": spinPulse,
"fa-pulse": pulse,
"fa-fw": fixedWidth,
"fa-inverse": inverse,
"fa-border": border,
"fa-li": listItem,
// @ts-expect-error either true or direction
"fa-flip": flip === true,
"fa-flip-horizontal": flip === "horizontal" || flip === "both",
"fa-flip-vertical": flip === "vertical" || flip === "both",
[`fa-${size}`]: typeof size !== "undefined" && size !== null,
[`fa-rotate-${rotation}`]:
// @ts-expect-error is a direction
typeof rotation !== "undefined" && rotation !== null && rotation !== 0,
[`fa-pull-${pull}`]: typeof pull !== "undefined" && pull !== null,
"fa-swap-opacity": props.swapOpacity,
}
// map over all the keys in the classes object
// return an array of the keys where the value for the key is not null
return Object.keys(classes)
.map((key) => (classes[key] ? key : null))
.filter((key) => key)
}