@skyscanner/backpack-web 34.0.0-premajor.1 → 34.0.0-premajor.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,46 +16,25 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { useState, cloneElement, useRef } from 'react';
20
- import { useFloating, autoUpdate, offset, flip, useClick, useDismiss, useInteractions, FloatingFocusManager, FloatingArrow, arrow } from '@floating-ui/react';
21
-
22
- // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
23
- import { surfaceHighlightDay } from '@skyscanner/bpk-foundations-web/tokens/base.es6';
24
-
25
- // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
26
- import BpkCloseButton from "../../bpk-component-close-button";
27
- // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
28
- import { BpkButtonLink } from "../../bpk-component-link";
29
- import BpkText, { TEXT_STYLES } from "../../bpk-component-text";
30
- import { TransitionInitialMount, cssModules } from "../../bpk-react-utils";
31
- import { ARROW_ID } from "./constants";
32
- import STYLES from "./BpkPopover.module.css";
33
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
34
- const getClassName = cssModules(STYLES);
19
+ import { useState, useRef } from 'react';
20
+ import { Popover, PopoverContent, PopoverTrigger } from "./PopperUtils";
21
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
35
22
  const EVENT_SOURCES = {
36
23
  CLOSE_BUTTON: 'CLOSE_BUTTON',
37
24
  CLOSE_LINK: 'CLOSE_LINK'
38
25
  };
