@khanacademy/math-input 17.0.3 → 17.0.5

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.
Files changed (84) hide show
  1. package/dist/es/index.js +2 -2
  2. package/dist/es/index.js.map +1 -1
  3. package/dist/index.js +2 -2
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -2
  6. package/.eslintrc.js +0 -18
  7. package/CHANGELOG.md +0 -654
  8. package/less/main.less +0 -2
  9. package/less/overrides.less +0 -122
  10. package/src/components/__tests__/integration.test.tsx +0 -300
  11. package/src/components/aphrodite-css-transition-group/index.tsx +0 -78
  12. package/src/components/aphrodite-css-transition-group/transition-child.tsx +0 -192
  13. package/src/components/aphrodite-css-transition-group/types.ts +0 -20
  14. package/src/components/aphrodite-css-transition-group/util.ts +0 -97
  15. package/src/components/input/__tests__/context-tracking.test.ts +0 -176
  16. package/src/components/input/__tests__/mathquill-helpers.test.ts +0 -105
  17. package/src/components/input/__tests__/mathquill.test.ts +0 -747
  18. package/src/components/input/__tests__/test-math-wrapper.ts +0 -29
  19. package/src/components/input/cursor-contexts.ts +0 -37
  20. package/src/components/input/cursor-handle.tsx +0 -137
  21. package/src/components/input/cursor-styles.ts +0 -10
  22. package/src/components/input/drag-listener.ts +0 -79
  23. package/src/components/input/math-input.tsx +0 -1036
  24. package/src/components/input/math-wrapper.ts +0 -189
  25. package/src/components/input/mathquill-helpers.ts +0 -262
  26. package/src/components/input/mathquill-instance.ts +0 -106
  27. package/src/components/input/mathquill-types.ts +0 -32
  28. package/src/components/input/scroll-into-view.ts +0 -65
  29. package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +0 -94
  30. package/src/components/key-handlers/handle-arrow.ts +0 -70
  31. package/src/components/key-handlers/handle-backspace.ts +0 -277
  32. package/src/components/key-handlers/handle-exponent.ts +0 -53
  33. package/src/components/key-handlers/handle-jump-out.ts +0 -107
  34. package/src/components/key-handlers/key-translator.ts +0 -222
  35. package/src/components/keypad/__tests__/__snapshots__/keypad.test.tsx.snap +0 -1913
  36. package/src/components/keypad/__tests__/__snapshots__/mobile-keypad.test.tsx.snap +0 -600
  37. package/src/components/keypad/__tests__/keypad-button.test.tsx +0 -84
  38. package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +0 -304
  39. package/src/components/keypad/__tests__/keypad-v2.cypress.ts +0 -16
  40. package/src/components/keypad/__tests__/keypad.test.tsx +0 -321
  41. package/src/components/keypad/__tests__/mobile-keypad.test.tsx +0 -115
  42. package/src/components/keypad/__tests__/test-data-tabs.ts +0 -21
  43. package/src/components/keypad/button-assets.tsx +0 -1880
  44. package/src/components/keypad/index.tsx +0 -2
  45. package/src/components/keypad/keypad-button.stories.tsx +0 -81
  46. package/src/components/keypad/keypad-button.tsx +0 -124
  47. package/src/components/keypad/keypad-mathquill.stories.tsx +0 -109
  48. package/src/components/keypad/keypad-pages/extras-page.tsx +0 -35
  49. package/src/components/keypad/keypad-pages/fractions-page.tsx +0 -125
  50. package/src/components/keypad/keypad-pages/geometry-page.tsx +0 -34
  51. package/src/components/keypad/keypad-pages/keypad-pages.stories.tsx +0 -37
  52. package/src/components/keypad/keypad-pages/numbers-page.tsx +0 -94
  53. package/src/components/keypad/keypad-pages/operators-page.tsx +0 -117
  54. package/src/components/keypad/keypad.tsx +0 -233
  55. package/src/components/keypad/mobile-keypad-internals.tsx +0 -240
  56. package/src/components/keypad/mobile-keypad.tsx +0 -24
  57. package/src/components/keypad/navigation-button.tsx +0 -127
  58. package/src/components/keypad/navigation-pad.stories.tsx +0 -26
  59. package/src/components/keypad/navigation-pad.tsx +0 -67
  60. package/src/components/keypad/shared-keys.tsx +0 -109
  61. package/src/components/keypad/utils.ts +0 -34
  62. package/src/components/keypad-context.tsx +0 -70
  63. package/src/components/prop-types.ts +0 -16
  64. package/src/components/tabbar/__tests__/tabbar.test.tsx +0 -105
  65. package/src/components/tabbar/icons.tsx +0 -122
  66. package/src/components/tabbar/index.ts +0 -1
  67. package/src/components/tabbar/item.tsx +0 -146
  68. package/src/components/tabbar/tabbar.stories.tsx +0 -83
  69. package/src/components/tabbar/tabbar.tsx +0 -65
  70. package/src/data/key-configs.ts +0 -770
  71. package/src/data/keys.ts +0 -123
  72. package/src/enums.ts +0 -27
  73. package/src/fake-react-native-web/index.ts +0 -11
  74. package/src/fake-react-native-web/text.tsx +0 -55
  75. package/src/fake-react-native-web/view.tsx +0 -91
  76. package/src/full-keypad.stories.tsx +0 -142
  77. package/src/full-mobile-input.stories.tsx +0 -115
  78. package/src/index.ts +0 -52
  79. package/src/types.ts +0 -70
  80. package/src/utils.test.ts +0 -33
  81. package/src/utils.ts +0 -61
  82. package/src/version.ts +0 -10
  83. package/tsconfig-build.json +0 -11
  84. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,127 +0,0 @@
