@xylabs/react-button 7.0.0 → 7.0.2
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/browser/components/ButtonEx.stories.d.ts +8 -8
- package/dist/browser/components/ButtonEx.stories.d.ts.map +1 -1
- package/dist/browser/components/ButtonExBase.d.ts.map +1 -1
- package/dist/browser/components/ButtonExProps.d.ts +1 -1
- package/dist/browser/components/ButtonExProps.d.ts.map +1 -1
- package/dist/browser/components/ButtonExTo.d.ts.map +1 -1
- package/dist/browser/index.mjs +68 -62
- package/dist/browser/index.mjs.map +1 -1
- package/package.json +22 -19
- package/src/components/ButtonEx.tsx +3 -3
- package/src/components/ButtonExBase.tsx +4 -3
- package/src/components/ButtonExProps.tsx +6 -3
- package/src/components/ButtonExTo.tsx +2 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Meta } from '@storybook/react-vite';
|
|
2
2
|
import { ButtonEx } from './ButtonEx.tsx';
|
|
3
3
|
declare const StorybookEntry: Meta<typeof ButtonEx>;
|
|
4
|
-
declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
5
|
-
declare const BusyCircular: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
6
|
-
declare const BusyLinear: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
7
|
-
declare const Href: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
8
|
-
declare const HrefTarget: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
9
|
-
declare const HrefTargetOnClick: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
10
|
-
declare const HrefTargetWithEvents: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
11
|
-
declare const HrefTargetOnClickWithEvents: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
4
|
+
declare const Default: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
5
|
+
declare const BusyCircular: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
6
|
+
declare const BusyLinear: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
7
|
+
declare const Href: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
8
|
+
declare const HrefTarget: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
9
|
+
declare const HrefTargetOnClick: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
10
|
+
declare const HrefTargetWithEvents: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
11
|
+
declare const HrefTargetOnClickWithEvents: import(".store/storybook-virtual-ae2e92fa55/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, import("./ButtonExProps.tsx").ButtonExProps>;
|
|
12
12
|
export { BusyCircular, BusyLinear, Default, Href, HrefTarget, HrefTargetOnClick, HrefTargetOnClickWithEvents, HrefTargetWithEvents, };
|
|
13
13
|
export default StorybookEntry;
|
|
14
14
|
//# sourceMappingURL=ButtonEx.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonEx.stories.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonEx.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,uBAAuB,CAAA;AAK1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,QAAA,MAAM,cAAc,EAKf,IAAI,CAAC,OAAO,QAAQ,CAAC,CAAA;AAwC1B,QAAA,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"ButtonEx.stories.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonEx.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,uBAAuB,CAAA;AAK1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,QAAA,MAAM,cAAc,EAKf,IAAI,CAAC,OAAO,QAAQ,CAAC,CAAA;AAwC1B,QAAA,MAAM,OAAO,iLAA2B,CAAA;AAGxC,QAAA,MAAM,YAAY,iLAA2B,CAAA;AAG7C,QAAA,MAAM,UAAU,iLAA2B,CAAA;AAG3C,QAAA,MAAM,IAAI,iLAA2B,CAAA;AAGrC,QAAA,MAAM,UAAU,iLAA2B,CAAA;AAG3C,QAAA,MAAM,iBAAiB,iLAA2B,CAAA;AAKlD,QAAA,MAAM,oBAAoB,iLAA6B,CAAA;AAGvD,QAAA,MAAM,2BAA2B,iLAA6B,CAAA;AAK9D,OAAO,EACL,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,EAAE,2BAA2B,EACnG,oBAAoB,GACrB,CAAA;AAED,eAAe,cAAc,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonExBase.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExBase.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ButtonExBase.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExBase.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,QAAA,MAAM,YAAY;oFAEf,aAAa;;CAoDf,CAAA;AAID,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -22,7 +22,7 @@ export interface ButtonHrefAndToProps {
|
|
|
22
22
|
to?: To;
|
|
23
23
|
toOptions?: NavigateOptions;
|
|
24
24
|
}
|
|
25
|
-
export declare const asButtonHrefOrToProps: (
|
|
25
|
+
export declare const asButtonHrefOrToProps: ({ href, to, toOptions, }: ButtonHrefAndToProps) => ButtonHrefOrToOrNoProps;
|
|
26
26
|
export interface ButtonBaseExProps extends Omit<ButtonProps, 'href'>, BoxlikeComponentProps, BusyProps {
|
|
27
27
|
disableUserEvents?: boolean;
|
|
28
28
|
funnel?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonExProps.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExProps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"ButtonExProps.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExProps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAE3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,KAAK,CAAA;IACV,SAAS,CAAC,EAAE,KAAK,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,EAAE,CAAC,EAAE,EAAE,CAAA;IACP,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,EAAE,CAAC,EAAE,KAAK,CAAA;IACV,SAAS,CAAC,EAAE,KAAK,CAAA;CAClB;AAED,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,qBAAqB,CAAA;AAErG,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,EAAE,CAAA;IACP,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,eAAO,MAAM,qBAAqB,GAAI,0BAEnC,oBAAoB,KAAG,uBAKzB,CAAA;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,qBAAqB,EAAE,SAAS;IACpG,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,uBAAuB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonExTo.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExTo.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ButtonExTo.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonExTo.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,QAAA,MAAM,UAAU;gDAEb,aAAa;;CAUf,CAAA;AAID,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
package/dist/browser/index.mjs
CHANGED
|
@@ -1,35 +1,50 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
|
-
// src/components/ButtonEx.tsx
|
|
5
|
-
import React3 from "react";
|
|
6
|
-
|
|
7
1
|
// src/components/ButtonExBase.tsx
|
|
8
2
|
import { Button, useTheme } from "@mui/material";
|
|
9
3
|
import { toPromise } from "@xylabs/promise";
|
|
10
4
|
import { useUserEvents } from "@xylabs/react-pixel";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
import {
|
|
6
|
+
BusyCircularProgress,
|
|
7
|
+
BusyLinearProgress,
|
|
8
|
+
mergeBoxlikeStyles
|
|
9
|
+
} from "@xylabs/react-shared";
|
|
10
|
+
import { isString } from "@xylabs/typeof";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
var ButtonExBase = ({
|
|
13
|
+
ref,
|
|
14
|
+
funnel,
|
|
15
|
+
intent,
|
|
16
|
+
target,
|
|
17
|
+
placement,
|
|
18
|
+
disableUserEvents,
|
|
19
|
+
href,
|
|
20
|
+
...props
|
|
21
|
+
}) => {
|
|
14
22
|
const theme = useTheme();
|
|
15
23
|
const userEvents = useUserEvents();
|
|
16
|
-
const {
|
|
17
|
-
|
|
24
|
+
const {
|
|
25
|
+
busy,
|
|
26
|
+
busyVariant = "linear",
|
|
27
|
+
busyOpacity,
|
|
28
|
+
onClick,
|
|
29
|
+
children,
|
|
30
|
+
...rootProps
|
|
31
|
+
} = mergeBoxlikeStyles(theme, props);
|
|
32
|
+
const localOnClick = (event) => {
|
|
18
33
|
if (busy) {
|
|
19
34
|
event.preventDefault();
|
|
20
35
|
} else {
|
|
21
36
|
const elementName = props["aria-label"] ?? event.currentTarget.textContent;
|
|
22
|
-
const windowToNavigate =
|
|
23
|
-
const callOnClickAndFollowHref =
|
|
37
|
+
const windowToNavigate = () => isString(target) && isString(href) ? window.open("", target) ?? globalThis : globalThis;
|
|
38
|
+
const callOnClickAndFollowHref = (windowToNav = windowToNavigate()) => {
|
|
24
39
|
onClick?.(event);
|
|
25
|
-
if (href) {
|
|
40
|
+
if (isString(href)) {
|
|
26
41
|
windowToNav.location.href = href;
|
|
27
42
|
}
|
|
28
|
-
}
|
|
43
|
+
};
|
|
29
44
|
if (!disableUserEvents && userEvents) {
|
|
30
45
|
event.preventDefault();
|
|
31
46
|
const windowToNav = windowToNavigate();
|
|
32
|
-
if (href) {
|
|
47
|
+
if (isString(href)) {
|
|
33
48
|
toPromise(userEvents.userClick({
|
|
34
49
|
elementName,
|
|
35
50
|
intent,
|
|
@@ -47,70 +62,61 @@ var ButtonExBase = /* @__PURE__ */ __name(({ ref, funnel, intent, target, placem
|
|
|
47
62
|
callOnClickAndFollowHref();
|
|
48
63
|
}
|
|
49
64
|
}
|
|
50
|
-
}
|
|
51
|
-
return /* @__PURE__ */
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, busy && busyVariant === "linear" ? /* @__PURE__ */ React.createElement(BusyLinearProgress, {
|
|
58
|
-
rounded: true,
|
|
59
|
-
opacity: busyOpacity ?? 0
|
|
60
|
-
}) : null, busy && busyVariant === "circular" ? /* @__PURE__ */ React.createElement(BusyCircularProgress, {
|
|
61
|
-
rounded: true,
|
|
62
|
-
size: 24,
|
|
63
|
-
opacity: busyOpacity ?? 0.5
|
|
64
|
-
}) : null, children);
|
|
65
|
-
}, "ButtonExBase");
|
|
65
|
+
};
|
|
66
|
+
return /* @__PURE__ */ jsxs(Button, { ref, href, onClick: localOnClick, target, ...rootProps, children: [
|
|
67
|
+
busy && busyVariant === "linear" ? /* @__PURE__ */ jsx(BusyLinearProgress, { rounded: true, opacity: busyOpacity ?? 0 }) : null,
|
|
68
|
+
busy && busyVariant === "circular" ? /* @__PURE__ */ jsx(BusyCircularProgress, { rounded: true, size: 24, opacity: busyOpacity ?? 0.5 }) : null,
|
|
69
|
+
children
|
|
70
|
+
] });
|
|
71
|
+
};
|
|
66
72
|
ButtonExBase.displayName = "ButtonExBaseXYLabs";
|
|
67
73
|
|
|
68
74
|
// src/components/ButtonExTo.tsx
|
|
69
|
-
import
|
|
75
|
+
import { isDefined } from "@xylabs/typeof";
|
|
70
76
|
import { useNavigate } from "react-router-dom";
|
|
71
|
-
|
|
77
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
78
|
+
var ButtonToEx = ({
|
|
79
|
+
ref,
|
|
80
|
+
to,
|
|
81
|
+
toOptions,
|
|
82
|
+
onClick,
|
|
83
|
+
...props
|
|
84
|
+
}) => {
|
|
72
85
|
const navigate = useNavigate();
|
|
73
|
-
const localOnClick =
|
|
86
|
+
const localOnClick = (event) => {
|
|
74
87
|
onClick?.(event);
|
|
75
|
-
if (to) {
|
|
88
|
+
if (isDefined(to)) {
|
|
76
89
|
void navigate(to, toOptions);
|
|
77
90
|
}
|
|
78
|
-
}
|
|
79
|
-
return /* @__PURE__ */
|
|
80
|
-
|
|
81
|
-
onClick: localOnClick,
|
|
82
|
-
...props
|
|
83
|
-
});
|
|
84
|
-
}, "ButtonToEx");
|
|
91
|
+
};
|
|
92
|
+
return /* @__PURE__ */ jsx2(ButtonExBase, { ref, onClick: localOnClick, ...props });
|
|
93
|
+
};
|
|
85
94
|
ButtonToEx.displayName = "ButtonToExXYLabs";
|
|
86
95
|
|
|
87
96
|
// src/components/ButtonEx.tsx
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return /* @__PURE__ */
|
|
92
|
-
to,
|
|
93
|
-
ref,
|
|
94
|
-
...additionalProps
|
|
95
|
-
});
|
|
97
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
98
|
+
var ButtonEx = ({ ref, ...props }) => {
|
|
99
|
+
if (props.to === void 0) {
|
|
100
|
+
return /* @__PURE__ */ jsx3(ButtonExBase, { ...props });
|
|
96
101
|
} else {
|
|
97
|
-
|
|
102
|
+
const { to, ...additionalProps } = props;
|
|
103
|
+
return /* @__PURE__ */ jsx3(ButtonToEx, { to, ref, ...additionalProps });
|
|
98
104
|
}
|
|
99
|
-
}
|
|
105
|
+
};
|
|
100
106
|
ButtonEx.displayName = "ButtonExXYLabs";
|
|
101
107
|
|
|
102
108
|
// src/components/ButtonExProps.tsx
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
import { isDefined as isDefined2, isString as isString2 } from "@xylabs/typeof";
|
|
110
|
+
var asButtonHrefOrToProps = ({
|
|
111
|
+
href,
|
|
112
|
+
to,
|
|
113
|
+
toOptions
|
|
114
|
+
}) => {
|
|
115
|
+
if (isString2(href) && (isDefined2(to) || isDefined2(toOptions))) {
|
|
105
116
|
throw new Error("ButtonExProps: cannot have both href and to");
|
|
106
117
|
}
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
} : props.to ? {
|
|
110
|
-
to: props.to,
|
|
111
|
-
toOptions: props.toOptions
|
|
112
|
-
} : {};
|
|
113
|
-
}, "asButtonHrefOrToProps");
|
|
118
|
+
return isString2(href) ? { href } : isDefined2(to) ? { to, toOptions } : {};
|
|
119
|
+
};
|
|
114
120
|
export {
|
|
115
121
|
ButtonEx,
|
|
116
122
|
asButtonHrefOrToProps
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/
|
|
1
|
+
{"version":3,"sources":["../../src/components/ButtonExBase.tsx","../../src/components/ButtonExTo.tsx","../../src/components/ButtonEx.tsx","../../src/components/ButtonExProps.tsx"],"sourcesContent":["import { Button, useTheme } from '@mui/material'\nimport { toPromise } from '@xylabs/promise'\nimport { useUserEvents } from '@xylabs/react-pixel'\nimport {\n BusyCircularProgress, BusyLinearProgress, mergeBoxlikeStyles,\n} from '@xylabs/react-shared'\nimport { isString } from '@xylabs/typeof'\nimport type { MouseEvent } from 'react'\nimport React from 'react'\n\nimport type { ButtonExProps } from './ButtonExProps.tsx'\n\nconst ButtonExBase = ({\n ref, funnel, intent, target, placement, disableUserEvents, href, ...props\n}: ButtonExProps) => {\n const theme = useTheme()\n const userEvents = useUserEvents()\n const {\n busy, busyVariant = 'linear', busyOpacity, onClick, children, ...rootProps\n } = mergeBoxlikeStyles<ButtonExProps>(theme, props)\n\n const localOnClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (busy) {\n // If it is busy, do not allow href clicks\n event.preventDefault()\n } else {\n const elementName = props['aria-label'] ?? event.currentTarget.textContent\n // we do this crazy navigate thing so that we can set it up outside the promise so that safari does not block it\n const windowToNavigate = () => (isString(target) && isString(href)) ? window.open('', target) ?? globalThis : globalThis\n const callOnClickAndFollowHref = (windowToNav = windowToNavigate()) => {\n onClick?.(event)\n if (isString(href)) {\n windowToNav.location.href = href\n }\n }\n if (!disableUserEvents && userEvents) {\n event.preventDefault()\n const windowToNav = windowToNavigate()\n if (isString(href)) {\n toPromise(userEvents.userClick({\n elementName, intent, funnel, placement,\n })).then(() => {\n callOnClickAndFollowHref(windowToNav)\n }).catch((ex) => {\n console.error('User event failed', elementName, funnel, placement, ex)\n callOnClickAndFollowHref(windowToNav)\n })\n }\n onClick?.(event)\n } else {\n callOnClickAndFollowHref()\n }\n }\n }\n\n return (\n <Button ref={ref} href={href} onClick={localOnClick} target={target} {...rootProps}>\n {busy && busyVariant === 'linear'\n ? <BusyLinearProgress rounded opacity={busyOpacity ?? 0} />\n : null}\n {busy && busyVariant === 'circular'\n ? <BusyCircularProgress rounded size={24} opacity={busyOpacity ?? 0.5} />\n : null}\n {children}\n </Button>\n )\n}\n\nButtonExBase.displayName = 'ButtonExBaseXYLabs'\n\nexport { ButtonExBase }\n","import { isDefined } from '@xylabs/typeof'\nimport type { MouseEvent } from 'react'\nimport React from 'react'\nimport { useNavigate } from 'react-router-dom'\n\nimport { ButtonExBase } from './ButtonExBase.tsx'\nimport type { ButtonExProps } from './ButtonExProps.tsx'\n\nconst ButtonToEx = ({\n ref, to, toOptions, onClick, ...props\n}: ButtonExProps) => {\n const navigate = useNavigate()\n const localOnClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (isDefined(to)) {\n void navigate(to, toOptions)\n }\n }\n\n return <ButtonExBase ref={ref} onClick={localOnClick} {...props} />\n}\n\nButtonToEx.displayName = 'ButtonToExXYLabs'\n\nexport { ButtonToEx }\n","import React from 'react'\n\nimport { ButtonExBase } from './ButtonExBase.tsx'\nimport type { ButtonExProps } from './ButtonExProps.tsx'\nimport { ButtonToEx } from './ButtonExTo.tsx'\n\nconst ButtonEx = ({ ref, ...props }: ButtonExProps) => {\n if (props.to === undefined) {\n return <ButtonExBase {...props} />\n } else {\n const { to, ...additionalProps } = props\n return <ButtonToEx to={to} ref={ref} {...additionalProps} />\n }\n}\n\nButtonEx.displayName = 'ButtonExXYLabs'\n\nexport { ButtonEx }\n","import type { ButtonProps } from '@mui/material'\nimport type { BoxlikeComponentProps, BusyProps } from '@xylabs/react-shared'\nimport { isDefined, isString } from '@xylabs/typeof'\nimport type { NavigateOptions, To } from 'react-router-dom'\n\nexport interface ButtonOnlyHrefProps {\n href?: string\n to?: never\n toOptions?: never\n}\n\nexport interface ButtonOnlyToProps {\n href?: never\n to?: To\n toOptions?: NavigateOptions\n}\n\nexport interface ButtonNoToOrHrefProps {\n href?: never\n to?: never\n toOptions?: never\n}\n\nexport type ButtonHrefOrToOrNoProps = ButtonOnlyHrefProps | ButtonOnlyToProps | ButtonNoToOrHrefProps\n\nexport interface ButtonHrefAndToProps {\n href?: string\n to?: To\n toOptions?: NavigateOptions\n}\n\nexport const asButtonHrefOrToProps = ({\n href, to, toOptions,\n}: ButtonHrefAndToProps): ButtonHrefOrToOrNoProps => {\n if (isString(href) && (isDefined(to) || isDefined(toOptions))) {\n throw new Error('ButtonExProps: cannot have both href and to')\n }\n return isString(href) ? { href } : isDefined(to) ? { to, toOptions } : {}\n}\n\nexport interface ButtonBaseExProps extends Omit<ButtonProps, 'href'>, BoxlikeComponentProps, BusyProps {\n disableUserEvents?: boolean\n funnel?: string\n intent?: string\n placement?: string\n target?: string\n}\n\nexport type ButtonExProps = ButtonBaseExProps & ButtonHrefOrToOrNoProps\n"],"mappings":"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","names":["jsx","jsx","isDefined","isString"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xylabs/react-button",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.2",
|
|
4
4
|
"description": "Common React library for all XY Labs projects that use React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"utility",
|
|
@@ -41,29 +41,32 @@
|
|
|
41
41
|
"packages/*"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@xylabs/promise": "
|
|
45
|
-
"@xylabs/react-pixel": "
|
|
46
|
-
"@xylabs/react-shared": "
|
|
47
|
-
"
|
|
44
|
+
"@xylabs/promise": "~5.0.8",
|
|
45
|
+
"@xylabs/react-pixel": "~7.0.2",
|
|
46
|
+
"@xylabs/react-shared": "~7.0.2",
|
|
47
|
+
"@xylabs/typeof": "~5.0.8",
|
|
48
|
+
"react-router-dom": "~7.8.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@mui/material": "
|
|
51
|
-
"@storybook/react-vite": "
|
|
52
|
-
"@types/react": "
|
|
53
|
-
"@xylabs/react-flexbox": "
|
|
54
|
-
"@xylabs/react-pixel": "
|
|
55
|
-
"@xylabs/ts-scripts-yarn3": "
|
|
56
|
-
"@xylabs/tsconfig
|
|
57
|
-
"
|
|
58
|
-
"react
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
51
|
+
"@mui/material": "~7.3.1",
|
|
52
|
+
"@storybook/react-vite": "~9.1.2",
|
|
53
|
+
"@types/react": "~19.1.10",
|
|
54
|
+
"@xylabs/react-flexbox": "~7.0.2",
|
|
55
|
+
"@xylabs/react-pixel": "~7.0.2",
|
|
56
|
+
"@xylabs/ts-scripts-yarn3": "~7.1.1",
|
|
57
|
+
"@xylabs/tsconfig": "~7.1.1",
|
|
58
|
+
"@xylabs/tsconfig-dom": "~7.1.1",
|
|
59
|
+
"@xylabs/tsconfig-react": "~7.1.1",
|
|
60
|
+
"react": "~19.1.1",
|
|
61
|
+
"react-dom": "~19.1.1",
|
|
62
|
+
"storybook": "~9.1.2",
|
|
63
|
+
"typescript": "~5.9.2",
|
|
64
|
+
"vite": "~7.1.2"
|
|
62
65
|
},
|
|
63
66
|
"peerDependencies": {
|
|
64
67
|
"@mui/material": ">=6 <8",
|
|
65
|
-
"react": "
|
|
66
|
-
"react-dom": "
|
|
68
|
+
"react": "~19",
|
|
69
|
+
"react-dom": "~19"
|
|
67
70
|
},
|
|
68
71
|
"publishConfig": {
|
|
69
72
|
"access": "public"
|
|
@@ -5,11 +5,11 @@ import type { ButtonExProps } from './ButtonExProps.tsx'
|
|
|
5
5
|
import { ButtonToEx } from './ButtonExTo.tsx'
|
|
6
6
|
|
|
7
7
|
const ButtonEx = ({ ref, ...props }: ButtonExProps) => {
|
|
8
|
-
if (props.to) {
|
|
8
|
+
if (props.to === undefined) {
|
|
9
|
+
return <ButtonExBase {...props} />
|
|
10
|
+
} else {
|
|
9
11
|
const { to, ...additionalProps } = props
|
|
10
12
|
return <ButtonToEx to={to} ref={ref} {...additionalProps} />
|
|
11
|
-
} else {
|
|
12
|
-
return <ButtonExBase {...props} />
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -4,6 +4,7 @@ import { useUserEvents } from '@xylabs/react-pixel'
|
|
|
4
4
|
import {
|
|
5
5
|
BusyCircularProgress, BusyLinearProgress, mergeBoxlikeStyles,
|
|
6
6
|
} from '@xylabs/react-shared'
|
|
7
|
+
import { isString } from '@xylabs/typeof'
|
|
7
8
|
import type { MouseEvent } from 'react'
|
|
8
9
|
import React from 'react'
|
|
9
10
|
|
|
@@ -25,17 +26,17 @@ const ButtonExBase = ({
|
|
|
25
26
|
} else {
|
|
26
27
|
const elementName = props['aria-label'] ?? event.currentTarget.textContent
|
|
27
28
|
// we do this crazy navigate thing so that we can set it up outside the promise so that safari does not block it
|
|
28
|
-
const windowToNavigate = () => (target && href) ? window.open('', target) ?? globalThis : globalThis
|
|
29
|
+
const windowToNavigate = () => (isString(target) && isString(href)) ? window.open('', target) ?? globalThis : globalThis
|
|
29
30
|
const callOnClickAndFollowHref = (windowToNav = windowToNavigate()) => {
|
|
30
31
|
onClick?.(event)
|
|
31
|
-
if (href) {
|
|
32
|
+
if (isString(href)) {
|
|
32
33
|
windowToNav.location.href = href
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
if (!disableUserEvents && userEvents) {
|
|
36
37
|
event.preventDefault()
|
|
37
38
|
const windowToNav = windowToNavigate()
|
|
38
|
-
if (href) {
|
|
39
|
+
if (isString(href)) {
|
|
39
40
|
toPromise(userEvents.userClick({
|
|
40
41
|
elementName, intent, funnel, placement,
|
|
41
42
|
})).then(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ButtonProps } from '@mui/material'
|
|
2
2
|
import type { BoxlikeComponentProps, BusyProps } from '@xylabs/react-shared'
|
|
3
|
+
import { isDefined, isString } from '@xylabs/typeof'
|
|
3
4
|
import type { NavigateOptions, To } from 'react-router-dom'
|
|
4
5
|
|
|
5
6
|
export interface ButtonOnlyHrefProps {
|
|
@@ -28,11 +29,13 @@ export interface ButtonHrefAndToProps {
|
|
|
28
29
|
toOptions?: NavigateOptions
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
export const asButtonHrefOrToProps = (
|
|
32
|
-
|
|
32
|
+
export const asButtonHrefOrToProps = ({
|
|
33
|
+
href, to, toOptions,
|
|
34
|
+
}: ButtonHrefAndToProps): ButtonHrefOrToOrNoProps => {
|
|
35
|
+
if (isString(href) && (isDefined(to) || isDefined(toOptions))) {
|
|
33
36
|
throw new Error('ButtonExProps: cannot have both href and to')
|
|
34
37
|
}
|
|
35
|
-
return
|
|
38
|
+
return isString(href) ? { href } : isDefined(to) ? { to, toOptions } : {}
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
export interface ButtonBaseExProps extends Omit<ButtonProps, 'href'>, BoxlikeComponentProps, BusyProps {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDefined } from '@xylabs/typeof'
|
|
1
2
|
import type { MouseEvent } from 'react'
|
|
2
3
|
import React from 'react'
|
|
3
4
|
import { useNavigate } from 'react-router-dom'
|
|
@@ -11,7 +12,7 @@ const ButtonToEx = ({
|
|
|
11
12
|
const navigate = useNavigate()
|
|
12
13
|
const localOnClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
13
14
|
onClick?.(event)
|
|
14
|
-
if (to) {
|
|
15
|
+
if (isDefined(to)) {
|
|
15
16
|
void navigate(to, toOptions)
|
|
16
17
|
}
|
|
17
18
|
}
|