import { type ComponentPropsWithoutRef } from 'react'; import { type TextBoxSlotRecipeVariant } from '../../styled-system/recipes'; import { type IconButtonProps } from '../IconButton/IconButton.types'; /** * The props for the FileBox component. */ export type FileDropZoneProps = { /** * Whether the file input is invalid or not. * This will change the style of the file box. * * @default false */ invalid?: TextBoxSlotRecipeVariant['invalid']; /** * Whether the file input is disabled or not. * If disabled, users cannot select files. * * @default false */ disabled?: boolean; /** * Allow users to select multiple files. * * @default false */ multiple?: ComponentPropsWithoutRef<'input'>['multiple']; /** * Accept attribute for the file input. * * @default undefined */ accept?: ComponentPropsWithoutRef<'input'>['accept']; /** * The properties for the clear button. * If this prop is not passed, the default values for each property will be applied. * * @property aria-label - The alternative text for the clear button. * * @default "ファイルをクリアする" */ clearButtonProps?: Pick; /** * The error message for the file drop zone. * * @default undefined */ errorMessage?: string; /** * The helper message for the file drop zone. * * @default undefined */ helperMessage?: string; /** * The image url for the illustration. * * @default undefined */ illustrationUrl?: string; /** * The prop to add extra element. * * @default undefined */ extraElement?: React.ReactNode; /** * The selected file names (controlled mode). * If provided, the component is controlled and displays these file names. * If not provided, the component manages its own state. * * **Important:** This prop accepts file names as strings for display purposes only. * These strings should correspond to actual files but are not validated against * the underlying file input state. Ensure consistency between displayed names * and actual selected files in your application logic. * * **Expected format:** Array of non-empty file name strings. * Example: `['document.pdf', 'image.jpg']` * * @default undefined */ value?: string[] | undefined; /** * The initial file names (uncontrolled mode). * Only used when value is not provided. * * **Expected format:** Array of valid, non-empty file name strings. * Example: `['document.pdf', 'image.jpg']` * * **Note:** Invalid values (empty strings, non-strings, null, undefined) * may cause unexpected display behavior. Validate your data before passing it to this prop. * * @default undefined */ defaultValue?: string[] | undefined; /** * The callback function to be called when files are selected through dialog or drag-and-drop. * This is the standard HTML input onChange event. * * @param event - The change event from the file input element * * @default undefined */ onChange?: React.ChangeEventHandler; /** * The callback function to be called when the file is cleared. * * @default undefined */ onClear?: () => void; /** * The callback function to be called when the controlled value becomes empty. * Only called in controlled mode when value transitions from non-empty to empty. * Separate from onClear to distinguish between user actions and programmatic changes. * * @default undefined */ onValueCleared?: () => void; /** * The width of the filebox element. * * @default 280 */ fileBoxWidth?: number; /** * Custom text for the file selection button. * * @default "ファイルを選択" * * @example "Select files" // English */ fileSelectButtonLabel?: string; /** * Custom text for drag and drop instruction area. * Use line breaks (`\n`) to control multi-line display. * * @default "ファイルを\nドラッグアンドドロップ\nまたは" * * @example "Drag files here\nor" // English (single line break) */ instructionText?: string; /** * Custom function to generate file count display text. * Used when multiple files are selected to show count. * * @param count - Number of selected files * * @returns Text to display for file count * * @default (count) => `${count}ファイル` * * @example * // English * (count) => `${count} files` */ fileCountLabel?: (count: number) => string; /** * Custom screen reader announcements for selected files. * Used for accessibility - announced when files are selected. * * @example * // English * { * single: (filename) => `Selected file: ${filename}`, * multiple: (count) => `Selected files: ${count} files` * } */ screenReaderTexts?: { /** * Screen reader text for single file selection. * * @param filename - Name of the selected file * * @returns Announcement text for screen readers * * @default (filename) => `選択済みファイル: ${filename}` * * @example (filename) => `Selected file: ${filename}` // English */ single?: (filename: string) => string; /** * Screen reader text for multiple file selection. * * @param count - Number of selected files * * @returns Announcement text for screen readers * * @default (count) => `選択済みファイル: ${count}個のファイル` * * @example (count) => `Selected files: ${count} files` // English */ multiple?: (count: number) => string; }; } & ComponentPropsWithoutRef<'input'>;