@khanacademy/wonder-blocks-layout 1.4.8 → 1.4.9
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/CHANGELOG.md +6 -0
- package/dist/es/index.js +21 -89
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/dist/es/index.js
CHANGED
|
@@ -4,11 +4,8 @@ import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
|
4
4
|
import { StyleSheet } from 'aphrodite';
|
|
5
5
|
import { View } from '@khanacademy/wonder-blocks-core';
|
|
6
6
|
|
|
7
|
-
// All possible valid media sizes
|
|
8
7
|
const VALID_MEDIA_SIZES = ["small", "medium", "large"];
|
|
9
|
-
const mediaDefaultSpecLargeMarginWidth = Spacing.large_24;
|
|
10
|
-
// three different settings (roughly mobile, tablet, and desktop).
|
|
11
|
-
|
|
8
|
+
const mediaDefaultSpecLargeMarginWidth = Spacing.large_24;
|
|
12
9
|
const MEDIA_DEFAULT_SPEC = {
|
|
13
10
|
small: {
|
|
14
11
|
query: "(max-width: 767px)",
|
|
@@ -29,8 +26,7 @@ const MEDIA_DEFAULT_SPEC = {
|
|
|
29
26
|
marginWidth: mediaDefaultSpecLargeMarginWidth,
|
|
30
27
|
maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
|
|
31
28
|
}
|
|
32
|
-
};
|
|
33
|
-
|
|
29
|
+
};
|
|
34
30
|
const MEDIA_INTERNAL_SPEC = {
|
|
35
31
|
large: {
|
|
36
32
|
query: "(min-width: 1px)",
|
|
@@ -38,8 +34,7 @@ const MEDIA_INTERNAL_SPEC = {
|
|
|
38
34
|
gutterWidth: Spacing.xLarge_32,
|
|
39
35
|
marginWidth: Spacing.medium_16
|
|
40
36
|
}
|
|
41
|
-
};
|
|
42
|
-
|
|
37
|
+
};
|
|
43
38
|
const MEDIA_MODAL_SPEC = {
|
|
44
39
|
small: {
|
|
45
40
|
query: "(max-width: 767px)",
|
|
@@ -59,24 +54,13 @@ const defaultContext = {
|
|
|
59
54
|
ssrSize: "large",
|
|
60
55
|
mediaSpec: MEDIA_DEFAULT_SPEC
|
|
61
56
|
};
|
|
62
|
-
var MediaLayoutContext =
|
|
57
|
+
var MediaLayoutContext = React.createContext(defaultContext);
|
|
63
58
|
|
|
64
59
|
const queries = [].concat(Object.values(MEDIA_DEFAULT_SPEC).map(spec => spec.query), Object.values(MEDIA_INTERNAL_SPEC).map(spec => spec.query), Object.values(MEDIA_MODAL_SPEC).map(spec => spec.query));
|
|
65
|
-
const mediaQueryLists = {};
|
|
66
|
-
|
|
67
|
-
// If for some reason we're not able to resolve the current media size we
|
|
68
|
-
// fall back to this state.
|
|
60
|
+
const mediaQueryLists = {};
|
|
69
61
|
const DEFAULT_SIZE = "large";
|
|
70
62
|
|
|
71
|
-
/**
|
|
72
|
-
* `MediaLayout` is responsible for changing the rendering of contents at
|
|
73
|
-
* differently sized viewports. `MediaLayoutContext.Provider` can be used
|
|
74
|
-
* to specify different breakpoint configurations. By default it uses
|
|
75
|
-
* `MEDIA_DEFAULT_SPEC`. See media-layout-context.js for additiional options.
|
|
76
|
-
*/
|
|
77
63
|
class MediaLayoutInternal extends React.Component {
|
|
78
|
-
// A collection of thunks that's used to clean up event listeners
|
|
79
|
-
// when the component is unmounted.
|
|
80
64
|
constructor(props) {
|
|
81
65
|
super(props);
|
|
82
66
|
this.state = {
|
|
@@ -86,11 +70,10 @@ class MediaLayoutInternal extends React.Component {
|
|
|
86
70
|
}
|
|
87
71
|
|
|
88
72
|
componentDidMount() {
|
|
89
|
-
// TODO(WB-534): handle changes to mediaSpec prop
|
|
90
73
|
const entries = Object.entries(this.props.mediaSpec);
|
|
91
74
|
|
|
92
75
|
for (const [size, spec] of entries) {
|
|
93
|
-
const mql = mediaQueryLists[spec.query];
|
|
76
|
+
const mql = mediaQueryLists[spec.query];
|
|
94
77
|
|
|
95
78
|
if (!mql) {
|
|
96
79
|
continue;
|
|
@@ -110,14 +93,10 @@ class MediaLayoutInternal extends React.Component {
|
|
|
110
93
|
}
|
|
111
94
|
|
|
112
95
|
componentWillUnmount() {
|
|
113
|
-
// Remove our listeners.
|
|
114
96
|
this.cleanupThunks.forEach(cleaup => cleaup());
|
|
115
97
|
}
|
|
116
98
|
|
|
117
99
|
getCurrentSize(spec) {
|
|
118
|
-
// If we have a state with the current size in it then we always want
|
|
119
|
-
// to use that. This will happen if the viewport changes sizes after
|
|
120
|
-
// we've already initialized.
|
|
121
100
|
if (this.state.size) {
|
|
122
101
|
return this.state.size;
|
|
123
102
|
} else {
|
|
@@ -133,48 +112,33 @@ class MediaLayoutInternal extends React.Component {
|
|
|
133
112
|
}
|
|
134
113
|
|
|
135
114
|
return DEFAULT_SIZE;
|
|
136
|
-
}
|
|
137
|
-
// environment) if there is no window object or matchMedia function
|
|
138
|
-
// available.
|
|
139
|
-
|
|
115
|
+
}
|
|
140
116
|
|
|
141
117
|
isServerSide() {
|
|
142
118
|
return typeof window === "undefined" || !window.matchMedia;
|
|
143
|
-
}
|
|
144
|
-
// We do this by looking at all of the stylesheets specified in the
|
|
145
|
-
// styleSheets prop and then all of the individual styles. We merge the
|
|
146
|
-
// styles together
|
|
147
|
-
// TODO(WB-533): move to util.js to make it easier to test
|
|
148
|
-
|
|
119
|
+
}
|
|
149
120
|
|
|
150
121
|
getMockStyleSheet(mediaSize) {
|
|
151
122
|
const {
|
|
152
123
|
styleSheets
|
|
153
124
|
} = this.props;
|
|
154
|
-
const mockStyleSheet = {};
|
|
125
|
+
const mockStyleSheet = {};
|
|
155
126
|
|
|
156
127
|
if (!styleSheets) {
|
|
157
128
|
return mockStyleSheet;
|
|
158
|
-
}
|
|
159
|
-
|
|
129
|
+
}
|
|
160
130
|
|
|
161
131
|
for (const styleSize of Object.keys(styleSheets)) {
|
|
162
132
|
const styleSheet = styleSheets[styleSize];
|
|
163
133
|
|
|
164
134
|
if (!styleSheet) {
|
|
165
135
|
continue;
|
|
166
|
-
}
|
|
167
|
-
|
|
136
|
+
}
|
|
168
137
|
|
|
169
138
|
for (const name of Object.keys(styleSheet)) {
|
|
170
|
-
if (
|
|
171
|
-
Object.prototype.hasOwnProperty.call(mockStyleSheet, name)) {
|
|
139
|
+
if (Object.prototype.hasOwnProperty.call(mockStyleSheet, name)) {
|
|
172
140
|
continue;
|
|
173
|
-
}
|
|
174
|
-
// the stylesheets together in least-specific to most-specific
|
|
175
|
-
// priority (thus small/medium/large styles will always have
|
|
176
|
-
// precedence over "all" or mdOrSmaller/mdOrLarger/etc.).
|
|
177
|
-
|
|
141
|
+
}
|
|
178
142
|
|
|
179
143
|
mockStyleSheet[name] = [styleSheets.all && styleSheets.all[name], mediaSize === "small" && [styleSheets.mdOrSmaller && styleSheets.mdOrSmaller[name], styleSheets.small && styleSheets.small[name]], mediaSize === "medium" && [styleSheets.mdOrSmaller && styleSheets.mdOrSmaller[name], styleSheets.mdOrLarger && styleSheets.mdOrLarger[name], styleSheets.medium && styleSheets.medium[name]], mediaSize === "large" && [styleSheets.mdOrLarger && styleSheets.mdOrLarger[name], styleSheets.large && styleSheets.large[name]]];
|
|
180
144
|
}
|
|
@@ -189,23 +153,15 @@ class MediaLayoutInternal extends React.Component {
|
|
|
189
153
|
mediaSpec,
|
|
190
154
|
ssrSize,
|
|
191
155
|
overrideSize
|
|
192
|
-
} = this.props;
|
|
193
|
-
// to query whether any of them match.
|
|
156
|
+
} = this.props;
|
|
194
157
|
|
|
195
158
|
if (!this.isServerSide()) {
|
|
196
159
|
for (const query of queries.filter(query => !mediaQueryLists[query])) {
|
|
197
160
|
mediaQueryLists[query] = window.matchMedia(query);
|
|
198
161
|
}
|
|
199
|
-
}
|
|
200
|
-
// If an override has been specified, we use that.
|
|
201
|
-
// If we're rendering on the server then we use the default
|
|
202
|
-
// SSR rendering size.
|
|
203
|
-
// Otherwise we attempt to get the current size based on
|
|
204
|
-
// the current MediaSpec.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const mediaSize = overrideSize || this.isServerSide() && ssrSize || this.getCurrentSize(mediaSpec); // Generate a mock stylesheet
|
|
162
|
+
}
|
|
208
163
|
|
|
164
|
+
const mediaSize = overrideSize || this.isServerSide() && ssrSize || this.getCurrentSize(mediaSpec);
|
|
209
165
|
const styles = this.getMockStyleSheet(mediaSize);
|
|
210
166
|
return children({
|
|
211
167
|
mediaSize,
|
|
@@ -214,19 +170,15 @@ class MediaLayoutInternal extends React.Component {
|
|
|
214
170
|
});
|
|
215
171
|
}
|
|
216
172
|
|
|
217
|
-
}
|
|
218
|
-
|
|
173
|
+
}
|
|
219
174
|
|
|
220
175
|
class MediaLayout extends React.Component {
|
|
221
176
|
render() {
|
|
222
|
-
|
|
223
|
-
// being given (this can be overriden by wrapping this component in
|
|
224
|
-
// a MediaLayoutContext.Consumer).
|
|
225
|
-
return /*#__PURE__*/React.createElement(MediaLayoutContext.Consumer, null, ({
|
|
177
|
+
return React.createElement(MediaLayoutContext.Consumer, null, ({
|
|
226
178
|
overrideSize,
|
|
227
179
|
ssrSize,
|
|
228
180
|
mediaSpec
|
|
229
|
-
}) =>
|
|
181
|
+
}) => React.createElement(MediaLayoutInternal, _extends({}, this.props, {
|
|
230
182
|
overrideSize: overrideSize,
|
|
231
183
|
ssrSize: ssrSize,
|
|
232
184
|
mediaSpec: mediaSpec
|
|
@@ -235,17 +187,12 @@ class MediaLayout extends React.Component {
|
|
|
235
187
|
|
|
236
188
|
}
|
|
237
189
|
|
|
238
|
-
/**
|
|
239
|
-
* Expands to fill space between sibling components.
|
|
240
|
-
*
|
|
241
|
-
* Assumes parent is a View.
|
|
242
|
-
*/
|
|
243
190
|
class Spring extends React.Component {
|
|
244
191
|
render() {
|
|
245
192
|
const {
|
|
246
193
|
style
|
|
247
194
|
} = this.props;
|
|
248
|
-
return
|
|
195
|
+
return React.createElement(View, {
|
|
249
196
|
"aria-hidden": "true",
|
|
250
197
|
style: [styles.grow, style]
|
|
251
198
|
});
|
|
@@ -258,18 +205,13 @@ const styles = StyleSheet.create({
|
|
|
258
205
|
}
|
|
259
206
|
});
|
|
260
207
|
|
|
261
|
-
/**
|
|
262
|
-
* A component for inserting fixed space between components.
|
|
263
|
-
*
|
|
264
|
-
* Assumes parent is a View.
|
|
265
|
-
*/
|
|
266
208
|
class Strut extends React.Component {
|
|
267
209
|
render() {
|
|
268
210
|
const {
|
|
269
211
|
size,
|
|
270
212
|
style
|
|
271
213
|
} = this.props;
|
|
272
|
-
return
|
|
214
|
+
return React.createElement(View, {
|
|
273
215
|
"aria-hidden": "true",
|
|
274
216
|
style: [strutStyle(size), style]
|
|
275
217
|
});
|
|
@@ -288,16 +230,6 @@ const strutStyle = size => {
|
|
|
288
230
|
};
|
|
289
231
|
};
|
|
290
232
|
|
|
291
|
-
/**
|
|
292
|
-
* Return where a media size matches a media query.
|
|
293
|
-
*
|
|
294
|
-
* examples:
|
|
295
|
-
* - `queryMatchesSize("all", "small")` returns `true`
|
|
296
|
-
* - `queryMatchesSize("mdOrLarger", "small")` returns `false`
|
|
297
|
-
*
|
|
298
|
-
* @param {MediaQuery} mediaQuery
|
|
299
|
-
* @param {MediaSize} mediaSize
|
|
300
|
-
*/
|
|
301
233
|
const queryMatchesSize = (mediaQuery, mediaSize) => {
|
|
302
234
|
switch (mediaQuery) {
|
|
303
235
|
case "all":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-layout",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.9",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@babel/runtime": "^7.16.3",
|
|
17
|
-
"@khanacademy/wonder-blocks-core": "^4.3.
|
|
17
|
+
"@khanacademy/wonder-blocks-core": "^4.3.1",
|
|
18
18
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"wb-dev-build-settings": "^0.
|
|
21
|
+
"wb-dev-build-settings": "^0.4.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"aphrodite": "^1.2.5",
|