@khanacademy/math-input 0.7.2 → 1.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 +10 -0
- package/dist/actions/index.d.ts +31 -0
- package/dist/actions/index.js.flow +40 -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/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 +53 -0
- package/dist/components/node-manager.js.flow +65 -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 +75 -0
- package/dist/components/popover-state-machine.js.flow +83 -0
- package/dist/components/provided-keypad.d.ts +8 -7
- package/dist/components/provided-keypad.js.flow +8 -7
- 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.js +938 -1059
- 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.d.ts +1 -1
- package/dist/index.js +988 -1089
- package/dist/index.js.flow +1 -4
- package/dist/index.js.map +1 -1
- package/dist/store/echo-reducer.d.ts +5 -0
- package/dist/store/echo-reducer.js.flow +14 -0
- package/dist/store/index.d.ts +46 -1
- package/dist/store/index.js.flow +64 -1
- package/dist/store/input-reducer.d.ts +7 -0
- package/dist/store/input-reducer.js.flow +16 -0
- package/dist/store/keypad-reducer.d.ts +9 -0
- package/dist/store/keypad-reducer.js.flow +18 -0
- package/dist/store/layout-reducer.d.ts +21 -0
- package/dist/store/layout-reducer.js.flow +30 -0
- package/dist/store/pager-reducer.d.ts +13 -0
- package/dist/store/pager-reducer.js.flow +22 -0
- package/dist/store/shared.d.ts +6 -0
- package/dist/store/shared.js.flow +13 -0
- package/dist/store/types.d.ts +57 -0
- package/dist/store/types.js.flow +63 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.js.flow +61 -0
- package/package.json +1 -1
- package/src/actions/{index.js → index.ts} +5 -5
- 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.tsx} +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 +1 -1
- 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} +41 -23
- package/src/components/{keypad.js → keypad.tsx} +31 -23
- 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} +21 -2
- package/src/components/prop-types.js +1 -67
- package/src/components/provided-keypad.tsx +14 -12
- 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/store/echo-reducer.ts +58 -0
- package/src/store/index.ts +14 -425
- package/src/store/input-reducer.ts +55 -0
- package/src/store/keypad-reducer.ts +62 -0
- package/src/store/layout-reducer.ts +133 -0
- package/src/store/pager-reducer.ts +141 -0
- package/src/store/shared.ts +12 -0
- package/src/store/types.ts +65 -0
- package/src/types.ts +69 -0
- package/tsconfig.tsbuildinfo +1 -1
- 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,133 @@
|
|
|
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 {LayoutState} from "./types";
|
|
8
|
+
|
|
9
|
+
const initialLayoutState = {
|
|
10
|
+
gridDimensions: {
|
|
11
|
+
numRows: keypadForType[defaultKeypadType].rows,
|
|
12
|
+
numColumns: keypadForType[defaultKeypadType].columns,
|
|
13
|
+
numMaxVisibleRows: keypadForType[defaultKeypadType].maxVisibleRows,
|
|
14
|
+
numPages: keypadForType[defaultKeypadType].numPages,
|
|
15
|
+
},
|
|
16
|
+
buttonDimensions: {
|
|
17
|
+
widthPx: 48,
|
|
18
|
+
heightPx: 48,
|
|
19
|
+
},
|
|
20
|
+
pageDimensions: {
|
|
21
|
+
pageWidthPx: 0,
|
|
22
|
+
pageHeightPx: 0,
|
|
23
|
+
},
|
|
24
|
+
layoutMode: LayoutModes.FULLSCREEN,
|
|
25
|
+
paginationEnabled: false,
|
|
26
|
+
navigationPadEnabled: false,
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compute the additional layout state based on the provided page and grid
|
|
31
|
+
* dimensions.
|
|
32
|
+
*/
|
|
33
|
+
const layoutParametersForDimensions = (
|
|
34
|
+
pageDimensions:
|
|
35
|
+
| {
|
|
36
|
+
pageHeightPx: never;
|
|
37
|
+
pageWidthPx: never;
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
pageHeightPx: number;
|
|
41
|
+
pageWidthPx: number;
|
|
42
|
+
},
|
|
43
|
+
gridDimensions,
|
|
44
|
+
) => {
|
|
45
|
+
const {pageWidthPx, pageHeightPx} = pageDimensions;
|
|
46
|
+
|
|
47
|
+
// Determine the device type and orientation.
|
|
48
|
+
const deviceOrientation =
|
|
49
|
+
pageWidthPx > pageHeightPx
|
|
50
|
+
? DeviceOrientations.LANDSCAPE
|
|
51
|
+
: DeviceOrientations.PORTRAIT;
|
|
52
|
+
const deviceType =
|
|
53
|
+
Math.min(pageWidthPx, pageHeightPx) > tabletCutoffPx
|
|
54
|
+
? DeviceTypes.TABLET
|
|
55
|
+
: DeviceTypes.PHONE;
|
|
56
|
+
|
|
57
|
+
// Using that information, make some decisions (or assumptions)
|
|
58
|
+
// about the resulting layout.
|
|
59
|
+
const navigationPadEnabled = deviceType === DeviceTypes.TABLET;
|
|
60
|
+
const paginationEnabled =
|
|
61
|
+
deviceType === DeviceTypes.PHONE &&
|
|
62
|
+
deviceOrientation === DeviceOrientations.PORTRAIT;
|
|
63
|
+
|
|
64
|
+
const deviceInfo = {deviceOrientation, deviceType} as const;
|
|
65
|
+
const layoutOptions = {
|
|
66
|
+
navigationPadEnabled,
|
|
67
|
+
paginationEnabled,
|
|
68
|
+
// HACK(charlie): It's not great that we're making assumptions about
|
|
69
|
+
// the toolbar (which is rendered by webapp, and should always be
|
|
70
|
+
// visible and anchored to the bottom of the page for phone and
|
|
71
|
+
// tablet exercises). But this is primarily a heuristic (the goal is
|
|
72
|
+
// to preserve a 'good' amount of space between the top of the
|
|
73
|
+
// keypad and the top of the page) so we afford to have some margin
|
|
74
|
+
// of error.
|
|
75
|
+
toolbarEnabled: true,
|
|
76
|
+
} as const;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
...computeLayoutParameters(
|
|
80
|
+
gridDimensions,
|
|
81
|
+
pageDimensions,
|
|
82
|
+
deviceInfo,
|
|
83
|
+
layoutOptions,
|
|
84
|
+
),
|
|
85
|
+
// Pass along some of the layout information, so that other
|
|
86
|
+
// components in the heirarchy can adapt appropriately.
|
|
87
|
+
navigationPadEnabled,
|
|
88
|
+
paginationEnabled,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const layoutReducer = function (
|
|
93
|
+
state = initialLayoutState,
|
|
94
|
+
action: any,
|
|
95
|
+
): LayoutState {
|
|
96
|
+
switch (action.type) {
|
|
97
|
+
case "ConfigureKeypad":
|
|
98
|
+
const {keypadType} = action.configuration;
|
|
99
|
+
const gridDimensions = {
|
|
100
|
+
numRows: keypadForType[keypadType].rows,
|
|
101
|
+
numColumns: keypadForType[keypadType].columns,
|
|
102
|
+
numMaxVisibleRows: keypadForType[keypadType].maxVisibleRows,
|
|
103
|
+
numPages: keypadForType[keypadType].numPages,
|
|
104
|
+
} as const;
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
...state,
|
|
108
|
+
...layoutParametersForDimensions(
|
|
109
|
+
state.pageDimensions,
|
|
110
|
+
gridDimensions,
|
|
111
|
+
),
|
|
112
|
+
gridDimensions,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
case "SetPageSize":
|
|
116
|
+
const {pageWidthPx, pageHeightPx} = action;
|
|
117
|
+
const pageDimensions = {pageWidthPx, pageHeightPx} as const;
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
...state,
|
|
121
|
+
...layoutParametersForDimensions(
|
|
122
|
+
pageDimensions,
|
|
123
|
+
state.gridDimensions,
|
|
124
|
+
),
|
|
125
|
+
pageDimensions,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
default:
|
|
129
|
+
return state;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export default layoutReducer;
|
|
@@ -0,0 +1,141 @@
|
|
|
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 {PagerState} from "./types";
|
|
8
|
+
|
|
9
|
+
// We default to the right-most page. This is done so-as to enforce a
|
|
10
|
+
// consistent orientation between the view pager layout and the flattened
|
|
11
|
+
// layout, where our default page appears on the far right.
|
|
12
|
+
const getDefaultPage = (numPages) => numPages - 1;
|
|
13
|
+
|
|
14
|
+
const initialPagerState = {
|
|
15
|
+
animateToPosition: false,
|
|
16
|
+
currentPage: getDefaultPage(keypadForType[defaultKeypadType].numPages),
|
|
17
|
+
// The cumulative differential in the horizontal direction for the
|
|
18
|
+
// current swipe.
|
|
19
|
+
dx: 0,
|
|
20
|
+
numPages: keypadForType[defaultKeypadType].numPages,
|
|
21
|
+
pageWidthPx: 0,
|
|
22
|
+
velocityTracker: new VelocityTracker(),
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
const pagerReducer = function (
|
|
26
|
+
state = initialPagerState,
|
|
27
|
+
action: {
|
|
28
|
+
type: string;
|
|
29
|
+
},
|
|
30
|
+
): PagerState {
|
|
31
|
+
switch (action.type) {
|
|
32
|
+
case "ConfigureKeypad":
|
|
33
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'configuration' does not exist on type '{ type: string; }'.
|
|
34
|
+
const {keypadType} = action.configuration;
|
|
35
|
+
const {numPages} = keypadForType[keypadType];
|
|
36
|
+
return {
|
|
37
|
+
...state,
|
|
38
|
+
numPages,
|
|
39
|
+
animateToPosition: false,
|
|
40
|
+
currentPage: getDefaultPage(numPages),
|
|
41
|
+
dx: 0,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
case "SetPageSize":
|
|
45
|
+
return {
|
|
46
|
+
...state,
|
|
47
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'pageWidthPx' does not exist on type '{ type: string; }'.
|
|
48
|
+
pageWidthPx: action.pageWidthPx,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
case "PressKey":
|
|
52
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'key' does not exist on type '{ type: string; }'.
|
|
53
|
+
const keyConfig = KeyConfigs[action.key];
|
|
54
|
+
|
|
55
|
+
// Reset the keypad page if the user performs a math operation.
|
|
56
|
+
if (
|
|
57
|
+
keyConfig.type === KeyTypes.VALUE ||
|
|
58
|
+
keyConfig.type === KeyTypes.OPERATOR
|
|
59
|
+
) {
|
|
60
|
+
return pagerReducer(state, {type: "ResetKeypadPage"});
|
|
61
|
+
}
|
|
62
|
+
return state;
|
|
63
|
+
|
|
64
|
+
case "ResetKeypadPage":
|
|
65
|
+
return {
|
|
66
|
+
...state,
|
|
67
|
+
animateToPosition: true,
|
|
68
|
+
// We start at the right-most page.
|
|
69
|
+
currentPage: getDefaultPage(state.numPages),
|
|
70
|
+
dx: 0,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
case "PageKeypadRight":
|
|
74
|
+
const nextPage = Math.min(
|
|
75
|
+
state.currentPage + 1,
|
|
76
|
+
state.numPages - 1,
|
|
77
|
+
);
|
|
78
|
+
return {
|
|
79
|
+
...state,
|
|
80
|
+
animateToPosition: true,
|
|
81
|
+
currentPage: nextPage,
|
|
82
|
+
dx: 0,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
case "PageKeypadLeft":
|
|
86
|
+
const prevPage = Math.max(state.currentPage - 1, 0);
|
|
87
|
+
return {
|
|
88
|
+
...state,
|
|
89
|
+
animateToPosition: true,
|
|
90
|
+
currentPage: prevPage,
|
|
91
|
+
dx: 0,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
case "OnSwipeChange":
|
|
95
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'dx' does not exist on type '{ type: string; }'.
|
|
96
|
+
state.velocityTracker.push(action.dx);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
...state,
|
|
100
|
+
animateToPosition: false,
|
|
101
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'dx' does not exist on type '{ type: string; }'.
|
|
102
|
+
dx: action.dx,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
case "OnSwipeEnd":
|
|
106
|
+
const {pageWidthPx, velocityTracker} = state;
|
|
107
|
+
// @ts-expect-error [FEI-5003] - TS2339 - Property 'dx' does not exist on type '{ type: string; }'.
|
|
108
|
+
const {dx} = action;
|
|
109
|
+
const velocity = velocityTracker.getVelocity();
|
|
110
|
+
|
|
111
|
+
// NOTE(charlie): These will need refinement. The velocity comes
|
|
112
|
+
// from Framer.
|
|
113
|
+
const minFlingVelocity = 0.1;
|
|
114
|
+
const minFlingDistance = 10;
|
|
115
|
+
|
|
116
|
+
const shouldPageRight =
|
|
117
|
+
dx < -pageWidthPx / 2 ||
|
|
118
|
+
(velocity < -minFlingVelocity && dx < -minFlingDistance);
|
|
119
|
+
|
|
120
|
+
const shouldPageLeft =
|
|
121
|
+
dx > pageWidthPx / 2 ||
|
|
122
|
+
(velocity > minFlingVelocity && dx > minFlingDistance);
|
|
123
|
+
|
|
124
|
+
if (shouldPageRight) {
|
|
125
|
+
return pagerReducer(state, {type: "PageKeypadRight"});
|
|
126
|
+
} else if (shouldPageLeft) {
|
|
127
|
+
return pagerReducer(state, {type: "PageKeypadLeft"});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...state,
|
|
132
|
+
animateToPosition: true,
|
|
133
|
+
dx: 0,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
default:
|
|
137
|
+
return state;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
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,65 @@
|
|
|
1
|
+
import GestureManager from "../components/gesture-manager";
|
|
2
|
+
import VelocityTracker from "../components/velocity-tracker";
|
|
3
|
+
import {LayoutModes} from "../consts";
|
|
4
|
+
|
|
5
|
+
import type {Key} from "../data/keys";
|
|
6
|
+
import type {Cursor, KeyHandler, Popover, Echo} from "../types";
|
|
7
|
+
|
|
8
|
+
export interface InputState {
|
|
9
|
+
keyHandler: KeyHandler | null;
|
|
10
|
+
cursor: Cursor | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface KeypadState {
|
|
14
|
+
extraKeys: ReadonlyArray<string>;
|
|
15
|
+
keypadType: any;
|
|
16
|
+
active: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PagerState {
|
|
20
|
+
animateToPosition: boolean;
|
|
21
|
+
currentPage: number;
|
|
22
|
+
dx: number;
|
|
23
|
+
numPages: number;
|
|
24
|
+
pageWidthPx: number;
|
|
25
|
+
velocityTracker: VelocityTracker;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface GestureState {
|
|
29
|
+
popover: Popover | null;
|
|
30
|
+
focus: Key | null;
|
|
31
|
+
gestureManager: GestureManager;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface EchoState {
|
|
35
|
+
echoes: ReadonlyArray<Echo>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface LayoutState {
|
|
39
|
+
gridDimensions: {
|
|
40
|
+
numRows: number;
|
|
41
|
+
numColumns: number;
|
|
42
|
+
numMaxVisibleRows: number;
|
|
43
|
+
numPages: number;
|
|
44
|
+
};
|
|
45
|
+
buttonDimensions: {
|
|
46
|
+
widthPx: number;
|
|
47
|
+
heightPx: number;
|
|
48
|
+
};
|
|
49
|
+
pageDimensions: {
|
|
50
|
+
pageWidthPx: number;
|
|
51
|
+
pageHeightPx: number;
|
|
52
|
+
};
|
|
53
|
+
layoutMode: keyof typeof LayoutModes;
|
|
54
|
+
paginationEnabled: boolean;
|
|
55
|
+
navigationPadEnabled: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface State {
|
|
59
|
+
input: InputState;
|
|
60
|
+
keypad: KeypadState;
|
|
61
|
+
pager: PagerState;
|
|
62
|
+
gestures: GestureState;
|
|
63
|
+
echoes: EchoState;
|
|
64
|
+
layout: LayoutState;
|
|
65
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
};
|