> = (args) => {
+ const [open, setOpen] = useState(true);
+
+ return (
+
+ setOpen(true)} />
+ setOpen(false)}
+ />
+
+ );
+};
+
/** Basic hint rendering with only a label and the default info icon. */
export const Default: Story = {
args: {
label: 'Helpful hint',
},
};
+
+/** Uncontrolled hint (no `open` prop): it manages its own visibility and closes itself when dismissed. */
+export const Uncontrolled: Story = {
+ args: {
+ title: 'Uncontrolled',
+ label: 'This hint manages its own visibility and closes itself when the close button is clicked.',
+ },
+};
+
+/** Controlled hint: visibility is driven by the `open` prop, so the parent decides when it reappears. */
+export const Controlled: Story = {
+ args: {
+ title: 'Controlled',
+ label: "This hint's visibility is controlled externally via the open prop.",
+ },
+ render: (args) => ,
+};
+
+/** Hint with `hideCloseButton`: no close (X) button, for hints that shouldn't be manually dismissed. */
+export const WithoutCloseButton: Story = {
+ args: {
+ title: 'No close button',
+ label: 'This hint cannot be manually dismissed.',
+ hideCloseButton: true,
+ },
+};
diff --git a/src/components/Hint/component.tsx b/src/components/Hint/component.tsx
index 50bb01b..ee61d3a 100644
--- a/src/components/Hint/component.tsx
+++ b/src/components/Hint/component.tsx
@@ -1,4 +1,4 @@
-import React, { JSX } from 'react';
+import React, { JSX, useState } from 'react';
import * as Styled from './styles';
import { HintProps } from './types';
import { MdClose, MdInfo } from 'react-icons/md';
@@ -9,15 +9,29 @@ import { MdClose, MdInfo } from 'react-icons/md';
* This component provides a small contextual hint used to surface tips, short help text or dismissible messages.
* It can be displayed with a title, an icon, and a close button.
*
+ * Visibility is uncontrolled by default (the hint closes itself when its close button is clicked); pass `open` to control it externally instead.
*/
function Hint({
title,
label,
icon = ,
+ open,
onRequestClose,
+ hideCloseButton = false,
children,
...rest
-}: HintProps): JSX.Element {
+}: HintProps): JSX.Element | null {
+ const isControlled = open !== undefined;
+ const [internalOpen, setInternalOpen] = useState(true);
+ const isOpen = isControlled ? open : internalOpen;
+
+ const handleClose = (): void => {
+ if (!isControlled) setInternalOpen(false);
+ onRequestClose?.();
+ };
+
+ if (!isOpen) return null;
+
const renderedLabel = {label}{children};
return (
{title}}
{!title && renderedLabel}
- {title && (
+ {!hideCloseButton && (
diff --git a/src/components/Hint/types.ts b/src/components/Hint/types.ts
index eddf53e..f2412d3 100644
--- a/src/components/Hint/types.ts
+++ b/src/components/Hint/types.ts
@@ -2,15 +2,21 @@ export interface HintProps extends React.HTMLAttributes {
/** Main text content of the hint. */
label: string;
- /** Optional title; if provided, shows a close button. */
+ /** Optional title shown in the header; when set, `label` renders as a separate line below instead of inline. */
title?: string;
/** Optional icon node displayed next to the title or label. @default */
icon?: React.ReactNode;
- /** Callback fired when the close button is clicked. */
+ /** Whether the hint is visible. Omit to let the hint manage its own visibility, closing itself when the close button is clicked; pass a boolean to control visibility externally. */
+ open?: boolean;
+
+ /** Callback fired when the close button is clicked, in both controlled and uncontrolled mode. */
onRequestClose?: () => void;
+ /** Hides the close (X) button, for hints that shouldn't be manually dismissed. @default false */
+ hideCloseButton?: boolean;
+
/** Optional additional content rendered under the label. */
children?: React.ReactNode;
}