Skip to content

Commit

Permalink
fix(fuselage): Some fuselage types (#637)
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris committed Feb 8, 2022
1 parent 54e7b46 commit 9653c77
Show file tree
Hide file tree
Showing 175 changed files with 1,683 additions and 1,811 deletions.
1 change: 1 addition & 0 deletions packages/eslint-config-alt/typescript/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/indent': 'off',
'@typescript-eslint/no-empty-function': 'error',
'@typescript-eslint/no-extra-parens': 'off',
Expand Down
9 changes: 6 additions & 3 deletions packages/fuselage-hooks/src/useAutoFocus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import { useEffect, useRef, Ref } from 'react';
* @param options - options of the focus request
* @returns the ref which holds the element
* @public
* @deprecated
*/
export const useAutoFocus = (
export const useAutoFocus = <
T extends { focus: (options?: FocusOptions) => void }
>(
isFocused = true,
options?: FocusOptions
): Ref<{ focus: (options?: FocusOptions) => void }> => {
const elementRef = useRef<{ focus: (options?: FocusOptions) => void }>();
): Ref<T> => {
const elementRef = useRef<T>();

const { preventScroll } = options || {};

Expand Down
3 changes: 2 additions & 1 deletion packages/fuselage-ui-kit/src/elements/OverflowElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Options,
Icon,
useCursor,
OptionType,
} from '@rocket.chat/fuselage';
import * as UiKit from '@rocket.chat/ui-kit';
import React, { useRef, useCallback, ReactElement, useMemo } from 'react';
Expand Down Expand Up @@ -49,7 +50,7 @@ const OverflowElement = ({
}, [show]);

const handleSelection = useCallback(
([value]: [unknown, string]) => {
([value]: OptionType) => {
action({ target: { value } });
reset();
hide();
Expand Down
11 changes: 5 additions & 6 deletions packages/fuselage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@
"@babel/plugin-transform-runtime": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@babel/preset-react": "^7.16.0",
"@rocket.chat/eslint-config-alt": "workspace:packages/eslint-config-alt",
"@rocket.chat/fuselage-hooks": "workspace:packages/fuselage-hooks",
"@rocket.chat/fuselage-polyfills": "workspace:packages/fuselage-polyfills",
"@rocket.chat/icons": "workspace:packages/icons",
"@rocket.chat/prettier-config": "workspace:packages/prettier-config",
"@rocket.chat/eslint-config-alt": "workspace:^",
"@rocket.chat/fuselage-hooks": "workspace:^",
"@rocket.chat/fuselage-polyfills": "workspace:^",
"@rocket.chat/icons": "workspace:^",
"@rocket.chat/prettier-config": "workspace:^",
"@storybook/addon-essentials": "~6.4.18",
"@storybook/addon-jest": "~6.4.18",
"@storybook/addon-links": "~6.4.18",
Expand Down Expand Up @@ -110,7 +110,6 @@
"postcss-logical": "^4.0.2",
"postcss-svg": "^3.0.0",
"prettier": "^2.3.2",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-live": "^2.3.0",
Expand Down
42 changes: 14 additions & 28 deletions packages/fuselage/src/components/Accordion/AccordionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import { useToggle, useUniqueId } from '@rocket.chat/fuselage-hooks';
import PropTypes from 'prop-types';
import React, { FC, KeyboardEvent, MouseEvent, ReactNode } from 'react';
import React, { FormEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react';

import { Box } from '../Box';
import { Chevron } from '../Chevron';
import { ToggleSwitch } from '../ToggleSwitch';

export const AccordionItem: FC<{
type AccordionItemProps = {
children?: ReactNode;
className?: string;
defaultExpanded?: boolean;
disabled?: boolean;
expanded?: boolean;
tabIndex?: number;
title: ReactNode;
noncollapsible?: boolean;
onToggle?: (
e: MouseEvent<HTMLElement, MouseEvent> | KeyboardEvent<HTMLElement>
) => void;
onToggleEnabled?: (
e: MouseEvent<HTMLElement, MouseEvent> | KeyboardEvent<HTMLElement>
) => void;
}> = function Item({
onToggle?: (e: MouseEvent | KeyboardEvent) => void;
onToggleEnabled?: (e: FormEvent) => void;
};

export const AccordionItem = function Item({
children,
className,
defaultExpanded,
Expand All @@ -32,12 +30,10 @@ export const AccordionItem: FC<{
onToggle,
onToggleEnabled,
...props
}) {
}: AccordionItemProps) {
const [stateExpanded, toggleStateExpanded] = useToggle(defaultExpanded);
const expanded = propExpanded || stateExpanded;
const toggleExpanded = (
event: MouseEvent<HTMLElement, MouseEvent> | KeyboardEvent<HTMLElement>
) => {
const toggleExpanded = (event: MouseEvent | KeyboardEvent) => {
if (onToggle) {
onToggle.call(event.currentTarget, event);
return;
Expand All @@ -51,15 +47,15 @@ export const AccordionItem: FC<{
const titleId = useUniqueId();
const panelId = useUniqueId();

const handleClick = (e: MouseEvent<HTMLElement, MouseEvent>) => {
const handleClick = (e: MouseEvent<HTMLElement>) => {
if (disabled) {
return;
}
e.currentTarget?.blur();
toggleExpanded(e);
};

const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {
const handleKeyDown = (event: KeyboardEvent) => {
if (disabled || event.currentTarget !== event.target) {
return;
}
Expand All @@ -85,13 +81,13 @@ export const AccordionItem: FC<{
'tabIndex': !disabled ? tabIndex : undefined,
'onClick': handleClick,
'onKeyDown': handleKeyDown,
};
} as const;

const nonCollapsibleProps = {
'aria-disabled': 'true',
'aria-expanded': 'true',
'aria-labelledby': titleId,
};
} as const;

const barProps = noncollapsible ? nonCollapsibleProps : collapsibleProps;

Expand Down Expand Up @@ -135,13 +131,3 @@ export const AccordionItem: FC<{
</Box>
);
};

AccordionItem.propTypes = {
defaultExpanded: PropTypes.bool,
disabled: PropTypes.bool,
expanded: PropTypes.bool,
tabIndex: PropTypes.number,
title: PropTypes.node,
onToggle: PropTypes.func,
onToggleEnabled: PropTypes.func,
};
18 changes: 18 additions & 0 deletions packages/fuselage/src/components/AutoComplete/AutoComplete.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ElementType, FC } from 'react';

type AutoCompleteProps = {
value: unknown[];
filter: string;
setFilter?: (filter: string) => void;
options?: { label: string; value: unknown }[];
renderItem?: ElementType;
renderSelected?: ElementType;
onChange: (value: unknown, action: 'remove' | undefined) => void;
getLabel?: (option: { label: string; value: unknown }) => string;
getValue?: (option: { label: string; value: unknown }) => unknown;
renderEmpty?: ElementType;
placeholder?: string;
error?: boolean;
disabled?: boolean;
};
export const AutoComplete: FC<AutoCompleteProps>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,54 @@ import {
useMutableCallback,
useResizeObserver,
} from '@rocket.chat/fuselage-hooks';
import React, {
useEffect,
useRef,
useMemo,
useState,
ComponentProps,
ElementType,
FC,
} from 'react';
import React, { useEffect, useRef, useMemo, useState } from 'react';

import { Box, PositionAnimated, AnimatedVisibility } from '../Box';
import Chip from '../Chip';
import { Icon } from '../Icon';
import { InputBox } from '../InputBox';
import Margins from '../Margins';
import { useCursor, Options } from '../Options';
import { Option } from '../Options/useCursor';

type OptionValue = string | number;
type OptionType = {
value: OptionValue;
label?: string | number;
};

type AutoCompleteProps = Omit<ComponentProps<typeof Options>, 'options'> & {
value: OptionValue;
filter: string;
setFilter?: (filter: string) => void;
options?: OptionType[];
renderItem?: ElementType;
renderSelected?: ElementType;
onChange: (value: OptionValue, action?: 'remove' | undefined) => void;
getLabel?: (option: OptionType) => string;
getValue?: (option: OptionType) => OptionValue;
renderEmpty?: ElementType;
placeholder?: string;
error?: boolean;
disabled?: boolean;
};

const Addon = (props: ComponentProps<typeof Box>) => (
<Box rcx-autocomplete__addon {...props} />
);
const Addon = (props) => <Box rcx-autocomplete__addon {...props} />;

const SelectedOptions = React.memo((props) => <Chip {...props} />);
export const AutoComplete: FC<AutoCompleteProps> = ({
export function AutoComplete({
value,
filter,
setFilter = () => {},
options = [],
renderItem,
renderSelected: RenderSelected = SelectedOptions,
onChange = () => {},
getLabel = ({ label }) => label,
getLabel = ({ label } = {}) => label,
getValue = ({ value }) => value,
renderEmpty,
placeholder,
error,
disabled,
}) => {
}) {
const { ref: containerRef, borderBoxSize } = useResizeObserver();

const ref = useRef<HTMLElement>(null);
const ref = useRef();

const [selected, setSelected] = useState(() =>
options.find((option) => getValue(option) === value)
);

const index = (selected && options.indexOf(selected)) || 0;

const selectByKeyboard = useMutableCallback(([value]) => {
setSelected(options.find((option) => getValue(option) === value));
onChange(value);
setFilter('');
});

const memoizedOptions = useMemo<[unknown, string, boolean?][]>(
() =>
options.map(
({ label, value }) => [value, label] as [unknown, string, boolean?]
),
const memoizedOptions = useMemo(
() => options.map(({ label, value }) => [value, label]),
[options]
);

const [cursor, handleKeyDown, , reset, [optionsAreVisible, hide, show]] =
useCursor(index, memoizedOptions as Option[], selectByKeyboard);
useCursor(value, memoizedOptions, selectByKeyboard);

const onSelect = useMutableCallback(([value]) => {
setSelected(options.find((option) => getValue(option) === value));
Expand All @@ -102,7 +64,7 @@ export const AutoComplete: FC<AutoCompleteProps> = ({
<Box
rcx-autocomplete
ref={containerRef}
onClick={useMutableCallback(() => ref.current && ref.current.focus())}
onClick={useMutableCallback(() => ref.current.focus())}
flexGrow={1}
className={useMemo(
() => [error && 'invalid', disabled && 'disabled'],
Expand Down Expand Up @@ -171,4 +133,4 @@ export const AutoComplete: FC<AutoCompleteProps> = ({
</PositionAnimated>
</Box>
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ it('renders without crashing', () => {
render(
<AutoComplete
filter=''
value={''}
value={[]}
renderItem={() => null}
onChange={jest.fn()}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,30 @@ export default {
export const Example = () => {
const [options, setOptions] = useState([]);
const [filter, setFilter] = useState('');
const [value, setValue] = useState<string | number>('');

const [value, setValue] = useState<unknown[]>([]);

useEffect(() => {
(async () => {
const result = await Promise.resolve([]);
setOptions(result);
})();
}, [filter]);

const handleValue = (value: unknown, action: 'remove' | undefined): void => {
if (action) {
return;
}
setValue([]);
};

return (
<AutoComplete
value={value}
filter={filter}
setFilter={setFilter}
options={options}
onChange={setValue}
onChange={handleValue}
/>
);
};
Loading

0 comments on commit 9653c77

Please sign in to comment.