Skip to content

Commit 62cafae

Browse files
committed
DropdownMenu: add props interfaces, update to named export --no-verify
1 parent f017cad commit 62cafae

File tree

3 files changed

+44
-46
lines changed

3 files changed

+44
-46
lines changed

client/components/Dropdown/DropdownMenu.tsx

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1-
import PropTypes from 'prop-types';
21
import React, { forwardRef, useCallback, useRef, useState } from 'react';
32
import styled from 'styled-components';
43
import { remSize, prop } from '../../theme';
54
import { useModalClose } from '../../common/useModalClose';
65
import DownArrowIcon from '../../images/down-filled-triangle.svg';
76

8-
// TODO: enable arrow keys to navigate options from list
9-
const DropdownWrapper = styled.ul`
7+
enum DropdownMenuAlignment {
8+
RIGHT = 'right',
9+
LEFT = 'left'
10+
}
11+
12+
interface StyledDropdownMenuProps {
13+
align: DropdownMenuAlignment;
14+
}
15+
16+
const DropdownWrapper = styled.ul<StyledDropdownMenuProps>`
1017
background-color: ${prop('Modal.background')};
1118
border: 1px solid ${prop('Modal.border')};
1219
box-shadow: 0 0 18px 0 ${prop('shadowColor')};
1320
color: ${prop('primaryTextColor')};
1421
1522
position: absolute;
16-
right: ${(props) => (props.right ? 0 : 'initial')};
17-
left: ${(props) => (props.left ? 0 : 'initial')};
23+
right: ${(props) =>
24+
props.align === DropdownMenuAlignment.RIGHT ? 0 : 'initial'};
25+
left: ${(props) =>
26+
props.align === DropdownMenuAlignment.LEFT ? 0 : 'initial'};
1827
19-
${(props) => props.align === 'right' && 'right: 0;'}
20-
${(props) => props.align === 'left' && 'left: 0;'}
28+
${(props) => props.align === DropdownMenuAlignment.RIGHT && 'right: 0;'}
29+
${(props) => props.align === DropdownMenuAlignment.LEFT && 'left: 0;'}
2130
2231
2332
text-align: left;
@@ -72,15 +81,34 @@ const DropdownWrapper = styled.ul`
7281
}
7382
`;
7483

75-
const DropdownMenu = forwardRef(
84+
export interface DropdownMenuProps extends StyledDropdownMenuProps {
85+
/**
86+
* Provide <MenuItem> elements as children to control the contents of the menu.
87+
*/
88+
children: React.ReactNode;
89+
/**
90+
* Can optionally override the contents of the button which opens the menu.
91+
* Defaults to <DownArrowIcon>
92+
*/
93+
anchor?: React.ReactNode;
94+
'aria-label': string;
95+
className?: string;
96+
classes?: {
97+
button?: string;
98+
list?: string;
99+
};
100+
maxHeight?: string;
101+
}
102+
103+
export const DropdownMenu = forwardRef<HTMLDivElement, DropdownMenuProps>(
76104
(
77105
{
78106
children,
79107
anchor,
80108
'aria-label': ariaLabel,
81-
align,
82-
className,
83-
classes,
109+
align = DropdownMenuAlignment.RIGHT,
110+
className = '',
111+
classes = {},
84112
maxHeight
85113
},
86114
ref
@@ -92,7 +120,7 @@ const DropdownMenu = forwardRef(
92120

93121
const close = useCallback(() => setIsOpen(false), [setIsOpen]);
94122

95-
const anchorRef = useModalClose(close, ref);
123+
const anchorRef = useModalClose<HTMLDivElement>(close, ref);
96124

97125
const toggle = useCallback(() => {
98126
setIsOpen((prevState) => !prevState);
@@ -116,7 +144,7 @@ const DropdownMenu = forwardRef(
116144
<button
117145
className={classes.button}
118146
aria-label={ariaLabel}
119-
tabIndex="0"
147+
tabIndex={0}
120148
onClick={toggle}
121149
onBlur={handleBlur}
122150
onFocus={handleFocus}
@@ -133,7 +161,7 @@ const DropdownMenu = forwardRef(
133161
}}
134162
onBlur={handleBlur}
135163
onFocus={handleFocus}
136-
style={maxHeight && { maxHeight, overflowY: 'auto' }}
164+
style={maxHeight ? { maxHeight, overflowY: 'auto' } : undefined}
137165
>
138166
{children}
139167
</DropdownWrapper>
@@ -142,33 +170,3 @@ const DropdownMenu = forwardRef(
142170
);
143171
}
144172
);
145-
146-
DropdownMenu.propTypes = {
147-
/**
148-
* Provide <MenuItem> elements as children to control the contents of the menu.
149-
*/
150-
children: PropTypes.node.isRequired,
151-
/**
152-
* Can optionally override the contents of the button which opens the menu.
153-
* Defaults to <DownArrowIcon>
154-
*/
155-
anchor: PropTypes.node,
156-
'aria-label': PropTypes.string.isRequired,
157-
align: PropTypes.oneOf(['left', 'right']),
158-
className: PropTypes.string,
159-
classes: PropTypes.shape({
160-
button: PropTypes.string,
161-
list: PropTypes.string
162-
}),
163-
maxHeight: PropTypes.string
164-
};
165-
166-
DropdownMenu.defaultProps = {
167-
anchor: null,
168-
align: 'right',
169-
className: '',
170-
classes: {},
171-
maxHeight: undefined
172-
};
173-
174-
export default DropdownMenu;

client/components/Dropdown/TableDropdown.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import styled from 'styled-components';
33
import { prop, remSize } from '../../theme';
4-
import DropdownMenu from './DropdownMenu';
4+
import { DropdownMenu } from './DropdownMenu';
55

66
import DownFilledTriangleIcon from '../../images/down-filled-triangle.svg';
77
import MoreIconSvg from '../../images/more.svg';

client/modules/IDE/components/VersionPicker.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { prop } from '../../../theme';
88
import { useP5Version } from '../hooks/useP5Version';
99
import { p5Versions } from '../../../../common/p5Versions';
1010
import MenuItem from '../../../components/Dropdown/MenuItem';
11-
import DropdownMenu from '../../../components/Dropdown/DropdownMenu';
11+
import { DropdownMenu } from '../../../components/Dropdown/DropdownMenu';
1212
import { updateFileContent } from '../actions/files';
1313
// eslint-disable-next-line import/no-cycle
1414
import { CmControllerContext } from '../pages/IDEView';

0 commit comments

Comments
 (0)