@khanacademy/math-input 0.7.2 → 1.0.1
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 +16 -0
- package/dist/components/compute-layout-parameters.d.ts +38 -0
- package/dist/components/compute-layout-parameters.js.flow +49 -0
- package/dist/components/corner-decal.d.ts +12 -0
- package/dist/components/corner-decal.js.flow +15 -0
- package/dist/components/echo-manager.d.ts +26 -0
- package/dist/components/echo-manager.js.flow +29 -0
- package/dist/components/empty-keypad-button.d.ts +13 -0
- package/dist/components/empty-keypad-button.js.flow +23 -0
- package/dist/components/expression-keypad.d.ts +22 -0
- package/dist/components/expression-keypad.js.flow +32 -0
- package/dist/components/fraction-keypad.d.ts +21 -0
- package/dist/components/fraction-keypad.js.flow +30 -0
- package/dist/components/gesture-manager.d.ts +74 -0
- package/dist/components/gesture-manager.js.flow +82 -0
- package/dist/components/gesture-state-machine.d.ts +105 -0
- package/dist/components/gesture-state-machine.js.flow +118 -0
- package/dist/components/icon.d.ts +15 -0
- package/dist/components/icon.js.flow +18 -0
- package/dist/components/input/__tests__/test-math-wrapper.d.ts +8 -0
- package/dist/components/input/__tests__/test-math-wrapper.js.flow +14 -0
- package/dist/components/input/cursor-handle.d.ts +1 -1
- package/dist/components/input/cursor-handle.js.flow +1 -1
- package/dist/components/input/drag-listener.d.ts +13 -0
- package/dist/components/input/drag-listener.js.flow +19 -0
- package/dist/components/input/math-input.d.ts +5 -4
- package/dist/components/input/math-input.js.flow +5 -4
- package/dist/components/input/math-wrapper.d.ts +110 -0
- package/dist/components/input/math-wrapper.js.flow +125 -0
- package/dist/components/input/scroll-into-view.d.ts +11 -0
- package/dist/components/input/scroll-into-view.js.flow +20 -0
- package/dist/components/keypad/button-assets.d.ts +4 -3
- package/dist/components/keypad/button-assets.js.flow +3 -3
- package/dist/components/keypad/button.d.ts +1 -2
- package/dist/components/keypad/button.js.flow +1 -2
- package/dist/components/keypad/index.d.ts +1 -1
- package/dist/components/keypad/index.js.flow +1 -3
- package/dist/components/keypad/keypad-page-items.d.ts +15 -10
- package/dist/components/keypad/keypad-page-items.js.flow +20 -10
- package/dist/components/keypad-button.d.ts +52 -0
- package/dist/components/keypad-button.js.flow +79 -0
- package/dist/components/keypad-container.d.ts +40 -0
- package/dist/components/keypad-container.js.flow +58 -0
- package/dist/components/keypad.d.ts +31 -0
- package/dist/components/keypad.js.flow +40 -0
- package/dist/components/many-keypad-button.d.ts +15 -0
- package/dist/components/many-keypad-button.js.flow +17 -0
- package/dist/components/math-icon.d.ts +16 -0
- package/dist/components/math-icon.js.flow +19 -0
- package/dist/components/multi-symbol-grid.d.ts +14 -0
- package/dist/components/multi-symbol-grid.js.flow +16 -0
- package/dist/components/multi-symbol-popover.d.ts +12 -0
- package/dist/components/multi-symbol-popover.js.flow +15 -0
- package/dist/components/navigation-pad.d.ts +14 -0
- package/dist/components/navigation-pad.js.flow +16 -0
- package/dist/components/node-manager.d.ts +50 -0
- package/dist/components/node-manager.js.flow +62 -0
- package/dist/components/popover-manager.d.ts +13 -0
- package/dist/components/popover-manager.js.flow +15 -0
- package/dist/components/popover-state-machine.d.ts +68 -0
- package/dist/components/popover-state-machine.js.flow +77 -0
- package/dist/components/provided-keypad.d.ts +8 -10
- package/dist/components/provided-keypad.js.flow +8 -10
- package/dist/components/styles.d.ts +6 -0
- package/dist/components/styles.js.flow +13 -0
- package/dist/components/svg-icon.d.ts +12 -0
- package/dist/components/svg-icon.js.flow +15 -0
- package/dist/components/tabbar/icons.d.ts +3 -2
- package/dist/components/tabbar/icons.js.flow +3 -2
- package/dist/components/tabbar/item.d.ts +1 -2
- package/dist/components/tabbar/item.js.flow +1 -2
- package/dist/components/tabbar/tabbar.d.ts +3 -3
- package/dist/components/tabbar/tabbar.js.flow +3 -3
- package/dist/components/text-icon.d.ts +13 -0
- package/dist/components/text-icon.js.flow +16 -0
- package/dist/components/touchable-keypad-button.d.ts +30 -0
- package/dist/components/touchable-keypad-button.js.flow +35 -0
- package/dist/components/two-page-keypad.d.ts +20 -0
- package/dist/components/two-page-keypad.js.flow +30 -0
- package/dist/components/velocity-tracker.d.ts +48 -0
- package/dist/components/velocity-tracker.js.flow +54 -0
- package/dist/es/index.css +0 -3
- package/dist/es/index.js +933 -1065
- package/dist/es/index.js.map +1 -1
- package/dist/fake-react-native-web/text.d.ts +2 -1
- package/dist/fake-react-native-web/text.js.flow +2 -1
- package/dist/fake-react-native-web/view.d.ts +3 -2
- package/dist/fake-react-native-web/view.js.flow +3 -2
- package/dist/index.css +0 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +977 -1090
- package/dist/index.js.flow +1 -4
- package/dist/index.js.map +1 -1
- package/dist/store/actions.d.ts +64 -0
- package/dist/store/actions.js.flow +100 -0
- package/dist/store/echo-reducer.d.ts +4 -0
- package/dist/store/echo-reducer.js.flow +10 -0
- package/dist/store/index.d.ts +10 -1
- package/dist/store/index.js.flow +17 -1
- package/dist/store/input-reducer.d.ts +4 -0
- package/dist/store/input-reducer.js.flow +13 -0
- package/dist/store/keypad-reducer.d.ts +4 -0
- package/dist/store/keypad-reducer.js.flow +13 -0
- package/dist/store/layout-reducer.d.ts +4 -0
- package/dist/store/layout-reducer.js.flow +13 -0
- package/dist/store/pager-reducer.d.ts +4 -0
- package/dist/store/pager-reducer.js.flow +13 -0
- package/dist/store/shared.d.ts +6 -0
- package/dist/store/shared.js.flow +13 -0
- package/dist/store/types.d.ts +58 -0
- package/dist/store/types.js.flow +64 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.js.flow +73 -0
- package/less/overrides.less +0 -6
- package/package.json +1 -1
- package/src/components/__tests__/{gesture-state-machine_test.js → gesture-state-machine.test.ts} +5 -1
- package/src/components/__tests__/{two-page-keypad_test.js → two-page-keypad.test.tsx} +0 -2
- package/src/components/{corner-decal.js → corner-decal.tsx} +6 -5
- package/src/components/{echo-manager.js → echo-manager.tsx} +29 -24
- package/src/components/{empty-keypad-button.js → empty-keypad-button.tsx} +17 -10
- package/src/components/{expression-keypad.js → expression-keypad.tsx} +27 -25
- package/src/components/{fraction-keypad.js → fraction-keypad.tsx} +21 -16
- package/src/components/{gesture-manager.js → gesture-manager.ts} +10 -4
- package/src/components/{gesture-state-machine.js → gesture-state-machine.ts} +49 -3
- package/src/components/{icon.js → icon.tsx} +12 -14
- package/src/components/input/cursor-handle.tsx +1 -1
- package/src/components/input/{drag-listener.js → drag-listener.ts} +4 -0
- package/src/components/input/math-input.tsx +10 -9
- package/src/components/input/{math-wrapper.js → math-wrapper.ts} +10 -6
- package/src/components/input/{scroll-into-view.js → scroll-into-view.ts} +5 -15
- package/src/components/keypad/button-assets.tsx +4 -5
- package/src/components/keypad/button.tsx +1 -2
- package/src/components/keypad/index.tsx +2 -2
- package/src/components/keypad/keypad-page-items.tsx +33 -10
- package/src/components/{keypad-button.js → keypad-button.tsx} +42 -37
- package/src/components/{keypad-container.js → keypad-container.tsx} +42 -24
- package/src/components/{keypad.js → keypad.tsx} +32 -24
- package/src/components/{many-keypad-button.js → many-keypad-button.tsx} +8 -6
- package/src/components/{math-icon.js → math-icon.tsx} +7 -6
- package/src/components/{multi-symbol-grid.js → multi-symbol-grid.tsx} +8 -8
- package/src/components/{multi-symbol-popover.js → multi-symbol-popover.tsx} +5 -6
- package/src/components/{navigation-pad.js → navigation-pad.tsx} +7 -6
- package/src/components/{node-manager.js → node-manager.ts} +16 -4
- package/src/components/{popover-manager.js → popover-manager.tsx} +13 -16
- package/src/components/{popover-state-machine.js → popover-state-machine.ts} +13 -2
- package/src/components/prop-types.js +1 -67
- package/src/components/provided-keypad.tsx +16 -23
- package/src/components/{svg-icon.js → svg-icon.tsx} +5 -6
- package/src/components/tabbar/icons.tsx +4 -2
- package/src/components/tabbar/item.tsx +1 -3
- package/src/components/tabbar/{tabbar.stories.js → tabbar.stories.tsx} +10 -1
- package/src/components/tabbar/tabbar.tsx +3 -3
- package/src/components/{text-icon.js → text-icon.tsx} +7 -6
- package/src/components/{touchable-keypad-button.js → touchable-keypad-button.tsx} +19 -16
- package/src/components/{two-page-keypad.js → two-page-keypad.tsx} +13 -9
- package/src/components/{velocity-tracker.js → velocity-tracker.ts} +14 -4
- package/src/fake-react-native-web/text.tsx +2 -1
- package/src/fake-react-native-web/view.tsx +3 -2
- package/src/index.ts +1 -4
- package/src/math-input.stories.tsx +67 -0
- package/src/store/actions.ts +178 -0
- package/src/store/echo-reducer.ts +61 -0
- package/src/store/index.ts +39 -449
- package/src/store/input-reducer.ts +56 -0
- package/src/store/keypad-reducer.ts +59 -0
- package/src/store/layout-reducer.ts +134 -0
- package/src/store/pager-reducer.ts +125 -0
- package/src/store/shared.ts +12 -0
- package/src/store/types.ts +82 -0
- package/src/types.ts +81 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/src/actions/index.js +0 -57
- package/src/components/app.js +0 -73
- package/src/demo.js +0 -9
- package/src/native-app.js +0 -85
- /package/src/components/__tests__/{node-manager_test.js → node-manager.test.ts} +0 -0
- /package/src/components/{compute-layout-parameters.js → compute-layout-parameters.ts} +0 -0
- /package/src/components/input/__tests__/{context-tracking_test.js → context-tracking.test.ts} +0 -0
- /package/src/components/input/__tests__/{mathquill_test.js → mathquill.test.ts} +0 -0
- /package/src/components/input/__tests__/{test-math-wrapper.jsx → test-math-wrapper.ts} +0 -0
- /package/src/components/keypad/{button.stories.js → button.stories.tsx} +0 -0
- /package/src/components/{styles.js → styles.ts} +0 -0
- /package/src/components/tabbar/__tests__/{tabbar_test.js → tabbar.test.tsx} +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {tabletCutoffPx} from "../components/common-style";
|
|
2
|
+
import {computeLayoutParameters} from "../components/compute-layout-parameters";
|
|
3
|
+
import {DeviceOrientations, DeviceTypes, LayoutModes} from "../consts";
|
|
4
|
+
|
|
5
|
+
import {defaultKeypadType, keypadForType} from "./shared";
|
|
6
|
+
|
|
7
|
+
import type {Action} from "./actions";
|
|
8
|
+
import type {LayoutState} from "./types";
|
|
9
|
+
|
|
10
|
+
const initialLayoutState = {
|
|
11
|
+
gridDimensions: {
|
|
12
|
+
numRows: keypadForType[defaultKeypadType].rows,
|
|
13
|
+
numColumns: keypadForType[defaultKeypadType].columns,
|
|
14
|
+
numMaxVisibleRows: keypadForType[defaultKeypadType].maxVisibleRows,
|
|
15
|
+
numPages: keypadForType[defaultKeypadType].numPages,
|
|
16
|
+
},
|
|
17
|
+
buttonDimensions: {
|
|
18
|
+
widthPx: 48,
|
|
19
|
+
heightPx: 48,
|
|
20
|
+
},
|
|
21
|
+
pageDimensions: {
|
|
22
|
+
pageWidthPx: 0,
|
|
23
|
+
pageHeightPx: 0,
|
|
24
|
+
},
|
|
25
|
+
layoutMode: LayoutModes.FULLSCREEN,
|
|
26
|
+
paginationEnabled: false,
|
|
27
|
+
navigationPadEnabled: false,
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Compute the additional layout state based on the provided page and grid
|
|
32
|
+
* dimensions.
|
|
33
|
+
*/
|
|
34
|
+
const layoutParametersForDimensions = (
|
|
35
|
+
pageDimensions:
|
|
36
|
+
| {
|
|
37
|
+
pageHeightPx: never;
|
|
38
|
+
pageWidthPx: never;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
pageHeightPx: number;
|
|
42
|
+
pageWidthPx: number;
|
|
43
|
+
},
|
|
44
|
+
gridDimensions,
|
|
45
|
+
) => {
|
|
46
|
+
const {pageWidthPx, pageHeightPx} = pageDimensions;
|
|
47
|
+
|
|
48
|
+
// Determine the device type and orientation.
|
|
49
|
+
const deviceOrientation =
|
|
50
|
+
pageWidthPx > pageHeightPx
|
|
51
|
+
? DeviceOrientations.LANDSCAPE
|
|
52
|
+
: DeviceOrientations.PORTRAIT;
|
|
53
|
+
const deviceType =
|
|
54
|
+
Math.min(pageWidthPx, pageHeightPx) > tabletCutoffPx
|
|
55
|
+
? DeviceTypes.TABLET
|
|
56
|
+
: DeviceTypes.PHONE;
|
|
57
|
+
|
|
58
|
+
// Using that information, make some decisions (or assumptions)
|
|
59
|
+
// about the resulting layout.
|
|
60
|
+
const navigationPadEnabled = deviceType === DeviceTypes.TABLET;
|
|
61
|
+
const paginationEnabled =
|
|
62
|
+
deviceType === DeviceTypes.PHONE &&
|
|
63
|
+
deviceOrientation === DeviceOrientations.PORTRAIT;
|
|
64
|
+
|
|
65
|
+
const deviceInfo = {deviceOrientation, deviceType} as const;
|
|
66
|
+
const layoutOptions = {
|
|
67
|
+
navigationPadEnabled,
|
|
68
|
+
paginationEnabled,
|
|
69
|
+
// HACK(charlie): It's not great that we're making assumptions about
|
|
70
|
+
// the toolbar (which is rendered by webapp, and should always be
|
|
71
|
+
// visible and anchored to the bottom of the page for phone and
|
|
72
|
+
// tablet exercises). But this is primarily a heuristic (the goal is
|
|
73
|
+
// to preserve a 'good' amount of space between the top of the
|
|
74
|
+
// keypad and the top of the page) so we afford to have some margin
|
|
75
|
+
// of error.
|
|
76
|
+
toolbarEnabled: true,
|
|
77
|
+
} as const;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
...computeLayoutParameters(
|
|
81
|
+
gridDimensions,
|
|
82
|
+
pageDimensions,
|
|
83
|
+
deviceInfo,
|
|
84
|
+
layoutOptions,
|
|
85
|
+
),
|
|
86
|
+
// Pass along some of the layout information, so that other
|
|
87
|
+
// components in the heirarchy can adapt appropriately.
|
|
88
|
+
navigationPadEnabled,
|
|
89
|
+
paginationEnabled,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const layoutReducer = function (
|
|
94
|
+
state: LayoutState = initialLayoutState,
|
|
95
|
+
action: Action,
|
|
96
|
+
): LayoutState {
|
|
97
|
+
switch (action.type) {
|
|
98
|
+
case "ConfigureKeypad":
|
|
99
|
+
const {keypadType} = action.configuration;
|
|
100
|
+
const gridDimensions = {
|
|
101
|
+
numRows: keypadForType[keypadType].rows,
|
|
102
|
+
numColumns: keypadForType[keypadType].columns,
|
|
103
|
+
numMaxVisibleRows: keypadForType[keypadType].maxVisibleRows,
|
|
104
|
+
numPages: keypadForType[keypadType].numPages,
|
|
105
|
+
} as const;
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
...state,
|
|
109
|
+
...layoutParametersForDimensions(
|
|
110
|
+
state.pageDimensions,
|
|
111
|
+
gridDimensions,
|
|
112
|
+
),
|
|
113
|
+
gridDimensions,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
case "SetPageSize":
|
|
117
|
+
const {pageWidthPx, pageHeightPx} = action;
|
|
118
|
+
const pageDimensions = {pageWidthPx, pageHeightPx} as const;
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
...state,
|
|
122
|
+
...layoutParametersForDimensions(
|
|
123
|
+
pageDimensions,
|
|
124
|
+
state.gridDimensions,
|
|
125
|
+
),
|
|
126
|
+
pageDimensions,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
default:
|
|
130
|
+
return state;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export default layoutReducer;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import VelocityTracker from "../components/velocity-tracker";
|
|
2
|
+
import {KeyTypes} from "../consts";
|
|
3
|
+
import KeyConfigs from "../data/key-configs";
|
|
4
|
+
|
|
5
|
+
import {defaultKeypadType, keypadForType} from "./shared";
|
|
6
|
+
|
|
7
|
+
import type {Action} from "./actions";
|
|
8
|
+
import type {PagerState} from "./types";
|
|
9
|
+
|
|
10
|
+
// We default to the right-most page. This is done so-as to enforce a
|
|
11
|
+
// consistent orientation between the view pager layout and the flattened
|
|
12
|
+
// layout, where our default page appears on the far right.
|
|
13
|
+
const getDefaultPage = (numPages) => numPages - 1;
|
|
14
|
+
|
|
15
|
+
const initialPagerState = {
|
|
16
|
+
animateToPosition: false,
|
|
17
|
+
currentPage: getDefaultPage(keypadForType[defaultKeypadType].numPages),
|
|
18
|
+
// The cumulative differential in the horizontal direction for the
|
|
19
|
+
// current swipe.
|
|
20
|
+
dx: 0,
|
|
21
|
+
numPages: keypadForType[defaultKeypadType].numPages,
|
|
22
|
+
pageWidthPx: 0,
|
|
23
|
+
velocityTracker: new VelocityTracker(),
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
const pagerReducer = function (
|
|
27
|
+
state: PagerState = initialPagerState,
|
|
28
|
+
action: Action,
|
|
29
|
+
): PagerState {
|
|
30
|
+
switch (action.type) {
|
|
31
|
+
case "ConfigureKeypad":
|
|
32
|
+
const {keypadType} = action.configuration;
|
|
33
|
+
const {numPages} = keypadForType[keypadType];
|
|
34
|
+
return {
|
|
35
|
+
...state,
|
|
36
|
+
numPages,
|
|
37
|
+
animateToPosition: false,
|
|
38
|
+
currentPage: getDefaultPage(numPages),
|
|
39
|
+
dx: 0,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
case "SetPageSize":
|
|
43
|
+
return {
|
|
44
|
+
...state,
|
|
45
|
+
pageWidthPx: action.pageWidthPx,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
case "PressKey":
|
|
49
|
+
const keyConfig = KeyConfigs[action.key];
|
|
50
|
+
|
|
51
|
+
// Reset the keypad page if the user performs a math operation.
|
|
52
|
+
if (
|
|
53
|
+
keyConfig.type === KeyTypes.VALUE ||
|
|
54
|
+
keyConfig.type === KeyTypes.OPERATOR
|
|
55
|
+
) {
|
|
56
|
+
return {
|
|
57
|
+
...state,
|
|
58
|
+
animateToPosition: true,
|
|
59
|
+
// We start at the right-most page.
|
|
60
|
+
currentPage: getDefaultPage(state.numPages),
|
|
61
|
+
dx: 0,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return state;
|
|
65
|
+
|
|
66
|
+
case "OnSwipeChange":
|
|
67
|
+
state.velocityTracker.push(action.dx);
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
...state,
|
|
71
|
+
animateToPosition: false,
|
|
72
|
+
dx: action.dx,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
case "OnSwipeEnd":
|
|
76
|
+
const {pageWidthPx, velocityTracker} = state;
|
|
77
|
+
const {dx} = action;
|
|
78
|
+
const velocity = velocityTracker.getVelocity();
|
|
79
|
+
|
|
80
|
+
// NOTE(charlie): These will need refinement. The velocity comes
|
|
81
|
+
// from Framer.
|
|
82
|
+
const minFlingVelocity = 0.1;
|
|
83
|
+
const minFlingDistance = 10;
|
|
84
|
+
|
|
85
|
+
const shouldPageRight =
|
|
86
|
+
dx < -pageWidthPx / 2 ||
|
|
87
|
+
(velocity < -minFlingVelocity && dx < -minFlingDistance);
|
|
88
|
+
|
|
89
|
+
const shouldPageLeft =
|
|
90
|
+
dx > pageWidthPx / 2 ||
|
|
91
|
+
(velocity > minFlingVelocity && dx > minFlingDistance);
|
|
92
|
+
|
|
93
|
+
if (shouldPageRight) {
|
|
94
|
+
const nextPage = Math.min(
|
|
95
|
+
state.currentPage + 1,
|
|
96
|
+
state.numPages - 1,
|
|
97
|
+
);
|
|
98
|
+
return {
|
|
99
|
+
...state,
|
|
100
|
+
animateToPosition: true,
|
|
101
|
+
currentPage: nextPage,
|
|
102
|
+
dx: 0,
|
|
103
|
+
};
|
|
104
|
+
} else if (shouldPageLeft) {
|
|
105
|
+
const prevPage = Math.max(state.currentPage - 1, 0);
|
|
106
|
+
return {
|
|
107
|
+
...state,
|
|
108
|
+
animateToPosition: true,
|
|
109
|
+
currentPage: prevPage,
|
|
110
|
+
dx: 0,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
...state,
|
|
116
|
+
animateToPosition: true,
|
|
117
|
+
dx: 0,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
default:
|
|
121
|
+
return state;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export default pagerReducer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {expressionKeypadLayout} from "../components/expression-keypad";
|
|
2
|
+
import {fractionKeypadLayout} from "../components/fraction-keypad";
|
|
3
|
+
import {KeypadTypes} from "../consts";
|
|
4
|
+
|
|
5
|
+
const defaultKeypadType = KeypadTypes.EXPRESSION;
|
|
6
|
+
|
|
7
|
+
const keypadForType = {
|
|
8
|
+
[KeypadTypes.FRACTION]: fractionKeypadLayout,
|
|
9
|
+
[KeypadTypes.EXPRESSION]: expressionKeypadLayout,
|
|
10
|
+
} as const;
|
|
11
|
+
|
|
12
|
+
export {keypadForType, defaultKeypadType};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import GestureManager from "../components/gesture-manager";
|
|
2
|
+
import VelocityTracker from "../components/velocity-tracker";
|
|
3
|
+
import {LayoutModes} from "../consts";
|
|
4
|
+
|
|
5
|
+
import type {KeypadType} from "../consts";
|
|
6
|
+
import type {Key} from "../data/keys";
|
|
7
|
+
import type {Cursor, KeyHandler, Popover, Echo} from "../types";
|
|
8
|
+
|
|
9
|
+
// Interaction between keypad and input
|
|
10
|
+
export interface InputState {
|
|
11
|
+
// This is the callback to tell the input
|
|
12
|
+
// that a key was pressed. It returns information
|
|
13
|
+
// about where the cursor is
|
|
14
|
+
keyHandler: KeyHandler | null;
|
|
15
|
+
// Information about where the cursor is, which we use to
|
|
16
|
+
// conditionally render buttons to help navigate
|
|
17
|
+
// where the cursor should go next
|
|
18
|
+
cursor: Cursor | undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Managing high-level keypad state
|
|
22
|
+
export interface KeypadState {
|
|
23
|
+
// Additional symbols that get grouped in a
|
|
24
|
+
// ManyKeypadButton; for variables and
|
|
25
|
+
// special symbols (pi)
|
|
26
|
+
extraKeys: ReadonlyArray<string>;
|
|
27
|
+
// Keypad variations (Fraction vs Expression)
|
|
28
|
+
keypadType: KeypadType;
|
|
29
|
+
// Whether or not to show the keypad
|
|
30
|
+
active: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Pagination for keypad types with multiple pages
|
|
34
|
+
export interface PagerState {
|
|
35
|
+
animateToPosition: boolean;
|
|
36
|
+
// On keypad types with multiple pages
|
|
37
|
+
// which page we are on
|
|
38
|
+
currentPage: number;
|
|
39
|
+
dx: number;
|
|
40
|
+
numPages: number;
|
|
41
|
+
pageWidthPx: number;
|
|
42
|
+
velocityTracker: VelocityTracker;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface GestureState {
|
|
46
|
+
popover: Popover | null;
|
|
47
|
+
focus: Key | null;
|
|
48
|
+
gestureManager: GestureManager;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EchoState {
|
|
52
|
+
echoes: ReadonlyArray<Echo>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface LayoutState {
|
|
56
|
+
gridDimensions: {
|
|
57
|
+
numRows: number;
|
|
58
|
+
numColumns: number;
|
|
59
|
+
numMaxVisibleRows: number;
|
|
60
|
+
numPages: number;
|
|
61
|
+
};
|
|
62
|
+
buttonDimensions: {
|
|
63
|
+
widthPx: number;
|
|
64
|
+
heightPx: number;
|
|
65
|
+
};
|
|
66
|
+
pageDimensions: {
|
|
67
|
+
pageWidthPx: number;
|
|
68
|
+
pageHeightPx: number;
|
|
69
|
+
};
|
|
70
|
+
layoutMode: keyof typeof LayoutModes;
|
|
71
|
+
paginationEnabled: boolean;
|
|
72
|
+
navigationPadEnabled: boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface State {
|
|
76
|
+
input: InputState;
|
|
77
|
+
keypad: KeypadState;
|
|
78
|
+
pager: PagerState;
|
|
79
|
+
gestures: GestureState;
|
|
80
|
+
echoes: EchoState;
|
|
81
|
+
layout: LayoutState;
|
|
82
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BorderDirections,
|
|
3
|
+
EchoAnimationTypes,
|
|
4
|
+
KeyTypes,
|
|
5
|
+
IconTypes,
|
|
6
|
+
} from "./consts";
|
|
7
|
+
|
|
8
|
+
import type {CursorContext} from "./components/input/cursor-contexts";
|
|
9
|
+
import type {KeypadType} from "./consts";
|
|
10
|
+
import type {Key} from "./data/keys";
|
|
11
|
+
|
|
12
|
+
export type Border = Partial<Array<keyof typeof BorderDirections>>;
|
|
13
|
+
|
|
14
|
+
export type Bound = {
|
|
15
|
+
top: number;
|
|
16
|
+
right: number;
|
|
17
|
+
bottom: number;
|
|
18
|
+
left: number;
|
|
19
|
+
height: number;
|
|
20
|
+
width: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type Popover = {
|
|
24
|
+
parentId: Key;
|
|
25
|
+
bounds: Partial<Bound>;
|
|
26
|
+
childKeyIds: Array<Key>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type Echo = {
|
|
30
|
+
animationId: string;
|
|
31
|
+
animationType: keyof typeof EchoAnimationTypes;
|
|
32
|
+
borders: Border;
|
|
33
|
+
id: Key;
|
|
34
|
+
initialBounds: DOMRect;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type Icon = {
|
|
38
|
+
type: keyof typeof IconTypes;
|
|
39
|
+
data: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type KeyConfig = {
|
|
43
|
+
ariaLabel: string;
|
|
44
|
+
id: Key;
|
|
45
|
+
type: keyof typeof KeyTypes;
|
|
46
|
+
childKeyIds: Array<Key>;
|
|
47
|
+
icon: Icon;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type KeypadConfiguration = {
|
|
51
|
+
keypadType: KeypadType;
|
|
52
|
+
extraKeys?: ReadonlyArray<Key>;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type KeyHandler = (key: Key) => Cursor;
|
|
56
|
+
|
|
57
|
+
export type Cursor = {
|
|
58
|
+
context: CursorContext;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type KeypadLayout = {
|
|
62
|
+
rows: number;
|
|
63
|
+
columns: number;
|
|
64
|
+
numPages: number;
|
|
65
|
+
// Since we include a two-key popover in the top-right, when the popover
|
|
66
|
+
// is visible, the keypad will expand to fill the equivalent of five
|
|
67
|
+
// rows vertically.
|
|
68
|
+
maxVisibleRows: number;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
type ActiveNodesObjPopover = {
|
|
72
|
+
parentId: string;
|
|
73
|
+
childIds: ReadonlyArray<string>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type ActiveNodesObj = {
|
|
77
|
+
popover: ActiveNodesObjPopover | null;
|
|
78
|
+
focus: string | null;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type LayoutProps = {initialBounds: DOMRect; borders: Border};
|