Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / pass / components / Form / Field / Layout / FieldBox.tsx
blob18e3a85fac8ae1fa1fb7bbc74377c2cb959e2cba
1 /* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
2 import {
3     Children,
4     type ForwardRefRenderFunction,
5     type MouseEventHandler,
6     type ReactElement,
7     type ReactNode,
8     cloneElement,
9     forwardRef,
10     isValidElement,
11 } from 'react';
13 import { Icon, type IconName } from '@proton/components';
14 import type { MaybeArray } from '@proton/pass/types';
15 import clsx from '@proton/utils/clsx';
17 import './FieldBox.scss';
19 export type FieldBoxProps = {
20     actions?: MaybeArray<ReactElement>;
21     actionsContainerClassName?: string;
22     children?: ReactNode | undefined;
23     className?: string;
24     icon?: IconName | ReactElement;
25     unstyled?: boolean;
26     onClick?: MouseEventHandler;
29 const stopOnClickPropagation = (nodes: MaybeArray<ReactElement>): MaybeArray<ReactElement> =>
30     Children.map(nodes, (node: ReactElement, index) => {
31         const props = node.props as any;
33         return isValidElement(node)
34             ? cloneElement<any>(node, {
35                   key: node.key || index,
36                   ...(props?.onClick
37                       ? {
38                             onClick: (e: MouseEvent) => {
39                                 e.stopPropagation();
40                                 props?.onClick?.(e);
41                             },
42                         }
43                       : {}),
44                   children: props?.children ? stopOnClickPropagation(props?.children) : undefined,
45               })
46             : node;
47     });
49 const FieldBoxRender: ForwardRefRenderFunction<HTMLDivElement, FieldBoxProps> = (props, ref) => {
50     const { className, actions, actionsContainerClassName, children, icon } = props;
51     const isCoreIcon = typeof icon == 'string';
52     const iconEl = isCoreIcon ? <Icon name={icon} size={4} /> : icon;
54     return (
55         <div
56             className={clsx('pass-field-box flex flex-nowrap items-start', !props.unstyled && 'px-4 py-3', className)}
57             ref={ref}
58             onClick={props.onClick}
59         >
60             {icon && (
61                 <span
62                     className={clsx('flex justify-center items-center shrink-0 pr-4', isCoreIcon && 'mt-2')}
63                     style={{ color: 'var(--fieldset-cluster-icon-color)' }}
64                 >
65                     {iconEl}
66                 </span>
67             )}
69             <div className="w-full">{children}</div>
71             {actions && (
72                 <span className={clsx('shrink-0 ml-3', actionsContainerClassName)}>
73                     {stopOnClickPropagation(actions)}
74                 </span>
75             )}
76         </div>
77     );
80 export const FieldBox = forwardRef(FieldBoxRender);