@khanacademy/wonder-blocks-core 12.2.1 → 12.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @khanacademy/wonder-blocks-core
2
2
 
3
+ ## 12.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1334e74: Adding dir to View's type to support RTL usage.
8
+
9
+ ## 12.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 28fa0c0: Add focus utilities: `findFocusableNodes` and `isFocusable`
14
+ - 28fa0c0: Add constants for `ArrowLeft`, `ArrowRight`, `Home`, and `End` keys
15
+
3
16
  ## 12.2.1
4
17
 
5
18
  ### Patch Changes
@@ -17,6 +17,7 @@ declare const Text: React.ForwardRefExoticComponent<{
17
17
  testId?: string;
18
18
  lang?: string;
19
19
  className?: string;
20
+ dir?: "ltr" | "rtl" | "auto";
20
21
  htmlFor?: string;
21
22
  tabIndex?: number;
22
23
  id?: string;
package/dist/es/index.js CHANGED
@@ -1,343 +1,40 @@
1
- import _extends from '@babel/runtime/helpers/extends';
2
- import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
3
2
  import * as React from 'react';
4
3
  import { useMemo, useId, useEffect as useEffect$1, useContext as useContext$1 } from 'react';
5
4
  import { StyleSheet, css } from 'aphrodite';
6
5
 
7
- function flatten(list) {
8
- const result = [];
9
- if (!list) {
10
- return result;
11
- } else if (Array.isArray(list)) {
12
- for (const item of list) {
13
- result.push(...flatten(item));
14
- }
15
- } else {
16
- result.push(list);
17
- }
18
- return result;
19
- }
20
- function processStyleList(style) {
21
- const stylesheetStyles = [];
22
- const inlineStyles = [];
23
- if (!style) {
24
- return {
25
- style: {},
26
- className: ""
27
- };
28
- }
29
- const shouldInlineStyles = typeof global !== "undefined" && global.SNAPSHOT_INLINE_APHRODITE;
30
- flatten(style).forEach(child => {
31
- const _definition = child._definition;
32
- if (_definition != null) {
33
- if (shouldInlineStyles) {
34
- const def = {};
35
- for (const [key, value] of Object.entries(_definition)) {
36
- def[key.replace(/-[a-z]/g, match => match[1].toUpperCase())] = value;
37
- }
38
- inlineStyles.push(def);
39
- } else {
40
- stylesheetStyles.push(child);
41
- }
42
- } else {
43
- inlineStyles.push(child);
44
- }
45
- });
46
- const inlineStylesObject = Object.assign({}, ...inlineStyles);
47
- if (inlineStyles.length > 0 && !shouldInlineStyles) {
48
- const inlineStylesStyleSheet = StyleSheet.create({
49
- inlineStyles: inlineStylesObject
50
- });
51
- stylesheetStyles.push(inlineStylesStyleSheet.inlineStyles);
52
- }
53
- return {
54
- style: shouldInlineStyles ? inlineStylesObject : {},
55
- className: css(...stylesheetStyles)
56
- };
57
- }
6
+ function flatten(list){const result=[];if(!list){return result}else if(Array.isArray(list)){for(const item of list){result.push(...flatten(item));}}else {result.push(list);}return result}function processStyleList(style){const stylesheetStyles=[];const inlineStyles=[];if(!style){return {style:{},className:""}}const shouldInlineStyles=typeof global!=="undefined"&&global.SNAPSHOT_INLINE_APHRODITE;flatten(style).forEach(child=>{const _definition=child._definition;if(_definition!=null){if(shouldInlineStyles){const def={};for(const[key,value]of Object.entries(_definition)){def[key.replace(/-[a-z]/g,match=>match[1].toUpperCase())]=value;}inlineStyles.push(def);}else {stylesheetStyles.push(child);}}else {inlineStyles.push(child);}});const inlineStylesObject=Object.assign({},...inlineStyles);if(inlineStyles.length>0&&!shouldInlineStyles){const inlineStylesStyleSheet=StyleSheet.create({inlineStyles:inlineStylesObject});stylesheetStyles.push(inlineStylesStyleSheet.inlineStyles);}return {style:shouldInlineStyles?inlineStylesObject:{},className:css(...stylesheetStyles)}}
58
7
 
59
- const _excluded$2 = ["children", "style", "tag", "testId"];
60
- const isHeaderRegex = /^h[1-6]$/;
61
- const styles$1 = StyleSheet.create({
62
- text: {
63
- WebkitFontSmoothing: "antialiased",
64
- MozOsxFontSmoothing: "grayscale"
65
- },
66
- header: {
67
- marginTop: 0,
68
- marginBottom: 0
69
- }
70
- });
71
- const Text = React.forwardRef(function Text(_ref, ref) {
72
- let {
73
- children,
74
- style,
75
- tag: Tag = "span",
76
- testId
77
- } = _ref,
78
- otherProps = _objectWithoutPropertiesLoose(_ref, _excluded$2);
79
- const isHeader = isHeaderRegex.test(Tag);
80
- const styleAttributes = processStyleList([styles$1.text, isHeader && styles$1.header, style]);
81
- const classNames = otherProps.className ? [otherProps.className, styleAttributes.className].join(" ") : styleAttributes.className;
82
- return (React.createElement(Tag, _extends({}, otherProps, {
83
- style: styleAttributes.style,
84
- className: classNames,
85
- "data-testid": testId,
86
- ref: ref
87
- }), children)
88
- );
89
- });
8
+ const isHeaderRegex=/^h[1-6]$/;const styles$1=StyleSheet.create({text:{WebkitFontSmoothing:"antialiased",MozOsxFontSmoothing:"grayscale"},header:{marginTop:0,marginBottom:0}});const Text=React.forwardRef(function Text({children,style,tag:Tag="span",testId,...otherProps},ref){const isHeader=isHeaderRegex.test(Tag);const styleAttributes=processStyleList([styles$1.text,isHeader&&styles$1.header,style]);const classNames=otherProps.className?[otherProps.className,styleAttributes.className].join(" "):styleAttributes.className;return jsx(Tag,{...otherProps,style:styleAttributes.style,className:classNames,"data-testid":testId,ref:ref,children:children})});
90
9
 
91
- const _excluded$1 = ["className", "style"];
92
- function addStyle(Component, defaultStyle) {
93
- return React.forwardRef((props, ref) => {
94
- const _ref = props,
95
- {
96
- className,
97
- style
98
- } = _ref,
99
- otherProps = _objectWithoutPropertiesLoose(_ref, _excluded$1);
100
- const reset = typeof Component === "string" ? overrides[Component] : null;
101
- const {
102
- className: aphroditeClassName,
103
- style: inlineStyles
104
- } = processStyleList([reset, defaultStyle, style]);
105
- return React.createElement(Component, _extends({}, otherProps, {
106
- ref: ref,
107
- className: [aphroditeClassName, className].filter(Boolean).join(" "),
108
- style: inlineStyles
109
- }));
110
- });
111
- }
112
- const overrides = StyleSheet.create({
113
- button: {
114
- margin: 0,
115
- "::-moz-focus-inner": {
116
- border: 0
117
- }
118
- }
119
- });
10
+ function addStyle(Component,defaultStyle){return React.forwardRef((props,ref)=>{const{className,style,...otherProps}=props;const reset=typeof Component==="string"?overrides[Component]:null;const{className:aphroditeClassName,style:inlineStyles}=processStyleList([reset,defaultStyle,style]);return jsx(Component,{...otherProps,ref:ref,className:[aphroditeClassName,className].filter(Boolean).join(" "),style:inlineStyles})})}const overrides=StyleSheet.create({button:{margin:0,"::-moz-focus-inner":{border:0}}});
120
11
 
121
- const _excluded = ["testId", "tag"];
122
- const styles = StyleSheet.create({
123
- default: {
124
- alignItems: "stretch",
125
- borderWidth: 0,
126
- borderStyle: "solid",
127
- boxSizing: "border-box",
128
- display: "flex",
129
- flexDirection: "column",
130
- margin: 0,
131
- padding: 0,
132
- position: "relative",
133
- zIndex: 0,
134
- minHeight: 0,
135
- minWidth: 0
136
- }
137
- });
138
- const View = React.forwardRef(function View(props, ref) {
139
- const {
140
- testId,
141
- tag = "div"
142
- } = props,
143
- restProps = _objectWithoutPropertiesLoose(props, _excluded);
144
- const commonProps = _extends({}, restProps, {
145
- "data-testid": testId
146
- });
147
- const StyledTag = useMemo(() => addStyle(tag, styles.default), [tag]);
148
- return React.createElement(StyledTag, _extends({}, commonProps, {
149
- ref: ref
150
- }));
151
- });
12
+ const styles=StyleSheet.create({default:{alignItems:"stretch",borderWidth:0,borderStyle:"solid",boxSizing:"border-box",display:"flex",flexDirection:"column",margin:0,padding:0,position:"relative",zIndex:0,minHeight:0,minWidth:0}});const View=React.forwardRef(function View(props,ref){const{testId,tag="div",...restProps}=props;const commonProps={...restProps,"data-testid":testId};const StyledTag=useMemo(()=>addStyle(tag,styles.default),[tag]);return jsx(StyledTag,{...commonProps,ref:ref})});
152
13
 
153
- let RenderState = function (RenderState) {
154
- RenderState["Initial"] = "initial";
155
- RenderState["Standard"] = "standard";
156
- return RenderState;
157
- }({});
158
- let RenderStateInternal = function (RenderStateInternal) {
159
- RenderStateInternal["Root"] = "root";
160
- RenderStateInternal["Initial"] = "initial";
161
- RenderStateInternal["Standard"] = "standard";
162
- return RenderStateInternal;
163
- }({});
164
- const RenderStateContext = React.createContext(RenderStateInternal.Root);
165
- RenderStateContext.displayName = "RenderStateContext";
14
+ var RenderState=/*#__PURE__*/function(RenderState){RenderState["Initial"]="initial";RenderState["Standard"]="standard";return RenderState}({});var RenderStateInternal=/*#__PURE__*/function(RenderStateInternal){RenderStateInternal["Root"]="root";RenderStateInternal["Initial"]="initial";RenderStateInternal["Standard"]="standard";return RenderStateInternal}({});const RenderStateContext=React.createContext("root");RenderStateContext.displayName="RenderStateContext";
166
15
 
167
- class InitialFallback extends React.Component {
168
- constructor(...args) {
169
- super(...args);
170
- this.state = {
171
- mounted: false
172
- };
173
- this._isTheRootComponent = false;
174
- }
175
- componentDidMount() {
176
- if (this._isTheRootComponent) {
177
- this.setState({
178
- mounted: true
179
- });
180
- }
181
- }
182
- _renderAsRootComponent() {
183
- const {
184
- mounted
185
- } = this.state;
186
- const {
187
- children,
188
- fallback
189
- } = this.props;
190
- this._isTheRootComponent = true;
191
- if (mounted) {
192
- return React.createElement(RenderStateContext.Provider, {
193
- value: RenderStateInternal.Standard
194
- }, children());
195
- }
196
- if (fallback) {
197
- return React.createElement(RenderStateContext.Provider, {
198
- value: RenderStateInternal.Initial
199
- }, fallback());
200
- }
201
- return null;
202
- }
203
- _maybeRender(renderState) {
204
- const {
205
- children,
206
- fallback
207
- } = this.props;
208
- switch (renderState) {
209
- case RenderStateInternal.Root:
210
- return this._renderAsRootComponent();
211
- case RenderStateInternal.Initial:
212
- return fallback ? fallback() : null;
213
- case RenderStateInternal.Standard:
214
- return children();
215
- }
216
- {
217
- var _JSON$stringify;
218
- console.log(`We got a render state we don't understand: "${(_JSON$stringify = JSON.stringify(renderState)) != null ? _JSON$stringify : ""}"`);
219
- return this._maybeRender(RenderStateInternal.Root);
220
- }
221
- }
222
- render() {
223
- return React.createElement(RenderStateContext.Consumer, null, value => this._maybeRender(value));
224
- }
225
- }
16
+ class InitialFallback extends React.Component{componentDidMount(){if(this._isTheRootComponent){this.setState({mounted:true});}}_renderAsRootComponent(){const{mounted}=this.state;const{children,fallback}=this.props;this._isTheRootComponent=true;if(mounted){return jsx(RenderStateContext.Provider,{value:RenderStateInternal.Standard,children:children()})}if(fallback){return jsx(RenderStateContext.Provider,{value:RenderStateInternal.Initial,children:fallback()})}return null}_maybeRender(renderState){const{children,fallback}=this.props;switch(renderState){case RenderStateInternal.Root:return this._renderAsRootComponent();case RenderStateInternal.Initial:return fallback?fallback():null;case RenderStateInternal.Standard:return children()}{console.log(`We got a render state we don't understand: "${JSON.stringify(renderState)??""}"`);return this._maybeRender(RenderStateInternal.Root)}}render(){return jsx(RenderStateContext.Consumer,{children:value=>this._maybeRender(value)})}constructor(...args){super(...args),this.state={mounted:false},this._isTheRootComponent=false;}}
226
17
 
227
- let serverSide = false;
228
- var Server = {
229
- isServerSide: () => serverSide,
230
- setServerSide: () => {
231
- serverSide = true;
232
- }
233
- };
18
+ let serverSide=false;var Server = {isServerSide:()=>serverSide,setServerSide:()=>{serverSide=true;}};
234
19
 
235
- const Id = ({
236
- id,
237
- children
238
- }) => {
239
- const generatedId = useId();
240
- return React.createElement(React.Fragment, null, children(id != null ? id : generatedId));
241
- };
20
+ const Id=({id,children})=>{const generatedId=useId();return jsx(Fragment,{children:children(id??generatedId)})};
242
21
 
243
- const useForceUpdate = () => {
244
- const [, setUpdateState] = React.useState({});
245
- const forceUpdate = React.useCallback(() => {
246
- setUpdateState({});
247
- }, []);
248
- return forceUpdate;
249
- };
22
+ const useForceUpdate=()=>{const[,setUpdateState]=React.useState({});const forceUpdate=React.useCallback(()=>{setUpdateState({});},[]);return forceUpdate};
250
23
 
251
- const useIsMounted = () => {
252
- const isMountedRef = React.useRef(false);
253
- const isMounted = React.useCallback(() => isMountedRef.current, []);
254
- React.useEffect(() => {
255
- isMountedRef.current = true;
256
- return () => {
257
- isMountedRef.current = false;
258
- };
259
- }, []);
260
- return isMounted;
261
- };
24
+ const useIsMounted=()=>{const isMountedRef=React.useRef(false);const isMounted=React.useCallback(()=>isMountedRef.current,[]);React.useEffect(()=>{isMountedRef.current=true;return ()=>{isMountedRef.current=false;}},[]);return isMounted};
262
25
 
263
- function useLatestRef(value) {
264
- const ref = React.useRef(value);
265
- ref.current = value;
266
- return ref;
267
- }
26
+ function useLatestRef(value){const ref=React.useRef(value);ref.current=value;return ref}
268
27
 
269
- const useOnMountEffect = callback => {
270
- const isMountedRef = React.useRef(true);
271
- React.useEffect(() => {
272
- const cleanup = callback(isMountedRef);
273
- return () => {
274
- cleanup == null || cleanup();
275
- isMountedRef.current = false;
276
- };
277
- }, []);
278
- };
28
+ const useOnMountEffect=callback=>{const isMountedRef=React.useRef(true);React.useEffect(()=>{const cleanup=callback(isMountedRef);return ()=>{cleanup?.();isMountedRef.current=false;}},[]);};
279
29
 
280
- const useOnline = () => {
281
- const forceUpdate = useForceUpdate();
282
- useEffect$1(() => {
283
- const handleChange = () => forceUpdate();
284
- window.addEventListener("online", handleChange);
285
- window.addEventListener("offline", handleChange);
286
- return () => {
287
- window.removeEventListener("online", handleChange);
288
- window.removeEventListener("offline", handleChange);
289
- };
290
- }, [forceUpdate]);
291
- return navigator.onLine;
292
- };
30
+ const useOnline=()=>{const forceUpdate=useForceUpdate();useEffect$1(()=>{const handleChange=()=>forceUpdate();window.addEventListener("online",handleChange);window.addEventListener("offline",handleChange);return ()=>{window.removeEventListener("online",handleChange);window.removeEventListener("offline",handleChange);}},[forceUpdate]);return navigator.onLine};
293
31
 
294
- const usePreHydrationEffect = effect => {
295
- const effectCallRef = React.useRef(Server.isServerSide() ? () => {} : React.useLayoutEffect);
296
- effectCallRef.current(effect, []);
297
- };
32
+ const usePreHydrationEffect=effect=>{const effectCallRef=React.useRef(Server.isServerSide()?()=>{}:React.useLayoutEffect);effectCallRef.current(effect,[]);};
298
33
 
299
- const useRenderState = () => {
300
- const rawRenderState = useContext$1(RenderStateContext);
301
- if (rawRenderState === RenderStateInternal.Standard) {
302
- return RenderState.Standard;
303
- } else {
304
- return RenderState.Initial;
305
- }
306
- };
34
+ const useRenderState=()=>{const rawRenderState=useContext$1(RenderStateContext);if(rawRenderState===RenderStateInternal.Standard){return RenderState.Standard}else {return RenderState.Initial}};
307
35
 
308
- const {
309
- useEffect,
310
- useState,
311
- useContext
312
- } = React;
313
- const RenderStateRoot = ({
314
- children,
315
- throwIfNested: _throwIfNested = true
316
- }) => {
317
- const [firstRender, setFirstRender] = useState(true);
318
- const renderState = useContext(RenderStateContext);
319
- useEffect(() => {
320
- setFirstRender(false);
321
- }, []);
322
- if (renderState !== RenderStateInternal.Root) {
323
- if (_throwIfNested) {
324
- throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
325
- }
326
- return React.createElement(React.Fragment, null, children);
327
- }
328
- const value = firstRender ? RenderStateInternal.Initial : RenderStateInternal.Standard;
329
- return React.createElement(RenderStateContext.Provider, {
330
- value: value
331
- }, children);
332
- };
36
+ const{useEffect,useState,useContext}=React;const RenderStateRoot=({children,throwIfNested=true})=>{const[firstRender,setFirstRender]=useState(true);const renderState=useContext(RenderStateContext);useEffect(()=>{setFirstRender(false);},[]);if(renderState!==RenderStateInternal.Root){if(throwIfNested){throw new Error("There's already a <RenderStateRoot> above this instance in "+"the render tree. This instance should be removed.")}return jsx(Fragment,{children:children})}const value=firstRender?RenderStateInternal.Initial:RenderStateInternal.Standard;return jsx(RenderStateContext.Provider,{value:value,children:children})};
333
37
 
334
- const keys = {
335
- enter: "Enter",
336
- escape: "Escape",
337
- tab: "Tab",
338
- space: " ",
339
- up: "ArrowUp",
340
- down: "ArrowDown"
341
- };
38
+ const keys={enter:"Enter",escape:"Escape",tab:"Tab",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End"};
342
39
 
343
40
  export { Id, InitialFallback, RenderState, RenderStateRoot, Server, Text, View, addStyle, keys, useForceUpdate, useIsMounted, useLatestRef, useOnMountEffect, useOnline, usePreHydrationEffect, useRenderState };
package/dist/index.js CHANGED
@@ -2,13 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var _extends = require('@babel/runtime/helpers/extends');
6
- var _objectWithoutPropertiesLoose = require('@babel/runtime/helpers/objectWithoutPropertiesLoose');
5
+ var jsxRuntime = require('react/jsx-runtime');
7
6
  var React = require('react');
8
7
  var aphrodite = require('aphrodite');
9
8
 
10
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
-
12
9
  function _interopNamespace(e) {
13
10
  if (e && e.__esModule) return e;
14
11
  var n = Object.create(null);
@@ -27,345 +24,41 @@ function _interopNamespace(e) {
27
24
  return Object.freeze(n);
28
25
  }
29
26
 
30
- var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
31
- var _objectWithoutPropertiesLoose__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutPropertiesLoose);
32
27
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
28
 
34
- function flatten(list) {
35
- const result = [];
36
- if (!list) {
37
- return result;
38
- } else if (Array.isArray(list)) {
39
- for (const item of list) {
40
- result.push(...flatten(item));
41
- }
42
- } else {
43
- result.push(list);
44
- }
45
- return result;
46
- }
47
- function processStyleList(style) {
48
- const stylesheetStyles = [];
49
- const inlineStyles = [];
50
- if (!style) {
51
- return {
52
- style: {},
53
- className: ""
54
- };
55
- }
56
- const shouldInlineStyles = typeof global !== "undefined" && global.SNAPSHOT_INLINE_APHRODITE;
57
- flatten(style).forEach(child => {
58
- const _definition = child._definition;
59
- if (_definition != null) {
60
- if (shouldInlineStyles) {
61
- const def = {};
62
- for (const [key, value] of Object.entries(_definition)) {
63
- def[key.replace(/-[a-z]/g, match => match[1].toUpperCase())] = value;
64
- }
65
- inlineStyles.push(def);
66
- } else {
67
- stylesheetStyles.push(child);
68
- }
69
- } else {
70
- inlineStyles.push(child);
71
- }
72
- });
73
- const inlineStylesObject = Object.assign({}, ...inlineStyles);
74
- if (inlineStyles.length > 0 && !shouldInlineStyles) {
75
- const inlineStylesStyleSheet = aphrodite.StyleSheet.create({
76
- inlineStyles: inlineStylesObject
77
- });
78
- stylesheetStyles.push(inlineStylesStyleSheet.inlineStyles);
79
- }
80
- return {
81
- style: shouldInlineStyles ? inlineStylesObject : {},
82
- className: aphrodite.css(...stylesheetStyles)
83
- };
84
- }
29
+ function flatten(list){const result=[];if(!list){return result}else if(Array.isArray(list)){for(const item of list){result.push(...flatten(item));}}else {result.push(list);}return result}function processStyleList(style){const stylesheetStyles=[];const inlineStyles=[];if(!style){return {style:{},className:""}}const shouldInlineStyles=typeof global!=="undefined"&&global.SNAPSHOT_INLINE_APHRODITE;flatten(style).forEach(child=>{const _definition=child._definition;if(_definition!=null){if(shouldInlineStyles){const def={};for(const[key,value]of Object.entries(_definition)){def[key.replace(/-[a-z]/g,match=>match[1].toUpperCase())]=value;}inlineStyles.push(def);}else {stylesheetStyles.push(child);}}else {inlineStyles.push(child);}});const inlineStylesObject=Object.assign({},...inlineStyles);if(inlineStyles.length>0&&!shouldInlineStyles){const inlineStylesStyleSheet=aphrodite.StyleSheet.create({inlineStyles:inlineStylesObject});stylesheetStyles.push(inlineStylesStyleSheet.inlineStyles);}return {style:shouldInlineStyles?inlineStylesObject:{},className:aphrodite.css(...stylesheetStyles)}}
85
30
 
86
- const _excluded$2 = ["children", "style", "tag", "testId"];
87
- const isHeaderRegex = /^h[1-6]$/;
88
- const styles$1 = aphrodite.StyleSheet.create({
89
- text: {
90
- WebkitFontSmoothing: "antialiased",
91
- MozOsxFontSmoothing: "grayscale"
92
- },
93
- header: {
94
- marginTop: 0,
95
- marginBottom: 0
96
- }
97
- });
98
- const Text = React__namespace.forwardRef(function Text(_ref, ref) {
99
- let {
100
- children,
101
- style,
102
- tag: Tag = "span",
103
- testId
104
- } = _ref,
105
- otherProps = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$2);
106
- const isHeader = isHeaderRegex.test(Tag);
107
- const styleAttributes = processStyleList([styles$1.text, isHeader && styles$1.header, style]);
108
- const classNames = otherProps.className ? [otherProps.className, styleAttributes.className].join(" ") : styleAttributes.className;
109
- return (React__namespace.createElement(Tag, _extends__default["default"]({}, otherProps, {
110
- style: styleAttributes.style,
111
- className: classNames,
112
- "data-testid": testId,
113
- ref: ref
114
- }), children)
115
- );
116
- });
31
+ const isHeaderRegex=/^h[1-6]$/;const styles$1=aphrodite.StyleSheet.create({text:{WebkitFontSmoothing:"antialiased",MozOsxFontSmoothing:"grayscale"},header:{marginTop:0,marginBottom:0}});const Text=React__namespace.forwardRef(function Text({children,style,tag:Tag="span",testId,...otherProps},ref){const isHeader=isHeaderRegex.test(Tag);const styleAttributes=processStyleList([styles$1.text,isHeader&&styles$1.header,style]);const classNames=otherProps.className?[otherProps.className,styleAttributes.className].join(" "):styleAttributes.className;return jsxRuntime.jsx(Tag,{...otherProps,style:styleAttributes.style,className:classNames,"data-testid":testId,ref:ref,children:children})});
117
32
 
118
- const _excluded$1 = ["className", "style"];
119
- function addStyle(Component, defaultStyle) {
120
- return React__namespace.forwardRef((props, ref) => {
121
- const _ref = props,
122
- {
123
- className,
124
- style
125
- } = _ref,
126
- otherProps = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$1);
127
- const reset = typeof Component === "string" ? overrides[Component] : null;
128
- const {
129
- className: aphroditeClassName,
130
- style: inlineStyles
131
- } = processStyleList([reset, defaultStyle, style]);
132
- return React__namespace.createElement(Component, _extends__default["default"]({}, otherProps, {
133
- ref: ref,
134
- className: [aphroditeClassName, className].filter(Boolean).join(" "),
135
- style: inlineStyles
136
- }));
137
- });
138
- }
139
- const overrides = aphrodite.StyleSheet.create({
140
- button: {
141
- margin: 0,
142
- "::-moz-focus-inner": {
143
- border: 0
144
- }
145
- }
146
- });
33
+ function addStyle(Component,defaultStyle){return React__namespace.forwardRef((props,ref)=>{const{className,style,...otherProps}=props;const reset=typeof Component==="string"?overrides[Component]:null;const{className:aphroditeClassName,style:inlineStyles}=processStyleList([reset,defaultStyle,style]);return jsxRuntime.jsx(Component,{...otherProps,ref:ref,className:[aphroditeClassName,className].filter(Boolean).join(" "),style:inlineStyles})})}const overrides=aphrodite.StyleSheet.create({button:{margin:0,"::-moz-focus-inner":{border:0}}});
147
34
 
