Last active
October 18, 2022 19:49
-
-
Save 3cL1p5e7/04bb6d2a6133e7bfa5bf1b8302e8017d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { cn } from '@bem-react/classname'; | |
// Суть в том, что ListItem с дополнительной UI логикой типа disabled пригодится в будущем еще много где | |
// И в будущем ляжет в UIKIT | |
const cls = cn('list-item'); | |
export interface ListItemProps<T extends keyof React.ReactHTML = 'li'> | |
extends Omit<React.HTMLAttributes<T>, 'onClick'> { | |
disabled?: boolean; | |
as?: T; | |
onClick?(id: string, e: React.MouseEvent<T>): void; | |
} | |
export const ListItem = <T extends keyof React.ReactHTML = 'li'>({ | |
as = 'li', | |
children, | |
className, // вложен в React.HTMLAttributes<T> | |
disabled, | |
...props | |
}: ListItemProps<T>) => | |
React.createElement( | |
as, | |
{ className: cls({ disabled }, [className]), disabled, ...props }, | |
children, | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { cn } from '@bem-react/classname'; | |
import { ListItem, ListItemProps } from './ListItem'; | |
const classname = cn('order'); | |
export interface OrderProps extends ListItemProps { | |
order: IOrder; | |
} | |
// спорный нейминг через I, но тут как раз кстати | |
// этот интерфейс должен быть импортирован из папки domain, содержащей все интерфейсы модели данных | |
// | |
// либо это должен быть интерфейс локальной UI репрезентации Order, как его понимает текущий UI компонент | |
// и тогда ему тут самое место, но он необязательно будет соотвествовать интерфейсу Order, полученному с сервера | |
export interface IOrder { | |
id: string; | |
name: string; | |
} | |
export const Order = ({ className, order, disabled, ...props }: OrderProps) => ( | |
<ListItem className={classname({ disabled }, [className])} disabled={disabled} {...props}> | |
{order.name} | |
</ListItem> | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { cn } from '@bem-react/classname'; | |
import { Order, IOrder } from './Order'; | |
const classname = cn('orders-list'); | |
export interface OrderListProps { | |
className?: string; | |
style?: React.CSSProperties; | |
orders: IOrder[]; | |
disabledIds?: string[]; | |
onClick(id: string): void; | |
} | |
export const OrdersList = ({ className = '', style, orders, onClick, disabledIds = [] }: OrderListProps) => { | |
const disabledSet = React.useMemo( | |
() => new Set(disabledIds), // тк сложность метода has() равна O(1) | |
[disabledIds], | |
); | |
return ( | |
<ul className={classname({}, [className])} style={style}> | |
{orders.map((order) => ( | |
<Order | |
key={order.id} | |
className={classname('order', { | |
/* shifted: true, // place for your mods if needed */ | |
})} | |
// моды будут использоваться только в случае, если влияют на верстку списка, а не элемента (как было в условии) | |
// Например: пусть мод shifted указывает на сдвиг по горизонтали в вертикальном списке. Тогда ему тут самое место | |
disabled={disabledSet.has(order.id)} | |
// disabled должно быть свойством компонента, а не стилем сверху (как и highlighted, muted, blured и тд) | |
// тк компонент должен сам реализовать поведение disabled исходя из его внутренней структуры, | |
// которая снаружи, вообще говоря, неизвестна | |
order={order} | |
onClick={onClick} // API компонента должно предоставлять любые хэндлеры с id на манер MaterialUI | |
/> | |
))} | |
</ul> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment