@xyo-network/react-xns 3.0.12 → 3.0.13

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.
Files changed (23) hide show
  1. package/dist/browser/components/XnsNameCapture/Props.d.ts +1 -0
  2. package/dist/browser/components/XnsNameCapture/Props.d.ts.map +1 -1
  3. package/dist/browser/components/XnsNameCapture/XnsNameCapture.d.ts.map +1 -1
  4. package/dist/browser/components/XnsNameCapture/hooks/index.d.ts +1 -1
  5. package/dist/browser/components/XnsNameCapture/hooks/index.d.ts.map +1 -1
  6. package/dist/browser/components/XnsNameCapture/hooks/routing/index.d.ts +3 -0
  7. package/dist/browser/components/XnsNameCapture/hooks/routing/index.d.ts.map +1 -0
  8. package/dist/browser/components/XnsNameCapture/hooks/{useXnsNameCaptureRouting.d.ts → routing/useXnsNameCaptureRouting.d.ts} +3 -2
  9. package/dist/browser/components/XnsNameCapture/hooks/{useXnsNameCaptureRouting.d.ts.map → routing/useXnsNameCaptureRouting.d.ts.map} +1 -1
  10. package/dist/browser/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.d.ts +2 -0
  11. package/dist/browser/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.d.ts.map +1 -0
  12. package/dist/browser/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.d.ts +1 -0
  13. package/dist/browser/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.d.ts.map +1 -1
  14. package/dist/browser/index.mjs +60 -19
  15. package/dist/browser/index.mjs.map +1 -1
  16. package/package.json +2 -2
  17. package/src/components/XnsNameCapture/Props.ts +1 -0
  18. package/src/components/XnsNameCapture/XnsNameCapture.tsx +2 -1
  19. package/src/components/XnsNameCapture/XnsNameCaptureWithContext.stories.tsx +35 -9
  20. package/src/components/XnsNameCapture/hooks/index.ts +1 -1
  21. package/src/components/XnsNameCapture/hooks/routing/index.ts +2 -0
  22. package/src/components/XnsNameCapture/hooks/{useXnsNameCaptureRouting.ts → routing/useXnsNameCaptureRouting.ts} +6 -1
  23. package/src/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.ts +26 -0