148
- const _excluded = ["testId", "tag"];
149
- const styles = aphrodite.StyleSheet.create({
150
- default: {
151
- alignItems: "stretch",
152
- borderWidth: 0,
153
- borderStyle: "solid",
154
- boxSizing: "border-box",
155
- display: "flex",
156
- flexDirection: "column",
157
- margin: 0,
158
- padding: 0,
159
- position: "relative",
160
- zIndex: 0,
161
- minHeight: 0,
162
- minWidth: 0
163
- }
164
- });
165
- const View = React__namespace.forwardRef(function View(props, ref) {
166
- const {
167
- testId,
168
- tag = "div"
169
- } = props,
170
- restProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded);
171
- const commonProps = _extends__default["default"]({}, restProps, {
172
- "data-testid": testId
173
- });
174
- const StyledTag = React.useMemo(() => addStyle(tag, styles.default), [tag]);
175
- return React__namespace.createElement(StyledTag, _extends__default["default"]({}, commonProps, {
176
- ref: ref
177
- }));
178
- });
35
+ const styles=aphrodite.StyleSheet.create({default:{alignItems:"stretch",borderWidth:0,borderStyle:"solid",boxSizing:"border-box",display:"flex",flexDirection:"column",margin:0,padding:0,position:"relative",zIndex:0,minHeight:0,minWidth:0}});const View=React__namespace.forwardRef(function View(props,ref){const{testId,tag="div",...restProps}=props;const commonProps={...restProps,"data-testid":testId};const StyledTag=React.useMemo(()=>addStyle(tag,styles.default),[tag]);return jsxRuntime.jsx(StyledTag,{...commonProps,ref:ref})});
179
36
 
