tidy up the ref to ref with a forwardRef and initialComponent signature
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/21833/head
parent
8087b521e6
commit
bc83984a62
|
@ -90,11 +90,12 @@ export default class CommunityProvider extends AutocompleteProvider {
|
||||||
type: "community",
|
type: "community",
|
||||||
href: makeGroupPermalink(groupId),
|
href: makeGroupPermalink(groupId),
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion initialComponent={
|
<PillCompletion title={name} description={groupId}>
|
||||||
<BaseAvatar name={name || groupId}
|
<BaseAvatar name={name || groupId}
|
||||||
width={24} height={24}
|
width={24}
|
||||||
|
height={24}
|
||||||
url={avatarUrl ? cli.mxcUrlToHttp(avatarUrl, 24, 24) : null} />
|
url={avatarUrl ? cli.mxcUrlToHttp(avatarUrl, 24, 24) : null} />
|
||||||
} title={name} description={groupId} />
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {createRef} from 'react';
|
import React, {forwardRef} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
/* These were earlier stateless functional components but had to be converted
|
/* These were earlier stateless functional components but had to be converted
|
||||||
|
@ -30,62 +30,37 @@ interface ITextualCompletionProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Completion<T> extends React.PureComponent<T> {
|
export const TextualCompletion = forwardRef<ITextualCompletionProps, any>((props, ref) => {
|
||||||
nodeRef = createRef<HTMLDivElement>();
|
const {title, subtitle, description, className, ...restProps} = props;
|
||||||
|
return (
|
||||||
|
<div {...restProps}
|
||||||
|
className={classNames('mx_Autocomplete_Completion_block', className)}
|
||||||
|
role="option"
|
||||||
|
ref={ref}
|
||||||
|
>
|
||||||
|
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||||
|
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
||||||
|
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
interface IPillCompletionProps extends ITextualCompletionProps {
|
||||||
|
children?: React.ReactNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TextualCompletion extends Completion<ITextualCompletionProps> {
|
export const PillCompletion = forwardRef<IPillCompletionProps, any>((props, ref) => {
|
||||||
render() {
|
const {title, subtitle, description, className, children, ...restProps} = props;
|
||||||
const {
|
return (
|
||||||
title,
|
<div {...restProps}
|
||||||
subtitle,
|
className={classNames('mx_Autocomplete_Completion_pill', className)}
|
||||||
description,
|
role="option"
|
||||||
className,
|
ref={ref}
|
||||||
...restProps
|
>
|
||||||
} = this.props;
|
{ children }
|
||||||
return (
|
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||||
<div {...restProps}
|
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
||||||
className={classNames('mx_Autocomplete_Completion_block', className)}
|
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
||||||
role="option"
|
</div>
|
||||||
ref={this.nodeRef}
|
);
|
||||||
>
|
});
|
||||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
|
||||||
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
|
||||||
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IPillCompletionProps {
|
|
||||||
title?: string;
|
|
||||||
subtitle?: string;
|
|
||||||
description?: string;
|
|
||||||
initialComponent?: React.ReactNode,
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PillCompletion extends Completion<IPillCompletionProps> {
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
title,
|
|
||||||
subtitle,
|
|
||||||
description,
|
|
||||||
initialComponent,
|
|
||||||
className,
|
|
||||||
...restProps
|
|
||||||
} = this.props;
|
|
||||||
return (
|
|
||||||
<div {...restProps}
|
|
||||||
className={classNames('mx_Autocomplete_Completion_pill', className)}
|
|
||||||
role="option"
|
|
||||||
ref={this.nodeRef}
|
|
||||||
>
|
|
||||||
{ initialComponent }
|
|
||||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
|
||||||
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
|
||||||
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -121,9 +121,9 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
return {
|
return {
|
||||||
completion: unicode,
|
completion: unicode,
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion title={shortname} aria-label={unicode} initialComponent={
|
<PillCompletion title={shortname} aria-label={unicode}>
|
||||||
<span style={{maxWidth: '1em'}}>{ unicode }</span>
|
<span style={{maxWidth: '1em'}}>{ unicode }</span>
|
||||||
} />
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,9 @@ export default class NotifProvider extends AutocompleteProvider {
|
||||||
type: "at-room",
|
type: "at-room",
|
||||||
suffix: ' ',
|
suffix: ' ',
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion initialComponent={<RoomAvatar width={24} height={24} room={this.room} />} title="@room" description={_t("Notify the whole room")} />
|
<PillCompletion title="@room" description={_t("Notify the whole room")}>
|
||||||
|
<RoomAvatar width={24} height={24} room={this.room} />
|
||||||
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -103,7 +103,9 @@ export default class RoomProvider extends AutocompleteProvider {
|
||||||
suffix: ' ',
|
suffix: ' ',
|
||||||
href: makeRoomPermalink(room.displayedAlias),
|
href: makeRoomPermalink(room.displayedAlias),
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion initialComponent={<RoomAvatar width={24} height={24} room={room.room} />} title={room.room.name} description={room.displayedAlias} />
|
<PillCompletion title={room.room.name} description={room.displayedAlias}>
|
||||||
|
<RoomAvatar width={24} height={24} room={room.room} />
|
||||||
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,10 +125,9 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
suffix: (selection.beginning && range.start === 0) ? ': ' : ' ',
|
suffix: (selection.beginning && range.start === 0) ? ': ' : ' ',
|
||||||
href: makeUserPermalink(user.userId),
|
href: makeUserPermalink(user.userId),
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion
|
<PillCompletion title={displayName} description={user.userId}>
|
||||||
initialComponent={<MemberAvatar member={user} width={24} height={24} />}
|
<MemberAvatar member={user} width={24} height={24} />
|
||||||
title={displayName}
|
</PillCompletion>
|
||||||
description={user.userId} />
|
|
||||||
),
|
),
|
||||||
range,
|
range,
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,6 @@ import {Room} from 'matrix-js-sdk/src/models/room';
|
||||||
|
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import Autocompleter from '../../../autocomplete/Autocompleter';
|
import Autocompleter from '../../../autocomplete/Autocompleter';
|
||||||
import { Completion } from '../../../autocomplete/Components';
|
|
||||||
|
|
||||||
const COMPOSER_SELECTED = 0;
|
const COMPOSER_SELECTED = 0;
|
||||||
|
|
||||||
|
@ -254,10 +253,10 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
||||||
componentDidUpdate(prevProps: IProps) {
|
componentDidUpdate(prevProps: IProps) {
|
||||||
this.applyNewProps(prevProps.query, prevProps.room);
|
this.applyNewProps(prevProps.query, prevProps.room);
|
||||||
// this is the selected completion, so scroll it into view if needed
|
// this is the selected completion, so scroll it into view if needed
|
||||||
const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`] as Completion<any>;
|
const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`] as HTMLElement;
|
||||||
|
|
||||||
if (selectedCompletion && selectedCompletion.nodeRef.current) {
|
if (selectedCompletion) {
|
||||||
selectedCompletion.nodeRef.current.scrollIntoView({
|
selectedCompletion.scrollIntoView({
|
||||||
behavior: "auto",
|
behavior: "auto",
|
||||||
block: "nearest",
|
block: "nearest",
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue