diff --git a/.changeset/global-alert-icon-mapping.md b/.changeset/global-alert-icon-mapping.md new file mode 100644 index 00000000..3ab76e68 --- /dev/null +++ b/.changeset/global-alert-icon-mapping.md @@ -0,0 +1,5 @@ +--- +"@ainsleydev/sveltekit-helper": minor +--- + +Adding global icon mapping for Alert and Notice components via `setAlertIcons()`. diff --git a/packages/sveltekit-helper/src/components/index.ts b/packages/sveltekit-helper/src/components/index.ts index 4d10128a..d21d8101 100644 --- a/packages/sveltekit-helper/src/components/index.ts +++ b/packages/sveltekit-helper/src/components/index.ts @@ -2,7 +2,14 @@ export { default as Modal } from './Modal.svelte'; export { default as Sidebar } from './Sidebar.svelte'; export { default as Hamburger } from './Hamburger.svelte'; export { default as TableOfContents } from './TableOfContents.svelte'; -export { Alert, Notice } from './notifications'; +export { Alert, Notice, setAlertIcons } from './notifications'; export type { ModalProps, TransitionFn } from './Modal.svelte'; -export type { AlertProps, AlertType, NoticeProps, NoticeType } from './notifications'; +export type { + AlertProps, + AlertType, + NoticeProps, + NoticeType, + IconDetail, + NotificationType, +} from './notifications'; export type { TableOfContentsProps, TOCItem } from './TableOfContents.svelte'; diff --git a/packages/sveltekit-helper/src/components/notifications/Alert.svelte b/packages/sveltekit-helper/src/components/notifications/Alert.svelte index cbcc9965..b41c4652 100644 --- a/packages/sveltekit-helper/src/components/notifications/Alert.svelte +++ b/packages/sveltekit-helper/src/components/notifications/Alert.svelte @@ -1,6 +1,5 @@ @@ -19,7 +18,7 @@ export type AlertProps = { import { X } from '@lucide/svelte' import { fade } from 'svelte/transition' - import { alertIcons } from './alertIcons.js' + import { alertIconStore } from './alertIcons.js' let { type = 'info', @@ -32,7 +31,7 @@ export type AlertProps = { ...restProps }: AlertProps = $props() - const iconDetail = $derived(alertIcons[type]) + const iconDetail = $derived($alertIconStore[type]) const Icon = $derived(customIcon || iconDetail.icon) const hide = () => (visible = false) const ariaLive = $derived(type === 'error' ? 'assertive' : 'polite') diff --git a/packages/sveltekit-helper/src/components/notifications/Notice.svelte b/packages/sveltekit-helper/src/components/notifications/Notice.svelte index 76b6a114..190f5d86 100644 --- a/packages/sveltekit-helper/src/components/notifications/Notice.svelte +++ b/packages/sveltekit-helper/src/components/notifications/Notice.svelte @@ -1,5 +1,5 @@ @@ -17,7 +17,7 @@ export type NoticeProps = { import { X } from '@lucide/svelte' import { fade } from 'svelte/transition' - import { alertIcons } from './alertIcons' + import { alertIconStore } from './alertIcons' let { type = 'info', @@ -29,7 +29,7 @@ export type NoticeProps = { ...restProps }: NoticeProps = $props() - const iconDetail = $derived(alertIcons[type]) + const iconDetail = $derived($alertIconStore[type]) const Icon = $derived(customIcon || iconDetail.icon) const hide = () => (visible = false) const ariaLive = $derived(type === 'error' ? 'assertive' : 'polite') diff --git a/packages/sveltekit-helper/src/components/notifications/alertIcons.ts b/packages/sveltekit-helper/src/components/notifications/alertIcons.ts index 0ee817b7..8c23a819 100644 --- a/packages/sveltekit-helper/src/components/notifications/alertIcons.ts +++ b/packages/sveltekit-helper/src/components/notifications/alertIcons.ts @@ -1,24 +1,52 @@ -import { CircleCheck, CircleX, type Icon as IconType, Info, TriangleAlert } from '@lucide/svelte'; +import { CircleCheck, CircleX, Info, TriangleAlert } from '@lucide/svelte'; +import type { Component } from 'svelte'; +import { writable } from 'svelte/store'; /** - * Notification type variants + * Notification type variants. */ -type NotificationType = 'info' | 'warning' | 'success' | 'error'; +export type NotificationType = 'info' | 'warning' | 'success' | 'error'; /** - * Icon configuration for notification types + * Icon configuration for a notification type. */ -type IconDetail = { - icon: typeof IconType; +export type IconDetail = { + icon: Component; colour: string; }; -/** - * Icon mapping for notification types - */ -export const alertIcons: Record = { +const defaultAlertIcons: Record = { info: { icon: Info, colour: 'var(--colour-semantic-info)' }, success: { icon: CircleCheck, colour: 'var(--colour-semantic-success)' }, warning: { icon: TriangleAlert, colour: 'var(--colour-semantic-warning)' }, error: { icon: CircleX, colour: 'var(--colour-semantic-error)' }, }; + +/** + * Writable store holding the active icon map for all Alert and Notice components. + * Consumers can override individual or all entries via setAlertIcons(). + */ +export const alertIconStore = writable>(defaultAlertIcons); + +/** + * Globally overrides icons for Alert and Notice components. + * Call this once in your root layout (e.g. +layout.svelte) to supply + * your own SVG components instead of the default Lucide icons. + * + * @example + * ```ts + * import { setAlertIcons } from '@ainsleydev/sveltekit-helper'; + * import InfoIcon from '$lib/icons/Info.svelte'; + * import SuccessIcon from '$lib/icons/Success.svelte'; + * + * setAlertIcons({ + * info: { icon: InfoIcon, colour: 'var(--colour-info)' }, + * success: { icon: SuccessIcon, colour: 'var(--colour-success)' }, + * }); + * ``` + * + * @param overrides - Partial map of notification types to icon configurations. + */ +export function setAlertIcons(overrides: Partial>): void { + alertIconStore.update((current) => ({ ...current, ...overrides })); +} diff --git a/packages/sveltekit-helper/src/components/notifications/index.ts b/packages/sveltekit-helper/src/components/notifications/index.ts index e841ddda..305d0dd0 100644 --- a/packages/sveltekit-helper/src/components/notifications/index.ts +++ b/packages/sveltekit-helper/src/components/notifications/index.ts @@ -2,3 +2,5 @@ export { default as Alert } from './Alert.svelte'; export { default as Notice } from './Notice.svelte'; export type { AlertProps, AlertType } from './Alert.svelte'; export type { NoticeProps, NoticeType } from './Notice.svelte'; +export { setAlertIcons } from './alertIcons.js'; +export type { IconDetail, NotificationType } from './alertIcons.js';