180
- let RenderState = function (RenderState) {
181
- RenderState["Initial"] = "initial";
182
- RenderState["Standard"] = "standard";
183
- return RenderState;
184
- }({});
185
- let RenderStateInternal = function (RenderStateInternal) {
186
- RenderStateInternal["Root"] = "root";
187
- RenderStateInternal["Initial"] = "initial";
188
- RenderStateInternal["Standard"] = "standard";
189
- return RenderStateInternal;
190
- }({});
191
- const RenderStateContext = React__namespace.createContext(RenderStateInternal.Root);
192
- RenderStateContext.displayName = "RenderStateContext";
37
+ var RenderState=/*#__PURE__*/function(RenderState){RenderState["Initial"]="initial";RenderState["Standard"]="standard";return RenderState}({});var RenderStateInternal=/*#__PURE__*/function(RenderStateInternal){RenderStateInternal["Root"]="root";RenderStateInternal["Initial"]="initial";RenderStateInternal["Standard"]="standard";return RenderStateInternal}({});const RenderStateContext=React__namespace.createContext("root");RenderStateContext.displayName="RenderStateContext";
193
38
 
194
- class InitialFallback extends React__namespace.Component {
195
- constructor(...args) {
196
- super(...args);
197
- this.state = {
198
- mounted: false
199
- };
200
- this._isTheRootComponent = false;
201
- }
202
- componentDidMount() {
203
- if (this._isTheRootComponent) {
204
- this.setState({
205
- mounted: true
206
- });
207
- }
208
- }
209
- _renderAsRootComponent() {
210
- const {
211
- mounted
212
- } = this.state;
213
- const {
214
- children,
215
- fallback
216
- } = this.props;
217
- this._isTheRootComponent = true;
218
- if (mounted) {
219
- return React__namespace.createElement(RenderStateContext.Provider, {
220
- value: RenderStateInternal.Standard
221
- }, children());
222
- }
223
- if (fallback) {
224
- return React__namespace.createElement(RenderStateContext.Provider, {
225
- value: RenderStateInternal.Initial
226
- }, fallback());
227
- }
228
- return null;
229
- }
230
- _maybeRender(renderState) {
231
- const {
232
- children,
233
- fallback
234
- } = this.props;
235
- switch (renderState) {
236
- case RenderStateInternal.Root:
237
- return this._renderAsRootComponent();
238
- case RenderStateInternal.Initial:
239
- return fallback ? fallback() : null;
240
- case RenderStateInternal.Standard:
241
- return children();
242
- }
243
- {
244
- var _JSON$stringify;
245
- console.log(`We got a render state we don't understand: "${(_JSON$stringify = JSON.stringify(renderState)) != null ? _JSON$stringify : ""}"`);
246
- return this._maybeRender(RenderStateInternal.Root);
247
- }
248
- }
249
- render() {
250
- return React__namespace.createElement(RenderStateContext.Consumer, null, value => this._maybeRender(value));
251
- }
252
- }
39
+ class InitialFallback extends React__namespace.Component{componentDidMount(){if(this._isTheRootComponent){this.setState({mounted:true});}}_renderAsRootComponent(){const{mounted}=this.state;const{children,fallback}=this.props;this._isTheRootComponent=true;if(mounted){return jsxRuntime.jsx(RenderStateContext.Provider,{value:RenderStateInternal.Standard,children:children()})}if(fallback){return jsxRuntime.jsx(RenderStateContext.Provider,{value:RenderStateInternal.Initial,children:fallback()})}return null}_maybeRender(renderState){const{children,fallback}=this.props;switch(renderState){case RenderStateInternal.Root:return this._renderAsRootComponent();case RenderStateInternal.Initial:return fallback?fallback():null;case RenderStateInternal.Standard:return children()}{console.log(`We got a render state we don't understand: "${JSON.stringify(renderState)??""}"`);return this._maybeRender(RenderStateInternal.Root)}}render(){return jsxRuntime.jsx(RenderStateContext.Consumer,{children:value=>this._maybeRender(value)})}constructor(...args){super(...args),this.state={mounted:false},this._isTheRootComponent=false;}}
253
40
 
