@khanacademy/wonder-blocks-dropdown 2.3.20 → 2.4.3
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.
- package/dist/es/index.js +1681 -2466
- package/dist/index.js +2676 -3342
- package/package.json +17 -16
- package/src/components/__tests__/dropdown-core.test.js +3 -1
- package/src/components/dropdown-core.js +29 -16
- package/src/components/single-select.stories.js +68 -0
- package/src/__tests__/index.test.js +0 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-dropdown",
|
|
3
|
-
"version": "2.3
|
|
3
|
+
"version": "2.4.3",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Dropdown variants for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,30 +15,31 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@
|
|
19
|
-
"@khanacademy/wonder-blocks-
|
|
20
|
-
"@khanacademy/wonder-blocks-
|
|
21
|
-
"@khanacademy/wonder-blocks-
|
|
22
|
-
"@khanacademy/wonder-blocks-
|
|
23
|
-
"@khanacademy/wonder-blocks-icon
|
|
24
|
-
"@khanacademy/wonder-blocks-
|
|
25
|
-
"@khanacademy/wonder-blocks-
|
|
26
|
-
"@khanacademy/wonder-blocks-
|
|
27
|
-
"@khanacademy/wonder-blocks-
|
|
28
|
-
"@khanacademy/wonder-blocks-
|
|
18
|
+
"@babel/runtime": "^7.13.10",
|
|
19
|
+
"@khanacademy/wonder-blocks-button": "^2.9.14",
|
|
20
|
+
"@khanacademy/wonder-blocks-clickable": "^2.1.3",
|
|
21
|
+
"@khanacademy/wonder-blocks-color": "^1.1.19",
|
|
22
|
+
"@khanacademy/wonder-blocks-core": "^3.1.5",
|
|
23
|
+
"@khanacademy/wonder-blocks-icon": "^1.2.22",
|
|
24
|
+
"@khanacademy/wonder-blocks-icon-button": "^3.3.14",
|
|
25
|
+
"@khanacademy/wonder-blocks-layout": "^1.4.4",
|
|
26
|
+
"@khanacademy/wonder-blocks-modal": "^2.1.43",
|
|
27
|
+
"@khanacademy/wonder-blocks-spacing": "^3.0.4",
|
|
28
|
+
"@khanacademy/wonder-blocks-timing": "^2.0.1",
|
|
29
|
+
"@khanacademy/wonder-blocks-typography": "^1.1.26"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
32
|
+
"@popperjs/core": "^2.10.1",
|
|
31
33
|
"aphrodite": "^1.2.5",
|
|
32
|
-
"popper.js": "^1.14.1",
|
|
33
34
|
"prop-types": "^15.6.2",
|
|
34
35
|
"react": "^16.4.1",
|
|
35
36
|
"react-dom": "^16.4.1",
|
|
36
|
-
"react-popper": "^
|
|
37
|
+
"react-popper": "^2.0.0",
|
|
37
38
|
"react-router-dom": "^4.2.2",
|
|
38
39
|
"react-window": "^1.8.5"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"wb-dev-build-settings": "^0.
|
|
42
|
+
"wb-dev-build-settings": "^0.1.2"
|
|
42
43
|
},
|
|
43
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "2a21f4ec19e5611fe716237c21f45c9164b65710"
|
|
44
45
|
}
|
|
@@ -662,7 +662,9 @@ describe("DropdownCore", () => {
|
|
|
662
662
|
});
|
|
663
663
|
|
|
664
664
|
// Assert
|
|
665
|
-
expect(dropdown
|
|
665
|
+
expect(dropdown).toContainMatchingElement(
|
|
666
|
+
`[data-test-id="dropdown-core-no-results"]`,
|
|
667
|
+
);
|
|
666
668
|
});
|
|
667
669
|
|
|
668
670
|
it("When SearchTextInput has input and focused, tab key should not close the select", () => {
|
|
@@ -19,11 +19,6 @@ import type {
|
|
|
19
19
|
WithActionSchedulerProps,
|
|
20
20
|
WithoutActionScheduler,
|
|
21
21
|
} from "@khanacademy/wonder-blocks-timing";
|
|
22
|
-
// NOTE(jeff): Here we share some code for use with PopperJS. Long term,
|
|
23
|
-
// we should either contribute this code to the PopperJS component, or its
|
|
24
|
-
// own non-wonder-blocks package.
|
|
25
|
-
// $FlowIgnore
|
|
26
|
-
import visibilityModifierDefaultConfig from "../../../../shared-unpackaged/visibility-modifier.js"; // eslint-disable-line import/no-restricted-paths
|
|
27
22
|
import DropdownCoreVirtualized from "./dropdown-core-virtualized.js";
|
|
28
23
|
import SeparatorItem from "./separator-item.js";
|
|
29
24
|
import SearchTextInput from "./search-text-input.js";
|
|
@@ -639,7 +634,7 @@ class DropdownCore extends React.Component<Props, State> {
|
|
|
639
634
|
});
|
|
640
635
|
}
|
|
641
636
|
|
|
642
|
-
renderItems(
|
|
637
|
+
renderItems(isReferenceHidden: ?boolean): React.Node {
|
|
643
638
|
const {dropdownStyle, light, openerElement} = this.props;
|
|
644
639
|
|
|
645
640
|
// The dropdown width is at least the width of the opener.
|
|
@@ -662,7 +657,7 @@ class DropdownCore extends React.Component<Props, State> {
|
|
|
662
657
|
style={[
|
|
663
658
|
styles.dropdown,
|
|
664
659
|
light && styles.light,
|
|
665
|
-
|
|
660
|
+
isReferenceHidden && styles.hidden,
|
|
666
661
|
{minWidth: minDropdownWidth},
|
|
667
662
|
dropdownStyle,
|
|
668
663
|
]}
|
|
@@ -690,24 +685,39 @@ class DropdownCore extends React.Component<Props, State> {
|
|
|
690
685
|
if (modalHost) {
|
|
691
686
|
return ReactDOM.createPortal(
|
|
692
687
|
<Popper
|
|
693
|
-
innerRef={(node) => {
|
|
688
|
+
innerRef={(node: ?HTMLElement) => {
|
|
694
689
|
if (node) {
|
|
695
690
|
this.popperElement = node;
|
|
696
691
|
}
|
|
697
692
|
}}
|
|
698
693
|
referenceElement={this.props.openerElement}
|
|
694
|
+
strategy="fixed"
|
|
699
695
|
placement={
|
|
700
696
|
alignment === "left" ? "bottom-start" : "bottom-end"
|
|
701
697
|
}
|
|
702
|
-
modifiers={
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
698
|
+
modifiers={[
|
|
699
|
+
{
|
|
700
|
+
name: "preventOverflow",
|
|
701
|
+
options: {
|
|
702
|
+
rootBoundary: "viewport",
|
|
703
|
+
// Allows to overlap the popper in case there's
|
|
704
|
+
// no more vertical room in the viewport.
|
|
705
|
+
altAxis: true,
|
|
706
|
+
// Also needed to make sure the Popper will be
|
|
707
|
+
// displayed correctly in different contexts
|
|
708
|
+
// (e.g inside a Modal)
|
|
709
|
+
tether: false,
|
|
710
|
+
},
|
|
707
711
|
},
|
|
708
|
-
}
|
|
712
|
+
]}
|
|
709
713
|
>
|
|
710
|
-
{({
|
|
714
|
+
{({
|
|
715
|
+
placement,
|
|
716
|
+
ref,
|
|
717
|
+
style,
|
|
718
|
+
hasPopperEscaped,
|
|
719
|
+
isReferenceHidden,
|
|
720
|
+
}) => {
|
|
711
721
|
// For some reason react-popper includes `pointerEvents: "none"`
|
|
712
722
|
// in the `style` it passes to us, but only when running the tests.
|
|
713
723
|
const {pointerEvents: _, ...restStyle} = style;
|
|
@@ -717,7 +727,9 @@ class DropdownCore extends React.Component<Props, State> {
|
|
|
717
727
|
style={restStyle}
|
|
718
728
|
data-placement={placement}
|
|
719
729
|
>
|
|
720
|
-
{this.renderItems(
|
|
730
|
+
{this.renderItems(
|
|
731
|
+
hasPopperEscaped || isReferenceHidden,
|
|
732
|
+
)}
|
|
721
733
|
</div>
|
|
722
734
|
);
|
|
723
735
|
}}
|
|
@@ -767,6 +779,7 @@ const styles = StyleSheet.create({
|
|
|
767
779
|
},
|
|
768
780
|
|
|
769
781
|
hidden: {
|
|
782
|
+
pointerEvents: "none",
|
|
770
783
|
visibility: "hidden",
|
|
771
784
|
},
|
|
772
785
|
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import {StyleSheet} from "aphrodite";
|
|
4
4
|
|
|
5
|
+
import Button from "@khanacademy/wonder-blocks-button";
|
|
5
6
|
import {View} from "@khanacademy/wonder-blocks-core";
|
|
6
7
|
import {SingleSelect, OptionItem} from "@khanacademy/wonder-blocks-dropdown";
|
|
8
|
+
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
9
|
+
import {OnePaneDialog, ModalLauncher} from "@khanacademy/wonder-blocks-modal";
|
|
10
|
+
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
11
|
+
import {Body} from "@khanacademy/wonder-blocks-typography";
|
|
7
12
|
|
|
8
13
|
import type {StoryComponentType} from "@storybook/react";
|
|
9
14
|
|
|
@@ -89,6 +94,14 @@ const styles = StyleSheet.create({
|
|
|
89
94
|
height: "800px",
|
|
90
95
|
width: "1200px",
|
|
91
96
|
},
|
|
97
|
+
centered: {
|
|
98
|
+
alignItems: "center",
|
|
99
|
+
justifyContent: "center",
|
|
100
|
+
height: `calc(100vh - 16px)`,
|
|
101
|
+
},
|
|
102
|
+
scrollableArea: {
|
|
103
|
+
height: "200vh",
|
|
104
|
+
},
|
|
92
105
|
});
|
|
93
106
|
|
|
94
107
|
export const WithFilter: StoryComponentType = () => <SingleSelectWithFilter />;
|
|
@@ -105,3 +118,58 @@ WithFilter.story = {
|
|
|
105
118
|
export const WithFilterOpened: StoryComponentType = () => (
|
|
106
119
|
<SingleSelectWithFilter opened={true} />
|
|
107
120
|
);
|
|
121
|
+
|
|
122
|
+
export const DropdownInModal: StoryComponentType = () => {
|
|
123
|
+
const [value, setValue] = React.useState(null);
|
|
124
|
+
const [opened, setOpened] = React.useState(true);
|
|
125
|
+
|
|
126
|
+
const modalContent = (
|
|
127
|
+
<View style={styles.scrollableArea}>
|
|
128
|
+
<View>
|
|
129
|
+
<Body>
|
|
130
|
+
Sometimes we want to include Dropdowns inside a Modal, and
|
|
131
|
+
these controls can be accessed only by scrolling down. This
|
|
132
|
+
example help us to demonstrate that SingleSelect components
|
|
133
|
+
can correctly be displayed within the visible scrolling
|
|
134
|
+
area.
|
|
135
|
+
</Body>
|
|
136
|
+
<Strut size={Spacing.large_24} />
|
|
137
|
+
<SingleSelect
|
|
138
|
+
onChange={(selected) => setValue(selected)}
|
|
139
|
+
isFilterable={true}
|
|
140
|
+
opened={opened}
|
|
141
|
+
onToggle={(opened) => setOpened(opened)}
|
|
142
|
+
placeholder="Select a fruit"
|
|
143
|
+
selectedValue={value}
|
|
144
|
+
>
|
|
145
|
+
{optionItems}
|
|
146
|
+
</SingleSelect>
|
|
147
|
+
</View>
|
|
148
|
+
</View>
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const modal = (
|
|
152
|
+
<OnePaneDialog title="Dropdown in a Modal" content={modalContent} />
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<View style={styles.centered}>
|
|
157
|
+
<ModalLauncher modal={modal}>
|
|
158
|
+
{({openModal}) => (
|
|
159
|
+
<Button onClick={openModal}>Click here!</Button>
|
|
160
|
+
)}
|
|
161
|
+
</ModalLauncher>
|
|
162
|
+
</View>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
DropdownInModal.story = {
|
|
167
|
+
name: "Dropdown in a modal",
|
|
168
|
+
parameters: {
|
|
169
|
+
chromatic: {
|
|
170
|
+
// We don't need screenshots because this story can be tested after
|
|
171
|
+
// the modal is opened.
|
|
172
|
+
disable: true,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
describe("@khanacademy/wonder-blocks-dropdown", () => {
|
|
4
|
-
test("package exports default", async () => {
|
|
5
|
-
// Arrange
|
|
6
|
-
const importedModule = import("../index.js");
|
|
7
|
-
|
|
8
|
-
// Act
|
|
9
|
-
const result = await importedModule;
|
|
10
|
-
|
|
11
|
-
// Assert
|
|
12
|
-
expect(Object.keys(result).sort()).toEqual(
|
|
13
|
-
[
|
|
14
|
-
"ActionItem",
|
|
15
|
-
"ActionMenu",
|
|
16
|
-
"MultiSelect",
|
|
17
|
-
"OptionItem",
|
|
18
|
-
"SeparatorItem",
|
|
19
|
-
"SingleSelect",
|
|
20
|
-
].sort(),
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
});
|