For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/en/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/en/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/en/components/message.md.
  • English
  • Message

    Provide brief feedback about an operation.

    Set up once

    Wrap your application in ConfigProvider. It manages messages automatically, so pages and business components can call useMessage directly.

    import { ConfigProvider } from '@ifhover/leaf-ui';
    
    export function Root() {
      return <ConfigProvider><App /></ConfigProvider>;
    }

    Applications already using ConfigProvider need no additional setup. Call useMessage in its descendants; the returned message can also be passed to business functions.

    Messages and updates

    basic.tsx
    import { Button, Flex, useMessage } from '@ifhover/leaf-ui';
    
    export function MessageBasic() {
      const { message } = useMessage();
      async function save() {
        const key = message.loading('Saving');
        await new Promise((resolve) => setTimeout(resolve, 1200));
        message.open({
          key,
          type: 'success',
          content: 'Saved successfully',
          duration: 3,
          closable: true,
        });
      }
      return (
        <Flex gap="md" align="center" wrap justify="center">
          <Button onClick={save}>Save asynchronously</Button>
          <Button variant="outline" onClick={() => message.info('An information message')}>
            Information
          </Button>
          <Button danger variant="outline" onClick={() => message.error('Failed. Please try again.')}>
            Error
          </Button>
          <Button variant="outline" onClick={() => message.success('Completed successfully')}>
            Success
          </Button>
          <Button variant="outline" onClick={() => message.warning('Please check your input')}>
            Warning
          </Button>
          <Button variant="ghost" onClick={() => message.close()}>
            Clear messages
          </Button>
        </Flex>
      );
    }
    

    Share between components

    These two buttons belong to different components. Use the same key to update one message, even when switching pages.

    shared.tsx
    import { Button, Flex, useMessage } from '@ifhover/leaf-ui';
    
    function PublishAction() {
      const { message } = useMessage();
      return (
        <Button
          variant="outline"
          onClick={() =>
            message.open({ key: 'shared-publish', type: 'loading', content: 'Publishing the project' })
          }
        >
          Start publishing
        </Button>
      );
    }
    
    function PublishResult() {
      const { message } = useMessage();
      return (
        <Button
          onClick={() =>
            message.open({
              key: 'shared-publish',
              type: 'success',
              content: 'Project published',
              duration: 3,
              closable: true,
            })
          }
        >
          Update from another component
        </Button>
      );
    }
    
    export function MessageShared() {
      return (
        <Flex gap="md" align="center" wrap justify="center">
          <PublishAction />
          <PublishResult />
        </Flex>
      );
    }
    

    Multiple messages

    When a message closes, those below it move up smoothly. Content of different heights collapses using its actual space.

    stack.tsx
    import { Button, useMessage } from '@ifhover/leaf-ui';
    
    export function MessageStack() {
      const { message } = useMessage();
      return (
        <Button
          variant="outline"
          onClick={() => {
            message.close();
            message.open({
              key: 'stack-first',
              content: 'The first message closes after one second',
              duration: 1,
            });
            message.open({
              key: 'stack-second',
              content: 'Following messages move up smoothly',
              duration: 5,
              closable: true,
            });
            message.open({
              key: 'stack-third',
              content:
                'Longer messages collapse using their actual height, without jumping to a new position.',
              type: 'success',
              duration: 7,
              closable: true,
            });
          }}
        >
          Show three messages
        </Button>
      );
    }
    

    useMessage API

    PropertyTypeDefaultDescription
    messageMessageApi—Call the queue managed by the application provider

    MessageProvider API

    If your application has no ConfigProvider, add MessageProvider at the entry point. An explicit MessageProvider also creates an independent queue for a region.

    import { MessageProvider } from '@ifhover/leaf-ui';
    
    export function Root() {
      return <MessageProvider><App /></MessageProvider>;
    }
    PropertyTypeDefaultDescription
    childrenReactNode—Components sharing this queue

    MessageApi

    PropertyTypeDefaultDescription
    open(options: MessageOptions) => string—Create or update by key; returns the key
    success / info / warning / error(content: ReactNode, duration?: number) => string—Show feedback of the specified type
    loading(content: ReactNode) => string—Persistent loading message; returns the key
    close(key?: string) => void—Close one message, or all when key is omitted

    MessageOptions

    PropertyTypeDefaultDescription
    keystringGeneratedUse the same key to update a message
    contentReactNodeRequiredMessage content
    type'success' | 'info' | 'warning' | 'error' | 'loading''info'Message type
    durationnumber3Seconds before dismissal; 0 persists, loading defaults to 0
    closablebooleanfalseShow a close button
    onClose() => void—Called once when dismissal starts

    Message API

    PropertyTypeDefaultDescription
    openbooleanRequiredControlled visibility
    contentReactNodeRequiredMessage content
    type'success' | 'info' | 'warning' | 'error' | 'loading''info'Message type
    durationnumber3Duration in seconds; 0 persists, loading defaults to 0
    closablebooleanfalseClose button
    onClose / afterClose() => void—Requests closure / closing animation completed

    Types

    Import types when defining reusable component props or assembling options.

    import type { MessageProps, MessageOptions, MessageApi, MessageProviderProps } from '@ifhover/leaf-ui';

    Usage notes

    Prefer useMessage. Update a loading message with its key to show the result. Timers pause while a message is hovered or focused and resume with the remaining time.

    Components under the same entry provider share a queue. close() closes all its messages; close(key) closes one. Nested ConfigProvider regions share that queue, while each message keeps the theme and language of the calling component.

    Messages continue after the calling component unmounts, and asynchronous work can update them through the same message instance. Unmounting the entry provider clears its messages and timers. Separate React applications and SSR requests have independent queues.

    Message also supports declarative rendering; set open=false after onClose.