254
- let serverSide = false;
255
- var Server = {
256
- isServerSide: () => serverSide,
257
- setServerSide: () => {
258
- serverSide = true;
259
- }
260
- };
41
+ let serverSide=false;var Server = {isServerSide:()=>serverSide,setServerSide:()=>{serverSide=true;}};
261
42
 
262
- const Id = ({
263
- id,
264
- children
265
- }) => {
266
- const generatedId = React.useId();
267
- return React__namespace.createElement(React__namespace.Fragment, null, children(id != null ? id : generatedId));
268
- };
43
+ const Id=({id,children})=>{const generatedId=React.useId();return jsxRuntime.jsx(jsxRuntime.Fragment,{children:children(id??generatedId)})};
269
44
 
270
- const useForceUpdate = () => {
271
- const [, setUpdateState] = React__namespace.useState({});
272
- const forceUpdate = React__namespace.useCallback(() => {
273
- setUpdateState({});
274
- }, []);
275
- return forceUpdate;
276
- };
45
+ const useForceUpdate=()=>{const[,setUpdateState]=React__namespace.useState({});const forceUpdate=React__namespace.useCallback(()=>{setUpdateState({});},[]);return forceUpdate};
277
46
 
278
- const useIsMounted = () => {
279
- const isMountedRef = React__namespace.useRef(false);
280
- const isMounted = React__namespace.useCallback(() => isMountedRef.current, []);
281
- React__namespace.useEffect(() => {
282
- isMountedRef.current = true;
283
- return () => {
284
- isMountedRef.current = false;
285
- };
286
- }, []);
287
- return isMounted;
288
- };
47
+ const useIsMounted=()=>{const isMountedRef=React__namespace.useRef(false);const isMounted=React__namespace.useCallback(()=>isMountedRef.current,[]);React__namespace.useEffect(()=>{isMountedRef.current=true;return ()=>{isMountedRef.current=false;}},[]);return isMounted};
289
48
 
