mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-06 00:42:43 +08:00
[ui][text input] add description prop
This commit is contained in:
@ -12,6 +12,9 @@ export default {
|
||||
autoComplete: {
|
||||
control: 'text',
|
||||
},
|
||||
description: {
|
||||
control: 'text',
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
@ -183,6 +186,25 @@ export function Error() {
|
||||
);
|
||||
}
|
||||
|
||||
export function Description() {
|
||||
const [value, setValue] = useState('1234567');
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
description="Select a password that is at least 6 characters"
|
||||
errorMessage={
|
||||
value.length < 6 ? 'Password must be at least 6 characters' : undefined
|
||||
}
|
||||
label="Password"
|
||||
startAddOn={KeyIcon}
|
||||
startAddOnType="icon"
|
||||
type="password"
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function AddOns() {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
|
@ -62,6 +62,7 @@ type EndAddOnProps =
|
||||
|
||||
type BaseProps = Readonly<{
|
||||
defaultValue?: string;
|
||||
description?: React.ReactNode;
|
||||
endIcon?: React.ComponentType<React.ComponentProps<'svg'>>;
|
||||
errorMessage?: React.ReactNode;
|
||||
id?: string;
|
||||
@ -99,6 +100,7 @@ const stateClasses: Record<
|
||||
function TextInput(
|
||||
{
|
||||
defaultValue,
|
||||
description,
|
||||
disabled,
|
||||
endAddOn,
|
||||
endAddOnType,
|
||||
@ -119,7 +121,7 @@ function TextInput(
|
||||
const hasError = errorMessage != null;
|
||||
const generatedId = useId();
|
||||
const id = idParam ?? generatedId;
|
||||
const errorId = useId();
|
||||
const messageId = useId();
|
||||
const state: State = hasError ? 'error' : 'normal';
|
||||
const { input: inputClass, container: containerClass } = stateClasses[state];
|
||||
|
||||
@ -175,7 +177,9 @@ function TextInput(
|
||||
})()}
|
||||
<input
|
||||
ref={ref}
|
||||
aria-describedby={hasError ? errorId : undefined}
|
||||
aria-describedby={
|
||||
hasError || description != null ? messageId : undefined
|
||||
}
|
||||
aria-invalid={hasError ? true : undefined}
|
||||
className={clsx(
|
||||
'w-0 flex-1 border-none text-sm focus:outline-none focus:ring-0 disabled:cursor-not-allowed disabled:bg-transparent disabled:text-slate-500',
|
||||
@ -224,9 +228,14 @@ function TextInput(
|
||||
}
|
||||
})()}
|
||||
</div>
|
||||
{errorMessage && (
|
||||
<p className="text-danger-600 mt-2 text-sm" id={errorId}>
|
||||
{errorMessage}
|
||||
{(errorMessage ?? description) && (
|
||||
<p
|
||||
className={clsx(
|
||||
'mt-2 text-sm',
|
||||
errorMessage ? 'text-danger-600' : 'text-slate-500',
|
||||
)}
|
||||
id={messageId}>
|
||||
{errorMessage ?? description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user