@transferwise/components 46.93.0 → 46.93.1
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/build/typeahead/typeaheadInput/TypeaheadInput.js +4 -1
- package/build/typeahead/typeaheadInput/TypeaheadInput.js.map +1 -1
- package/build/typeahead/typeaheadInput/TypeaheadInput.mjs +4 -1
- package/build/typeahead/typeaheadInput/TypeaheadInput.mjs.map +1 -1
- package/build/types/typeahead/typeaheadInput/TypeaheadInput.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/typeahead/Typeahead.story.tsx +46 -0
- package/src/typeahead/typeaheadInput/TypeaheadInput.tsx +4 -1
|
@@ -24,7 +24,10 @@ class TypeaheadInput extends React.Component {
|
|
|
24
24
|
autoFocus
|
|
25
25
|
} = this.props;
|
|
26
26
|
if (autoFocus) {
|
|
27
|
-
|
|
27
|
+
// Autofocus after context code executions (e.g open Modal) is completed
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
this.inputRef.current?.focus();
|
|
30
|
+
});
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
33
|
componentDidUpdate(previousProps) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeaheadInput.js","sources":["../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"sourcesContent":["/* eslint-disable jsx-a11y/no-autofocus */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\n/* eslint-disable jsx-a11y/no-static-element-interactions */\nimport { clsx } from 'clsx';\nimport { Component, createRef, ReactNode } from 'react';\n\nimport { Input } from '../../inputs/Input';\nimport { TypeaheadOption, TypeaheadProps } from '../Typeahead';\n\nconst DEFAULT_INPUT_MIN_WIDTH = 10;\n\nexport type TypeaheadInputProps<T> = {\n typeaheadId: string;\n value: string;\n selected: readonly TypeaheadOption<T>[];\n dropdownOpen?: boolean;\n autoComplete: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onFocus: () => void;\n onPaste: React.ClipboardEventHandler<HTMLInputElement>;\n renderChip: (chip: TypeaheadOption<T>, index: number) => ReactNode;\n ariaActivedescendant?: string;\n} & Pick<TypeaheadProps<T>, 'id' | 'name' | 'autoFocus' | 'multiple' | 'placeholder' | 'maxHeight'>;\n\ntype TypeaheadInputState = {\n inputWidth: number;\n keyboardFocusedOptionIndex: number | null;\n};\n\nexport default class TypeaheadInput<T> extends Component<\n TypeaheadInputProps<T>,\n TypeaheadInputState\n> {\n inputRef = createRef<HTMLInputElement>();\n sizerRef = createRef<HTMLDivElement>();\n\n constructor(props: TypeaheadInputProps<T>) {\n super(props);\n this.state = {\n inputWidth: DEFAULT_INPUT_MIN_WIDTH,\n keyboardFocusedOptionIndex: null,\n };\n }\n\n componentDidMount() {\n const { autoFocus } = this.props;\n if (autoFocus) {\n this.inputRef.current?.focus();\n }\n }\n\n componentDidUpdate(previousProps: TypeaheadInputProps<T>) {\n if (previousProps.value !== this.props.value && this.props.multiple) {\n this.recalculateWidth();\n }\n }\n\n recalculateWidth = () => {\n requestAnimationFrame(() => {\n this.setState({\n inputWidth: Math.max(DEFAULT_INPUT_MIN_WIDTH, this.sizerRef.current?.scrollWidth ?? 0 + 10),\n });\n });\n };\n\n renderInput = () => {\n const {\n typeaheadId,\n autoFocus,\n multiple,\n name,\n dropdownOpen,\n placeholder,\n selected,\n value,\n onChange,\n onKeyDown,\n onFocus,\n onPaste,\n autoComplete,\n ariaActivedescendant, // Declare the ariaActivedescendant variable\n } = this.props;\n const { inputWidth } = this.state;\n\n const hasPlaceholder = !multiple || selected.length === 0;\n return (\n <Input\n ref={this.inputRef}\n className={clsx(multiple && 'typeahead__input')}\n name={name}\n id={`input-${typeaheadId}`}\n aria-activedescendant={\n ariaActivedescendant\n ? `menu-${typeaheadId} ${ariaActivedescendant}`\n : `menu-${typeaheadId}`\n }\n autoFocus={autoFocus}\n placeholder={hasPlaceholder ? placeholder : ''}\n aria-autocomplete=\"list\"\n aria-expanded={dropdownOpen}\n aria-haspopup=\"listbox\"\n aria-controls={dropdownOpen ? `menu-${typeaheadId}` : undefined}\n autoComplete={autoComplete}\n role=\"combobox\"\n value={value}\n style={multiple && selected.length > 0 ? { width: inputWidth } : {}}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onClick={onFocus}\n onFocus={onFocus}\n onPaste={onPaste}\n />\n );\n };\n\n render() {\n const { multiple, selected, value, maxHeight, renderChip } = this.props;\n\n return multiple ? (\n <div\n className=\"form-control typeahead__input-container\"\n style={{ maxHeight }}\n onClick={() => {\n this.inputRef.current?.focus();\n }}\n >\n <div className=\"typeahead__input-wrapper\">\n {selected && selected.map((chip, idx) => renderChip(chip, idx))}\n\n {this.renderInput()}\n <div className=\"typeahead__input-aligner\" />\n </div>\n <div ref={this.sizerRef} className=\"sizer form-control typeahead__input\">\n {value}\n </div>\n </div>\n ) : (\n this.renderInput()\n );\n }\n}\n"],"names":["DEFAULT_INPUT_MIN_WIDTH","TypeaheadInput","Component","inputRef","createRef","sizerRef","constructor","props","state","inputWidth","keyboardFocusedOptionIndex","componentDidMount","autoFocus","current","focus","componentDidUpdate","previousProps","value","multiple","recalculateWidth","requestAnimationFrame","setState","Math","max","scrollWidth","renderInput","typeaheadId","name","dropdownOpen","placeholder","selected","onChange","onKeyDown","onFocus","onPaste","autoComplete","ariaActivedescendant","hasPlaceholder","length","_jsx","Input","ref","className","clsx","id","undefined","role","style","width","onClick","render","maxHeight","renderChip","_jsxs","children","map","chip","idx"],"mappings":";;;;;;;AAAA;AACA;AACA;AAOA,MAAMA,uBAAuB,GAAG,EAAE,CAAA;AAqBb,MAAAC,cAAkB,SAAQC,eAG9C,CAAA;EACCC,QAAQ,gBAAGC,eAAS,EAAoB,CAAA;EACxCC,QAAQ,gBAAGD,eAAS,EAAkB,CAAA;EAEtCE,WAAAA,CAAYC,KAA6B,EAAA;IACvC,KAAK,CAACA,KAAK,CAAC,CAAA;IACZ,IAAI,CAACC,KAAK,GAAG;AACXC,MAAAA,UAAU,EAAET,uBAAuB;AACnCU,MAAAA,0BAA0B,EAAE,IAAA;KAC7B,CAAA;AACH,GAAA;AAEAC,EAAAA,iBAAiBA,GAAA;IACf,MAAM;AAAEC,MAAAA,SAAAA;KAAW,GAAG,IAAI,CAACL,KAAK,CAAA;AAChC,IAAA,IAAIK,SAAS,EAAE;AACb,
|
|
1
|
+
{"version":3,"file":"TypeaheadInput.js","sources":["../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"sourcesContent":["/* eslint-disable jsx-a11y/no-autofocus */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\n/* eslint-disable jsx-a11y/no-static-element-interactions */\nimport { clsx } from 'clsx';\nimport { Component, createRef, ReactNode } from 'react';\n\nimport { Input } from '../../inputs/Input';\nimport { TypeaheadOption, TypeaheadProps } from '../Typeahead';\n\nconst DEFAULT_INPUT_MIN_WIDTH = 10;\n\nexport type TypeaheadInputProps<T> = {\n typeaheadId: string;\n value: string;\n selected: readonly TypeaheadOption<T>[];\n dropdownOpen?: boolean;\n autoComplete: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onFocus: () => void;\n onPaste: React.ClipboardEventHandler<HTMLInputElement>;\n renderChip: (chip: TypeaheadOption<T>, index: number) => ReactNode;\n ariaActivedescendant?: string;\n} & Pick<TypeaheadProps<T>, 'id' | 'name' | 'autoFocus' | 'multiple' | 'placeholder' | 'maxHeight'>;\n\ntype TypeaheadInputState = {\n inputWidth: number;\n keyboardFocusedOptionIndex: number | null;\n};\n\nexport default class TypeaheadInput<T> extends Component<\n TypeaheadInputProps<T>,\n TypeaheadInputState\n> {\n inputRef = createRef<HTMLInputElement>();\n sizerRef = createRef<HTMLDivElement>();\n\n constructor(props: TypeaheadInputProps<T>) {\n super(props);\n this.state = {\n inputWidth: DEFAULT_INPUT_MIN_WIDTH,\n keyboardFocusedOptionIndex: null,\n };\n }\n\n componentDidMount() {\n const { autoFocus } = this.props;\n if (autoFocus) {\n // Autofocus after context code executions (e.g open Modal) is completed\n setTimeout(() => {\n this.inputRef.current?.focus();\n });\n }\n }\n\n componentDidUpdate(previousProps: TypeaheadInputProps<T>) {\n if (previousProps.value !== this.props.value && this.props.multiple) {\n this.recalculateWidth();\n }\n }\n\n recalculateWidth = () => {\n requestAnimationFrame(() => {\n this.setState({\n inputWidth: Math.max(DEFAULT_INPUT_MIN_WIDTH, this.sizerRef.current?.scrollWidth ?? 0 + 10),\n });\n });\n };\n\n renderInput = () => {\n const {\n typeaheadId,\n autoFocus,\n multiple,\n name,\n dropdownOpen,\n placeholder,\n selected,\n value,\n onChange,\n onKeyDown,\n onFocus,\n onPaste,\n autoComplete,\n ariaActivedescendant, // Declare the ariaActivedescendant variable\n } = this.props;\n const { inputWidth } = this.state;\n\n const hasPlaceholder = !multiple || selected.length === 0;\n return (\n <Input\n ref={this.inputRef}\n className={clsx(multiple && 'typeahead__input')}\n name={name}\n id={`input-${typeaheadId}`}\n aria-activedescendant={\n ariaActivedescendant\n ? `menu-${typeaheadId} ${ariaActivedescendant}`\n : `menu-${typeaheadId}`\n }\n autoFocus={autoFocus}\n placeholder={hasPlaceholder ? placeholder : ''}\n aria-autocomplete=\"list\"\n aria-expanded={dropdownOpen}\n aria-haspopup=\"listbox\"\n aria-controls={dropdownOpen ? `menu-${typeaheadId}` : undefined}\n autoComplete={autoComplete}\n role=\"combobox\"\n value={value}\n style={multiple && selected.length > 0 ? { width: inputWidth } : {}}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onClick={onFocus}\n onFocus={onFocus}\n onPaste={onPaste}\n />\n );\n };\n\n render() {\n const { multiple, selected, value, maxHeight, renderChip } = this.props;\n\n return multiple ? (\n <div\n className=\"form-control typeahead__input-container\"\n style={{ maxHeight }}\n onClick={() => {\n this.inputRef.current?.focus();\n }}\n >\n <div className=\"typeahead__input-wrapper\">\n {selected && selected.map((chip, idx) => renderChip(chip, idx))}\n\n {this.renderInput()}\n <div className=\"typeahead__input-aligner\" />\n </div>\n <div ref={this.sizerRef} className=\"sizer form-control typeahead__input\">\n {value}\n </div>\n </div>\n ) : (\n this.renderInput()\n );\n }\n}\n"],"names":["DEFAULT_INPUT_MIN_WIDTH","TypeaheadInput","Component","inputRef","createRef","sizerRef","constructor","props","state","inputWidth","keyboardFocusedOptionIndex","componentDidMount","autoFocus","setTimeout","current","focus","componentDidUpdate","previousProps","value","multiple","recalculateWidth","requestAnimationFrame","setState","Math","max","scrollWidth","renderInput","typeaheadId","name","dropdownOpen","placeholder","selected","onChange","onKeyDown","onFocus","onPaste","autoComplete","ariaActivedescendant","hasPlaceholder","length","_jsx","Input","ref","className","clsx","id","undefined","role","style","width","onClick","render","maxHeight","renderChip","_jsxs","children","map","chip","idx"],"mappings":"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"}
|
|
@@ -22,7 +22,10 @@ class TypeaheadInput extends Component {
|
|
|
22
22
|
autoFocus
|
|
23
23
|
} = this.props;
|
|
24
24
|
if (autoFocus) {
|
|
25
|
-
|
|
25
|
+
// Autofocus after context code executions (e.g open Modal) is completed
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
this.inputRef.current?.focus();
|
|
28
|
+
});
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
componentDidUpdate(previousProps) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeaheadInput.mjs","sources":["../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"sourcesContent":["/* eslint-disable jsx-a11y/no-autofocus */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\n/* eslint-disable jsx-a11y/no-static-element-interactions */\nimport { clsx } from 'clsx';\nimport { Component, createRef, ReactNode } from 'react';\n\nimport { Input } from '../../inputs/Input';\nimport { TypeaheadOption, TypeaheadProps } from '../Typeahead';\n\nconst DEFAULT_INPUT_MIN_WIDTH = 10;\n\nexport type TypeaheadInputProps<T> = {\n typeaheadId: string;\n value: string;\n selected: readonly TypeaheadOption<T>[];\n dropdownOpen?: boolean;\n autoComplete: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onFocus: () => void;\n onPaste: React.ClipboardEventHandler<HTMLInputElement>;\n renderChip: (chip: TypeaheadOption<T>, index: number) => ReactNode;\n ariaActivedescendant?: string;\n} & Pick<TypeaheadProps<T>, 'id' | 'name' | 'autoFocus' | 'multiple' | 'placeholder' | 'maxHeight'>;\n\ntype TypeaheadInputState = {\n inputWidth: number;\n keyboardFocusedOptionIndex: number | null;\n};\n\nexport default class TypeaheadInput<T> extends Component<\n TypeaheadInputProps<T>,\n TypeaheadInputState\n> {\n inputRef = createRef<HTMLInputElement>();\n sizerRef = createRef<HTMLDivElement>();\n\n constructor(props: TypeaheadInputProps<T>) {\n super(props);\n this.state = {\n inputWidth: DEFAULT_INPUT_MIN_WIDTH,\n keyboardFocusedOptionIndex: null,\n };\n }\n\n componentDidMount() {\n const { autoFocus } = this.props;\n if (autoFocus) {\n this.inputRef.current?.focus();\n }\n }\n\n componentDidUpdate(previousProps: TypeaheadInputProps<T>) {\n if (previousProps.value !== this.props.value && this.props.multiple) {\n this.recalculateWidth();\n }\n }\n\n recalculateWidth = () => {\n requestAnimationFrame(() => {\n this.setState({\n inputWidth: Math.max(DEFAULT_INPUT_MIN_WIDTH, this.sizerRef.current?.scrollWidth ?? 0 + 10),\n });\n });\n };\n\n renderInput = () => {\n const {\n typeaheadId,\n autoFocus,\n multiple,\n name,\n dropdownOpen,\n placeholder,\n selected,\n value,\n onChange,\n onKeyDown,\n onFocus,\n onPaste,\n autoComplete,\n ariaActivedescendant, // Declare the ariaActivedescendant variable\n } = this.props;\n const { inputWidth } = this.state;\n\n const hasPlaceholder = !multiple || selected.length === 0;\n return (\n <Input\n ref={this.inputRef}\n className={clsx(multiple && 'typeahead__input')}\n name={name}\n id={`input-${typeaheadId}`}\n aria-activedescendant={\n ariaActivedescendant\n ? `menu-${typeaheadId} ${ariaActivedescendant}`\n : `menu-${typeaheadId}`\n }\n autoFocus={autoFocus}\n placeholder={hasPlaceholder ? placeholder : ''}\n aria-autocomplete=\"list\"\n aria-expanded={dropdownOpen}\n aria-haspopup=\"listbox\"\n aria-controls={dropdownOpen ? `menu-${typeaheadId}` : undefined}\n autoComplete={autoComplete}\n role=\"combobox\"\n value={value}\n style={multiple && selected.length > 0 ? { width: inputWidth } : {}}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onClick={onFocus}\n onFocus={onFocus}\n onPaste={onPaste}\n />\n );\n };\n\n render() {\n const { multiple, selected, value, maxHeight, renderChip } = this.props;\n\n return multiple ? (\n <div\n className=\"form-control typeahead__input-container\"\n style={{ maxHeight }}\n onClick={() => {\n this.inputRef.current?.focus();\n }}\n >\n <div className=\"typeahead__input-wrapper\">\n {selected && selected.map((chip, idx) => renderChip(chip, idx))}\n\n {this.renderInput()}\n <div className=\"typeahead__input-aligner\" />\n </div>\n <div ref={this.sizerRef} className=\"sizer form-control typeahead__input\">\n {value}\n </div>\n </div>\n ) : (\n this.renderInput()\n );\n }\n}\n"],"names":["DEFAULT_INPUT_MIN_WIDTH","TypeaheadInput","Component","inputRef","createRef","sizerRef","constructor","props","state","inputWidth","keyboardFocusedOptionIndex","componentDidMount","autoFocus","current","focus","componentDidUpdate","previousProps","value","multiple","recalculateWidth","requestAnimationFrame","setState","Math","max","scrollWidth","renderInput","typeaheadId","name","dropdownOpen","placeholder","selected","onChange","onKeyDown","onFocus","onPaste","autoComplete","ariaActivedescendant","hasPlaceholder","length","_jsx","Input","ref","className","clsx","id","undefined","role","style","width","onClick","render","maxHeight","renderChip","_jsxs","children","map","chip","idx"],"mappings":";;;;;AAAA;AACA;AACA;AAOA,MAAMA,uBAAuB,GAAG,EAAE,CAAA;AAqBb,MAAAC,cAAkB,SAAQC,SAG9C,CAAA;EACCC,QAAQ,gBAAGC,SAAS,EAAoB,CAAA;EACxCC,QAAQ,gBAAGD,SAAS,EAAkB,CAAA;EAEtCE,WAAAA,CAAYC,KAA6B,EAAA;IACvC,KAAK,CAACA,KAAK,CAAC,CAAA;IACZ,IAAI,CAACC,KAAK,GAAG;AACXC,MAAAA,UAAU,EAAET,uBAAuB;AACnCU,MAAAA,0BAA0B,EAAE,IAAA;KAC7B,CAAA;AACH,GAAA;AAEAC,EAAAA,iBAAiBA,GAAA;IACf,MAAM;AAAEC,MAAAA,SAAAA;KAAW,GAAG,IAAI,CAACL,KAAK,CAAA;AAChC,IAAA,IAAIK,SAAS,EAAE;AACb,
|
|
1
|
+
{"version":3,"file":"TypeaheadInput.mjs","sources":["../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"sourcesContent":["/* eslint-disable jsx-a11y/no-autofocus */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\n/* eslint-disable jsx-a11y/no-static-element-interactions */\nimport { clsx } from 'clsx';\nimport { Component, createRef, ReactNode } from 'react';\n\nimport { Input } from '../../inputs/Input';\nimport { TypeaheadOption, TypeaheadProps } from '../Typeahead';\n\nconst DEFAULT_INPUT_MIN_WIDTH = 10;\n\nexport type TypeaheadInputProps<T> = {\n typeaheadId: string;\n value: string;\n selected: readonly TypeaheadOption<T>[];\n dropdownOpen?: boolean;\n autoComplete: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onFocus: () => void;\n onPaste: React.ClipboardEventHandler<HTMLInputElement>;\n renderChip: (chip: TypeaheadOption<T>, index: number) => ReactNode;\n ariaActivedescendant?: string;\n} & Pick<TypeaheadProps<T>, 'id' | 'name' | 'autoFocus' | 'multiple' | 'placeholder' | 'maxHeight'>;\n\ntype TypeaheadInputState = {\n inputWidth: number;\n keyboardFocusedOptionIndex: number | null;\n};\n\nexport default class TypeaheadInput<T> extends Component<\n TypeaheadInputProps<T>,\n TypeaheadInputState\n> {\n inputRef = createRef<HTMLInputElement>();\n sizerRef = createRef<HTMLDivElement>();\n\n constructor(props: TypeaheadInputProps<T>) {\n super(props);\n this.state = {\n inputWidth: DEFAULT_INPUT_MIN_WIDTH,\n keyboardFocusedOptionIndex: null,\n };\n }\n\n componentDidMount() {\n const { autoFocus } = this.props;\n if (autoFocus) {\n // Autofocus after context code executions (e.g open Modal) is completed\n setTimeout(() => {\n this.inputRef.current?.focus();\n });\n }\n }\n\n componentDidUpdate(previousProps: TypeaheadInputProps<T>) {\n if (previousProps.value !== this.props.value && this.props.multiple) {\n this.recalculateWidth();\n }\n }\n\n recalculateWidth = () => {\n requestAnimationFrame(() => {\n this.setState({\n inputWidth: Math.max(DEFAULT_INPUT_MIN_WIDTH, this.sizerRef.current?.scrollWidth ?? 0 + 10),\n });\n });\n };\n\n renderInput = () => {\n const {\n typeaheadId,\n autoFocus,\n multiple,\n name,\n dropdownOpen,\n placeholder,\n selected,\n value,\n onChange,\n onKeyDown,\n onFocus,\n onPaste,\n autoComplete,\n ariaActivedescendant, // Declare the ariaActivedescendant variable\n } = this.props;\n const { inputWidth } = this.state;\n\n const hasPlaceholder = !multiple || selected.length === 0;\n return (\n <Input\n ref={this.inputRef}\n className={clsx(multiple && 'typeahead__input')}\n name={name}\n id={`input-${typeaheadId}`}\n aria-activedescendant={\n ariaActivedescendant\n ? `menu-${typeaheadId} ${ariaActivedescendant}`\n : `menu-${typeaheadId}`\n }\n autoFocus={autoFocus}\n placeholder={hasPlaceholder ? placeholder : ''}\n aria-autocomplete=\"list\"\n aria-expanded={dropdownOpen}\n aria-haspopup=\"listbox\"\n aria-controls={dropdownOpen ? `menu-${typeaheadId}` : undefined}\n autoComplete={autoComplete}\n role=\"combobox\"\n value={value}\n style={multiple && selected.length > 0 ? { width: inputWidth } : {}}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onClick={onFocus}\n onFocus={onFocus}\n onPaste={onPaste}\n />\n );\n };\n\n render() {\n const { multiple, selected, value, maxHeight, renderChip } = this.props;\n\n return multiple ? (\n <div\n className=\"form-control typeahead__input-container\"\n style={{ maxHeight }}\n onClick={() => {\n this.inputRef.current?.focus();\n }}\n >\n <div className=\"typeahead__input-wrapper\">\n {selected && selected.map((chip, idx) => renderChip(chip, idx))}\n\n {this.renderInput()}\n <div className=\"typeahead__input-aligner\" />\n </div>\n <div ref={this.sizerRef} className=\"sizer form-control typeahead__input\">\n {value}\n </div>\n </div>\n ) : (\n this.renderInput()\n );\n }\n}\n"],"names":["DEFAULT_INPUT_MIN_WIDTH","TypeaheadInput","Component","inputRef","createRef","sizerRef","constructor","props","state","inputWidth","keyboardFocusedOptionIndex","componentDidMount","autoFocus","setTimeout","current","focus","componentDidUpdate","previousProps","value","multiple","recalculateWidth","requestAnimationFrame","setState","Math","max","scrollWidth","renderInput","typeaheadId","name","dropdownOpen","placeholder","selected","onChange","onKeyDown","onFocus","onPaste","autoComplete","ariaActivedescendant","hasPlaceholder","length","_jsx","Input","ref","className","clsx","id","undefined","role","style","width","onClick","render","maxHeight","renderChip","_jsxs","children","map","chip","idx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeaheadInput.d.ts","sourceRoot":"","sources":["../../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI/D,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACrD,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC,CAAC;AAEpG,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CACtD,mBAAmB,CAAC,CAAC,CAAC,EACtB,mBAAmB,CACpB;IACC,QAAQ,8CAAiC;IACzC,QAAQ,4CAA+B;gBAE3B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"TypeaheadInput.d.ts","sourceRoot":"","sources":["../../../../src/typeahead/typeaheadInput/TypeaheadInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI/D,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACrD,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC,CAAC;AAEpG,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CACtD,mBAAmB,CAAC,CAAC,CAAC,EACtB,mBAAmB,CACpB;IACC,QAAQ,8CAAiC;IACzC,QAAQ,4CAA+B;gBAE3B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzC,iBAAiB;IAUjB,kBAAkB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAMxD,gBAAgB,aAMd;IAEF,WAAW,oCAgDT;IAEF,MAAM;CAyBP"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,8 @@ import { Size } from '../common';
|
|
|
7
7
|
import { useState } from 'react';
|
|
8
8
|
import { Input } from '../inputs/Input';
|
|
9
9
|
import { Field } from '../field/Field';
|
|
10
|
+
import Button from '../button';
|
|
11
|
+
import Modal from '../modal';
|
|
10
12
|
|
|
11
13
|
type Story = StoryObj<typeof Typeahead>;
|
|
12
14
|
|
|
@@ -231,3 +233,47 @@ export const Search: Story = {
|
|
|
231
233
|
);
|
|
232
234
|
},
|
|
233
235
|
};
|
|
236
|
+
|
|
237
|
+
export const AutoFocusInModal: Story = {
|
|
238
|
+
render: function Render() {
|
|
239
|
+
const [open, setOpen] = useState<boolean>(true);
|
|
240
|
+
return (
|
|
241
|
+
<>
|
|
242
|
+
<Button v2 onClick={() => setOpen(true)}>
|
|
243
|
+
Open Modal
|
|
244
|
+
</Button>
|
|
245
|
+
<Modal
|
|
246
|
+
title="Global Search"
|
|
247
|
+
body={
|
|
248
|
+
<Typeahead
|
|
249
|
+
id="typeahead"
|
|
250
|
+
name="search-input"
|
|
251
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
252
|
+
autoFocus
|
|
253
|
+
size="md"
|
|
254
|
+
showSuggestions
|
|
255
|
+
showNewEntry={false}
|
|
256
|
+
addon={<SearchIcon size={24} />}
|
|
257
|
+
options={[
|
|
258
|
+
{ label: 'Option 1' },
|
|
259
|
+
{ label: 'Option 2' },
|
|
260
|
+
{ label: 'Option 3' },
|
|
261
|
+
{ label: 'Option 4' },
|
|
262
|
+
]}
|
|
263
|
+
inputAutoComplete="off"
|
|
264
|
+
onSearch={(search) => {
|
|
265
|
+
console.log(search);
|
|
266
|
+
}}
|
|
267
|
+
onChange={(option) => {}}
|
|
268
|
+
onBlur={() => {}}
|
|
269
|
+
/>
|
|
270
|
+
}
|
|
271
|
+
open={open}
|
|
272
|
+
onClose={() => {
|
|
273
|
+
setOpen(false);
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
</>
|
|
277
|
+
);
|
|
278
|
+
},
|
|
279
|
+
};
|
|
@@ -46,7 +46,10 @@ export default class TypeaheadInput<T> extends Component<
|
|
|
46
46
|
componentDidMount() {
|
|
47
47
|
const { autoFocus } = this.props;
|
|
48
48
|
if (autoFocus) {
|
|
49
|
-
|
|
49
|
+
// Autofocus after context code executions (e.g open Modal) is completed
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
this.inputRef.current?.focus();
|
|
52
|
+
});
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
|