290
- function useLatestRef(value) {
291
- const ref = React__namespace.useRef(value);
292
- ref.current = value;
293
- return ref;
294
- }
49
+ function useLatestRef(value){const ref=React__namespace.useRef(value);ref.current=value;return ref}
295
50
 
296
- const useOnMountEffect = callback => {
297
- const isMountedRef = React__namespace.useRef(true);
298
- React__namespace.useEffect(() => {
299
- const cleanup = callback(isMountedRef);
300
- return () => {
301
- cleanup == null || cleanup();
302
- isMountedRef.current = false;
303
- };
304
- }, []);
305
- };
51
+ const useOnMountEffect=callback=>{const isMountedRef=React__namespace.useRef(true);React__namespace.useEffect(()=>{const cleanup=callback(isMountedRef);return ()=>{cleanup?.();isMountedRef.current=false;}},[]);};
306
52
 
307
- const useOnline = () => {
308
- const forceUpdate = useForceUpdate();
309
- React.useEffect(() => {
310
- const handleChange = () => forceUpdate();
311
- window.addEventListener("online", handleChange);
312
- window.addEventListener("offline", handleChange);
313
- return () => {
314
- window.removeEventListener("online", handleChange);
315
- window.removeEventListener("offline", handleChange);
316
- };
317
- }, [forceUpdate]);
318
- return navigator.onLine;
319
- };
53
+ const useOnline=()=>{const forceUpdate=useForceUpdate();React.useEffect(()=>{const handleChange=()=>forceUpdate();window.addEventListener("online",handleChange);window.addEventListener("offline",handleChange);return ()=>{window.removeEventListener("online",handleChange);window.removeEventListener("offline",handleChange);}},[forceUpdate]);return navigator.onLine};
320
54
 
