@swan-io/lake 13.7.3 → 13.7.5

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-io/lake",
3
- "version": "13.7.3",
3
+ "version": "13.7.5",
4
4
  "engines": {
5
5
  "node": ">22.12.0"
6
6
  },
@@ -23,6 +23,7 @@ export type ButtonProps = {
23
23
  hrefAttrs?: HrefAttrs;
24
24
  pill?: boolean;
25
25
  disabledUntil?: string;
26
+ [key: `data-${string}`]: string | undefined;
26
27
  } & ({
27
28
  ariaLabel: string;
28
29
  children?: never;
@@ -30,7 +31,7 @@ export type ButtonProps = {
30
31
  ariaLabel?: string;
31
32
  children: ReactNode;
32
33
  });
33
- export declare const LakeButton: import("react").MemoExoticComponent<({ ref, ariaControls, ariaExpanded, ariaLabel, children, color, direction, disabled, icon, grow, iconPosition, loading, mode, onPress, size, iconSize, style, forceBackground, href, hrefAttrs, pill, disabledUntil, }: ButtonProps) => import("react/jsx-runtime").JSX.Element>;
34
+ export declare const LakeButton: import("react").MemoExoticComponent<({ ref, ariaControls, ariaExpanded, ariaLabel, children, color, direction, disabled, icon, grow, iconPosition, loading, mode, onPress, size, iconSize, style, forceBackground, href, hrefAttrs, pill, disabledUntil, ...dataAttributes }: ButtonProps) => import("react/jsx-runtime").JSX.Element>;
34
35
  type GroupProps = {
35
36
  children: ReactNode;
36
37
  justifyContent?: ViewStyle["justifyContent"];
@@ -123,7 +123,7 @@ const styles = StyleSheet.create({
123
123
  visibility: "hidden",
124
124
  },
125
125
  });
126
- export const LakeButton = memo(({ ref, 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, }) => {
126
+ export const LakeButton = memo(({ ref, 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, ...dataAttributes }) => {
127
127
  const [progressAnimation, setProgressAnimation] = useState(() => Option.None());
128
128
  const isPrimary = mode === "primary";
129
129
  const isSmall = size === "small";
@@ -163,7 +163,7 @@ export const LakeButton = memo(({ ref, ariaControls, ariaExpanded, ariaLabel, ch
163
163
  return () => cancelAnimationFrame(animationFrameId);
164
164
  }, [disabledUntil]);
165
165
  const shouldHideContents = loading || progressAnimation.isSome();
166
- 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: ref, onPress: onPress, style: ({ hovered, pressed, focused }) => [
166
+ return (_jsx(Pressable, { ...dataAttributes, 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: ref, onPress: onPress, style: ({ hovered, pressed, focused }) => [
167
167
  styles.base,
168
168
  (hovered || pressed) && styles.transition,
169
169
  grow && styles.grow,
@@ -16,5 +16,7 @@ type Props = {
16
16
  style?: StyleProp<ViewStyle>;
17
17
  };
18
18
  export declare const LakeStepper: ({ steps, activeStepId, style }: Props) => import("react/jsx-runtime").JSX.Element;
19
+ /** @deprecated Use <MobileStepper> instead */
19
20
  export declare const MobileStepTitle: ({ steps, activeStepId }: Props) => import("react/jsx-runtime").JSX.Element | null;
21
+ export declare const MobileStepper: ({ steps, activeStepId }: Props) => import("react/jsx-runtime").JSX.Element | null;
20
22
  export {};
@@ -62,6 +62,20 @@ const styles = StyleSheet.create({
62
62
  backgroundColor: colors.negative[50],
63
63
  },
64
64
  });
65
+ const stylesMobile = StyleSheet.create({
66
+ progress: {
67
+ borderRadius: 10,
68
+ marginTop: 10,
69
+ height: 3,
70
+ backgroundColor: colors.gray[100],
71
+ },
72
+ progressBar: {
73
+ borderRadius: 10,
74
+ height: "100%",
75
+ backgroundColor: colors.current[500],
76
+ transitionDuration: "300ms",
77
+ },
78
+ });
65
79
  const StepLink = ({ to, disabled, style, children }) => {
66
80
  return disabled ? (_jsx("span", { style: style, children: children })) : (_jsx(Link, { to: to, style: style, children: children }));
67
81
  };
@@ -113,6 +127,7 @@ export const LakeStepper = ({ steps, activeStepId, style }) => {
113
127
  }) })] }, currentId));
114
128
  }) }));
115
129
  };
