Frameworks

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.

terminal
npm install glyphfox
Aspektglyph-fox-ElementGlyph-Komponente
RendertIm Browser, beim Upgrade des Elements.Auf dem Server und im Browser.
Liefert ausDas Element, seine Engine und die Icons, die Sie registrieren.Den Renderer und die Icon-Module, die Sie importieren.
AnimationMorphs bei jedem Namenswechsel, Auslöser für Hover und Klick, Zustände.CSS-Animationen im SVG: Presets und Hover-Morphs.
Geeignet fürIcons, 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.

src/index.jsx
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:

Toolbar.jsx
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.

MenuButton.jsx
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.

src/glyphfox.d.ts
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.

Glyph.jsx
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)}
    />
  );
}
Nav.jsx
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:

NextLink.jsx
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.

Status.jsx
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.

src/app.css
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.

OptionTypStandardBeschreibung
sizenumber, string24Breite und Höhe; Zahlen sind Pixel.
colorstringcurrentColorHauptfarbe.
secondaryColorstringcolorFarbe der Duotone-Ebene und der Solid-Füllung.
secondaryOpacitynumber0.3 / 1Deckkraft der Duotone-Ebene oder der Solid-Füllung.
weightnumber2Strichstärke von 1 bis 3 im 24er-Raster, unter 24 px optisch ausgeglichen.
absoluteWeightbooleanfalseHält den Strich bei jeder Größe auf weight Pixeln.
cornersround, sharproundAbgerundete oder spitze Verbindungen und Enden.
variantoutline, duotone, solidoutlineStilachse; solid entsteht aus den geschlossenen Formen.
rotatenumber0Drehung in Grad.
flipXbooleanfalseHorizontal spiegeln.
flipYbooleanfalseVertikal spiegeln.
mirrorRtlbooleanfalseIn Layouts von rechts nach links spiegeln.
animatedraw, pop, wiggle, spin, pulse, bounce, shakekeinerVoreinstellung für den lebendigen Zustand.
triggermount, hover, click, statemountWann die Animation oder der Morph abläuft.
activebooleanfalseDer Zustand für den Auslöser state.
durationnumber (ms)je nach VoreinstellungDauer der Animation oder des Morphs.
delaynumber (ms)0Verzögerung der Animation oder des Morphs.
loopboolean, numberfalseEndlos oder eine bestimmte Anzahl von Malen wiederholen (spin und pulse laufen standardmäßig in Schleife).
modifierplus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dotkeinerBadge mit automatischer Aussparung.
modifierCornertop-left, top-right, bottom-left, bottom-rightbottom-rightEcke des Badges.
morphToname, datakeinerZiel des Morphs; der Auslöser bestimmt, wann es erscheint.
titlestringkeinerZugänglicher Name: title, role img und aria-label.
decorativebooleantrue ohne titleVerbirgt das Icon vor assistiven Technologien.

Stolperfallen

Dynamische Props ohne attr:
name={...} auf glyph-fox setzt eine Property, die das Element ignoriert, und das Icon bleibt leer. Schreiben Sie attr:name={...}. Statische Strings funktionieren ohne das Präfix.
Ein Name in morphTo
renderToString aus dem Core benötigt für morphTo Icon-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 Standardwert trigger="mount" erneut ab. Für zustandsgebundene Animationen verwenden Sie trigger="state" mit active.
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; toSvg gehö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 class landet 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.

Icons in diesem Leitfaden