321
- const usePreHydrationEffect = effect => {
322
- const effectCallRef = React__namespace.useRef(Server.isServerSide() ? () => {} : React__namespace.useLayoutEffect);
323
- effectCallRef.current(effect, []);
324
- };
55
+ const usePreHydrationEffect=effect=>{const effectCallRef=React__namespace.useRef(Server.isServerSide()?()=>{}:React__namespace.useLayoutEffect);effectCallRef.current(effect,[]);};
325
56
 
326
- const useRenderState = () => {
327
- const rawRenderState = React.useContext(RenderStateContext);
328
- if (rawRenderState === RenderStateInternal.Standard) {
329
- return RenderState.Standard;
330
- } else {
331
- return RenderState.Initial;
332
- }
333
- };
57
+ const useRenderState=()=>{const rawRenderState=React.useContext(RenderStateContext);if(rawRenderState===RenderStateInternal.Standard){return RenderState.Standard}else {return RenderState.Initial}};
334
58
 
335
- const {
336
- useEffect,
337
- useState,
338
- useContext
339
- } = React__namespace;
340
- const RenderStateRoot = ({
341
- children,
342
- throwIfNested: _throwIfNested = true
343
- }) => {
344
- const [firstRender, setFirstRender] = useState(true);
345
- const renderState = useContext(RenderStateContext);
346
- useEffect(() => {
347
- setFirstRender(false);
348
- }, []);
349
- if (renderState !== RenderStateInternal.Root) {
350
- if (_throwIfNested) {
351
- throw new Error("There's already a <RenderStateRoot> above this instance in " + "the render tree. This instance should be removed.");
352
- }
353
- return React__namespace.createElement(React__namespace.Fragment, null, children);
354
- }
355
- const value = firstRender ? RenderStateInternal.Initial : RenderStateInternal.Standard;
356
- return React__namespace.createElement(RenderStateContext.Provider, {
357
- value: value
358
- }, children);
359
- };
59
+ const{useEffect,useState,useContext}=React__namespace;const RenderStateRoot=({children,throwIfNested=true})=>{const[firstRender,setFirstRender]=useState(true);const renderState=useContext(RenderStateContext);useEffect(()=>{setFirstRender(false);},[]);if(renderState!==RenderStateInternal.Root){if(throwIfNested){throw new Error("There's already a <RenderStateRoot> above this instance in "+"the render tree. This instance should be removed.")}return jsxRuntime.jsx(jsxRuntime.Fragment,{children:children})}const value=firstRender?RenderStateInternal.Initial:RenderStateInternal.Standard;return jsxRuntime.jsx(RenderStateContext.Provider,{value:value,children:children})};
360
60
 
