@saasquatch/mint-components 2.1.8-21 → 2.1.8-22

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 (42) hide show
  1. package/dist/cjs/sqm-share-link.cjs.entry.js +271 -0
  2. package/dist/cjs/sqm-stencilbook.cjs.entry.js +1144 -588
  3. package/dist/cjs/useShareLink-1282123e.js +422 -0
  4. package/dist/cjs/useShareLink-3c22b1b9.js +448 -0
  5. package/dist/cjs/useShareLink-54e24928.js +448 -0
  6. package/dist/cjs/useShareLink-b664fbc7.js +450 -0
  7. package/dist/cjs/useShareLink-bf04b25c.js +450 -0
  8. package/dist/cjs/useShareLink-e8e2ae6d.js +448 -0
  9. package/dist/collection/components/sqm-share-link/sqm-share-link-view.js +2 -28
  10. package/dist/esm/sqm-share-link.entry.js +267 -0
  11. package/dist/esm/sqm-stencilbook.entry.js +3327 -2771
  12. package/dist/esm/useShareLink-023284f3.js +445 -0
  13. package/dist/esm/useShareLink-436e9cad.js +445 -0
  14. package/dist/esm/useShareLink-4ba01373.js +447 -0
  15. package/dist/esm/useShareLink-79056582.js +445 -0
  16. package/dist/esm/useShareLink-a3329e33.js +419 -0
  17. package/dist/esm/useShareLink-bc20ec4c.js +447 -0
  18. package/dist/esm-es5/sqm-share-link.entry.js +1 -0
  19. package/dist/esm-es5/sqm-stencilbook.entry.js +1 -1
  20. package/dist/esm-es5/useShareLink-023284f3.js +1 -0
  21. package/dist/esm-es5/useShareLink-436e9cad.js +1 -0
  22. package/dist/esm-es5/useShareLink-4ba01373.js +1 -0
  23. package/dist/esm-es5/useShareLink-79056582.js +1 -0
  24. package/dist/esm-es5/useShareLink-a3329e33.js +1 -0
  25. package/dist/esm-es5/useShareLink-bc20ec4c.js +1 -0
  26. package/dist/mint-components/sqm-share-link.entry.js +267 -0
  27. package/dist/mint-components/sqm-share-link.system.entry.js +1 -0
  28. package/dist/mint-components/sqm-stencilbook.entry.js +22106 -0
  29. package/dist/mint-components/sqm-stencilbook.system.entry.js +1 -0
  30. package/dist/mint-components/useShareLink-023284f3.js +445 -0
  31. package/dist/mint-components/useShareLink-1d7c9fd8.system.js +1 -0
  32. package/dist/mint-components/useShareLink-211e061c.system.js +1 -0
  33. package/dist/mint-components/useShareLink-2de7ffce.system.js +1 -0
  34. package/dist/mint-components/useShareLink-436e9cad.js +445 -0
  35. package/dist/mint-components/useShareLink-454939f5.system.js +1 -0
  36. package/dist/mint-components/useShareLink-4ba01373.js +447 -0
  37. package/dist/mint-components/useShareLink-79056582.js +445 -0
  38. package/dist/mint-components/useShareLink-a3329e33.js +419 -0
  39. package/dist/mint-components/useShareLink-bc20ec4c.js +447 -0
  40. package/dist/mint-components/useShareLink-c05fe151.system.js +1 -0
  41. package/dist/mint-components/useShareLink-cb5abd96.system.js +1 -0
  42. package/package.json +1 -1
