Skip to content

Commit

Permalink
Merge branch 'components-shared-ts-migration-parent' of github.com:ji…
Browse files Browse the repository at this point in the history
…m-deriv/deriv-app into shayan/74991/checkbox-component-ts-migration
  • Loading branch information
iman committed Oct 3, 2022
2 parents 2e7e8e0 + c47c0c4 commit de657e6
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { usePrevious } from '../../hooks';
import Icon from '../icon';
import { TAccordionProps } from '../types';

const Accordion = ({ className, icon_close, icon_open, list }) => {
const [open_idx, setOpenIdx] = React.useState(null);
const Accordion = ({ className, icon_close, icon_open, list }: TAccordionProps) => {
const [open_idx, setOpenIdx] = React.useState<number | null>(null);

const prev_list = usePrevious(list);

Expand All @@ -14,7 +14,7 @@ const Accordion = ({ className, icon_close, icon_open, list }) => {
}, [list, prev_list]);

// close if clicking the accordion that's open, otherwise open the new one
const onClick = index => setOpenIdx(index === open_idx ? null : index);
const onClick = (index: number) => setOpenIdx(index === open_idx ? null : index);

return (
<div className={classNames('dc-accordion__wrapper', className)}>
Expand Down Expand Up @@ -47,11 +47,4 @@ const Accordion = ({ className, icon_close, icon_open, list }) => {
);
};

Accordion.propTypes = {
className: PropTypes.string,
icon_close: PropTypes.string,
icon_open: PropTypes.string,
list: PropTypes.arrayOf(PropTypes.object),
};

export default Accordion;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Accordion from './accordion.jsx';
import Accordion from './accordion';
import './accordion.scss';

export default Accordion;
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { Highlight } from './button-highlight.jsx';
import { Highlight } from './button-highlight';

type THighlightWrapperProps = Omit<React.HTMLProps<HTMLDivElement>, 'children'> & {
children: React.ReactElement | React.ReactElement[];
has_rounded_button?: boolean;
highlight_color?: string;
};

const class_selector = 'dc-button-menu__button--active';

const HighlightWrapper = ({ children, className, has_rounded_button, ...other_props }) => {
const HighlightWrapper = ({ children, className, has_rounded_button, ...other_props }: THighlightWrapperProps) => {
const [left, setLeft] = React.useState(0);

const wrapper_ref = React.useRef();
const wrapper_ref = React.useRef<HTMLDivElement>(null);

React.useEffect(() => {
if (wrapper_ref.current) {
const active_button_el = [...wrapper_ref.current.getElementsByClassName(class_selector)][0];
const active_button_el = wrapper_ref?.current
?.getElementsByClassName(class_selector)
?.item(0) as HTMLButtonElement;
updateHighlightPosition(active_button_el);
}
return () => resetHighlight();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

React.useEffect(() => {
const active_button_el = [...wrapper_ref.current?.getElementsByClassName(class_selector)][0];
const active_button_el = wrapper_ref?.current
?.getElementsByClassName(class_selector)
?.item(0) as HTMLButtonElement;
if (active_button_el) updateHighlightPosition(active_button_el);
else if (left !== 0) resetHighlight(); // clear highlight when active element doesn't exist
});

const onClick = (e, buttonClick) => {
const onClick = (e: Event, buttonClick: () => void) => {
if (!e.target) return;
updateHighlightPosition(e.target.closest('button'));
if (typeof buttonClick === 'function') {
buttonClick();
}
updateHighlightPosition((e.target as HTMLButtonElement).closest('button'));
buttonClick?.();
};

const resetHighlight = () => setLeft(0);

const updateHighlightPosition = el => {
const updateHighlightPosition = (el: HTMLButtonElement | null) => {
if (!el) return;
const { offsetLeft } = el;
if (left !== offsetLeft) setLeft(offsetLeft);
Expand All @@ -45,29 +52,23 @@ const HighlightWrapper = ({ children, className, has_rounded_button, ...other_pr
className: classnames('dc-button-menu__wrapper', className),
...other_props,
};
const button_width = (100 / children.length).toFixed(2);
const button_width = (100 / ((Array.isArray(children) && children?.length) || 1)).toFixed(2);

return (
<div ref={wrapper_ref} {...props}>
{React.Children.map(children, child =>
React.cloneElement(child, {
onClick: e => onClick(e, child.props.onClick),
onClick: (e: Event) => onClick(e, child.props.onClick),
})
)}
<Highlight
has_rounded_button={has_rounded_button}
highlight_color={other_props?.highlight_color}
has_rounded_button={has_rounded_button || false}
highlight_color={other_props.highlight_color}
left={left}
width={`${button_width}%`}
/>
</div>
);
};

HighlightWrapper.propTypes = {
children: PropTypes.array,
className: PropTypes.string,
has_rounded_button: PropTypes.bool,
};

export default React.memo(HighlightWrapper);
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import PropTypes from 'prop-types';
import React from 'react';

const Highlight = ({ has_rounded_button, highlight_color = 'var(--button-toggle-secondary)', left, width }) => {
type THighlightProps = {
has_rounded_button: boolean;
highlight_color?: string;
left: number;
width: number | string;
};

const Highlight = ({
has_rounded_button,
highlight_color = 'var(--button-toggle-secondary)',
left,
width,
}: THighlightProps) => {
const border_radius_size = '4px';
const highlight_style = {
backgroundColor: highlight_color,
left: 0,
transform: `translate3d(${left}px, 0, 0)`,
width,
borderRadius: '0',
};

if (has_rounded_button) {
Expand All @@ -24,11 +36,4 @@ const Highlight = ({ has_rounded_button, highlight_color = 'var(--button-toggle-
return <span style={highlight_style} className='dc-button-menu--highlight' />;
};

Highlight.propTypes = {
has_rounded_button: PropTypes.bool,
highlight_color: PropTypes.string,
left: PropTypes.number,
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
};

export { Highlight };
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import HighlightWrapper from './button-highlight-wrapper.jsx';
import HighlightWrapper from './button-highlight-wrapper';
import Counter from '../counter/counter';
import Button from '../button/button';

const ButtonToggle = ({ buttons_arr, className, has_rounded_button, id, is_animated, name, onChange, value }) => {
const changeValue = selected_value => {
type TButtonToggleProps = {
buttons_arr: Array<{ text: string; value: string; count?: number }>;
className?: string;
id?: string;
is_animated?: boolean;
name: string;
onChange: (new_values: {
target: {
value: string;
name: string;
};
}) => void;
has_rounded_button?: boolean;
value: number | string;
};

const ButtonToggle = ({
buttons_arr,
className,
has_rounded_button = false,
id,
is_animated = false,
name,
onChange,
value,
}: TButtonToggleProps) => {
const changeValue = (selected_value: string) => {
if (value === selected_value) return;
onChange({ target: { value: selected_value, name } });
};
Expand All @@ -25,7 +49,7 @@ const ButtonToggle = ({ buttons_arr, className, has_rounded_button, id, is_anima
className={menuClassNames}
is_button_toggle
>
{`${val.text.charAt(0).toUpperCase()}${val.text.slice(1)}`}
{`${val.text?.toString().charAt(0).toUpperCase()}${val.text?.toString().slice(1)}`}
{!!val.count && <Counter className='dc-button-menu__counter' count={val.count} />}
</Button>
);
Expand All @@ -45,15 +69,4 @@ const ButtonToggle = ({ buttons_arr, className, has_rounded_button, id, is_anima
);
};

ButtonToggle.propTypes = {
buttons_arr: PropTypes.array,
className: PropTypes.string,
id: PropTypes.string,
is_animated: PropTypes.bool,
name: PropTypes.string,
onChange: PropTypes.func,
has_rounded_button: PropTypes.bool,
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
};

export default ButtonToggle;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ButtonToggle from './button-toggle.jsx';
import ButtonToggle from './button-toggle';
import './button-toggle.scss';

export default ButtonToggle;
2 changes: 1 addition & 1 deletion packages/components/src/components/money/money.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Money = ({

// if it's formatted already then don't make any changes unless we should remove extra -/+ signs
const value = has_sign || should_format ? Math.abs(Number(amount)) : amount;
const final_amount = should_format ? formatMoney(currency, value, true) : value;
const final_amount = should_format ? formatMoney(currency, value, true, 0, 0) : value;

return (
<React.Fragment>
Expand Down
11 changes: 11 additions & 0 deletions packages/components/src/components/types/accordion.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type TAccordionItem = Array<{
header: string;
content: React.ReactNode;
}>;

export type TAccordionProps = {
className?: string;
icon_close?: string;
icon_open?: string;
list: TAccordionItem;
};
3 changes: 2 additions & 1 deletion packages/components/src/components/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TIconsManifest, TIconProps } from './icons.types';
import { TAccordionProps, TAccordionItem } from './accordion.types';

export type { TIconsManifest, TIconProps };
export type { TIconsManifest, TIconProps, TAccordionProps, TAccordionItem };

0 comments on commit de657e6

Please sign in to comment.