Icons in SolidJS
Ein eigenes Solid-Paket gibt es noch nicht, und Sie kommen auch ohne aus. Das Element <glyph-fox> funktioniert in Solid-Templates, und eine Komponente aus wenigen Zeilen auf Basis von glyphfox/core liefert Ihnen reaktive, tree-shakable Icons, die auf dem Server rendern.
Installation
Installieren Sie das Kernpaket. Alles auf dieser Seite nutzt Einstiegspunkte, die darin enthalten sind: glyphfox/web für das Element sowie glyphfox/core mit glyphfox/icons/NAME für die Komponente.
npm install glyphfox
| Aspekt | glyph-fox-Element | Glyph-Komponente |
|---|---|---|
| Rendert | Im Browser, beim Upgrade des Elements. | Auf dem Server und im Browser. |
| Liefert aus | Das Element, seine Engine und die Icons, die Sie registrieren. | Den Renderer und die Icon-Module, die Sie importieren. |
| Animation | Morphs bei jedem Namenswechsel, Auslöser für Hover und Klick, Zustände. | CSS-Animationen im SVG: Presets und Hover-Morphs. |
| Geeignet für | Icons, die auf Benutzeraktionen reagieren. | Die meisten Icons einer App. |
Das glyph-fox-Element
Registrieren Sie das Element einmalig in Ihrer Einstiegsdatei. glyphfox/web registriert alle Icons; damit das Bundle nur die von Ihnen aufgeführten Icons enthält, verwenden Sie glyphfox/web/element mit registerIcons, wie in der Anleitung zu Web Components gezeigt.
import { render } from 'solid-js/web'; import 'glyphfox/web'; import App from './App'; render(() => <App />, document.getElementById('root'));
Statische Attribute werden in das Template kompiliert, erreichen das Element also als Attribute und funktionieren so, wie sie geschrieben sind:
export function Toolbar() { return ( <div class="toolbar"> <glyph-fox name="settings" size="20" weight="1.5" /> <glyph-fox name="bell" animate="shake" trigger="hover" /> </div> ); }
Bei dynamischen Werten ist das anders. Auf Custom Elements weist Solid Ausdrücke als Properties zu, und <glyph-fox> hat keine Properties: Es liest Attribute. Stellen Sie dynamischen Props den Namespace attr: voran, damit Solid stattdessen das Attribut setzt.
import { createSignal } from 'solid-js'; export function MenuButton() { const [open, setOpen] = createSignal(false); return ( <button type="button" aria-expanded={open()} aria-label={open() ? 'Close menu' : 'Open menu'} onClick={() => setOpen(!open())} > <glyph-fox attr:name={open() ? 'x' : 'menu'} morph duration="300" /> </button> ); }
Mit dem Attribut morph animiert das Element jede Änderung von name, sodass jedes Umschalten des Signals den von Hand abgestimmten Morph vom Menü- zum Schließen-Icon abspielt. Events brauchen keine Sonderbehandlung: onClick an einem Elternelement funktioniert wie gewohnt, und Auslöser wie trigger="click" verarbeitet das Element intern.
TypeScript
Die JSX-Typen von Solid kennen glyph-fox nicht. Deklarieren Sie das Element einmalig in einer Deklarationsdatei, und tragen Sie die Attribute, die Sie über attr: setzen, in ExplicitAttributes ein, dem Interface, das Solid für diesen Namespace ausliest.
import 'solid-js'; type GlyphFoxAttributes = { name?: string; size?: string | number; color?: string; weight?: string | number; variant?: 'outline' | 'duotone' | 'solid'; animate?: 'draw' | 'pop' | 'wiggle' | 'spin' | 'pulse' | 'bounce' | 'shake'; trigger?: 'mount' | 'hover' | 'click' | 'state'; morph?: boolean | string; 'morph-to'?: string; duration?: string | number; }; declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'glyph-fox': JSX.HTMLAttributes<HTMLElement> & GlyphFoxAttributes; } interface ExplicitAttributes { name: string; size: string | number; active: boolean | string; } } }
Eine kleine Glyph-Komponente
Für Icons, die die eingebaute Interaktion des Elements nicht brauchen, rendern Sie das SVG selbst. renderToString aus glyphfox/core wandelt Icon-Daten in Markup um und unterstützt dabei alle gemeinsamen Props. Jedes Modul unter glyphfox/icons/NAME enthält die Daten genau eines Icons, sodass das Bundle nur enthält, was Sie importieren.
import { splitProps } from 'solid-js'; import { renderToString } from 'glyphfox/core'; export function Glyph(props) { const [local, options] = splitProps(props, ['icon', 'class']); return ( <span class={local.class} style={{ display: 'inline-flex', 'line-height': '0' }} innerHTML={renderToString(local.icon, options)} /> ); }
import { Glyph } from './Glyph'; import home from 'glyphfox/icons/home'; import bell from 'glyphfox/icons/bell'; export function Nav(props) { return ( <nav> <a href="/"> <Glyph icon={home} size={20} /> Home </a> <button type="button" aria-label="Notifications"> <Glyph icon={bell} animate="shake" trigger="state" active={props.unread > 0} /> </button> </nav> ); }
Der Effekt hinter innerHTML verfolgt alle Props, die renderToString liest, daher schreibt eine Änderung von active, size oder icon das Markup neu. Das Markup wird ersetzt, nicht animiert überblendet. Für einen Morph zwischen zwei Icons verwenden Sie das Element oder einen CSS-Morph beim Hover mit morphTo:
import { Glyph } from './Glyph'; import arrowRight from 'glyphfox/icons/arrow-right'; import chevronRight from 'glyphfox/icons/chevron-right'; export const NextLink = () => ( <a href="/next" class="next"> Next <Glyph icon={arrowRight} morphTo={chevronRight} trigger="hover" /> </a> );
Mit glyphfox/core erwartet morphTo Icon-Daten, keinen Namen: Nur toSvg im Haupteinstiegspunkt löst Namen auf. Ein hier übergebener Name wird ignoriert, und das Icon bleibt unbewegt. Der CSS-Morph läuft, solange sich der Zeiger über dem svg-Element oder seinem direkten Elternelement befindet, in dieser Komponente also über dem Wrapper-Span.
Auch die Namenssyntax (file+check@tr, cloud&lock) wird von toSvg aufgelöst. Mit dem Core verwenden Sie stattdessen die entsprechenden Props und Hilfsfunktionen: modifier und modifierCorner für Badges, fuse für Fusionen.
import { fuse } from 'glyphfox/core'; import { Glyph } from './Glyph'; import file from 'glyphfox/icons/file'; import cloud from 'glyphfox/icons/cloud'; import lock from 'glyphfox/icons/lock'; const secureCloud = fuse([cloud, lock], { layout: 'overlap' }); export const Status = () => ( <p> <Glyph icon={file} modifier="check" modifierCorner="top-right" title="Saved" /> <Glyph icon={secureCloud} size={32} title="Encrypted backup" /> </p> );
SolidStart und serverseitiges Rendering
Die Glyph-Komponente rendert auf dem Server wie jedes andere Markup: SolidStart schreibt das SVG ins HTML, daher sind die Icons Teil der ersten Darstellung, und das Layout verschiebt sich bei der Hydration nicht.
Das Element ist ein Browser-Feature. Sein Upgrade erfolgt erst, nachdem sein Skript gelaufen ist, und es nutzt kein deklaratives Shadow DOM, daher enthält das Server-HTML das leere Tag. Reservieren Sie seine Box per CSS, oder setzen Sie für Icons, die sofort sichtbar sein müssen, weiterhin auf die Glyph-Komponente. Die Abwägungen für jedes Framework finden Sie unter Serverseitiges Rendering.
glyph-fox:not(:defined) { display: inline-block; width: 24px; height: 24px; }
Ein Import von glyphfox/web auf dem Server ist unproblematisch: Das Element prüft, ob customElements vorhanden ist, und bleibt andernfalls untätig. Importieren Sie es dennoch aus Client-Code, etwa aus src/entry-client.tsx in SolidStart, damit das Element und seine Icons nicht im Server-Bundle landen.
Props
Die Glyph-Komponente reicht ihre Props an renderToString weiter und akzeptiert daher die gemeinsamen Optionen mit ihren camelCase-Namen. Am Element sind dieselben Props Attribute in kebab-case, aufgeführt in der Anleitung zu Web Components.
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
size | number, string | 24 | Breite und Höhe; Zahlen sind Pixel. |
color | string | currentColor | Hauptfarbe. |
secondaryColor | string | color | Farbe der Duotone-Ebene und der Solid-Füllung. |
secondaryOpacity | number | 0.3 / 1 | Deckkraft der Duotone-Ebene oder der Solid-Füllung. |
weight | number | 2 | Strichstärke von 1 bis 3 im 24er-Raster, unter 24 px optisch ausgeglichen. |
absoluteWeight | boolean | false | Hält den Strich bei jeder Größe auf weight Pixeln. |
corners | round, sharp | round | Abgerundete oder spitze Verbindungen und Enden. |
variant | outline, duotone, solid | outline | Stilachse; solid entsteht aus den geschlossenen Formen. |
rotate | number | 0 | Drehung in Grad. |
flipX | boolean | false | Horizontal spiegeln. |
flipY | boolean | false | Vertikal spiegeln. |
mirrorRtl | boolean | false | In Layouts von rechts nach links spiegeln. |
animate | draw, pop, wiggle, spin, pulse, bounce, shake | keiner | Voreinstellung für den lebendigen Zustand. |
trigger | mount, hover, click, state | mount | Wann die Animation oder der Morph abläuft. |
active | boolean | false | Der Zustand für den Auslöser state. |
duration | number (ms) | je nach Voreinstellung | Dauer der Animation oder des Morphs. |
delay | number (ms) | 0 | Verzögerung der Animation oder des Morphs. |
loop | boolean, number | false | Endlos oder eine bestimmte Anzahl von Malen wiederholen (spin und pulse laufen standardmäßig in Schleife). |
modifier | plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dot | keiner | Badge mit automatischer Aussparung. |
modifierCorner | top-left, top-right, bottom-left, bottom-right | bottom-right | Ecke des Badges. |
morphTo | name, data | keiner | Ziel des Morphs; der Auslöser bestimmt, wann es erscheint. |
title | string | keiner | Zugänglicher Name: title, role img und aria-label. |
decorative | boolean | true ohne title | Verbirgt das Icon vor assistiven Technologien. |
Stolperfallen
- Dynamische Props ohne attr:
name={...}aufglyph-foxsetzt eine Property, die das Element ignoriert, und das Icon bleibt leer. Schreiben Sieattr:name={...}. Statische Strings funktionieren ohne das Präfix.- Ein Name in morphTo
renderToStringaus dem Core benötigt fürmorphToIcon-Daten. Ein String wird ignoriert. Importieren Sie das Ziel-Icon und übergeben Sie dessen Daten.- Mount-Animationen laufen erneut
- Jede Prop-Änderung ersetzt das
innerHTML, daher läuft ein Preset mit dem Standardwerttrigger="mount"erneut ab. Für zustandsgebundene Animationen verwenden Sietrigger="state"mitactive. - Versehentlich alle Icons
import { toSvg } from 'glyphfox'holt alle Icons ins Bundle, weil ein Name auf jedes von ihnen verweisen kann. Verwenden Sie in Client-Code den Core mit Modulen pro Icon;toSvggehört in reinen Servercode.- Das Element auf dem Server
- Das Server-HTML enthält ein leeres
<glyph-fox>, bis das Skript läuft. Reservieren Sie seine Größe, oder rendern Sie Icons, die schon im Server-HTML sichtbar sein sollen, mit der Glyph-Komponente. - Das Wrapper-Span
- Die Glyph-Komponente umschließt das svg-Element mit einem span-Element: Flex- und Grid-Abstände gelten für dieses span-Element, und
classlandet dort statt auf dem svg-Element. Legen Sie Größen lieber über Props fest als per CSS auf dem span-Element.
Häufige Fragen
Gibt es ein glyphfox-Paket für Solid?
Noch nicht. Beide Ansätze auf dieser Seite nutzen, was das glyphfox-Paket bereits heute mitbringt: das Custom Element und den Core-Renderer, auf dem die Pakete für React, Vue und Svelte aufbauen.
Aktualisieren sich Icons, wenn sich ein Signal ändert?
Ja. Beim Element binden Sie über attr:, und das Element zeichnet sich bei jeder Attributänderung neu, mit Morph, wenn das Attribut morph gesetzt ist. Bei der Glyph-Komponente verfolgt der Effekt hinter innerHTML die Props, die der Renderer liest, und schreibt das Markup neu.