@@ -51,6 +51,10 @@ export interface ComboBoxProps extends Omit<React.HTMLProps<ComboBoxDerivedEleme | |||||
* Input mode of the component. | * Input mode of the component. | ||||
*/ | */ | ||||
inputMode?: TextControl.InputMode, | inputMode?: TextControl.InputMode, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -74,6 +78,7 @@ export const ComboBox = React.forwardRef<ComboBoxDerivedElement, ComboBoxProps>( | |||||
inputMode = 'text' as const, | inputMode = 'text' as const, | ||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}: ComboBoxProps, | }: ComboBoxProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -112,6 +117,7 @@ export const ComboBox = React.forwardRef<ComboBoxDerivedElement, ComboBoxProps>( | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
@@ -245,4 +251,5 @@ ComboBox.defaultProps = { | |||||
variant: 'default' as const, | variant: 'default' as const, | ||||
hiddenLabel: false as const, | hiddenLabel: false as const, | ||||
inputMode: 'text' as const, | inputMode: 'text' as const, | ||||
length: undefined, | |||||
}; | }; |
@@ -4,7 +4,7 @@ import clsx from 'clsx'; | |||||
export type EmailInputDerivedElement = HTMLInputElement; | export type EmailInputDerivedElement = HTMLInputElement; | ||||
export interface EmailInputProps extends Omit<React.HTMLProps<EmailInputDerivedElement>, 'size' | 'type' | 'label' | 'inputMode'> { | |||||
export interface EmailInputProps extends Omit<React.HTMLProps<EmailInputDerivedElement>, 'size' | 'type' | 'label' | 'inputMode' | 'pattern'> { | |||||
/** | /** | ||||
* Short textual description indicating the nature of the component's value. | * Short textual description indicating the nature of the component's value. | ||||
*/ | */ | ||||
@@ -37,6 +37,14 @@ export interface EmailInputProps extends Omit<React.HTMLProps<EmailInputDerivedE | |||||
* Is the label hidden? | * Is the label hidden? | ||||
*/ | */ | ||||
hiddenLabel?: boolean, | hiddenLabel?: boolean, | ||||
/** | |||||
* Allowed domains for emails. | |||||
*/ | |||||
domains?: string[], | |||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -56,6 +64,8 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP | |||||
className, | className, | ||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
domains = [], | |||||
length, | |||||
...etcProps | ...etcProps | ||||
}: EmailInputProps, | }: EmailInputProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -64,6 +74,12 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP | |||||
const defaultId = React.useId(); | const defaultId = React.useId(); | ||||
const id = idProp ?? defaultId; | const id = idProp ?? defaultId; | ||||
const pattern = ( | |||||
Array.isArray(domains) && domains.length > 0 | |||||
? `.+?@(${domains.join('|').replace(/\./g, '\\.')})$` | |||||
: undefined | |||||
); | |||||
return ( | return ( | ||||
<div | <div | ||||
className={clsx( | className={clsx( | ||||
@@ -79,11 +95,13 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
type="email" | type="email" | ||||
data-testid="input" | data-testid="input" | ||||
pattern={pattern} | |||||
className={clsx( | className={clsx( | ||||
'bg-negative rounded-inherit w-full peer block font-inherit', | 'bg-negative rounded-inherit w-full peer block font-inherit', | ||||
'focus:outline-0', | 'focus:outline-0', | ||||
@@ -173,6 +191,7 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP | |||||
)} | )} | ||||
{indicator && ( | {indicator && ( | ||||
<div | <div | ||||
data-testid="indicator" | |||||
className={clsx( | className={clsx( | ||||
'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | 'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | ||||
{ | { | ||||
@@ -207,4 +226,6 @@ EmailInput.defaultProps = { | |||||
block: false, | block: false, | ||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
domains: [], | |||||
length: undefined, | |||||
}; | }; |
@@ -15,20 +15,20 @@ import { | |||||
} from 'vitest'; | } from 'vitest'; | ||||
import matchers from '@testing-library/jest-dom/matchers'; | import matchers from '@testing-library/jest-dom/matchers'; | ||||
import { | import { | ||||
TextInput, | |||||
TextInputDerivedElement, | |||||
PatternTextInput, | |||||
PatternTextInputDerivedElement, | |||||
} from '.'; | } from '.'; | ||||
expect.extend(matchers); | expect.extend(matchers); | ||||
describe('TextInput', () => { | |||||
describe('PatternTextInput', () => { | |||||
afterEach(() => { | afterEach(() => { | ||||
cleanup(); | cleanup(); | ||||
}); | }); | ||||
it('renders a textbox', () => { | it('renders a textbox', () => { | ||||
render( | render( | ||||
<TextInput />, | |||||
<PatternTextInput />, | |||||
); | ); | ||||
const textbox = screen.getByRole('textbox'); | const textbox = screen.getByRole('textbox'); | ||||
expect(textbox).toBeInTheDocument(); | expect(textbox).toBeInTheDocument(); | ||||
@@ -37,7 +37,7 @@ describe('TextInput', () => { | |||||
it('renders a border', () => { | it('renders a border', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
border | border | ||||
/>, | />, | ||||
); | ); | ||||
@@ -47,7 +47,7 @@ describe('TextInput', () => { | |||||
it('renders a label', () => { | it('renders a label', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
label="foo" | label="foo" | ||||
/>, | />, | ||||
); | ); | ||||
@@ -59,7 +59,7 @@ describe('TextInput', () => { | |||||
it('renders a hidden label', () => { | it('renders a hidden label', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
label="foo" | label="foo" | ||||
hiddenLabel | hiddenLabel | ||||
/>, | />, | ||||
@@ -73,7 +73,7 @@ describe('TextInput', () => { | |||||
it('renders a hint', () => { | it('renders a hint', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
hint="foo" | hint="foo" | ||||
/>, | />, | ||||
); | ); | ||||
@@ -83,7 +83,7 @@ describe('TextInput', () => { | |||||
it('renders an indicator', () => { | it('renders an indicator', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
indicator={ | indicator={ | ||||
<div /> | <div /> | ||||
} | } | ||||
@@ -111,7 +111,7 @@ describe('TextInput', () => { | |||||
}) => { | }) => { | ||||
it('renders input styles', () => { | it('renders input styles', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
size={size} | size={size} | ||||
/>, | />, | ||||
); | ); | ||||
@@ -122,7 +122,7 @@ describe('TextInput', () => { | |||||
it('renders label styles with indicator', () => { | it('renders label styles with indicator', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
size={size} | size={size} | ||||
label="foo" | label="foo" | ||||
indicator={<div />} | indicator={<div />} | ||||
@@ -134,7 +134,7 @@ describe('TextInput', () => { | |||||
it('renders hint styles when indicator is present', () => { | it('renders hint styles when indicator is present', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
size={size} | size={size} | ||||
hint="hint" | hint="hint" | ||||
indicator={<div />} | indicator={<div />} | ||||
@@ -147,7 +147,7 @@ describe('TextInput', () => { | |||||
it('renders indicator styles', () => { | it('renders indicator styles', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
size={size} | size={size} | ||||
indicator={ | indicator={ | ||||
<div /> | <div /> | ||||
@@ -162,7 +162,7 @@ describe('TextInput', () => { | |||||
it('renders a block textbox', () => { | it('renders a block textbox', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
block | block | ||||
/>, | />, | ||||
); | ); | ||||
@@ -173,7 +173,7 @@ describe('TextInput', () => { | |||||
it.each(TextControl.AVAILABLE_INPUT_TYPES)('renders a textbox with type %s', (inputType) => { | it.each(TextControl.AVAILABLE_INPUT_TYPES)('renders a textbox with type %s', (inputType) => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
type={inputType} | type={inputType} | ||||
/>, | />, | ||||
); | ); | ||||
@@ -183,7 +183,7 @@ describe('TextInput', () => { | |||||
it('falls back to text input mode when it clashes with the input type', () => { | it('falls back to text input mode when it clashes with the input type', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
type="text" | type="text" | ||||
inputMode="search" | inputMode="search" | ||||
/>, | />, | ||||
@@ -207,7 +207,7 @@ describe('TextInput', () => { | |||||
}) => { | }) => { | ||||
it('renders input styles', () => { | it('renders input styles', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
variant={variant} | variant={variant} | ||||
/>, | />, | ||||
); | ); | ||||
@@ -218,7 +218,7 @@ describe('TextInput', () => { | |||||
it('renders hint styles', () => { | it('renders hint styles', () => { | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
variant={variant} | variant={variant} | ||||
hint="hint" | hint="hint" | ||||
/>, | />, | ||||
@@ -231,12 +231,12 @@ describe('TextInput', () => { | |||||
it('handles change events', async () => { | it('handles change events', async () => { | ||||
const onChange = vi.fn().mockImplementationOnce( | const onChange = vi.fn().mockImplementationOnce( | ||||
(e: React.ChangeEvent<TextInputDerivedElement>) => { | |||||
(e: React.ChangeEvent<PatternTextInputDerivedElement>) => { | |||||
e.preventDefault(); | e.preventDefault(); | ||||
}, | }, | ||||
); | ); | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
onChange={onChange} | onChange={onChange} | ||||
/>, | />, | ||||
); | ); | ||||
@@ -247,12 +247,12 @@ describe('TextInput', () => { | |||||
it('handles input events', async () => { | it('handles input events', async () => { | ||||
const onInput = vi.fn().mockImplementationOnce( | const onInput = vi.fn().mockImplementationOnce( | ||||
(e: React.SyntheticEvent<TextInputDerivedElement>) => { | |||||
(e: React.SyntheticEvent<PatternTextInputDerivedElement>) => { | |||||
e.preventDefault(); | e.preventDefault(); | ||||
}, | }, | ||||
); | ); | ||||
render( | render( | ||||
<TextInput | |||||
<PatternTextInput | |||||
onInput={onInput} | onInput={onInput} | ||||
/>, | />, | ||||
); | ); |
@@ -45,6 +45,10 @@ export interface PatternTextInputProps extends Omit<React.HTMLProps<PatternTextI | |||||
* Input mode of the component. | * Input mode of the component. | ||||
*/ | */ | ||||
inputMode?: TextControl.InputMode, | inputMode?: TextControl.InputMode, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -52,7 +56,10 @@ export interface PatternTextInputProps extends Omit<React.HTMLProps<PatternTextI | |||||
* | * | ||||
* This component supports multiline input and adjusts its layout accordingly. | * This component supports multiline input and adjusts its layout accordingly. | ||||
*/ | */ | ||||
export const PatternTextInput = React.forwardRef<PatternTextInputDerivedElement, PatternTextInputProps>(( | |||||
export const PatternTextInput = React.forwardRef< | |||||
PatternTextInputDerivedElement, | |||||
PatternTextInputProps | |||||
>(( | |||||
{ | { | ||||
label, | label, | ||||
hint, | hint, | ||||
@@ -67,6 +74,7 @@ export const PatternTextInput = React.forwardRef<PatternTextInputDerivedElement, | |||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
inputMode = type, | inputMode = type, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}, | }, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -98,6 +106,7 @@ export const PatternTextInput = React.forwardRef<PatternTextInputDerivedElement, | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
id={id} | id={id} | ||||
@@ -229,4 +238,5 @@ PatternTextInput.defaultProps = { | |||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
inputMode: 'text', | inputMode: 'text', | ||||
length: undefined, | |||||
}; | }; |
@@ -47,6 +47,10 @@ export interface PhoneNumberInputProps extends Omit<React.HTMLProps<PhoneNumberI | |||||
* Country where the phone number should be formatted for. | * Country where the phone number should be formatted for. | ||||
*/ | */ | ||||
country?: Country, | country?: Country, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -73,6 +77,7 @@ export const PhoneNumberInput = React.forwardRef< | |||||
value, | value, | ||||
onChange, | onChange, | ||||
name, | name, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}: PhoneNumberInputProps, | }: PhoneNumberInputProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -140,9 +145,11 @@ export const PhoneNumberInput = React.forwardRef< | |||||
className, | className, | ||||
)} | )} | ||||
style={style} | style={style} | ||||
data-testid="base" | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
value={value} | value={value} | ||||
onChange={onChange} | onChange={onChange} | ||||
ref={ref} | ref={ref} | ||||
@@ -222,6 +229,7 @@ export const PhoneNumberInput = React.forwardRef< | |||||
)} | )} | ||||
{indicator && ( | {indicator && ( | ||||
<div | <div | ||||
data-testid="indicator" | |||||
className={clsx( | className={clsx( | ||||
'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | 'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | ||||
{ | { | ||||
@@ -37,6 +37,10 @@ export interface UrlInputProps extends Omit<React.HTMLProps<UrlInputDerivedEleme | |||||
* Is the label hidden? | * Is the label hidden? | ||||
*/ | */ | ||||
hiddenLabel?: boolean, | hiddenLabel?: boolean, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -54,6 +58,7 @@ export const UrlInput = React.forwardRef<UrlInputDerivedElement, UrlInputProps>( | |||||
hiddenLabel = false, | hiddenLabel = false, | ||||
className, | className, | ||||
style, | style, | ||||
length, | |||||
id: idProp, | id: idProp, | ||||
...etcProps | ...etcProps | ||||
}: UrlInputProps, | }: UrlInputProps, | ||||
@@ -75,9 +80,11 @@ export const UrlInput = React.forwardRef<UrlInputDerivedElement, UrlInputProps>( | |||||
className, | className, | ||||
)} | )} | ||||
style={style} | style={style} | ||||
data-testid="base" | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
@@ -172,6 +179,7 @@ export const UrlInput = React.forwardRef<UrlInputDerivedElement, UrlInputProps>( | |||||
)} | )} | ||||
{indicator && ( | {indicator && ( | ||||
<div | <div | ||||
data-testid="indicator" | |||||
className={clsx( | className={clsx( | ||||
'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | 'text-center flex items-center justify-center peer-disabled:opacity-50 aspect-square absolute bottom-0 right-0 pointer-events-none select-none', | ||||
{ | { | ||||
@@ -205,4 +213,5 @@ UrlInput.defaultProps = { | |||||
block: false, | block: false, | ||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
length: undefined, | |||||
}; | }; |
@@ -37,6 +37,10 @@ export interface MaskedTextInputProps extends Omit<React.HTMLProps<MaskedTextInp | |||||
* Is the label hidden? | * Is the label hidden? | ||||
*/ | */ | ||||
hiddenLabel?: boolean, | hiddenLabel?: boolean, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -58,6 +62,7 @@ export const MaskedTextInput = React.forwardRef< | |||||
className, | className, | ||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}: MaskedTextInputProps, | }: MaskedTextInputProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -82,6 +87,7 @@ export const MaskedTextInput = React.forwardRef< | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
@@ -210,4 +216,5 @@ MaskedTextInput.defaultProps = { | |||||
block: false, | block: false, | ||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
length: undefined, | |||||
}; | }; |
@@ -45,6 +45,10 @@ export interface TextInputProps extends Omit<React.HTMLProps<TextInputDerivedEle | |||||
* Input mode of the component. | * Input mode of the component. | ||||
*/ | */ | ||||
inputMode?: TextControl.InputMode, | inputMode?: TextControl.InputMode, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -67,6 +71,7 @@ export const TextInput = React.forwardRef<TextInputDerivedElement, TextInputProp | |||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
inputMode = type, | inputMode = type, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}, | }, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -98,6 +103,7 @@ export const TextInput = React.forwardRef<TextInputDerivedElement, TextInputProp | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
id={id} | id={id} | ||||
@@ -229,4 +235,5 @@ TextInput.defaultProps = { | |||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
inputMode: 'text', | inputMode: 'text', | ||||
length: undefined, | |||||
}; | }; |
@@ -55,6 +55,9 @@ export interface TagInputProps extends Omit<React.HTMLProps<TagInputDerivedEleme | |||||
* Separators for splitting the input value into multiple tags. | * Separators for splitting the input value into multiple tags. | ||||
*/ | */ | ||||
separator?: TagInputSeparator[], | separator?: TagInputSeparator[], | ||||
/** | |||||
* Should the last tag be editable when removed? | |||||
*/ | |||||
editOnRemove?: boolean, | editOnRemove?: boolean, | ||||
} | } | ||||
@@ -221,6 +224,7 @@ export const TagInput = React.forwardRef<TagInputDerivedElement, TagInputProps>( | |||||
variant === 'alternate' && 'tag-input-alternate', | variant === 'alternate' && 'tag-input-alternate', | ||||
className, | className, | ||||
)} | )} | ||||
data-testid="base" | |||||
onFocusCapture={handleFocusCapture} | onFocusCapture={handleFocusCapture} | ||||
> | > | ||||
<textarea | <textarea | ||||
@@ -37,6 +37,10 @@ export interface NumberSpinnerProps extends Omit<React.HTMLProps<NumberSpinnerDe | |||||
* Is the label hidden? | * Is the label hidden? | ||||
*/ | */ | ||||
hiddenLabel?: boolean, | hiddenLabel?: boolean, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -55,6 +59,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||||
className, | className, | ||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}: NumberSpinnerProps, | }: NumberSpinnerProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -79,6 +84,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
@@ -208,4 +214,5 @@ NumberSpinner.defaultProps = { | |||||
hiddenLabel: false, | hiddenLabel: false, | ||||
size: 'medium', | size: 'medium', | ||||
variant: 'default', | variant: 'default', | ||||
length: undefined, | |||||
}; | }; |
@@ -37,6 +37,10 @@ export interface DateDropdownProps extends Omit<React.HTMLProps<DateDropdownDeri | |||||
* Is the label hidden? | * Is the label hidden? | ||||
*/ | */ | ||||
hiddenLabel?: boolean, | hiddenLabel?: boolean, | ||||
/** | |||||
* Visual length of the input. | |||||
*/ | |||||
length?: number, | |||||
} | } | ||||
/** | /** | ||||
@@ -58,6 +62,7 @@ export const DateDropdown = React.forwardRef< | |||||
className, | className, | ||||
id: idProp, | id: idProp, | ||||
style, | style, | ||||
length, | |||||
...etcProps | ...etcProps | ||||
}: DateDropdownProps, | }: DateDropdownProps, | ||||
forwardedRef, | forwardedRef, | ||||
@@ -82,6 +87,7 @@ export const DateDropdown = React.forwardRef< | |||||
> | > | ||||
<input | <input | ||||
{...etcProps} | {...etcProps} | ||||
size={length} | |||||
ref={forwardedRef} | ref={forwardedRef} | ||||
id={id} | id={id} | ||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
@@ -211,4 +217,5 @@ DateDropdown.defaultProps = { | |||||
block: false, | block: false, | ||||
variant: 'default', | variant: 'default', | ||||
hiddenLabel: false, | hiddenLabel: false, | ||||
length: undefined, | |||||
}; | }; |
@@ -19,6 +19,26 @@ const TemporalPage: NextPage = () => { | |||||
/> | /> | ||||
</Subsection> | </Subsection> | ||||
</Section> | </Section> | ||||
<Section title="EmailInput"> | |||||
<Subsection title="Default"> | |||||
<Formatted.EmailInput | |||||
label="Email" | |||||
name="email" | |||||
border | |||||
/> | |||||
</Subsection> | |||||
<Subsection title="With domains"> | |||||
<Formatted.EmailInput | |||||
label="Email" | |||||
name="email" | |||||
border | |||||
variant="alternate" | |||||
domains={['gmail.com', 'yahoo.com']} | |||||
hint="Only GMail or Yahoo Mail allowed" | |||||
length={50} | |||||
/> | |||||
</Subsection> | |||||
</Section> | |||||
</DefaultLayout> | </DefaultLayout> | ||||
) | ) | ||||
} | } | ||||