@fpkit/acss 2.2.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/{chunk-R7NLLZU2.cjs → chunk-C622WBGW.cjs} +3 -3
- package/libs/{chunk-UJAQVHWC.js → chunk-D2PSO7MU.js} +2 -2
- package/libs/chunk-KG4GHIQJ.js +8 -0
- package/libs/chunk-KG4GHIQJ.js.map +1 -0
- package/libs/chunk-ZOBAJTNE.cjs +17 -0
- package/libs/chunk-ZOBAJTNE.cjs.map +1 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs +5 -5
- package/libs/components/breadcrumbs/breadcrumb.d.cts +2 -2
- package/libs/components/breadcrumbs/breadcrumb.d.ts +2 -2
- package/libs/components/breadcrumbs/breadcrumb.js +2 -2
- package/libs/components/link/link.cjs +5 -5
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.css.map +1 -1
- package/libs/components/link/link.d.cts +2 -131
- package/libs/components/link/link.d.ts +2 -131
- package/libs/components/link/link.js +1 -1
- package/libs/components/link/link.min.css +2 -2
- package/libs/components/link/link.min.min.css +2 -2
- package/libs/components/nav/nav.css +1 -1
- package/libs/components/nav/nav.css.map +1 -1
- package/libs/components/nav/nav.min.css +2 -2
- package/libs/components/nav/nav.min.min.css +2 -2
- package/libs/hooks.cjs +3 -3
- package/libs/hooks.d.cts +1 -1
- package/libs/hooks.d.ts +1 -1
- package/libs/hooks.js +2 -2
- package/libs/index.cjs +21 -21
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +4 -239
- package/libs/index.d.ts +4 -239
- package/libs/index.js +6 -6
- package/libs/index.js.map +1 -1
- package/libs/link-59ad884f.d.ts +371 -0
- package/package.json +2 -2
- package/src/components/link/link.scss +4 -10
- package/src/components/link/link.tsx +17 -2
- package/src/components/nav/nav.scss +1 -1
- package/src/index.ts +2 -2
- package/src/patterns/page/page-header.tsx +1 -3
- package/src/styles/index.css +6 -10
- package/src/styles/index.css.map +1 -1
- package/src/styles/link/link.css +3 -7
- package/src/styles/link/link.css.map +1 -1
- package/src/styles/nav/nav.css +3 -3
- package/libs/chunk-5PJYLVFY.cjs +0 -17
- package/libs/chunk-5PJYLVFY.cjs.map +0 -1
- package/libs/chunk-NNTBIHSD.js +0 -8
- package/libs/chunk-NNTBIHSD.js.map +0 -1
- /package/libs/{chunk-R7NLLZU2.cjs.map → chunk-C622WBGW.cjs.map} +0 -0
- /package/libs/{chunk-UJAQVHWC.js.map → chunk-D2PSO7MU.js.map} +0 -0
package/libs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/alert/alert.tsx","../src/components/alert/views/alert-screen-reader-text.tsx","../src/components/alert/views/alert-icon.tsx","../src/components/alert/views/alert-title.tsx","../src/components/alert/views/alert-content.tsx","../src/components/alert/views/alert-actions.tsx","../src/components/alert/views/alert-view.tsx","../src/components/alert/elements/dismiss-button.tsx","../src/components/images/img.tsx","../src/components/text-to-speech/TextToSpeech.tsx","../src/components/text-to-speech/useTextToSpeech.tsx","../src/components/text-to-speech/views/TextToSpeechControls.tsx","../src/components/layout/landmarks.tsx","../src/components/badge/badge.tsx","../src/components/tag/tag.tsx","../src/components/details/details.tsx"],"names":["React","SEVERITY_SCREEN_READER_TEXT","AlertScreenReaderText","severity","text","getSeverityIcon","iconProps","icon_default","AlertIcon","hideIcon","icon","ui_default","AlertTitle","title","titleLevel","TitleElement","AlertContent","children","contentType","AlertActions","actions","DismissButton","onDismiss","iconSize","button_default","dismiss_button_default","SEVERITY_ARIA_LIVE","AlertView","variant","isVisible","dismissible","onInteractionStart","onInteractionEnd","autoFocus","props","ref","useAlertBehavior","open","autoHideDuration","pauseOnHover","alertRef","setIsVisible","shouldRender","setShouldRender","isPaused","setIsPaused","handleDismiss","timer","handleKeyDown","e","pause","resume","Alert","handleInteractionStart","handleInteractionEnd","mergedIconProps","useMemo","Img","src","alt","width","height","styles","loading","placeholder","fetchpriority","decoding","srcSet","sizes","onError","onLoad","defaultPlaceholder","w","h","svg","fallbackPlaceholder","useState","useEffect","useTextToSpeech","initialVoice","availableVoices","setAvailableVoices","currentVoice","setCurrentVoice","isSpeaking","setIsSpeaking","utterance","setUtterance","updateVoices","voices","googleVoice","voice","englishVoice","options","onEnd","TTSButtonComponent","onClick","TTSButton","TextToSpeechControls","label","onSpeak","onPause","onResume","onCancel","TextToSpeechControls_default","TextToSpeech","initialText","showTextInput","pitch","rate","language","speak","cancel","getAvailableLanguages","setText","handleSpeak","handleEnd","handleChange","textarea_default","Landmarks","Header","id","headerBackground","classes","Main","Footer","Aside","Section","Article","Badge","Tag","elm","role","useCallback","Details","summary","ariaLabel","name","onPointerDown","onToggle","handlePointerDown","handleToggle"],"mappings":"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","sourcesContent":["import React from \"react\";\nimport { IconProps } from \"#components/icons/types\";\nimport { AlertView } from \"./views\";\n\n// ============================================================================\n// TYPES & CONFIGURATION\n// ============================================================================\n\n/**\n * Valid severity levels for alerts.\n * Each severity has associated colors, icons, and ARIA attributes.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Props for the Alert component.\n */\nexport type AlertProps = {\n /**\n * Whether the alert is open.\n */\n open: boolean;\n /**\n * The severity level of the alert.\n * @default \"default\"\n */\n severity?: Severity;\n /**\n * The main message content.\n */\n children: React.ReactNode;\n /**\n * Optional title for the alert.\n */\n title?: string;\n /**\n * Whether the alert can be dismissed.\n * @default false\n */\n dismissible?: boolean;\n /**\n * Callback when alert is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * Size of the severity icon in pixels.\n * Allows customization of icon size for different contexts.\n * @default 24\n * @example\n * ```tsx\n * <Alert iconSize={32} severity=\"error\">Larger icon</Alert>\n * <Alert iconSize={16} severity=\"info\">Smaller icon</Alert>\n * ```\n */\n iconSize?: number;\n\n /**\n * Whether to hide the severity icon.\n * When true, only text content is displayed.\n * @default false\n */\n hideIcon?: boolean;\n\n /**\n * Additional props to pass to the Icon component.\n * Allows fine-grained control over icon appearance.\n * @example\n * ```tsx\n * <Alert iconProps={{ className: 'custom-icon', 'aria-label': 'Custom' }}>\n * Alert with custom icon props\n * </Alert>\n * ```\n */\n iconProps?: IconProps;\n\n /**\n * Duration in milliseconds before the alert automatically dismisses.\n * Set to 0 or undefined to disable auto-dismiss.\n * @default undefined\n * @example\n * ```tsx\n * <Alert autoHideDuration={5000}>Success message</Alert>\n * ```\n */\n autoHideDuration?: number;\n\n /**\n * Whether to pause auto-dismiss when the alert is hovered or focused.\n * Complies with WCAG 2.2.1 (Timing Adjustable).\n * @default true\n */\n pauseOnHover?: boolean;\n\n /**\n * Semantic heading level for the title (2-6).\n * When undefined, uses <strong> element instead of heading.\n * Use this to maintain proper heading hierarchy on the page.\n * @default undefined\n * @example\n * ```tsx\n * <Alert titleLevel={2} title=\"Section Alert\">...</Alert>\n * <Alert titleLevel={3} title=\"Subsection Alert\">...</Alert>\n * ```\n */\n titleLevel?: 2 | 3 | 4 | 5 | 6;\n\n /**\n * Custom action buttons to display in the alert.\n * @example\n * ```tsx\n * <Alert actions={<><Button>Undo</Button><Button>Dismiss</Button></>}>\n * File deleted\n * </Alert>\n * ```\n */\n actions?: React.ReactNode;\n\n /**\n * Whether to automatically focus the alert when it becomes visible.\n * Useful for critical alerts that require immediate attention.\n * @default false\n */\n autoFocus?: boolean;\n\n /**\n * Visual variant of the alert.\n * - outlined: Border with lighter background (default)\n * - filled: Solid colored background\n * - soft: No border, subtle background\n * @default \"outlined\"\n */\n variant?: \"outlined\" | \"filled\" | \"soft\";\n\n /**\n * Content rendering mode for alert children.\n * Determines how the children content is wrapped in the alert message area.\n * - \"text\": Wraps children in a paragraph tag (default, for simple text content)\n * - \"node\": Renders children directly without wrapper (for complex layouts, lists, or custom components)\n * @default \"text\"\n * @example Simple text content (uses default \"text\" mode)\n * ```tsx\n * <Alert severity=\"info\">\n * This is a simple text message that will be wrapped in a paragraph.\n * </Alert>\n * ```\n * @example Complex content with list\n * ```tsx\n * <Alert severity=\"warning\" contentType=\"node\">\n * <p>Please review the following items:</p>\n * <ul>\n * <li>Check your email settings</li>\n * <li>Update your password</li>\n * <li>Enable two-factor authentication</li>\n * </ul>\n * </Alert>\n * ```\n * @example Custom component layout\n * ```tsx\n * <Alert severity=\"success\" contentType=\"node\">\n * <div className=\"custom-layout\">\n * <p>Operation completed successfully!</p>\n * <div className=\"stats\">\n * <span>Items processed: 150</span>\n * <span>Time elapsed: 2.5s</span>\n * </div>\n * </div>\n * </Alert>\n * ```\n */\n contentType?: \"text\" | \"node\";\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"title\" | \"children\">;\n\n/**\n * Alert is a fully accessible component for displaying status messages with different severity levels.\n * It supports multiple severity types (default, info, success, warning, error) and can include\n * optional titles and dismissal functionality.\n *\n * Features:\n * - Multiple severity levels with matching visual indicators\n * - Three variants: outlined (default), filled, and soft\n * - Auto-dismiss with configurable duration and pause on hover/focus\n * - Optional title with configurable heading levels (h2-h6) for proper document structure\n * - Action buttons support for interactive alerts\n * - Accessible by default with appropriate ARIA attributes\n * - Screen reader announcements for severity levels\n * - Keyboard support (ESC to dismiss)\n * - WCAG 2.1 Level AA compliant\n *\n * Accessibility Features:\n * - Visually hidden severity text for screen readers (WCAG 1.1.1, 1.4.1)\n * - Configurable heading levels to maintain document hierarchy (WCAG 1.3.1)\n * - Visible focus indicators for keyboard navigation (WCAG 2.4.7)\n * - Adequate color contrast for all variants (WCAG 1.4.3)\n * - 44×44px minimum touch target size for dismiss button (WCAG 2.5.5)\n * - Pause auto-dismiss on hover/focus (WCAG 2.2.1)\n *\n * @example Basic Usage\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"info\"\n * title=\"Optional Title\"\n * dismissible={true}\n * onDismiss={() => console.log('Alert dismissed')}\n * >\n * Alert message content\n * </Alert>\n * ```\n *\n * @example With Heading Level (for proper document structure)\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"error\"\n * title=\"Error Title\"\n * titleLevel={2}\n * dismissible={true}\n * >\n * Error message\n * </Alert>\n * ```\n *\n * @example Auto-dismiss with Pause on Hover\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"success\"\n * autoHideDuration={5000}\n * pauseOnHover={true}\n * >\n * This will auto-dismiss in 5 seconds, but pauses when hovered\n * </Alert>\n * ```\n *\n * @see {@link AlertProps} for available configuration options\n */\n\n// ============================================================================\n// CUSTOM HOOK (Behavior Management)\n// ============================================================================\n\n/**\n * Custom hook that manages all Alert component behavior in one cohesive unit.\n * Consolidates visibility, auto-dismiss, keyboard, and focus management.\n *\n * @param open - Whether the alert should be open\n * @param onDismiss - Callback when alert is dismissed\n * @param dismissible - Whether the alert can be dismissed\n * @param autoHideDuration - Duration before auto-dismiss (ms)\n * @param pauseOnHover - Whether to pause auto-dismiss on hover/focus\n * @param autoFocus - Whether to auto-focus the alert\n * @param alertRef - Ref to the alert DOM element\n * @returns Object with visibility state, handlers, and event callbacks\n */\nconst useAlertBehavior = ({\n open,\n onDismiss,\n dismissible,\n autoHideDuration,\n pauseOnHover,\n autoFocus,\n alertRef,\n}: {\n open: boolean;\n onDismiss?: () => void;\n dismissible: boolean;\n autoHideDuration?: number;\n pauseOnHover: boolean;\n autoFocus: boolean;\n alertRef: React.RefObject<HTMLDivElement>;\n}) => {\n const [isVisible, setIsVisible] = React.useState(open);\n const [shouldRender, setShouldRender] = React.useState(open);\n const [isPaused, setIsPaused] = React.useState(false);\n\n // Dismiss handler with animation timing\n const handleDismiss = React.useCallback((): void => {\n setIsVisible(false);\n // Wait for animation to complete before unmounting\n setTimeout(() => {\n setShouldRender(false);\n onDismiss?.();\n }, 300); // Match CSS transition duration\n }, [onDismiss]);\n\n // Visibility management - sync with open prop\n React.useEffect(() => {\n if (open) {\n setShouldRender(true);\n setIsVisible(true);\n } else {\n setIsVisible(false);\n }\n }, [open]);\n\n // Auto-dismiss timer with pause support\n React.useEffect(() => {\n if (!autoHideDuration || !isVisible || isPaused) return;\n\n const timer = setTimeout(() => {\n handleDismiss();\n }, autoHideDuration);\n\n return () => clearTimeout(timer);\n }, [autoHideDuration, isVisible, isPaused, handleDismiss]);\n\n // ESC key support for dismissible alerts\n React.useEffect(() => {\n if (!dismissible || !isVisible) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n handleDismiss();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [dismissible, isVisible, handleDismiss]);\n\n // Auto-focus for critical alerts\n React.useEffect(() => {\n if (autoFocus && isVisible && alertRef.current) {\n alertRef.current.focus();\n }\n }, [autoFocus, isVisible, alertRef]);\n\n // Pause/resume handlers (memoized for stable references)\n const pause = React.useCallback(() => {\n if (pauseOnHover && autoHideDuration) {\n setIsPaused(true);\n }\n }, [pauseOnHover, autoHideDuration]);\n\n const resume = React.useCallback(() => {\n if (pauseOnHover && autoHideDuration) {\n setIsPaused(false);\n }\n }, [pauseOnHover, autoHideDuration]);\n\n return {\n isVisible,\n shouldRender,\n handleDismiss,\n handleInteractionStart: pause,\n handleInteractionEnd: resume,\n };\n};\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport const Alert: React.FC<AlertProps> = ({\n open,\n severity = \"default\",\n children,\n title,\n dismissible = false,\n onDismiss,\n iconSize,\n iconProps,\n hideIcon,\n autoHideDuration,\n pauseOnHover = true,\n titleLevel = 3,\n actions,\n autoFocus = false,\n variant = \"outlined\",\n contentType = \"text\",\n ...props\n}) => {\n const alertRef = React.useRef<HTMLDivElement>(null);\n\n // Use consolidated behavior hook\n const {\n isVisible,\n shouldRender,\n handleDismiss,\n handleInteractionStart,\n handleInteractionEnd,\n } = useAlertBehavior({\n open,\n onDismiss,\n dismissible,\n autoHideDuration,\n pauseOnHover,\n autoFocus,\n alertRef,\n });\n\n // Early return if component shouldn't render\n if (!shouldRender) return null;\n\n // Merge icon props with defaults\n const mergedIconProps: IconProps = {\n size: iconSize || 16,\n ...iconProps,\n };\n\n return (\n <AlertView\n ref={alertRef}\n severity={severity}\n variant={variant}\n isVisible={isVisible}\n dismissible={dismissible}\n onDismiss={handleDismiss}\n onInteractionStart={handleInteractionStart}\n onInteractionEnd={handleInteractionEnd}\n autoFocus={autoFocus}\n title={title}\n titleLevel={titleLevel}\n contentType={contentType}\n actions={actions}\n hideIcon={hideIcon}\n iconProps={mergedIconProps}\n {...props}\n >\n {children}\n </AlertView>\n );\n};\nexport default Alert;\nAlert.displayName = \"Alert\";\n","import React from \"react\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Screen reader announcement text for each severity level.\n */\nconst SEVERITY_SCREEN_READER_TEXT: Record<Severity, string> = {\n default: \"\",\n info: \"Information: \",\n success: \"Success: \",\n warning: \"Warning: \",\n error: \"Error: \",\n} as const;\n\n/**\n * Renders visually hidden severity text for screen readers.\n * Provides context about the alert type without visual clutter.\n *\n * @param severity - The alert severity level\n * @returns Hidden text for screen readers, or null if no text needed\n */\nexport const AlertScreenReaderText: React.FC<{ severity: Severity }> = ({ severity }) => {\n const text = SEVERITY_SCREEN_READER_TEXT[severity];\n if (!text) return null;\n return <span className=\"sr-only\">{text}</span>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\nimport Icon from \"#components/icons/icon\";\nimport { IconProps } from \"#components/icons/types\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Pure function to get the appropriate icon for a severity level.\n *\n * @param severity - The alert severity level\n * @param iconProps - Props to pass to the Icon component\n * @returns The icon element for the severity\n */\nconst getSeverityIcon = (\n severity: Severity,\n iconProps: IconProps\n): JSX.Element => {\n const severityIcons: Record<Severity, JSX.Element> = {\n info: <Icon.InfoSolid {...iconProps} />,\n success: <Icon.SuccessSolid {...iconProps} />,\n warning: <Icon.WarnSolid {...iconProps} />,\n error: <Icon.AlertSolid {...iconProps} />,\n default: <Icon.AlertSquareSolid {...iconProps} />,\n };\n return severityIcons[severity];\n};\n\n/**\n * Renders the severity icon with proper ARIA attributes.\n * Icon is hidden from screen readers as the text provides context.\n *\n * @param severity - The alert severity level\n * @param iconProps - Props to pass to the Icon component\n * @param hideIcon - Whether to hide the icon\n * @returns Icon element, or null if hidden\n */\nexport const AlertIcon: React.FC<{\n severity: Severity;\n iconProps: IconProps;\n hideIcon?: boolean;\n}> = ({ severity, iconProps, hideIcon }) => {\n if (hideIcon) return null;\n const icon = getSeverityIcon(severity, iconProps);\n return (\n <UI aria-hidden=\"true\" className=\"alert-icon\">\n {icon}\n </UI>\n );\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders the alert title with configurable heading level.\n * Uses semantic heading (h2-h6) or strong element based on titleLevel prop.\n *\n * @param title - The title text to display\n * @param titleLevel - Semantic heading level (2-6)\n * @returns Title element, or null if no title provided\n */\nexport const AlertTitle: React.FC<{\n title?: string;\n titleLevel: 2 | 3 | 4 | 5 | 6;\n}> = ({ title, titleLevel }) => {\n if (!title) return null;\n const TitleElement = titleLevel ? (`h${titleLevel}` as const) : \"strong\";\n return (\n <UI as={TitleElement} className=\"alert-title\">\n {title}\n </UI>\n );\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders the alert message content.\n * Supports both simple text (wrapped in <p>) and complex node structures.\n *\n * @param children - The content to render\n * @param contentType - How to wrap the content (\"text\" or \"node\")\n * @returns Wrapped content\n */\nexport const AlertContent: React.FC<{\n children: React.ReactNode;\n contentType: \"text\" | \"node\";\n}> = ({ children, contentType }) => {\n return contentType === \"node\" ? <>{children}</> : <UI as=\"p\">{children}</UI>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders optional action buttons within the alert.\n *\n * @param actions - Action button elements to display\n * @returns Actions container, or null if no actions provided\n */\nexport const AlertActions: React.FC<{ actions?: React.ReactNode }> = ({ actions }) => {\n if (!actions) return null;\n return <UI as=\"div\" className=\"alert-actions\">{actions}</UI>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\nimport { IconProps } from \"#components/icons/types\";\nimport DismissButton from \"../elements/dismiss-button\";\nimport {\n AlertScreenReaderText,\n AlertIcon,\n AlertTitle,\n AlertContent,\n AlertActions,\n} from \".\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Maps severity levels to ARIA live region types.\n */\nconst SEVERITY_ARIA_LIVE: Record<Severity, \"polite\" | \"assertive\"> = {\n default: \"polite\",\n info: \"polite\",\n success: \"polite\",\n warning: \"polite\",\n error: \"assertive\",\n} as const;\n\n/**\n * Props for the AlertView presentation component.\n */\nexport type AlertViewProps = {\n /**\n * The severity level of the alert.\n */\n severity: Severity;\n /**\n * Visual variant of the alert.\n */\n variant: \"outlined\" | \"filled\" | \"soft\";\n /**\n * Whether the alert is currently visible (for animations).\n */\n isVisible: boolean;\n /**\n * Whether the alert can be dismissed.\n */\n dismissible: boolean;\n /**\n * Callback when dismiss button is clicked.\n */\n onDismiss: () => void;\n /**\n * Handler for interaction start (hover/focus).\n */\n onInteractionStart: () => void;\n /**\n * Handler for interaction end (leave/blur).\n */\n onInteractionEnd: () => void;\n /**\n * Whether to automatically focus the alert.\n */\n autoFocus: boolean;\n /**\n * Optional title for the alert.\n */\n title?: string;\n /**\n * Semantic heading level for the title (2-6).\n */\n titleLevel: 2 | 3 | 4 | 5 | 6;\n /**\n * The main message content.\n */\n children: React.ReactNode;\n /**\n * Content rendering mode for alert children.\n */\n contentType: \"text\" | \"node\";\n /**\n * Custom action buttons to display in the alert.\n */\n actions?: React.ReactNode;\n /**\n * Whether to hide the severity icon.\n */\n hideIcon?: boolean;\n /**\n * Merged props for the Icon component.\n */\n iconProps: IconProps;\n} & React.ComponentProps<typeof UI>;\n\n/**\n * AlertView is a pure presentation component that renders the Alert UI structure.\n * It receives all presentation props and behavior handlers from the parent Alert component.\n *\n * This component is focused solely on rendering the visual structure and does not contain\n * any business logic or state management. All behavior is delegated to the parent.\n *\n * @param props - AlertView props including severity, variant, handlers, and content\n * @returns The rendered alert UI structure\n */\nexport const AlertView = React.forwardRef<HTMLDivElement, AlertViewProps>(\n (\n {\n severity,\n variant,\n isVisible,\n dismissible,\n onDismiss,\n onInteractionStart,\n onInteractionEnd,\n autoFocus,\n title,\n titleLevel,\n children,\n contentType,\n actions,\n hideIcon,\n iconProps,\n ...props\n },\n ref\n ) => {\n return (\n <UI\n as=\"div\"\n ref={ref}\n role=\"alert\"\n aria-live={SEVERITY_ARIA_LIVE[severity]}\n aria-atomic=\"true\"\n className={`alert alert-${severity}`}\n data-alert={severity}\n data-visible={isVisible}\n data-variant={variant}\n tabIndex={autoFocus ? -1 : undefined}\n onMouseEnter={onInteractionStart}\n onMouseLeave={onInteractionEnd}\n onFocus={onInteractionStart}\n onBlur={onInteractionEnd}\n {...props}\n >\n <AlertScreenReaderText severity={severity} />\n <AlertIcon severity={severity} iconProps={iconProps} hideIcon={hideIcon} />\n <UI as=\"div\" className=\"alert-message\">\n <AlertTitle title={title} titleLevel={titleLevel} />\n <AlertContent contentType={contentType}>{children}</AlertContent>\n <AlertActions actions={actions} />\n </UI>\n {dismissible && <DismissButton onDismiss={onDismiss} />}\n </UI>\n );\n }\n);\n\nAlertView.displayName = \"AlertView\";\n","import React from \"react\";\nimport Button from \"#components/buttons/button\";\nimport Icon from \"#components/icons/icon\";\n/** Props for the DismissButton component */\ntype DismissButtonProps = {\n /** Callback function when dismiss button is clicked */\n onDismiss: () => void;\n /** Size of the close icon in pixels. Defaults to 16 */\n iconSize?: number;\n};\nexport const DismissButton = React.memo(\n ({ onDismiss, iconSize = 16 }: DismissButtonProps) => (\n <Button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Close alert\"\n className=\"alert-dismiss\"\n data-btn=\"icon sm\"\n >\n <Icon>\n <Icon.Close size={iconSize} />\n </Icon>\n </Button>\n )\n);\n\nexport default DismissButton;\nDismissButton.displayName = \"DismissButton\";\n","import UI from \"../ui\";\nimport React, { useMemo } from \"react\";\nimport type { ImgProps } from \"./img.types\";\n\n/**\n * Img - A semantic image component with accessibility and performance best practices.\n *\n * This component wraps the native `<img>` element with enhanced features:\n * - **Responsive images** via optional srcset/sizes\n * - **Lazy loading** by default for performance\n * - **Error handling** with configurable fallback placeholders\n * - **Type safety** with full TypeScript support\n *\n * ## Accessibility Patterns (WCAG 2.1 AA)\n *\n * ### Decorative Images\n * Images that are purely visual decoration should use an empty alt attribute.\n * These images are typically borders, patterns, or visual separators.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Decorative border image\n * <Img src=\"/decorative-border.png\" alt=\"\" />\n *\n * // ✅ GOOD: Background pattern\n * <Img src=\"/pattern.svg\" alt=\"\" loading=\"eager\" />\n * ```\n *\n * ### Semantic Images\n * Images that convey information must have descriptive alt text that explains\n * the content and purpose of the image.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Informative image with descriptive alt\n * <Img\n * src=\"/sales-chart.png\"\n * alt=\"Sales chart showing 30% revenue growth in Q4 2024\"\n * />\n *\n * // ✅ GOOD: Product photo with context\n * <Img\n * src=\"/laptop.jpg\"\n * alt=\"Silver MacBook Pro 14-inch on wooden desk\"\n * />\n * ```\n *\n * ## Performance Optimization\n *\n * ### Lazy Loading\n * By default, images use lazy loading to improve page load performance.\n * Only use `loading=\"eager\"` for above-the-fold images.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Lazy load below-the-fold image\n * <Img src=\"/photo.jpg\" alt=\"Photo\" />\n *\n * // ✅ GOOD: Eager load hero image\n * <Img\n * src=\"/hero.jpg\"\n * alt=\"Hero banner\"\n * loading=\"eager\"\n * fetchpriority=\"high\"\n * />\n * ```\n *\n * ### Responsive Images\n * Use srcset and sizes for responsive images to serve appropriate image sizes\n * based on viewport width, improving performance and bandwidth usage.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Responsive image with multiple sizes\n * <Img\n * src=\"/photo.jpg\"\n * srcSet=\"/photo-320w.jpg 320w, /photo-640w.jpg 640w, /photo-1024w.jpg 1024w\"\n * sizes=\"(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 800px\"\n * alt=\"Responsive image adapts to viewport\"\n * />\n * ```\n *\n * ## Error Handling\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Custom placeholder on error\n * <Img\n * src=\"/photo.jpg\"\n * placeholder=\"/fallback.png\"\n * alt=\"User profile photo\"\n * />\n *\n * // ✅ GOOD: Custom error handler\n * <Img\n * src=\"/photo.jpg\"\n * onError={(e) => {\n * console.error('Image failed to load')\n * logToAnalytics('image_error', { src: e.currentTarget.src })\n * }}\n * alt=\"Photo\"\n * />\n * ```\n *\n * @param {ImgProps} props - Component props extending native img attributes\n * @returns {React.ReactElement} Image element with enhanced functionality\n *\n * @see {@link ImgProps} for complete prop documentation\n * @see https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html\n */\nexport const Img = ({\n src = \"//\",\n alt,\n width = 480,\n height,\n styles,\n loading = \"lazy\",\n placeholder,\n fetchpriority = \"low\",\n decoding = \"auto\",\n srcSet,\n sizes,\n onError,\n onLoad,\n ...props\n}: ImgProps) => {\n /**\n * Generates a performant, responsive SVG gradient placeholder.\n * Uses data URI to avoid network requests and memoizes based on dimensions.\n * The SVG uses viewBox for perfect scaling at any size.\n *\n * Features:\n * - Zero network requests (works offline)\n * - ~900 bytes vs. 5-10KB external image\n * - Responsive with viewBox\n * - Attractive gradient (indigo → purple → pink)\n * - Dimension text for debugging\n */\n const defaultPlaceholder = useMemo(() => {\n const w = typeof width === \"number\" ? width : 480;\n const h = typeof height === \"number\" ? height : Math.round(w * 0.75);\n\n // Responsive SVG with attractive gradient and dimension text\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\">\n <defs>\n <linearGradient id=\"grad-${w}-${h}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" style=\"stop-color:#6366f1;stop-opacity:1\" />\n <stop offset=\"50%\" style=\"stop-color:#8b5cf6;stop-opacity:1\" />\n <stop offset=\"100%\" style=\"stop-color:#ec4899;stop-opacity:1\" />\n </linearGradient>\n </defs>\n <rect width=\"${w}\" height=\"${h}\" fill=\"url(#grad-${w}-${h})\"/>\n <circle cx=\"${w * 0.15}\" cy=\"${h * 0.2}\" r=\"${Math.min(w, h) * 0.08}\" fill=\"rgba(255,255,255,0.2)\"/>\n <path d=\"M0,${h * 0.75} Q${w * 0.25},${h * 0.65} ${w * 0.5},${h * 0.75} T${w},${h * 0.75} L${w},${h} L0,${h} Z\" fill=\"rgba(0,0,0,0.15)\"/>\n <text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"system-ui,-apple-system,sans-serif\" font-size=\"${Math.max(16, Math.min(w, h) * 0.05)}\" font-weight=\"500\" fill=\"rgba(255,255,255,0.9)\">${w}×${h}</text>\n </svg>`;\n\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n }, [width, height]);\n\n const fallbackPlaceholder = placeholder ?? defaultPlaceholder;\n\n /**\n * Handles image load errors.\n * Calls custom error handler if provided, then applies fallback placeholder.\n * The custom handler can prevent the default fallback by calling e.preventDefault().\n */\n const handleImgError = (\n e: React.SyntheticEvent<HTMLImageElement, Event>\n ): void => {\n // Call custom error handler first (for logging, analytics, etc.)\n if (onError) {\n onError(e);\n }\n\n // Apply fallback unless preventDefault() was called\n if (!e.defaultPrevented) {\n // Avoid infinite error loop by checking if already showing placeholder\n if (e.currentTarget.src !== fallbackPlaceholder) {\n e.currentTarget.src = fallbackPlaceholder;\n }\n }\n };\n\n /**\n * Handles successful image load.\n * Calls custom load handler if provided.\n */\n const handleImgLoad = (\n e: React.SyntheticEvent<HTMLImageElement, Event>\n ): void => {\n onLoad?.(e);\n };\n\n return (\n <UI\n as=\"img\"\n src={src}\n alt={alt}\n width={width}\n height={height || \"auto\"}\n loading={loading}\n style={styles}\n srcSet={srcSet}\n sizes={sizes}\n onError={handleImgError}\n onLoad={handleImgLoad}\n decoding={decoding}\n {...props}\n {...(fetchpriority && { fetchpriority })}\n />\n );\n};\n\nexport default Img;\nImg.displayName = \"Img\";\n","import React, { useState, ChangeEvent, useEffect } from 'react'\nimport { useTextToSpeech } from './useTextToSpeech'\nimport Textarea from '#components/form/textarea.jsx'\nimport TextToSpeechControls from './views/TextToSpeechControls'\n\n/**\n * Props for the TextToSpeechComponent.\n * @interface TextToSpeechComponentProps\n */\ninterface TextToSpeechComponentProps {\n /** Initial text to be spoken. Defaults to an empty string. */\n initialText?: string\n /** Whether to show the text input field. Defaults to true. */\n showTextInput?: boolean\n /** The voice to be used for speech synthesis. */\n voice?: SpeechSynthesisVoice | undefined\n /** The pitch of the voice. Defaults to 1. */\n pitch?: number\n /** The rate of speech. Defaults to 1. */\n rate?: number\n /** The language to be used for speech synthesis. */\n language?: string\n /** Player label */\n label?: string | React.ReactNode\n /** Callback function to be called when speech ends. */\n onEnd?: () => void\n}\n\n/**\n * A component that converts text to speech using the Web Speech API.\n * @param {TextToSpeechComponentProps} props - The props for the component.\n * @returns {JSX.Element} The rendered TextToSpeechComponent.\n */\nexport const TextToSpeech: React.FC<TextToSpeechComponentProps> = ({\n initialText = '',\n showTextInput = false,\n voice,\n pitch = 1,\n rate = 1,\n language,\n label,\n onEnd,\n}) => {\n const {\n speak,\n pause,\n resume,\n cancel,\n isSpeaking,\n isPaused,\n getAvailableLanguages,\n availableVoices,\n } = useTextToSpeech()\n const [text, setText] = useState<string>(initialText)\n console.log(getAvailableLanguages())\n\n useEffect(() => {\n setText(initialText)\n }, [initialText])\n\n const handleSpeak = (): void => {\n if (text.trim() !== '') {\n speak(text, { voice, pitch, rate }, handleEnd)\n }\n }\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>): void => {\n setText(e.target.value)\n }\n\n const handleEnd = (): void => {\n if (onEnd) {\n onEnd()\n }\n }\n\n return (\n <>\n {showTextInput && <Textarea value={text} onChange={handleChange} />}\n <TextToSpeechControls\n label={label}\n isSpeaking={isSpeaking}\n isPaused={isPaused}\n onSpeak={handleSpeak}\n onPause={pause}\n onResume={resume}\n onCancel={cancel}\n />\n </>\n )\n}\n\nexport default TextToSpeech\nTextToSpeech.displayName = 'TextToSpeechComponent'\n","import { useState, useEffect } from 'react'\n\n/**\n * Options for configuring speech synthesis.\n * @interface SpeechOptions\n */\ninterface SpeechOptions {\n /** The language for speech synthesis (e.g., 'en-US') */\n lang?: string\n\n /** The pitch of the voice (0 to 2) */\n pitch?: number\n /** The speed of the voice (0.1 to 10) */\n rate?: number\n\n /** The voice to use for speech synthesis */\n voice?: SpeechSynthesisVoice\n}\n/**\n * Custom hook to handle text-to-speech functionality.\n *\n * @param {SpeechSynthesisVoice} [initialVoice] - The initial voice to use for speech synthesis.\n * @returns {Object} An object containing methods to control speech synthesis and state variables.\n */\nexport const useTextToSpeech = (initialVoice?: SpeechSynthesisVoice) => {\n const [availableVoices, setAvailableVoices] = useState<\n SpeechSynthesisVoice[]\n >([])\n const [currentVoice, setCurrentVoice] = useState<\n SpeechSynthesisVoice | undefined\n >(initialVoice)\n\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false)\n const [isPaused, setIsPaused] = useState<boolean>(false)\n const [utterance, setUtterance] = useState<SpeechSynthesisUtterance | null>(\n null,\n )\n\n useEffect(() => {\n const updateVoices = () => {\n const voices = window.speechSynthesis.getVoices()\n setAvailableVoices(voices)\n\n // Set default voice to Google US English if available\n const googleVoice = voices.find(\n (voice) => voice.name === 'Google US English',\n )\n if (googleVoice) {\n setCurrentVoice(googleVoice)\n } else {\n // Fallback to the first English voice if Google voice is not available\n const englishVoice = voices.find((voice) =>\n voice.lang.startsWith('en-'),\n )\n if (englishVoice) {\n setCurrentVoice(englishVoice)\n }\n }\n }\n\n updateVoices()\n window.speechSynthesis.onvoiceschanged = updateVoices\n\n return () => {\n window.speechSynthesis.onvoiceschanged = null\n }\n }, [])\n\n /**\n * Gets the list of available languages for speech synthesis.\n * @returns {string[]} An array of available language codes.\n */\n const getAvailableLanguages = () => {\n return [...new Set(availableVoices.map((voice) => voice.lang))]\n }\n\n /**\n * Initiates speech synthesis for the given text.\n *\n * @param {string} text - The text to be spoken.\n * @param {SpeechOptions} [options={}] - Options for speech synthesis.\n * @param {Function} [onEnd] - Callback function to be called when speech ends.\n */\n const speak = (\n text: string,\n options: SpeechOptions = {},\n onEnd?: () => void,\n ) => {\n const utterance = new SpeechSynthesisUtterance(text)\n\n utterance.lang = options.lang ?? 'en-US'\n utterance.pitch = options.pitch ?? 1\n utterance.rate = options.rate ?? 1\n utterance.voice = currentVoice ?? options.voice ?? null\n\n utterance.onend = () => {\n setIsSpeaking(false)\n setIsPaused(false)\n if (onEnd) {\n onEnd()\n }\n }\n\n if ('speechSynthesis' in window) {\n window.speechSynthesis.speak(utterance)\n setUtterance(utterance)\n setIsSpeaking(true)\n setIsPaused(false)\n } else {\n console.error('Speech synthesis not supported')\n // Handle the error appropriately\n }\n }\n\n /**\n * Changes the current voice used for speech synthesis.\n * @param {SpeechSynthesisVoice} voice - The new voice to use.\n */\n const changeVoice = (voice: SpeechSynthesisVoice) => {\n setCurrentVoice(voice)\n }\n\n /**\n * Pauses the ongoing speech synthesis.\n */\n const pause = () => {\n if (isSpeaking && !isPaused) {\n window.speechSynthesis.pause()\n setIsPaused(true)\n }\n }\n\n /**\n * Resumes the paused speech synthesis.\n */\n const resume = () => {\n if (isSpeaking && isPaused) {\n window.speechSynthesis.resume()\n setIsPaused(false)\n }\n }\n\n /**\n * Cancels the ongoing speech synthesis.\n */\n const cancel = () => {\n if (isSpeaking) {\n window.speechSynthesis.cancel()\n setIsSpeaking(false)\n setIsPaused(false)\n }\n }\n\n return {\n /** Initiates speech synthesis for the given text */\n speak,\n /** Pauses the ongoing speech synthesis */\n pause,\n /** Resumes the paused speech synthesis */\n resume,\n /** Cancels the ongoing speech synthesis */\n cancel,\n /** Indicates whether speech synthesis is currently active */\n isSpeaking,\n /** Indicates whether speech synthesis is currently paused */\n isPaused,\n /** Array of available voices for speech synthesis */\n availableVoices,\n /** Changes the current voice used for speech synthesis */\n changeVoice,\n /** The currently selected voice for speech synthesis */\n currentVoice,\n /** Gets the list of available languages for speech synthesis */\n getAvailableLanguages,\n }\n}\n","import React from 'react'\nimport Icon from '#components/icons/icon'\nimport UI from '#components/ui'\nimport { FC } from 'react'\n\n/**\n * Props for the TextToSpeechControls component.\n * @interface TextToSpeechControlsProps\n */\ninterface TextToSpeechControlsProps {\n /** Optional label for the controls */\n label?: string | React.ReactNode\n /** Indicates if the text-to-speech is currently speaking */\n isSpeaking: boolean\n /** Indicates if the text-to-speech is paused */\n isPaused: boolean\n /** Function to start speaking */\n onSpeak: () => void\n /** Function to pause speaking */\n onPause: () => void\n /** Function to resume speaking */\n onResume: () => void\n /** Function to cancel speaking */\n onCancel: () => void\n}\n\n/**\n * TTSButtonComponent props\n * @interface TTSButtonComponentProps\n */\ninterface TTSButtonComponentProps {\n /** The content of the button */\n children: React.ReactNode\n /** Function to call when the button is clicked */\n onClick: () => void\n}\n\n/**\n * TTSButtonComponent is a reusable button component for text-to-speech controls.\n * @param {TTSButtonComponentProps} props - The component props\n * @returns {React.ReactElement} The rendered button\n */\nexport const TTSButtonComponent: React.FC<TTSButtonComponentProps> = ({\n children,\n onClick,\n}) => {\n return (\n <UI\n as=\"button\"\n type=\"button\"\n className=\"tts-border\"\n data-btn=\"sm text pill\"\n onClick={onClick}\n >\n {children}\n </UI>\n )\n}\n\nexport const TTSButton = React.memo(TTSButtonComponent)\n\n/**\n * TextToSpeechControlsComponent interface extends FC<TextToSpeechControlsProps>\n * and includes a TTSButton property.\n * @interface TextToSpeechControlsComponent\n * @extends {FC<TextToSpeechControlsProps>}\n */\ninterface TextToSpeechControlsComponent extends FC<TextToSpeechControlsProps> {\n /** The TTSButton component used within TextToSpeechControls */\n TTSButton: typeof TTSButton\n}\n\n/**\n * TextToSpeechControls component provides a user interface for controlling text-to-speech functionality.\n * @param {TextToSpeechControlsProps} props - The component props\n * @returns {React.ReactElement} The rendered TextToSpeechControls component\n */\nconst TextToSpeechControls: TextToSpeechControlsComponent = ({\n label,\n isSpeaking,\n isPaused,\n onSpeak,\n onPause,\n onResume,\n onCancel,\n}) => {\n const iconSize = 16\n\n return (\n <UI as=\"div\" data-tts>\n {label && <p>{label}</p>}\n {!isSpeaking && (\n <TTSButton aria-label=\"Speak\" onClick={onSpeak}>\n <Icon.PlaySolid size={iconSize} />\n </TTSButton>\n )}\n {isSpeaking && !isPaused && (\n <TTSButton aria-label=\"Pause\" onClick={onPause}>\n <Icon.PauseSolid size={iconSize} />\n </TTSButton>\n )}\n {isPaused && (\n <TTSButton aria-label=\"Resume\" onClick={onResume}>\n <Icon.ResumeSolid size={iconSize} />\n </TTSButton>\n )}\n <TTSButton aria-label=\"Stop\" onClick={onCancel}>\n <Icon.StopSolid size={iconSize} />\n </TTSButton>\n </UI>\n )\n}\n\nTextToSpeechControls.displayName = 'TextToSpeechControls'\nTextToSpeechControls.TTSButton = TTSButton\n\nexport default TextToSpeechControls\n","import UI from '../ui'\nimport React, { ReactNode } from 'react'\n\ntype ComponentProps = React.ComponentProps<typeof UI>\n\n/**\n * Renders children elements without any wrapping component.\n * Can be used as a placeholder when no semantic landmark is needed.\n */\nexport const Landmarks = (children?: React.FC) => <>{children}</>\n\ntype HeaderProps = {\n headerBackground?: ReactNode\n} & ComponentProps\n/**\n * Header component.\n *\n * Renders a header landmark with a section child.\n *\n * @param children - The content to render inside the header.\n * @param styles - Optional styles object.\n * @param props - Other props.\n */\nexport const Header = ({\n id,\n children,\n headerBackground,\n styles,\n classes,\n ...props\n}: HeaderProps) => {\n return (\n <UI as=\"header\" id={id} styles={styles} className={classes} {...props}>\n {headerBackground}\n <UI as=\"section\">{children}</UI>\n </UI>\n )\n}\n\n/**\n * Main component.\n *\n * Renders a main landmark.\n *\n * @param children - The content to render inside the main element.\n * @param styles - Optional styles object.\n * @param props - Other props.\n */\nexport const Main = ({\n id,\n children,\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"main\" id={id} styles={styles} {...props} className={classes}>\n {children}\n </UI>\n )\n}\n\n/**\n * Footer component that renders a footer element with a section element inside.\n * @param {ReactNode} children - Child elements to render inside the section element.\n * @param styles - CSS styles to apply to the footer element.\n * @param props - Additional props to pass to the footer element.\n * @returns A React component that renders a footer element with a section element inside.\n */\nexport const Footer = ({\n id,\n classes,\n children,\n styles = {},\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"footer\" id={id} className={classes} styles={styles} {...props}>\n <UI as=\"section\">{children || 'Copyright © 2022'}</UI>\n </UI>\n )\n}\n\nexport const Aside = ({\n id,\n children,\n styles = {},\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"aside\" id={id} styles={styles} className={classes} {...props}>\n <UI as=\"section\">{children}</UI>\n </UI>\n )\n}\n\n/**\n * Section component that renders a section element.\n *\n * @param children - Child elements to render inside the section.\n * @param styles - CSS styles to apply to the section.\n * @param props - Other props.\n */\nexport const Section = ({\n id,\n children,\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"section\" id={id} styles={styles} className={classes} {...props}>\n {children}\n </UI>\n )\n}\n\n/**\n * Article component renders an HTML <article> element.\n *\n * @param children - Child elements to render inside the article.\n * @param styles - CSS styles to apply to the article.\n * @param props - Additional props to pass to the article element.\n */\nexport const Article = ({\n id,\n children,\n\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"article\" id={id} styles={styles} className={classes} {...props}>\n {children}\n </UI>\n )\n}\n\nexport default Landmarks\n\nLandmarks.displayName = 'Landmarks'\nLandmarks.Header = Header\nLandmarks.Main = Main\nLandmarks.Footer = Footer\nLandmarks.Aside = Aside\nLandmarks.Section = Section\nLandmarks.Article = Article\n","import UI from '#components/ui'\nimport React from 'react'\n\n/**\n * Props for the Badge component\n *\n * @property {React.ReactNode} children - Content to display inside the badge (typically numbers or short text)\n * @property {string} [id] - Optional HTML id attribute for the badge element\n * @property {React.CSSProperties} [styles] - Inline styles to apply to the badge\n * @property {string} [classes] - CSS class names to apply to the badge\n * @property {'rounded'} [variant] - Visual variant of the badge. Use 'rounded' for circular badges (fixed size with ellipsis for overflow)\n * @property {string} [aria-label] - Accessible label for screen readers. Required for icon-only or number-only badges\n * @property {'status' | 'note'} [role] - ARIA role for the badge. Defaults to 'status' for dynamic content\n */\nexport type BadgeProps = {\n /**\n * Content to display inside the badge (typically numbers or short text)\n */\n children?: React.ReactNode\n /**\n * Visual variant of the badge\n * - 'rounded': Circular badge style\n */\n variant?: 'rounded'\n} & React.ComponentProps<typeof UI>\n\n/**\n * Badge - A small label component for displaying status, counts, or notifications\n *\n * The Badge component is used to display supplementary information alongside other content,\n * such as notification counts, status indicators, or labels. It renders as a semantic `<sup>`\n * element with a nested `<span>` required for the component's styling architecture.\n *\n * ## Styling Architecture\n *\n * The Badge uses a nested structure (`<sup><span>content</span></sup>`) which is required\n * for the SCSS styling system. The outer `<sup>` element provides positioning context,\n * while the inner `<span>` receives the visual styling (background, padding, border-radius).\n *\n * ## Rounded Variant Behavior\n *\n * The `rounded` variant creates a perfect circular badge with fixed dimensions (1.5625rem).\n * Content that exceeds the available space will be truncated with an ellipsis (...).\n * **Best practice**: Format large numbers yourself (e.g., pass \"99+\" instead of \"999\").\n *\n * ## Accessibility Considerations\n *\n * - **Semantic HTML**: Uses `<sup>` (superscript) element for proper positioning context\n * - **ARIA Role**: Defaults to `role=\"status\"` for dynamic badges (e.g., unread counts)\n * - **Accessible Names**: For icon-only or number-only badges, provide an `aria-label`\n * to give context (e.g., \"3 unread messages\" instead of just \"3\")\n * - **Live Regions**: The `role=\"status\"` makes badges announce updates to screen readers\n *\n * @param {BadgeProps} props - Component props\n * @returns {React.ReactElement} A Badge component\n *\n * @example\n * // Basic badge with notification count\n * <p>\n * Messages\n * <Badge aria-label=\"3 unread messages\">3</Badge>\n * </p>\n *\n * @example\n * // Rounded badge variant (perfect circle)\n * <p>\n * Notifications\n * <Badge variant=\"rounded\" aria-label=\"99 or more notifications\">99+</Badge>\n * </p>\n *\n * @example\n * // Status badge with custom styling\n * <p>\n * Active Users\n * <Badge styles={{ backgroundColor: 'green', color: 'white' }}>21</Badge>\n * </p>\n *\n * @example\n * // ✅ GOOD: Accessible badge with descriptive label and formatted content\n * <Badge variant=\"rounded\" aria-label=\"12 items in cart\">12</Badge>\n *\n * @example\n * // ✅ GOOD: Large numbers formatted by developer\n * <Badge variant=\"rounded\" aria-label=\"More than 99 notifications\">99+</Badge>\n *\n * @example\n * // ❌ BAD: Number-only badge without context for screen readers\n * <Badge>12</Badge>\n */\nexport const Badge = ({ id, styles, classes, children, variant, ...props }: BadgeProps) => {\n // Build data-badge attribute for variant styling\n const dataBadge = variant ? variant : undefined\n\n return (\n <UI\n as=\"sup\"\n id={id}\n styles={styles}\n className={classes}\n data-badge={dataBadge}\n role=\"status\"\n {...props}\n >\n <UI as=\"span\">{children}</UI>\n </UI>\n )\n}\n\nBadge.displayName = 'Badge'\nexport default Badge\n","import React from 'react'\nimport UI from '#components/ui'\nimport type { TagProps, TagVariant } from './tag.types'\n\n/**\n * Tag - A small inline label component for displaying status, versions, or environment indicators\n *\n * The Tag component is used to highlight supplementary information such as release stages\n * (alpha, beta, stable), environment indicators (production), or version labels. It renders\n * as either a `<span>` (inline) or `<p>` (block) element with semantic ARIA roles.\n *\n * ## Design Philosophy\n *\n * Tags serve as visual and semantic indicators that:\n * - Communicate the state or stage of features, releases, or environments\n * - Provide quick visual scanning through color-coded variants\n * - Maintain accessibility through proper ARIA roles and labels\n *\n * ## Styling Architecture\n *\n * The Tag component uses CSS custom properties (CSS variables) for theming and styling,\n * allowing for easy customization through the `data-tag` attribute. Each variant\n * (alpha, beta, stable, production) applies predefined color schemes defined in SCSS.\n *\n * ## Accessibility Considerations (WCAG 2.1 AA Compliance)\n *\n * - **Semantic Roles**: Uses `role=\"note\"` for static tags or `role=\"status\"` for dynamic content\n * - `role=\"note\"`: Read once by screen readers, suitable for static labels (default)\n * - `role=\"status\"`: Announces updates to screen readers, use for changing status indicators\n * - **Color Independence**: Don't rely solely on color to convey meaning - include text labels\n * - **Text Alternatives**: For icon-only tags, provide `aria-label` for screen reader context\n * - **Contrast Ratios**: All variants meet WCAG AA contrast requirements (4.5:1 for normal text)\n * - **Live Regions**: When using `role=\"status\"`, tag becomes a live region for accessibility\n *\n * ## When to Use Each Role\n *\n * **Use `role=\"note\"` (default) when:**\n * - Displaying static version numbers (e.g., \"v2.1.0\")\n * - Showing fixed environment indicators (e.g., \"Beta Feature\")\n * - Labeling unchanging content categories\n *\n * **Use `role=\"status\"` when:**\n * - Indicating real-time status that may change (e.g., \"Processing\" → \"Complete\")\n * - Displaying live build/deployment states\n * - Showing dynamic feature flags that toggle\n *\n * @param {TagProps} props - Component props\n * @returns {React.ReactElement} A Tag component\n *\n * @example\n * // Basic tag with beta variant (default inline span)\n * <Tag variant=\"beta\">Beta</Tag>\n *\n * @example\n * // Production environment indicator as block element\n * <Tag elm=\"p\" variant=\"production\">Production Environment</Tag>\n *\n * @example\n * // Dynamic status tag with live updates\n * <Tag role=\"status\" variant=\"stable\">\n * {isDeployed ? 'Deployed' : 'Deploying...'}\n * </Tag>\n *\n * @example\n * // Tag with custom styling and accessibility label\n * <Tag\n * variant=\"alpha\"\n * aria-label=\"Alpha version - may contain bugs\"\n * styles={{ fontSize: '0.75rem' }}\n * >\n * Alpha\n * </Tag>\n *\n * @example\n * // ✅ GOOD: Clear text content with variant for visual enhancement\n * <Tag variant=\"stable\">v2.0 Stable</Tag>\n *\n * @example\n * // ✅ GOOD: Dynamic status with proper role\n * <Tag role=\"status\" variant=\"production\">{deploymentStatus}</Tag>\n *\n * @example\n * // ✅ GOOD: Accessible tag with descriptive label\n * <Tag variant=\"beta\" aria-label=\"Beta feature - feedback welcome\">\n * Beta\n * </Tag>\n *\n * @example\n * // ❌ BAD: Relying only on color without text\n * <Tag variant=\"production\" aria-label=\"Production\" />\n *\n * @example\n * // ❌ BAD: Using status role for static content\n * <Tag role=\"status\" variant=\"stable\">v1.0</Tag>\n */\nexport const Tag = ({\n elm = 'span',\n role = 'note',\n variant,\n children,\n styles,\n ...props\n}: TagProps) => {\n // Map variant to data-tag attribute for SCSS styling\n const dataTag = variant ? variant : undefined\n\n return (\n <UI\n as={elm}\n role={role}\n data-tag={dataTag}\n styles={styles}\n {...props}\n >\n {children}\n </UI>\n )\n}\n\nTag.displayName = 'Tag'\nexport default Tag\nexport type { TagProps, TagVariant }\n","import UI from \"#components/ui\";\nimport React, { useCallback } from \"react\";\nimport type { DetailsProps } from \"./details.types\";\n\n/**\n * Details - A progressive disclosure component using native HTML `<details>` element.\n *\n * This component wraps the native `<details>` and `<summary>` elements to provide\n * an accessible, semantic way to show and hide content. It supports accordion behavior\n * through the `name` attribute and includes proper keyboard navigation out of the box.\n *\n * ## Key Features:\n * - **Semantic HTML**: Uses native `<details>` for built-in accessibility\n * - **Keyboard Support**: Space/Enter to toggle, fully accessible by default\n * - **Accordion Mode**: Group multiple details with `name` for exclusive expansion\n * - **Customizable**: Supports icons, custom styles, and event handlers\n *\n * ## Accessibility:\n * - ✅ WCAG 2.1 AA compliant using semantic HTML\n * - ✅ Native keyboard support (Space, Enter)\n * - ✅ Screen reader compatible (announced as \"disclosure\" or \"expandable\")\n * - ✅ Focus indicators automatically applied via CSS\n * - ✅ `aria-expanded` managed automatically by browser\n *\n * @example\n * ```tsx\n * // Basic usage\n * <Details summary=\"Click to expand\">\n * <p>Hidden content here</p>\n * </Details>\n * ```\n *\n * @example\n * ```tsx\n * // With icon and custom styling\n * <Details\n * summary=\"Shipping Information\"\n * icon={<ChevronDownIcon />}\n * classes=\"custom-details\"\n * onToggle={(e) => console.log('Open:', e.currentTarget.open)}\n * >\n * <p>Ships within 2-3 business days</p>\n * </Details>\n * ```\n *\n * @example\n * ```tsx\n * // Accordion mode - only one open at a time\n * <Details name=\"faq\" summary=\"Question 1\">Answer 1</Details>\n * <Details name=\"faq\" summary=\"Question 2\">Answer 2</Details>\n * <Details name=\"faq\" summary=\"Question 3\">Answer 3</Details>\n * ```\n */\nexport const Details = React.forwardRef<HTMLDetailsElement, DetailsProps>(\n (\n {\n summary,\n icon,\n styles,\n classes,\n ariaLabel,\n name,\n open,\n onPointerDown,\n onToggle,\n children,\n ...props\n },\n ref\n ) => {\n // Memoize callbacks to prevent unnecessary re-renders of child components\n const handlePointerDown = useCallback(\n (e: React.PointerEvent<HTMLElement>) => {\n onPointerDown?.(e as React.PointerEvent<HTMLDetailsElement>);\n },\n [onPointerDown]\n );\n\n const handleToggle = useCallback(\n (e: React.SyntheticEvent<HTMLDetailsElement>) => {\n onToggle?.(e);\n },\n [onToggle]\n );\n\n return (\n <UI\n as=\"details\"\n styles={styles}\n classes={classes}\n onToggle={handleToggle}\n ref={ref}\n open={open}\n aria-label={ariaLabel}\n name={name}\n {...props}\n >\n <UI as=\"summary\" onPointerDown={handlePointerDown}>\n {icon}\n {summary}\n </UI>\n <UI as=\"section\">{children}</UI>\n </UI>\n );\n }\n);\n\nDetails.displayName = \"Details\";\n\nexport default Details;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/alert/alert.tsx","../src/components/alert/views/alert-screen-reader-text.tsx","../src/components/alert/views/alert-icon.tsx","../src/components/alert/views/alert-title.tsx","../src/components/alert/views/alert-content.tsx","../src/components/alert/views/alert-actions.tsx","../src/components/alert/views/alert-view.tsx","../src/components/alert/elements/dismiss-button.tsx","../src/components/images/img.tsx","../src/components/text-to-speech/TextToSpeech.tsx","../src/components/text-to-speech/useTextToSpeech.tsx","../src/components/text-to-speech/views/TextToSpeechControls.tsx","../src/components/layout/landmarks.tsx","../src/components/badge/badge.tsx","../src/components/tag/tag.tsx","../src/components/details/details.tsx"],"names":["React","SEVERITY_SCREEN_READER_TEXT","AlertScreenReaderText","severity","text","getSeverityIcon","iconProps","icon_default","AlertIcon","hideIcon","icon","ui_default","AlertTitle","title","titleLevel","TitleElement","AlertContent","children","contentType","AlertActions","actions","DismissButton","onDismiss","iconSize","button_default","dismiss_button_default","SEVERITY_ARIA_LIVE","AlertView","variant","isVisible","dismissible","onInteractionStart","onInteractionEnd","autoFocus","props","ref","useAlertBehavior","open","autoHideDuration","pauseOnHover","alertRef","setIsVisible","shouldRender","setShouldRender","isPaused","setIsPaused","handleDismiss","timer","handleKeyDown","e","pause","resume","Alert","handleInteractionStart","handleInteractionEnd","mergedIconProps","useMemo","Img","src","alt","width","height","styles","loading","placeholder","fetchpriority","decoding","srcSet","sizes","onError","onLoad","defaultPlaceholder","w","h","svg","fallbackPlaceholder","useState","useEffect","useTextToSpeech","initialVoice","availableVoices","setAvailableVoices","currentVoice","setCurrentVoice","isSpeaking","setIsSpeaking","utterance","setUtterance","updateVoices","voices","googleVoice","voice","englishVoice","options","onEnd","TTSButtonComponent","onClick","TTSButton","TextToSpeechControls","label","onSpeak","onPause","onResume","onCancel","TextToSpeechControls_default","TextToSpeech","initialText","showTextInput","pitch","rate","language","speak","cancel","getAvailableLanguages","setText","handleSpeak","handleEnd","handleChange","textarea_default","Landmarks","Header","id","headerBackground","classes","Main","Footer","Aside","Section","Article","Badge","Tag","elm","role","useCallback","Details","summary","ariaLabel","name","onPointerDown","onToggle","handlePointerDown","handleToggle"],"mappings":"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","sourcesContent":["import React from \"react\";\nimport { IconProps } from \"#components/icons/types\";\nimport { AlertView } from \"./views\";\n\n// ============================================================================\n// TYPES & CONFIGURATION\n// ============================================================================\n\n/**\n * Valid severity levels for alerts.\n * Each severity has associated colors, icons, and ARIA attributes.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Props for the Alert component.\n */\nexport type AlertProps = {\n /**\n * Whether the alert is open.\n */\n open: boolean;\n /**\n * The severity level of the alert.\n * @default \"default\"\n */\n severity?: Severity;\n /**\n * The main message content.\n */\n children: React.ReactNode;\n /**\n * Optional title for the alert.\n */\n title?: string;\n /**\n * Whether the alert can be dismissed.\n * @default false\n */\n dismissible?: boolean;\n /**\n * Callback when alert is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * Size of the severity icon in pixels.\n * Allows customization of icon size for different contexts.\n * @default 24\n * @example\n * ```tsx\n * <Alert iconSize={32} severity=\"error\">Larger icon</Alert>\n * <Alert iconSize={16} severity=\"info\">Smaller icon</Alert>\n * ```\n */\n iconSize?: number;\n\n /**\n * Whether to hide the severity icon.\n * When true, only text content is displayed.\n * @default false\n */\n hideIcon?: boolean;\n\n /**\n * Additional props to pass to the Icon component.\n * Allows fine-grained control over icon appearance.\n * @example\n * ```tsx\n * <Alert iconProps={{ className: 'custom-icon', 'aria-label': 'Custom' }}>\n * Alert with custom icon props\n * </Alert>\n * ```\n */\n iconProps?: IconProps;\n\n /**\n * Duration in milliseconds before the alert automatically dismisses.\n * Set to 0 or undefined to disable auto-dismiss.\n * @default undefined\n * @example\n * ```tsx\n * <Alert autoHideDuration={5000}>Success message</Alert>\n * ```\n */\n autoHideDuration?: number;\n\n /**\n * Whether to pause auto-dismiss when the alert is hovered or focused.\n * Complies with WCAG 2.2.1 (Timing Adjustable).\n * @default true\n */\n pauseOnHover?: boolean;\n\n /**\n * Semantic heading level for the title (2-6).\n * When undefined, uses <strong> element instead of heading.\n * Use this to maintain proper heading hierarchy on the page.\n * @default undefined\n * @example\n * ```tsx\n * <Alert titleLevel={2} title=\"Section Alert\">...</Alert>\n * <Alert titleLevel={3} title=\"Subsection Alert\">...</Alert>\n * ```\n */\n titleLevel?: 2 | 3 | 4 | 5 | 6;\n\n /**\n * Custom action buttons to display in the alert.\n * @example\n * ```tsx\n * <Alert actions={<><Button>Undo</Button><Button>Dismiss</Button></>}>\n * File deleted\n * </Alert>\n * ```\n */\n actions?: React.ReactNode;\n\n /**\n * Whether to automatically focus the alert when it becomes visible.\n * Useful for critical alerts that require immediate attention.\n * @default false\n */\n autoFocus?: boolean;\n\n /**\n * Visual variant of the alert.\n * - outlined: Border with lighter background (default)\n * - filled: Solid colored background\n * - soft: No border, subtle background\n * @default \"outlined\"\n */\n variant?: \"outlined\" | \"filled\" | \"soft\";\n\n /**\n * Content rendering mode for alert children.\n * Determines how the children content is wrapped in the alert message area.\n * - \"text\": Wraps children in a paragraph tag (default, for simple text content)\n * - \"node\": Renders children directly without wrapper (for complex layouts, lists, or custom components)\n * @default \"text\"\n * @example Simple text content (uses default \"text\" mode)\n * ```tsx\n * <Alert severity=\"info\">\n * This is a simple text message that will be wrapped in a paragraph.\n * </Alert>\n * ```\n * @example Complex content with list\n * ```tsx\n * <Alert severity=\"warning\" contentType=\"node\">\n * <p>Please review the following items:</p>\n * <ul>\n * <li>Check your email settings</li>\n * <li>Update your password</li>\n * <li>Enable two-factor authentication</li>\n * </ul>\n * </Alert>\n * ```\n * @example Custom component layout\n * ```tsx\n * <Alert severity=\"success\" contentType=\"node\">\n * <div className=\"custom-layout\">\n * <p>Operation completed successfully!</p>\n * <div className=\"stats\">\n * <span>Items processed: 150</span>\n * <span>Time elapsed: 2.5s</span>\n * </div>\n * </div>\n * </Alert>\n * ```\n */\n contentType?: \"text\" | \"node\";\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"title\" | \"children\">;\n\n/**\n * Alert is a fully accessible component for displaying status messages with different severity levels.\n * It supports multiple severity types (default, info, success, warning, error) and can include\n * optional titles and dismissal functionality.\n *\n * Features:\n * - Multiple severity levels with matching visual indicators\n * - Three variants: outlined (default), filled, and soft\n * - Auto-dismiss with configurable duration and pause on hover/focus\n * - Optional title with configurable heading levels (h2-h6) for proper document structure\n * - Action buttons support for interactive alerts\n * - Accessible by default with appropriate ARIA attributes\n * - Screen reader announcements for severity levels\n * - Keyboard support (ESC to dismiss)\n * - WCAG 2.1 Level AA compliant\n *\n * Accessibility Features:\n * - Visually hidden severity text for screen readers (WCAG 1.1.1, 1.4.1)\n * - Configurable heading levels to maintain document hierarchy (WCAG 1.3.1)\n * - Visible focus indicators for keyboard navigation (WCAG 2.4.7)\n * - Adequate color contrast for all variants (WCAG 1.4.3)\n * - 44×44px minimum touch target size for dismiss button (WCAG 2.5.5)\n * - Pause auto-dismiss on hover/focus (WCAG 2.2.1)\n *\n * @example Basic Usage\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"info\"\n * title=\"Optional Title\"\n * dismissible={true}\n * onDismiss={() => console.log('Alert dismissed')}\n * >\n * Alert message content\n * </Alert>\n * ```\n *\n * @example With Heading Level (for proper document structure)\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"error\"\n * title=\"Error Title\"\n * titleLevel={2}\n * dismissible={true}\n * >\n * Error message\n * </Alert>\n * ```\n *\n * @example Auto-dismiss with Pause on Hover\n * ```tsx\n * <Alert\n * open={true}\n * severity=\"success\"\n * autoHideDuration={5000}\n * pauseOnHover={true}\n * >\n * This will auto-dismiss in 5 seconds, but pauses when hovered\n * </Alert>\n * ```\n *\n * @see {@link AlertProps} for available configuration options\n */\n\n// ============================================================================\n// CUSTOM HOOK (Behavior Management)\n// ============================================================================\n\n/**\n * Custom hook that manages all Alert component behavior in one cohesive unit.\n * Consolidates visibility, auto-dismiss, keyboard, and focus management.\n *\n * @param open - Whether the alert should be open\n * @param onDismiss - Callback when alert is dismissed\n * @param dismissible - Whether the alert can be dismissed\n * @param autoHideDuration - Duration before auto-dismiss (ms)\n * @param pauseOnHover - Whether to pause auto-dismiss on hover/focus\n * @param autoFocus - Whether to auto-focus the alert\n * @param alertRef - Ref to the alert DOM element\n * @returns Object with visibility state, handlers, and event callbacks\n */\nconst useAlertBehavior = ({\n open,\n onDismiss,\n dismissible,\n autoHideDuration,\n pauseOnHover,\n autoFocus,\n alertRef,\n}: {\n open: boolean;\n onDismiss?: () => void;\n dismissible: boolean;\n autoHideDuration?: number;\n pauseOnHover: boolean;\n autoFocus: boolean;\n alertRef: React.RefObject<HTMLDivElement>;\n}) => {\n const [isVisible, setIsVisible] = React.useState(open);\n const [shouldRender, setShouldRender] = React.useState(open);\n const [isPaused, setIsPaused] = React.useState(false);\n\n // Dismiss handler with animation timing\n const handleDismiss = React.useCallback((): void => {\n setIsVisible(false);\n // Wait for animation to complete before unmounting\n setTimeout(() => {\n setShouldRender(false);\n onDismiss?.();\n }, 300); // Match CSS transition duration\n }, [onDismiss]);\n\n // Visibility management - sync with open prop\n React.useEffect(() => {\n if (open) {\n setShouldRender(true);\n setIsVisible(true);\n } else {\n setIsVisible(false);\n }\n }, [open]);\n\n // Auto-dismiss timer with pause support\n React.useEffect(() => {\n if (!autoHideDuration || !isVisible || isPaused) return;\n\n const timer = setTimeout(() => {\n handleDismiss();\n }, autoHideDuration);\n\n return () => clearTimeout(timer);\n }, [autoHideDuration, isVisible, isPaused, handleDismiss]);\n\n // ESC key support for dismissible alerts\n React.useEffect(() => {\n if (!dismissible || !isVisible) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n handleDismiss();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [dismissible, isVisible, handleDismiss]);\n\n // Auto-focus for critical alerts\n React.useEffect(() => {\n if (autoFocus && isVisible && alertRef.current) {\n alertRef.current.focus();\n }\n }, [autoFocus, isVisible, alertRef]);\n\n // Pause/resume handlers (memoized for stable references)\n const pause = React.useCallback(() => {\n if (pauseOnHover && autoHideDuration) {\n setIsPaused(true);\n }\n }, [pauseOnHover, autoHideDuration]);\n\n const resume = React.useCallback(() => {\n if (pauseOnHover && autoHideDuration) {\n setIsPaused(false);\n }\n }, [pauseOnHover, autoHideDuration]);\n\n return {\n isVisible,\n shouldRender,\n handleDismiss,\n handleInteractionStart: pause,\n handleInteractionEnd: resume,\n };\n};\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport const Alert: React.FC<AlertProps> = ({\n open,\n severity = \"default\",\n children,\n title,\n dismissible = false,\n onDismiss,\n iconSize,\n iconProps,\n hideIcon,\n autoHideDuration,\n pauseOnHover = true,\n titleLevel = 3,\n actions,\n autoFocus = false,\n variant = \"outlined\",\n contentType = \"text\",\n ...props\n}) => {\n const alertRef = React.useRef<HTMLDivElement>(null);\n\n // Use consolidated behavior hook\n const {\n isVisible,\n shouldRender,\n handleDismiss,\n handleInteractionStart,\n handleInteractionEnd,\n } = useAlertBehavior({\n open,\n onDismiss,\n dismissible,\n autoHideDuration,\n pauseOnHover,\n autoFocus,\n alertRef,\n });\n\n // Early return if component shouldn't render\n if (!shouldRender) return null;\n\n // Merge icon props with defaults\n const mergedIconProps: IconProps = {\n size: iconSize || 16,\n ...iconProps,\n };\n\n return (\n <AlertView\n ref={alertRef}\n severity={severity}\n variant={variant}\n isVisible={isVisible}\n dismissible={dismissible}\n onDismiss={handleDismiss}\n onInteractionStart={handleInteractionStart}\n onInteractionEnd={handleInteractionEnd}\n autoFocus={autoFocus}\n title={title}\n titleLevel={titleLevel}\n contentType={contentType}\n actions={actions}\n hideIcon={hideIcon}\n iconProps={mergedIconProps}\n {...props}\n >\n {children}\n </AlertView>\n );\n};\nexport default Alert;\nAlert.displayName = \"Alert\";\n","import React from \"react\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Screen reader announcement text for each severity level.\n */\nconst SEVERITY_SCREEN_READER_TEXT: Record<Severity, string> = {\n default: \"\",\n info: \"Information: \",\n success: \"Success: \",\n warning: \"Warning: \",\n error: \"Error: \",\n} as const;\n\n/**\n * Renders visually hidden severity text for screen readers.\n * Provides context about the alert type without visual clutter.\n *\n * @param severity - The alert severity level\n * @returns Hidden text for screen readers, or null if no text needed\n */\nexport const AlertScreenReaderText: React.FC<{ severity: Severity }> = ({ severity }) => {\n const text = SEVERITY_SCREEN_READER_TEXT[severity];\n if (!text) return null;\n return <span className=\"sr-only\">{text}</span>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\nimport Icon from \"#components/icons/icon\";\nimport { IconProps } from \"#components/icons/types\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Pure function to get the appropriate icon for a severity level.\n *\n * @param severity - The alert severity level\n * @param iconProps - Props to pass to the Icon component\n * @returns The icon element for the severity\n */\nconst getSeverityIcon = (\n severity: Severity,\n iconProps: IconProps\n): JSX.Element => {\n const severityIcons: Record<Severity, JSX.Element> = {\n info: <Icon.InfoSolid {...iconProps} />,\n success: <Icon.SuccessSolid {...iconProps} />,\n warning: <Icon.WarnSolid {...iconProps} />,\n error: <Icon.AlertSolid {...iconProps} />,\n default: <Icon.AlertSquareSolid {...iconProps} />,\n };\n return severityIcons[severity];\n};\n\n/**\n * Renders the severity icon with proper ARIA attributes.\n * Icon is hidden from screen readers as the text provides context.\n *\n * @param severity - The alert severity level\n * @param iconProps - Props to pass to the Icon component\n * @param hideIcon - Whether to hide the icon\n * @returns Icon element, or null if hidden\n */\nexport const AlertIcon: React.FC<{\n severity: Severity;\n iconProps: IconProps;\n hideIcon?: boolean;\n}> = ({ severity, iconProps, hideIcon }) => {\n if (hideIcon) return null;\n const icon = getSeverityIcon(severity, iconProps);\n return (\n <UI aria-hidden=\"true\" className=\"alert-icon\">\n {icon}\n </UI>\n );\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders the alert title with configurable heading level.\n * Uses semantic heading (h2-h6) or strong element based on titleLevel prop.\n *\n * @param title - The title text to display\n * @param titleLevel - Semantic heading level (2-6)\n * @returns Title element, or null if no title provided\n */\nexport const AlertTitle: React.FC<{\n title?: string;\n titleLevel: 2 | 3 | 4 | 5 | 6;\n}> = ({ title, titleLevel }) => {\n if (!title) return null;\n const TitleElement = titleLevel ? (`h${titleLevel}` as const) : \"strong\";\n return (\n <UI as={TitleElement} className=\"alert-title\">\n {title}\n </UI>\n );\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders the alert message content.\n * Supports both simple text (wrapped in <p>) and complex node structures.\n *\n * @param children - The content to render\n * @param contentType - How to wrap the content (\"text\" or \"node\")\n * @returns Wrapped content\n */\nexport const AlertContent: React.FC<{\n children: React.ReactNode;\n contentType: \"text\" | \"node\";\n}> = ({ children, contentType }) => {\n return contentType === \"node\" ? <>{children}</> : <UI as=\"p\">{children}</UI>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\n\n/**\n * Renders optional action buttons within the alert.\n *\n * @param actions - Action button elements to display\n * @returns Actions container, or null if no actions provided\n */\nexport const AlertActions: React.FC<{ actions?: React.ReactNode }> = ({ actions }) => {\n if (!actions) return null;\n return <UI as=\"div\" className=\"alert-actions\">{actions}</UI>;\n};\n","import React from \"react\";\nimport UI from \"#components/ui\";\nimport { IconProps } from \"#components/icons/types\";\nimport DismissButton from \"../elements/dismiss-button\";\nimport {\n AlertScreenReaderText,\n AlertIcon,\n AlertTitle,\n AlertContent,\n AlertActions,\n} from \".\";\n\n/**\n * Valid severity levels for alerts.\n */\ntype Severity = \"default\" | \"info\" | \"success\" | \"warning\" | \"error\";\n\n/**\n * Maps severity levels to ARIA live region types.\n */\nconst SEVERITY_ARIA_LIVE: Record<Severity, \"polite\" | \"assertive\"> = {\n default: \"polite\",\n info: \"polite\",\n success: \"polite\",\n warning: \"polite\",\n error: \"assertive\",\n} as const;\n\n/**\n * Props for the AlertView presentation component.\n */\nexport type AlertViewProps = {\n /**\n * The severity level of the alert.\n */\n severity: Severity;\n /**\n * Visual variant of the alert.\n */\n variant: \"outlined\" | \"filled\" | \"soft\";\n /**\n * Whether the alert is currently visible (for animations).\n */\n isVisible: boolean;\n /**\n * Whether the alert can be dismissed.\n */\n dismissible: boolean;\n /**\n * Callback when dismiss button is clicked.\n */\n onDismiss: () => void;\n /**\n * Handler for interaction start (hover/focus).\n */\n onInteractionStart: () => void;\n /**\n * Handler for interaction end (leave/blur).\n */\n onInteractionEnd: () => void;\n /**\n * Whether to automatically focus the alert.\n */\n autoFocus: boolean;\n /**\n * Optional title for the alert.\n */\n title?: string;\n /**\n * Semantic heading level for the title (2-6).\n */\n titleLevel: 2 | 3 | 4 | 5 | 6;\n /**\n * The main message content.\n */\n children: React.ReactNode;\n /**\n * Content rendering mode for alert children.\n */\n contentType: \"text\" | \"node\";\n /**\n * Custom action buttons to display in the alert.\n */\n actions?: React.ReactNode;\n /**\n * Whether to hide the severity icon.\n */\n hideIcon?: boolean;\n /**\n * Merged props for the Icon component.\n */\n iconProps: IconProps;\n} & React.ComponentProps<typeof UI>;\n\n/**\n * AlertView is a pure presentation component that renders the Alert UI structure.\n * It receives all presentation props and behavior handlers from the parent Alert component.\n *\n * This component is focused solely on rendering the visual structure and does not contain\n * any business logic or state management. All behavior is delegated to the parent.\n *\n * @param props - AlertView props including severity, variant, handlers, and content\n * @returns The rendered alert UI structure\n */\nexport const AlertView = React.forwardRef<HTMLDivElement, AlertViewProps>(\n (\n {\n severity,\n variant,\n isVisible,\n dismissible,\n onDismiss,\n onInteractionStart,\n onInteractionEnd,\n autoFocus,\n title,\n titleLevel,\n children,\n contentType,\n actions,\n hideIcon,\n iconProps,\n ...props\n },\n ref\n ) => {\n return (\n <UI\n as=\"div\"\n ref={ref}\n role=\"alert\"\n aria-live={SEVERITY_ARIA_LIVE[severity]}\n aria-atomic=\"true\"\n className={`alert alert-${severity}`}\n data-alert={severity}\n data-visible={isVisible}\n data-variant={variant}\n tabIndex={autoFocus ? -1 : undefined}\n onMouseEnter={onInteractionStart}\n onMouseLeave={onInteractionEnd}\n onFocus={onInteractionStart}\n onBlur={onInteractionEnd}\n {...props}\n >\n <AlertScreenReaderText severity={severity} />\n <AlertIcon severity={severity} iconProps={iconProps} hideIcon={hideIcon} />\n <UI as=\"div\" className=\"alert-message\">\n <AlertTitle title={title} titleLevel={titleLevel} />\n <AlertContent contentType={contentType}>{children}</AlertContent>\n <AlertActions actions={actions} />\n </UI>\n {dismissible && <DismissButton onDismiss={onDismiss} />}\n </UI>\n );\n }\n);\n\nAlertView.displayName = \"AlertView\";\n","import React from \"react\";\nimport Button from \"#components/buttons/button\";\nimport Icon from \"#components/icons/icon\";\n/** Props for the DismissButton component */\ntype DismissButtonProps = {\n /** Callback function when dismiss button is clicked */\n onDismiss: () => void;\n /** Size of the close icon in pixels. Defaults to 16 */\n iconSize?: number;\n};\nexport const DismissButton = React.memo(\n ({ onDismiss, iconSize = 16 }: DismissButtonProps) => (\n <Button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Close alert\"\n className=\"alert-dismiss\"\n data-btn=\"icon sm\"\n >\n <Icon>\n <Icon.Close size={iconSize} />\n </Icon>\n </Button>\n )\n);\n\nexport default DismissButton;\nDismissButton.displayName = \"DismissButton\";\n","import UI from \"../ui\";\nimport React, { useMemo } from \"react\";\nimport type { ImgProps } from \"./img.types\";\n\n/**\n * Img - A semantic image component with accessibility and performance best practices.\n *\n * This component wraps the native `<img>` element with enhanced features:\n * - **Responsive images** via optional srcset/sizes\n * - **Lazy loading** by default for performance\n * - **Error handling** with configurable fallback placeholders\n * - **Type safety** with full TypeScript support\n *\n * ## Accessibility Patterns (WCAG 2.1 AA)\n *\n * ### Decorative Images\n * Images that are purely visual decoration should use an empty alt attribute.\n * These images are typically borders, patterns, or visual separators.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Decorative border image\n * <Img src=\"/decorative-border.png\" alt=\"\" />\n *\n * // ✅ GOOD: Background pattern\n * <Img src=\"/pattern.svg\" alt=\"\" loading=\"eager\" />\n * ```\n *\n * ### Semantic Images\n * Images that convey information must have descriptive alt text that explains\n * the content and purpose of the image.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Informative image with descriptive alt\n * <Img\n * src=\"/sales-chart.png\"\n * alt=\"Sales chart showing 30% revenue growth in Q4 2024\"\n * />\n *\n * // ✅ GOOD: Product photo with context\n * <Img\n * src=\"/laptop.jpg\"\n * alt=\"Silver MacBook Pro 14-inch on wooden desk\"\n * />\n * ```\n *\n * ## Performance Optimization\n *\n * ### Lazy Loading\n * By default, images use lazy loading to improve page load performance.\n * Only use `loading=\"eager\"` for above-the-fold images.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Lazy load below-the-fold image\n * <Img src=\"/photo.jpg\" alt=\"Photo\" />\n *\n * // ✅ GOOD: Eager load hero image\n * <Img\n * src=\"/hero.jpg\"\n * alt=\"Hero banner\"\n * loading=\"eager\"\n * fetchpriority=\"high\"\n * />\n * ```\n *\n * ### Responsive Images\n * Use srcset and sizes for responsive images to serve appropriate image sizes\n * based on viewport width, improving performance and bandwidth usage.\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Responsive image with multiple sizes\n * <Img\n * src=\"/photo.jpg\"\n * srcSet=\"/photo-320w.jpg 320w, /photo-640w.jpg 640w, /photo-1024w.jpg 1024w\"\n * sizes=\"(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 800px\"\n * alt=\"Responsive image adapts to viewport\"\n * />\n * ```\n *\n * ## Error Handling\n *\n * @example\n * ```tsx\n * // ✅ GOOD: Custom placeholder on error\n * <Img\n * src=\"/photo.jpg\"\n * placeholder=\"/fallback.png\"\n * alt=\"User profile photo\"\n * />\n *\n * // ✅ GOOD: Custom error handler\n * <Img\n * src=\"/photo.jpg\"\n * onError={(e) => {\n * console.error('Image failed to load')\n * logToAnalytics('image_error', { src: e.currentTarget.src })\n * }}\n * alt=\"Photo\"\n * />\n * ```\n *\n * @param {ImgProps} props - Component props extending native img attributes\n * @returns {React.ReactElement} Image element with enhanced functionality\n *\n * @see {@link ImgProps} for complete prop documentation\n * @see https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html\n */\nexport const Img = ({\n src = \"//\",\n alt,\n width = 480,\n height,\n styles,\n loading = \"lazy\",\n placeholder,\n fetchpriority = \"low\",\n decoding = \"auto\",\n srcSet,\n sizes,\n onError,\n onLoad,\n ...props\n}: ImgProps) => {\n /**\n * Generates a performant, responsive SVG gradient placeholder.\n * Uses data URI to avoid network requests and memoizes based on dimensions.\n * The SVG uses viewBox for perfect scaling at any size.\n *\n * Features:\n * - Zero network requests (works offline)\n * - ~900 bytes vs. 5-10KB external image\n * - Responsive with viewBox\n * - Attractive gradient (indigo → purple → pink)\n * - Dimension text for debugging\n */\n const defaultPlaceholder = useMemo(() => {\n const w = typeof width === \"number\" ? width : 480;\n const h = typeof height === \"number\" ? height : Math.round(w * 0.75);\n\n // Responsive SVG with attractive gradient and dimension text\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\">\n <defs>\n <linearGradient id=\"grad-${w}-${h}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" style=\"stop-color:#6366f1;stop-opacity:1\" />\n <stop offset=\"50%\" style=\"stop-color:#8b5cf6;stop-opacity:1\" />\n <stop offset=\"100%\" style=\"stop-color:#ec4899;stop-opacity:1\" />\n </linearGradient>\n </defs>\n <rect width=\"${w}\" height=\"${h}\" fill=\"url(#grad-${w}-${h})\"/>\n <circle cx=\"${w * 0.15}\" cy=\"${h * 0.2}\" r=\"${Math.min(w, h) * 0.08}\" fill=\"rgba(255,255,255,0.2)\"/>\n <path d=\"M0,${h * 0.75} Q${w * 0.25},${h * 0.65} ${w * 0.5},${h * 0.75} T${w},${h * 0.75} L${w},${h} L0,${h} Z\" fill=\"rgba(0,0,0,0.15)\"/>\n <text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"system-ui,-apple-system,sans-serif\" font-size=\"${Math.max(16, Math.min(w, h) * 0.05)}\" font-weight=\"500\" fill=\"rgba(255,255,255,0.9)\">${w}×${h}</text>\n </svg>`;\n\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n }, [width, height]);\n\n const fallbackPlaceholder = placeholder ?? defaultPlaceholder;\n\n /**\n * Handles image load errors.\n * Calls custom error handler if provided, then applies fallback placeholder.\n * The custom handler can prevent the default fallback by calling e.preventDefault().\n */\n const handleImgError = (\n e: React.SyntheticEvent<HTMLImageElement, Event>\n ): void => {\n // Call custom error handler first (for logging, analytics, etc.)\n if (onError) {\n onError(e);\n }\n\n // Apply fallback unless preventDefault() was called\n if (!e.defaultPrevented) {\n // Avoid infinite error loop by checking if already showing placeholder\n if (e.currentTarget.src !== fallbackPlaceholder) {\n e.currentTarget.src = fallbackPlaceholder;\n }\n }\n };\n\n /**\n * Handles successful image load.\n * Calls custom load handler if provided.\n */\n const handleImgLoad = (\n e: React.SyntheticEvent<HTMLImageElement, Event>\n ): void => {\n onLoad?.(e);\n };\n\n return (\n <UI\n as=\"img\"\n src={src}\n alt={alt}\n width={width}\n height={height || \"auto\"}\n loading={loading}\n style={styles}\n srcSet={srcSet}\n sizes={sizes}\n onError={handleImgError}\n onLoad={handleImgLoad}\n decoding={decoding}\n {...props}\n {...(fetchpriority && { fetchpriority })}\n />\n );\n};\n\nexport default Img;\nImg.displayName = \"Img\";\n","import React, { useState, ChangeEvent, useEffect } from 'react'\nimport { useTextToSpeech } from './useTextToSpeech'\nimport Textarea from '#components/form/textarea.jsx'\nimport TextToSpeechControls from './views/TextToSpeechControls'\n\n/**\n * Props for the TextToSpeechComponent.\n * @interface TextToSpeechComponentProps\n */\ninterface TextToSpeechComponentProps {\n /** Initial text to be spoken. Defaults to an empty string. */\n initialText?: string\n /** Whether to show the text input field. Defaults to true. */\n showTextInput?: boolean\n /** The voice to be used for speech synthesis. */\n voice?: SpeechSynthesisVoice | undefined\n /** The pitch of the voice. Defaults to 1. */\n pitch?: number\n /** The rate of speech. Defaults to 1. */\n rate?: number\n /** The language to be used for speech synthesis. */\n language?: string\n /** Player label */\n label?: string | React.ReactNode\n /** Callback function to be called when speech ends. */\n onEnd?: () => void\n}\n\n/**\n * A component that converts text to speech using the Web Speech API.\n * @param {TextToSpeechComponentProps} props - The props for the component.\n * @returns {JSX.Element} The rendered TextToSpeechComponent.\n */\nexport const TextToSpeech: React.FC<TextToSpeechComponentProps> = ({\n initialText = '',\n showTextInput = false,\n voice,\n pitch = 1,\n rate = 1,\n language,\n label,\n onEnd,\n}) => {\n const {\n speak,\n pause,\n resume,\n cancel,\n isSpeaking,\n isPaused,\n getAvailableLanguages,\n availableVoices,\n } = useTextToSpeech()\n const [text, setText] = useState<string>(initialText)\n console.log(getAvailableLanguages())\n\n useEffect(() => {\n setText(initialText)\n }, [initialText])\n\n const handleSpeak = (): void => {\n if (text.trim() !== '') {\n speak(text, { voice, pitch, rate }, handleEnd)\n }\n }\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>): void => {\n setText(e.target.value)\n }\n\n const handleEnd = (): void => {\n if (onEnd) {\n onEnd()\n }\n }\n\n return (\n <>\n {showTextInput && <Textarea value={text} onChange={handleChange} />}\n <TextToSpeechControls\n label={label}\n isSpeaking={isSpeaking}\n isPaused={isPaused}\n onSpeak={handleSpeak}\n onPause={pause}\n onResume={resume}\n onCancel={cancel}\n />\n </>\n )\n}\n\nexport default TextToSpeech\nTextToSpeech.displayName = 'TextToSpeechComponent'\n","import { useState, useEffect } from 'react'\n\n/**\n * Options for configuring speech synthesis.\n * @interface SpeechOptions\n */\ninterface SpeechOptions {\n /** The language for speech synthesis (e.g., 'en-US') */\n lang?: string\n\n /** The pitch of the voice (0 to 2) */\n pitch?: number\n /** The speed of the voice (0.1 to 10) */\n rate?: number\n\n /** The voice to use for speech synthesis */\n voice?: SpeechSynthesisVoice\n}\n/**\n * Custom hook to handle text-to-speech functionality.\n *\n * @param {SpeechSynthesisVoice} [initialVoice] - The initial voice to use for speech synthesis.\n * @returns {Object} An object containing methods to control speech synthesis and state variables.\n */\nexport const useTextToSpeech = (initialVoice?: SpeechSynthesisVoice) => {\n const [availableVoices, setAvailableVoices] = useState<\n SpeechSynthesisVoice[]\n >([])\n const [currentVoice, setCurrentVoice] = useState<\n SpeechSynthesisVoice | undefined\n >(initialVoice)\n\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false)\n const [isPaused, setIsPaused] = useState<boolean>(false)\n const [utterance, setUtterance] = useState<SpeechSynthesisUtterance | null>(\n null,\n )\n\n useEffect(() => {\n const updateVoices = () => {\n const voices = window.speechSynthesis.getVoices()\n setAvailableVoices(voices)\n\n // Set default voice to Google US English if available\n const googleVoice = voices.find(\n (voice) => voice.name === 'Google US English',\n )\n if (googleVoice) {\n setCurrentVoice(googleVoice)\n } else {\n // Fallback to the first English voice if Google voice is not available\n const englishVoice = voices.find((voice) =>\n voice.lang.startsWith('en-'),\n )\n if (englishVoice) {\n setCurrentVoice(englishVoice)\n }\n }\n }\n\n updateVoices()\n window.speechSynthesis.onvoiceschanged = updateVoices\n\n return () => {\n window.speechSynthesis.onvoiceschanged = null\n }\n }, [])\n\n /**\n * Gets the list of available languages for speech synthesis.\n * @returns {string[]} An array of available language codes.\n */\n const getAvailableLanguages = () => {\n return [...new Set(availableVoices.map((voice) => voice.lang))]\n }\n\n /**\n * Initiates speech synthesis for the given text.\n *\n * @param {string} text - The text to be spoken.\n * @param {SpeechOptions} [options={}] - Options for speech synthesis.\n * @param {Function} [onEnd] - Callback function to be called when speech ends.\n */\n const speak = (\n text: string,\n options: SpeechOptions = {},\n onEnd?: () => void,\n ) => {\n const utterance = new SpeechSynthesisUtterance(text)\n\n utterance.lang = options.lang ?? 'en-US'\n utterance.pitch = options.pitch ?? 1\n utterance.rate = options.rate ?? 1\n utterance.voice = currentVoice ?? options.voice ?? null\n\n utterance.onend = () => {\n setIsSpeaking(false)\n setIsPaused(false)\n if (onEnd) {\n onEnd()\n }\n }\n\n if ('speechSynthesis' in window) {\n window.speechSynthesis.speak(utterance)\n setUtterance(utterance)\n setIsSpeaking(true)\n setIsPaused(false)\n } else {\n console.error('Speech synthesis not supported')\n // Handle the error appropriately\n }\n }\n\n /**\n * Changes the current voice used for speech synthesis.\n * @param {SpeechSynthesisVoice} voice - The new voice to use.\n */\n const changeVoice = (voice: SpeechSynthesisVoice) => {\n setCurrentVoice(voice)\n }\n\n /**\n * Pauses the ongoing speech synthesis.\n */\n const pause = () => {\n if (isSpeaking && !isPaused) {\n window.speechSynthesis.pause()\n setIsPaused(true)\n }\n }\n\n /**\n * Resumes the paused speech synthesis.\n */\n const resume = () => {\n if (isSpeaking && isPaused) {\n window.speechSynthesis.resume()\n setIsPaused(false)\n }\n }\n\n /**\n * Cancels the ongoing speech synthesis.\n */\n const cancel = () => {\n if (isSpeaking) {\n window.speechSynthesis.cancel()\n setIsSpeaking(false)\n setIsPaused(false)\n }\n }\n\n return {\n /** Initiates speech synthesis for the given text */\n speak,\n /** Pauses the ongoing speech synthesis */\n pause,\n /** Resumes the paused speech synthesis */\n resume,\n /** Cancels the ongoing speech synthesis */\n cancel,\n /** Indicates whether speech synthesis is currently active */\n isSpeaking,\n /** Indicates whether speech synthesis is currently paused */\n isPaused,\n /** Array of available voices for speech synthesis */\n availableVoices,\n /** Changes the current voice used for speech synthesis */\n changeVoice,\n /** The currently selected voice for speech synthesis */\n currentVoice,\n /** Gets the list of available languages for speech synthesis */\n getAvailableLanguages,\n }\n}\n","import React from 'react'\nimport Icon from '#components/icons/icon'\nimport UI from '#components/ui'\nimport { FC } from 'react'\n\n/**\n * Props for the TextToSpeechControls component.\n * @interface TextToSpeechControlsProps\n */\ninterface TextToSpeechControlsProps {\n /** Optional label for the controls */\n label?: string | React.ReactNode\n /** Indicates if the text-to-speech is currently speaking */\n isSpeaking: boolean\n /** Indicates if the text-to-speech is paused */\n isPaused: boolean\n /** Function to start speaking */\n onSpeak: () => void\n /** Function to pause speaking */\n onPause: () => void\n /** Function to resume speaking */\n onResume: () => void\n /** Function to cancel speaking */\n onCancel: () => void\n}\n\n/**\n * TTSButtonComponent props\n * @interface TTSButtonComponentProps\n */\ninterface TTSButtonComponentProps {\n /** The content of the button */\n children: React.ReactNode\n /** Function to call when the button is clicked */\n onClick: () => void\n}\n\n/**\n * TTSButtonComponent is a reusable button component for text-to-speech controls.\n * @param {TTSButtonComponentProps} props - The component props\n * @returns {React.ReactElement} The rendered button\n */\nexport const TTSButtonComponent: React.FC<TTSButtonComponentProps> = ({\n children,\n onClick,\n}) => {\n return (\n <UI\n as=\"button\"\n type=\"button\"\n className=\"tts-border\"\n data-btn=\"sm text pill\"\n onClick={onClick}\n >\n {children}\n </UI>\n )\n}\n\nexport const TTSButton = React.memo(TTSButtonComponent)\n\n/**\n * TextToSpeechControlsComponent interface extends FC<TextToSpeechControlsProps>\n * and includes a TTSButton property.\n * @interface TextToSpeechControlsComponent\n * @extends {FC<TextToSpeechControlsProps>}\n */\ninterface TextToSpeechControlsComponent extends FC<TextToSpeechControlsProps> {\n /** The TTSButton component used within TextToSpeechControls */\n TTSButton: typeof TTSButton\n}\n\n/**\n * TextToSpeechControls component provides a user interface for controlling text-to-speech functionality.\n * @param {TextToSpeechControlsProps} props - The component props\n * @returns {React.ReactElement} The rendered TextToSpeechControls component\n */\nconst TextToSpeechControls: TextToSpeechControlsComponent = ({\n label,\n isSpeaking,\n isPaused,\n onSpeak,\n onPause,\n onResume,\n onCancel,\n}) => {\n const iconSize = 16\n\n return (\n <UI as=\"div\" data-tts>\n {label && <p>{label}</p>}\n {!isSpeaking && (\n <TTSButton aria-label=\"Speak\" onClick={onSpeak}>\n <Icon.PlaySolid size={iconSize} />\n </TTSButton>\n )}\n {isSpeaking && !isPaused && (\n <TTSButton aria-label=\"Pause\" onClick={onPause}>\n <Icon.PauseSolid size={iconSize} />\n </TTSButton>\n )}\n {isPaused && (\n <TTSButton aria-label=\"Resume\" onClick={onResume}>\n <Icon.ResumeSolid size={iconSize} />\n </TTSButton>\n )}\n <TTSButton aria-label=\"Stop\" onClick={onCancel}>\n <Icon.StopSolid size={iconSize} />\n </TTSButton>\n </UI>\n )\n}\n\nTextToSpeechControls.displayName = 'TextToSpeechControls'\nTextToSpeechControls.TTSButton = TTSButton\n\nexport default TextToSpeechControls\n","import UI from '../ui'\nimport React, { ReactNode } from 'react'\n\ntype ComponentProps = React.ComponentProps<typeof UI>\n\n/**\n * Renders children elements without any wrapping component.\n * Can be used as a placeholder when no semantic landmark is needed.\n */\nexport const Landmarks = (children?: React.FC) => <>{children}</>\n\ntype HeaderProps = {\n headerBackground?: ReactNode\n} & ComponentProps\n/**\n * Header component.\n *\n * Renders a header landmark with a section child.\n *\n * @param children - The content to render inside the header.\n * @param styles - Optional styles object.\n * @param props - Other props.\n */\nexport const Header = ({\n id,\n children,\n headerBackground,\n styles,\n classes,\n ...props\n}: HeaderProps) => {\n return (\n <UI as=\"header\" id={id} styles={styles} className={classes} {...props}>\n {headerBackground}\n <UI as=\"section\">{children}</UI>\n </UI>\n )\n}\n\n/**\n * Main component.\n *\n * Renders a main landmark.\n *\n * @param children - The content to render inside the main element.\n * @param styles - Optional styles object.\n * @param props - Other props.\n */\nexport const Main = ({\n id,\n children,\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"main\" id={id} styles={styles} {...props} className={classes}>\n {children}\n </UI>\n )\n}\n\n/**\n * Footer component that renders a footer element with a section element inside.\n * @param {ReactNode} children - Child elements to render inside the section element.\n * @param styles - CSS styles to apply to the footer element.\n * @param props - Additional props to pass to the footer element.\n * @returns A React component that renders a footer element with a section element inside.\n */\nexport const Footer = ({\n id,\n classes,\n children,\n styles = {},\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"footer\" id={id} className={classes} styles={styles} {...props}>\n <UI as=\"section\">{children || 'Copyright © 2022'}</UI>\n </UI>\n )\n}\n\nexport const Aside = ({\n id,\n children,\n styles = {},\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"aside\" id={id} styles={styles} className={classes} {...props}>\n <UI as=\"section\">{children}</UI>\n </UI>\n )\n}\n\n/**\n * Section component that renders a section element.\n *\n * @param children - Child elements to render inside the section.\n * @param styles - CSS styles to apply to the section.\n * @param props - Other props.\n */\nexport const Section = ({\n id,\n children,\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"section\" id={id} styles={styles} className={classes} {...props}>\n {children}\n </UI>\n )\n}\n\n/**\n * Article component renders an HTML <article> element.\n *\n * @param children - Child elements to render inside the article.\n * @param styles - CSS styles to apply to the article.\n * @param props - Additional props to pass to the article element.\n */\nexport const Article = ({\n id,\n children,\n\n styles,\n classes,\n ...props\n}: ComponentProps) => {\n return (\n <UI as=\"article\" id={id} styles={styles} className={classes} {...props}>\n {children}\n </UI>\n )\n}\n\nexport default Landmarks\n\nLandmarks.displayName = 'Landmarks'\nLandmarks.Header = Header\nLandmarks.Main = Main\nLandmarks.Footer = Footer\nLandmarks.Aside = Aside\nLandmarks.Section = Section\nLandmarks.Article = Article\n","import UI from '#components/ui'\nimport React from 'react'\n\n/**\n * Props for the Badge component\n *\n * @property {React.ReactNode} children - Content to display inside the badge (typically numbers or short text)\n * @property {string} [id] - Optional HTML id attribute for the badge element\n * @property {React.CSSProperties} [styles] - Inline styles to apply to the badge\n * @property {string} [classes] - CSS class names to apply to the badge\n * @property {'rounded'} [variant] - Visual variant of the badge. Use 'rounded' for circular badges (fixed size with ellipsis for overflow)\n * @property {string} [aria-label] - Accessible label for screen readers. Required for icon-only or number-only badges\n * @property {'status' | 'note'} [role] - ARIA role for the badge. Defaults to 'status' for dynamic content\n */\nexport type BadgeProps = {\n /**\n * Content to display inside the badge (typically numbers or short text)\n */\n children?: React.ReactNode\n /**\n * Visual variant of the badge\n * - 'rounded': Circular badge style\n */\n variant?: 'rounded'\n} & React.ComponentProps<typeof UI>\n\n/**\n * Badge - A small label component for displaying status, counts, or notifications\n *\n * The Badge component is used to display supplementary information alongside other content,\n * such as notification counts, status indicators, or labels. It renders as a semantic `<sup>`\n * element with a nested `<span>` required for the component's styling architecture.\n *\n * ## Styling Architecture\n *\n * The Badge uses a nested structure (`<sup><span>content</span></sup>`) which is required\n * for the SCSS styling system. The outer `<sup>` element provides positioning context,\n * while the inner `<span>` receives the visual styling (background, padding, border-radius).\n *\n * ## Rounded Variant Behavior\n *\n * The `rounded` variant creates a perfect circular badge with fixed dimensions (1.5625rem).\n * Content that exceeds the available space will be truncated with an ellipsis (...).\n * **Best practice**: Format large numbers yourself (e.g., pass \"99+\" instead of \"999\").\n *\n * ## Accessibility Considerations\n *\n * - **Semantic HTML**: Uses `<sup>` (superscript) element for proper positioning context\n * - **ARIA Role**: Defaults to `role=\"status\"` for dynamic badges (e.g., unread counts)\n * - **Accessible Names**: For icon-only or number-only badges, provide an `aria-label`\n * to give context (e.g., \"3 unread messages\" instead of just \"3\")\n * - **Live Regions**: The `role=\"status\"` makes badges announce updates to screen readers\n *\n * @param {BadgeProps} props - Component props\n * @returns {React.ReactElement} A Badge component\n *\n * @example\n * // Basic badge with notification count\n * <p>\n * Messages\n * <Badge aria-label=\"3 unread messages\">3</Badge>\n * </p>\n *\n * @example\n * // Rounded badge variant (perfect circle)\n * <p>\n * Notifications\n * <Badge variant=\"rounded\" aria-label=\"99 or more notifications\">99+</Badge>\n * </p>\n *\n * @example\n * // Status badge with custom styling\n * <p>\n * Active Users\n * <Badge styles={{ backgroundColor: 'green', color: 'white' }}>21</Badge>\n * </p>\n *\n * @example\n * // ✅ GOOD: Accessible badge with descriptive label and formatted content\n * <Badge variant=\"rounded\" aria-label=\"12 items in cart\">12</Badge>\n *\n * @example\n * // ✅ GOOD: Large numbers formatted by developer\n * <Badge variant=\"rounded\" aria-label=\"More than 99 notifications\">99+</Badge>\n *\n * @example\n * // ❌ BAD: Number-only badge without context for screen readers\n * <Badge>12</Badge>\n */\nexport const Badge = ({ id, styles, classes, children, variant, ...props }: BadgeProps) => {\n // Build data-badge attribute for variant styling\n const dataBadge = variant ? variant : undefined\n\n return (\n <UI\n as=\"sup\"\n id={id}\n styles={styles}\n className={classes}\n data-badge={dataBadge}\n role=\"status\"\n {...props}\n >\n <UI as=\"span\">{children}</UI>\n </UI>\n )\n}\n\nBadge.displayName = 'Badge'\nexport default Badge\n","import React from 'react'\nimport UI from '#components/ui'\nimport type { TagProps, TagVariant } from './tag.types'\n\n/**\n * Tag - A small inline label component for displaying status, versions, or environment indicators\n *\n * The Tag component is used to highlight supplementary information such as release stages\n * (alpha, beta, stable), environment indicators (production), or version labels. It renders\n * as either a `<span>` (inline) or `<p>` (block) element with semantic ARIA roles.\n *\n * ## Design Philosophy\n *\n * Tags serve as visual and semantic indicators that:\n * - Communicate the state or stage of features, releases, or environments\n * - Provide quick visual scanning through color-coded variants\n * - Maintain accessibility through proper ARIA roles and labels\n *\n * ## Styling Architecture\n *\n * The Tag component uses CSS custom properties (CSS variables) for theming and styling,\n * allowing for easy customization through the `data-tag` attribute. Each variant\n * (alpha, beta, stable, production) applies predefined color schemes defined in SCSS.\n *\n * ## Accessibility Considerations (WCAG 2.1 AA Compliance)\n *\n * - **Semantic Roles**: Uses `role=\"note\"` for static tags or `role=\"status\"` for dynamic content\n * - `role=\"note\"`: Read once by screen readers, suitable for static labels (default)\n * - `role=\"status\"`: Announces updates to screen readers, use for changing status indicators\n * - **Color Independence**: Don't rely solely on color to convey meaning - include text labels\n * - **Text Alternatives**: For icon-only tags, provide `aria-label` for screen reader context\n * - **Contrast Ratios**: All variants meet WCAG AA contrast requirements (4.5:1 for normal text)\n * - **Live Regions**: When using `role=\"status\"`, tag becomes a live region for accessibility\n *\n * ## When to Use Each Role\n *\n * **Use `role=\"note\"` (default) when:**\n * - Displaying static version numbers (e.g., \"v2.1.0\")\n * - Showing fixed environment indicators (e.g., \"Beta Feature\")\n * - Labeling unchanging content categories\n *\n * **Use `role=\"status\"` when:**\n * - Indicating real-time status that may change (e.g., \"Processing\" → \"Complete\")\n * - Displaying live build/deployment states\n * - Showing dynamic feature flags that toggle\n *\n * @param {TagProps} props - Component props\n * @returns {React.ReactElement} A Tag component\n *\n * @example\n * // Basic tag with beta variant (default inline span)\n * <Tag variant=\"beta\">Beta</Tag>\n *\n * @example\n * // Production environment indicator as block element\n * <Tag elm=\"p\" variant=\"production\">Production Environment</Tag>\n *\n * @example\n * // Dynamic status tag with live updates\n * <Tag role=\"status\" variant=\"stable\">\n * {isDeployed ? 'Deployed' : 'Deploying...'}\n * </Tag>\n *\n * @example\n * // Tag with custom styling and accessibility label\n * <Tag\n * variant=\"alpha\"\n * aria-label=\"Alpha version - may contain bugs\"\n * styles={{ fontSize: '0.75rem' }}\n * >\n * Alpha\n * </Tag>\n *\n * @example\n * // ✅ GOOD: Clear text content with variant for visual enhancement\n * <Tag variant=\"stable\">v2.0 Stable</Tag>\n *\n * @example\n * // ✅ GOOD: Dynamic status with proper role\n * <Tag role=\"status\" variant=\"production\">{deploymentStatus}</Tag>\n *\n * @example\n * // ✅ GOOD: Accessible tag with descriptive label\n * <Tag variant=\"beta\" aria-label=\"Beta feature - feedback welcome\">\n * Beta\n * </Tag>\n *\n * @example\n * // ❌ BAD: Relying only on color without text\n * <Tag variant=\"production\" aria-label=\"Production\" />\n *\n * @example\n * // ❌ BAD: Using status role for static content\n * <Tag role=\"status\" variant=\"stable\">v1.0</Tag>\n */\nexport const Tag = ({\n elm = 'span',\n role = 'note',\n variant,\n children,\n styles,\n ...props\n}: TagProps) => {\n // Map variant to data-tag attribute for SCSS styling\n const dataTag = variant ? variant : undefined\n\n return (\n <UI\n as={elm}\n role={role}\n data-tag={dataTag}\n styles={styles}\n {...props}\n >\n {children}\n </UI>\n )\n}\n\nTag.displayName = 'Tag'\nexport default Tag\nexport type { TagProps, TagVariant }\n","import UI from \"#components/ui\";\nimport React, { useCallback } from \"react\";\nimport type { DetailsProps } from \"./details.types\";\n\n/**\n * Details - A progressive disclosure component using native HTML `<details>` element.\n *\n * This component wraps the native `<details>` and `<summary>` elements to provide\n * an accessible, semantic way to show and hide content. It supports accordion behavior\n * through the `name` attribute and includes proper keyboard navigation out of the box.\n *\n * ## Key Features:\n * - **Semantic HTML**: Uses native `<details>` for built-in accessibility\n * - **Keyboard Support**: Space/Enter to toggle, fully accessible by default\n * - **Accordion Mode**: Group multiple details with `name` for exclusive expansion\n * - **Customizable**: Supports icons, custom styles, and event handlers\n *\n * ## Accessibility:\n * - ✅ WCAG 2.1 AA compliant using semantic HTML\n * - ✅ Native keyboard support (Space, Enter)\n * - ✅ Screen reader compatible (announced as \"disclosure\" or \"expandable\")\n * - ✅ Focus indicators automatically applied via CSS\n * - ✅ `aria-expanded` managed automatically by browser\n *\n * @example\n * ```tsx\n * // Basic usage\n * <Details summary=\"Click to expand\">\n * <p>Hidden content here</p>\n * </Details>\n * ```\n *\n * @example\n * ```tsx\n * // With icon and custom styling\n * <Details\n * summary=\"Shipping Information\"\n * icon={<ChevronDownIcon />}\n * classes=\"custom-details\"\n * onToggle={(e) => console.log('Open:', e.currentTarget.open)}\n * >\n * <p>Ships within 2-3 business days</p>\n * </Details>\n * ```\n *\n * @example\n * ```tsx\n * // Accordion mode - only one open at a time\n * <Details name=\"faq\" summary=\"Question 1\">Answer 1</Details>\n * <Details name=\"faq\" summary=\"Question 2\">Answer 2</Details>\n * <Details name=\"faq\" summary=\"Question 3\">Answer 3</Details>\n * ```\n */\nexport const Details = React.forwardRef<HTMLDetailsElement, DetailsProps>(\n (\n {\n summary,\n icon,\n styles,\n classes,\n ariaLabel,\n name,\n open,\n onPointerDown,\n onToggle,\n children,\n ...props\n },\n ref\n ) => {\n // Memoize callbacks to prevent unnecessary re-renders of child components\n const handlePointerDown = useCallback(\n (e: React.PointerEvent<HTMLElement>) => {\n onPointerDown?.(e as React.PointerEvent<HTMLDetailsElement>);\n },\n [onPointerDown]\n );\n\n const handleToggle = useCallback(\n (e: React.SyntheticEvent<HTMLDetailsElement>) => {\n onToggle?.(e);\n },\n [onToggle]\n );\n\n return (\n <UI\n as=\"details\"\n styles={styles}\n classes={classes}\n onToggle={handleToggle}\n ref={ref}\n open={open}\n aria-label={ariaLabel}\n name={name}\n {...props}\n >\n <UI as=\"summary\" onPointerDown={handlePointerDown}>\n {icon}\n {summary}\n </UI>\n <UI as=\"section\">{children}</UI>\n </UI>\n );\n }\n);\n\nDetails.displayName = \"Details\";\n\nexport default Details;\n"]}
|