@swan-io/lake 8.12.0 → 8.13.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/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Option } from "@swan-io/boxed";
|
|
3
|
+
import { Children, forwardRef, Fragment, memo, useEffect, useState } from "react";
|
|
3
4
|
import { ActivityIndicator, StyleSheet, View, } from "react-native";
|
|
4
|
-
import { match } from "ts-pattern";
|
|
5
|
+
import { match, P } from "ts-pattern";
|
|
5
6
|
import { commonStyles } from "../constants/commonStyles";
|
|
6
7
|
import { backgroundColor, colors, invariantColors, radii, spacings, texts, } from "../constants/design";
|
|
7
8
|
import { isNotNullish, isNullish } from "../utils/nullish";
|
|
@@ -52,6 +53,12 @@ const styles = StyleSheet.create({
|
|
|
52
53
|
backgroundColor: colors.gray[900],
|
|
53
54
|
borderRadius: radii[6],
|
|
54
55
|
},
|
|
56
|
+
loaderContainerProgress: {
|
|
57
|
+
opacity: 0.5,
|
|
58
|
+
backgroundColor: colors.gray[900],
|
|
59
|
+
transformOrigin: "0 0",
|
|
60
|
+
...StyleSheet.absoluteFillObject,
|
|
61
|
+
},
|
|
55
62
|
small: {
|
|
56
63
|
height: 40,
|
|
57
64
|
paddingLeft: 16,
|
|
@@ -83,6 +90,8 @@ const styles = StyleSheet.create({
|
|
|
83
90
|
alignItems: "center",
|
|
84
91
|
justifyContent: "center",
|
|
85
92
|
transform: "translateZ(0px)",
|
|
93
|
+
borderRadius: radii[6],
|
|
94
|
+
overflow: "hidden",
|
|
86
95
|
},
|
|
87
96
|
group: {
|
|
88
97
|
flexDirection: "row",
|
|
@@ -112,7 +121,8 @@ const styles = StyleSheet.create({
|
|
|
112
121
|
visibility: "hidden",
|
|
113
122
|
},
|
|
114
123
|
});
|
|
115
|
-
export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLabel, children, color = "gray", direction = "row", disabled = false, icon, grow = false, iconPosition = "start", loading = false, mode = "primary", onPress, size = "large", iconSize = size === "small" ? 18 : 20, style, forceBackground = false, href, hrefAttrs, pill = false, }, forwardedRef) => {
|
|
124
|
+
export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLabel, children, color = "gray", direction = "row", disabled = false, icon, grow = false, iconPosition = "start", loading = false, mode = "primary", onPress, size = "large", iconSize = size === "small" ? 18 : 20, style, forceBackground = false, href, hrefAttrs, pill = false, disabledUntil, }, forwardedRef) => {
|
|
125
|
+
const [progressAnimation, setProgressAnimation] = useState(() => Option.None());
|
|
116
126
|
const isPrimary = mode === "primary";
|
|
117
127
|
const isSmall = size === "small";
|
|
118
128
|
const vertical = direction === "column";
|
|
@@ -122,14 +132,43 @@ export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLab
|
|
|
122
132
|
const hasIconStart = hasIcon && iconPosition === "start";
|
|
123
133
|
const hasIconEnd = hasIcon && iconPosition === "end";
|
|
124
134
|
const hasOnlyIcon = hasIcon && isNullish(children);
|
|
125
|
-
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (disabledUntil == null) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
const endTime = new Date(disabledUntil).getTime();
|
|
141
|
+
const config = {
|
|
142
|
+
startTime,
|
|
143
|
+
duration: endTime - startTime,
|
|
144
|
+
endTime,
|
|
145
|
+
};
|
|
146
|
+
const tick = () => {
|
|
147
|
+
const now = Date.now();
|
|
148
|
+
if (now >= config.endTime) {
|
|
149
|
+
setProgressAnimation(Option.None());
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
setProgressAnimation(Option.Some({
|
|
153
|
+
startTime: config.startTime,
|
|
154
|
+
duration: config.duration,
|
|
155
|
+
now: Date.now(),
|
|
156
|
+
}));
|
|
157
|
+
animationFrameId = requestAnimationFrame(tick);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
let animationFrameId = requestAnimationFrame(tick);
|
|
161
|
+
return () => cancelAnimationFrame(animationFrameId);
|
|
162
|
+
}, [disabledUntil]);
|
|
163
|
+
const shouldHideContents = loading || progressAnimation.isSome();
|
|
164
|
+
return (_jsx(Pressable, { href: href, hrefAttrs: hrefAttrs, role: href != null ? "link" : "button", "aria-busy": loading, "aria-disabled": disabled, "aria-controls": ariaControls, "aria-expanded": ariaExpanded, "aria-label": ariaLabel, disabled: loading || disabled || progressAnimation.isSome(), ref: forwardedRef, onPress: onPress, style: ({ hovered, pressed, focused }) => [
|
|
126
165
|
styles.base,
|
|
127
166
|
isSmall && styles.small,
|
|
128
167
|
vertical && [styles.vertical, isSmall && styles.verticalSmall],
|
|
129
168
|
hasIconStart && isSmall ? styles.withIconStartSmall : styles.withIconStart,
|
|
130
169
|
hasIconEnd && (isSmall ? styles.withIconEndSmall : styles.withIconEnd),
|
|
131
170
|
hasOnlyIcon && (isSmall ? styles.iconSmallOnly : styles.iconOnly),
|
|
132
|
-
disabled && commonStyles.disabled,
|
|
171
|
+
(disabled || progressAnimation.isSome()) && commonStyles.disabled,
|
|
133
172
|
disabled && forceBackground && styles.resetOpacity,
|
|
134
173
|
grow && styles.grow,
|
|
135
174
|
match(mode)
|
|
@@ -174,11 +213,16 @@ export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLab
|
|
|
174
213
|
: hovered || pressed
|
|
175
214
|
? colors[color][700]
|
|
176
215
|
: colors[color][600];
|
|
177
|
-
return (_jsxs(_Fragment, { children: [hasIconStart && (_jsxs(_Fragment, { children: [_jsx(Icon, { color: textColor, name: icon, size: iconSize, style:
|
|
216
|
+
return (_jsxs(_Fragment, { children: [hasIconStart && (_jsxs(_Fragment, { children: [_jsx(Icon, { color: textColor, name: icon, size: iconSize, style: shouldHideContents && styles.hidden }), isNotNullish(children) && _jsx(Space, { height: spaceHeight, width: spaceWidth })] })), typeof children === "string" || typeof children === "number" ? (_jsx(LakeText, { numberOfLines: 1, userSelect: "none", style: [
|
|
178
217
|
isSmall ? styles.textSmall : styles.text,
|
|
179
|
-
|
|
218
|
+
shouldHideContents && styles.hidden,
|
|
180
219
|
{ color: textColor },
|
|
181
|
-
], children: children })) : (_jsx(Box, { alignItems: "center", direction: "row", justifyContent: "center", style: [vertical && styles.vertical,
|
|
220
|
+
], children: children })) : (_jsx(Box, { alignItems: "center", direction: "row", justifyContent: "center", style: [vertical && styles.vertical, shouldHideContents && styles.hidden], children: children })), hasIconEnd && (_jsxs(_Fragment, { children: [isNotNullish(children) && _jsx(Space, { height: spaceHeight, width: spaceWidth }), _jsx(Icon, { color: textColor, name: icon, size: iconSize, style: shouldHideContents && styles.hidden })] })), loading && (_jsx(View, { style: styles.loaderContainer, children: _jsx(ActivityIndicator, { color: isPrimary ? colors[color].contrast : colors[color].primary, size: iconSize }) })), isPrimary && _jsx(View, { style: [styles.hiddenView, pressed && styles.pressed] }), match(progressAnimation)
|
|
221
|
+
.with(Option.P.Some(P.select()), ({ startTime, now, duration }) => (_jsxs(View, { style: styles.loaderContainer, children: [_jsx(View, { style: [
|
|
222
|
+
styles.loaderContainerProgress,
|
|
223
|
+
{ transform: `scaleX(${((now - startTime) / duration) * 100}%)` },
|
|
224
|
+
] }), _jsx(LakeText, { color: isPrimary ? colors[color].contrast : colors[color].primary, children: Math.ceil((duration - (now - startTime)) / 1000) })] })))
|
|
225
|
+
.otherwise(() => null), pill && _jsx(View, { style: styles.pill })] }));
|
|
182
226
|
} }));
|
|
183
227
|
}));
|
|
184
228
|
LakeButton.displayName = "Button";
|