@khanacademy/math-input 17.0.4 → 17.0.6
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/components/input/math-wrapper.d.ts +2 -2
- package/dist/components/input/mathquill-types.d.ts +49 -6
- package/dist/es/index.js +8 -6
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/.eslintrc.js +0 -18
- package/CHANGELOG.md +0 -660
- package/less/main.less +0 -2
- package/less/overrides.less +0 -122
- package/src/components/__tests__/integration.test.tsx +0 -300
- package/src/components/aphrodite-css-transition-group/index.tsx +0 -78
- package/src/components/aphrodite-css-transition-group/transition-child.tsx +0 -192
- package/src/components/aphrodite-css-transition-group/types.ts +0 -20
- package/src/components/aphrodite-css-transition-group/util.ts +0 -97
- package/src/components/input/__tests__/context-tracking.test.ts +0 -176
- package/src/components/input/__tests__/mathquill-helpers.test.ts +0 -105
- package/src/components/input/__tests__/mathquill.test.ts +0 -747
- package/src/components/input/__tests__/test-math-wrapper.ts +0 -29
- package/src/components/input/cursor-contexts.ts +0 -37
- package/src/components/input/cursor-handle.tsx +0 -137
- package/src/components/input/cursor-styles.ts +0 -10
- package/src/components/input/drag-listener.ts +0 -79
- package/src/components/input/math-input.tsx +0 -1036
- package/src/components/input/math-wrapper.ts +0 -189
- package/src/components/input/mathquill-helpers.ts +0 -262
- package/src/components/input/mathquill-instance.ts +0 -106
- package/src/components/input/mathquill-types.ts +0 -32
- package/src/components/input/scroll-into-view.ts +0 -65
- package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +0 -94
- package/src/components/key-handlers/handle-arrow.ts +0 -70
- package/src/components/key-handlers/handle-backspace.ts +0 -277
- package/src/components/key-handlers/handle-exponent.ts +0 -53
- package/src/components/key-handlers/handle-jump-out.ts +0 -107
- package/src/components/key-handlers/key-translator.ts +0 -222
- package/src/components/keypad/__tests__/__snapshots__/keypad.test.tsx.snap +0 -1913
- package/src/components/keypad/__tests__/__snapshots__/mobile-keypad.test.tsx.snap +0 -600
- package/src/components/keypad/__tests__/keypad-button.test.tsx +0 -84
- package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +0 -304
- package/src/components/keypad/__tests__/keypad-v2.cypress.ts +0 -16
- package/src/components/keypad/__tests__/keypad.test.tsx +0 -321
- package/src/components/keypad/__tests__/mobile-keypad.test.tsx +0 -115
- package/src/components/keypad/__tests__/test-data-tabs.ts +0 -21
- package/src/components/keypad/button-assets.tsx +0 -1880
- package/src/components/keypad/index.tsx +0 -2
- package/src/components/keypad/keypad-button.stories.tsx +0 -81
- package/src/components/keypad/keypad-button.tsx +0 -124
- package/src/components/keypad/keypad-mathquill.stories.tsx +0 -109
- package/src/components/keypad/keypad-pages/extras-page.tsx +0 -35
- package/src/components/keypad/keypad-pages/fractions-page.tsx +0 -125
- package/src/components/keypad/keypad-pages/geometry-page.tsx +0 -34
- package/src/components/keypad/keypad-pages/keypad-pages.stories.tsx +0 -37
- package/src/components/keypad/keypad-pages/numbers-page.tsx +0 -94
- package/src/components/keypad/keypad-pages/operators-page.tsx +0 -117
- package/src/components/keypad/keypad.tsx +0 -233
- package/src/components/keypad/mobile-keypad-internals.tsx +0 -240
- package/src/components/keypad/mobile-keypad.tsx +0 -24
- package/src/components/keypad/navigation-button.tsx +0 -127
- package/src/components/keypad/navigation-pad.stories.tsx +0 -26
- package/src/components/keypad/navigation-pad.tsx +0 -67
- package/src/components/keypad/shared-keys.tsx +0 -109
- package/src/components/keypad/utils.ts +0 -34
- package/src/components/keypad-context.tsx +0 -70
- package/src/components/prop-types.ts +0 -16
- package/src/components/tabbar/__tests__/tabbar.test.tsx +0 -105
- package/src/components/tabbar/icons.tsx +0 -122
- package/src/components/tabbar/index.ts +0 -1
- package/src/components/tabbar/item.tsx +0 -146
- package/src/components/tabbar/tabbar.stories.tsx +0 -83
- package/src/components/tabbar/tabbar.tsx +0 -65
- package/src/data/key-configs.ts +0 -770
- package/src/data/keys.ts +0 -123
- package/src/enums.ts +0 -27
- package/src/fake-react-native-web/index.ts +0 -11
- package/src/fake-react-native-web/text.tsx +0 -55
- package/src/fake-react-native-web/view.tsx +0 -91
- package/src/full-keypad.stories.tsx +0 -142
- package/src/full-mobile-input.stories.tsx +0 -115
- package/src/index.ts +0 -52
- package/src/types.ts +0 -70
- package/src/utils.test.ts +0 -33
- package/src/utils.ts +0 -61
- package/src/version.ts +0 -10
- package/tsconfig-build.json +0 -11
- package/tsconfig-build.tsbuildinfo +0 -1
package/src/data/keys.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
export const KeyArray = [
|
|
2
|
-
"PLUS",
|
|
3
|
-
"MINUS",
|
|
4
|
-
"NEGATIVE",
|
|
5
|
-
"TIMES",
|
|
6
|
-
"DIVIDE",
|
|
7
|
-
"DECIMAL",
|
|
8
|
-
"PERIOD",
|
|
9
|
-
"PERCENT",
|
|
10
|
-
"CDOT",
|
|
11
|
-
"EQUAL",
|
|
12
|
-
"NEQ",
|
|
13
|
-
"GT",
|
|
14
|
-
"LT",
|
|
15
|
-
"GEQ",
|
|
16
|
-
"LEQ", // mobile native only
|
|
17
|
-
"FRAC_INCLUSIVE", // mobile native only
|
|
18
|
-
"FRAC_EXCLUSIVE", // mobile native only
|
|
19
|
-
"FRAC",
|
|
20
|
-
"EXP",
|
|
21
|
-
"EXP_2",
|
|
22
|
-
"EXP_3",
|
|
23
|
-
"SQRT",
|
|
24
|
-
"CUBE_ROOT",
|
|
25
|
-
"RADICAL",
|
|
26
|
-
"LEFT_PAREN",
|
|
27
|
-
"RIGHT_PAREN",
|
|
28
|
-
"LN",
|
|
29
|
-
"LOG",
|
|
30
|
-
"LOG_N",
|
|
31
|
-
"SIN",
|
|
32
|
-
"COS", // TODO(charlie): Add in additional Greek letters.,
|
|
33
|
-
"TAN",
|
|
34
|
-
"PI",
|
|
35
|
-
"THETA",
|
|
36
|
-
"UP",
|
|
37
|
-
"RIGHT",
|
|
38
|
-
"DOWN",
|
|
39
|
-
"LEFT",
|
|
40
|
-
"BACKSPACE",
|
|
41
|
-
"DISMISS",
|
|
42
|
-
"JUMP_OUT_PARENTHESES",
|
|
43
|
-
"JUMP_OUT_EXPONENT",
|
|
44
|
-
"JUMP_OUT_BASE",
|
|
45
|
-
"JUMP_INTO_NUMERATOR",
|
|
46
|
-
"JUMP_OUT_NUMERATOR",
|
|
47
|
-
"JUMP_OUT_DENOMINATOR", // Multi-functional keys.
|
|
48
|
-
"NOOP", // mobile native only
|
|
49
|
-
"MANY", // A custom key that captures an arbitrary number of symbols but has no 'default' symbol or action.
|
|
50
|
-
"NUM_0",
|
|
51
|
-
"NUM_1",
|
|
52
|
-
"NUM_2",
|
|
53
|
-
"NUM_3",
|
|
54
|
-
"NUM_4",
|
|
55
|
-
"NUM_5",
|
|
56
|
-
"NUM_6",
|
|
57
|
-
"NUM_7",
|
|
58
|
-
"NUM_8",
|
|
59
|
-
"NUM_9",
|
|
60
|
-
"a",
|
|
61
|
-
"b",
|
|
62
|
-
"c",
|
|
63
|
-
"d",
|
|
64
|
-
"e",
|
|
65
|
-
"f",
|
|
66
|
-
"g",
|
|
67
|
-
"h",
|
|
68
|
-
"i",
|
|
69
|
-
"j",
|
|
70
|
-
"k",
|
|
71
|
-
"l",
|
|
72
|
-
"m",
|
|
73
|
-
"n",
|
|
74
|
-
"o",
|
|
75
|
-
"p",
|
|
76
|
-
"q",
|
|
77
|
-
"r",
|
|
78
|
-
"s",
|
|
79
|
-
"t",
|
|
80
|
-
"u",
|
|
81
|
-
"v",
|
|
82
|
-
"w",
|
|
83
|
-
"x",
|
|
84
|
-
"y",
|
|
85
|
-
"z",
|
|
86
|
-
"A",
|
|
87
|
-
"B",
|
|
88
|
-
"C",
|
|
89
|
-
"D",
|
|
90
|
-
"E",
|
|
91
|
-
"F",
|
|
92
|
-
"G",
|
|
93
|
-
"H",
|
|
94
|
-
"I",
|
|
95
|
-
"J",
|
|
96
|
-
"K",
|
|
97
|
-
"L",
|
|
98
|
-
"M",
|
|
99
|
-
"N",
|
|
100
|
-
"O",
|
|
101
|
-
"P",
|
|
102
|
-
"Q",
|
|
103
|
-
"R",
|
|
104
|
-
"S",
|
|
105
|
-
"T",
|
|
106
|
-
"U",
|
|
107
|
-
"V",
|
|
108
|
-
"W",
|
|
109
|
-
"X",
|
|
110
|
-
"Y",
|
|
111
|
-
"Z",
|
|
112
|
-
|
|
113
|
-
// Currently only used by
|
|
114
|
-
// Perseus' Expression MathInput
|
|
115
|
-
"PHI",
|
|
116
|
-
"NTHROOT3",
|
|
117
|
-
"POW",
|
|
118
|
-
"LOG_B",
|
|
119
|
-
] as const;
|
|
120
|
-
|
|
121
|
-
type Key = typeof KeyArray[number];
|
|
122
|
-
|
|
123
|
-
export default Key;
|
package/src/enums.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constants that are shared between multiple files.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export enum KeypadType {
|
|
6
|
-
FRACTION = "FRACTION",
|
|
7
|
-
EXPRESSION = "EXPRESSION",
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const KeyTypes = [
|
|
11
|
-
"EMPTY",
|
|
12
|
-
// For numerals, variables, and any other characters that themselves
|
|
13
|
-
// compose 'values'.
|
|
14
|
-
"VALUE",
|
|
15
|
-
// For buttons that insert or adjust math in an input.
|
|
16
|
-
"OPERATOR",
|
|
17
|
-
// For buttons that move the cursor in an input (including via
|
|
18
|
-
// deletion).
|
|
19
|
-
"INPUT_NAVIGATION",
|
|
20
|
-
// For buttons that modify the broader keypad state (e.g., by changing
|
|
21
|
-
// the visible pane).
|
|
22
|
-
"KEYPAD_NAVIGATION",
|
|
23
|
-
// For buttons that house multiple buttons and have no action
|
|
24
|
-
// themselves.
|
|
25
|
-
"MANY",
|
|
26
|
-
];
|
|
27
|
-
export type KeyType = typeof KeyTypes[number];
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file exports components View and Text which wrap <div> and <span>.
|
|
3
|
-
* We do this so that someday in the future we can use these components with
|
|
4
|
-
* React Native.
|
|
5
|
-
*
|
|
6
|
-
* Inspired by https://github.com/necolas/react-native-web. We use aphrodite
|
|
7
|
-
* StyleSheets instead.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export {default as Text} from "./text";
|
|
11
|
-
export {default as View} from "./view";
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import {StyleSheet, css} from "aphrodite";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
5
|
-
import type {CSSProperties} from "aphrodite";
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
children: React.ReactNode;
|
|
9
|
-
// The `dynamicStyle` prop is provided for animating dynamic
|
|
10
|
-
// properties, as creating Aphrodite StyleSheets in animation loops is
|
|
11
|
-
// expensive. `dynamicStyle` should be a raw style object, rather than
|
|
12
|
-
// a StyleSheet.
|
|
13
|
-
dynamicStyle?: CSSProperties;
|
|
14
|
-
numberOfLines?: number;
|
|
15
|
-
style?: StyleType;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
class Text extends React.Component<Props> {
|
|
19
|
-
render(): React.ReactNode {
|
|
20
|
-
const {numberOfLines, style} = this.props;
|
|
21
|
-
|
|
22
|
-
const className = css(
|
|
23
|
-
styles.initial,
|
|
24
|
-
...(Array.isArray(style) ? style : [style]),
|
|
25
|
-
numberOfLines === 1 && styles.singleLineStyle,
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<span className={className} style={this.props.dynamicStyle}>
|
|
30
|
-
{this.props.children}
|
|
31
|
-
</span>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// https://github.com/necolas/react-native-web/blob/master/src/components/Text/index.js
|
|
37
|
-
const styles = StyleSheet.create({
|
|
38
|
-
initial: {
|
|
39
|
-
color: "inherit",
|
|
40
|
-
display: "inline",
|
|
41
|
-
font: "inherit",
|
|
42
|
-
margin: 0,
|
|
43
|
-
padding: 0,
|
|
44
|
-
textDecorationLine: "none",
|
|
45
|
-
wordWrap: "break-word",
|
|
46
|
-
},
|
|
47
|
-
singleLineStyle: {
|
|
48
|
-
maxWidth: "100%",
|
|
49
|
-
overflow: "hidden",
|
|
50
|
-
textOverflow: "ellipsis",
|
|
51
|
-
whiteSpace: "nowrap",
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
export default Text;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import {StyleSheet, css} from "aphrodite";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
5
|
-
import type {CSSProperties} from "aphrodite";
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
ariaLabel?: string;
|
|
9
|
-
children?: React.ReactNode;
|
|
10
|
-
// The `dynamicStyle` prop is provided for animating dynamic
|
|
11
|
-
// properties, as creating Aphrodite StyleSheets in animation loops is
|
|
12
|
-
// expensive. `dynamicStyle` should be a raw style object, rather than
|
|
13
|
-
// a StyleSheet.
|
|
14
|
-
dynamicStyle?: CSSProperties;
|
|
15
|
-
// The `extraClassName` prop should almost never be used. It gives the
|
|
16
|
-
// client a way to provide an additional CSS class name, to augment
|
|
17
|
-
// the class name generated by Aphrodite. (Right now, it's only used to
|
|
18
|
-
// disable some externally-applied CSS that would otherwise be far too
|
|
19
|
-
// difficult to override with inline styles.)
|
|
20
|
-
extraClassName?: string;
|
|
21
|
-
numberOfLines?: number;
|
|
22
|
-
onClick?: (arg1: React.SyntheticEvent<HTMLDivElement>) => void;
|
|
23
|
-
onTouchCancel?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
|
|
24
|
-
onTouchEnd?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
|
|
25
|
-
onTouchMove?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
|
|
26
|
-
onTouchStart?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
|
|
27
|
-
role?: string;
|
|
28
|
-
style?: StyleType;
|
|
29
|
-
forwardRef?: React.RefObject<HTMLDivElement>;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
class View extends React.Component<Props> {
|
|
33
|
-
static styles = StyleSheet.create({
|
|
34
|
-
// From: https://github.com/necolas/react-native-web/blob/master/src/components/View/index.js
|
|
35
|
-
// eslint-disable-next-line react-native/no-unused-styles
|
|
36
|
-
initial: {
|
|
37
|
-
alignItems: "stretch",
|
|
38
|
-
borderWidth: 0,
|
|
39
|
-
borderStyle: "solid",
|
|
40
|
-
boxSizing: "border-box",
|
|
41
|
-
display: "flex",
|
|
42
|
-
flexBasis: "auto",
|
|
43
|
-
flexDirection: "column",
|
|
44
|
-
margin: 0,
|
|
45
|
-
padding: 0,
|
|
46
|
-
position: "relative",
|
|
47
|
-
// button and anchor reset
|
|
48
|
-
backgroundColor: "transparent",
|
|
49
|
-
color: "inherit",
|
|
50
|
-
font: "inherit",
|
|
51
|
-
textAlign: "inherit",
|
|
52
|
-
textDecorationLine: "none",
|
|
53
|
-
// list reset
|
|
54
|
-
listStyle: "none",
|
|
55
|
-
// fix flexbox bugs
|
|
56
|
-
maxWidth: "100%",
|
|
57
|
-
minHeight: 0,
|
|
58
|
-
minWidth: 0,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
render(): React.ReactNode {
|
|
63
|
-
const className =
|
|
64
|
-
css(
|
|
65
|
-
View.styles.initial,
|
|
66
|
-
...(Array.isArray(this.props.style)
|
|
67
|
-
? this.props.style
|
|
68
|
-
: [this.props.style]),
|
|
69
|
-
) +
|
|
70
|
-
(this.props.extraClassName ? ` ${this.props.extraClassName}` : "");
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<div
|
|
74
|
-
className={className}
|
|
75
|
-
style={this.props.dynamicStyle}
|
|
76
|
-
onClick={this.props.onClick}
|
|
77
|
-
onTouchCancel={this.props.onTouchCancel}
|
|
78
|
-
onTouchEnd={this.props.onTouchEnd}
|
|
79
|
-
onTouchMove={this.props.onTouchMove}
|
|
80
|
-
onTouchStart={this.props.onTouchStart}
|
|
81
|
-
aria-label={this.props.ariaLabel}
|
|
82
|
-
role={this.props.role}
|
|
83
|
-
ref={this.props.forwardRef}
|
|
84
|
-
>
|
|
85
|
-
{this.props.children}
|
|
86
|
-
</div>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export default View;
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import {action} from "@storybook/addon-actions";
|
|
2
|
-
import {INITIAL_VIEWPORTS} from "@storybook/addon-viewport";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
import Keypad from "./components/keypad";
|
|
6
|
-
|
|
7
|
-
import type {PropsFor} from "@khanacademy/wonder-blocks-core";
|
|
8
|
-
import type {ComponentStory} from "@storybook/react";
|
|
9
|
-
|
|
10
|
-
const opsPage = "Operators Page";
|
|
11
|
-
const numsPage = "Numbers Page";
|
|
12
|
-
const geoPage = "Geometry Page";
|
|
13
|
-
const fracPage = "Fractions Page";
|
|
14
|
-
|
|
15
|
-
export default {
|
|
16
|
-
title: "math-input/Full Keypad",
|
|
17
|
-
parameters: {
|
|
18
|
-
backgrounds: {
|
|
19
|
-
values: [{name: "light background", value: "white", default: true}],
|
|
20
|
-
},
|
|
21
|
-
viewport: {defaultViewport: "iphone6", viewports: INITIAL_VIEWPORTS},
|
|
22
|
-
},
|
|
23
|
-
component: Keypad,
|
|
24
|
-
args: {
|
|
25
|
-
advancedRelations: false,
|
|
26
|
-
basicRelations: false,
|
|
27
|
-
divisionKey: false,
|
|
28
|
-
logarithms: false,
|
|
29
|
-
fractionsOnly: false,
|
|
30
|
-
convertDotToTimes: false,
|
|
31
|
-
preAlgebra: false,
|
|
32
|
-
trigonometry: false,
|
|
33
|
-
sendEvent: () => {},
|
|
34
|
-
onAnalyticsEvent: async () => {},
|
|
35
|
-
},
|
|
36
|
-
argTypes: {
|
|
37
|
-
advancedRelations: {
|
|
38
|
-
control: "boolean",
|
|
39
|
-
table: {
|
|
40
|
-
category: opsPage,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
basicRelations: {
|
|
44
|
-
control: "boolean",
|
|
45
|
-
table: {
|
|
46
|
-
category: opsPage,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
divisionKey: {
|
|
50
|
-
control: "boolean",
|
|
51
|
-
table: {
|
|
52
|
-
category: numsPage,
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
logarithms: {
|
|
56
|
-
control: "boolean",
|
|
57
|
-
table: {
|
|
58
|
-
category: opsPage,
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
fractionsOnly: {
|
|
62
|
-
control: "boolean",
|
|
63
|
-
table: {
|
|
64
|
-
category: fracPage,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
multiplicationDot: {
|
|
68
|
-
control: "boolean",
|
|
69
|
-
table: {
|
|
70
|
-
category: numsPage,
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
preAlgebra: {
|
|
74
|
-
control: "boolean",
|
|
75
|
-
table: {
|
|
76
|
-
category: opsPage,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
trigonometry: {
|
|
80
|
-
control: "boolean",
|
|
81
|
-
table: {
|
|
82
|
-
category: geoPage,
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const Template: ComponentStory<typeof Keypad> = (
|
|
89
|
-
args: PropsFor<typeof Keypad>,
|
|
90
|
-
): React.ReactElement => (
|
|
91
|
-
<Keypad
|
|
92
|
-
{...args}
|
|
93
|
-
onClickKey={action("onClickKey")}
|
|
94
|
-
onAnalyticsEvent={async (e) => action("onAnalyticsEvent")(e)}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
export const Default = Template.bind({});
|
|
99
|
-
|
|
100
|
-
export const PreAlgebra = Template.bind({});
|
|
101
|
-
PreAlgebra.args = {
|
|
102
|
-
preAlgebra: true,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export const Trigonometry = Template.bind({});
|
|
106
|
-
Trigonometry.args = {
|
|
107
|
-
preAlgebra: true,
|
|
108
|
-
trigonometry: true,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export const FractionsOnly = Template.bind({});
|
|
112
|
-
FractionsOnly.args = {
|
|
113
|
-
fractionsOnly: true,
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const Everything = Template.bind({});
|
|
117
|
-
Everything.args = {
|
|
118
|
-
advancedRelations: true,
|
|
119
|
-
basicRelations: true,
|
|
120
|
-
divisionKey: true,
|
|
121
|
-
logarithms: true,
|
|
122
|
-
convertDotToTimes: false,
|
|
123
|
-
preAlgebra: true,
|
|
124
|
-
trigonometry: true,
|
|
125
|
-
expandedView: true,
|
|
126
|
-
showDismiss: true,
|
|
127
|
-
extraKeys: ["a", "b", "c"],
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export const EverythingMinusNavigationPad = Template.bind({});
|
|
131
|
-
EverythingMinusNavigationPad.args = {
|
|
132
|
-
advancedRelations: true,
|
|
133
|
-
basicRelations: true,
|
|
134
|
-
divisionKey: true,
|
|
135
|
-
logarithms: true,
|
|
136
|
-
convertDotToTimes: false,
|
|
137
|
-
preAlgebra: true,
|
|
138
|
-
trigonometry: true,
|
|
139
|
-
expandedView: false,
|
|
140
|
-
showDismiss: true,
|
|
141
|
-
extraKeys: ["a", "b", "c"],
|
|
142
|
-
};
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import {action} from "@storybook/addon-actions";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
KeypadInput,
|
|
6
|
-
KeypadType,
|
|
7
|
-
MobileKeypad,
|
|
8
|
-
StatefulKeypadContextProvider,
|
|
9
|
-
KeypadContext,
|
|
10
|
-
} from "./index";
|
|
11
|
-
|
|
12
|
-
export default {
|
|
13
|
-
title: "math-input/Full Mobile MathInput",
|
|
14
|
-
parameters: {
|
|
15
|
-
backgrounds: {
|
|
16
|
-
default: "light background",
|
|
17
|
-
values: [
|
|
18
|
-
// We want a slightly darker default bg so that we can
|
|
19
|
-
// see the top of the keypad when it is open
|
|
20
|
-
{name: "light background", value: "lightgrey", default: true},
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const Basic = ({keypadElement, setKeypadElement}) => {
|
|
27
|
-
const [value, setValue] = React.useState("");
|
|
28
|
-
// Whether to use Expression or Fraction keypad
|
|
29
|
-
const [expression, setExpression] = React.useState<boolean>(false);
|
|
30
|
-
// Whether to use CDOT or TIMES
|
|
31
|
-
const [times, setTimes] = React.useState<boolean>(true);
|
|
32
|
-
// Whether to use v1 or v2 keypad
|
|
33
|
-
const [v2Keypad, setV2Keypad] = React.useState<boolean>(true);
|
|
34
|
-
|
|
35
|
-
const input = React.useRef<KeypadInput>(null);
|
|
36
|
-
|
|
37
|
-
const timesLabel = times ? "CDOT" : "TIMES";
|
|
38
|
-
|
|
39
|
-
React.useEffect(() => {
|
|
40
|
-
keypadElement?.configure(
|
|
41
|
-
{
|
|
42
|
-
keypadType: expression
|
|
43
|
-
? KeypadType.EXPRESSION
|
|
44
|
-
: KeypadType.FRACTION,
|
|
45
|
-
extraKeys: expression ? ["x", "y", "PI", "THETA"] : [],
|
|
46
|
-
times: times,
|
|
47
|
-
},
|
|
48
|
-
() => {},
|
|
49
|
-
);
|
|
50
|
-
}, [keypadElement, expression, times]);
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<div style={{padding: "1rem 2rem"}}>
|
|
54
|
-
<div>
|
|
55
|
-
<div>
|
|
56
|
-
NOTE: To properly test the input interaction, you will need
|
|
57
|
-
to simulate a device using the dev tools. MathInput requires
|
|
58
|
-
touch events (not click events).
|
|
59
|
-
</div>
|
|
60
|
-
<div style={{padding: "1rem 0"}}>
|
|
61
|
-
<button onClick={() => setExpression(!expression)}>
|
|
62
|
-
{`Use ${expression ? "Fraction" : "Expression"} Keypad`}
|
|
63
|
-
</button>
|
|
64
|
-
<button onClick={() => setV2Keypad(!v2Keypad)}>
|
|
65
|
-
{`Use ${v2Keypad ? "Legacy" : "New"} Keypad`}
|
|
66
|
-
</button>
|
|
67
|
-
<button onClick={() => setTimes(!times)}>
|
|
68
|
-
{`Toggle to ` + timesLabel}
|
|
69
|
-
</button>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<KeypadInput
|
|
74
|
-
value={value}
|
|
75
|
-
ref={input}
|
|
76
|
-
keypadElement={keypadElement}
|
|
77
|
-
onChange={(newValue, callback) => {
|
|
78
|
-
setValue(newValue);
|
|
79
|
-
callback?.();
|
|
80
|
-
}}
|
|
81
|
-
onFocus={() => {
|
|
82
|
-
keypadElement?.activate();
|
|
83
|
-
}}
|
|
84
|
-
onBlur={() => {
|
|
85
|
-
keypadElement?.dismiss();
|
|
86
|
-
}}
|
|
87
|
-
/>
|
|
88
|
-
|
|
89
|
-
<MobileKeypad
|
|
90
|
-
onElementMounted={(node) => {
|
|
91
|
-
if (node) {
|
|
92
|
-
setKeypadElement(node);
|
|
93
|
-
}
|
|
94
|
-
}}
|
|
95
|
-
onDismiss={() => {}}
|
|
96
|
-
onAnalyticsEvent={async (e) => action("onAnalyticsEvent")(e)}
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export function Wrapped() {
|
|
103
|
-
return (
|
|
104
|
-
<StatefulKeypadContextProvider>
|
|
105
|
-
<KeypadContext.Consumer>
|
|
106
|
-
{({keypadElement, setKeypadElement}) => (
|
|
107
|
-
<Basic
|
|
108
|
-
keypadElement={keypadElement}
|
|
109
|
-
setKeypadElement={setKeypadElement}
|
|
110
|
-
/>
|
|
111
|
-
)}
|
|
112
|
-
</KeypadContext.Consumer>
|
|
113
|
-
</StatefulKeypadContextProvider>
|
|
114
|
-
);
|
|
115
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A single entry-point for all of the external-facing functionality.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import "../less/main.less";
|
|
6
|
-
|
|
7
|
-
export {libVersion} from "./version";
|
|
8
|
-
|
|
9
|
-
// MathInput input field (MathQuill wrapper)
|
|
10
|
-
export {default as KeypadInput} from "./components/input/math-input";
|
|
11
|
-
|
|
12
|
-
export {
|
|
13
|
-
// Helper to create a MathQuill MathField
|
|
14
|
-
createMathField,
|
|
15
|
-
// Instance of the MathQuill library
|
|
16
|
-
mathQuillInstance,
|
|
17
|
-
} from "./components/input/mathquill-instance";
|
|
18
|
-
|
|
19
|
-
// MathQuill MathField type
|
|
20
|
-
export {type MathFieldInterface} from "./components/input/mathquill-types";
|
|
21
|
-
|
|
22
|
-
// Cursor context data: where in a forumla the cursor is in
|
|
23
|
-
// ex: in numerator, in parenthesis, in subscript
|
|
24
|
-
export {CursorContext} from "./components/input/cursor-contexts";
|
|
25
|
-
|
|
26
|
-
// Helper to get cursor context from MathField
|
|
27
|
-
export {getCursorContext} from "./components/input/mathquill-helpers";
|
|
28
|
-
|
|
29
|
-
// Wrapper around v1 and v2 mobile keypads to switch between them
|
|
30
|
-
export {MobileKeypad} from "./components/keypad";
|
|
31
|
-
// Unwrapped v2 keypad for desktop
|
|
32
|
-
export {default as DesktopKeypad} from "./components/keypad";
|
|
33
|
-
|
|
34
|
-
// Context used to pass data/refs around
|
|
35
|
-
export {
|
|
36
|
-
KeypadContext,
|
|
37
|
-
StatefulKeypadContextProvider,
|
|
38
|
-
} from "./components/keypad-context";
|
|
39
|
-
|
|
40
|
-
// External API of the "Provided" keypad component
|
|
41
|
-
export {keypadElementPropType} from "./components/prop-types";
|
|
42
|
-
export type {KeypadAPI, KeypadConfiguration} from "./types";
|
|
43
|
-
export {convertDotToTimesByLocale} from "./utils";
|
|
44
|
-
|
|
45
|
-
// Key list, configuration map, and types
|
|
46
|
-
export type {default as Keys} from "./data/keys";
|
|
47
|
-
export {KeyArray} from "./data/keys";
|
|
48
|
-
export {default as KeyConfigs} from "./data/key-configs";
|
|
49
|
-
export {type KeyType, KeypadType} from "./enums";
|
|
50
|
-
|
|
51
|
-
// Helper to translate key pressed to MathField update
|
|
52
|
-
export {default as keyTranslator} from "./components/key-handlers/key-translator";
|
package/src/types.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type {CursorContext} from "./components/input/cursor-contexts";
|
|
2
|
-
import type Key from "./data/keys";
|
|
3
|
-
import type {KeyType, KeypadType} from "./enums";
|
|
4
|
-
import type {KeypadContextRendererInterface} from "@khanacademy/perseus-core";
|
|
5
|
-
import type * as React from "react";
|
|
6
|
-
import type ReactDOM from "react-dom";
|
|
7
|
-
|
|
8
|
-
export type IconConfig = {
|
|
9
|
-
data: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type NonManyKeyConfig = {
|
|
13
|
-
id: Key;
|
|
14
|
-
type: Exclude<KeyType, "MANY">;
|
|
15
|
-
icon: IconConfig;
|
|
16
|
-
ariaLabel: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type ManyKeyConfig = Omit<NonManyKeyConfig, "type"> & {
|
|
20
|
-
type: Extract<KeyType, "MANY">;
|
|
21
|
-
childKeyIds: ReadonlyArray<string>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type KeyConfig = NonManyKeyConfig | ManyKeyConfig;
|
|
25
|
-
|
|
26
|
-
export type KeypadConfiguration = {
|
|
27
|
-
keypadType: KeypadType;
|
|
28
|
-
extraKeys?: ReadonlyArray<Key>;
|
|
29
|
-
times?: boolean;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export type KeyHandler = (key: Key) => Cursor;
|
|
33
|
-
|
|
34
|
-
export type Cursor = {
|
|
35
|
-
context: typeof CursorContext[keyof typeof CursorContext];
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type ClickKeyCallback = (key: Key, event?: React.SyntheticEvent) => void;
|
|
39
|
-
|
|
40
|
-
export type KeypadPageType =
|
|
41
|
-
| "Geometry"
|
|
42
|
-
| "Operators"
|
|
43
|
-
| "Numbers"
|
|
44
|
-
| "Fractions"
|
|
45
|
-
| "Extras"
|
|
46
|
-
| "Dismiss";
|
|
47
|
-
|
|
48
|
-
export interface KeypadAPI {
|
|
49
|
-
activate: () => void;
|
|
50
|
-
dismiss: () => void;
|
|
51
|
-
configure: (configuration: KeypadConfiguration, cb: () => void) => void;
|
|
52
|
-
setCursor: (cursor: Cursor) => void;
|
|
53
|
-
setKeyHandler: (keyHandler: KeyHandler) => void;
|
|
54
|
-
getDOMNode: () => ReturnType<typeof ReactDOM.findDOMNode>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type KeypadContextType = {
|
|
58
|
-
setKeypadActive: (keypadActive: boolean) => void;
|
|
59
|
-
keypadActive: boolean;
|
|
60
|
-
setKeypadElement: (keypadElement?: KeypadAPI) => void;
|
|
61
|
-
keypadElement: KeypadAPI | null | undefined;
|
|
62
|
-
setRenderer: (
|
|
63
|
-
renderer?: KeypadContextRendererInterface | null | undefined,
|
|
64
|
-
) => void;
|
|
65
|
-
renderer: KeypadContextRendererInterface | null | undefined;
|
|
66
|
-
setScrollableElement: (
|
|
67
|
-
scrollableElement?: HTMLElement | null | undefined,
|
|
68
|
-
) => void;
|
|
69
|
-
scrollableElement: HTMLElement | null | undefined;
|
|
70
|
-
};
|