ferns-ui 0.22.4 → 0.23.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/dist/Button.d.ts +2 -1
- package/dist/Button.js +2 -2
- package/dist/Button.js.map +1 -1
- package/dist/Common.d.ts +1 -14
- package/dist/Common.js.map +1 -1
- package/dist/FernsProvider.d.ts +4 -0
- package/dist/FernsProvider.js +7 -0
- package/dist/FernsProvider.js.map +1 -0
- package/dist/IconButton.d.ts +21 -3
- package/dist/IconButton.js +44 -31
- package/dist/IconButton.js.map +1 -1
- package/dist/InfoTooltipButton.d.ts +8 -0
- package/dist/InfoTooltipButton.js +6 -0
- package/dist/InfoTooltipButton.js.map +1 -0
- package/dist/Modal.js +17 -18
- package/dist/Modal.js.map +1 -1
- package/dist/SelectList.js +26 -4
- package/dist/SelectList.js.map +1 -1
- package/dist/TapToEdit.js +17 -0
- package/dist/TapToEdit.js.map +1 -1
- package/dist/Toast.d.ts +10 -0
- package/dist/Toast.js +40 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Tooltip.d.ts +9 -0
- package/dist/Tooltip.js +170 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/src/Button.tsx +3 -1
- package/src/Common.ts +2 -15
- package/src/FernsProvider.tsx +20 -0
- package/src/IconButton.tsx +131 -79
- package/src/InfoTooltipButton.tsx +23 -0
- package/src/Modal.tsx +34 -36
- package/src/SelectList.tsx +25 -3
- package/src/TapToEdit.tsx +21 -0
- package/src/Toast.tsx +87 -0
- package/src/Tooltip.tsx +259 -0
- package/src/index.tsx +4 -0
- package/README.md +0 -22
package/dist/Tooltip.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Dimensions, Platform, Pressable, } from "react-native";
|
|
4
|
+
import { Portal } from "react-native-portalize";
|
|
5
|
+
import { Text } from "./Text";
|
|
6
|
+
import { Unifier } from "./Unifier";
|
|
7
|
+
const TOOLTIP_OFFSET = 8;
|
|
8
|
+
// How many pixels to leave between the tooltip and the edge of the screen
|
|
9
|
+
const TOOLTIP_OVERFLOW_PADDING = 20;
|
|
10
|
+
const overflowLeft = (x) => {
|
|
11
|
+
return x < TOOLTIP_OVERFLOW_PADDING;
|
|
12
|
+
};
|
|
13
|
+
const overflowRight = (x) => {
|
|
14
|
+
const { width: layoutWidth } = Dimensions.get("window");
|
|
15
|
+
return x + TOOLTIP_OVERFLOW_PADDING > layoutWidth;
|
|
16
|
+
};
|
|
17
|
+
const getTooltipPosition = ({ children, tooltip, measured, idealDirection, }) => {
|
|
18
|
+
if (!measured) {
|
|
19
|
+
console.debug("No measurements for child yet, cannot show tooltip.");
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const { pageY: childrenY, height: childrenHeight, pageX: childrenX, width: childrenWidth, } = children;
|
|
23
|
+
const { width: tooltipWidth, height: tooltipHeight } = tooltip;
|
|
24
|
+
const horizontalCenter = childrenX + childrenWidth / 2;
|
|
25
|
+
const right = childrenX + childrenWidth + TOOLTIP_OFFSET;
|
|
26
|
+
const left = childrenX - tooltipWidth - TOOLTIP_OFFSET;
|
|
27
|
+
const top = childrenY - tooltipHeight - TOOLTIP_OFFSET;
|
|
28
|
+
const bottom = childrenY + childrenHeight + TOOLTIP_OFFSET;
|
|
29
|
+
const verticalCenter = top + childrenHeight + TOOLTIP_OFFSET;
|
|
30
|
+
// Top is overflowed if it would go off either side or the top of the screen.
|
|
31
|
+
const overflowTop = top < TOOLTIP_OVERFLOW_PADDING;
|
|
32
|
+
// Bottom is overflowed if it would go off either side or the bottom of the screen.
|
|
33
|
+
const overflowBottom = bottom + tooltipHeight + TOOLTIP_OVERFLOW_PADDING > Dimensions.get("window").height;
|
|
34
|
+
// If it would overflow to the right, try to put it above, if not, put it on the left.
|
|
35
|
+
// If it would overflow to the left, try to put it above, if not, put it to the right.
|
|
36
|
+
// Happy path:
|
|
37
|
+
if (idealDirection === "left" && !overflowLeft(left)) {
|
|
38
|
+
return { left, top: verticalCenter };
|
|
39
|
+
}
|
|
40
|
+
else if (idealDirection === "right" && !overflowRight(right + tooltipWidth)) {
|
|
41
|
+
return { left: right, top: verticalCenter };
|
|
42
|
+
}
|
|
43
|
+
else if (idealDirection === "bottom" &&
|
|
44
|
+
!overflowBottom &&
|
|
45
|
+
!overflowLeft(horizontalCenter - tooltipWidth) &&
|
|
46
|
+
!overflowRight(horizontalCenter + tooltipWidth)) {
|
|
47
|
+
return { left: horizontalCenter - tooltipWidth / 2, top: bottom };
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// At this point, we're either trying to place it above or below, and force it into the viewport.
|
|
51
|
+
let y = top;
|
|
52
|
+
if ((idealDirection === "bottom" && !overflowBottom) || overflowTop) {
|
|
53
|
+
y = bottom;
|
|
54
|
+
}
|
|
55
|
+
// If it fits in the viewport, center it above the child.
|
|
56
|
+
if (!overflowLeft(horizontalCenter - tooltipWidth) &&
|
|
57
|
+
!overflowRight(horizontalCenter + tooltipWidth)) {
|
|
58
|
+
return { left: horizontalCenter - tooltipWidth / 2, top: y };
|
|
59
|
+
}
|
|
60
|
+
// Failing that, if it fits on the left, put it there, otherwise to the right. We know it's smaller than the
|
|
61
|
+
// viewport.
|
|
62
|
+
else if (overflowLeft(horizontalCenter - tooltipWidth)) {
|
|
63
|
+
return { left: TOOLTIP_OVERFLOW_PADDING, top: y };
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return {
|
|
67
|
+
left: Dimensions.get("window").width - TOOLTIP_OVERFLOW_PADDING - tooltipWidth,
|
|
68
|
+
top: y,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
// eslint-disable-next-line react/display-name
|
|
74
|
+
export const Tooltip = forwardRef((props, _ref) => {
|
|
75
|
+
const { text, children, bgColor, idealDirection } = props;
|
|
76
|
+
const hoverDelay = 500;
|
|
77
|
+
const hoverEndDelay = 1500;
|
|
78
|
+
const [visible, setVisible] = React.useState(false);
|
|
79
|
+
const [measurement, setMeasurement] = React.useState({
|
|
80
|
+
children: {},
|
|
81
|
+
tooltip: {},
|
|
82
|
+
measured: false,
|
|
83
|
+
});
|
|
84
|
+
const showTooltipTimer = React.useRef();
|
|
85
|
+
const hideTooltipTimer = React.useRef();
|
|
86
|
+
const childrenWrapperRef = React.useRef();
|
|
87
|
+
const touched = React.useRef(false);
|
|
88
|
+
const isWeb = Platform.OS === "web";
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
return () => {
|
|
91
|
+
if (showTooltipTimer.current) {
|
|
92
|
+
clearTimeout(showTooltipTimer.current);
|
|
93
|
+
}
|
|
94
|
+
if (hideTooltipTimer.current) {
|
|
95
|
+
clearTimeout(hideTooltipTimer.current);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
const handleOnLayout = ({ nativeEvent: { layout } }) => {
|
|
100
|
+
var _a;
|
|
101
|
+
(_a = childrenWrapperRef === null || childrenWrapperRef === void 0 ? void 0 : childrenWrapperRef.current) === null || _a === void 0 ? void 0 : _a.measure((_x, _y, width, height, pageX, pageY) => {
|
|
102
|
+
setMeasurement({
|
|
103
|
+
children: { pageX, pageY, height, width },
|
|
104
|
+
tooltip: Object.assign({}, layout),
|
|
105
|
+
measured: true,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const handleTouchStart = () => {
|
|
110
|
+
if (hideTooltipTimer.current) {
|
|
111
|
+
clearTimeout(hideTooltipTimer.current);
|
|
112
|
+
}
|
|
113
|
+
showTooltipTimer.current = setTimeout(() => {
|
|
114
|
+
touched.current = true;
|
|
115
|
+
setVisible(true);
|
|
116
|
+
}, 100);
|
|
117
|
+
};
|
|
118
|
+
const handleHoverIn = () => {
|
|
119
|
+
if (hideTooltipTimer.current) {
|
|
120
|
+
clearTimeout(hideTooltipTimer.current);
|
|
121
|
+
}
|
|
122
|
+
showTooltipTimer.current = setTimeout(() => {
|
|
123
|
+
touched.current = true;
|
|
124
|
+
setVisible(true);
|
|
125
|
+
}, hoverDelay);
|
|
126
|
+
};
|
|
127
|
+
const handleHoverOut = () => {
|
|
128
|
+
touched.current = false;
|
|
129
|
+
if (showTooltipTimer.current) {
|
|
130
|
+
clearTimeout(showTooltipTimer.current);
|
|
131
|
+
}
|
|
132
|
+
hideTooltipTimer.current = setTimeout(() => {
|
|
133
|
+
setVisible(false);
|
|
134
|
+
setMeasurement({ children: {}, tooltip: {}, measured: false });
|
|
135
|
+
}, hoverEndDelay);
|
|
136
|
+
};
|
|
137
|
+
const mobilePressProps = {
|
|
138
|
+
onPress: React.useCallback(() => {
|
|
139
|
+
var _a, _b;
|
|
140
|
+
if (touched.current) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
return (_b = (_a = children.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
145
|
+
}
|
|
146
|
+
}, [children.props]),
|
|
147
|
+
};
|
|
148
|
+
const webPressProps = {
|
|
149
|
+
onHoverIn: () => {
|
|
150
|
+
var _a, _b;
|
|
151
|
+
handleHoverIn();
|
|
152
|
+
(_b = (_a = children.props).onHoverIn) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
153
|
+
},
|
|
154
|
+
onHoverOut: () => {
|
|
155
|
+
var _a, _b;
|
|
156
|
+
handleHoverOut();
|
|
157
|
+
(_b = (_a = children.props).onHoverOut) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
return (React.createElement(React.Fragment, null,
|
|
161
|
+
visible && (React.createElement(Portal, null,
|
|
162
|
+
React.createElement(Pressable, { style: Object.assign(Object.assign({ alignSelf: "flex-start", justifyContent: "center", paddingHorizontal: 16, backgroundColor: Unifier.theme[bgColor !== null && bgColor !== void 0 ? bgColor : "darkGray"], borderRadius: 16, paddingVertical: 8, display: "flex", flexShrink: 1, maxWidth: Math.max(Dimensions.get("window").width - 32, 300) }, getTooltipPosition(Object.assign(Object.assign({}, measurement), { idealDirection }))), (measurement.measured ? { opacity: 1 } : { opacity: 0 })), testID: "tooltip-container", onLayout: handleOnLayout, onPress: () => {
|
|
163
|
+
setVisible(false);
|
|
164
|
+
} },
|
|
165
|
+
React.createElement(Text, { color: "white" }, text)))),
|
|
166
|
+
React.createElement(Pressable, Object.assign({ onTouchStart: handleTouchStart }, (isWeb ? webPressProps : mobilePressProps)), React.cloneElement(children, {
|
|
167
|
+
ref: childrenWrapperRef,
|
|
168
|
+
}))));
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=Tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../src/Tooltip.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from "./CheckBox";
|
|
|
13
13
|
export * from "./DateTimeActionSheet";
|
|
14
14
|
export * from "./ErrorBoundary";
|
|
15
15
|
export * from "./ErrorPage";
|
|
16
|
+
export * from "./FernsProvider";
|
|
16
17
|
export * from "./FlatList";
|
|
17
18
|
export * from "./Field";
|
|
18
19
|
export * from "./Form";
|
|
@@ -22,6 +23,7 @@ export * from "./Icon";
|
|
|
22
23
|
export * from "./IconButton";
|
|
23
24
|
export * from "./Image";
|
|
24
25
|
export * from "./ImageBackground";
|
|
26
|
+
export * from "./InfoTooltipButton";
|
|
25
27
|
export * from "./Link";
|
|
26
28
|
export * from "./Mask";
|
|
27
29
|
export * from "./Meta";
|
|
@@ -38,6 +40,8 @@ export * from "./TapToEdit";
|
|
|
38
40
|
export * from "./Text";
|
|
39
41
|
export * from "./TextArea";
|
|
40
42
|
export * from "./TextField";
|
|
43
|
+
export * from "./Tooltip";
|
|
44
|
+
export * from "./Toast";
|
|
41
45
|
export * from "./UnifiedScreens";
|
|
42
46
|
export * from "./Unifier";
|
|
43
47
|
export * from "./WithLabel";
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from "./CheckBox";
|
|
|
13
13
|
export * from "./DateTimeActionSheet";
|
|
14
14
|
export * from "./ErrorBoundary";
|
|
15
15
|
export * from "./ErrorPage";
|
|
16
|
+
export * from "./FernsProvider";
|
|
16
17
|
export * from "./FlatList";
|
|
17
18
|
export * from "./Field";
|
|
18
19
|
export * from "./Form";
|
|
@@ -22,6 +23,7 @@ export * from "./Icon";
|
|
|
22
23
|
export * from "./IconButton";
|
|
23
24
|
export * from "./Image";
|
|
24
25
|
export * from "./ImageBackground";
|
|
26
|
+
export * from "./InfoTooltipButton";
|
|
25
27
|
// export * from "./Layout";
|
|
26
28
|
// export * from "./Drawer";
|
|
27
29
|
export * from "./Link";
|
|
@@ -40,6 +42,8 @@ export * from "./TapToEdit";
|
|
|
40
42
|
export * from "./Text";
|
|
41
43
|
export * from "./TextArea";
|
|
42
44
|
export * from "./TextField";
|
|
45
|
+
export * from "./Tooltip";
|
|
46
|
+
export * from "./Toast";
|
|
43
47
|
export * from "./UnifiedScreens";
|
|
44
48
|
export * from "./Unifier";
|
|
45
49
|
export * from "./WithLabel";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,4BAA4B;AAC5B,4BAA4B;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AAExB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,2BAA2B;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,4BAA4B;AAC5B,4BAA4B;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AAExB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,2BAA2B;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ferns-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"scripts": {
|
|
@@ -167,6 +167,7 @@
|
|
|
167
167
|
"react-native-picker-select": "^8.0.0",
|
|
168
168
|
"react-native-portalize": "^1.0.7",
|
|
169
169
|
"react-native-svg": "^13.0.0",
|
|
170
|
+
"react-native-toast-notifications": "^3.3.1",
|
|
170
171
|
"react-router": "^6.3.0",
|
|
171
172
|
"react-router-dom": "^6.3.0",
|
|
172
173
|
"react-time-picker": "^5.0.0",
|
|
@@ -198,6 +199,7 @@
|
|
|
198
199
|
"react-native-picker-select": "^8.0.0",
|
|
199
200
|
"react-native-portalize": "^1.0.7",
|
|
200
201
|
"react-native-svg": "^13.0.0",
|
|
202
|
+
"react-native-toast-notifications": "^3.3.1",
|
|
201
203
|
"react-router": "^6.3.0",
|
|
202
204
|
"react-router-dom": "^6.3.0",
|
|
203
205
|
"react-time-picker": "^5.0.0"
|
package/src/Button.tsx
CHANGED
|
@@ -29,6 +29,7 @@ export interface ButtonProps {
|
|
|
29
29
|
withConfirmation?: boolean;
|
|
30
30
|
confirmationText?: string;
|
|
31
31
|
confirmationHeading?: string;
|
|
32
|
+
shape?: "rounded" | "pill";
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const buttonTextColor: {[buttonColor: string]: "white" | "darkGray"} = {
|
|
@@ -67,6 +68,7 @@ export function Button({
|
|
|
67
68
|
withConfirmation = false,
|
|
68
69
|
confirmationText = "Are you sure you want to continue?",
|
|
69
70
|
confirmationHeading = "Confirm",
|
|
71
|
+
shape = "rounded",
|
|
70
72
|
}: ButtonProps) {
|
|
71
73
|
const [loading, setLoading] = useState(propsLoading);
|
|
72
74
|
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
@@ -136,7 +138,7 @@ export function Button({
|
|
|
136
138
|
// flexGrow: inline ? 0 : 1,
|
|
137
139
|
alignItems: "center",
|
|
138
140
|
justifyContent: "center",
|
|
139
|
-
borderRadius: 5,
|
|
141
|
+
borderRadius: shape === "pill" ? 999 : 5,
|
|
140
142
|
borderColor: getBorderColor(color),
|
|
141
143
|
borderWidth: type === "outline" ? 2 : 0,
|
|
142
144
|
opacity: disabled ? 0.4 : 1,
|
package/src/Common.ts
CHANGED
|
@@ -2004,25 +2004,12 @@ export interface IconProps {
|
|
|
2004
2004
|
containerStyle?: any;
|
|
2005
2005
|
}
|
|
2006
2006
|
|
|
2007
|
-
export interface IconButtonProps {
|
|
2008
|
-
prefix?: IconPrefix;
|
|
2009
|
-
icon: IconName;
|
|
2010
|
-
accessibilityLabel: string;
|
|
2011
|
-
iconColor: "darkGray" | ButtonColor | ThemeColor | Color;
|
|
2012
|
-
onClick: () => void;
|
|
2013
|
-
size?: IconSize;
|
|
2014
|
-
bgColor?: "transparent" | "transparentDarkGray" | "gray" | "lightGray" | "white"; // default transparent
|
|
2015
|
-
disabled?: boolean;
|
|
2016
|
-
selected?: boolean;
|
|
2017
|
-
withConfirmation?: boolean;
|
|
2018
|
-
confirmationText?: string;
|
|
2019
|
-
confirmationHeading?: string;
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
2007
|
export interface NavigatorProps {
|
|
2023
2008
|
config?: any;
|
|
2024
2009
|
}
|
|
2025
2010
|
|
|
2011
|
+
export type TooltipDirection = "top" | "bottom" | "left" | "right";
|
|
2012
|
+
|
|
2026
2013
|
export interface PillProps {
|
|
2027
2014
|
text: string;
|
|
2028
2015
|
color: AllColors;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {ToastProvider} from "react-native-toast-notifications";
|
|
3
|
+
|
|
4
|
+
import {Toast} from "./Toast";
|
|
5
|
+
|
|
6
|
+
export function FernsProvider({children}: {children: React.ReactNode}): React.ReactElement {
|
|
7
|
+
return (
|
|
8
|
+
<ToastProvider
|
|
9
|
+
animationDuration={250}
|
|
10
|
+
animationType="slide-in"
|
|
11
|
+
duration={50000}
|
|
12
|
+
offset={50}
|
|
13
|
+
placement="bottom"
|
|
14
|
+
renderToast={(toastOptions) => <Toast {...(toastOptions as any)} />}
|
|
15
|
+
swipeEnabled
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</ToastProvider>
|
|
19
|
+
);
|
|
20
|
+
}
|
package/src/IconButton.tsx
CHANGED
|
@@ -1,89 +1,141 @@
|
|
|
1
|
-
import React, {useState} from "react";
|
|
2
|
-
import {TouchableOpacity} from "react-native";
|
|
1
|
+
import React, {forwardRef, useState} from "react";
|
|
2
|
+
import {Platform, TouchableOpacity, View} from "react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ButtonColor,
|
|
6
|
+
Color,
|
|
7
|
+
IconName,
|
|
8
|
+
IconPrefix,
|
|
9
|
+
IconSize,
|
|
10
|
+
iconSizeToNumber,
|
|
11
|
+
ThemeColor,
|
|
12
|
+
TooltipDirection,
|
|
13
|
+
} from "./Common";
|
|
5
14
|
import {Icon} from "./Icon";
|
|
6
15
|
import {Modal} from "./Modal";
|
|
7
16
|
import {Text} from "./Text";
|
|
17
|
+
import {Tooltip} from "./Tooltip";
|
|
8
18
|
import {Unifier} from "./Unifier";
|
|
9
19
|
|
|
10
|
-
export
|
|
11
|
-
prefix
|
|
12
|
-
icon
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
export interface IconButtonProps {
|
|
21
|
+
prefix?: IconPrefix;
|
|
22
|
+
icon: IconName;
|
|
23
|
+
accessibilityLabel: string;
|
|
24
|
+
iconColor: "darkGray" | ButtonColor | ThemeColor | Color;
|
|
25
|
+
onClick: () => void;
|
|
26
|
+
size?: IconSize;
|
|
27
|
+
bgColor?: "transparent" | "transparentDarkGray" | "gray" | "lightGray" | "white"; // default transparent
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
selected?: boolean;
|
|
30
|
+
withConfirmation?: boolean;
|
|
31
|
+
confirmationText?: string;
|
|
32
|
+
confirmationHeading?: string;
|
|
33
|
+
tooltip?: {
|
|
34
|
+
text: string;
|
|
35
|
+
idealDirection?: TooltipDirection;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
22
38
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
// eslint-disable-next-line react/display-name
|
|
40
|
+
export const IconButton = forwardRef(
|
|
41
|
+
(
|
|
42
|
+
{
|
|
43
|
+
prefix,
|
|
44
|
+
icon,
|
|
45
|
+
iconColor,
|
|
46
|
+
onClick,
|
|
47
|
+
size,
|
|
48
|
+
bgColor = "transparent",
|
|
49
|
+
withConfirmation = false,
|
|
50
|
+
confirmationText = "Are you sure you want to continue?",
|
|
51
|
+
confirmationHeading = "Confirm",
|
|
52
|
+
tooltip,
|
|
53
|
+
}: IconButtonProps,
|
|
54
|
+
ref
|
|
55
|
+
) => {
|
|
56
|
+
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
size="sm"
|
|
47
|
-
visible={showConfirmation}
|
|
48
|
-
onDismiss={(): void => {
|
|
49
|
-
setShowConfirmation(false);
|
|
50
|
-
}}
|
|
51
|
-
>
|
|
52
|
-
<Text>{confirmationText}</Text>
|
|
53
|
-
</Modal>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
58
|
+
let opacity = 1;
|
|
59
|
+
let color: string;
|
|
60
|
+
if (bgColor === "transparentDarkGray") {
|
|
61
|
+
opacity = 0.8;
|
|
62
|
+
color = Unifier.theme.darkGray;
|
|
63
|
+
} else if (bgColor === "transparent" || !bgColor) {
|
|
64
|
+
opacity = 1.0;
|
|
65
|
+
color = Unifier.theme.white;
|
|
66
|
+
} else {
|
|
67
|
+
color = Unifier.theme[bgColor];
|
|
68
|
+
}
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
opacity,
|
|
63
|
-
backgroundColor: color,
|
|
64
|
-
borderRadius: 100,
|
|
65
|
-
// paddingBottom: iconSizeToNumber(size) / 4,
|
|
66
|
-
// paddingTop: iconSizeToNumber(size) / 4,
|
|
67
|
-
// paddingLeft: iconSizeToNumber(size) / 2,
|
|
68
|
-
// paddingRight: iconSizeToNumber(size) / 2,
|
|
69
|
-
width: iconSizeToNumber(size) * 2.5,
|
|
70
|
-
height: iconSizeToNumber(size) * 2.5,
|
|
71
|
-
display: "flex",
|
|
72
|
-
justifyContent: "center",
|
|
73
|
-
alignItems: "center",
|
|
74
|
-
}}
|
|
75
|
-
onPress={() => {
|
|
76
|
-
Unifier.utils.haptic();
|
|
77
|
-
if (withConfirmation && !showConfirmation) {
|
|
78
|
-
setShowConfirmation(true);
|
|
79
|
-
} else if (onClick) {
|
|
70
|
+
const renderConfirmation = () => {
|
|
71
|
+
return (
|
|
72
|
+
<Modal
|
|
73
|
+
heading={confirmationHeading}
|
|
74
|
+
primaryButtonOnClick={() => {
|
|
80
75
|
onClick();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
setShowConfirmation(false);
|
|
77
|
+
}}
|
|
78
|
+
primaryButtonText="Confirm"
|
|
79
|
+
secondaryButtonOnClick={(): void => setShowConfirmation(false)}
|
|
80
|
+
secondaryButtonText="Cancel"
|
|
81
|
+
size="sm"
|
|
82
|
+
visible={showConfirmation}
|
|
83
|
+
onDismiss={(): void => {
|
|
84
|
+
setShowConfirmation(false);
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
<Text>{confirmationText}</Text>
|
|
88
|
+
</Modal>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
function renderIconButton(): React.ReactElement {
|
|
93
|
+
return (
|
|
94
|
+
<View>
|
|
95
|
+
<TouchableOpacity
|
|
96
|
+
ref={ref as any}
|
|
97
|
+
hitSlop={{top: 10, left: 10, bottom: 10, right: 10}}
|
|
98
|
+
style={{
|
|
99
|
+
opacity,
|
|
100
|
+
backgroundColor: color,
|
|
101
|
+
borderRadius: 100,
|
|
102
|
+
// paddingBottom: iconSizeToNumber(size) / 4,
|
|
103
|
+
// paddingTop: iconSizeToNumber(size) / 4,
|
|
104
|
+
// paddingLeft: iconSizeToNumber(size) / 2,
|
|
105
|
+
// paddingRight: iconSizeToNumber(size) / 2,
|
|
106
|
+
width: iconSizeToNumber(size) * 2.5,
|
|
107
|
+
height: iconSizeToNumber(size) * 2.5,
|
|
108
|
+
display: "flex",
|
|
109
|
+
justifyContent: "center",
|
|
110
|
+
alignItems: "center",
|
|
111
|
+
}}
|
|
112
|
+
onPress={() => {
|
|
113
|
+
Unifier.utils.haptic();
|
|
114
|
+
if (withConfirmation && !showConfirmation) {
|
|
115
|
+
setShowConfirmation(true);
|
|
116
|
+
} else if (onClick) {
|
|
117
|
+
onClick();
|
|
118
|
+
}
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
<Icon color={iconColor} name={icon} prefix={prefix || "fas"} size={size} />
|
|
122
|
+
</TouchableOpacity>
|
|
123
|
+
{Boolean(withConfirmation) && renderConfirmation()}
|
|
124
|
+
</View>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Only add for web. This doesn't make much sense for mobile, since the action would be performed for the button
|
|
129
|
+
// as well as the tooltip appearing.
|
|
130
|
+
// TODO: Add tooltip info button next to the icon button on mobile.
|
|
131
|
+
if (tooltip && Platform.OS === "web") {
|
|
132
|
+
return (
|
|
133
|
+
<Tooltip idealDirection={tooltip.idealDirection} text={tooltip.text}>
|
|
134
|
+
{renderIconButton()}
|
|
135
|
+
</Tooltip>
|
|
136
|
+
);
|
|
137
|
+
} else {
|
|
138
|
+
return renderIconButton();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import {IconSize} from "./Common";
|
|
4
|
+
import {IconButton} from "./IconButton";
|
|
5
|
+
|
|
6
|
+
interface InfoTooltipButtonProps {
|
|
7
|
+
text: string;
|
|
8
|
+
size?: IconSize;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function InfoTooltipButton({text, size}: InfoTooltipButtonProps): React.ReactElement {
|
|
12
|
+
return (
|
|
13
|
+
<IconButton
|
|
14
|
+
accessibilityLabel="info"
|
|
15
|
+
bgColor="transparent"
|
|
16
|
+
icon="exclamation"
|
|
17
|
+
iconColor="blue"
|
|
18
|
+
size={size}
|
|
19
|
+
tooltip={{text}}
|
|
20
|
+
onClick={() => {}}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
package/src/Modal.tsx
CHANGED
|
@@ -108,43 +108,41 @@ export const Modal = ({
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
return (
|
|
111
|
-
<
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
height: 6,
|
|
124
|
-
},
|
|
125
|
-
shadowRadius: 4,
|
|
126
|
-
shadowOpacity: 1.0,
|
|
127
|
-
elevation: 8,
|
|
111
|
+
<RNModal animationType="slide" transparent visible={visible} onRequestClose={onDismiss}>
|
|
112
|
+
<Box
|
|
113
|
+
alignItems="center"
|
|
114
|
+
alignSelf="center"
|
|
115
|
+
color="white"
|
|
116
|
+
dangerouslySetInlineStyle={{
|
|
117
|
+
__style: {
|
|
118
|
+
zIndex: 1,
|
|
119
|
+
shadowColor: "#999",
|
|
120
|
+
shadowOffset: {
|
|
121
|
+
width: 4,
|
|
122
|
+
height: 6,
|
|
128
123
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
124
|
+
shadowRadius: 4,
|
|
125
|
+
shadowOpacity: 1.0,
|
|
126
|
+
elevation: 8,
|
|
127
|
+
},
|
|
128
|
+
}}
|
|
129
|
+
direction="column"
|
|
130
|
+
justifyContent="center"
|
|
131
|
+
marginTop={12}
|
|
132
|
+
maxWidth={sizePx}
|
|
133
|
+
minWidth={300}
|
|
134
|
+
paddingX={8}
|
|
135
|
+
paddingY={2}
|
|
136
|
+
rounding={6}
|
|
137
|
+
shadow
|
|
138
|
+
width={sizePx}
|
|
139
|
+
>
|
|
140
|
+
<Box marginBottom={6} width="100%">
|
|
141
|
+
{renderHeader()}
|
|
142
|
+
<Box paddingY={4}>{children}</Box>
|
|
143
|
+
<Box paddingY={4}>{renderFooter()}</Box>
|
|
146
144
|
</Box>
|
|
147
|
-
</
|
|
148
|
-
</
|
|
145
|
+
</Box>
|
|
146
|
+
</RNModal>
|
|
149
147
|
);
|
|
150
148
|
};
|