@@ -15,6 +15,7 @@ export interface XnsNameCaptureTrackingProps {
15
15
  export interface XnsNameCaptureRoutingProps {
16
16
  navigate?: (to: string) => void;
17
17
  paramsString?: string;
18
+ routingError?: Error;
18
19
  to?: To;
19
20
  }
20
21
  export interface XnsNameCaptureBaseProps {
@@ -1 +1 @@
1
- {"version":3,"file":"Props.d.ts","sourceRoot":"","sources":["../../../../src/components/XnsNameCapture/Props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAE1C,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAKD,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,UAAU,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACvD;AAKD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,EAAE,CAAC,EAAE,EAAE,CAAA;CACR;AAKD,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB,EAClE,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,YAAY;CACZ;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAA;CAAE,CAAA"}
1
+ {"version":3,"file":"Props.d.ts","sourceRoot":"","sources":["../../../../src/components/XnsNameCapture/Props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAE1C,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAKD,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,UAAU,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACvD;AAKD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,EAAE,CAAC,EAAE,EAAE,CAAA;CACR;AAKD,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB,EAClE,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,YAAY;CACZ;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAA;CAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"XnsNameCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/XnsNameCapture/XnsNameCapture.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAgC,MAAM,OAAO,CAAA;AAIpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAGrD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAkGxD,CAAA"}
1
+ {"version":3,"file":"XnsNameCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/XnsNameCapture/XnsNameCapture.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAgC,MAAM,OAAO,CAAA;AAIpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAGrD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAmGxD,CAAA"}
@@ -1,3 +1,3 @@
1
+ export * from './routing/index.ts';
1
2
  export * from './useXnsNameCaptureProviders.ts';
2
- export * from './useXnsNameCaptureRouting.ts';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/XnsNameCapture/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAA;AAC/C,cAAc,+BAA+B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/XnsNameCapture/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,iCAAiC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './useXnsNameCaptureRouting.ts';
2
+ export * from './useXnsNameFromLocation.ts';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/XnsNameCapture/hooks/routing/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA"}
@@ -1,10 +1,11 @@
1
- import type { XnsNameCaptureProps } from '../Props.ts';
1
+ import type { XnsNameCaptureProps } from '../../Props.ts';
2
2
  export declare const useXnsNameCaptureRouting: (props: XnsNameCaptureProps) => {
3
+ defaultXnsName: string | undefined;
4
+ routingError: Error | undefined;
3
5
  navigate: (to: string) => void;
4
6
  paramsString: string;
5
7
  autoFocus?: boolean;
6
8
  buttonText?: string;
7
- defaultXnsName?: string;
8
9
  errorUi?: "alert" | "toast";
9
10
  mobileButtonText?: string;
10
11
  placement?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useXnsNameCaptureRouting.d.ts","sourceRoot":"","sources":["../../../../../src/components/XnsNameCapture/hooks/useXnsNameCaptureRouting.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,eAAO,MAAM,wBAAwB,UAAW,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYlE,CAAA"}
1
+ {"version":3,"file":"useXnsNameCaptureRouting.d.ts","sourceRoot":"","sources":["../../../../../../src/components/XnsNameCapture/hooks/routing/useXnsNameCaptureRouting.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAGzD,eAAO,MAAM,wBAAwB,UAAW,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBlE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const useXnsNameFromLocation: () => [name: string | undefined, error: Error | undefined];
2
+ //# sourceMappingURL=useXnsNameFromLocation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useXnsNameFromLocation.d.ts","sourceRoot":"","sources":["../../../../../../src/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,sBAAsB,QAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,CAmB5F,CAAA"}
@@ -14,6 +14,7 @@ export declare const useXnsNameCaptureProviders: (props: XnsNameCaptureProps) =>
14
14
  onCaptureName?: (name: string) => Promise<void>;
15
15
  navigate?: (to: string) => void;
16
16
  paramsString?: string;
17
+ routingError?: Error;
17
18
  to?: import("react-router").To;
18
19
  background?: boolean;
19
20
  paper?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useXnsNameCaptureProviders.d.ts","sourceRoot":"","sources":["../../../../../src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,eAAO,MAAM,0BAA0B,UAAW,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOpE,CAAA"}
1
+ {"version":3,"file":"useXnsNameCaptureProviders.d.ts","sourceRoot":"","sources":["../../../../../src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,eAAO,MAAM,0BAA0B,UAAW,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOpE,CAAA"}
@@ -77,30 +77,56 @@ var XnsNameCaptureErrors = /* @__PURE__ */ __name(({ error, errorUi, resetError
77
77
  })());
78
78
  }, "XnsNameCaptureErrors");
79
79
 
80
- // src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts
81
- import { useMixpanel } from "@xylabs/react-mixpanel";
80
+ // src/components/XnsNameCapture/hooks/routing/useXnsNameCaptureRouting.ts
82
81
  import { useMemo } from "react";
83
- var useXnsNameCaptureProviders = /* @__PURE__ */ __name((props) => {
84
- const mixpanel = useMixpanel();
85
- return useMemo(() => ({
86
- ...props,
87
- mixpanel: props.mixpanel ?? mixpanel
88
- }), [
89
- props,
90
- mixpanel
91
- ]);
92
- }, "useXnsNameCaptureProviders");
93
-
94
- // src/components/XnsNameCapture/hooks/useXnsNameCaptureRouting.ts
95
- import { useMemo as useMemo2 } from "react";
96
82
  import { useNavigate, useSearchParams } from "react-router-dom";
83
+
84
+ // src/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.ts
85
+ import { useLocation } from "react-router-dom";
86
+ var useXnsNameFromLocation = /* @__PURE__ */ __name(() => {
87
+ const location = useLocation();
88
+ const search = new URLSearchParams(location.search);
89
+ const rawName = (search.get("xnsname") ?? search.get("name") ?? search.get("username") ?? "").toLowerCase();
90
+ switch (rawName?.split(".").length) {
91
+ case 1: {
92
+ return [
93
+ rawName,
94
+ void 0
95
+ ];
96
+ }
97
+ case 2: {
98
+ const rawNameParts = rawName.split(".");
99
+ if (rawNameParts[1] !== "xyo") {
100
+ return [
101
+ ,
102
+ new Error("Invalid xNS name [Bad root]")
103
+ ];
104
+ }
105
+ return [
106
+ rawNameParts[0],
107
+ void 0
108
+ ];
109
+ }
110
+ default: {
111
+ return [
112
+ ,
113
+ new Error("Invalid xNS name [Too many parts]")
114
+ ];
115
+ }
116
+ }
117
+ }, "useXnsNameFromLocation");
118
+
119
+ // src/components/XnsNameCapture/hooks/routing/useXnsNameCaptureRouting.ts
97
120
  var useXnsNameCaptureRouting = /* @__PURE__ */ __name((props) => {
98
121
  const [params] = useSearchParams();
99
122
  const signatureParam = params.get("signature");
100
123
  const signatureParamString = signatureParam ? `&signature=${encodeURIComponent(signatureParam)}` : "";
101
124
  const navigate = useNavigate();
102
- return useMemo2(() => ({
125
+ const [name, error] = useXnsNameFromLocation();
126
+ return useMemo(() => ({
103
127
  ...props,
128
+ defaultXnsName: name,
129
+ routingError: error,
104
130
  navigate: props.navigate ?? ((to) => navigate(to)),
105
131
  paramsString: signatureParamString
106
132
  }), [
@@ -109,6 +135,20 @@ var useXnsNameCaptureRouting = /* @__PURE__ */ __name((props) => {
109
135
  ]);
110
136
  }, "useXnsNameCaptureRouting");
111
137
 
138
+ // src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts
139
+ import { useMixpanel } from "@xylabs/react-mixpanel";
140
+ import { useMemo as useMemo2 } from "react";
141
+ var useXnsNameCaptureProviders = /* @__PURE__ */ __name((props) => {
142
+ const mixpanel = useMixpanel();
143
+ return useMemo2(() => ({
144
+ ...props,
145
+ mixpanel: props.mixpanel ?? mixpanel
146
+ }), [
147
+ props,
148
+ mixpanel
149
+ ]);
150
+ }, "useXnsNameCaptureProviders");
151
+
112
152
  // src/components/XnsNameCapture/SecondaryLink.tsx
113
153
  import { ArrowForwardRounded } from "@mui/icons-material";
114
154
  import { Stack } from "@mui/material";
@@ -160,9 +200,9 @@ import { ButtonEx } from "@xylabs/react-button";
160
200
  import { FlexCol, FlexRow as FlexRow2 } from "@xylabs/react-flexbox";
161
201
  import { MIN_DOMAIN_LENGTH as MIN_DOMAIN_LENGTH2, XnsNameHelper as XnsNameHelper3 } from "@xyo-network/xns-record-payloadset-plugins";
162
202
  import React4, { useCallback, useState as useState2 } from "react";
163
- var XnsNameCapture = /* @__PURE__ */ __name(({ autoFocus = false, buttonText = "Buy My Name", children, defaultXnsName, errorUi = "alert", event = "Click to Checkout", funnel = "xns", mixpanel, mobileButtonText = "Buy", navigate, onCaptureName: onCaptureNameProp, paramsString = "", placement = "", showSecondary = false, to = "/xns/estimation", userEvents, ...props }) => {
203
+ var XnsNameCapture = /* @__PURE__ */ __name(({ autoFocus = false, buttonText = "Buy My Name", children, defaultXnsName, errorUi = "alert", event = "Click to Checkout", funnel = "xns", mixpanel, mobileButtonText = "Buy", navigate, onCaptureName: onCaptureNameProp, paramsString = "", placement = "", routingError, showSecondary = false, to = "/xns/estimation", userEvents, ...props }) => {
164
204
  const [xnsName, setXnsName] = useState2(() => defaultXnsName ?? "");
165
- const [error, setError] = useState2();
205
+ const [error, setError] = useState2(routingError);
166
206
  const theme = useTheme3();
167
207
  const isMobile = useMediaQuery2(theme.breakpoints.down("md"));
168
208
  const captureDisabled = !xnsName || xnsName.length < MIN_DOMAIN_LENGTH2;
@@ -271,6 +311,7 @@ export {
271
311
  XnsNameCaptureErrors,
272
312
  XnsNameCaptureWithContext,
273
313
  useXnsNameCaptureProviders,
274
- useXnsNameCaptureRouting
314
+ useXnsNameCaptureRouting,
315
+ useXnsNameFromLocation
275
316
  };
276
317
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/EstimateName/EstimateNameTextField.tsx","../../src/components/XnsNameCapture/Errors.tsx","../../src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts","../../src/components/XnsNameCapture/hooks/useXnsNameCaptureRouting.ts","../../src/components/XnsNameCapture/SecondaryLink.tsx","../../src/components/XnsNameCapture/XnsNameCapture.tsx","../../src/components/XnsNameCapture/XnsNameCaptureWithContext.tsx"],"sourcesContent":["import type { StandardTextFieldProps, TextFieldProps } from '@mui/material'\nimport {\n alpha, TextField, useTheme,\n} from '@mui/material'\nimport { MIN_DOMAIN_LENGTH, XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport React, { useState } from 'react'\n\nexport interface XnsEstimateNameTextFieldProps {\n maskOutput?: boolean\n}\n\nexport const XnsEstimateNameTextField: React.FC<XnsEstimateNameTextFieldProps & TextFieldProps> = ({\n maskOutput = true, onChange: onChangeProp, onBlur: onBlurProp, ...props\n}) => {\n const theme = useTheme()\n const [validLength, setValidLength] = useState(false)\n\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n // override onChange to mask the input and update the event value\n const handleChange: StandardTextFieldProps['onChange'] = (event) => {\n if (maskOutput) {\n const value = event.target.value\n event.target.value = XnsNameHelper.mask(value)\n }\n onChangeProp?.(event)\n\n if (inputRef.current) {\n setValidLength(inputRef.current.value.length >= MIN_DOMAIN_LENGTH)\n }\n }\n\n const handleBlur: StandardTextFieldProps['onBlur'] = (event) => {\n if (maskOutput) {\n const value = event.target.value\n event.target.value = XnsNameHelper.mask(value, { maskStartEndHyphens: true })\n }\n onBlurProp?.(event)\n }\n\n return (\n <TextField\n inputProps={{ style: { color: validLength ? theme.palette.text.primary : alpha(theme.palette.text.primary, 0.5) } }}\n inputRef={inputRef}\n onBlur={handleBlur}\n onChange={handleChange}\n {...props}\n />\n )\n}\n","import {\n Alert, Snackbar, useMediaQuery, useTheme,\n} from '@mui/material'\nimport { FlexRow } from '@xylabs/react-flexbox'\nimport React from 'react'\n\nexport interface XnsNameCaptureErrorsProps {\n error?: Error\n errorUi?: 'alert' | 'toast'\n resetError?: () => void\n}\n\nexport const XnsNameCaptureErrors: React.FC<XnsNameCaptureErrorsProps> = ({\n error, errorUi, resetError,\n}) => {\n const theme = useTheme()\n const isMobile = useMediaQuery(theme.breakpoints.down('md'))\n\n return (\n <>\n {(errorUi === 'toast')\n ? (\n <Snackbar\n open={!!error}\n message={error?.toString()}\n autoHideDuration={3000}\n onClose={() => resetError?.()}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert\n severity=\"error\"\n sx={{\n width: '100%', display: (isMobile && !error) ? 'none' : undefined, visibility: error ? 'visible' : 'hidden',\n }}\n >\n {error?.message}\n </Alert>\n </Snackbar>\n )\n : (() => {\n // setTimeout(() => setError(undefined), 1500)\n return (\n <FlexRow alignSelf=\"stretch\">\n <Alert\n severity=\"error\"\n sx={{ display: (isMobile && !error) ? 'none' : undefined, visibility: error ? 'visible' : 'hidden' }}\n >\n {error?.message}\n </Alert>\n </FlexRow>\n )\n })()}\n </>\n )\n}\n","import { useMixpanel } from '@xylabs/react-mixpanel'\nimport { useMemo } from 'react'\n\nimport type { XnsNameCaptureProps } from '../Props.ts'\n\nexport const useXnsNameCaptureProviders = (props: XnsNameCaptureProps) => {\n const mixpanel = useMixpanel()\n\n return useMemo(() => ({\n ...props,\n mixpanel: props.mixpanel ?? mixpanel,\n }), [props, mixpanel])\n}\n","import { useMemo } from 'react'\nimport { useNavigate, useSearchParams } from 'react-router-dom'\n\nimport type { XnsNameCaptureProps } from '../Props.ts'\n\nexport const useXnsNameCaptureRouting = (props: XnsNameCaptureProps) => {\n const [params] = useSearchParams()\n const signatureParam = params.get('signature')\n const signatureParamString = signatureParam ? `&signature=${encodeURIComponent(signatureParam)}` : ''\n\n const navigate = useNavigate()\n\n return useMemo(() => ({\n ...props,\n navigate: props.navigate ?? ((to: string) => navigate(to)),\n paramsString: signatureParamString,\n }), [props, signatureParamString])\n}\n","import { ArrowForwardRounded } from '@mui/icons-material'\nimport { Stack } from '@mui/material'\nimport type { LinkExProps } from '@xylabs/react-link'\nimport { LinkEx } from '@xylabs/react-link'\nimport { XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport type { Dispatch } from 'react'\nimport React from 'react'\n\nimport type {\n XnsNameCaptureBuyCallbacks, XnsNameCaptureRoutingProps, XnsNameCaptureTrackingProps,\n} from './Props.ts'\n\nexport interface XnsCaptureSecondaryLinkProps extends XnsNameCaptureTrackingProps, XnsNameCaptureRoutingProps, XnsNameCaptureBuyCallbacks, LinkExProps {\n event?: string\n funnel?: string\n placement?: string\n setError?: Dispatch<Error | undefined>\n text?: string\n xnsName: string\n}\n\nexport const XnsCaptureSecondaryLink: React.FC<XnsCaptureSecondaryLinkProps> = ({\n event = 'Click to Reservation',\n funnel = 'xns',\n mixpanel,\n navigate,\n onCaptureName,\n paramsString = '',\n placement = '',\n setError,\n text = 'Or make a free reservation',\n to = '/xns/reservation',\n userEvents,\n xnsName,\n ...props\n}) => {\n return (\n <LinkEx\n paddingX={0}\n color=\"inherit\"\n style={{ textDecoration: 'underline', textUnderlineOffset: '5px' }}\n onClick={async () => {\n mixpanel?.track(event, {\n Funnel: funnel,\n Placement: placement,\n })\n const formattedXnsName = `${xnsName}.xyo`\n const helper = XnsNameHelper.fromString(formattedXnsName)\n const [valid, errors] = await helper.validate()\n if (valid) {\n await userEvents?.userClick({ elementName: event, elementType: 'xns-cta' })\n navigate?.(`${to}?username=${xnsName}${paramsString}`)\n await onCaptureName?.(xnsName)\n } else {\n setError?.(new Error(errors.join(', ')))\n }\n }}\n {...props}\n >\n <Stack flexDirection=\"row\" gap={0.5} alignItems=\"center\" sx={{ cursor: 'pointer' }}>\n {text}\n <ArrowForwardRounded />\n </Stack>\n </LinkEx>\n )\n}\n","import { KeyboardArrowRightRounded } from '@mui/icons-material'\nimport type { StandardTextFieldProps } from '@mui/material'\nimport { useMediaQuery, useTheme } from '@mui/material'\nimport { ButtonEx } from '@xylabs/react-button'\nimport { FlexCol, FlexRow } from '@xylabs/react-flexbox'\nimport { MIN_DOMAIN_LENGTH, XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport type { KeyboardEventHandler } from 'react'\nimport React, { useCallback, useState } from 'react'\n\nimport { XnsEstimateNameTextField } from '../EstimateName/index.ts'\nimport { XnsNameCaptureErrors } from './Errors.tsx'\nimport type { XnsNameCaptureProps } from './Props.ts'\nimport { XnsCaptureSecondaryLink } from './SecondaryLink.js'\n\nexport const XnsNameCapture: React.FC<XnsNameCaptureProps> = ({\n autoFocus = false,\n buttonText = 'Buy My Name',\n children,\n defaultXnsName,\n errorUi = 'alert',\n event = 'Click to Checkout',\n funnel = 'xns',\n mixpanel,\n mobileButtonText = 'Buy',\n navigate,\n onCaptureName: onCaptureNameProp,\n paramsString = '',\n placement = '',\n showSecondary = false,\n to = '/xns/estimation',\n userEvents,\n ...props\n}) => {\n const [xnsName, setXnsName] = useState<string>(() => defaultXnsName ?? '')\n const [error, setError] = useState<Error | undefined>()\n\n const theme = useTheme()\n const isMobile = useMediaQuery(theme.breakpoints.down('md'))\n\n const captureDisabled = !xnsName || xnsName.length < MIN_DOMAIN_LENGTH\n\n const handleChange: StandardTextFieldProps['onChange'] = (event) => {\n const NsName = XnsNameHelper.mask(event.target.value)\n setXnsName(NsName)\n setError(undefined)\n }\n\n const onCaptureName = useCallback(async () => {\n if (captureDisabled) return\n mixpanel?.track(event, {\n Funnel: funnel,\n Placement: placement,\n })\n const formattedXnsName = `${xnsName}.xyo`\n const helper = XnsNameHelper.fromString(formattedXnsName)\n const [valid, errors] = await helper.validate()\n if (valid) {\n await userEvents?.userClick({ elementName: event, elementType: 'xns-cta' })\n await onCaptureNameProp?.(xnsName)\n navigate?.(`${to}?username=${xnsName}${paramsString}`)\n } else {\n setError(new Error(errors.join(', ')))\n }\n }, [event, funnel, mixpanel, paramsString, placement, to, userEvents, xnsName])\n\n const onKeyDown: KeyboardEventHandler<HTMLDivElement> = useCallback(async (event) => {\n if (event.key === 'Enter' && !captureDisabled) {\n await onCaptureName?.()\n }\n }, [captureDisabled, onCaptureName])\n\n return (\n <FlexCol gap={showSecondary ? 1.5 : 0} alignItems=\"center\" {...props}>\n <FlexRow gap={1}>\n <XnsEstimateNameTextField\n autoFocus={autoFocus}\n label=\"xNS Name\"\n variant=\"outlined\"\n size=\"small\"\n value={xnsName ?? ''}\n onKeyDown={onKeyDown}\n onChange={handleChange}\n onBlur={handleChange}\n />\n <ButtonEx\n disabled={captureDisabled}\n variant=\"contained\"\n color=\"success\"\n endIcon={<KeyboardArrowRightRounded />}\n onClick={onCaptureName}\n >\n {isMobile ? mobileButtonText : buttonText}\n </ButtonEx>\n </FlexRow>\n {(showSecondary === true)\n ? (\n <XnsCaptureSecondaryLink\n xnsName={xnsName}\n placement={placement}\n funnel={funnel}\n setError={setError}\n />\n )\n : null}\n {\n // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary\n showSecondary ? showSecondary : null\n }\n {children}\n <XnsNameCaptureErrors error={error} errorUi={errorUi} resetError={() => setError(undefined)} />\n </FlexCol>\n )\n}\n","import React, { useMemo } from 'react'\n\nimport { useXnsNameCaptureProviders, useXnsNameCaptureRouting } from './hooks/index.ts'\nimport type { XnsNameCaptureProps } from './Props.ts'\nimport { XnsNameCapture } from './XnsNameCapture.tsx'\n\nexport const XnsNameCaptureWithContext: React.FC<XnsNameCaptureProps> = (props) => {\n const routingProps = useXnsNameCaptureRouting(props)\n const providersProps = useXnsNameCaptureProviders(routingProps)\n\n const updatedProps = useMemo<XnsNameCaptureProps>(() => ({\n ...props,\n ...routingProps,\n ...providersProps,\n }), [providersProps])\n\n return (\n <XnsNameCapture {...updatedProps} />\n )\n}\n"],"mappings":"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","names":["alpha","TextField","useTheme","MIN_DOMAIN_LENGTH","XnsNameHelper","React","useState","XnsEstimateNameTextField","maskOutput","onChange","onChangeProp","onBlur","onBlurProp","props","theme","useTheme","validLength","setValidLength","useState","inputRef","React","useRef","handleChange","event","value","target","XnsNameHelper","mask","current","length","MIN_DOMAIN_LENGTH","handleBlur","maskStartEndHyphens","TextField","inputProps","style","color","palette","text","primary","alpha","Alert","Snackbar","useMediaQuery","useTheme","FlexRow","React","XnsNameCaptureErrors","error","errorUi","resetError","theme","useTheme","isMobile","useMediaQuery","breakpoints","down","React","Snackbar","open","message","toString","autoHideDuration","onClose","anchorOrigin","vertical","horizontal","Alert","severity","sx","width","display","undefined","visibility","FlexRow","alignSelf","useMixpanel","useMemo","useXnsNameCaptureProviders","props","mixpanel","useMixpanel","useMemo","useMemo","useNavigate","useSearchParams","useXnsNameCaptureRouting","props","params","useSearchParams","signatureParam","get","signatureParamString","encodeURIComponent","navigate","useNavigate","useMemo","to","paramsString","ArrowForwardRounded","Stack","LinkEx","XnsNameHelper","React","XnsCaptureSecondaryLink","event","funnel","mixpanel","navigate","onCaptureName","paramsString","placement","setError","text","to","userEvents","xnsName","props","React","LinkEx","paddingX","color","style","textDecoration","textUnderlineOffset","onClick","track","Funnel","Placement","formattedXnsName","helper","XnsNameHelper","fromString","valid","errors","validate","userClick","elementName","elementType","Error","join","Stack","flexDirection","gap","alignItems","sx","cursor","ArrowForwardRounded","KeyboardArrowRightRounded","useMediaQuery","useTheme","ButtonEx","FlexCol","FlexRow","MIN_DOMAIN_LENGTH","XnsNameHelper","React","useCallback","useState","XnsNameCapture","autoFocus","buttonText","children","defaultXnsName","errorUi","event","funnel","mixpanel","mobileButtonText","navigate","onCaptureName","onCaptureNameProp","paramsString","placement","showSecondary","to","userEvents","props","xnsName","setXnsName","useState","error","setError","theme","useTheme","isMobile","useMediaQuery","breakpoints","down","captureDisabled","length","MIN_DOMAIN_LENGTH","handleChange","NsName","XnsNameHelper","mask","target","value","undefined","useCallback","track","Funnel","Placement","formattedXnsName","helper","fromString","valid","errors","validate","userClick","elementName","elementType","Error","join","onKeyDown","key","React","FlexCol","gap","alignItems","FlexRow","XnsEstimateNameTextField","label","variant","size","onChange","onBlur","ButtonEx","disabled","color","endIcon","KeyboardArrowRightRounded","onClick","XnsCaptureSecondaryLink","XnsNameCaptureErrors","resetError","React","useMemo","XnsNameCaptureWithContext","props","routingProps","useXnsNameCaptureRouting","providersProps","useXnsNameCaptureProviders","updatedProps","useMemo","React","XnsNameCapture"]}
1
+ {"version":3,"sources":["../../src/components/EstimateName/EstimateNameTextField.tsx","../../src/components/XnsNameCapture/Errors.tsx","../../src/components/XnsNameCapture/hooks/routing/useXnsNameCaptureRouting.ts","../../src/components/XnsNameCapture/hooks/routing/useXnsNameFromLocation.ts","../../src/components/XnsNameCapture/hooks/useXnsNameCaptureProviders.ts","../../src/components/XnsNameCapture/SecondaryLink.tsx","../../src/components/XnsNameCapture/XnsNameCapture.tsx","../../src/components/XnsNameCapture/XnsNameCaptureWithContext.tsx"],"sourcesContent":["import type { StandardTextFieldProps, TextFieldProps } from '@mui/material'\nimport {\n alpha, TextField, useTheme,\n} from '@mui/material'\nimport { MIN_DOMAIN_LENGTH, XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport React, { useState } from 'react'\n\nexport interface XnsEstimateNameTextFieldProps {\n maskOutput?: boolean\n}\n\nexport const XnsEstimateNameTextField: React.FC<XnsEstimateNameTextFieldProps & TextFieldProps> = ({\n maskOutput = true, onChange: onChangeProp, onBlur: onBlurProp, ...props\n}) => {\n const theme = useTheme()\n const [validLength, setValidLength] = useState(false)\n\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n // override onChange to mask the input and update the event value\n const handleChange: StandardTextFieldProps['onChange'] = (event) => {\n if (maskOutput) {\n const value = event.target.value\n event.target.value = XnsNameHelper.mask(value)\n }\n onChangeProp?.(event)\n\n if (inputRef.current) {\n setValidLength(inputRef.current.value.length >= MIN_DOMAIN_LENGTH)\n }\n }\n\n const handleBlur: StandardTextFieldProps['onBlur'] = (event) => {\n if (maskOutput) {\n const value = event.target.value\n event.target.value = XnsNameHelper.mask(value, { maskStartEndHyphens: true })\n }\n onBlurProp?.(event)\n }\n\n return (\n <TextField\n inputProps={{ style: { color: validLength ? theme.palette.text.primary : alpha(theme.palette.text.primary, 0.5) } }}\n inputRef={inputRef}\n onBlur={handleBlur}\n onChange={handleChange}\n {...props}\n />\n )\n}\n","import {\n Alert, Snackbar, useMediaQuery, useTheme,\n} from '@mui/material'\nimport { FlexRow } from '@xylabs/react-flexbox'\nimport React from 'react'\n\nexport interface XnsNameCaptureErrorsProps {\n error?: Error\n errorUi?: 'alert' | 'toast'\n resetError?: () => void\n}\n\nexport const XnsNameCaptureErrors: React.FC<XnsNameCaptureErrorsProps> = ({\n error, errorUi, resetError,\n}) => {\n const theme = useTheme()\n const isMobile = useMediaQuery(theme.breakpoints.down('md'))\n\n return (\n <>\n {(errorUi === 'toast')\n ? (\n <Snackbar\n open={!!error}\n message={error?.toString()}\n autoHideDuration={3000}\n onClose={() => resetError?.()}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert\n severity=\"error\"\n sx={{\n width: '100%', display: (isMobile && !error) ? 'none' : undefined, visibility: error ? 'visible' : 'hidden',\n }}\n >\n {error?.message}\n </Alert>\n </Snackbar>\n )\n : (() => {\n // setTimeout(() => setError(undefined), 1500)\n return (\n <FlexRow alignSelf=\"stretch\">\n <Alert\n severity=\"error\"\n sx={{ display: (isMobile && !error) ? 'none' : undefined, visibility: error ? 'visible' : 'hidden' }}\n >\n {error?.message}\n </Alert>\n </FlexRow>\n )\n })()}\n </>\n )\n}\n","import { useMemo } from 'react'\nimport { useNavigate, useSearchParams } from 'react-router-dom'\n\nimport type { XnsNameCaptureProps } from '../../Props.ts'\nimport { useXnsNameFromLocation } from './useXnsNameFromLocation.ts'\n\nexport const useXnsNameCaptureRouting = (props: XnsNameCaptureProps) => {\n const [params] = useSearchParams()\n const signatureParam = params.get('signature')\n const signatureParamString = signatureParam ? `&signature=${encodeURIComponent(signatureParam)}` : ''\n\n const navigate = useNavigate()\n\n const [name, error] = useXnsNameFromLocation()\n\n return useMemo(() => ({\n ...props,\n defaultXnsName: name,\n routingError: error,\n navigate: props.navigate ?? ((to: string) => navigate(to)),\n paramsString: signatureParamString,\n }), [props, signatureParamString])\n}\n","import { useLocation } from 'react-router-dom'\n\n/**\n * Assumes the user was redirected with a link that contains a username query parameter.\n * @returns The xNS name from the URI username query parameter.\n */\nexport const useXnsNameFromLocation = (): [name: string | undefined, error: Error | undefined] => {\n const location = useLocation()\n const search = new URLSearchParams(location.search)\n const rawName = (search.get('xnsname') ?? search.get('name') ?? search.get('username') ?? '').toLowerCase()\n switch (rawName?.split('.').length) {\n case 1: {\n return [rawName, undefined]\n }\n case 2: {\n const rawNameParts = rawName.split('.')\n if (rawNameParts[1] !== 'xyo') {\n return [, new Error('Invalid xNS name [Bad root]')]\n }\n return [rawNameParts[0], undefined]\n }\n default: {\n return [, new Error('Invalid xNS name [Too many parts]')]\n }\n }\n}\n","import { useMixpanel } from '@xylabs/react-mixpanel'\nimport { useMemo } from 'react'\n\nimport type { XnsNameCaptureProps } from '../Props.ts'\n\nexport const useXnsNameCaptureProviders = (props: XnsNameCaptureProps) => {\n const mixpanel = useMixpanel()\n\n return useMemo(() => ({\n ...props,\n mixpanel: props.mixpanel ?? mixpanel,\n }), [props, mixpanel])\n}\n","import { ArrowForwardRounded } from '@mui/icons-material'\nimport { Stack } from '@mui/material'\nimport type { LinkExProps } from '@xylabs/react-link'\nimport { LinkEx } from '@xylabs/react-link'\nimport { XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport type { Dispatch } from 'react'\nimport React from 'react'\n\nimport type {\n XnsNameCaptureBuyCallbacks, XnsNameCaptureRoutingProps, XnsNameCaptureTrackingProps,\n} from './Props.ts'\n\nexport interface XnsCaptureSecondaryLinkProps extends XnsNameCaptureTrackingProps, XnsNameCaptureRoutingProps, XnsNameCaptureBuyCallbacks, LinkExProps {\n event?: string\n funnel?: string\n placement?: string\n setError?: Dispatch<Error | undefined>\n text?: string\n xnsName: string\n}\n\nexport const XnsCaptureSecondaryLink: React.FC<XnsCaptureSecondaryLinkProps> = ({\n event = 'Click to Reservation',\n funnel = 'xns',\n mixpanel,\n navigate,\n onCaptureName,\n paramsString = '',\n placement = '',\n setError,\n text = 'Or make a free reservation',\n to = '/xns/reservation',\n userEvents,\n xnsName,\n ...props\n}) => {\n return (\n <LinkEx\n paddingX={0}\n color=\"inherit\"\n style={{ textDecoration: 'underline', textUnderlineOffset: '5px' }}\n onClick={async () => {\n mixpanel?.track(event, {\n Funnel: funnel,\n Placement: placement,\n })\n const formattedXnsName = `${xnsName}.xyo`\n const helper = XnsNameHelper.fromString(formattedXnsName)\n const [valid, errors] = await helper.validate()\n if (valid) {\n await userEvents?.userClick({ elementName: event, elementType: 'xns-cta' })\n navigate?.(`${to}?username=${xnsName}${paramsString}`)\n await onCaptureName?.(xnsName)\n } else {\n setError?.(new Error(errors.join(', ')))\n }\n }}\n {...props}\n >\n <Stack flexDirection=\"row\" gap={0.5} alignItems=\"center\" sx={{ cursor: 'pointer' }}>\n {text}\n <ArrowForwardRounded />\n </Stack>\n </LinkEx>\n )\n}\n","import { KeyboardArrowRightRounded } from '@mui/icons-material'\nimport type { StandardTextFieldProps } from '@mui/material'\nimport { useMediaQuery, useTheme } from '@mui/material'\nimport { ButtonEx } from '@xylabs/react-button'\nimport { FlexCol, FlexRow } from '@xylabs/react-flexbox'\nimport { MIN_DOMAIN_LENGTH, XnsNameHelper } from '@xyo-network/xns-record-payloadset-plugins'\nimport type { KeyboardEventHandler } from 'react'\nimport React, { useCallback, useState } from 'react'\n\nimport { XnsEstimateNameTextField } from '../EstimateName/index.ts'\nimport { XnsNameCaptureErrors } from './Errors.tsx'\nimport type { XnsNameCaptureProps } from './Props.ts'\nimport { XnsCaptureSecondaryLink } from './SecondaryLink.js'\n\nexport const XnsNameCapture: React.FC<XnsNameCaptureProps> = ({\n autoFocus = false,\n buttonText = 'Buy My Name',\n children,\n defaultXnsName,\n errorUi = 'alert',\n event = 'Click to Checkout',\n funnel = 'xns',\n mixpanel,\n mobileButtonText = 'Buy',\n navigate,\n onCaptureName: onCaptureNameProp,\n paramsString = '',\n placement = '',\n routingError,\n showSecondary = false,\n to = '/xns/estimation',\n userEvents,\n ...props\n}) => {\n const [xnsName, setXnsName] = useState<string>(() => defaultXnsName ?? '')\n const [error, setError] = useState<Error | undefined>(routingError)\n\n const theme = useTheme()\n const isMobile = useMediaQuery(theme.breakpoints.down('md'))\n\n const captureDisabled = !xnsName || xnsName.length < MIN_DOMAIN_LENGTH\n\n const handleChange: StandardTextFieldProps['onChange'] = (event) => {\n const NsName = XnsNameHelper.mask(event.target.value)\n setXnsName(NsName)\n setError(undefined)\n }\n\n const onCaptureName = useCallback(async () => {\n if (captureDisabled) return\n mixpanel?.track(event, {\n Funnel: funnel,\n Placement: placement,\n })\n const formattedXnsName = `${xnsName}.xyo`\n const helper = XnsNameHelper.fromString(formattedXnsName)\n const [valid, errors] = await helper.validate()\n if (valid) {\n await userEvents?.userClick({ elementName: event, elementType: 'xns-cta' })\n await onCaptureNameProp?.(xnsName)\n navigate?.(`${to}?username=${xnsName}${paramsString}`)\n } else {\n setError(new Error(errors.join(', ')))\n }\n }, [event, funnel, mixpanel, paramsString, placement, to, userEvents, xnsName])\n\n const onKeyDown: KeyboardEventHandler<HTMLDivElement> = useCallback(async (event) => {\n if (event.key === 'Enter' && !captureDisabled) {\n await onCaptureName?.()\n }\n }, [captureDisabled, onCaptureName])\n\n return (\n <FlexCol gap={showSecondary ? 1.5 : 0} alignItems=\"center\" {...props}>\n <FlexRow gap={1}>\n <XnsEstimateNameTextField\n autoFocus={autoFocus}\n label=\"xNS Name\"\n variant=\"outlined\"\n size=\"small\"\n value={xnsName ?? ''}\n onKeyDown={onKeyDown}\n onChange={handleChange}\n onBlur={handleChange}\n />\n <ButtonEx\n disabled={captureDisabled}\n variant=\"contained\"\n color=\"success\"\n endIcon={<KeyboardArrowRightRounded />}\n onClick={onCaptureName}\n >\n {isMobile ? mobileButtonText : buttonText}\n </ButtonEx>\n </FlexRow>\n {(showSecondary === true)\n ? (\n <XnsCaptureSecondaryLink\n xnsName={xnsName}\n placement={placement}\n funnel={funnel}\n setError={setError}\n />\n )\n : null}\n {\n // eslint-disable-next-line unicorn/prefer-logical-operator-over-ternary\n showSecondary ? showSecondary : null\n }\n {children}\n <XnsNameCaptureErrors error={error} errorUi={errorUi} resetError={() => setError(undefined)} />\n </FlexCol>\n )\n}\n","import React, { useMemo } from 'react'\n\nimport { useXnsNameCaptureProviders, useXnsNameCaptureRouting } from './hooks/index.ts'\nimport type { XnsNameCaptureProps } from './Props.ts'\nimport { XnsNameCapture } from './XnsNameCapture.tsx'\n\nexport const XnsNameCaptureWithContext: React.FC<XnsNameCaptureProps> = (props) => {\n const routingProps = useXnsNameCaptureRouting(props)\n const providersProps = useXnsNameCaptureProviders(routingProps)\n\n const updatedProps = useMemo<XnsNameCaptureProps>(() => ({\n ...props,\n ...routingProps,\n ...providersProps,\n }), [providersProps])\n\n return (\n <XnsNameCapture {...updatedProps} />\n )\n}\n"],"mappings":"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","names":["alpha","TextField","useTheme","MIN_DOMAIN_LENGTH","XnsNameHelper","React","useState","XnsEstimateNameTextField","maskOutput","onChange","onChangeProp","onBlur","onBlurProp","props","theme","useTheme","validLength","setValidLength","useState","inputRef","React","useRef","handleChange","event","value","target","XnsNameHelper","mask","current","length","MIN_DOMAIN_LENGTH","handleBlur","maskStartEndHyphens","TextField","inputProps","style","color","palette","text","primary","alpha","Alert","Snackbar","useMediaQuery","useTheme","FlexRow","React","XnsNameCaptureErrors","error","errorUi","resetError","theme","useTheme","isMobile","useMediaQuery","breakpoints","down","React","Snackbar","open","message","toString","autoHideDuration","onClose","anchorOrigin","vertical","horizontal","Alert","severity","sx","width","display","undefined","visibility","FlexRow","alignSelf","useMemo","useNavigate","useSearchParams","useLocation","useXnsNameFromLocation","location","useLocation","search","URLSearchParams","rawName","get","toLowerCase","split","length","undefined","rawNameParts","Error","useXnsNameCaptureRouting","props","params","useSearchParams","signatureParam","get","signatureParamString","encodeURIComponent","navigate","useNavigate","name","error","useXnsNameFromLocation","useMemo","defaultXnsName","routingError","to","paramsString","useMixpanel","useMemo","useXnsNameCaptureProviders","props","mixpanel","useMixpanel","useMemo","ArrowForwardRounded","Stack","LinkEx","XnsNameHelper","React","XnsCaptureSecondaryLink","event","funnel","mixpanel","navigate","onCaptureName","paramsString","placement","setError","text","to","userEvents","xnsName","props","React","LinkEx","paddingX","color","style","textDecoration","textUnderlineOffset","onClick","track","Funnel","Placement","formattedXnsName","helper","XnsNameHelper","fromString","valid","errors","validate","userClick","elementName","elementType","Error","join","Stack","flexDirection","gap","alignItems","sx","cursor","ArrowForwardRounded","KeyboardArrowRightRounded","useMediaQuery","useTheme","ButtonEx","FlexCol","FlexRow","MIN_DOMAIN_LENGTH","XnsNameHelper","React","useCallback","useState","XnsNameCapture","autoFocus","buttonText","children","defaultXnsName","errorUi","event","funnel","mixpanel","mobileButtonText","navigate","onCaptureName","onCaptureNameProp","paramsString","placement","routingError","showSecondary","to","userEvents","props","xnsName","setXnsName","useState","error","setError","theme","useTheme","isMobile","useMediaQuery","breakpoints","down","captureDisabled","length","MIN_DOMAIN_LENGTH","handleChange","NsName","XnsNameHelper","mask","target","value","undefined","useCallback","track","Funnel","Placement","formattedXnsName","helper","fromString","valid","errors","validate","userClick","elementName","elementType","Error","join","onKeyDown","key","React","FlexCol","gap","alignItems","FlexRow","XnsEstimateNameTextField","label","variant","size","onChange","onBlur","ButtonEx","disabled","color","endIcon","KeyboardArrowRightRounded","onClick","XnsCaptureSecondaryLink","XnsNameCaptureErrors","resetError","React","useMemo","XnsNameCaptureWithContext","props","routingProps","useXnsNameCaptureRouting","providersProps","useXnsNameCaptureProviders","updatedProps","useMemo","React","XnsNameCapture"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/react-xns",
3
- "version": "3.0.12",
3
+ "version": "3.0.13",
4
4
  "description": "Common React library for all XYO projects that use React",
5
5
  "keywords": [
6
6
  "xyo",
@@ -59,7 +59,7 @@
59
59
  "@types/mixpanel-browser": "^2.50.0",
60
60
  "@xylabs/ts-scripts-yarn3": "^4.0.7",
61
61
  "@xylabs/tsconfig-react": "^4.0.7",
62
- "@xyo-network/react-storybook": "^3.0.12",
62
+ "@xyo-network/react-storybook": "^3.0.13",
63
63
  "react": "^18.3.1",
64
64
  "react-dom": "^18.3.1",
65
65
  "react-router-dom": "^6.26.1",
@@ -24,6 +24,7 @@ export interface XnsNameCaptureTrackingProps {
24
24
  export interface XnsNameCaptureRoutingProps {
25
25
  navigate?: (to: string) => void
26
26
  paramsString?: string
27
+ routingError?: Error
27
28
  to?: To
28
29
  }
29
30
 
@@ -26,13 +26,14 @@ export const XnsNameCapture: React.FC<XnsNameCaptureProps> = ({
26
26
  onCaptureName: onCaptureNameProp,
27
27
  paramsString = '',
28
28
  placement = '',
29
+ routingError,
29
30
  showSecondary = false,
30
31
  to = '/xns/estimation',
31
32
  userEvents,
32
33
  ...props
33
34
  }) => {
34
35
  const [xnsName, setXnsName] = useState<string>(() => defaultXnsName ?? '')
35
- const [error, setError] = useState<Error | undefined>()
36
+ const [error, setError] = useState<Error | undefined>(routingError)
36
37
 
37
38
  const theme = useTheme()
38
39
  const isMobile = useMediaQuery(theme.breakpoints.down('md'))
@@ -1,4 +1,6 @@
1
- import type { Meta, StoryFn } from '@storybook/react'
1
+ import type {
2
+ Decorator, Meta, StoryFn,
3
+ } from '@storybook/react'
2
4
  import React from 'react'
3
5
  import type { To } from 'react-router-dom'
4
6
  import { BrowserRouter } from 'react-router-dom'
@@ -7,15 +9,28 @@ import { XnsNameCaptureWithContext } from './XnsNameCaptureWithContext.tsx'
7
9
 
8
10
  export default { title: 'modules/xns/XnsNameCaptureWithContext' } as Meta
9
11
 
10
- const Template: StoryFn<typeof XnsNameCaptureWithContext> = (args) => {
11
- // Get the current URL
12
+ const testableParams = ['signature', 'username'] as const
13
+ type RouteDecorator = (params: [typeof testableParams[number], string][]) => Decorator
14
+
15
+ // eslint-disable-next-line react/display-name
16
+ const RouteDecorator: RouteDecorator = params => (Story, args) => {
17
+ // Get the URL object
12
18
  const url = new URL(window.location.href)
13
19
 
14
- // Update or add the URL parameter
15
- url.searchParams.set('signature', '0x1234567890abcdef')
20
+ // Remove all stale testable params from the URL
21
+ for (const param of testableParams) url.searchParams.delete(param)
22
+ window.history.replaceState({}, '', url)
23
+
24
+ // Add the new testable params to the URL
25
+ for (const [param, value] of params) url.searchParams.set(param, value)
16
26
 
17
- // Update the URL without reloading the page
27
+ // Replace the URL without reloading
18
28
  window.history.replaceState({}, '', url)
29
+
30
+ return <Story {...args} />
31
+ }
32
+
33
+ const Template: StoryFn<typeof XnsNameCaptureWithContext> = (args) => {
19
34
  return (
20
35
  <BrowserRouter>
21
36
  <XnsNameCaptureWithContext {...args}></XnsNameCaptureWithContext>
@@ -24,9 +39,20 @@ const Template: StoryFn<typeof XnsNameCaptureWithContext> = (args) => {
24
39
  }
25
40
 
26
41
  const Default = Template.bind({})
42
+ Default.decorators = [RouteDecorator([['signature', '0x1234567890abcdef']])]
27
43
  Default.args = {}
28
44
 
29
- const WithOnBuyName = Template.bind({})
30
- WithOnBuyName.args = { navigate: (to: To) => alert(`navigated to: ${to}`), onCaptureName: (name: string) => Promise.resolve(alert(`Buy Name: ${name}`)) }
45
+ const WithOnCaptureName = Template.bind({})
46
+ WithOnCaptureName.decorators = [RouteDecorator([['signature', '0x1234567890abcdef']])]
47
+ WithOnCaptureName.args = { navigate: (to: To) => alert(`navigated to: ${to}`), onCaptureName: (name: string) => Promise.resolve(alert(`Buy Name: ${name}`)) }
31
48
 
32
- export { Default, WithOnBuyName }
49
+ const WithBadXnsNameInRoute = Template.bind({})
50
+ WithBadXnsNameInRoute.decorators = [RouteDecorator([['signature', '0x1234567890abcdef'], ['username', 'badname.xyo.xyo']])]
51
+ WithBadXnsNameInRoute.args = {
52
+ navigate: (to: To) => alert(`navigated to: ${to}`),
53
+ onCaptureName: (name: string) => Promise.resolve(alert(`Buy Name: ${name}`)),
54
+ }
55
+
56
+ export {
57
+ Default, WithBadXnsNameInRoute, WithOnCaptureName,
58
+ }
@@ -1,2 +1,2 @@
1
+ export * from './routing/index.ts'
1
2
  export * from './useXnsNameCaptureProviders.ts'
2
- export * from './useXnsNameCaptureRouting.ts'
@@ -0,0 +1,2 @@
1
+ export * from './useXnsNameCaptureRouting.ts'
2
+ export * from './useXnsNameFromLocation.ts'
@@ -1,7 +1,8 @@
1
1
  import { useMemo } from 'react'
2
2
  import { useNavigate, useSearchParams } from 'react-router-dom'
3
3
 
4
- import type { XnsNameCaptureProps } from '../Props.ts'
4
+ import type { XnsNameCaptureProps } from '../../Props.ts'
5
+ import { useXnsNameFromLocation } from './useXnsNameFromLocation.ts'
5
6
 
6
7
  export const useXnsNameCaptureRouting = (props: XnsNameCaptureProps) => {
7
8
  const [params] = useSearchParams()
@@ -10,8 +11,12 @@ export const useXnsNameCaptureRouting = (props: XnsNameCaptureProps) => {
10
11
 
11
12
  const navigate = useNavigate()
12
13
 
14
+ const [name, error] = useXnsNameFromLocation()
15
+
13
16
  return useMemo(() => ({
14
17
  ...props,
18
+ defaultXnsName: name,
19
+ routingError: error,
15
20
  navigate: props.navigate ?? ((to: string) => navigate(to)),
16
21
  paramsString: signatureParamString,
17
22
  }), [props, signatureParamString])
@@ -0,0 +1,26 @@
1
+ import { useLocation } from 'react-router-dom'
2
+
3
+ /**
4
+ * Assumes the user was redirected with a link that contains a username query parameter.
5
+ * @returns The xNS name from the URI username query parameter.
6
+ */
7
+ export const useXnsNameFromLocation = (): [name: string | undefined, error: Error | undefined] => {
8
+ const location = useLocation()
9
+ const search = new URLSearchParams(location.search)
10
+ const rawName = (search.get('xnsname') ?? search.get('name') ?? search.get('username') ?? '').toLowerCase()
11
+ switch (rawName?.split('.').length) {
12
+ case 1: {
13
+ return [rawName, undefined]
14
+ }
15
+ case 2: {
16
+ const rawNameParts = rawName.split('.')
17
+ if (rawNameParts[1] !== 'xyo') {
18
+ return [, new Error('Invalid xNS name [Bad root]')]
19
+ }
20
+ return [rawNameParts[0], undefined]
21
+ }
22
+ default: {
23
+ return [, new Error('Invalid xNS name [Too many parts]')]
24
+ }
25
+ }
26
+ }