Skip to content

Commit

Permalink
Merge pull request Hacker0x01#4393 from G07cha/chore/migrate-to-float…
Browse files Browse the repository at this point in the history
…ing-ui

migrate from Popper.js to Floating-UI
  • Loading branch information
martijnrusschen authored Jan 3, 2024
2 parents 1be1893 + 267c138 commit 3cd50f6
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 213 deletions.
13 changes: 7 additions & 6 deletions docs-site/src/components/Examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import DisabledKeyboardNavigation from "../../examples/disabledKeyboardNavigatio
import ReadOnly from "../../examples/readOnly";
import ClearInput from "../../examples/clearInput";
import OnBlurCallbacks from "../../examples/onBlurCallbacks";
import ConfigurePopper from "../../examples/configurePopper";
import ConfigureFloatingUI from "../../examples/configureFloatingUI";
import Portal from "../../examples/portal";
import PortalById from "../../examples/portalById";
import WithPortalById from "../../examples/withPortalById";
Expand Down Expand Up @@ -159,17 +159,18 @@ export default class exampleComponents extends React.Component {
component: CloseOnScrollCallback,
},
{
title: "Configure Popper Properties",
component: ConfigurePopper,
title: "Configure Floating UI Properties",
component: ConfigureFloatingUI,
description: (
<div>
Full docs for the popper can be found at{" "}
Full docs for the underlying library that manages the overlay used can
be found at{" "}
<a
href="https://popper.js.org"
href="https://floating-ui.com/"
target="_blank"
rel="noopener noreferrer"
>
popper.js.org
floating-ui.com
</a>
</div>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,10 @@
popperPlacement="top-end"
popperModifiers={[
{
name: "offset",
options: {
offset: [5, 10],
},
},
{
name: "preventOverflow",
options: {
rootBoundary: "viewport",
tether: false,
altAxis: true,
name: "myModifier",
fn(state) {
// Do something with the state
return state;
},
},
]}
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
"!**/node_modules/**",
"!**/vendor/**",
],
transformIgnorePatterns: ["/node_modules/(?!(@popperjs)|date-fns)"],
transformIgnorePatterns: ["/node_modules/(?!date-fns)"],
transform: {
"^.+\\.(js|jsx)$": "babel-jest",
"^.+\\.ts?$": "ts-jest",
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,11 @@
"react-dom": "^16.9.0 || ^17 || ^18"
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"@floating-ui/react": "^0.26.2",
"classnames": "^2.2.6",
"date-fns": "^2.30.0",
"prop-types": "^15.7.2",
"react-onclickoutside": "^6.13.0",
"react-popper": "^2.3.0"
"react-onclickoutside": "^6.13.0"
},
"scripts": {
"eslint": "eslint --ext .js,.jsx src test",
Expand Down
1 change: 0 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const globals = {
react: "React",
"prop-types": "PropTypes",
"react-onclickoutside": "onClickOutside",
"react-popper": "ReactPopper",
classnames: "classNames",
};

Expand Down
5 changes: 1 addition & 4 deletions src/calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export default class Calendar extends React.Component {

static propTypes = {
adjustDateOnChange: PropTypes.bool,
arrowProps: PropTypes.object,
chooseDayAriaLabelPrefix: PropTypes.string,
className: PropTypes.string,
children: PropTypes.node,
Expand Down Expand Up @@ -1074,13 +1073,11 @@ export default class Calendar extends React.Component {
render() {
const Container = this.props.container || CalendarContainer;
return (
<div style={{display: 'contents'}} ref={this.containerRef}>
<div style={{ display: "contents" }} ref={this.containerRef}>
<Container
className={classnames("react-datepicker", this.props.className, {
"react-datepicker--time-only": this.props.showTimeSelectOnly,
})}
showPopperArrow={this.props.showPopperArrow}
arrowProps={this.props.arrowProps}
>
{this.renderAriaLiveRegion()}
{this.renderPreviousButton()}
Expand Down
18 changes: 2 additions & 16 deletions src/calendar_container.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
import PropTypes from "prop-types";
import React from "react";

export default function CalendarContainer({
className,
children,
showPopperArrow,
arrowProps = {},
}) {
return (
<div className={className}>
{showPopperArrow && (
<div className="react-datepicker__triangle" {...arrowProps} />
)}
{children}
</div>
);
export default function CalendarContainer({ className, children }) {
return <div className={className}>{children}</div>;
}

CalendarContainer.propTypes = {
className: PropTypes.string,
children: PropTypes.node,
arrowProps: PropTypes.object, // react-popper arrow props
showPopperArrow: PropTypes.bool,
};
5 changes: 3 additions & 2 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import PropTypes from "prop-types";
import Calendar from "./calendar";
import CalendarIcon from "./calendar_icon";
import Portal from "./portal";
import PopperComponent, { popperPlacementPositions } from "./popper_component";
import PopperComponent from "./popper_component";
import { popperPlacementPositions } from "./with_floating";
import classnames from "classnames";
import set from "date-fns/set";
import startOfDay from "date-fns/startOfDay";
Expand Down Expand Up @@ -1091,7 +1092,6 @@ export default class DatePicker extends React.Component {
showYearPicker={this.props.showYearPicker}
showQuarterYearPicker={this.props.showQuarterYearPicker}
showWeekPicker={this.props.showWeekPicker}
showPopperArrow={this.props.showPopperArrow}
excludeScrollbar={this.props.excludeScrollbar}
handleOnKeyDown={this.props.onKeyDown}
handleOnDayKeyDown={this.onDayKeyDown}
Expand Down Expand Up @@ -1340,6 +1340,7 @@ export default class DatePicker extends React.Component {
popperProps={this.props.popperProps}
popperOnKeyDown={this.onPopperKeyDown}
enableTabLoop={this.props.enableTabLoop}
showArrow={this.props.showPopperArrow}
/>
);
}
Expand Down
77 changes: 37 additions & 40 deletions src/popper_component.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import classnames from "classnames";
import React from "react";
import PropTypes from "prop-types";
import { Manager, Reference, Popper } from "react-popper";
import { placements } from "@popperjs/core/lib";
import { FloatingArrow } from "@floating-ui/react";
import TabLoop from "./tab_loop";
import Portal from "./portal";
import withFloating from "./with_floating";

export const popperPlacementPositions = placements;

export default class PopperComponent extends React.Component {
// Exported for testing purposes
export class PopperComponent extends React.Component {
static get defaultProps() {
return {
hidePopper: true,
popperModifiers: [],
popperProps: {},
popperPlacement: "bottom-start",
};
}

Expand All @@ -23,13 +19,12 @@ export default class PopperComponent extends React.Component {
wrapperClassName: PropTypes.string,
hidePopper: PropTypes.bool,
popperComponent: PropTypes.element,
popperModifiers: PropTypes.arrayOf(PropTypes.object), // <datepicker/> props
popperPlacement: PropTypes.oneOf(popperPlacementPositions), // <datepicker/> props
popperContainer: PropTypes.func,
popperProps: PropTypes.object,
targetComponent: PropTypes.element,
enableTabLoop: PropTypes.bool,
popperOnKeyDown: PropTypes.func,
showArrow: PropTypes.bool,
portalId: PropTypes.string,
portalHost: PropTypes.instanceOf(ShadowRoot),
};
Expand All @@ -40,39 +35,43 @@ export default class PopperComponent extends React.Component {
wrapperClassName,
hidePopper,
popperComponent,
popperModifiers,
popperPlacement,
popperProps,
targetComponent,
enableTabLoop,
popperOnKeyDown,
portalId,
portalHost,
popperProps,
showArrow,
} = this.props;

let popper;

if (!hidePopper) {
const classes = classnames("react-datepicker-popper", className);
popper = (
<Popper
modifiers={popperModifiers}
placement={popperPlacement}
{...popperProps}
>
{({ ref, style, placement, arrowProps }) => (
<TabLoop enableTabLoop={enableTabLoop}>
<div
{...{ ref, style }}
className={classes}
data-placement={placement}
onKeyDown={popperOnKeyDown}
>
{React.cloneElement(popperComponent, { arrowProps })}
</div>
</TabLoop>
)}
</Popper>
<TabLoop enableTabLoop={enableTabLoop}>
<div
ref={popperProps.refs.setFloating}
style={popperProps.floatingStyles}
className={classes}
data-placement={popperProps.placement}
onKeyDown={popperOnKeyDown}
>
{popperComponent}
{showArrow && (
<FloatingArrow
ref={popperProps.arrowRef}
context={popperProps.context}
fill="currentColor"
strokeWidth={1}
height={8}
width={16}
style={{ transform: "translateY(-1px)" }}
className="react-datepicker__triangle"
/>
)}
</div>
</TabLoop>
);
}

Expand All @@ -94,16 +93,14 @@ export default class PopperComponent extends React.Component {
);

return (
<Manager className="react-datepicker-manager">
<Reference>
{({ ref }) => (
<div ref={ref} className={wrapperClasses}>
{targetComponent}
</div>
)}
</Reference>
<React.Fragment>
<div ref={popperProps.refs.setReference} className={wrapperClasses}>
{targetComponent}
</div>
{popper}
</Manager>
</React.Fragment>
);
}
}

export default withFloating(PopperComponent);
45 changes: 6 additions & 39 deletions src/stylesheets/datepicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
border-radius: $datepicker__border-radius;
display: inline-block;
position: relative;

// Reverting value set in .react-datepicker-popper
line-height: initial;
}

.react-datepicker--time-only {
.react-datepicker__triangle {
left: 35px;
}

.react-datepicker__time-container {
border-left: 0;
}
Expand All @@ -34,55 +33,23 @@
}
}

.react-datepicker__triangle {
position: absolute;
left: 50px;
}

.react-datepicker-popper {
z-index: 1;

&[data-placement^="bottom"] {
padding-top: $datepicker__triangle-size + 2px;
// Eliminating extra space at the bottom of the container
line-height: 0;

&[data-placement^="bottom"] {
.react-datepicker__triangle {
@extend %triangle-arrow-up;
}
}

&[data-placement="bottom-end"],
&[data-placement="top-end"] {
.react-datepicker__triangle {
left: auto;
right: 50px;
}
}

&[data-placement^="top"] {
padding-bottom: $datepicker__triangle-size + 2px;

.react-datepicker__triangle {
@extend %triangle-arrow-down;
}
}

&[data-placement^="right"] {
padding-left: $datepicker__triangle-size;

.react-datepicker__triangle {
left: auto;
right: 42px;
}
}

&[data-placement^="left"] {
padding-right: $datepicker__triangle-size;

.react-datepicker__triangle {
left: 42px;
right: auto;
}
}
}

.react-datepicker__header {
Expand Down
Loading

0 comments on commit 3cd50f6

Please sign in to comment.