39
- const bindEventSource = (source, callback) => event => {
40
- if (event.persist) {
41
- event.persist();
42
- }
43
- callback(event, {
44
- source
45
- });
46
- };
47
26
  const BpkPopover = ({
48
- children,
49
- className = null,
50
- closeButtonIcon = true,
51
- closeButtonProps = {},
52
- closeButtonText,
53
- id,
27
+ // children,
28
+ // className = null,
29
+ // closeButtonIcon = true,
30
+ // closeButtonProps = {},
31
+ // closeButtonText,
32
+ // id,
54
33
  isOpen = false,
55
- label,
56
- labelAsTitle = false,
57
- onClose,
58
- padded = true,
34
+ // label,
35
+ // labelAsTitle = false,
36
+ // onClose,
37
+ // padded = true,
59
38
  placement = 'bottom',
60
39
  showArrow = true,
61
40
  target,
@@ -63,109 +42,68 @@ const BpkPopover = ({
63
42
  }) => {
64
43
  const [isOpenState, setIsOpenState] = useState(isOpen);
65
44
  const arrowRef = useRef(null);
66
- const {
67
- context,
68
- floatingStyles,
69
- refs
70
- } = useFloating({
71
- open: isOpenState,
72
- onOpenChange: setIsOpenState,
73
- placement,
74
- middleware: [showArrow && offset(14), flip({
75
- fallbackAxisSideDirection: 'start'
76
- }), arrow({
77
- element: arrowRef
78
- })],
79
- whileElementsMounted: autoUpdate
80
- });
81
- const click = useClick(context);
82
- const dismiss = useDismiss(context);
45
+
46
+ // const { context, floatingStyles, refs } = useFloating({
47
+ // open: isOpenState,
48
+ // onOpenChange: setIsOpenState,
49
+ // placement,
50
+ // middleware: [
51
+ // showArrow && offset(14),
52
+ // flip({ fallbackAxisSideDirection: 'start' }),
53
+ // arrow({ element: arrowRef }),
54
+ // ],
55
+ // whileElementsMounted: autoUpdate,
56
+ // });
57
+
58
+ // const click = useClick(context);
59
+ // const dismiss = useDismiss(context);
83
60
 
84
61
  // Merge all the interactions into prop getters
85
- const {
86
- getFloatingProps,
87
- getReferenceProps
88
- } = useInteractions([click, dismiss]);
89
- const targetElement = /*#__PURE__*/cloneElement(target, {
90
- ...getReferenceProps(),
91
- ref: refs.setReference
92
- });
93
- const classNames = getClassName('bpk-popover', className);
94
- const bodyClassNames = getClassName(padded && 'bpk-popover__body--padded');
95
- const labelId = `bpk-popover-label-${id}`;
96
- return /*#__PURE__*/_jsxs(_Fragment, {
97
- children: [targetElement, isOpenState && /*#__PURE__*/_jsx(FloatingFocusManager, {
98
- context: context,
99
- modal: false,
100
- children: /*#__PURE__*/_jsx("div", {
101
- ref: refs.setFloating,
102
- style: floatingStyles,
103
- ...getFloatingProps(),
104
- children: /*#__PURE__*/_jsx(TransitionInitialMount, {
105
- appearClassName: getClassName('bpk-popover--appear'),
106
- appearActiveClassName: getClassName('bpk-popover--appear-active'),
107
- transitionTimeout: 200,
108
- children: /*#__PURE__*/_jsxs("section", {
109
- id: id,
110
- tabIndex: -1,
111
- role: "dialog",
112
- "aria-labelledby": labelId,
113
- className: classNames,
114
- ...rest,
115
- children: [showArrow && /*#__PURE__*/_jsx(FloatingArrow, {
116
- ref: arrowRef,
117
- context: context,
118
- id: ARROW_ID
119
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
120
- ,
121
- className: getClassName('bpk-popover__arrow'),
122
- role: "presentation",
123
- stroke: surfaceHighlightDay,
124
- strokeWidth: 0.0625
125
- }), labelAsTitle ? /*#__PURE__*/_jsxs("header", {
126
- className: getClassName('bpk-popover__header'),
127
- children: [/*#__PURE__*/_jsx(BpkText, {
128
- tagName: "h2",
129
- id: labelId,
130
- textStyle: TEXT_STYLES.label1,
131
- children: label
132
- }), "\xA0", closeButtonIcon ? /*#__PURE__*/_jsx(BpkCloseButton, {
133
- label: closeButtonText,
134
- onClick: () => {
135
- bindEventSource(EVENT_SOURCES.CLOSE_BUTTON, onClose);
136
- setIsOpenState(false);
137
- },
138
- ...closeButtonProps
139
- }) : /*#__PURE__*/_jsx(BpkButtonLink, {
140
- onClick: () => {
141
- bindEventSource(EVENT_SOURCES.CLOSE_LINK, onClose);
142
- setIsOpenState(false);
143
- },
144
- ...closeButtonProps,
145
- children: closeButtonText
146
- })]
147
- }) : /*#__PURE__*/_jsx("span", {
148
- id: labelId,
149
- className: getClassName('bpk-popover__label'),
150
- children: label
151
- }), /*#__PURE__*/_jsx("div", {
152
- className: bodyClassNames,
153
- children: children
154
- }), !labelAsTitle && /*#__PURE__*/_jsx("footer", {
155
- className: getClassName('bpk-popover__footer'),
156
- children: /*#__PURE__*/_jsx(BpkButtonLink, {
157
- onClick: () => {
158
- bindEventSource(EVENT_SOURCES.CLOSE_LINK, onClose);
159
- setIsOpenState(false);
160
- },
161
- ...closeButtonProps,
162
- children: closeButtonText
163
- })
164
- })]
165
- })
166
- })
167
- })
168
- })]
169
- });
62
+ // const { getFloatingProps, getReferenceProps } = useInteractions([
63
+ // click,
64
+ // dismiss,
65
+ // ]);
66
+
67
+ // const targetElement = cloneElement(target, {
68
+ // ...getReferenceProps(),
69
+ // ref: refs.setReference,
70
+ // });
71
+ // const classNames = getClassName('bpk-popover', className);
72
+ // const bodyClassNames = getClassName(padded && 'bpk-popover__body--padded');
73
+
74
+ // const labelId = `bpk-popover-label-${id}`;
75
+
76
+ return (
77
+ /*#__PURE__*/
78
+ // <>
79
+ // {targetElement}
80
+ // {isOpenState && (
81
+ // <FloatingFocusManager context={context} modal={false}>
82
+ // <div
83
+ // ref={refs.setFloating}
84
+ // style={floatingStyles}
85
+ // {...getFloatingProps()}
86
+ // >
87
+ // </div>
88
+ // </FloatingFocusManager>
89
+ // )}
90
+ // </>
91
+ _jsxs(Popover, {
92
+ open: isOpenState,
93
+ onOpenChange: setIsOpenState,
94
+ arrowRef: arrowRef,
95
+ showArrow: showArrow,
96
+ placement: placement,
97
+ children: [/*#__PURE__*/_jsx(PopoverTrigger, {
98
+ onClick: () => setIsOpenState(v => !v),
99
+ children: target
100
+ }), /*#__PURE__*/_jsx(PopoverContent, {
101
+ setState: setIsOpenState,
102
+ arrowRef: arrowRef,
103
+ showArrow: showArrow,
104
+ ...rest
105
+ })]
106
+ })
107
+ );
170
108
  };
171
109
  export default BpkPopover;
@@ -0,0 +1,224 @@
1
+ import * as React from 'react';
2
+ import { useFloating, autoUpdate, offset, flip, useClick, useDismiss, useRole, useInteractions, useMergeRefs, FloatingPortal, FloatingFocusManager, arrow, FloatingArrow } from '@floating-ui/react';
3
+
4
+ // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
5
+ import { surfaceHighlightDay } from '@skyscanner/bpk-foundations-web/tokens/base.es6';
6
+
7
+ // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
8
+ import BpkCloseButton from "../../bpk-component-close-button";
9
+ // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
10
+ import { BpkButtonLink } from "../../bpk-component-link";
11
+ import BpkText, { TEXT_STYLES } from "../../bpk-component-text";
12
+ import { TransitionInitialMount, cssModules } from "../../bpk-react-utils";
13
+ import { ARROW_ID } from "./constants";
14
+ import STYLES from "./BpkPopover.module.css";
15
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
+ const getClassName = cssModules(STYLES);
17
+ export function usePopover({
18
+ arrowRef,
19
+ modal,
20
+ onOpenChange: setControlledOpen,
21
+ open: controlledOpen,
22
+ placement,
23
+ showArrow
24
+ } = {}) {
25
+ const open = controlledOpen;
26
+ const setOpen = setControlledOpen;
27
+ const data = useFloating({
28
+ placement,
29
+ open,
30
+ onOpenChange: setOpen,
31
+ whileElementsMounted: autoUpdate,
32
+ middleware: [showArrow && offset(14), arrow({
33
+ element: arrowRef
34
+ }), flip({
35
+ fallbackAxisSideDirection: 'start'
36
+ })]
37
+ });
38
+ const {
39
+ context
40
+ } = data;
41
+ const click = useClick(context, {
42
+ enabled: controlledOpen == null
43
+ });
44
+ const dismiss = useDismiss(context);
45
+ const role = useRole(context);
46
+ const interactions = useInteractions([click, dismiss, role]);
47
+ return React.useMemo(() => ({
48
+ open,
49
+ setOpen,
50
+ ...interactions,
51
+ ...data,
52
+ modal
53
+ }), [open, setOpen, interactions, data, modal]);
54
+ }
55
+ const PopoverContext = /*#__PURE__*/React.createContext(null);
56
+ export const usePopoverContext = () => {
57
+ const context = React.useContext(PopoverContext);
58
+ if (context == null) {
59
+ throw new Error('Popover components must be wrapped in <Popover />');
60
+ }
61
+ return context;
62
+ };
63
+ export function Popover({
64
+ children,
65
+ modal = false,
66
+ ...restOptions
67
+ }) {
68
+ // This can accept any props as options, e.g. `placement`,
69
+ // or other positioning options.
70
+ const popover = usePopover({
71
+ modal,
72
+ ...restOptions
73
+ });
74
+ return /*#__PURE__*/_jsx(PopoverContext.Provider, {
75
+ value: popover,
76
+ children: children
77
+ });
78
+ }
79
+ export const PopoverTrigger = /*#__PURE__*/React.forwardRef(({
80
+ asChild = false,
81
+ children,
82
+ ...props
83
+ }, propRef) => {
84
+ const context = usePopoverContext();
85
+ const childrenRef = children.ref;
86
+ const ref = useMergeRefs([context.refs.setReference, propRef, childrenRef]);
87
+
88
+ // `asChild` allows the user to pass any element as the anchor
89
+ if (asChild && /*#__PURE__*/React.isValidElement(children)) {
90
+ return /*#__PURE__*/React.cloneElement(children, context.getReferenceProps({
91
+ ref,
92
+ ...props,
93
+ ...children.props,
94
+ 'data-state': context.open ? 'open' : 'closed'
95
+ }));
96
+ }
97
+ return /*#__PURE__*/_jsx("div", {
98
+ ref: ref
99
+ // The user can style the trigger based on the state
100
+ ,
101
+ "data-state": context.open ? 'open' : 'closed',
102
+ ...context.getReferenceProps(props),
103
+ children: children
104
+ });
105
+ });
106
+ const EVENT_SOURCES = {
107
+ CLOSE_BUTTON: 'CLOSE_BUTTON',
108
+ CLOSE_LINK: 'CLOSE_LINK'
109
+ };
110
+ const bindEventSource = (source, callback) => event => {
111
+ if (event.persist) {
112
+ event.persist();
113
+ }
114
+ callback(event, {
115
+ source
116
+ });
117
+ };
118
+ export const PopoverContent = /*#__PURE__*/React.forwardRef(({
119
+ arrowRef,
120
+ children,
121
+ className = null,
122
+ closeButtonIcon = true,
123
+ closeButtonProps = {},
124
+ closeButtonText,
125
+ id,
126
+ isOpen = false,
127
+ label,
128
+ labelAsTitle = false,
129
+ onClose,
130
+ padded = true,
131
+ placement = 'bottom',
132
+ setState: setIsOpenState,
133
+ showArrow,
134
+ target,
135
+ ...rest
136
+ }, propRef) => {
137
+ // const [isOpenState, setIsOpenState] = React.useState(isOpen);
138
+
139
+ const {
140
+ context: floatingContext,
141
+ ...context
142
+ } = usePopoverContext();
143
+ const ref = useMergeRefs([context.refs.setFloating, propRef]);
144
+ const classNames = getClassName('bpk-popover', className);
145
+ const bodyClassNames = getClassName(padded && 'bpk-popover__body--padded');
146
+ const labelId = `bpk-popover-label-${id}`;
147
+ if (!floatingContext.open) return null;
148
+ return /*#__PURE__*/_jsx(FloatingPortal, {
149
+ children: /*#__PURE__*/_jsx(FloatingFocusManager, {
150
+ context: floatingContext,
151
+ modal: context.modal,
152
+ children: /*#__PURE__*/_jsx("div", {
153
+ ref: ref,
154
+ style: {
155
+ ...context.floatingStyles
156
+ },
157
+ ...context.getFloatingProps(),
158
+ children: /*#__PURE__*/_jsx(TransitionInitialMount, {
159
+ appearClassName: getClassName('bpk-popover--appear'),
160
+ appearActiveClassName: getClassName('bpk-popover--appear-active'),
161
+ transitionTimeout: 200,
162
+ children: /*#__PURE__*/_jsxs("section", {
163
+ id: id,
164
+ tabIndex: -1,
165
+ role: "dialog",
166
+ "aria-labelledby": labelId,
167
+ className: classNames,
168
+ ...rest,
169
+ children: [showArrow && /*#__PURE__*/_jsx(FloatingArrow, {
170
+ ref: arrowRef,
171
+ context: floatingContext,
172
+ id: ARROW_ID
173
+ // eslint-disable-next-line @skyscanner/rules/forbid-component-props
174
+ ,
175
+ className: getClassName('bpk-popover__arrow'),
176
+ role: "presentation",
177
+ stroke: surfaceHighlightDay,
178
+ strokeWidth: 0.0625
179
+ }), labelAsTitle ? /*#__PURE__*/_jsxs("header", {
180
+ className: getClassName('bpk-popover__header'),
181
+ children: [/*#__PURE__*/_jsx(BpkText, {
182
+ tagName: "h2",
183
+ id: labelId,
184
+ textStyle: TEXT_STYLES.label1,
185
+ children: label
186
+ }), "\xA0", closeButtonIcon ? /*#__PURE__*/_jsx(BpkCloseButton, {
187
+ label: closeButtonText,
188
+ onClick: () => {
189
+ bindEventSource(EVENT_SOURCES.CLOSE_BUTTON, onClose);
190
+ setIsOpenState(false);
191
+ },
192
+ ...closeButtonProps
193
+ }) : /*#__PURE__*/_jsx(BpkButtonLink, {
194
+ onClick: () => {
195
+ bindEventSource(EVENT_SOURCES.CLOSE_LINK, onClose);
196
+ setIsOpenState(false);
197
+ },
198
+ ...closeButtonProps,
199
+ children: closeButtonText
200
+ })]
201
+ }) : /*#__PURE__*/_jsx("span", {
202
+ id: labelId,
203
+ className: getClassName('bpk-popover__label'),
204
+ children: label
205
+ }), /*#__PURE__*/_jsx("div", {
206
+ className: bodyClassNames,
207
+ children: children
208
+ }), !labelAsTitle && /*#__PURE__*/_jsx("footer", {
209
+ className: getClassName('bpk-popover__footer'),
210
+ children: /*#__PURE__*/_jsx(BpkButtonLink, {
211
+ onClick: () => {
212
+ bindEventSource(EVENT_SOURCES.CLOSE_LINK, onClose);
213
+ setIsOpenState(false);
214
+ },
215
+ ...closeButtonProps,
216
+ children: closeButtonText
217
+ })
218
+ })]
219
+ })
220
+ })
221
+ })
222
+ })
223
+ });
224
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyscanner/backpack-web",
3
- "version": "34.0.0-premajor.1",
3
+ "version": "34.0.0-premajor.2",
4
4
  "description": "Backpack Design System web library",
5
5
  "repository": {
6
6
  "type": "git",