130
+ /** @deprecated Use <MobileStepper> instead */
116
131
  export const MobileStepTitle = ({ steps, activeStepId }) => {
117
132
  const currentStep = Option.fromNullable(steps
118
133
  .flatMap((step, index) => match(step)
@@ -132,3 +147,26 @@ export const MobileStepTitle = ({ steps, activeStepId }) => {
132
147
  None: () => null,
133
148
  });
134
149
  };
150
+ export const MobileStepper = ({ steps, activeStepId }) => {
151
+ const total = steps.length;
152
+ const currentStep = Option.fromNullable(steps
153
+ .flatMap((step, index) => match(step)
154
+ .with({ id: P.string }, step => ({ ...step, number: `${index + 1}` }))
155
+ .with({ children: P.array(P.any) }, ({ children }) => children.map((child, subIndex) => ({
156
+ ...child,
157
+ number: `${index + 1}.${subIndex + 1}`,
158
+ })))
159
+ .exhaustive())
160
+ .find(({ id }) => id === activeStepId)).map(({ label, hasErrors, number }) => ({
161
+ number,
162
+ label,
163
+ isErrorState: hasErrors === true,
164
+ }));
165
+ return currentStep.match({
166
+ Some: ({ number, label, isErrorState }) => {
167
+ const progress = `${(Number.parseFloat(number) / total) * 100}%`;
168
+ return (_jsxs(View, { children: [_jsx(LakeText, { variant: "smallMedium", color: isErrorState ? colors.negative[500] : colors.current[500], children: label }), _jsxs(LakeText, { variant: "smallRegular", color: colors.gray[300], children: [number, " of ", total] }), _jsx(View, { style: stylesMobile.progress, children: _jsx(View, { style: [stylesMobile.progressBar, { width: progress }] }) })] }));
169
+ },
170
+ None: () => null,
171
+ });
172
+ };
@@ -1,5 +1,5 @@
1
1
  import { FC, ReactNode, Ref } from "react";
2
- import { HrefAttrs, NativeSyntheticEvent, PressableProps, PressableStateCallbackType, Text, TextInputProps, TextProps, View, ViewProps } from "react-native";
2
+ import { HrefAttrs, NativeSyntheticEvent, PressableStateCallbackType, Text, TextInputProps, TextProps, View, ViewProps } from "react-native";
3
3
  import { Except, Merge } from "type-fest";
4
4
  import { PressResponderConfig } from "../hooks/usePressEvents";
5
5
  type Props<BaseProps extends TextProps | TextInputProps> = Merge<BaseProps, {
@@ -22,6 +22,7 @@ type Props<BaseProps extends TextProps | TextInputProps> = Merge<BaseProps, {
22
22
  onPressMove?: PressResponderConfig["onPressMove"];
23
23
  onPressOut?: PressResponderConfig["onPressEnd"];
24
24
  style?: BaseProps["style"] | ((state: PressableStateCallbackType) => BaseProps["style"]);
25
+ [key: `data-${string}`]: string | undefined;
25
26
  /**
26
27
  * Used only for documentation or testing (e.g. snapshot testing).
27
28
  */
@@ -32,12 +33,12 @@ type ExtraProps = {
32
33
  href?: string;
33
34
  hrefAttrs?: HrefAttrs;
34
35
  };
35
- export type PressableViewProps = Except<Props<ViewProps>, "children">;
36
+ export type PressableViewProps = Props<ViewProps>;
36
37
  export type PressableTextProps = Props<TextProps>;
37
- export declare const Pressable: FC<PressableProps & ExtraProps & {
38
+ export declare const Pressable: FC<Except<PressableViewProps, "ref"> & ExtraProps & {
38
39
  ref?: Ref<View>;
39
40
  }>;
40
- export declare const PressableText: FC<PressableTextProps & {
41
+ export declare const PressableText: FC<Except<PressableTextProps, "ref"> & {
41
42
  ref?: Ref<Text>;
42
43
  }>;
43
44
  export {};
@@ -22,6 +22,10 @@ Component, config = {}) => {
22
22
  const { applyPressStyle = true } = config;
23
23
  return (props) => {
24
24
  const { ref, children, delayLongPress, delayPressIn, delayPressOut, disabled = false, onBlur, onContextMenu, onFocus, onHoverIn, onHoverOut, onKeyDown, onLongPress, onPress, onPressIn, onPressMove, onPressOut, style, tabIndex, testOnly_hovered, testOnly_pressed, ...rest } = props;
25
+ const dataSet = Object.fromEntries(Object.entries(props)
26
+ .filter(([key]) => key.startsWith("data-"))
27
+ // remove the "data-" prefix from the keys to match React Native's dataSet prop format
28
+ .map(([key, value]) => [key.slice(5), value]));
25
29
  const [hovered, setHovered] = useForceableState(testOnly_hovered === true);
26
30
  const [focused, setFocused] = useForceableState(false);
27
31
  const [pressed, setPressed] = useForceableState(testOnly_pressed === true);
@@ -91,7 +95,7 @@ Component, config = {}) => {
91
95
  else {
92
96
  _tabIndex = disabled ? -1 : 0;
93
97
  }
94
- return (_jsx(Component, { ...rest, ...pressEventHandlers, "aria-disabled": disabled, onBlur: blurHandler, onContextmenu: contextMenuHandler, onFocus: focusHandler, onKeyDown: keyDownHandler, ref: setRef, style: [
98
+ return (_jsx(Component, { ...rest, ...pressEventHandlers, dataSet: dataSet, "aria-disabled": disabled, onBlur: blurHandler, onContextmenu: contextMenuHandler, onFocus: focusHandler, onKeyDown: keyDownHandler, ref: setRef, style: [
95
99
  match({ disabled, applyPressStyle })
96
100
  .with({ disabled: false, applyPressStyle: true }, () => styles.active)
97
101
  .with({ disabled: true }, () => styles.disabled)
@@ -1,8 +0,0 @@
1
- type Props = {
2
- steps: {
3
- label: string;
4
- }[];
5
- activeStep: number;
6
- };
7
- export declare const Stepper: ({ steps, activeStep }: Props) => import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,67 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Fragment } from "react";
3
- import { StyleSheet, View } from "react-native";
4
- import { colors, spacings } from "../constants/design";
5
- import { Box } from "./Box";
6
- import { Icon } from "./Icon";
7
- import { LakeHeading } from "./LakeHeading";
8
- import { LakeText } from "./LakeText";
9
- const styles = StyleSheet.create({
10
- container: {
11
- paddingBottom: spacings[24],
12
- },
13
- circle: {
14
- width: spacings[32],
15
- height: spacings[32],
16
- borderColor: colors.gray[100],
17
- borderWidth: 1,
18
- borderRadius: 16,
19
- color: colors.gray[400],
20
- alignItems: "center",
21
- justifyContent: "center",
22
- },
23
- activeCircle: {
24
- width: spacings[32],
25
- height: spacings[32],
26
- borderColor: colors.current[500],
27
- backgroundColor: colors.current[500],
28
- borderWidth: 1,
29
- borderRadius: 16,
30
- color: colors.current.contrast,
31
- alignItems: "center",
32
- justifyContent: "center",
33
- },
34
- counter: {
35
- lineHeight: 0.8,
36
- },
37
- item: {
38
- paddingHorizontal: spacings[12],
39
- },
40
- textContainer: {
41
- position: "absolute",
42
- top: "100%",
43
- left: "50%",
44
- transform: "translateX(-50%) translateY(5px)",
45
- },
46
- text: {
47
- whiteSpace: "nowrap",
48
- },
49
- separator: {
50
- height: spacings[4],
51
- borderRadius: 2,
52
- backgroundColor: colors.gray[100],
53
- flexGrow: 1,
54
- },
55
- doneSeparator: {
56
- backgroundColor: colors.current[500],
57
- },
58
- });
59
- export const Stepper = ({ steps, activeStep }) => {
60
- return (_jsx(Box, { direction: "row", alignItems: "center", style: styles.container, children: steps.map((item, index) => {
61
- const isActive = index === activeStep;
62
- const isDone = index < activeStep;
63
- const color = isActive || isDone ? colors.current.contrast : colors.gray[300];
64
- const textColor = isActive || isDone ? colors.current[500] : colors.gray[300];
65
- return (_jsxs(Fragment, { children: [index > 0 ? (_jsx(View, { style: [styles.separator, (isActive || isDone) && styles.doneSeparator] })) : null, _jsxs(View, { style: styles.item, children: [_jsx(View, { style: isActive || isDone ? styles.activeCircle : styles.circle, children: isDone ? (_jsx(Icon, { size: 20, name: "checkmark-filled", color: color })) : (_jsx(LakeHeading, { level: 3, variant: "h3", color: color, style: styles.counter, children: String(index + 1) })) }), _jsx(View, { style: styles.textContainer, children: _jsx(LakeText, { style: styles.text, color: textColor, variant: isDone || isActive ? "semibold" : "regular", children: item.label }) })] })] }, index));
66
- }) }));
67
- };