361
- const keys = {
362
- enter: "Enter",
363
- escape: "Escape",
364
- tab: "Tab",
365
- space: " ",
366
- up: "ArrowUp",
367
- down: "ArrowDown"
368
- };
61
+ const keys={enter:"Enter",escape:"Escape",tab:"Tab",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End"};
369
62
 
370
63
  exports.Id = Id;
371
64
  exports.InitialFallback = InitialFallback;
@@ -0,0 +1,6 @@
1
+ export declare function findFocusableNodes(root: HTMLElement | Document): Array<HTMLElement>;
2
+ /**
3
+ * Checks if an element is focusable
4
+ * @see https://html.spec.whatwg.org/multipage/interaction.html#focusable-area
5
+ */
6
+ export declare function isFocusable(element: HTMLElement): boolean;
@@ -9,4 +9,8 @@ export declare const keys: {
9
9
  readonly space: " ";
10
10
  readonly up: "ArrowUp";
11
11
  readonly down: "ArrowDown";
12
+ readonly left: "ArrowLeft";
13
+ readonly right: "ArrowRight";
14
+ readonly home: "Home";
15
+ readonly end: "End";
12
16
  };
@@ -71,6 +71,10 @@ export type TextViewSharedProps = {
71
71
  * Optional CSS classes for the entire dropdown component.
72
72
  */
73
73
  className?: string;
74
+ /**
75
+ * The text direction for the element.
76
+ */
77
+ dir?: "ltr" | "rtl" | "auto";
74
78
  htmlFor?: string;
75
79
  tabIndex?: number;
76
80
  id?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-core",
3
- "version": "12.2.1",
3
+ "version": "12.4.0",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -9,19 +9,18 @@
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/es/index.js",
11
11
  "types": "dist/index.d.ts",
12
- "dependencies": {
13
- "@babel/runtime": "^7.24.5"
14
- },
12
+ "dependencies": {},
15
13
  "peerDependencies": {
16
14
  "aphrodite": "^1.2.5",
17
15
  "react": "18.2.0",
18
16
  "react-dom": "18.2.0",
19
17
  "react-router": "5.3.4",
20
- "react-router-dom": "5.3.4"
18
+ "react-router-dom": "5.3.4",
19
+ "react-router-dom-v5-compat": "^6.30.0"
21
20
  },
22
21
  "devDependencies": {
23
- "@khanacademy/wb-dev-build-settings": "2.1.1",
24
- "@khanacademy/wonder-blocks-testing-core": "2.2.1"
22
+ "@khanacademy/wb-dev-build-settings": "3.2.0",
23
+ "@khanacademy/wonder-blocks-testing-core": "3.0.1"
25
24
  },
26
25
  "author": "",
27
26
  "license": "MIT",