@@ -0,0 +1,422 @@
1
+ 'use strict';
2
+
3
+ const index = require('./index-fd67d7bc.js');
4
+ const global = require('./global-746daf93.js');
5
+ const domContextHooks_module = require('./dom-context-hooks.module-224e09d4.js');
6
+ const index_module = require('./index.module-c79bd5b0.js');
7
+ const JSS = require('./JSS-518e9b4d.js');
8
+ const useReferralCodes = require('./useReferralCodes-4304f68f.js');
9
+ const copyTextView = require('./copy-text-view-fd17b89a.js');
10
+
11
+ const vanillaStyle = `
12
+ :host {
13
+ display: block;
14
+ width: 100%;
15
+ }
16
+ `;
17
+ function ShareLinkView(props) {
18
+ const { copyTextViewProps, customizeUrl, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, } = props;
19
+ const style = {
20
+ Container: {
21
+ display: "flex",
22
+ flexDirection: "column",
23
+ gap: "var(--sl-spacing-xx-small)",
24
+ width: "100%",
25
+ },
26
+ CustomizeLinkText: {
27
+ margin: "0",
28
+ fontSize: "var(--sl-font-size-small)",
29
+ fontWeight: "600",
30
+ cursor: "pointer",
31
+ color: "var(--sl-color-neutral-900)",
32
+ textAlign: "left",
33
+ padding: "var(--sl-spacing-small)",
34
+ "&:hover": {
35
+ textDecoration: "underline",
36
+ },
37
+ },
38
+ CustomizeLinkDisabled: {
39
+ margin: "0",
40
+ fontSize: "var(--sl-font-size-small)",
41
+ fontWeight: "600",
42
+ color: "var(--sl-color-neutral-400)",
43
+ cursor: "default",
44
+ textAlign: "left",
45
+ padding: "var(--sl-spacing-small)",
46
+ },
47
+ EditContainer: {
48
+ display: "flex",
49
+ flexDirection: "column",
50
+ gap: "var(--sl-spacing-x-small)",
51
+ width: "100%",
52
+ },
53
+ EditInputWrapper: {
54
+ display: "flex",
55
+ alignItems: "center",
56
+ width: "100%",
57
+ border: "var(--sqm-border-thickness, 1px) solid var(--sqm-input-border-color, #d1d5db)",
58
+ borderRadius: "var(--sqm-border-radius-normal, 4px)",
59
+ background: "var(--sqm-input-background, #fff)",
60
+ overflow: "hidden",
61
+ "&:focus-within": {
62
+ borderColor: "#999999",
63
+ boxShadow: "0 0 0 var(--sl-focus-ring-width) var(--sl-input-focus-ring-color)",
64
+ },
65
+ },
66
+ DomainPrefix: {
67
+ padding: "0 0 0 var(--sl-spacing-medium)",
68
+ fontSize: "var(--sl-font-size-medium)",
69
+ color: "var(--sl-color-neutral-500)",
70
+ whiteSpace: "nowrap",
71
+ userSelect: "none",
72
+ lineHeight: "var(--sl-input-height-medium)",
73
+ },
74
+ EditInput: {
75
+ flex: "1",
76
+ border: "none",
77
+ outline: "none",
78
+ padding: "0 var(--sl-spacing-medium) 0 0",
79
+ fontSize: "var(--sl-font-size-medium)",
80
+ fontFamily: "var(--sl-font-sans)",
81
+ color: "var(--sl-input-color)",
82
+ background: "transparent",
83
+ lineHeight: "var(--sl-input-height-medium)",
84
+ minWidth: "0",
85
+ },
86
+ EditLabel: {
87
+ margin: "0",
88
+ fontSize: "var(--sl-font-size-small)",
89
+ color: "var(--sl-color-neutral-500)",
90
+ },
91
+ HelperText: {
92
+ margin: "0",
93
+ fontSize: "var(--sl-font-size-small)",
94
+ color: "var(--sl-color-neutral-500)",
95
+ },
96
+ ErrorText: {
97
+ margin: "0",
98
+ fontSize: "var(--sl-font-size-small)",
99
+ color: "var(--sqm-danger-color-text, #dc2626)",
100
+ },
101
+ ActionRow: {
102
+ display: "flex",
103
+ gap: "var(--sl-spacing-medium)",
104
+ alignItems: "center",
105
+ },
106
+ LimitReachedContainer: {
107
+ display: "flex",
108
+ alignItems: "center",
109
+ gap: "var(--sl-spacing-x-small)",
110
+ },
111
+ };
112
+ const sheet = JSS.createStyleSheet(style);
113
+ const styleString = sheet.toString();
114
+ const errorMessageType = (validationError === null || validationError === void 0 ? void 0 : validationError.code) === "EXISTING_CODE_CONFLICT" ? "info" : "warning";
115
+ const showCharactersRemaining = charactersRemaining <= 14;
116
+ console.log(customizeUrl, limitReached, customizeDisabled, validationError, "customize URL state");
117
+ // Editing state
118
+ if (isEditing) {
119
+ return (index.h("div", { class: sheet.classes.Container },
120
+ index.h("style", { type: "text/css" },
121
+ styleString,
122
+ vanillaStyle),
123
+ index.h("p", { class: sheet.classes.EditLabel }, "Enter your link"),
124
+ index.h("div", { class: sheet.classes.EditInputWrapper },
125
+ index.h("span", { class: sheet.classes.DomainPrefix }, domainPrefix),
126
+ index.h("input", { class: sheet.classes.EditInput, type: "text", value: editValue, onInput: (e) => onEditValueChange(e.target.value), onKeyDown: (e) => {
127
+ if (e.key === "/" || e.key === "@")
128
+ e.preventDefault();
129
+ }, disabled: isSaving, maxLength: characterLimit })),
130
+ index.h("p", { class: sheet.classes.HelperText },
131
+ editLimitText,
132
+ showCharactersRemaining &&
133
+ ` Characters remaining: ${charactersRemaining}`),
134
+ validationError && (index.h("sqm-form-message", { type: errorMessageType, style: { paddingBottom: "var(--sl-spacing-xx-small)" } },
135
+ index.h("p", { part: "alert-title" }, validationError.title),
136
+ validationError.description)),
137
+ isValidating && index.h("p", { class: sheet.classes.HelperText }, "Validating..."),
138
+ index.h("div", { class: sheet.classes.ActionRow },
139
+ index.h("sl-button", { type: "primary", onClick: onSave, disabled: isSaving ||
140
+ isValidating ||
141
+ !!validationError ||
142
+ !editValue ||
143
+ editValue.length < minCharacters }, isSaving ? "Saving..." : saveLabelText),
144
+ index.h("sl-button", { type: "secondary", onClick: onCancel, disabled: isSaving }, cancelLabelText))));
145
+ }
146
+ // Default / Customized / Limit reached states
147
+ return (index.h("div", { class: sheet.classes.Container },
148
+ index.h("style", { type: "text/css" },
149
+ styleString,
150
+ vanillaStyle),
151
+ index.h(copyTextView.CopyTextView, Object.assign({}, copyTextViewProps)),
152
+ customizeUrl &&
153
+ (customizeDisabled ? (index.h("sl-tooltip", { content: customizeDisabledTooltip, placement: "top", style: { display: "inline-block", width: "fit-content" } },
154
+ index.h("p", { class: sheet.classes.CustomizeLinkDisabled }, customizeLinkLabel))) : (index.h("div", { class: sheet.classes.LimitReachedContainer },
155
+ index.h("p", { class: limitReached
156
+ ? sheet.classes.CustomizeLinkDisabled
157
+ : sheet.classes.CustomizeLinkText, onClick: limitReached ? undefined : onCustomizeClick }, customizeLinkLabel),
158
+ customizeUrl && limitReached && (index.h("p", { class: sheet.classes.HelperText }, global.intl.formatMessage({
159
+ id: "editLimitReached",
160
+ defaultMessage: editLimitReachedText,
161
+ }, {
162
+ supportLink: (index.h("a", { target: "_blank", href: "https://help.impact.com/other/readme/get-help-and-support" }, supportLinkText)),
163
+ }))))))));
164
+ }
165
+
166
+ const MAX_EDITS = 5;
167
+ const CHARACTER_LIMIT = 15;
168
+ const MIN_CHARACTERS = 3;
169
+ const MessageLinkQuery = index_module.dist.gql `
170
+ query ($programId: ID) {
171
+ user: viewer {
172
+ ... on User {
173
+ shareLink(programId: $programId)
174
+ }
175
+ }
176
+ }
177
+ `;
178
+ const WIDGET_ENGAGEMENT_EVENT = index_module.dist.gql `
179
+ mutation loadEvent($eventMeta: UserAnalyticsEvent!) {
180
+ createUserAnalyticsEvent(eventMeta: $eventMeta)
181
+ }
182
+ `;
183
+ const ADD_SHARE_LINK_CODE = index_module.dist.gql `
184
+ mutation ($addShareLinkCodeInput: AddShareLinkCodeInput!) {
185
+ addShareLinkCode(addShareLinkCodeInput: $addShareLinkCodeInput) {
186
+ linkCode {
187
+ linkCode
188
+ shortUrl
189
+ referralCode {
190
+ code
191
+ }
192
+ }
193
+ }
194
+ }
195
+ `;
196
+ const VALIDATE_LINK_CODE = index_module.dist.gql `
197
+ query validateLinkCode($linkCode: String!) {
198
+ validateLinkCode(linkCode: $linkCode) {
199
+ valid
200
+ invalidReason
201
+ }
202
+ }
203
+ `;
204
+ const GET_LINK_DOMAIN = index_module.dist.gql `
205
+ query getLinkDomain {
206
+ tenantSettings {
207
+ primaryLinkDomain {
208
+ host
209
+ }
210
+ }
211
+ }
212
+ `;
213
+ const SHARE_LINK_EDIT_COUNT = index_module.dist.gql `
214
+ query shareLinkEditCount {
215
+ viewer {
216
+ ... on User {
217
+ shareLinkCodes {
218
+ totalCount
219
+ data {
220
+ isVanity
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ `;
227
+ function parseShareUrl(url) {
228
+ try {
229
+ const parsed = new URL(url);
230
+ return {
231
+ url: parsed.origin + parsed.pathname,
232
+ domain: parsed.origin + "/",
233
+ path: parsed.pathname.slice(1),
234
+ };
235
+ }
236
+ catch {
237
+ return { url, domain: url, path: "" };
238
+ }
239
+ }
240
+ function useShareLink(props) {
241
+ var _a, _b, _c, _d, _e, _f, _g;
242
+ const { programId = index_module.H() } = props;
243
+ const user = index_module.J();
244
+ const engagementMedium = index_module.B();
245
+ const contextData = index_module.Fn(useReferralCodes.REFERRAL_CODES_NAMESPACE);
246
+ const { data, refetch } = index_module.wn(MessageLinkQuery, { programId }, !(user === null || user === void 0 ? void 0 : user.jwt) || !!props.linkOverride || (contextData === null || contextData === void 0 ? void 0 : contextData.shareLink) !== undefined);
247
+ const [sendLoadEvent] = index_module.$e(WIDGET_ENGAGEMENT_EVENT);
248
+ const [setCopied] = index_module.$e(useReferralCodes.SET_CODE_COPIED);
249
+ const [addShareLinkCode, { loading: isSaving }] = index_module.$e(ADD_SHARE_LINK_CODE);
250
+ const [validateLinkCode] = index_module.Xe(VALIDATE_LINK_CODE);
251
+ const { refresh } = index_module.Qe();
252
+ const { data: linkDomainData } = index_module.wn(GET_LINK_DOMAIN, {}, !(user === null || user === void 0 ? void 0 : user.jwt) || !props.customizeUrl);
253
+ const { data: editCountData, refetch: refetchEditCount } = index_module.wn(SHARE_LINK_EDIT_COUNT, {}, !(user === null || user === void 0 ? void 0 : user.jwt) || !props.customizeUrl);
254
+ const { url: copyString, domain: domainPrefix, path: pathSuffix, } = parseShareUrl((_b = ((contextData === null || contextData === void 0 ? void 0 : contextData.shareLink) || ((_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.shareLink))) !== null && _b !== void 0 ? _b :
255
+ // Shown during loading
256
+ "...");
257
+ const [open, setOpen] = domContextHooks_module.useState(false);
258
+ const [isEditing, setIsEditing] = domContextHooks_module.useState(false);
259
+ const [editValue, setEditValue] = domContextHooks_module.useState("");
260
+ const [validationError, setValidationError] = domContextHooks_module.useState(null);
261
+ const [isValidating, setIsValidating] = domContextHooks_module.useState(false);
262
+ const debounceTimerRef = domContextHooks_module.useRef(undefined);
263
+ const hasPrimaryLinkDomain = ((_c = linkDomainData === null || linkDomainData === void 0 ? void 0 : linkDomainData.tenantSettings) === null || _c === void 0 ? void 0 : _c.primaryLinkDomain) != null;
264
+ const customizeDisabled = !hasPrimaryLinkDomain;
265
+ const vanityCount = (_g = (_f = (_e = (_d = editCountData === null || editCountData === void 0 ? void 0 : editCountData.viewer) === null || _d === void 0 ? void 0 : _d.shareLinkCodes) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.filter((code) => code.isVanity).length) !== null && _g !== void 0 ? _g : 0;
266
+ const editCount = vanityCount;
267
+ const editsRemaining = Math.max(0, MAX_EDITS - editCount);
268
+ const limitReached = editsRemaining <= 0;
269
+ function mapErrorCodeToInfo(errorCode) {
270
+ if (!errorCode)
271
+ return null;
272
+ const errorMap = {
273
+ EXISTING_CODE_CONFLICT: {
274
+ code: "EXISTING_CODE_CONFLICT",
275
+ title: props.existingCodeConflictErrorTitle,
276
+ description: props.existingCodeConflictErrorDescription,
277
+ },
278
+ INVALID_CHARACTER: {
279
+ code: "INVALID_CHARACTER",
280
+ title: props.invalidCharactersErrorTitle,
281
+ description: props.invalidCharactersErrorDescription,
282
+ },
283
+ BLOCKED_WORD: {
284
+ code: "BLOCKED_WORD",
285
+ title: props.profanityErrorTitle,
286
+ description: props.profanityErrorDescription,
287
+ },
288
+ };
289
+ return errorMap[errorCode];
290
+ }
291
+ async function onClick() {
292
+ if (contextData) {
293
+ await setCopied({ referralCode: contextData.referralCode });
294
+ contextData.refresh();
295
+ }
296
+ // Should well supported: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard#browser_compatibility
297
+ // Only if called from a user-initiated event
298
+ navigator.clipboard.writeText(copyString);
299
+ setOpen(true);
300
+ setTimeout(() => setOpen(false), props.tooltiplifespan);
301
+ sendLoadEvent({
302
+ eventMeta: {
303
+ programId,
304
+ id: user === null || user === void 0 ? void 0 : user.id,
305
+ accountId: user === null || user === void 0 ? void 0 : user.accountId,
306
+ type: "USER_REFERRAL_PROGRAM_ENGAGEMENT_EVENT",
307
+ meta: {
308
+ engagementMedium,
309
+ shareMedium: "DIRECT",
310
+ },
311
+ },
312
+ });
313
+ }
314
+ function onCustomizeClick() {
315
+ if (limitReached || customizeDisabled)
316
+ return;
317
+ setIsEditing(true);
318
+ setEditValue(editCount === 0 ? "" : pathSuffix);
319
+ setValidationError(null);
320
+ }
321
+ function onEditValueChange(value) {
322
+ const trimmed = value.slice(0, CHARACTER_LIMIT);
323
+ setEditValue(trimmed);
324
+ setValidationError(null);
325
+ if (debounceTimerRef.current)
326
+ clearTimeout(debounceTimerRef.current);
327
+ if (!trimmed || trimmed.length < MIN_CHARACTERS) {
328
+ setIsValidating(false);
329
+ return;
330
+ }
331
+ setIsValidating(true);
332
+ debounceTimerRef.current = setTimeout(async () => {
333
+ var _a, _b;
334
+ try {
335
+ const result = await validateLinkCode({ linkCode: trimmed });
336
+ if (!((_a = result === null || result === void 0 ? void 0 : result.validateLinkCode) === null || _a === void 0 ? void 0 : _a.valid)) {
337
+ const reason = (_b = result === null || result === void 0 ? void 0 : result.validateLinkCode) === null || _b === void 0 ? void 0 : _b.invalidReason;
338
+ console.log(reason, "validation error reason from validateLinkCode query");
339
+ setValidationError(mapErrorCodeToInfo(reason));
340
+ }
341
+ }
342
+ catch {
343
+ // Validation query failed — don't block the user
344
+ }
345
+ setIsValidating(false);
346
+ }, 2000);
347
+ }
348
+ async function onSave() {
349
+ var _a, _b;
350
+ if (!editValue ||
351
+ editValue.length < MIN_CHARACTERS ||
352
+ validationError ||
353
+ isValidating)
354
+ return;
355
+ try {
356
+ await addShareLinkCode({
357
+ addShareLinkCodeInput: {
358
+ userId: user === null || user === void 0 ? void 0 : user.id,
359
+ accountId: user === null || user === void 0 ? void 0 : user.accountId,
360
+ programId,
361
+ linkCode: editValue,
362
+ makeShareLinkCodePrimaryForReferralCode: true,
363
+ },
364
+ });
365
+ setIsEditing(false);
366
+ await Promise.all([refetch(), refetchEditCount()]);
367
+ refresh();
368
+ }
369
+ catch (e) {
370
+ const errorCode = (_a = e === null || e === void 0 ? void 0 : e.extensions) === null || _a === void 0 ? void 0 : _a.code;
371
+ console.log(errorCode, "errorCode from addSharelInkCodeMutation");
372
+ setValidationError((_b = mapErrorCodeToInfo(errorCode)) !== null && _b !== void 0 ? _b : {
373
+ code: null,
374
+ title: "Error",
375
+ description: (e === null || e === void 0 ? void 0 : e.message) || "Failed to save custom link. Please try again.",
376
+ });
377
+ }
378
+ }
379
+ function onCancel() {
380
+ setIsEditing(false);
381
+ setEditValue("");
382
+ setValidationError(null);
383
+ setIsValidating(false);
384
+ }
385
+ console.log(validationError, "validation error state"); // TEMP --- IGNORE ---
386
+ return {
387
+ copyTextViewProps: {
388
+ ...props,
389
+ onClick,
390
+ open,
391
+ copyString,
392
+ },
393
+ customizeUrl: props.customizeUrl,
394
+ customizeLinkLabel: props.customizeLinkLabel,
395
+ saveLabelText: props.saveLabelText,
396
+ cancelLabelText: props.cancelLabelText,
397
+ isEditing,
398
+ editValue,
399
+ domainPrefix,
400
+ editsRemaining,
401
+ maxEdits: MAX_EDITS,
402
+ limitReached,
403
+ validationError,
404
+ isValidating,
405
+ isSaving,
406
+ characterLimit: CHARACTER_LIMIT,
407
+ minCharacters: MIN_CHARACTERS,
408
+ charactersRemaining: CHARACTER_LIMIT - editValue.length,
409
+ editLimitText: props.editLimitText,
410
+ editLimitReachedText: props.editLimitReachedText,
411
+ supportLinkText: props.supportLinkText,
412
+ customizeDisabled,
413
+ customizeDisabledTooltip: props.customizeDisabledTooltip,
414
+ onCustomizeClick,
415
+ onEditValueChange,
416
+ onSave,
417
+ onCancel,
418
+ };
419
+ }
420
+
421
+ exports.ShareLinkView = ShareLinkView;
422
+ exports.useShareLink = useShareLink;