1
- import Clickable from "@khanacademy/wonder-blocks-clickable";
2
- import Color from "@khanacademy/wonder-blocks-color";
3
- import {View} from "@khanacademy/wonder-blocks-core";
4
- import {StyleSheet} from "aphrodite";
5
- import * as React from "react";
6
-
7
- import ButtonAsset from "./button-assets";
8
-
9
- import type Key from "../../data/keys";
10
- import type {KeyConfig, ClickKeyCallback} from "../../types";
11
-
12
- export type KeypadButtonProps = {
13
- // 0 indexed [x, y] position in keypad CSS grid
14
- coord: readonly [number, number];
15
- keyConfig: KeyConfig;
16
- onClickKey: ClickKeyCallback;
17
- };
18
-
19
- function getStyles(key: Key) {
20
- switch (key) {
21
- case "UP":
22
- return styles.up;
23
- case "RIGHT":
24
- return styles.right;
25
- case "DOWN":
26
- return styles.down;
27
- case "LEFT":
28
- return styles.left;
29
- default:
30
- throw new Error(`Invalid key: ${key}`);
31
- }
32
- }
33
-
34
- export default function NavigationButton({
35
- coord,
36
- keyConfig,
37
- onClickKey,
38
- }: KeypadButtonProps) {
39
- const key = keyConfig.id;
40
- const directionalStyles = getStyles(key);
41
-
42
- return (
43
- <View
44
- style={{
45
- gridColumn: coord[0] + 1,
46
- gridRow: coord[1] + 1,
47
- }}
48
- >
49
- <Clickable
50
- onClick={(e) => onClickKey(keyConfig.id, e)}
51
- style={styles.clickable}
52
- aria-label={keyConfig.ariaLabel}
53
- >
54
- {({hovered, focused, pressed}) => (
55
- <View style={styles.outerBoxBase}>
56
- <View
57
- style={[
58
- styles.base,
59
- directionalStyles,
60
- hovered && styles.hovered,
61
- focused && styles.focused,
62
- pressed && styles.pressed,
63
- ]}
64
- >
65
- <ButtonAsset id={keyConfig.id} />
66
- </View>
67
- </View>
68
- )}
69
- </Clickable>
70
- </View>
71
- );
72
- }
73
-
74
- const borderRadiusPx = 4;
75
-
76
- const styles = StyleSheet.create({
77
- clickable: {
78
- width: "100%",
79
- height: "100%",
80
-
81
- ":focus": {
82
- outline: `none`,
83
- },
84
- },
85
- outerBoxBase: {
86
- height: "100%",
87
- width: "100%",
88
- },
89
- base: {
90
- boxShadow: `0px 1px 0px ${Color.offBlack32}`,
91
- display: "flex",
92
- justifyContent: "center",
93
- alignItems: "center",
94
- background: Color.white,
95
- borderWidth: 2,
96
- borderColor: Color.white,
97
- },
98
- up: {
99
- borderTopLeftRadius: borderRadiusPx,
100
- borderTopRightRadius: borderRadiusPx,
101
- },
102
- right: {
103
- borderTopRightRadius: borderRadiusPx,
104
- borderBottomRightRadius: borderRadiusPx,
105
- },
106
- down: {
107
- borderBottomLeftRadius: borderRadiusPx,
108
- borderBottomRightRadius: borderRadiusPx,
109
- },
110
- left: {
111
- borderTopLeftRadius: borderRadiusPx,
112
- borderBottomLeftRadius: borderRadiusPx,
113
- },
114
- hovered: {
115
- borderColor: Color.blue,
116
- boxShadow: "none",
117
- },
118
- focused: {
119
- borderColor: Color.blue,
120
- boxShadow: "none",
121
- },
122
- pressed: {
123
- border: "2px solid #1B50B3",
124
- background: `linear-gradient(0deg, rgba(24, 101, 242, 0.32), rgba(24, 101, 242, 0.32)), ${Color.white}`,
125
- boxShadow: "none",
126
- },
127
- });
@@ -1,26 +0,0 @@
1
- import {action} from "@storybook/addon-actions";
2
- import * as React from "react";
3
-
4
- import NavigationPad from "./navigation-pad";
5
-
6
- export default {
7
- title: "math-input/components/MathInput v2 Navigation Pad",
8
- parameters: {
9
- backgrounds: {
10
- default: "light background",
11
- values: [
12
- // We want a slightly darker default bg so that we can
13
- // see the top of the keypad when it is open
14
- {name: "light background", value: "lightgrey", default: true},
15
- ],
16
- },
17
- },
18
- };
19
-
20
- export function basic() {
21
- return (
22
- <div style={{padding: 50}}>
23
- <NavigationPad onClickKey={action("onClickKey")} />
24
- </div>
25
- );
26
- }
@@ -1,67 +0,0 @@
1
- import Color from "@khanacademy/wonder-blocks-color";
2
- import {View} from "@khanacademy/wonder-blocks-core";
3
- import {StyleSheet} from "aphrodite";
4
- import * as React from "react";
5
-
6
- import Keys from "../../data/key-configs";
7
-
8
- import NavigationButton from "./navigation-button";
9
-
10
- import type {ClickKeyCallback} from "../../types";
11
-
12
- export type Props = {
13
- onClickKey: ClickKeyCallback;
14
- };
15
-
16
- export default function NavigationPad(props: Props) {
17
- const {onClickKey} = props;
18
-
19
- return (
20
- <View style={styles.container}>
21
- <View style={styles.grid}>
22
- <NavigationButton
23
- keyConfig={Keys.UP}
24
- onClickKey={onClickKey}
25
- coord={[1, 0]}
26
- />
27
- <NavigationButton
28
- keyConfig={Keys.RIGHT}
29
- onClickKey={onClickKey}
30
- coord={[2, 1]}
31
- />
32
- <NavigationButton
33
- keyConfig={Keys.DOWN}
34
- onClickKey={onClickKey}
35
- coord={[1, 2]}
36
- />
37
- <NavigationButton
38
- keyConfig={Keys.LEFT}
39
- onClickKey={onClickKey}
40
- coord={[0, 1]}
41
- />
42
- <View style={styles.spacer} />
43
- </View>
44
- </View>
45
- );
46
- }
47
-
48
- const styles = StyleSheet.create({
49
- container: {
50
- display: "flex",
51
- alignItems: "center",
52
- justifyContent: "center",
53
- padding: "0 1.5rem",
54
- },
55
- grid: {
56
- width: 140,
57
- height: 140,
58
- display: "grid",
59
- gridTemplateColumns: "repeat(3, 1fr)",
60
- gridTemplateRows: "repeat(3, 1fr)",
61
- },
62
- spacer: {
63
- gridColumn: 2,
64
- gridRow: 2,
65
- background: Color.white,
66
- },
67
- });
@@ -1,109 +0,0 @@
1
- import * as React from "react";
2
-
3
- import Keys from "../../data/key-configs";
4
- import {convertDotToTimesByLocale} from "../../utils";
5
-
6
- import {KeypadButton} from "./keypad-button";
7
- import {getCursorContextConfig} from "./utils";
8
-
9
- import type {ClickKeyCallback, KeypadPageType} from "../../types";
10
- import type {CursorContext} from "../input/cursor-contexts";
11
-
12
- type Props = {
13
- onClickKey: ClickKeyCallback;
14
- selectedPage: KeypadPageType;
15
- cursorContext?: typeof CursorContext[keyof typeof CursorContext];
16
- convertDotToTimes?: boolean;
17
- divisionKey?: boolean;
18
- };
19
-
20
- export default function SharedKeys(props: Props) {
21
- const {
22
- onClickKey,
23
- cursorContext,
24
- divisionKey,
25
- convertDotToTimes,
26
- selectedPage,
27
- } = props;
28
-
29
- const cursorKeyConfig = getCursorContextConfig(cursorContext);
30
-
31
- // Fraction position depends on the page
32
- const fractionCoord: readonly [number, number] =
33
- selectedPage === "Numbers" || selectedPage === "Operators"
34
- ? [3, 1]
35
- : [3, 0];
36
-
37
- return (
38
- <>
39
- <KeypadButton
40
- keyConfig={Keys.FRAC}
41
- onClickKey={onClickKey}
42
- coord={fractionCoord}
43
- secondary
44
- />
45
- <KeypadButton
46
- keyConfig={Keys.PLUS}
47
- onClickKey={onClickKey}
48
- coord={[4, 0]}
49
- secondary
50
- />
51
- <KeypadButton
52
- keyConfig={Keys.MINUS}
53
- onClickKey={onClickKey}
54
- coord={[5, 0]}
55
- secondary
56
- />
57
-
58
- {/* Row 2 */}
59
- <KeypadButton
60
- keyConfig={
61
- convertDotToTimesByLocale(!!convertDotToTimes)
62
- ? Keys.TIMES
63
- : Keys.CDOT
64
- }
65
- onClickKey={onClickKey}
66
- coord={[4, 1]}
67
- secondary
68
- />
69
- {divisionKey && (
70
- <KeypadButton
71
- keyConfig={Keys.DIVIDE}
72
- onClickKey={onClickKey}
73
- coord={[5, 1]}
74
- secondary
75
- />
76
- )}
77
-
78
- {/* Row 3 */}
79
- <KeypadButton
80
- keyConfig={Keys.LEFT_PAREN}
81
- onClickKey={onClickKey}
82
- coord={[4, 2]}
83
- secondary
84
- />
85
- <KeypadButton
86
- keyConfig={Keys.RIGHT_PAREN}
87
- onClickKey={onClickKey}
88
- coord={[5, 2]}
89
- secondary
90
- />
91
-
92
- {/* Row 4 */}
93
- {cursorKeyConfig && (
94
- <KeypadButton
95
- keyConfig={cursorKeyConfig}
96
- onClickKey={onClickKey}
97
- coord={[4, 3]}
98
- secondary
99
- />
100
- )}
101
- <KeypadButton
102
- keyConfig={Keys.BACKSPACE}
103
- onClickKey={onClickKey}
104
- coord={[5, 3]}
105
- action
106
- />
107
- </>
108
- );
109
- }
@@ -1,34 +0,0 @@
1
- import Keys from "../../data/key-configs";
2
- import {CursorContext} from "../input/cursor-contexts";
3
-
4
- // This is just a magic number, I just played around with it
5
- // until the transition from expanded -> regular -> expanded felt natural
6
- export const expandedViewThreshold = 500;
7
-
8
- // This is a helper function that returns the correct context for the cursor
9
- // based on the cursorContext prop. It is used in the keypad to determine
10
- // which key to render as the "jump out" key.
11
- export function getCursorContextConfig(
12
- cursorContext?: typeof CursorContext[keyof typeof CursorContext],
13
- ) {
14
- if (!cursorContext) {
15
- return null;
16
- }
17
-
18
- switch (cursorContext) {
19
- case CursorContext.NONE:
20
- return null;
21
- case CursorContext.IN_PARENS:
22
- return Keys.JUMP_OUT_PARENTHESES;
23
- case CursorContext.IN_SUPER_SCRIPT:
24
- return Keys.JUMP_OUT_EXPONENT;
25
- case CursorContext.IN_SUB_SCRIPT:
26
- return Keys.JUMP_OUT_BASE;
27
- case CursorContext.IN_NUMERATOR:
28
- return Keys.JUMP_OUT_NUMERATOR;
29
- case CursorContext.IN_DENOMINATOR:
30
- return Keys.JUMP_OUT_DENOMINATOR;
31
- case CursorContext.BEFORE_FRACTION:
32
- return Keys.JUMP_INTO_NUMERATOR;
33
- }
34
- }
@@ -1,70 +0,0 @@
1
- /**
2
- * KeypadContext provides a way to the Keypad and Perseus Renderers to
3
- * communicate.
4
- *
5
- * The StatefulKeypadContextProvider wraps the application
6
- * while KeypadContext.Consumer wraps things that need this state:
7
- * - mobile keypad usages
8
- * - Perseus Renderers (Server/Item/Article)
9
- */
10
- import * as React from "react";
11
- import {useState, useMemo} from "react";
12
-
13
- import type {KeypadAPI, KeypadContextType} from "../types";
14
- import type {KeypadContextRendererInterface} from "@khanacademy/perseus-core";
15
-
16
- // @ts-expect-error - TS2322 - Type 'Context<{ setKeypadElement: (keypadElement: HTMLElement | null | undefined) => void; keypadElement: null; setRenderer: (renderer: RendererInterface | null | undefined) => void; renderer: null; setScrollableElement: (scrollableElement: HTMLElement | ... 1 more ... | undefined) => void; scrollableElement: null; }>' is not assignable to type 'Context<KeypadContext>'.
17
- export const KeypadContext: React.Context<KeypadContextType> =
18
- React.createContext({
19
- setKeypadActive: (keypadActive) => {},
20
- keypadActive: false,
21
- setKeypadElement: (keypadElement) => {},
22
- keypadElement: null,
23
- setRenderer: (renderer) => {},
24
- renderer: null,
25
- setScrollableElement: (scrollableElement) => {},
26
- scrollableElement: null,
27
- });
28
-
29
- type Props = React.PropsWithChildren<unknown>;
30
-
31
- export function StatefulKeypadContextProvider(props: Props) {
32
- // whether or not to display the keypad
33
- const [keypadActive, setKeypadActive] = useState<boolean>(false);
34
- // used to communicate between the keypad and the Renderer
35
- const [keypadElement, setKeypadElement] = useState<KeypadAPI | null>();
36
- // this is a KeypadContextRendererInterface from Perseus
37
- const [renderer, setRenderer] =
38
- useState<KeypadContextRendererInterface | null>();
39
- const [scrollableElement, setScrollableElement] =
40
- useState<HTMLElement | null>();
41
-
42
- const memoizedValue = useMemo(
43
- () => ({
44
- keypadActive,
45
- setKeypadActive,
46
- keypadElement,
47
- setKeypadElement,
48
- renderer,
49
- setRenderer,
50
- scrollableElement,
51
- setScrollableElement,
52
- }),
53
- [
54
- keypadActive,
55
- setKeypadActive,
56
- keypadElement,
57
- setKeypadElement,
58
- renderer,
59
- setRenderer,
60
- scrollableElement,
61
- setScrollableElement,
62
- ],
63
- );
64
-
65
- return (
66
- <KeypadContext.Provider value={memoizedValue}>
67
- {props.children}
68
- </KeypadContext.Provider>
69
- );
70
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * React PropTypes that may be shared between components.
3
- */
4
-
5
- import PropTypes from "prop-types";
6
-
7
- // NOTE(jared): This is no longer guaranteed to be React element
8
- // @deprecated Use `KeypadAPI` Typescript interface instead.
9
- export const keypadElementPropType = PropTypes.shape({
10
- activate: PropTypes.func.isRequired,
11
- dismiss: PropTypes.func.isRequired,
12
- configure: PropTypes.func.isRequired,
13
- setCursor: PropTypes.func.isRequired,
14
- setKeyHandler: PropTypes.func.isRequired,
15
- getDOMNode: PropTypes.func.isRequired,
16
- });
@@ -1,105 +0,0 @@
1
- import {render, screen} from "@testing-library/react";
2
- import userEvent from "@testing-library/user-event";
3
- import * as React from "react";
4
- import "@testing-library/jest-dom";
5
-
6
- import Tabbar from "../tabbar";
7
-
8
- describe("<Tabbar />", () => {
9
- it("renders one tab", () => {
10
- // Arrange
11
- render(
12
- <Tabbar
13
- items={["Numbers"]}
14
- selectedItem={"Numbers"}
15
- onSelectItem={() => {}}
16
- />,
17
- );
18
-
19
- // Assert
20
- expect(screen.getByRole("tab", {name: "Numbers"})).toBeInTheDocument();
21
- });
22
-
23
- it("renders many tabs", () => {
24
- // Arrange
25
- render(
26
- <Tabbar
27
- items={["Numbers", "Extras", "Geometry", "Operators"]}
28
- selectedItem={"Numbers"}
29
- onSelectItem={() => {}}
30
- />,
31
- );
32
-
33
- // Assert
34
- expect(screen.getByRole("tab", {name: "Numbers"})).toBeInTheDocument();
35
- expect(screen.getByRole("tab", {name: "Extras"})).toBeInTheDocument();
36
- expect(screen.getByRole("tab", {name: "Geometry"})).toBeInTheDocument();
37
- expect(
38
- screen.getByRole("tab", {name: "Operators"}),
39
- ).toBeInTheDocument();
40
- });
41
-
42
- it("handles callback", () => {
43
- // Arrange
44
- const mockSelectCallback = jest.fn();
45
- render(
46
- <Tabbar
47
- items={["Numbers", "Geometry"]}
48
- selectedItem={"Numbers"}
49
- onSelectItem={mockSelectCallback}
50
- />,
51
- );
52
-
53
- // Assert
54
- userEvent.click(screen.getByRole("tab", {name: "Geometry"}));
55
- expect(mockSelectCallback).toHaveBeenCalledWith("Geometry");
56
- });
57
-
58
- it("shows dismiss button with a onClickClose callback", () => {
59
- // Arrange
60
- render(
61
- <Tabbar
62
- items={["Numbers"]}
63
- selectedItem={"Numbers"}
64
- onSelectItem={() => {}}
65
- onClickClose={() => {}}
66
- />,
67
- );
68
-
69
- // Assert
70
- expect(screen.getByRole("tab", {name: "Dismiss"})).toBeInTheDocument();
71
- });
72
-
73
- it("does not show dismiss button without onClickClose callback", () => {
74
- // Arrange
75
- render(
76
- <Tabbar
77
- items={["Numbers"]}
78
- selectedItem={"Numbers"}
79
- onSelectItem={() => {}}
80
- />,
81
- );
82
-
83
- // Assert
84
- expect(
85
- screen.queryByRole("tab", {name: "Dismiss"}),
86
- ).not.toBeInTheDocument();
87
- });
88
-
89
- it("handles onClickClose callback", () => {
90
- // Arrange
91
- const mockClickCloseCallback = jest.fn();
92
- render(
93
- <Tabbar
94
- items={["Numbers", "Geometry"]}
95
- selectedItem={"Numbers"}
96
- onSelectItem={() => {}}
97
- onClickClose={mockClickCloseCallback}
98
- />,
99
- );
100
-
101
- // Assert
102
- userEvent.click(screen.getByRole("tab", {name: "Dismiss"}));
103
- expect(mockClickCloseCallback).toHaveBeenCalled();
104
- });
105
- });