Skip to content

Commit c8eacbe

Browse files
AlessioGrjacobsfletch
authored andcommitted
feat: remove qs, upgrade dependencies & misc improvements (#58)
1 parent 97e7ba4 commit c8eacbe

File tree

12 files changed

+299
-269
lines changed

12 files changed

+299
-269
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ node_modules
33
package-lock.json
44
dist
55
dist-demo
6+
/.idea/*
7+
!/.idea/runConfigurations
8+
!/.idea/payload.iml

package.json

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,27 @@
22
"name": "@faceless-ui/modal",
33
"version": "3.0.0-beta.0",
44
"type": "module",
5-
"main": "dist/index.js",
6-
"types": "dist/index.d.ts",
5+
"main": "src/index.ts",
6+
"types": "src/index.ts",
7+
"exports": {
8+
".": {
9+
"import": "./src/index.ts",
10+
"types": "./src/index.ts",
11+
"default": "./src/index.ts"
12+
}
13+
},
14+
"publishConfig": {
15+
"main": "dist/index.js",
16+
"types": "dist/index.d.ts",
17+
"exports": {
18+
".": {
19+
"import": "./dist/index.js",
20+
"types": "./dist/index.d.ts",
21+
"default": "./dist/index.js"
22+
}
23+
}
24+
},
25+
"sideEffects": false,
726
"homepage:": "https://facelessui.com/docs/modal",
827
"repository": "[email protected]:faceless-ui/modal.git",
928
"description": "America's next top modal",
@@ -56,10 +75,9 @@
5675
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc.0"
5776
},
5877
"dependencies": {
59-
"body-scroll-lock": "^3.1.5",
60-
"focus-trap": "^6.9.2",
61-
"qs": "^6.9.1",
62-
"react-transition-group": "^4.4.2"
78+
"body-scroll-lock": "4.0.0-beta.0",
79+
"focus-trap": "7.5.4",
80+
"react-transition-group": "4.4.5"
6381
},
6482
"devDependencies": {
6583
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
@@ -88,7 +106,7 @@
88106
"react-refresh": "^0.13.0",
89107
"react-refresh-typescript": "^2.0.4",
90108
"ts-loader": "^9.5.1",
91-
"typescript": "^5.4.5",
109+
"typescript": "5.5.2",
92110
"webpack": "^5.91.0",
93111
"webpack-cli": "^5.1.4",
94112
"webpack-dev-server": "^5.0.4"

src/Modal/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use client'
2-
import * as focusTrap from 'focus-trap';
2+
import type { Options } from 'focus-trap';
33
import React, { Fragment, ElementType, HTMLProps } from 'react';
44
import { asModal } from '../asModal/index.js';
55
import { IModalContext } from '../ModalProvider/context.js';
@@ -27,10 +27,10 @@ export interface ModalProps extends Omit<HTMLProps<HTMLElement>, 'children'> {
2727
openOnInit?: boolean
2828
children?: React.ReactNode | ChildFunction
2929
trapFocus?: boolean
30-
focusTrapOptions?: focusTrap.Options
30+
focusTrapOptions?: Options
3131
}
3232

33-
const Modal: React.FC<ModalPropsWithContext & {
33+
const _Modal: React.FC<ModalPropsWithContext & {
3434
children?: React.ReactNode | ChildFunction
3535
}> = (props) => {
3636
const { children } = props;
@@ -53,4 +53,4 @@ const Modal: React.FC<ModalPropsWithContext & {
5353
return null;
5454
};
5555

56-
export default asModal(Modal);
56+
export const Modal = asModal(_Modal)

src/ModalContainer/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import React, { MouseEvent, ElementType, HTMLProps } from 'react';
33
import { CSSTransition } from 'react-transition-group';
44
import { useModal } from '../useModal/index.js';
5-
import generateTransitionClasses from '../ModalProvider/generateTransitionClasses.js';
5+
import { generateTransitionClasses } from '../ModalProvider/generateTransitionClasses.js';
66

77
export const containerBaseClass = 'modal-container';
88

src/ModalProvider/generateCSS.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { containerBaseClass } from '../ModalContainer/index.js';
22
import { itemBaseClass } from '../asModal/index.js';
33

4-
const CSS = ({
4+
export const generateCSS = ({
55
classPrefix,
66
zIndex,
77
}: {
@@ -47,4 +47,3 @@ const CSS = ({
4747
`);
4848
};
4949

50-
export default CSS;

src/ModalProvider/generateTransitionClasses.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const generateTransitionClasses = (baseClass: string): Record<string, unknown> => {
1+
export const generateTransitionClasses = (baseClass: string): Record<string, unknown> => {
22
if (baseClass) {
33
return ({
44
appear: `${baseClass}--appear`,
@@ -14,5 +14,3 @@ const generateTransitionClasses = (baseClass: string): Record<string, unknown> =
1414
}
1515
return {};
1616
};
17-
18-
export default generateTransitionClasses;

src/ModalProvider/index.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import React, {
77
useCallback,
88
useReducer,
99
} from 'react';
10-
import queryString from 'qs';
1110
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
12-
import generateCSS from './generateCSS.js';
11+
import { generateCSS } from './generateCSS.js';
1312
import { ModalContext, ModalState } from './context.js';
14-
import reducer from './reducer.js';
13+
import { reducer } from './reducer.js';
1514

1615
export type ModalProviderProps = {
1716
generateCSS?: boolean
@@ -25,21 +24,22 @@ export type ModalProviderProps = {
2524

2625
const getSearchQuery = () => {
2726
if (typeof window !== 'undefined') {
28-
return queryString.parse(
29-
window.location.search,
30-
{ ignoreQueryPrefix: true },
31-
);
27+
return new URLSearchParams(window.location.search);
3228
}
3329
};
3430

3531
const getModalParamArray = (): string[] => {
3632
const searchQuery = getSearchQuery();
3733
let params: string[] = [];
38-
if (searchQuery && searchQuery.modal) {
39-
if (typeof searchQuery.modal === 'string') {
40-
params = [searchQuery.modal];
41-
} else if (Array.isArray(searchQuery.modal)) {
42-
params = searchQuery.modal as string[];
34+
if (searchQuery) {
35+
const modalParam = searchQuery.get('modal');
36+
if (modalParam) {
37+
// Check if the parameter contains a comma, indicating multiple values
38+
if (modalParam.includes(',')) {
39+
params = modalParam.split(',');
40+
} else {
41+
params = [modalParam];
42+
}
4343
}
4444
}
4545
return params;
@@ -124,12 +124,13 @@ export const ModalProvider: React.FC<ModalProviderProps> = (props) => {
124124

125125
if (typeof handleParamChange === 'boolean' && handleParamChange) {
126126
const openModals = Object.keys(modalState).filter((slug) => modalState[slug].isOpen);
127-
const queryWithModal = queryString.stringify({
128-
modal: openModals
129-
}, {
130-
addQueryPrefix: true,
131-
encode: false,
132-
});
127+
const params = new URLSearchParams();
128+
129+
for (const modal of openModals) {
130+
params.append('modal', modal);
131+
}
132+
133+
const queryWithModal = params.toString() ? `?${params}` : '';
133134
const newURL = `${window.location.pathname}${queryWithModal}`;
134135
window.history.pushState({}, '', newURL);
135136
}

src/ModalProvider/reducer.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export type Action = UPDATE_MODAL
5151
| CLOSE_LATEST_MODAL
5252
| CLOSE_ALL_MODALS;
5353

54-
const reducer = (
54+
export const reducer = (
5555
state: ModalState,
5656
action: Action,
5757
): ModalState => {
@@ -191,5 +191,3 @@ const reducer = (
191191

192192
return newState;
193193
};
194-
195-
export default reducer;

src/asModal/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import React, {
77
import ReactDOM from 'react-dom';
88
import { CSSTransition } from 'react-transition-group';
99
import { useModal } from '../useModal/index.js';
10-
import generateTransitionClasses from '../ModalProvider/generateTransitionClasses.js';
10+
import { generateTransitionClasses } from '../ModalProvider/generateTransitionClasses.js';
1111
import { ModalProps } from '../Modal/index.js';
12-
import * as focusTrap from 'focus-trap'; // ESM
12+
import { createFocusTrap, type FocusTrap }from 'focus-trap';
1313

1414
export const itemBaseClass = 'modal-item';
1515

@@ -22,7 +22,7 @@ export const asModal = <P extends ModalProps>(
2222
const modalRef = useRef(null);
2323
const [layTrap, setLayTrap] = useState(false);
2424
const trapHasBeenLayed = useRef(false);
25-
const [trap, setTrap] = useState<focusTrap.FocusTrap | null>(null);
25+
const [trap, setTrap] = useState<FocusTrap | null>(null);
2626

2727
const {
2828
modalState,
@@ -66,7 +66,7 @@ export const asModal = <P extends ModalProps>(
6666
const currentModal = modalRef.current;
6767

6868
if (trapHasBeenLayed.current === false && currentModal) {
69-
const newTrap = focusTrap.createFocusTrap(currentModal, {
69+
const newTrap = createFocusTrap(currentModal, {
7070
...focusTrapOptions,
7171
fallbackFocus: focusTrapOptions?.fallbackFocus || currentModal,
7272
allowOutsideClick: typeof focusTrapOptions.allowOutsideClick !== 'undefined' ? focusTrapOptions.allowOutsideClick : true,

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { asModal } from './asModal/index.js';
2-
export { default as Modal } from './Modal/index.js';
2+
export { Modal } from './Modal/index.js';
33
export { ModalContainer } from './ModalContainer/index.js';
44
export { ModalContext } from './ModalProvider/context.js';
55
export { ModalProvider } from './ModalProvider/index.js';

tsconfig.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@
88
"resolveJsonModule": true,
99
"strict": true,
1010
"sourceMap": true,
11-
"jsx": "react",
11+
"jsx": "react-jsx",
1212
"skipLibCheck": true,
1313
"esModuleInterop": true,
1414
"declaration": true,
1515
"declarationDir": "./dist",
1616
"paths": {
17-
"@faceless-ui/modal": ["./src/index.ts"],
18-
},
17+
"@faceless-ui/modal": ["./src/index.ts"]
18+
}
1919
},
2020
"include": [
2121
"src/**/*",
22-
"demo/**/*",
22+
"demo/**/*"
2323
],
2424
"exclude": [
2525
"**/*.test.js",
26-
"node_modules",
26+
"node_modules"
2727
]
2828
}

0 commit comments

Comments
 (0)