Skip to content

Commit 2ff369e

Browse files
committed
Update examples to demonstrate usage of arrow, offsetX, and offsetY props
1 parent 68d6b27 commit 2ff369e

File tree

4 files changed

+147
-30
lines changed

4 files changed

+147
-30
lines changed

example/src/components/Usage.js

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,18 @@ function CustomisedButtonExample() {
415415
}
416416

417417
function MenuDirectionExample() {
418+
const [option, setOption] = useState('default');
418419

419-
const menus = ['top', 'left', 'right', 'bottom'].map(direction => (
420+
const menus = ['right', 'top', 'bottom', 'left'].map(direction => (
420421
<Menu menuButton={<MenuButton>{direction}</MenuButton>}
421-
key={direction} direction={direction}>
422+
key={direction} direction={direction}
423+
arrow={option === 'arrow'}
424+
offsetX={option === 'offset' &&
425+
(direction === 'left' || direction === 'right')
426+
? 12 : 0}
427+
offsetY={option === 'offset' &&
428+
(direction === 'top' || direction === 'bottom')
429+
? 12 : 0}>
422430
<MenuItem>New File</MenuItem>
423431
<MenuItem>Save</MenuItem>
424432
<MenuItem>Close Window</MenuItem>
@@ -427,16 +435,23 @@ function MenuDirectionExample() {
427435

428436
return (
429437
<Example data={codeExamples.direction} >
430-
{menus}
438+
<PlacementOptions name="directionGroup" option={option}
439+
onOptionChange={setOption} />
440+
<div className="menus">
441+
{menus}
442+
</div>
431443
</Example>
432444
);
433445
}
434446

435447
function MenuAlignmentExample() {
448+
const [option, setOption] = useState('default');
436449

437450
const menus = ['start', 'center', 'end'].map(align => (
438451
<Menu menuButton={<MenuButton>{align}</MenuButton>}
439-
key={align} align={align}>
452+
key={align} align={align}
453+
arrow={option === 'arrow'}
454+
offsetY={option === 'offset' ? 12 : 0}>
440455
<MenuItem>New File</MenuItem>
441456
<MenuItem>Save</MenuItem>
442457
<MenuItem>Close Window</MenuItem>
@@ -445,7 +460,11 @@ function MenuAlignmentExample() {
445460

446461
return (
447462
<Example data={codeExamples.alignment} >
448-
{menus}
463+
<PlacementOptions name="alignmentGroup" option={option}
464+
onOptionChange={setOption} />
465+
<div className="menus">
466+
{menus}
467+
</div>
449468
</Example>
450469
);
451470
}
@@ -571,3 +590,21 @@ function ClassNamePropExample() {
571590
);
572591
}
573592

593+
function PlacementOptions({ name, option, onOptionChange }) {
594+
595+
return (
596+
<form className="form">
597+
{['default', 'arrow', 'offset'].map((item) =>
598+
<label key={item}>
599+
<input type="radio"
600+
name={name}
601+
value={item}
602+
checked={option === item}
603+
onChange={({ target }) =>
604+
(target.checked && onOptionChange(target.value))
605+
} />
606+
{item}
607+
</label>)}
608+
</form>
609+
);
610+
}

example/src/data/codeExamples.js

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -784,12 +784,14 @@ export const direction = {
784784
desc:
785785
<>
786786
<p>You could control the direction in which a menu expands using the <code>direction</code> prop.</p>
787+
<p>Optionally, menu can be set to display an arrow pointing to its anchor element or add an offset using
788+
the <code>arrow, offsetX</code>, and <code>offsetY</code> props.</p>
787789
<p>Please note the actual direction might be different depending on the available
788790
viewport space, please see {menuLink} for more details.</p>
789791
</>,
790792

791793
source:
792-
`['top', 'left', 'right', 'bottom'].map(direction =>
794+
`['right', 'top', 'bottom', 'left'].map(direction =>
793795
<Menu menuButton={<MenuButton>{direction}</MenuButton>}
794796
key={direction} direction={direction}>
795797
<MenuItem>New File</MenuItem>
@@ -798,7 +800,7 @@ export const direction = {
798800
</Menu>)`,
799801

800802
fullSource:
801-
`import React from 'react';
803+
`import React, { useState } from 'react';
802804
import {
803805
Menu,
804806
MenuItem,
@@ -807,14 +809,48 @@ import {
807809
import '@szhsin/react-menu/dist/index.css';
808810
809811
export default function Example() {
812+
const [option, setOption] = useState('default');
813+
814+
const menus = ['right', 'top', 'bottom', 'left'].map(direction => (
815+
<Menu menuButton={<MenuButton>{direction}</MenuButton>}
816+
key={direction} direction={direction}
817+
arrow={option === 'arrow'}
818+
offsetX={option === 'offset' &&
819+
(direction === 'left' || direction === 'right')
820+
? 12 : 0}
821+
offsetY={option === 'offset' &&
822+
(direction === 'top' || direction === 'bottom')
823+
? 12 : 0}>
824+
<MenuItem>New File</MenuItem>
825+
<MenuItem>Save</MenuItem>
826+
<MenuItem>Close Window</MenuItem>
827+
</Menu>
828+
));
829+
810830
return (
811-
['top', 'left', 'right', 'bottom'].map(direction =>
812-
<Menu menuButton={<MenuButton>{direction}</MenuButton>}
813-
key={direction} direction={direction}>
814-
<MenuItem>New File</MenuItem>
815-
<MenuItem>Save</MenuItem>
816-
<MenuItem>Close Window</MenuItem>
817-
</Menu>)
831+
<>
832+
<PlacementOptions name="directionGroup" option={option}
833+
onOptionChange={setOption} />
834+
<div className="menus">
835+
{menus}
836+
</div>
837+
</>
838+
);
839+
}
840+
841+
function PlacementOptions({ name, option, onOptionChange }) {
842+
return (
843+
<form className="form">
844+
{['default', 'arrow', 'offset'].map((item) =>
845+
<label key={item}>
846+
<input type="radio" name={name} value={item}
847+
checked={option === item}
848+
onChange={({ target }) =>
849+
(target.checked && onOptionChange(target.value))
850+
} />
851+
{item}
852+
</label>)}
853+
</form>
818854
);
819855
}`
820856
};
@@ -838,7 +874,7 @@ export const alignment = {
838874
</Menu>)`,
839875

840876
fullSource:
841-
`import React from 'react';
877+
`import React, { useState } from 'react';
842878
import {
843879
Menu,
844880
MenuItem,
@@ -847,14 +883,42 @@ import {
847883
import '@szhsin/react-menu/dist/index.css';
848884
849885
export default function Example() {
886+
const [option, setOption] = useState('default');
887+
const menus = ['start', 'center', 'end'].map(align => (
888+
<Menu menuButton={<MenuButton>{align}</MenuButton>}
889+
key={align} align={align}
890+
arrow={option === 'arrow'}
891+
offsetY={option === 'offset' ? 12 : 0}>
892+
<MenuItem>New File</MenuItem>
893+
<MenuItem>Save</MenuItem>
894+
<MenuItem>Close Window</MenuItem>
895+
</Menu>
896+
));
897+
850898
return (
851-
['start', 'center', 'end'].map(align =>
852-
<Menu menuButton={<MenuButton>{align}</MenuButton>}
853-
key={align} align={align}>
854-
<MenuItem>New File</MenuItem>
855-
<MenuItem>Save</MenuItem>
856-
<MenuItem>Close Window</MenuItem>
857-
</Menu>)
899+
<>
900+
<PlacementOptions name="alignmentGroup" option={option}
901+
onOptionChange={setOption} />
902+
<div className="menus">
903+
{menus}
904+
</div>
905+
</>
906+
);
907+
}
908+
909+
function PlacementOptions({ name, option, onOptionChange }) {
910+
return (
911+
<form className="form">
912+
{['default', 'arrow', 'offset'].map((item) =>
913+
<label key={item}>
914+
<input type="radio" name={name} value={item}
915+
checked={option === item}
916+
onChange={({ target }) =>
917+
(target.checked && onOptionChange(target.value))
918+
} />
919+
{item}
920+
</label>)}
921+
</form>
858922
);
859923
}`
860924
};

example/src/styles/_example.scss

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,27 @@
6969
[aria-labelledby="menu-direction"],
7070
[aria-labelledby="menu-alignment"] {
7171
.example__demo {
72-
justify-content: space-around;
73-
}
74-
.rc-menu-button {
75-
flex: 0 1 6rem;
72+
flex-direction: column;
73+
74+
.menus {
75+
display: flex;
76+
justify-content: space-around;
77+
align-self: stretch;
78+
}
79+
80+
.form {
81+
margin: 0 -1rem 1rem -1rem;
82+
label {
83+
margin: 0 1rem;
84+
}
85+
input[type="radio"] {
86+
margin-right: 0.5rem;
87+
}
88+
}
89+
90+
.rc-menu-button {
91+
flex: 0 1 6rem;
92+
}
7693
}
7794
}
7895

src/components/MenuList.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export const MenuList = defineName(React.memo(function MenuList({
294294
}) => {
295295
if (!arrow) return;
296296
let y = anchorRect.top - containerRect.top - menuY + anchorRect.height / 2;
297-
const offset = arrowRef.current.offsetWidth * 1.25;
297+
const offset = arrowRef.current.offsetHeight * 1.25;
298298
y = Math.max(offset, y);
299299
y = Math.min(y, menuRect.height - offset);
300300
setArrowPosition({ y });
@@ -479,11 +479,10 @@ export const MenuList = defineName(React.memo(function MenuList({
479479
let horizontalOffset = offsetX;
480480
let verticalOffset = offsetY;
481481
if (arrow) {
482-
const offset = arrowRef.current.offsetWidth;
483482
if (direction === 'left' || direction === 'right') {
484-
horizontalOffset += offset;
483+
horizontalOffset += arrowRef.current.offsetWidth;
485484
} else {
486-
verticalOffset += offset;
485+
verticalOffset += arrowRef.current.offsetHeight;
487486
}
488487
}
489488

0 commit comments

Comments
 (0)