Skip to content

Commit 6764acc

Browse files
author
Kubit
committed
Improve actionBottomSheet including tab draggable
1 parent 0fcfaa7 commit 6764acc

File tree

7 files changed

+73
-6
lines changed

7 files changed

+73
-6
lines changed

src/components/actionBottomSheet/__tests__/actionBottomSheet.test.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@ describe('ActionBottomSheet component', () => {
3535
expect(results).toHaveNoViolations();
3636
});
3737

38+
it('Should render ActionBottomSheet component but closed', async () => {
39+
const { container } = renderProvider(
40+
<ActionBottomSheet variant={'DEFAULT'}>Hello</ActionBottomSheet>
41+
);
42+
43+
const popover = screen.queryByText('Hello');
44+
expect(popover).not.toBeInTheDocument();
45+
46+
const results = await axe(container);
47+
expect(container).toHTMLValidate({
48+
rules: {
49+
'no-inline-style': 'off',
50+
},
51+
});
52+
expect(results).toHaveNoViolations();
53+
});
54+
3855
it('When no title is used, an aria-dialog-name should be provided', async () => {
3956
const { container } = renderProvider(
4057
<ActionBottomSheet

src/components/actionBottomSheet/actionBottomSheet.styled.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ export const ActionBottomSheetContentStyled = styled.div<IActionBottomSheetStyle
6464
}
6565
`}
6666
`;
67+
68+
export const DraggableIcon = styled.div<ActionBottomSheetStylesTypes>`
69+
${props => getStyles(props.styles.dragIconContainer)}
70+
`;

src/components/actionBottomSheet/actionBottomSheetControlled.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22

33
import { PopoverControlled as Popover, PopoverComponentType } from '@/components/popover';
44
import { STYLES_NAME } from '@/constants';
5-
import { useDeviceHeight, useId, useMediaDevice, useScrollEffect } from '@/hooks';
5+
import { useDeviceHeight, useId, useMediaDevice, useScrollEffect, useSwipeDown } from '@/hooks';
66
import { useStyles } from '@/hooks/useStyles/useStyles';
77
import { ErrorBoundary, FallbackComponent } from '@/provider/errorBoundary';
88
import { DeviceBreakpointsType, ROLES } from '@/types';
@@ -85,20 +85,39 @@ const ActionBottomSheetControlledComponent = React.forwardRef(
8585
ref: React.ForwardedRef<HTMLDivElement> | undefined | null
8686
): JSX.Element => {
8787
const uniqueTitleId = useId('actionSheet-title');
88-
const titleId = (title?.id ?? title?.content) ? uniqueTitleId : undefined;
88+
const titleId = title?.id ?? title?.content ? uniqueTitleId : undefined;
8989
const styles = useStyles<ActionBottomSheetVariantStylesType>(
9090
STYLES_NAME.ACTION_BOTTOM_SHEET,
9191
props.variant,
9292
props.ctv
9393
);
9494

95+
const innerRef = React.useRef<HTMLDivElement | null>(null);
96+
React.useImperativeHandle(ref, () => {
97+
return innerRef.current as HTMLDivElement;
98+
}, []);
99+
100+
const { setPopoverRef, setDragIconRef } = useSwipeDown(
101+
popover?.animationOptions,
102+
popover?.onCloseInternally
103+
);
104+
105+
const setInnerRef = React.useCallback(node => {
106+
innerRef.current = node;
107+
const dragIcon = innerRef.current?.querySelector('[data-drag-icon]');
108+
if (dragIcon instanceof HTMLElement) {
109+
setDragIconRef(dragIcon);
110+
}
111+
}, []);
112+
95113
return (
96114
<Popover
97115
aria-labelledby={titleId}
98116
aria-modal={true}
99117
clickOverlayClose={!blocked}
100118
component={PopoverComponentType.DIV}
101119
dataTestId={`${props.dataTestId}Popover`}
120+
forwardedRef={setPopoverRef}
102121
hasBackDrop={true}
103122
open={open}
104123
role={ROLES.DIALOG}
@@ -108,7 +127,7 @@ const ActionBottomSheetControlledComponent = React.forwardRef(
108127
>
109128
<ActionBottomSheetControlledStructure
110129
{...props}
111-
ref={ref}
130+
ref={setInnerRef}
112131
title={{ ...title, id: titleId }}
113132
/>
114133
</Popover>

src/components/actionBottomSheet/actionBottomSheetStandAlone.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33
import { ElementOrIcon } from '@/components/elementOrIcon';
44
import { Text } from '@/components/text/text';
55
import { TextComponentType } from '@/components/text/types/component';
6+
import { DeviceBreakpointsType } from '@/types';
67

78
import { Link } from '../link';
89
import {
@@ -14,6 +15,7 @@ import {
1415
ActionBottomSheetIconSyled,
1516
ActionBottomSheetStyled,
1617
ActionBottomSheetTitleSyled,
18+
DraggableIcon,
1719
} from './actionBottomSheet.styled';
1820
import { IActionBottomSheetStandAlone } from './types';
1921

@@ -34,13 +36,22 @@ const ActionBottomSheetStandAloneComponent = (
3436
scrollableRef(actionBottomRef.current);
3537
}, []);
3638

39+
const isMobileOrTablet = [DeviceBreakpointsType.MOBILE, DeviceBreakpointsType.TABLET].includes(
40+
props.device
41+
);
42+
3743
return (
3844
<ActionBottomSheetStyled
3945
ref={actionBottomRef}
4046
$height={props.height}
4147
data-testid={`${props.dataTestId}Container`}
4248
styles={props.styles.container}
4349
>
50+
{props.dragIcon && isMobileOrTablet && (
51+
<DraggableIcon ref={props.dragIconRef} data-drag-icon styles={props.styles}>
52+
<ElementOrIcon {...props.dragIcon} />
53+
</DraggableIcon>
54+
)}
4455
{hasHeader && (
4556
<>
4657
<ActionBottomSheetControlStyled ref={shadowRef} styles={props.styles.controlContainer}>

src/components/actionBottomSheet/stories/argtypes.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ export const argtypes = (variants: IThemeObjectVariants, themeSelected: string):
133133
category: CATEGORY_CONTROL.MODIFIERS,
134134
},
135135
},
136+
dragIcon: {
137+
description: 'Add drag icon to swipe down gesture',
138+
type: { name: 'object' },
139+
control: { type: 'object' },
140+
table: {
141+
type: {
142+
summary: 'IElementOrIcon',
143+
},
144+
category: CATEGORY_CONTROL.CONTENT,
145+
},
146+
},
136147
dataTestId: {
137148
description: 'String used for testing',
138149
control: { type: 'text' },

src/components/actionBottomSheet/types/actionBottomSheet.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface IActionBottomSheetStandAlone {
2929
device: DeviceBreakpointsType;
3030
headerContent?: React.ReactNode;
3131
height?: string;
32+
dragIcon?: IElementOrIcon;
33+
dragIconRef?: (node: HTMLDivElement) => void;
3234
/* to useScrollEffect */
3335
scrollableRef: (node) => void;
3436
shadowRef: (node) => void;
@@ -58,7 +60,7 @@ export interface IActionBottomSheetControlledStructure<
5860
* @extends {IActionBottomSheetControlledStructure<V>}
5961
*/
6062
export interface IActionBottomSheetControlled<V = undefined extends string ? unknown : string>
61-
extends IActionBottomSheetControlledStructure<V> {
63+
extends Omit<IActionBottomSheetControlledStructure<V>, 'dragIconRef'> {
6264
open: boolean;
6365
popover?: ActionBottomPopoverType;
6466
}
@@ -69,5 +71,7 @@ export interface IActionBottomSheetControlled<V = undefined extends string ? unk
6971
* @interface ActionBottomSheetPropsStylesType
7072
* @template V
7173
*/
72-
export type ActionBottomSheetUnControlledType<V = undefined extends string ? unknown : string> =
73-
IActionBottomSheetControlled<V>;
74+
export interface ActionBottomSheetUnControlledType<V = undefined extends string ? unknown : string>
75+
extends Omit<IActionBottomSheetControlled<V>, 'open'> {
76+
open?: boolean;
77+
}

src/components/actionBottomSheet/types/actionBottomSheetTheme.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type ActionBottomSheetVariantStylesType = {
1919
headerContent?: CommonStyleType;
2020
content?: CommonStyleType;
2121
popoverVariant?: string;
22+
dragIconContainer?: CommonStyleType;
2223
};
2324

2425
/**

0 commit comments

Comments
 (0)