playbook_ui 11.19.0.pre.typeahead1 → 11.19.0
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleContent.tsx +8 -8
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +10 -3
- data/app/pb_kits/playbook/pb_list/_list.tsx +97 -0
- data/app/pb_kits/playbook/pb_list/{_list_item.jsx → _list_item.tsx} +4 -6
- data/app/pb_kits/playbook/pb_popover/_popover.tsx +239 -0
- data/app/pb_kits/playbook/pb_popover/{index.js → index.ts} +10 -6
- data/app/pb_kits/playbook/pb_popover/popover.test.js +222 -0
- data/lib/playbook/version.rb +1 -1
- metadata +9 -8
- data/app/pb_kits/playbook/pb_list/_list.jsx +0 -98
- data/app/pb_kits/playbook/pb_popover/_popover.jsx +0 -227
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb389dc6dd09b729a058710f9dbaffccf1c70f4994dabad0e8c877fdfb15160a
|
4
|
+
data.tar.gz: 5f8d2f82abeccdb16d5a8e0896db8c9c701b524f1fdfd86ac0cdb3e296dc5b16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ef7df4f5c65d61d144d0b552b11c7205451cb77d50dff97c181af2175de03374ee98d18505c0765b219b217caef55f5714425585a27f7d0d2597efa50a1af21
|
7
|
+
data.tar.gz: '0068b2d612e89e7932399e089b1478faac10bd3a710e29ef4f555b6e57060236ff0a4f346c15ae61bd08e2a925b136174901803b55a066d1c1d6397b1379f1ee'
|
@@ -23,15 +23,15 @@ const CollapsibleContent = ({
|
|
23
23
|
const contentSpacing = globalProps(props, { padding })
|
24
24
|
|
25
25
|
return (
|
26
|
-
<
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
>
|
26
|
+
<AnimateHeight
|
27
|
+
duration={400}
|
28
|
+
height={context.collapsed ? 0 : 'auto'}
|
29
|
+
id="bottom-section"
|
30
|
+
>
|
31
|
+
<div className={classnames(contentCSS, className, contentSpacing)}>
|
32
32
|
{children}
|
33
|
-
</
|
34
|
-
</
|
33
|
+
</div>
|
34
|
+
</AnimateHeight>
|
35
35
|
)
|
36
36
|
}
|
37
37
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React, { useEffect, useCallback, useRef } from 'react'
|
2
|
-
import { useDropzone } from 'react-dropzone'
|
2
|
+
import { useDropzone, DropzoneInputProps, DropzoneRootProps } from 'react-dropzone'
|
3
3
|
import classnames from 'classnames'
|
4
4
|
|
5
5
|
import { buildCss, buildDataProps, noop } from '../utilities/props'
|
@@ -38,13 +38,20 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => {
|
|
38
38
|
onFilesAccepted(files)
|
39
39
|
}, [onFilesAccepted])
|
40
40
|
|
41
|
-
|
41
|
+
type DropZoneProps = {
|
42
|
+
getRootProps: () => DropzoneRootProps & any;
|
43
|
+
getInputProps: () => DropzoneInputProps & any;
|
44
|
+
isDragActive: boolean;
|
45
|
+
rejectedFiles: File[];
|
46
|
+
}
|
47
|
+
|
48
|
+
const { getRootProps, getInputProps, isDragActive, rejectedFiles }: DropZoneProps = useDropzone({
|
42
49
|
accept,
|
43
50
|
maxSize,
|
44
51
|
onDrop,
|
45
52
|
})
|
46
53
|
|
47
|
-
const prevRejected
|
54
|
+
const prevRejected = useRef<File[] | null>(null);
|
48
55
|
|
49
56
|
const maxFileSizeText = `Max file size is ${getFormattedFileSize(maxSize)}.`
|
50
57
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
|
4
|
+
import { globalProps } from "../utilities/globalProps";
|
5
|
+
|
6
|
+
type ListProps = {
|
7
|
+
aria?: { [key: string]: string };
|
8
|
+
borderless?: boolean;
|
9
|
+
className?: string;
|
10
|
+
children: React.ReactNode[] | React.ReactNode;
|
11
|
+
dark?: boolean;
|
12
|
+
data?: object;
|
13
|
+
id?: string;
|
14
|
+
layout: "" | "left" | "right";
|
15
|
+
ordered?: boolean;
|
16
|
+
role?: string;
|
17
|
+
tabIndex?: number;
|
18
|
+
text?: string;
|
19
|
+
size?: string;
|
20
|
+
variant?: string;
|
21
|
+
xpadding: boolean;
|
22
|
+
};
|
23
|
+
|
24
|
+
const List = (props: ListProps) => {
|
25
|
+
const {
|
26
|
+
aria = {},
|
27
|
+
borderless = false,
|
28
|
+
children,
|
29
|
+
className,
|
30
|
+
dark = false,
|
31
|
+
data = {},
|
32
|
+
id,
|
33
|
+
layout = "",
|
34
|
+
ordered = false,
|
35
|
+
role,
|
36
|
+
size = "",
|
37
|
+
tabIndex,
|
38
|
+
xpadding = false,
|
39
|
+
variant,
|
40
|
+
text,
|
41
|
+
} = props;
|
42
|
+
|
43
|
+
const layoutClass: { [key: string]: string } = {
|
44
|
+
left: "layout_left",
|
45
|
+
right: "layout_right",
|
46
|
+
default: "",
|
47
|
+
};
|
48
|
+
|
49
|
+
const childrenWithProps = React.Children.map(
|
50
|
+
children,
|
51
|
+
(child: React.ReactElement) => {
|
52
|
+
return React.cloneElement(child, { text, variant });
|
53
|
+
}
|
54
|
+
);
|
55
|
+
const ariaProps = buildAriaProps(aria);
|
56
|
+
const dataProps = buildDataProps(data);
|
57
|
+
const classes = classnames(
|
58
|
+
buildCss("pb_list_kit", layoutClass[layout], size, {
|
59
|
+
dark: dark,
|
60
|
+
borderless: borderless,
|
61
|
+
ordered: ordered,
|
62
|
+
xpadding: xpadding,
|
63
|
+
}),
|
64
|
+
globalProps(props),
|
65
|
+
className
|
66
|
+
);
|
67
|
+
|
68
|
+
return (
|
69
|
+
<div className={classes}>
|
70
|
+
{ordered ? (
|
71
|
+
<ol
|
72
|
+
{...ariaProps}
|
73
|
+
{...dataProps}
|
74
|
+
className={className}
|
75
|
+
id={id}
|
76
|
+
role={role}
|
77
|
+
tabIndex={tabIndex}
|
78
|
+
>
|
79
|
+
{childrenWithProps}
|
80
|
+
</ol>
|
81
|
+
) : (
|
82
|
+
<ul
|
83
|
+
{...ariaProps}
|
84
|
+
{...dataProps}
|
85
|
+
className={className}
|
86
|
+
id={id}
|
87
|
+
role={role}
|
88
|
+
tabIndex={tabIndex}
|
89
|
+
>
|
90
|
+
{childrenWithProps}
|
91
|
+
</ul>
|
92
|
+
)}
|
93
|
+
</div>
|
94
|
+
);
|
95
|
+
};
|
96
|
+
|
97
|
+
export default List;
|
@@ -1,17 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
import React, { type Node } from 'react'
|
1
|
+
import React from 'react'
|
4
2
|
import classnames from 'classnames'
|
5
3
|
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
6
4
|
import { globalProps } from '../utilities/globalProps'
|
7
5
|
|
8
6
|
type ListItemProps = {
|
9
|
-
aria?:
|
10
|
-
children:
|
7
|
+
aria?: { [key: string]: string },
|
8
|
+
children: React.ReactNode[] | React.ReactNode,
|
11
9
|
className?: string,
|
12
10
|
data?: object,
|
13
11
|
id?: string,
|
14
|
-
tabIndex?:
|
12
|
+
tabIndex?: number,
|
15
13
|
}
|
16
14
|
|
17
15
|
const ListItem = (props: ListItemProps) => {
|
@@ -0,0 +1,239 @@
|
|
1
|
+
import React, { useEffect } from "react";
|
2
|
+
import ReactDOM from "react-dom";
|
3
|
+
|
4
|
+
import {
|
5
|
+
Popper,
|
6
|
+
Manager as PopperManager,
|
7
|
+
Modifier,
|
8
|
+
PopperProps,
|
9
|
+
Reference as PopperReference,
|
10
|
+
} from "react-popper";
|
11
|
+
|
12
|
+
import {
|
13
|
+
buildAriaProps,
|
14
|
+
buildCss,
|
15
|
+
buildDataProps,
|
16
|
+
noop,
|
17
|
+
} from "../utilities/props";
|
18
|
+
|
19
|
+
import classnames from "classnames";
|
20
|
+
import { globalProps, GlobalProps } from "../utilities/globalProps";
|
21
|
+
|
22
|
+
type PbPopoverProps = {
|
23
|
+
aria?: { [key: string]: string };
|
24
|
+
className?: string;
|
25
|
+
closeOnClick?: "outside" | "inside" | "any";
|
26
|
+
data?: object;
|
27
|
+
id?: string;
|
28
|
+
offset?: boolean;
|
29
|
+
reference: PopperReference & any;
|
30
|
+
show?: boolean;
|
31
|
+
shouldClosePopover?: (arg0: boolean) => boolean | boolean;
|
32
|
+
} & GlobalProps &
|
33
|
+
PopperProps<any>;
|
34
|
+
|
35
|
+
// Prop enabled default modifiers here
|
36
|
+
// https://popper.js.org/docs/v2/modifiers
|
37
|
+
|
38
|
+
const POPOVER_MODIFIERS = {
|
39
|
+
offset: {
|
40
|
+
//https://popper.js.org/docs/v2/modifiers/offset/
|
41
|
+
enabled: true,
|
42
|
+
name: "offset",
|
43
|
+
options: {
|
44
|
+
offset: [0, 20],
|
45
|
+
},
|
46
|
+
phase: "main",
|
47
|
+
},
|
48
|
+
};
|
49
|
+
|
50
|
+
const popoverModifiers = ({
|
51
|
+
modifiers,
|
52
|
+
offset,
|
53
|
+
}: {
|
54
|
+
modifiers: Modifier<any> & any;
|
55
|
+
offset: {};
|
56
|
+
}) => {
|
57
|
+
return offset ? modifiers.concat([POPOVER_MODIFIERS.offset]) : modifiers;
|
58
|
+
};
|
59
|
+
|
60
|
+
const Popover = (props: PbPopoverProps) => {
|
61
|
+
const {
|
62
|
+
aria = {},
|
63
|
+
className,
|
64
|
+
children,
|
65
|
+
data = {},
|
66
|
+
id,
|
67
|
+
modifiers,
|
68
|
+
offset,
|
69
|
+
placement,
|
70
|
+
referenceElement,
|
71
|
+
zIndex,
|
72
|
+
maxHeight,
|
73
|
+
maxWidth,
|
74
|
+
minHeight,
|
75
|
+
minWidth,
|
76
|
+
} = props;
|
77
|
+
|
78
|
+
const popoverSpacing =
|
79
|
+
globalProps(props).includes("dark") || !globalProps(props)
|
80
|
+
? "p_sm"
|
81
|
+
: globalProps(props);
|
82
|
+
const overflowHandling = maxHeight || maxWidth ? "overflow_handling" : "";
|
83
|
+
const zIndexStyle = zIndex ? { zIndex: zIndex } : {};
|
84
|
+
const widthHeightStyles = () => {
|
85
|
+
return Object.assign(
|
86
|
+
{},
|
87
|
+
maxHeight ? { maxHeight: maxHeight } : {},
|
88
|
+
maxWidth ? { maxWidth: maxWidth } : {},
|
89
|
+
minHeight ? { minHeight: minHeight } : {},
|
90
|
+
minWidth ? { minWidth: minWidth } : {}
|
91
|
+
);
|
92
|
+
};
|
93
|
+
const ariaProps = buildAriaProps(aria);
|
94
|
+
const dataProps = buildDataProps(data);
|
95
|
+
const classes = classnames(
|
96
|
+
buildCss("pb_popover_kit"),
|
97
|
+
globalProps(props),
|
98
|
+
className
|
99
|
+
);
|
100
|
+
|
101
|
+
return (
|
102
|
+
<Popper
|
103
|
+
modifiers={popoverModifiers({ modifiers, offset })}
|
104
|
+
placement={placement}
|
105
|
+
referenceElement={referenceElement}
|
106
|
+
>
|
107
|
+
{({ placement, ref, style }) => {
|
108
|
+
return (
|
109
|
+
<div
|
110
|
+
{...ariaProps}
|
111
|
+
{...dataProps}
|
112
|
+
className={classes}
|
113
|
+
data-placement={placement}
|
114
|
+
id={id}
|
115
|
+
ref={ref}
|
116
|
+
style={Object.assign({}, style, zIndexStyle)}
|
117
|
+
>
|
118
|
+
<div
|
119
|
+
className={classnames(`${buildCss("pb_popover_tooltip")} show`)}
|
120
|
+
>
|
121
|
+
<div
|
122
|
+
className={classnames(
|
123
|
+
"pb_popover_body",
|
124
|
+
popoverSpacing,
|
125
|
+
overflowHandling
|
126
|
+
)}
|
127
|
+
style={widthHeightStyles()}
|
128
|
+
>
|
129
|
+
{children}
|
130
|
+
</div>
|
131
|
+
</div>
|
132
|
+
</div>
|
133
|
+
);
|
134
|
+
}}
|
135
|
+
</Popper>
|
136
|
+
);
|
137
|
+
};
|
138
|
+
|
139
|
+
const PbReactPopover = (props: PbPopoverProps) => {
|
140
|
+
const {
|
141
|
+
className,
|
142
|
+
children,
|
143
|
+
modifiers = [],
|
144
|
+
offset = false,
|
145
|
+
placement = "left",
|
146
|
+
portal = "body",
|
147
|
+
reference,
|
148
|
+
referenceElement,
|
149
|
+
show = false,
|
150
|
+
usePortal = true,
|
151
|
+
zIndex,
|
152
|
+
maxHeight,
|
153
|
+
maxWidth,
|
154
|
+
minHeight,
|
155
|
+
minWidth,
|
156
|
+
} = props;
|
157
|
+
|
158
|
+
useEffect(() => {
|
159
|
+
const { closeOnClick, shouldClosePopover = noop } = props;
|
160
|
+
|
161
|
+
if (!closeOnClick) return;
|
162
|
+
|
163
|
+
document.body.addEventListener(
|
164
|
+
"click",
|
165
|
+
({ target }) => {
|
166
|
+
const targetIsPopover =
|
167
|
+
(target as HTMLElement).closest("[class^=pb_popover_tooltip]") !==
|
168
|
+
null;
|
169
|
+
const targetIsReference =
|
170
|
+
(target as HTMLElement).closest(".pb_popover_reference_wrapper") !==
|
171
|
+
null;
|
172
|
+
|
173
|
+
switch (closeOnClick) {
|
174
|
+
case "outside":
|
175
|
+
if (!targetIsPopover || targetIsReference) {
|
176
|
+
shouldClosePopover(true);
|
177
|
+
}
|
178
|
+
break;
|
179
|
+
case "inside":
|
180
|
+
if (targetIsPopover || targetIsReference) {
|
181
|
+
shouldClosePopover(true);
|
182
|
+
}
|
183
|
+
break;
|
184
|
+
case "any":
|
185
|
+
shouldClosePopover(true);
|
186
|
+
break;
|
187
|
+
}
|
188
|
+
},
|
189
|
+
{ capture: true }
|
190
|
+
);
|
191
|
+
}, []);
|
192
|
+
|
193
|
+
const popoverComponent = (
|
194
|
+
<Popover
|
195
|
+
className={className}
|
196
|
+
maxHeight={maxHeight}
|
197
|
+
maxWidth={maxWidth}
|
198
|
+
minHeight={minHeight}
|
199
|
+
minWidth={minWidth}
|
200
|
+
modifiers={modifiers}
|
201
|
+
offset={offset}
|
202
|
+
placement={placement}
|
203
|
+
referenceElement={referenceElement}
|
204
|
+
zIndex={zIndex}
|
205
|
+
{...props}
|
206
|
+
>
|
207
|
+
{children}
|
208
|
+
</Popover>
|
209
|
+
);
|
210
|
+
|
211
|
+
return (
|
212
|
+
<PopperManager>
|
213
|
+
<>
|
214
|
+
{reference && !referenceElement && (
|
215
|
+
<PopperReference>
|
216
|
+
{({ ref }) => (
|
217
|
+
<span className="pb_popover_reference_wrapper" ref={ref}>
|
218
|
+
<reference.type {...reference.props} />
|
219
|
+
</span>
|
220
|
+
)}
|
221
|
+
</PopperReference>
|
222
|
+
)}
|
223
|
+
{show &&
|
224
|
+
(usePortal ? (
|
225
|
+
<>
|
226
|
+
{ReactDOM.createPortal(
|
227
|
+
popoverComponent,
|
228
|
+
document.querySelector(portal)
|
229
|
+
)}
|
230
|
+
</>
|
231
|
+
) : (
|
232
|
+
{ popoverComponent }
|
233
|
+
))}
|
234
|
+
</>
|
235
|
+
</PopperManager>
|
236
|
+
);
|
237
|
+
};
|
238
|
+
|
239
|
+
export default PbReactPopover;
|
@@ -1,9 +1,13 @@
|
|
1
1
|
import PbEnhancedElement from '../pb_enhanced_element'
|
2
|
-
import { createPopper } from '@popperjs/core'
|
2
|
+
import { createPopper, Instance, Placement } from '@popperjs/core'
|
3
3
|
|
4
4
|
const POPOVER_OFFSET_Y = [0, 20]
|
5
5
|
|
6
6
|
export default class PbPopover extends PbEnhancedElement {
|
7
|
+
popper: Instance
|
8
|
+
_triggerElement: HTMLElement
|
9
|
+
_tooltip: HTMLElement
|
10
|
+
element: HTMLElement
|
7
11
|
static get selector() {
|
8
12
|
return '[data-pb-popover-kit]'
|
9
13
|
}
|
@@ -14,8 +18,8 @@ export default class PbPopover extends PbEnhancedElement {
|
|
14
18
|
|
15
19
|
connect() {
|
16
20
|
this.moveTooltip()
|
17
|
-
this.popper = createPopper(this.triggerElement, this.tooltip, {
|
18
|
-
placement: this.position,
|
21
|
+
this.popper = createPopper (this.triggerElement, this.tooltip, {
|
22
|
+
placement: this.position as Placement,
|
19
23
|
strategy: 'fixed',
|
20
24
|
modifiers: [
|
21
25
|
{
|
@@ -27,7 +31,7 @@ export default class PbPopover extends PbEnhancedElement {
|
|
27
31
|
],
|
28
32
|
})
|
29
33
|
|
30
|
-
this.triggerElement.addEventListener('click', (event) => {
|
34
|
+
this.triggerElement.addEventListener('click', (event: Event) => {
|
31
35
|
event.preventDefault()
|
32
36
|
event.stopPropagation()
|
33
37
|
|
@@ -43,8 +47,8 @@ export default class PbPopover extends PbEnhancedElement {
|
|
43
47
|
}
|
44
48
|
|
45
49
|
checkCloseTooltip() {
|
46
|
-
document.querySelector('body').addEventListener('click', ({ target }) => {
|
47
|
-
const isTooltipElement = target.closest(`#${this.tooltipId}`) !== null
|
50
|
+
document.querySelector('body').addEventListener('click', ({ target } ) => {
|
51
|
+
const isTooltipElement = (target as HTMLElement).closest(`#${this.tooltipId}`) !== null
|
48
52
|
|
49
53
|
switch (this.closeOnClick) {
|
50
54
|
case 'any':
|
@@ -0,0 +1,222 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { render, screen, fireEvent } from "../utilities/test-utils";
|
3
|
+
import { Button, PbReactPopover } from "..";
|
4
|
+
|
5
|
+
const testId = "popover-kit";
|
6
|
+
|
7
|
+
//Test default popover
|
8
|
+
const PopoverTest = () => {
|
9
|
+
const [mockState, setMockState] = React.useState(false)
|
10
|
+
const togglePopover = () => {
|
11
|
+
setMockState(!mockState)
|
12
|
+
}
|
13
|
+
|
14
|
+
const popoverReference = (
|
15
|
+
<Button onClick={togglePopover}
|
16
|
+
text="Click Me"
|
17
|
+
/>
|
18
|
+
);
|
19
|
+
return (
|
20
|
+
<PbReactPopover
|
21
|
+
offset
|
22
|
+
reference={popoverReference}
|
23
|
+
show={mockState}
|
24
|
+
>
|
25
|
+
{"Click Anywhere"}
|
26
|
+
</PbReactPopover>
|
27
|
+
)
|
28
|
+
};
|
29
|
+
//Test popover with z-index
|
30
|
+
const PopoverTestZIndex = () => {
|
31
|
+
const [mockState, setMockState] = React.useState(false)
|
32
|
+
const togglePopover = () => {
|
33
|
+
setMockState(!mockState)
|
34
|
+
}
|
35
|
+
|
36
|
+
const popoverReference = (
|
37
|
+
<Button onClick={togglePopover}
|
38
|
+
text="Click Me"
|
39
|
+
/>
|
40
|
+
);
|
41
|
+
return (
|
42
|
+
<PbReactPopover
|
43
|
+
offset
|
44
|
+
reference={popoverReference}
|
45
|
+
show={mockState}
|
46
|
+
zIndex={3}
|
47
|
+
>
|
48
|
+
{"Click Anywhere"}
|
49
|
+
</PbReactPopover>
|
50
|
+
)
|
51
|
+
};
|
52
|
+
|
53
|
+
//Test popover with max-height and max-width
|
54
|
+
const PopoverTestHeight = () => {
|
55
|
+
const [mockState, setMockState] = React.useState(false)
|
56
|
+
const togglePopover = () => {
|
57
|
+
setMockState(!mockState)
|
58
|
+
}
|
59
|
+
|
60
|
+
const popoverReference = (
|
61
|
+
<Button onClick={togglePopover}
|
62
|
+
text="Click Me"
|
63
|
+
/>
|
64
|
+
);
|
65
|
+
return (
|
66
|
+
<PbReactPopover
|
67
|
+
maxHeight="150px"
|
68
|
+
maxWidth="240px"
|
69
|
+
offset
|
70
|
+
reference={popoverReference}
|
71
|
+
show={mockState}
|
72
|
+
>
|
73
|
+
{"Click Anywhere"}
|
74
|
+
</PbReactPopover>
|
75
|
+
)
|
76
|
+
};
|
77
|
+
|
78
|
+
//Test Popover with click to close 'anywhere'
|
79
|
+
const PopoverTestClicktoClose = () => {
|
80
|
+
const [mockState, setMockState] = React.useState(false)
|
81
|
+
const togglePopover = () => {
|
82
|
+
setMockState(!mockState)
|
83
|
+
}
|
84
|
+
const handleShouldClosePopover = (shouldClosePopover) => {
|
85
|
+
setMockState(!shouldClosePopover)
|
86
|
+
}
|
87
|
+
|
88
|
+
const popoverReference = (
|
89
|
+
<Button onClick={togglePopover}
|
90
|
+
text="Click Me"
|
91
|
+
/>
|
92
|
+
);
|
93
|
+
return (
|
94
|
+
<PbReactPopover
|
95
|
+
closeOnClick="any"
|
96
|
+
offset
|
97
|
+
reference={popoverReference}
|
98
|
+
shouldClosePopover={handleShouldClosePopover}
|
99
|
+
show={mockState}
|
100
|
+
>
|
101
|
+
{"Click Anywhere"}
|
102
|
+
</PbReactPopover>
|
103
|
+
)
|
104
|
+
};
|
105
|
+
|
106
|
+
//Test Popover with click to close 'inside'
|
107
|
+
const PopoverTestClicktoClose2 = () => {
|
108
|
+
const [mockState, setMockState] = React.useState(false)
|
109
|
+
const togglePopover = () => {
|
110
|
+
setMockState(!mockState)
|
111
|
+
}
|
112
|
+
const handleShouldClosePopover = (shouldClosePopover) => {
|
113
|
+
setMockState(!shouldClosePopover)
|
114
|
+
}
|
115
|
+
|
116
|
+
const popoverReference = (
|
117
|
+
<Button onClick={togglePopover}
|
118
|
+
text="Click Me"
|
119
|
+
/>
|
120
|
+
);
|
121
|
+
return (
|
122
|
+
<PbReactPopover
|
123
|
+
closeOnClick="inside"
|
124
|
+
offset
|
125
|
+
reference={popoverReference}
|
126
|
+
shouldClosePopover={handleShouldClosePopover}
|
127
|
+
show={mockState}
|
128
|
+
>
|
129
|
+
{"Click Inside"}
|
130
|
+
</PbReactPopover>
|
131
|
+
)
|
132
|
+
};
|
133
|
+
|
134
|
+
//Test Popover with click to close 'outside'
|
135
|
+
const PopoverTestClicktoClose3 = () => {
|
136
|
+
const [mockState, setMockState] = React.useState(false)
|
137
|
+
const togglePopover = () => {
|
138
|
+
setMockState(!mockState)
|
139
|
+
}
|
140
|
+
const handleShouldClosePopover = (shouldClosePopover) => {
|
141
|
+
setMockState(!shouldClosePopover)
|
142
|
+
}
|
143
|
+
|
144
|
+
const popoverReference = (
|
145
|
+
<Button onClick={togglePopover}
|
146
|
+
text="Click Me"
|
147
|
+
/>
|
148
|
+
);
|
149
|
+
return (
|
150
|
+
<PbReactPopover
|
151
|
+
closeOnClick="outside"
|
152
|
+
offset
|
153
|
+
reference={popoverReference}
|
154
|
+
shouldClosePopover={handleShouldClosePopover}
|
155
|
+
show={mockState}
|
156
|
+
>
|
157
|
+
{"Click Outside"}
|
158
|
+
</PbReactPopover>
|
159
|
+
)
|
160
|
+
};
|
161
|
+
|
162
|
+
|
163
|
+
test("renders Popover", () => {
|
164
|
+
render(<PopoverTest data={{ testid: testId}}/>)
|
165
|
+
const btn = screen.getByText(/click me/i)
|
166
|
+
fireEvent.click(btn);
|
167
|
+
const kit = screen.getByText("Click Anywhere");
|
168
|
+
expect(kit).toBeInTheDocument();
|
169
|
+
});
|
170
|
+
|
171
|
+
test("renders Popover with z index", () => {
|
172
|
+
render(<PopoverTestZIndex data={{ testid: testId}}/>)
|
173
|
+
const btn = screen.getByText(/click me/i)
|
174
|
+
fireEvent.click(btn);
|
175
|
+
const kit = screen.getByText("Click Anywhere");
|
176
|
+
expect(kit).toHaveClass("pb_popover_body z_index_3");
|
177
|
+
});
|
178
|
+
|
179
|
+
test("renders Popover with max height and max width", () => {
|
180
|
+
render(<PopoverTestHeight data={{ testid: testId}}/>)
|
181
|
+
const btn = screen.getByText(/click me/i)
|
182
|
+
fireEvent.click(btn);
|
183
|
+
const kit = screen.getByText("Click Anywhere");
|
184
|
+
expect(kit).toHaveClass("pb_popover_body max_width_240px overflow_handling");
|
185
|
+
});
|
186
|
+
|
187
|
+
test("closes Popover on click anywhere", () => {
|
188
|
+
render(<PopoverTestClicktoClose data={{ testid: testId}}/>)
|
189
|
+
const btn = screen.getByText(/click me/i)
|
190
|
+
fireEvent.click(btn);
|
191
|
+
const kit = screen.getByText("Click Anywhere");
|
192
|
+
expect(kit).toBeInTheDocument();
|
193
|
+
fireEvent.click(kit);
|
194
|
+
|
195
|
+
expect(kit).not.toBeInTheDocument();
|
196
|
+
|
197
|
+
});
|
198
|
+
|
199
|
+
test("closes Popover on click inside", () => {
|
200
|
+
render(<PopoverTestClicktoClose2 data={{ testid: testId}}/>)
|
201
|
+
const btn = screen.getByText(/click me/i)
|
202
|
+
fireEvent.click(btn);
|
203
|
+
const kit = screen.getByText("Click Inside");
|
204
|
+
expect(kit).toBeInTheDocument();
|
205
|
+
fireEvent.click(kit);
|
206
|
+
|
207
|
+
expect(kit).not.toBeInTheDocument();
|
208
|
+
|
209
|
+
});
|
210
|
+
|
211
|
+
test("closes Popover on click outside", () => {
|
212
|
+
render(<PopoverTestClicktoClose3 data={{ testid: testId}}/>)
|
213
|
+
const btn = screen.getByText(/click me/i)
|
214
|
+
fireEvent.click(btn);
|
215
|
+
const kit = screen.getByText("Click Outside");
|
216
|
+
expect(kit).toBeInTheDocument();
|
217
|
+
fireEvent.click(kit);
|
218
|
+
expect(kit).toBeInTheDocument();
|
219
|
+
fireEvent.click(btn);
|
220
|
+
expect(kit).not.toBeInTheDocument();
|
221
|
+
|
222
|
+
});
|
data/lib/playbook/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playbook_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.19.0
|
4
|
+
version: 11.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Power UX
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-01-
|
12
|
+
date: 2023-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -1336,9 +1336,9 @@ files:
|
|
1336
1336
|
- app/pb_kits/playbook/pb_line_graph/lineGraphSettings.js
|
1337
1337
|
- app/pb_kits/playbook/pb_line_graph/line_graph.html.erb
|
1338
1338
|
- app/pb_kits/playbook/pb_line_graph/line_graph.rb
|
1339
|
-
- app/pb_kits/playbook/pb_list/_list.jsx
|
1340
1339
|
- app/pb_kits/playbook/pb_list/_list.scss
|
1341
|
-
- app/pb_kits/playbook/pb_list/
|
1340
|
+
- app/pb_kits/playbook/pb_list/_list.tsx
|
1341
|
+
- app/pb_kits/playbook/pb_list/_list_item.tsx
|
1342
1342
|
- app/pb_kits/playbook/pb_list/_list_mixin.scss
|
1343
1343
|
- app/pb_kits/playbook/pb_list/docs/_description.md
|
1344
1344
|
- app/pb_kits/playbook/pb_list/docs/_list_borderless.html.erb
|
@@ -1533,8 +1533,8 @@ files:
|
|
1533
1533
|
- app/pb_kits/playbook/pb_pill/docs/index.js
|
1534
1534
|
- app/pb_kits/playbook/pb_pill/pill.html.erb
|
1535
1535
|
- app/pb_kits/playbook/pb_pill/pill.rb
|
1536
|
-
- app/pb_kits/playbook/pb_popover/_popover.jsx
|
1537
1536
|
- app/pb_kits/playbook/pb_popover/_popover.scss
|
1537
|
+
- app/pb_kits/playbook/pb_popover/_popover.tsx
|
1538
1538
|
- app/pb_kits/playbook/pb_popover/docs/_description.md
|
1539
1539
|
- app/pb_kits/playbook/pb_popover/docs/_popover_close.html.erb
|
1540
1540
|
- app/pb_kits/playbook/pb_popover/docs/_popover_close.jsx
|
@@ -1549,9 +1549,10 @@ files:
|
|
1549
1549
|
- app/pb_kits/playbook/pb_popover/docs/_popover_z_index.jsx
|
1550
1550
|
- app/pb_kits/playbook/pb_popover/docs/example.yml
|
1551
1551
|
- app/pb_kits/playbook/pb_popover/docs/index.js
|
1552
|
-
- app/pb_kits/playbook/pb_popover/index.
|
1552
|
+
- app/pb_kits/playbook/pb_popover/index.ts
|
1553
1553
|
- app/pb_kits/playbook/pb_popover/popover.html.erb
|
1554
1554
|
- app/pb_kits/playbook/pb_popover/popover.rb
|
1555
|
+
- app/pb_kits/playbook/pb_popover/popover.test.js
|
1555
1556
|
- app/pb_kits/playbook/pb_progress_pills/_progress_pills.jsx
|
1556
1557
|
- app/pb_kits/playbook/pb_progress_pills/_progress_pills.scss
|
1557
1558
|
- app/pb_kits/playbook/pb_progress_pills/docs/_description.md
|
@@ -2363,9 +2364,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
2363
2364
|
version: '0'
|
2364
2365
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
2365
2366
|
requirements:
|
2366
|
-
- - "
|
2367
|
+
- - ">="
|
2367
2368
|
- !ruby/object:Gem::Version
|
2368
|
-
version:
|
2369
|
+
version: '0'
|
2369
2370
|
requirements: []
|
2370
2371
|
rubygems_version: 3.3.7
|
2371
2372
|
signing_key:
|
@@ -1,98 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
|
-
import React, { type Node } from 'react'
|
4
|
-
import classnames from 'classnames'
|
5
|
-
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
6
|
-
import { globalProps } from '../utilities/globalProps'
|
7
|
-
|
8
|
-
type ListProps = {
|
9
|
-
aria?: object,
|
10
|
-
borderless: boolean,
|
11
|
-
className?: string,
|
12
|
-
children: array<Node> | Node,
|
13
|
-
dark: boolean,
|
14
|
-
data?: object,
|
15
|
-
id?: string,
|
16
|
-
layout: "" | "left" | "right",
|
17
|
-
ordered: boolean,
|
18
|
-
role?: string,
|
19
|
-
tabIndex?: string,
|
20
|
-
text?: string,
|
21
|
-
size?: string,
|
22
|
-
variant?: string,
|
23
|
-
xpadding: boolean,
|
24
|
-
}
|
25
|
-
|
26
|
-
const List = (props: ListProps) => {
|
27
|
-
const {
|
28
|
-
aria = {},
|
29
|
-
borderless = false,
|
30
|
-
children,
|
31
|
-
className,
|
32
|
-
dark = false,
|
33
|
-
data = {},
|
34
|
-
id,
|
35
|
-
layout = '',
|
36
|
-
ordered = false,
|
37
|
-
role,
|
38
|
-
size = '',
|
39
|
-
tabIndex,
|
40
|
-
xpadding = false,
|
41
|
-
variant,
|
42
|
-
text,
|
43
|
-
} = props
|
44
|
-
|
45
|
-
const layoutClass = {
|
46
|
-
left: 'layout_left',
|
47
|
-
right: 'layout_right',
|
48
|
-
default: '',
|
49
|
-
}
|
50
|
-
|
51
|
-
const childrenWithProps = React.Children.map(children, (child) => {
|
52
|
-
return React.cloneElement(child, { text, variant })
|
53
|
-
})
|
54
|
-
const ariaProps = buildAriaProps(aria)
|
55
|
-
const dataProps = buildDataProps(data)
|
56
|
-
const classes = classnames(
|
57
|
-
buildCss('pb_list_kit', layoutClass[layout], size, {
|
58
|
-
dark: dark,
|
59
|
-
borderless: borderless,
|
60
|
-
ordered: ordered,
|
61
|
-
xpadding: xpadding,
|
62
|
-
}),
|
63
|
-
globalProps(props),
|
64
|
-
className
|
65
|
-
)
|
66
|
-
|
67
|
-
return (
|
68
|
-
<div
|
69
|
-
className={classes}
|
70
|
-
>
|
71
|
-
<If condition={ordered}>
|
72
|
-
<ol
|
73
|
-
{...ariaProps}
|
74
|
-
{...dataProps}
|
75
|
-
className={className}
|
76
|
-
id={id}
|
77
|
-
role={role}
|
78
|
-
tabIndex={tabIndex}
|
79
|
-
>
|
80
|
-
{childrenWithProps}
|
81
|
-
</ol>
|
82
|
-
<Else />
|
83
|
-
<ul
|
84
|
-
{...ariaProps}
|
85
|
-
{...dataProps}
|
86
|
-
className={className}
|
87
|
-
id={id}
|
88
|
-
role={role}
|
89
|
-
tabIndex={tabIndex}
|
90
|
-
>
|
91
|
-
{childrenWithProps}
|
92
|
-
</ul>
|
93
|
-
</If>
|
94
|
-
</div>
|
95
|
-
)
|
96
|
-
}
|
97
|
-
|
98
|
-
export default List
|
@@ -1,227 +0,0 @@
|
|
1
|
-
/* eslint-disable react/no-multi-comp */
|
2
|
-
// @flow
|
3
|
-
|
4
|
-
import React, {useEffect} from "react";
|
5
|
-
import ReactDOM from "react-dom";
|
6
|
-
|
7
|
-
import {
|
8
|
-
Popper,
|
9
|
-
Manager as PopperManager,
|
10
|
-
PopperProps,
|
11
|
-
Reference as PopperReference,
|
12
|
-
} from "react-popper";
|
13
|
-
|
14
|
-
import {
|
15
|
-
buildAriaProps,
|
16
|
-
buildCss,
|
17
|
-
buildDataProps,
|
18
|
-
noop,
|
19
|
-
} from "../utilities/props";
|
20
|
-
|
21
|
-
import classnames from "classnames";
|
22
|
-
import { globalProps } from "../utilities/globalProps";
|
23
|
-
|
24
|
-
type PbPopoverProps = {
|
25
|
-
aria?: object,
|
26
|
-
className?: string,
|
27
|
-
closeOnClick?: "outside" | "inside",
|
28
|
-
data?: object,
|
29
|
-
id?: String,
|
30
|
-
offset?: boolean,
|
31
|
-
reference: PopperReference,
|
32
|
-
show?: boolean,
|
33
|
-
shouldClosePopover?: () => boolean,
|
34
|
-
} & PopperProps;
|
35
|
-
|
36
|
-
// Prop enabled default modifiers here
|
37
|
-
// https://popper.js.org/docs/v2/modifiers
|
38
|
-
|
39
|
-
const POPOVER_MODIFIERS = {
|
40
|
-
offset: {
|
41
|
-
//https://popper.js.org/docs/v2/modifiers/offset/
|
42
|
-
enabled: true,
|
43
|
-
name: "offset",
|
44
|
-
options: {
|
45
|
-
offset: [0, 20],
|
46
|
-
},
|
47
|
-
phase: "main",
|
48
|
-
},
|
49
|
-
};
|
50
|
-
|
51
|
-
const popoverModifiers = ({ modifiers, offset }) => {
|
52
|
-
return offset ? modifiers.concat([POPOVER_MODIFIERS.offset]) : modifiers;
|
53
|
-
};
|
54
|
-
|
55
|
-
const Popover = (props: PbPopoverProps) => {
|
56
|
-
const {
|
57
|
-
aria = {},
|
58
|
-
className,
|
59
|
-
children,
|
60
|
-
data = {},
|
61
|
-
id,
|
62
|
-
modifiers,
|
63
|
-
offset,
|
64
|
-
placement,
|
65
|
-
referenceElement,
|
66
|
-
zIndex,
|
67
|
-
maxHeight,
|
68
|
-
maxWidth,
|
69
|
-
minHeight,
|
70
|
-
minWidth,
|
71
|
-
} = props;
|
72
|
-
|
73
|
-
const popoverSpacing =
|
74
|
-
globalProps(props).includes("dark") || !globalProps(props)
|
75
|
-
? "p_sm"
|
76
|
-
: globalProps(props);
|
77
|
-
const overflowHandling = maxHeight || maxWidth ? "overflow_handling" : "";
|
78
|
-
const zIndexStyle = zIndex ? { zIndex: zIndex } : {};
|
79
|
-
const widthHeightStyles = () => {
|
80
|
-
return Object.assign(
|
81
|
-
{},
|
82
|
-
maxHeight ? { maxHeight: maxHeight } : {},
|
83
|
-
maxWidth ? { maxWidth: maxWidth } : {},
|
84
|
-
minHeight ? { minHeight: minHeight } : {},
|
85
|
-
minWidth ? { minWidth: minWidth } : {}
|
86
|
-
);
|
87
|
-
};
|
88
|
-
const ariaProps = buildAriaProps(aria);
|
89
|
-
const dataProps = buildDataProps(data);
|
90
|
-
const classes = classnames(
|
91
|
-
buildCss("pb_popover_kit"),
|
92
|
-
globalProps(props),
|
93
|
-
className
|
94
|
-
);
|
95
|
-
|
96
|
-
return (
|
97
|
-
<Popper
|
98
|
-
modifiers={popoverModifiers({ modifiers, offset })}
|
99
|
-
placement={placement}
|
100
|
-
referenceElement={referenceElement}
|
101
|
-
>
|
102
|
-
{({ placement, ref, style }) => {
|
103
|
-
return (
|
104
|
-
<div
|
105
|
-
{...ariaProps}
|
106
|
-
{...dataProps}
|
107
|
-
className={classes}
|
108
|
-
data-placement={placement}
|
109
|
-
id={id}
|
110
|
-
ref={ref}
|
111
|
-
style={Object.assign({}, style, zIndexStyle)}
|
112
|
-
>
|
113
|
-
<div
|
114
|
-
className={classnames(`${buildCss("pb_popover_tooltip")} show`)}
|
115
|
-
>
|
116
|
-
<div
|
117
|
-
className={classnames(
|
118
|
-
"pb_popover_body",
|
119
|
-
popoverSpacing,
|
120
|
-
overflowHandling
|
121
|
-
)}
|
122
|
-
style={widthHeightStyles()}
|
123
|
-
>
|
124
|
-
{children}
|
125
|
-
</div>
|
126
|
-
</div>
|
127
|
-
</div>
|
128
|
-
);
|
129
|
-
}}
|
130
|
-
</Popper>
|
131
|
-
);
|
132
|
-
};
|
133
|
-
|
134
|
-
const PbReactPopover = (props: PbPopoverProps) => {
|
135
|
-
const {
|
136
|
-
className,
|
137
|
-
children,
|
138
|
-
modifiers = [],
|
139
|
-
offset = false,
|
140
|
-
placement = "left",
|
141
|
-
portal = "body",
|
142
|
-
reference,
|
143
|
-
referenceElement,
|
144
|
-
show = false,
|
145
|
-
usePortal = true,
|
146
|
-
zIndex,
|
147
|
-
maxHeight,
|
148
|
-
maxWidth,
|
149
|
-
minHeight,
|
150
|
-
minWidth,
|
151
|
-
} = props;
|
152
|
-
|
153
|
-
useEffect(() => {
|
154
|
-
const { closeOnClick, shouldClosePopover = noop } = props
|
155
|
-
|
156
|
-
if (!closeOnClick) return
|
157
|
-
|
158
|
-
document.body.addEventListener('click', ({ target }) => {
|
159
|
-
const targetIsPopover =
|
160
|
-
target.closest('[class^=pb_popover_tooltip]') !== null
|
161
|
-
const targetIsReference =
|
162
|
-
target.closest('.pb_popover_reference_wrapper') !== null
|
163
|
-
|
164
|
-
switch (closeOnClick) {
|
165
|
-
case 'outside':
|
166
|
-
if (!targetIsPopover || targetIsReference) {
|
167
|
-
shouldClosePopover(true)
|
168
|
-
}
|
169
|
-
break
|
170
|
-
case 'inside':
|
171
|
-
if (targetIsPopover || targetIsReference) {
|
172
|
-
shouldClosePopover(true)
|
173
|
-
}
|
174
|
-
break
|
175
|
-
case 'any':
|
176
|
-
shouldClosePopover(true)
|
177
|
-
break
|
178
|
-
}
|
179
|
-
}, { capture: true })
|
180
|
-
}, [])
|
181
|
-
|
182
|
-
const popoverComponent = (
|
183
|
-
<Popover
|
184
|
-
className={className}
|
185
|
-
maxHeight={maxHeight}
|
186
|
-
maxWidth={maxWidth}
|
187
|
-
minHeight={minHeight}
|
188
|
-
minWidth={minWidth}
|
189
|
-
modifiers={modifiers}
|
190
|
-
offset={offset}
|
191
|
-
placement={placement}
|
192
|
-
referenceElement={referenceElement}
|
193
|
-
zIndex={zIndex}
|
194
|
-
{...props}
|
195
|
-
>
|
196
|
-
{children}
|
197
|
-
</Popover>
|
198
|
-
);
|
199
|
-
|
200
|
-
return (
|
201
|
-
<PopperManager>
|
202
|
-
<If condition={reference && !referenceElement}>
|
203
|
-
<PopperReference>
|
204
|
-
{({ ref }) => (
|
205
|
-
<span className="pb_popover_reference_wrapper"
|
206
|
-
ref={ref}
|
207
|
-
>
|
208
|
-
<reference.type {...reference.props} />
|
209
|
-
</span>
|
210
|
-
)}
|
211
|
-
</PopperReference>
|
212
|
-
</If>
|
213
|
-
<If condition={show}>
|
214
|
-
<If condition={usePortal}>
|
215
|
-
{ReactDOM.createPortal(
|
216
|
-
popoverComponent,
|
217
|
-
document.querySelector(portal)
|
218
|
-
)}
|
219
|
-
<Else />
|
220
|
-
{popoverComponent}
|
221
|
-
</If>
|
222
|
-
</If>
|
223
|
-
</PopperManager>
|
224
|
-
);
|
225
|
-
};
|
226
|
-
|
227
|
-
export default PbReactPopover;
|