@fvc/notification
v1.2.3
Published
`@fvc/notification` wraps Ant Design's notification system with FE-VIS design tokens and icons. It applies the dark card background, per-type icon colours, and Roboto typography automatically. Supports both a hook-based API (recommended) and static method
Readme
@fvc/notification
@fvc/notification wraps Ant Design's notification system with FE-VIS design tokens and icons. It applies the dark card background, per-type icon colours, and Roboto typography automatically. Supports both a hook-based API (recommended) and static methods for non-component contexts.
Installation
bun add @fvc/notificationPeer Dependencies
bun add react antd @fvc/iconsImport
import { notification } from '@fvc/notification';Quick Start
import { notification } from '@fvc/notification';
function SaveButton() {
const [api, contextHolder] = notification.useNotification({});
return (
<>
{contextHolder}
<button onClick={() => api.success({ message: 'Changes saved' })}>
Save
</button>
</>
);
}Notification Types
| Type | Auto icon | Message colour |
| --- | --- | --- |
| success | CheckCircleOutline | --link-on-dark-bg-color-400 |
| info | Info | --gray-300 |
| warning | Warning | --orange-200 |
| error | Report | --warning-icon-on-dark-bg-color-400 |
Icons and colours are applied automatically by type. Pass icon explicitly to override.
Usage Patterns
useNotification — recommended
Binds the notification to the React tree so it inherits ConfigProvider context (locale, theme, etc.). contextHolder must be rendered somewhere in the tree above where the notification is triggered — placing it at the top of the component is sufficient.
function Page() {
const [api, contextHolder] = notification.useNotification({});
const handleError = () => {
api.error({
message: 'Request failed',
innerComponent: <button onClick={retry}>Retry</button>,
});
};
return (
<>
{contextHolder}
<button onClick={handleError}>Submit</button>
</>
);
}Static API — deprecated
Works without a hook but does not inherit React context. Suitable for non-component code such as axios interceptors where a hook cannot be called.
notification.success({ message: 'Done' });
notification.error({ message: 'Something went wrong' });Deprecated. Static methods (
success,error,info,warning) will be removed in a future major version. Usenotification.useNotification()for all new code.
Methods
| Method | Description |
| --- | --- |
| useNotification(config) | Returns [api, contextHolder]. Recommended pattern. |
| open(config) | Opens a notification without a preset type. |
| success(config) | Opens a success notification. Deprecated. |
| info(config) | Opens an info notification. Deprecated. |
| warning(config) | Opens a warning notification. Deprecated. |
| error(config) | Opens an error notification. Deprecated. |
| destroy(key?) | Destroys one notification by key, or all if no key is provided. |
| config(globalConfig) | Sets global defaults (placement, duration, maxCount, etc.). |
Config (ArgsProps)
Extends antd's ArgsProps. The description field from antd is replaced by innerComponent.
| Prop | Type | Description |
| --- | --- | --- |
| message | ReactNode | Notification title. |
| innerComponent | ReactNode | Content rendered below the title. Replaces antd's description. |
| icon | ReactNode | Overrides the automatic type icon. |
| duration | number | Auto-close in seconds. 0 disables auto-close. |
| placement | NotificationPlacement | Where the notification appears. Default: topRight. |
| key | string | Unique key for programmatic updates or targeted destruction. |
| onClose | () => void | Called when the notification closes. |
Common Usage
With innerComponent
api.warning({
message: 'Session expiring soon',
duration: 0,
innerComponent: (
<button onClick={extendSession}>Extend session</button>
),
});Custom placement
const [api, contextHolder] = notification.useNotification({
placement: 'bottomRight',
});Custom icon
import { Icon } from '@fvc/icons';
api.open({
message: 'Upload complete',
icon: <Icon.CheckCircle color="var(--green-400)" width={24} height={24} />,
});Persistent notification
api.error({
key: 'save-error',
message: 'Could not save changes',
duration: 0,
});
// Dismiss programmatically
api.destroy('save-error');Consumer Example
import { notification } from '@fvc/notification';
function useFormSubmit() {
const [api, contextHolder] = notification.useNotification({
placement: 'bottomRight',
});
const submit = async (data: FormData) => {
try {
await postData(data);
api.success({ message: 'Record saved successfully' });
} catch {
api.error({
message: 'Save failed',
duration: 0,
innerComponent: (
<button onClick={() => submit(data)}>Try again</button>
),
});
}
};
return { submit, contextHolder };
}Testing
Notifications render outside the React tree in a portal. Call notification.destroy() in afterEach to prevent toast leakage between test cases.
afterEach(() => {
notification.destroy();
});CSS Classes
| Class | Description |
| --- | --- |
| .fvc-notification | Root notification container |
| .fvc-notification-notice-wrapper | Individual notification card (dark background) |
| .fvc-notification-notice | Inner notice element |
| .fvc-notification-notice-message | Title text |
| .fvc-notification-notice-icon | Icon slot |
| .fvc-notification-notice-btn | innerComponent slot |
| .fvc-notification-notice-close | Close button |
| .fvc-notification-notice-success | Applied on success type notifications |
| .fvc-notification-notice-info | Applied on info type notifications |
| .fvc-notification-notice-warning | Applied on warning type notifications |
| .fvc-notification-notice-error | Applied on error type notifications |
Customisation
@fvc/notification exposes a CSS custom properties API. Override any of the variables below in your own stylesheet — no fork, no component re-bundle required.
/* consumer's app stylesheet */
:root {
--notification-default-bg-color: #1e293b;
--notification-default-border-radius: 12px;
--notification-success-message-color: #4ade80;
--notification-success-icon-color: #4ade80;
}Variable reference
| Variable | Default | Controls |
| --- | --- | --- |
| --notification-font-family | 'Roboto', sans-serif | Typeface for all notification text |
| --notification-fz | 14px | Message text size |
| --notification-fw | 400 | Message text weight |
| --notification-lh | 16px | Message text line height |
| --notification-default-bg-color | var(--blue-gray-700) | Card background colour |
| --notification-default-border-radius | 8px | Card corner radius |
| --notification-notice-padding | 16px | Inner card padding |
| --notification-default-message-color | var(--neutral-0) | Default message text colour |
| --notification-default-message-icon-margin | 32px | Left offset of message text when an icon is present |
| --notification-close-size | 16px | Close button width and height |
| --notification-close-top | 4px | Close button top offset |
| --notification-close-right | 4px | Close button right offset |
| --notification-close-bg-color | var(--blue-gray-900) | Close button background |
| --notification-close-hover-bg-color | var(--blue-gray-900) | Close button background on hover |
| --notification-close-icon-size | 7px | Close icon width and height |
| --notification-close-icon-color | var(--blue-gray-250) | Close icon colour |
| --notification-success-message-color | var(--link-on-dark-bg-color-400) | success message text colour |
| --notification-success-icon-color | var(--link-on-dark-bg-color-400) | success auto-icon colour |
| --notification-info-message-color | var(--gray-300) | info message text colour |
| --notification-info-icon-color | var(--gray-300) | info auto-icon colour |
| --notification-warning-message-color | var(--orange-200) | warning message text colour |
| --notification-warning-icon-color | var(--orange-200) | warning auto-icon colour |
| --notification-error-message-color | var(--warning-icon-on-dark-bg-color-400) | error message text colour |
| --notification-error-icon-color | var(--warning-text-on-dark-bg-color-400) | error auto-icon colour |
Development
bun run lint
bun run type-check
bun run test