Skip to content

Commit

Permalink
Fix v11.0.0 types that removed the default export (#1406)
Browse files Browse the repository at this point in the history
* Fix v11.0.0 types that removed the default export

Fixes #1396

My original intent was to remove the default export (a breaking change)
as part of the major 11.0.0 release but I totally flopped on that by
not also actually providing the named export in the code.

Now that the major release ship has sailed, this change fixes the types
by reinstating the default export in the typings but marking it
deprecated, while also providing the new named export alternative
as the way forward.

* Props no longer extend from AllHTMLAttributes
  • Loading branch information
stefcameron authored Dec 12, 2024
1 parent ea9d453 commit cd75caa
Show file tree
Hide file tree
Showing 16 changed files with 79 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-buttons-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'focus-trap-react': patch
---

Fix missing default export in typings; props no longer extend `React.AllHTMLAttributes<any>` to allow things like `className` (those extra props have always been ignored anyway); deprecate default export; add named export in code ([#1396](https://github.com/focus-trap/focus-trap-react/issues/1396))
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ You can read further code examples in `demo/` (it's very simple), and [see how i
Here's one more simple example:

```jsx
const React = require('react');
const ReactDOM = require('react-dom'); // React 16-17
const { createRoot } = require('react-dom/client'); // React 18
const FocusTrap = require('focus-trap-react');
import React from 'react';
import { createRoot } from 'react-dom/client';
import { FocusTrap } from 'focus-trap-react';

class Demo extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -150,7 +149,6 @@ class Demo extends React.Component {
}
}

ReactDOM.render(<Demo />, document.getElementById('root')); // React 16-17
createRoot(document.getElementById('root')).render(<Demo />); // React 18
```

Expand Down Expand Up @@ -192,14 +190,13 @@ The result can be that (depending on how you render the trap) in Strict Mode, th
Example:

```jsx
const React = require('react');
const { createRoot } = require('react-dom/client');
const propTypes = require('prop-types');
const FocusTrap = require('../../dist/focus-trap-react');
import { forwardRef, Component } from 'react';
import { createRoot } from 'react-dom/client';
import { FocusTrap } from 'focus-trap-react';

const container = document.getElementById('demo-function-child');

const TrapChild = React.forwardRef(function ({ onDeactivate }, ref) {
const TrapChild = forwardRef(function ({ onDeactivate }, ref) {
return (
<div ref={ref}>
<p>
Expand All @@ -223,7 +220,7 @@ TrapChild.propTypes = {
onDeactivate: propTypes.func,
};

class DemoFunctionChild extends React.Component {
class DemoFunctionChild extends Component {
constructor(props) {
super(props);

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-animated-dialog.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { useState } = require('react');
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-animated-dialog');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-animated-trigger.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { useState } = require('react');
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-animated-trigger');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-autofocus.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-autofocus');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-containerelements-childless.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-containerelements-childless');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-containerelements.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-containerelements');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-defaults.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-defaults');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-ffne.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-ffne');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const React = require('react');
const ReactDOM = require('react-dom');
const { createRoot } = require('react-dom/client');
const PropTypes = require('prop-types');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const { useRef, useState, useEffect } = React;
const container = document.getElementById('demo-iframe');
Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-setReturnFocus.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { useState, useMemo } = require('react');
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-setReturnFocus');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-special-element.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const container = document.getElementById('demo-special-element');

Expand Down
2 changes: 1 addition & 1 deletion demo/js/demo-with-shadow-dom.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const React = require('react');
const { createRoot } = require('react-dom/client');
const FocusTrap = require('../../dist/focus-trap-react');
const { FocusTrap } = require('../../dist/focus-trap-react');

const createShadow = function (hostEl, isOpen) {
const containerEl = document.createElement('div');
Expand Down
58 changes: 50 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
import { Options as FocusTrapOptions } from 'focus-trap';
import * as React from 'react';

export interface FocusTrapProps {
/**
* __Single container child__ for the trap. Use `containerElements` instead
* if you need a trap with multiple containers.
*/
children?: React.ReactNode;

/**
* By default, the trap will be active when it mounts, so it's activated by
* mounting, and deactivated by unmounting. Use this prop to control when
* it's active while it's mounted, or if it's initially inactive.
*/
active?: boolean;

/**
* To pause or unpause the trap while it's `active`. Primarily for use when
* you need to manage multiple traps in the same view. When paused, the trap
* retains its various event listeners, but ignores all events.
*/
paused?: boolean;

/**
* See Focus-trap's [createOptions](https://github.com/focus-trap/focus-trap?tab=readme-ov-file#createoptions)
* for more details on available options.
*/
focusTrapOptions?: FocusTrapOptions;

/**
* If specified, these elements will be used as the boundaries for the
* trap, __instead of the child__ specified in `children` (though
* `children` will still be rendered).
*/
containerElements?: Array<HTMLElement>;
}

export declare class FocusTrap extends React.Component<FocusTrapProps> { }

/**
* Default export of the FocusTrap component.
* @deprecated 🔺 Use the named import `{ FocusTrap }` instead.
* @description 🔺 The default export will be removed in a future release. Migrate to the named
* import `{ FocusTrap }` today to ensure future compatibility.
*/
declare namespace FocusTrap {
export interface Props extends React.AllHTMLAttributes<any> {
children?: React.ReactNode;
active?: boolean;
paused?: boolean;
focusTrapOptions?: FocusTrapOptions;
containerElements?: Array<HTMLElement>;
}
export type Props = FocusTrapProps;
}

export declare class FocusTrap extends React.Component<FocusTrap.Props> { }
/**
* @deprecated 🔺 Use the named import `{ FocusTrap }` instead.
* @description 🔺 The default export will be removed in a future release. Migrate to the named
* import `{ FocusTrap }` today to ensure future compatibility.
*/
export default FocusTrap;
4 changes: 4 additions & 0 deletions src/focus-trap-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,4 +425,8 @@ FocusTrap.defaultProps = {
_createFocusTrap: createFocusTrap,
};

// 🔺 DEPRECATED: default export
module.exports = FocusTrap;

// named export
module.exports.FocusTrap = FocusTrap;
2 changes: 1 addition & 1 deletion test/focus-trap-react.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
waitFor,
} = require('@testing-library/react');
const { default: userEvent } = require('@testing-library/user-event');
const FocusTrap = require('../src/focus-trap-react');
const { FocusTrap } = require('../src/focus-trap-react');

const getTestFocusTrapOptions = function (focusTrapOptions) {
const { tabbableOptions, ...rest } = focusTrapOptions || {};
Expand Down

0 comments on commit cd75caa

Please sign in to comment.