Skip to content

Framework Integrations

Every icon export returns a raw SVG string. That keeps the package framework-agnostic, but it also means each framework needs a slightly different rendering pattern.

Shared Install

bash
vp add @prastavna/icons

Plain TypeScript

Use innerHTML when you control the SVG source and want direct DOM rendering.

ts
import { noteQuarter, noteQuarterFilled } from "@prastavna/icons";

const outlineTarget = document.querySelector<HTMLElement>('[data-icon="outline"]');
const filledTarget = document.querySelector<HTMLElement>('[data-icon="filled"]');

if (outlineTarget) {
  outlineTarget.innerHTML = noteQuarter({ size: 28, color: "#7c3aed" });
}

if (filledTarget) {
  filledTarget.innerHTML = noteQuarterFilled({ size: 28, color: "#7c3aed" });
}

React

In React, render the returned string with dangerouslySetInnerHTML inside a small wrapper component.

tsx
import type { CSSProperties } from "react";
import { noteQuarter, type IconFunction } from "@prastavna/icons";

type IconProps = {
  icon: IconFunction;
  size?: number;
  color?: string;
  style?: CSSProperties;
};

function SvgIcon({ icon, size = 24, color = "currentColor", style }: IconProps) {
  return (
    <span
      aria-hidden="true"
      style={{ display: "inline-flex", lineHeight: 0, ...style }}
      dangerouslySetInnerHTML={{ __html: icon({ size, color }) }}
    />
  );
}

export function ScoreToolbar() {
  return <SvgIcon icon={noteQuarter} size={28} color="#7c3aed" />;
}

Vue

With Vue, use v-html in a focused wrapper component.

vue
<script setup lang="ts">
import { computed } from "vue";
import { noteQuarter, type IconFunction } from "@prastavna/icons";

const props = defineProps<{
  icon?: IconFunction;
  size?: number;
  color?: string;
}>();

const svg = computed(() =>
  (props.icon ?? noteQuarter)({
    size: props.size ?? 24,
    color: props.color ?? "currentColor",
  }),
);
</script>

<template>
  <span aria-hidden="true" class="svg-icon" v-html="svg" />
</template>

<style scoped>
.svg-icon {
  display: inline-flex;
  line-height: 0;
}
</style>

Svelte

In Svelte, the {@html ...} block is the most direct fit.

svelte
<script lang="ts">
  import { noteQuarter, type IconFunction } from '@prastavna/icons'

  export let icon: IconFunction = noteQuarter
  export let size = 24
  export let color = 'currentColor'

  $: svg = icon({ size, color })
</script>

<span aria-hidden="true" class="svg-icon">{@html svg}</span>

<style>
  .svg-icon {
    display: inline-flex;
    line-height: 0;
  }
</style>

Astro

Astro can inject the SVG string directly with set:html.

astro
---
import { noteQuarter, type IconFunction } from '@prastavna/icons'

type Props = {
  icon?: IconFunction
  size?: number
  color?: string
}

const {
  icon = noteQuarter,
  size = 24,
  color = 'currentColor',
} = Astro.props satisfies Props

const svg = icon({ size, color })
---

<span aria-hidden="true" class="svg-icon" set:html={svg} />

<style>
  .svg-icon {
    display: inline-flex;
    line-height: 0;
  }
</style>

Import Styles

Use root imports when you want one central entry point:

ts
import { noteQuarter, clefTreble, actionSearch } from "@prastavna/icons";

Use category imports when you want shorter names:

ts
import { quarter } from "@prastavna/icons/notes";
import { treble } from "@prastavna/icons/clefs";
import { search } from "@prastavna/icons/actions";

Notes

  • The SVG strings are generated by your own code, so these HTML injection patterns are intended for trusted icon output.
  • Each icon also exposes metadata such as iconName, category, variant, and viewBox.
  • Pass size for square icons, or use width and height separately when you need explicit dimensions.

Released under the MIT License.