@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.
Files changed (140) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/components/aphrodite-css-transition-group/transition-child.d.ts +11 -8
  3. package/dist/components/keypad/index.d.ts +1 -1
  4. package/dist/components/keypad/mobile-keypad-internals.d.ts +49 -0
  5. package/dist/components/keypad/mobile-keypad.d.ts +4 -48
  6. package/dist/es/index.js +168 -4740
  7. package/dist/es/index.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +166 -4722
  10. package/dist/index.js.map +1 -1
  11. package/package.json +10 -9
  12. package/src/components/__tests__/integration.test.tsx +2 -3
  13. package/src/components/keypad/__tests__/mobile-keypad.test.tsx +8 -8
  14. package/src/components/keypad/index.tsx +1 -1
  15. package/src/components/keypad/mobile-keypad-internals.tsx +240 -0
  16. package/src/components/keypad/mobile-keypad.tsx +21 -234
  17. package/src/full-mobile-input.stories.tsx +0 -1
  18. package/src/index.ts +1 -1
  19. package/tsconfig-build.tsbuildinfo +1 -1
  20. package/dist/components/keypad-legacy/compute-layout-parameters.d.ts +0 -28
  21. package/dist/components/keypad-legacy/corner-decal.d.ts +0 -12
  22. package/dist/components/keypad-legacy/echo-manager.d.ts +0 -17
  23. package/dist/components/keypad-legacy/empty-keypad-button.d.ts +0 -13
  24. package/dist/components/keypad-legacy/expression-keypad.d.ts +0 -21
  25. package/dist/components/keypad-legacy/fraction-keypad.d.ts +0 -21
  26. package/dist/components/keypad-legacy/gesture-manager.d.ts +0 -86
  27. package/dist/components/keypad-legacy/gesture-state-machine.d.ts +0 -105
  28. package/dist/components/keypad-legacy/icon.d.ts +0 -15
  29. package/dist/components/keypad-legacy/index.d.ts +0 -1
  30. package/dist/components/keypad-legacy/keypad-button.d.ts +0 -53
  31. package/dist/components/keypad-legacy/keypad-container.d.ts +0 -41
  32. package/dist/components/keypad-legacy/keypad.d.ts +0 -31
  33. package/dist/components/keypad-legacy/many-keypad-button.d.ts +0 -15
  34. package/dist/components/keypad-legacy/math-icon.d.ts +0 -16
  35. package/dist/components/keypad-legacy/multi-symbol-grid.d.ts +0 -14
  36. package/dist/components/keypad-legacy/multi-symbol-popover.d.ts +0 -12
  37. package/dist/components/keypad-legacy/navigation-pad.d.ts +0 -14
  38. package/dist/components/keypad-legacy/node-manager.d.ts +0 -49
  39. package/dist/components/keypad-legacy/popover-manager.d.ts +0 -13
  40. package/dist/components/keypad-legacy/popover-state-machine.d.ts +0 -68
  41. package/dist/components/keypad-legacy/provided-keypad.d.ts +0 -28
  42. package/dist/components/keypad-legacy/store/actions.d.ts +0 -55
  43. package/dist/components/keypad-legacy/store/echo-reducer.d.ts +0 -4
  44. package/dist/components/keypad-legacy/store/index.d.ts +0 -9
  45. package/dist/components/keypad-legacy/store/input-reducer.d.ts +0 -4
  46. package/dist/components/keypad-legacy/store/keypad-reducer.d.ts +0 -4
  47. package/dist/components/keypad-legacy/store/layout-reducer.d.ts +0 -4
  48. package/dist/components/keypad-legacy/store/shared.d.ts +0 -7
  49. package/dist/components/keypad-legacy/store/types.d.ts +0 -47
  50. package/dist/components/keypad-legacy/styles.d.ts +0 -5
  51. package/dist/components/keypad-legacy/svg-icon.d.ts +0 -12
  52. package/dist/components/keypad-legacy/text-icon.d.ts +0 -13
  53. package/dist/components/keypad-legacy/touchable-keypad-button.d.ts +0 -37
  54. package/dist/components/keypad-legacy/two-page-keypad.d.ts +0 -21
  55. package/dist/components/keypad-legacy/z-indexes.d.ts +0 -7
  56. package/dist/components/keypad-switch.d.ts +0 -12
  57. package/src/components/keypad-legacy/__tests__/gesture-state-machine.test.ts +0 -441
  58. package/src/components/keypad-legacy/__tests__/node-manager.test.ts +0 -89
  59. package/src/components/keypad-legacy/__tests__/two-page-keypad.test.tsx +0 -38
  60. package/src/components/keypad-legacy/compute-layout-parameters.ts +0 -205
  61. package/src/components/keypad-legacy/corner-decal.tsx +0 -56
  62. package/src/components/keypad-legacy/echo-manager.tsx +0 -152
  63. package/src/components/keypad-legacy/empty-keypad-button.tsx +0 -58
  64. package/src/components/keypad-legacy/expression-keypad.tsx +0 -315
  65. package/src/components/keypad-legacy/fraction-keypad.tsx +0 -180
  66. package/src/components/keypad-legacy/gesture-manager.ts +0 -255
  67. package/src/components/keypad-legacy/gesture-state-machine.ts +0 -329
  68. package/src/components/keypad-legacy/icon.tsx +0 -72
  69. package/src/components/keypad-legacy/iconography/arrow.js +0 -22
  70. package/src/components/keypad-legacy/iconography/backspace.js +0 -29
  71. package/src/components/keypad-legacy/iconography/cdot.js +0 -29
  72. package/src/components/keypad-legacy/iconography/cos.js +0 -30
  73. package/src/components/keypad-legacy/iconography/cube-root.js +0 -36
  74. package/src/components/keypad-legacy/iconography/dismiss.js +0 -25
  75. package/src/components/keypad-legacy/iconography/divide.js +0 -34
  76. package/src/components/keypad-legacy/iconography/down.js +0 -16
  77. package/src/components/keypad-legacy/iconography/equal.js +0 -33
  78. package/src/components/keypad-legacy/iconography/exp-2.js +0 -29
  79. package/src/components/keypad-legacy/iconography/exp-3.js +0 -29
  80. package/src/components/keypad-legacy/iconography/exp.js +0 -29
  81. package/src/components/keypad-legacy/iconography/frac.js +0 -44
  82. package/src/components/keypad-legacy/iconography/geq.js +0 -33
  83. package/src/components/keypad-legacy/iconography/gt.js +0 -33
  84. package/src/components/keypad-legacy/iconography/index.js +0 -45
  85. package/src/components/keypad-legacy/iconography/jump-into-numerator.js +0 -41
  86. package/src/components/keypad-legacy/iconography/jump-out-base.js +0 -30
  87. package/src/components/keypad-legacy/iconography/jump-out-denominator.js +0 -41
  88. package/src/components/keypad-legacy/iconography/jump-out-exponent.js +0 -30
  89. package/src/components/keypad-legacy/iconography/jump-out-numerator.js +0 -41
  90. package/src/components/keypad-legacy/iconography/jump-out-parentheses.js +0 -33
  91. package/src/components/keypad-legacy/iconography/left-paren.js +0 -33
  92. package/src/components/keypad-legacy/iconography/left.js +0 -16
  93. package/src/components/keypad-legacy/iconography/leq.js +0 -33
  94. package/src/components/keypad-legacy/iconography/ln.js +0 -29
  95. package/src/components/keypad-legacy/iconography/log-n.js +0 -29
  96. package/src/components/keypad-legacy/iconography/log.js +0 -29
  97. package/src/components/keypad-legacy/iconography/lt.js +0 -33
  98. package/src/components/keypad-legacy/iconography/minus.js +0 -32
  99. package/src/components/keypad-legacy/iconography/neq.js +0 -33
  100. package/src/components/keypad-legacy/iconography/parens.js +0 -33
  101. package/src/components/keypad-legacy/iconography/percent.js +0 -49
  102. package/src/components/keypad-legacy/iconography/period.js +0 -26
  103. package/src/components/keypad-legacy/iconography/plus.js +0 -32
  104. package/src/components/keypad-legacy/iconography/radical.js +0 -36
  105. package/src/components/keypad-legacy/iconography/right-paren.js +0 -33
  106. package/src/components/keypad-legacy/iconography/right.js +0 -16
  107. package/src/components/keypad-legacy/iconography/sin.js +0 -30
  108. package/src/components/keypad-legacy/iconography/sqrt.js +0 -32
  109. package/src/components/keypad-legacy/iconography/tan.js +0 -30
  110. package/src/components/keypad-legacy/iconography/times.js +0 -33
  111. package/src/components/keypad-legacy/iconography/up.js +0 -16
  112. package/src/components/keypad-legacy/index.ts +0 -1
  113. package/src/components/keypad-legacy/keypad-button.tsx +0 -368
  114. package/src/components/keypad-legacy/keypad-container.tsx +0 -358
  115. package/src/components/keypad-legacy/keypad.tsx +0 -162
  116. package/src/components/keypad-legacy/many-keypad-button.tsx +0 -54
  117. package/src/components/keypad-legacy/math-icon.tsx +0 -66
  118. package/src/components/keypad-legacy/multi-symbol-grid.tsx +0 -182
  119. package/src/components/keypad-legacy/multi-symbol-popover.tsx +0 -58
  120. package/src/components/keypad-legacy/navigation-pad.tsx +0 -140
  121. package/src/components/keypad-legacy/node-manager.ts +0 -133
  122. package/src/components/keypad-legacy/popover-manager.tsx +0 -73
  123. package/src/components/keypad-legacy/popover-state-machine.ts +0 -184
  124. package/src/components/keypad-legacy/provided-keypad.tsx +0 -136
  125. package/src/components/keypad-legacy/store/actions.ts +0 -155
  126. package/src/components/keypad-legacy/store/echo-reducer.ts +0 -57
  127. package/src/components/keypad-legacy/store/index.ts +0 -110
  128. package/src/components/keypad-legacy/store/input-reducer.ts +0 -55
  129. package/src/components/keypad-legacy/store/keypad-reducer.ts +0 -58
  130. package/src/components/keypad-legacy/store/layout-reducer.test.ts +0 -171
  131. package/src/components/keypad-legacy/store/layout-reducer.ts +0 -129
  132. package/src/components/keypad-legacy/store/shared.ts +0 -12
  133. package/src/components/keypad-legacy/store/types.ts +0 -78
  134. package/src/components/keypad-legacy/styles.ts +0 -38
  135. package/src/components/keypad-legacy/svg-icon.tsx +0 -24
  136. package/src/components/keypad-legacy/text-icon.tsx +0 -53
  137. package/src/components/keypad-legacy/touchable-keypad-button.tsx +0 -163
  138. package/src/components/keypad-legacy/two-page-keypad.tsx +0 -115
  139. package/src/components/keypad-legacy/z-indexes.ts +0 -8
  140. 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;