summaryrefslogtreecommitdiff
path: root/src/components/SFSymbol.svelte
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /src/components/SFSymbol.svelte
init commit
Diffstat (limited to 'src/components/SFSymbol.svelte')
-rw-r--r--src/components/SFSymbol.svelte51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/components/SFSymbol.svelte b/src/components/SFSymbol.svelte
new file mode 100644
index 0000000..998ab06
--- /dev/null
+++ b/src/components/SFSymbol.svelte
@@ -0,0 +1,51 @@
+<!--
+@component
+Renders a supported "SF Symbol" from the icons available in `~/sf-symbols`
+-->
+<script lang="ts" context="module">
+ import type { ComponentType } from 'svelte';
+
+ const iconComponents = import.meta.glob('~/sf-symbols/*.svg', {
+ eager: true,
+ import: 'default',
+ });
+
+ const iconNameToComponent: Record<string, ComponentType | undefined> =
+ Object.fromEntries(
+ Object.entries(iconComponents).map(
+ ([fullPathToIcon, iconComponent]) => {
+ const iconName = fullPathToIcon
+ .replace('/src/sf-symbols/', '')
+ .replace('.svg', '');
+
+ return [iconName, iconComponent as ComponentType];
+ },
+ ),
+ );
+
+ /**
+ * The list of all supported icons
+ *
+ * This is exposed only for testing/Storybook purposes
+ */
+ export const __iconNames = Object.keys(iconNameToComponent);
+
+ export function getIconComponentByName(iconName: string) {
+ return iconNameToComponent[iconName];
+ }
+</script>
+
+<script lang="ts">
+ /**
+ * The name of the SF Symbol to render
+ *
+ * Must match the name of an `.svg` file in `~/sf-symbols`. If a file with a matching
+ * name does not exist, nothing will be rendered
+ */
+ export let name: string;
+ export let ariaHidden: boolean = false;
+
+ $: icon = getIconComponentByName(name);
+</script>
+
+<svelte:component this={icon} aria-hidden={ariaHidden ? 'true' : 'false'} />