@khanacademy/math-input 15.0.1 → 16.0.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 +17 -0
- package/dist/components/aphrodite-css-transition-group/transition-child.d.ts +11 -8
- package/dist/components/keypad/index.d.ts +1 -1
- package/dist/components/keypad/mobile-keypad-internals.d.ts +49 -0
- package/dist/components/keypad/mobile-keypad.d.ts +4 -48
- package/dist/es/index.js +168 -4740
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +166 -4722
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
- package/src/components/__tests__/integration.test.tsx +2 -3
- package/src/components/keypad/__tests__/mobile-keypad.test.tsx +8 -8
- package/src/components/keypad/index.tsx +1 -1
- package/src/components/keypad/mobile-keypad-internals.tsx +240 -0
- package/src/components/keypad/mobile-keypad.tsx +21 -234
- package/src/full-mobile-input.stories.tsx +0 -1
- package/src/index.ts +1 -1
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/components/keypad-legacy/compute-layout-parameters.d.ts +0 -28
- package/dist/components/keypad-legacy/corner-decal.d.ts +0 -12
- package/dist/components/keypad-legacy/echo-manager.d.ts +0 -17
- package/dist/components/keypad-legacy/empty-keypad-button.d.ts +0 -13
- package/dist/components/keypad-legacy/expression-keypad.d.ts +0 -21
- package/dist/components/keypad-legacy/fraction-keypad.d.ts +0 -21
- package/dist/components/keypad-legacy/gesture-manager.d.ts +0 -86
- package/dist/components/keypad-legacy/gesture-state-machine.d.ts +0 -105
- package/dist/components/keypad-legacy/icon.d.ts +0 -15
- package/dist/components/keypad-legacy/index.d.ts +0 -1
- package/dist/components/keypad-legacy/keypad-button.d.ts +0 -53
- package/dist/components/keypad-legacy/keypad-container.d.ts +0 -41
- package/dist/components/keypad-legacy/keypad.d.ts +0 -31
- package/dist/components/keypad-legacy/many-keypad-button.d.ts +0 -15
- package/dist/components/keypad-legacy/math-icon.d.ts +0 -16
- package/dist/components/keypad-legacy/multi-symbol-grid.d.ts +0 -14
- package/dist/components/keypad-legacy/multi-symbol-popover.d.ts +0 -12
- package/dist/components/keypad-legacy/navigation-pad.d.ts +0 -14
- package/dist/components/keypad-legacy/node-manager.d.ts +0 -49
- package/dist/components/keypad-legacy/popover-manager.d.ts +0 -13
- package/dist/components/keypad-legacy/popover-state-machine.d.ts +0 -68
- package/dist/components/keypad-legacy/provided-keypad.d.ts +0 -28
- package/dist/components/keypad-legacy/store/actions.d.ts +0 -55
- package/dist/components/keypad-legacy/store/echo-reducer.d.ts +0 -4
- package/dist/components/keypad-legacy/store/index.d.ts +0 -9
- package/dist/components/keypad-legacy/store/input-reducer.d.ts +0 -4
- package/dist/components/keypad-legacy/store/keypad-reducer.d.ts +0 -4
- package/dist/components/keypad-legacy/store/layout-reducer.d.ts +0 -4
- package/dist/components/keypad-legacy/store/shared.d.ts +0 -7
- package/dist/components/keypad-legacy/store/types.d.ts +0 -47
- package/dist/components/keypad-legacy/styles.d.ts +0 -5
- package/dist/components/keypad-legacy/svg-icon.d.ts +0 -12
- package/dist/components/keypad-legacy/text-icon.d.ts +0 -13
- package/dist/components/keypad-legacy/touchable-keypad-button.d.ts +0 -37
- package/dist/components/keypad-legacy/two-page-keypad.d.ts +0 -21
- package/dist/components/keypad-legacy/z-indexes.d.ts +0 -7
- package/dist/components/keypad-switch.d.ts +0 -12
- package/src/components/keypad-legacy/__tests__/gesture-state-machine.test.ts +0 -441
- package/src/components/keypad-legacy/__tests__/node-manager.test.ts +0 -89
- package/src/components/keypad-legacy/__tests__/two-page-keypad.test.tsx +0 -38
- package/src/components/keypad-legacy/compute-layout-parameters.ts +0 -205
- package/src/components/keypad-legacy/corner-decal.tsx +0 -56
- package/src/components/keypad-legacy/echo-manager.tsx +0 -152
- package/src/components/keypad-legacy/empty-keypad-button.tsx +0 -58
- package/src/components/keypad-legacy/expression-keypad.tsx +0 -315
- package/src/components/keypad-legacy/fraction-keypad.tsx +0 -180
- package/src/components/keypad-legacy/gesture-manager.ts +0 -255
- package/src/components/keypad-legacy/gesture-state-machine.ts +0 -329
- package/src/components/keypad-legacy/icon.tsx +0 -72
- package/src/components/keypad-legacy/iconography/arrow.js +0 -22
- package/src/components/keypad-legacy/iconography/backspace.js +0 -29
- package/src/components/keypad-legacy/iconography/cdot.js +0 -29
- package/src/components/keypad-legacy/iconography/cos.js +0 -30
- package/src/components/keypad-legacy/iconography/cube-root.js +0 -36
- package/src/components/keypad-legacy/iconography/dismiss.js +0 -25
- package/src/components/keypad-legacy/iconography/divide.js +0 -34
- package/src/components/keypad-legacy/iconography/down.js +0 -16
- package/src/components/keypad-legacy/iconography/equal.js +0 -33
- package/src/components/keypad-legacy/iconography/exp-2.js +0 -29
- package/src/components/keypad-legacy/iconography/exp-3.js +0 -29
- package/src/components/keypad-legacy/iconography/exp.js +0 -29
- package/src/components/keypad-legacy/iconography/frac.js +0 -44
- package/src/components/keypad-legacy/iconography/geq.js +0 -33
- package/src/components/keypad-legacy/iconography/gt.js +0 -33
- package/src/components/keypad-legacy/iconography/index.js +0 -45
- package/src/components/keypad-legacy/iconography/jump-into-numerator.js +0 -41
- package/src/components/keypad-legacy/iconography/jump-out-base.js +0 -30
- package/src/components/keypad-legacy/iconography/jump-out-denominator.js +0 -41
- package/src/components/keypad-legacy/iconography/jump-out-exponent.js +0 -30
- package/src/components/keypad-legacy/iconography/jump-out-numerator.js +0 -41
- package/src/components/keypad-legacy/iconography/jump-out-parentheses.js +0 -33
- package/src/components/keypad-legacy/iconography/left-paren.js +0 -33
- package/src/components/keypad-legacy/iconography/left.js +0 -16
- package/src/components/keypad-legacy/iconography/leq.js +0 -33
- package/src/components/keypad-legacy/iconography/ln.js +0 -29
- package/src/components/keypad-legacy/iconography/log-n.js +0 -29
- package/src/components/keypad-legacy/iconography/log.js +0 -29
- package/src/components/keypad-legacy/iconography/lt.js +0 -33
- package/src/components/keypad-legacy/iconography/minus.js +0 -32
- package/src/components/keypad-legacy/iconography/neq.js +0 -33
- package/src/components/keypad-legacy/iconography/parens.js +0 -33
- package/src/components/keypad-legacy/iconography/percent.js +0 -49
- package/src/components/keypad-legacy/iconography/period.js +0 -26
- package/src/components/keypad-legacy/iconography/plus.js +0 -32
- package/src/components/keypad-legacy/iconography/radical.js +0 -36
- package/src/components/keypad-legacy/iconography/right-paren.js +0 -33
- package/src/components/keypad-legacy/iconography/right.js +0 -16
- package/src/components/keypad-legacy/iconography/sin.js +0 -30
- package/src/components/keypad-legacy/iconography/sqrt.js +0 -32
- package/src/components/keypad-legacy/iconography/tan.js +0 -30
- package/src/components/keypad-legacy/iconography/times.js +0 -33
- package/src/components/keypad-legacy/iconography/up.js +0 -16
- package/src/components/keypad-legacy/index.ts +0 -1
- package/src/components/keypad-legacy/keypad-button.tsx +0 -368
- package/src/components/keypad-legacy/keypad-container.tsx +0 -358
- package/src/components/keypad-legacy/keypad.tsx +0 -162
- package/src/components/keypad-legacy/many-keypad-button.tsx +0 -54
- package/src/components/keypad-legacy/math-icon.tsx +0 -66
- package/src/components/keypad-legacy/multi-symbol-grid.tsx +0 -182
- package/src/components/keypad-legacy/multi-symbol-popover.tsx +0 -58
- package/src/components/keypad-legacy/navigation-pad.tsx +0 -140
- package/src/components/keypad-legacy/node-manager.ts +0 -133
- package/src/components/keypad-legacy/popover-manager.tsx +0 -73
- package/src/components/keypad-legacy/popover-state-machine.ts +0 -184
- package/src/components/keypad-legacy/provided-keypad.tsx +0 -136
- package/src/components/keypad-legacy/store/actions.ts +0 -155
- package/src/components/keypad-legacy/store/echo-reducer.ts +0 -57
- package/src/components/keypad-legacy/store/index.ts +0 -110
- package/src/components/keypad-legacy/store/input-reducer.ts +0 -55
- package/src/components/keypad-legacy/store/keypad-reducer.ts +0 -58
- package/src/components/keypad-legacy/store/layout-reducer.test.ts +0 -171
- package/src/components/keypad-legacy/store/layout-reducer.ts +0 -129
- package/src/components/keypad-legacy/store/shared.ts +0 -12
- package/src/components/keypad-legacy/store/types.ts +0 -78
- package/src/components/keypad-legacy/styles.ts +0 -38
- package/src/components/keypad-legacy/svg-icon.tsx +0 -24
- package/src/components/keypad-legacy/text-icon.tsx +0 -53
- package/src/components/keypad-legacy/touchable-keypad-button.tsx +0 -163
- package/src/components/keypad-legacy/two-page-keypad.tsx +0 -115
- package/src/components/keypad-legacy/z-indexes.ts +0 -8
- package/src/components/keypad-switch.tsx +0 -42
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A grid of symbols, rendered as text and positioned based on the number of
|
|
3
|
-
* symbols provided. Up to four symbols will be shown.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {StyleSheet} from "aphrodite";
|
|
7
|
-
import * as React from "react";
|
|
8
|
-
|
|
9
|
-
import {IconType} from "../../enums";
|
|
10
|
-
import {View} from "../../fake-react-native-web/index";
|
|
11
|
-
import {iconSizeHeightPx, iconSizeWidthPx} from "../common-style";
|
|
12
|
-
|
|
13
|
-
import Icon from "./icon";
|
|
14
|
-
import Styles from "./styles";
|
|
15
|
-
|
|
16
|
-
import type {IconConfig} from "../../types";
|
|
17
|
-
|
|
18
|
-
const {row, column, centered, fullWidth} = Styles;
|
|
19
|
-
|
|
20
|
-
type Props = {
|
|
21
|
-
focused: boolean;
|
|
22
|
-
icons: ReadonlyArray<IconConfig>;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
class MultiSymbolGrid extends React.Component<Props> {
|
|
26
|
-
render() {
|
|
27
|
-
const {focused, icons} = this.props;
|
|
28
|
-
|
|
29
|
-
// Validate that we only received math-based icons. Right now, this
|
|
30
|
-
// component only supports math icons (and it should only be passed
|
|
31
|
-
// variables and Greek letters, which are always rendered as math).
|
|
32
|
-
// Supporting other types of icons is possible but would require
|
|
33
|
-
// some styles coercion and doesn't seem worthwhile right now.
|
|
34
|
-
icons.forEach((icon) => {
|
|
35
|
-
if (icon.type !== IconType.MATH) {
|
|
36
|
-
throw new Error(
|
|
37
|
-
`Received invalid icon: type=${icon.type}, ` +
|
|
38
|
-
`data=${icon.data}`,
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (icons.length === 1) {
|
|
44
|
-
return <Icon icon={icons[0]} focused={focused} />;
|
|
45
|
-
} else {
|
|
46
|
-
const primaryIconStyle = styles.base;
|
|
47
|
-
const secondaryIconStyle = [styles.base, styles.secondary];
|
|
48
|
-
|
|
49
|
-
if (icons.length === 2) {
|
|
50
|
-
return (
|
|
51
|
-
<View style={[row, styles.size]}>
|
|
52
|
-
<View
|
|
53
|
-
style={[
|
|
54
|
-
column,
|
|
55
|
-
centered,
|
|
56
|
-
fullWidth,
|
|
57
|
-
styles.middleLeft,
|
|
58
|
-
]}
|
|
59
|
-
>
|
|
60
|
-
<Icon
|
|
61
|
-
style={primaryIconStyle}
|
|
62
|
-
icon={icons[0]}
|
|
63
|
-
focused={focused}
|
|
64
|
-
/>
|
|
65
|
-
</View>
|
|
66
|
-
<View
|
|
67
|
-
style={[
|
|
68
|
-
column,
|
|
69
|
-
centered,
|
|
70
|
-
fullWidth,
|
|
71
|
-
styles.middleRight,
|
|
72
|
-
]}
|
|
73
|
-
>
|
|
74
|
-
<Icon
|
|
75
|
-
style={secondaryIconStyle}
|
|
76
|
-
icon={icons[1]}
|
|
77
|
-
focused={focused}
|
|
78
|
-
/>
|
|
79
|
-
</View>
|
|
80
|
-
</View>
|
|
81
|
-
);
|
|
82
|
-
} else if (icons.length >= 3) {
|
|
83
|
-
return (
|
|
84
|
-
<View style={[column, styles.size]}>
|
|
85
|
-
<View style={row}>
|
|
86
|
-
<View style={[centered, fullWidth, styles.topLeft]}>
|
|
87
|
-
<Icon
|
|
88
|
-
style={primaryIconStyle}
|
|
89
|
-
icon={icons[0]}
|
|
90
|
-
focused={focused}
|
|
91
|
-
/>
|
|
92
|
-
</View>
|
|
93
|
-
<View
|
|
94
|
-
style={[centered, fullWidth, styles.topRight]}
|
|
95
|
-
>
|
|
96
|
-
<Icon
|
|
97
|
-
style={secondaryIconStyle}
|
|
98
|
-
icon={icons[1]}
|
|
99
|
-
focused={focused}
|
|
100
|
-
/>
|
|
101
|
-
</View>
|
|
102
|
-
</View>
|
|
103
|
-
<View style={row}>
|
|
104
|
-
<View
|
|
105
|
-
style={[centered, fullWidth, styles.bottomLeft]}
|
|
106
|
-
>
|
|
107
|
-
<Icon
|
|
108
|
-
style={secondaryIconStyle}
|
|
109
|
-
icon={icons[2]}
|
|
110
|
-
focused={focused}
|
|
111
|
-
/>
|
|
112
|
-
</View>
|
|
113
|
-
<View
|
|
114
|
-
style={[
|
|
115
|
-
centered,
|
|
116
|
-
fullWidth,
|
|
117
|
-
styles.bottomRight,
|
|
118
|
-
]}
|
|
119
|
-
>
|
|
120
|
-
{icons[3] && (
|
|
121
|
-
<Icon
|
|
122
|
-
style={secondaryIconStyle}
|
|
123
|
-
icon={icons[3]}
|
|
124
|
-
focused={focused}
|
|
125
|
-
/>
|
|
126
|
-
)}
|
|
127
|
-
</View>
|
|
128
|
-
</View>
|
|
129
|
-
</View>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
throw new Error(`Invalid number of icons: ${icons.length}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const verticalInsetPx = 2;
|
|
139
|
-
const horizontalInsetPx = 4;
|
|
140
|
-
|
|
141
|
-
const styles = StyleSheet.create({
|
|
142
|
-
size: {
|
|
143
|
-
height: iconSizeHeightPx,
|
|
144
|
-
width: iconSizeWidthPx,
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
// For the three- and four-icon layouts.
|
|
148
|
-
bottomLeft: {
|
|
149
|
-
marginBottom: verticalInsetPx,
|
|
150
|
-
marginLeft: horizontalInsetPx,
|
|
151
|
-
},
|
|
152
|
-
topLeft: {
|
|
153
|
-
marginTop: verticalInsetPx,
|
|
154
|
-
marginLeft: horizontalInsetPx,
|
|
155
|
-
},
|
|
156
|
-
topRight: {
|
|
157
|
-
marginTop: verticalInsetPx,
|
|
158
|
-
marginRight: horizontalInsetPx,
|
|
159
|
-
},
|
|
160
|
-
bottomRight: {
|
|
161
|
-
marginBottom: verticalInsetPx,
|
|
162
|
-
marginRight: horizontalInsetPx,
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
// For the two-icon layout.
|
|
166
|
-
middleLeft: {
|
|
167
|
-
marginLeft: horizontalInsetPx,
|
|
168
|
-
},
|
|
169
|
-
middleRight: {
|
|
170
|
-
marginRight: horizontalInsetPx,
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
base: {
|
|
174
|
-
fontSize: 18,
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
secondary: {
|
|
178
|
-
opacity: 0.3,
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
export default MultiSymbolGrid;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A popover that renders a set of keys floating above the page.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {StyleSheet} from "aphrodite";
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
|
|
8
|
-
import {BorderStyles} from "../../enums";
|
|
9
|
-
import {View} from "../../fake-react-native-web/index";
|
|
10
|
-
|
|
11
|
-
import TouchableKeypadButton from "./touchable-keypad-button";
|
|
12
|
-
import * as zIndexes from "./z-indexes";
|
|
13
|
-
|
|
14
|
-
import type {KeyConfig} from "../../types";
|
|
15
|
-
|
|
16
|
-
type Prop = {
|
|
17
|
-
keys: ReadonlyArray<KeyConfig>;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
class MultiSymbolPopover extends React.Component<Prop> {
|
|
21
|
-
render() {
|
|
22
|
-
const {keys} = this.props;
|
|
23
|
-
|
|
24
|
-
// TODO(charlie): We have to require this lazily because of a cyclic
|
|
25
|
-
// dependence in our components.
|
|
26
|
-
return (
|
|
27
|
-
<View style={styles.container}>
|
|
28
|
-
{keys.map((key) => {
|
|
29
|
-
return (
|
|
30
|
-
<TouchableKeypadButton
|
|
31
|
-
keyConfig={key}
|
|
32
|
-
borders={BorderStyles.NONE}
|
|
33
|
-
/>
|
|
34
|
-
);
|
|
35
|
-
})}
|
|
36
|
-
</View>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const styles = StyleSheet.create({
|
|
42
|
-
container: {
|
|
43
|
-
flexDirection: "column-reverse",
|
|
44
|
-
position: "relative",
|
|
45
|
-
width: "100%",
|
|
46
|
-
borderRadius: 2,
|
|
47
|
-
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.3)",
|
|
48
|
-
zIndex: zIndexes.popover,
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
// eslint-disable-next-line react-native/no-unused-styles
|
|
52
|
-
popoverButton: {
|
|
53
|
-
backgroundColor: "#FFF",
|
|
54
|
-
borderWidth: 0,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
export default MultiSymbolPopover;
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A component that renders a navigation pad, which consists of an arrow for
|
|
3
|
-
* each possible direction.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {StyleSheet} from "aphrodite";
|
|
7
|
-
import * as React from "react";
|
|
8
|
-
|
|
9
|
-
import KeyConfigs from "../../data/key-configs";
|
|
10
|
-
import {BorderStyles} from "../../enums";
|
|
11
|
-
import {View} from "../../fake-react-native-web/index";
|
|
12
|
-
import {
|
|
13
|
-
navigationPadWidthPx,
|
|
14
|
-
controlGrey,
|
|
15
|
-
valueGrey,
|
|
16
|
-
offBlack16,
|
|
17
|
-
} from "../common-style";
|
|
18
|
-
|
|
19
|
-
import Styles from "./styles";
|
|
20
|
-
import TouchableKeypadButton from "./touchable-keypad-button";
|
|
21
|
-
|
|
22
|
-
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
23
|
-
|
|
24
|
-
const {row, column, centered, stretch, roundedTopLeft} = Styles;
|
|
25
|
-
|
|
26
|
-
type Props = {
|
|
27
|
-
roundTopLeft: boolean;
|
|
28
|
-
style: StyleType;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
class NavigationPad extends React.Component<Props> {
|
|
32
|
-
render() {
|
|
33
|
-
// TODO(charlie): Disable the navigational arrows depending on the
|
|
34
|
-
// cursor context.
|
|
35
|
-
const {roundTopLeft, style} = this.props;
|
|
36
|
-
|
|
37
|
-
const containerStyle = [
|
|
38
|
-
column,
|
|
39
|
-
centered,
|
|
40
|
-
styles.container,
|
|
41
|
-
roundTopLeft && roundedTopLeft,
|
|
42
|
-
...(Array.isArray(style) ? style : [style]),
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<View style={containerStyle}>
|
|
47
|
-
<View style={[row, centered]}>
|
|
48
|
-
<TouchableKeypadButton
|
|
49
|
-
keyConfig={KeyConfigs.UP}
|
|
50
|
-
borders={BorderStyles.NONE}
|
|
51
|
-
style={[styles.navigationKey, styles.topArrow]}
|
|
52
|
-
/>
|
|
53
|
-
</View>
|
|
54
|
-
<View style={[row, centered, stretch]}>
|
|
55
|
-
<TouchableKeypadButton
|
|
56
|
-
keyConfig={KeyConfigs.LEFT}
|
|
57
|
-
borders={BorderStyles.NONE}
|
|
58
|
-
style={[styles.navigationKey, styles.leftArrow]}
|
|
59
|
-
/>
|
|
60
|
-
<View style={styles.horizontalSpacer} />
|
|
61
|
-
<TouchableKeypadButton
|
|
62
|
-
keyConfig={KeyConfigs.RIGHT}
|
|
63
|
-
borders={BorderStyles.NONE}
|
|
64
|
-
style={[styles.navigationKey, styles.rightArrow]}
|
|
65
|
-
/>
|
|
66
|
-
</View>
|
|
67
|
-
<View style={[row, centered]}>
|
|
68
|
-
<TouchableKeypadButton
|
|
69
|
-
keyConfig={KeyConfigs.DOWN}
|
|
70
|
-
borders={BorderStyles.NONE}
|
|
71
|
-
style={[styles.navigationKey, styles.bottomArrow]}
|
|
72
|
-
/>
|
|
73
|
-
</View>
|
|
74
|
-
</View>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const buttonSizePx = 48;
|
|
80
|
-
const borderRadiusPx = 4;
|
|
81
|
-
const borderWidthPx = 1;
|
|
82
|
-
|
|
83
|
-
const styles = StyleSheet.create({
|
|
84
|
-
container: {
|
|
85
|
-
backgroundColor: controlGrey,
|
|
86
|
-
width: navigationPadWidthPx,
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
navigationKey: {
|
|
90
|
-
borderColor: offBlack16,
|
|
91
|
-
backgroundColor: valueGrey,
|
|
92
|
-
width: buttonSizePx,
|
|
93
|
-
height: buttonSizePx,
|
|
94
|
-
|
|
95
|
-
// Override the default box-sizing so that our buttons are
|
|
96
|
-
// `buttonSizePx` exclusive of their borders.
|
|
97
|
-
boxSizing: "content-box",
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
topArrow: {
|
|
101
|
-
borderTopWidth: borderWidthPx,
|
|
102
|
-
borderLeftWidth: borderWidthPx,
|
|
103
|
-
borderRightWidth: borderWidthPx,
|
|
104
|
-
borderTopLeftRadius: borderRadiusPx,
|
|
105
|
-
borderTopRightRadius: borderRadiusPx,
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
rightArrow: {
|
|
109
|
-
borderTopWidth: borderWidthPx,
|
|
110
|
-
borderRightWidth: borderWidthPx,
|
|
111
|
-
borderBottomWidth: borderWidthPx,
|
|
112
|
-
borderTopRightRadius: borderRadiusPx,
|
|
113
|
-
borderBottomRightRadius: borderRadiusPx,
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
bottomArrow: {
|
|
117
|
-
borderBottomWidth: borderWidthPx,
|
|
118
|
-
borderLeftWidth: borderWidthPx,
|
|
119
|
-
borderRightWidth: borderWidthPx,
|
|
120
|
-
borderBottomLeftRadius: borderRadiusPx,
|
|
121
|
-
borderBottomRightRadius: borderRadiusPx,
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
leftArrow: {
|
|
125
|
-
borderTopWidth: borderWidthPx,
|
|
126
|
-
borderBottomWidth: borderWidthPx,
|
|
127
|
-
borderLeftWidth: borderWidthPx,
|
|
128
|
-
borderTopLeftRadius: borderRadiusPx,
|
|
129
|
-
borderBottomLeftRadius: borderRadiusPx,
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
horizontalSpacer: {
|
|
133
|
-
background: valueGrey,
|
|
134
|
-
// No need to set a height -- the spacer will be stretched by its
|
|
135
|
-
// parent.
|
|
136
|
-
width: buttonSizePx,
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
export default NavigationPad;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import type {LayoutProps, Bound} from "../../types";
|
|
2
|
-
/**
|
|
3
|
-
* A manager for our node-to-ID system. In particular, this class is
|
|
4
|
-
* responsible for maintaing a mapping between DOM nodes and node IDs, and
|
|
5
|
-
* translating touch events from the raw positions at which they occur to the
|
|
6
|
-
* nodes over which they are occurring. This differs from browser behavior, in
|
|
7
|
-
* which touch events are only sent to the node in which a touch started.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
class NodeManager {
|
|
11
|
-
_nodesById: Record<string, HTMLElement>;
|
|
12
|
-
_orderedIds: ReadonlyArray<string>;
|
|
13
|
-
_cachedBoundingBoxesById: Record<string, Bound>;
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
// A mapping from IDs to DOM nodes.
|
|
17
|
-
this._nodesById = {};
|
|
18
|
-
|
|
19
|
-
// An ordered list of IDs, where DOM nodes that are "higher" on the
|
|
20
|
-
// page come earlier in the list. Note that an ID may be present in
|
|
21
|
-
// this ordered list but not be registered to a DOM node (i.e., if it
|
|
22
|
-
// is registered as a child of another DOM node, but hasn't appeared in
|
|
23
|
-
// the DOM yet).
|
|
24
|
-
this._orderedIds = [];
|
|
25
|
-
|
|
26
|
-
// Cache bounding boxes aggressively, re-computing on page resize. Our
|
|
27
|
-
// caching here makes the strict assumption that if a node is reasonably
|
|
28
|
-
// assumed to be on-screen, its bounds won't change. For example, if we
|
|
29
|
-
// see that a touch occurred within the bounds of a node, we cache those
|
|
30
|
-
// bounds.
|
|
31
|
-
// TODO(charlie): It'd be great if we could pre-compute these when the
|
|
32
|
-
// page is idle and the keypad is visible (i.e., the nodes are in their
|
|
33
|
-
// proper positions).
|
|
34
|
-
this._cachedBoundingBoxesById = {};
|
|
35
|
-
window.addEventListener("resize", () => {
|
|
36
|
-
this._cachedBoundingBoxesById = {};
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Register a DOM node with a given identifier.
|
|
42
|
-
*
|
|
43
|
-
* @param {string} id - the identifier of the given node
|
|
44
|
-
* @param {node} domNode - the DOM node linked to the identifier
|
|
45
|
-
* @param {object} borders - an opaque object describing the node's borders
|
|
46
|
-
*/
|
|
47
|
-
registerDOMNode(
|
|
48
|
-
id: string,
|
|
49
|
-
domNode: HTMLElement,
|
|
50
|
-
childIds: ReadonlyArray<string>,
|
|
51
|
-
) {
|
|
52
|
-
this._nodesById[id] = domNode;
|
|
53
|
-
|
|
54
|
-
// Make sure that any children appear first.
|
|
55
|
-
// TODO(charlie): This is a very simplistic system that wouldn't
|
|
56
|
-
// properly handle multiple levels of nesting.
|
|
57
|
-
const allIds = [...(childIds || []), id, ...this._orderedIds];
|
|
58
|
-
|
|
59
|
-
// De-dupe the list of IDs.
|
|
60
|
-
const orderedIds = [];
|
|
61
|
-
const seenIds = {};
|
|
62
|
-
for (const id of allIds) {
|
|
63
|
-
if (!seenIds[id]) {
|
|
64
|
-
// @ts-expect-error TS2345
|
|
65
|
-
orderedIds.push(id);
|
|
66
|
-
seenIds[id] = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
this._orderedIds = orderedIds;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Unregister the DOM node with the given identifier.
|
|
75
|
-
*
|
|
76
|
-
* @param {string} id - the identifier of the node to unregister
|
|
77
|
-
*/
|
|
78
|
-
unregisterDOMNode(id: string) {
|
|
79
|
-
delete this._nodesById[id];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Return the identifier of the topmost node located at the given
|
|
84
|
-
* coordinates.
|
|
85
|
-
*
|
|
86
|
-
* @param {number} x - the x coordinate at which to search for a node
|
|
87
|
-
* @param {number} y - the y coordinate at which to search for a node
|
|
88
|
-
* @returns {null|string} - null or the identifier of the topmost node at
|
|
89
|
-
* the given coordinates
|
|
90
|
-
*/
|
|
91
|
-
idForCoords(x: number, y: number): string | void {
|
|
92
|
-
for (const id of this._orderedIds) {
|
|
93
|
-
const domNode = this._nodesById[id];
|
|
94
|
-
if (domNode) {
|
|
95
|
-
const bounds = domNode.getBoundingClientRect();
|
|
96
|
-
if (
|
|
97
|
-
bounds.left <= x &&
|
|
98
|
-
bounds.right > x &&
|
|
99
|
-
bounds.top <= y &&
|
|
100
|
-
bounds.bottom > y
|
|
101
|
-
) {
|
|
102
|
-
this._cachedBoundingBoxesById[id] = bounds;
|
|
103
|
-
return id;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Return the necessary layout information, including the bounds and border
|
|
111
|
-
* values, for the node with the given identifier.
|
|
112
|
-
*
|
|
113
|
-
* @param {string} id - the identifier of the node for which to return the
|
|
114
|
-
* layout information
|
|
115
|
-
* @returns {object} - the bounding client rect for the given node, along
|
|
116
|
-
* with its borders
|
|
117
|
-
*/
|
|
118
|
-
layoutPropsForId(id: string): LayoutProps {
|
|
119
|
-
if (!this._cachedBoundingBoxesById[id]) {
|
|
120
|
-
const node = this._nodesById[id];
|
|
121
|
-
|
|
122
|
-
this._cachedBoundingBoxesById[id] = node
|
|
123
|
-
? node.getBoundingClientRect()
|
|
124
|
-
: new DOMRect();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
initialBounds: this._cachedBoundingBoxesById[id],
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export default NodeManager;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A component that renders and animates the popovers that appear over the
|
|
3
|
-
* multi-functional keys.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
import {CSSTransition} from "react-transition-group";
|
|
8
|
-
|
|
9
|
-
import KeyConfigs from "../../data/key-configs";
|
|
10
|
-
|
|
11
|
-
import MultiSymbolPopover from "./multi-symbol-popover";
|
|
12
|
-
|
|
13
|
-
import type {Popover, KeyConfig} from "../../types";
|
|
14
|
-
|
|
15
|
-
// NOTE(charlie): These must be kept in sync with the transition durations and
|
|
16
|
-
// classnames specified in popover.less.
|
|
17
|
-
const animationTransitionName = "popover";
|
|
18
|
-
const animationDurationMs = 200;
|
|
19
|
-
|
|
20
|
-
type Props = {
|
|
21
|
-
// TODO(matthewc) should be something like Bound, but couldn't fix errors
|
|
22
|
-
bounds: any;
|
|
23
|
-
childKeys: ReadonlyArray<KeyConfig>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// A container component used to position a popover absolutely at a specific
|
|
27
|
-
// position.
|
|
28
|
-
class PopoverContainer extends React.Component<Props> {
|
|
29
|
-
render() {
|
|
30
|
-
const {bounds, childKeys} = this.props;
|
|
31
|
-
|
|
32
|
-
const containerStyle = {
|
|
33
|
-
position: "absolute",
|
|
34
|
-
...bounds,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div style={containerStyle}>
|
|
39
|
-
<MultiSymbolPopover keys={childKeys} />
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
type PopoverManagerProps = {
|
|
46
|
-
popover: Popover | null;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
class PopoverManager extends React.Component<PopoverManagerProps> {
|
|
50
|
-
render() {
|
|
51
|
-
const {popover} = this.props;
|
|
52
|
-
|
|
53
|
-
return popover ? (
|
|
54
|
-
<CSSTransition
|
|
55
|
-
in={true}
|
|
56
|
-
classNames={animationTransitionName}
|
|
57
|
-
enter={true}
|
|
58
|
-
exit={false}
|
|
59
|
-
timeout={{
|
|
60
|
-
enter: animationDurationMs,
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
-
<PopoverContainer
|
|
64
|
-
key={popover.childKeyIds[0]}
|
|
65
|
-
bounds={popover.bounds}
|
|
66
|
-
childKeys={popover.childKeyIds.map((id) => KeyConfigs[id])}
|
|
67
|
-
/>
|
|
68
|
-
</CSSTransition>
|
|
69
|
-
) : null;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export default PopoverManager;
|