@heymantle/litho 0.0.12 → 0.0.14

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 (33) hide show
  1. package/dist/cjs/components/DropZone.js +4 -0
  2. package/dist/cjs/components/Navigation.js +4 -3
  3. package/dist/cjs/components/Popover.js +33 -5
  4. package/dist/cjs/components/Select.js +4 -0
  5. package/dist/cjs/components/TabNavigation.js +65 -11
  6. package/dist/cjs/components/TextField.js +4 -2
  7. package/dist/cjs/components/ToastNotification.js +368 -0
  8. package/dist/cjs/components/ToastProvider.js +342 -0
  9. package/dist/cjs/index.js +11 -0
  10. package/dist/esm/components/DropZone.js +5 -1
  11. package/dist/esm/components/Navigation.js +4 -3
  12. package/dist/esm/components/Popover.js +33 -5
  13. package/dist/esm/components/Select.js +5 -1
  14. package/dist/esm/components/TabNavigation.js +65 -11
  15. package/dist/esm/components/TextField.js +4 -2
  16. package/dist/esm/components/ToastNotification.js +353 -0
  17. package/dist/esm/components/ToastProvider.js +336 -0
  18. package/dist/esm/index.js +2 -0
  19. package/dist/types/components/DropZone.d.ts.map +1 -1
  20. package/dist/types/components/Navigation.d.ts +1 -0
  21. package/dist/types/components/Navigation.d.ts.map +1 -1
  22. package/dist/types/components/Popover.d.ts.map +1 -1
  23. package/dist/types/components/Select.d.ts.map +1 -1
  24. package/dist/types/components/TabNavigation.d.ts.map +1 -1
  25. package/dist/types/components/TextField.d.ts +2 -0
  26. package/dist/types/components/TextField.d.ts.map +1 -1
  27. package/dist/types/components/ToastNotification.d.ts +36 -0
  28. package/dist/types/components/ToastNotification.d.ts.map +1 -0
  29. package/dist/types/components/ToastProvider.d.ts +21 -0
  30. package/dist/types/components/ToastProvider.d.ts.map +1 -0
  31. package/dist/types/index.d.ts +2 -0
  32. package/index.css +3 -0
  33. package/package.json +2 -2
@@ -291,6 +291,10 @@ var dropZoneStyles = (0, _tailwindvariants.tv)({
291
291
  }),
292
292
  labelAction && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Link.default, {
293
293
  onClick: labelAction.onAction,
294
+ insight: labelAction.insight,
295
+ icon: labelAction.insight ? _polarisicons.MagicMajor : undefined,
296
+ color: labelAction.insight ? "insight" : undefined,
297
+ disabled: labelAction.disabled,
294
298
  removeUnderline: true,
295
299
  children: labelAction.content
296
300
  })
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "default", {
9
9
  }
10
10
  });
11
11
  var _jsxruntime = require("react/jsx-runtime");
12
+ var _react = /*#__PURE__*/ _interop_require_default(require("react"));
12
13
  var _tailwindvariants = require("tailwind-variants");
13
14
  var _Badge = /*#__PURE__*/ _interop_require_default(require("./Badge"));
14
15
  var _Icon = /*#__PURE__*/ _interop_require_default(require("./Icon"));
@@ -240,7 +241,7 @@ var linkStyles = (0, _tailwindvariants.tv)({
240
241
  })
241
242
  ]
242
243
  }),
243
- badge ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_Badge.default, {
244
+ badge ? /*#__PURE__*/ _react.default.isValidElement(badge) ? badge : /*#__PURE__*/ (0, _jsxruntime.jsx)(_Badge.default, {
244
245
  status: badge.status,
245
246
  children: badge.label
246
247
  }) : external ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_Icon.default, {
@@ -329,10 +330,10 @@ var subLinkStyles = (0, _tailwindvariants.tv)({
329
330
  })
330
331
  ]
331
332
  }),
332
- badge && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Badge.default, {
333
+ badge && /*#__PURE__*/ (_react.default.isValidElement(badge) ? badge : /*#__PURE__*/ (0, _jsxruntime.jsx)(_Badge.default, {
333
334
  status: badge.status,
334
335
  children: badge.label
335
- }),
336
+ })),
336
337
  accessory
337
338
  ]
338
339
  });
@@ -194,7 +194,7 @@ var styles = (0, _tailwindvariants.tv)({
194
194
  * @returns {JSX.Element} The rendered popover component.
195
195
  */ function Popover() {
196
196
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
197
- var activatorWrapper = props.activatorWrapper, _props_activatorDisplayType = props.activatorDisplayType, activatorDisplayType = _props_activatorDisplayType === void 0 ? "inline-block" : _props_activatorDisplayType, activator = props.activator, children = props.children, onClose = props.onClose, active = props.active, fixed = props.fixed, zIndexOverride = props.zIndexOverride, _props_sectioned = props.sectioned, sectioned = _props_sectioned === void 0 ? false : _props_sectioned, _props_preferredAlignment = props.preferredAlignment, preferredAlignment = _props_preferredAlignment === void 0 ? "center" : _props_preferredAlignment, _props_preferredPosition = props.preferredPosition, preferredPosition = _props_preferredPosition === void 0 ? "below" : _props_preferredPosition, _props_matchActivatorWidth = props.matchActivatorWidth, matchActivatorWidth = _props_matchActivatorWidth === void 0 ? false : _props_matchActivatorWidth, _props_maxWidth = props.maxWidth, maxWidth = _props_maxWidth === void 0 ? "default" : _props_maxWidth, className = props.className, containerClassName = props.containerClassName;
197
+ var activatorWrapper = props.activatorWrapper, _props_activatorDisplayType = props.activatorDisplayType, activatorDisplayType = _props_activatorDisplayType === void 0 ? "inline-block" : _props_activatorDisplayType, activator = props.activator, children = props.children, onClose = props.onClose, active = props.active, fixed = props.fixed, zIndexOverride = props.zIndexOverride, _props_sectioned = props.sectioned, sectioned = _props_sectioned === void 0 ? false : _props_sectioned, _props_preferredAlignment = props.preferredAlignment, preferredAlignment = _props_preferredAlignment === void 0 ? "center" : _props_preferredAlignment, _props_preferredPosition = props.preferredPosition, preferredPosition = _props_preferredPosition === void 0 ? "below" : _props_preferredPosition, _props_matchActivatorWidth = props.matchActivatorWidth, matchActivatorWidth = _props_matchActivatorWidth === void 0 ? false : _props_matchActivatorWidth, _props_maxWidth = props.maxWidth, maxWidth = _props_maxWidth === void 0 ? "default" : _props_maxWidth, className = props.className, containerClassName = props.containerClassName, _props_closeOnResize = props.closeOnResize, closeOnResize = _props_closeOnResize === void 0 ? true : _props_closeOnResize, _props_debounceResizeObserver = props.debounceResizeObserver, debounceResizeObserver = _props_debounceResizeObserver === void 0 ? false : _props_debounceResizeObserver, _props_usePortal = props.usePortal, usePortal = _props_usePortal === void 0 ? true : _props_usePortal;
198
198
  var ActivatorWrapper = activatorWrapper || "div";
199
199
  var idValue = (0, _react.useId)();
200
200
  var idRef = (0, _react.useRef)(idValue);
@@ -210,6 +210,25 @@ var styles = (0, _tailwindvariants.tv)({
210
210
  }, zIndexOverride ? {
211
211
  zIndex: zIndexOverride
212
212
  } : {})), 2), popoverStyle = _useState[0], setPopoverStyle = _useState[1];
213
+ // Reset popover style to hidden when it becomes active - this prevents flash
214
+ // of stale position from previous open. useLayoutEffect ensures this happens
215
+ // synchronously before paint.
216
+ (0, _react.useLayoutEffect)(function() {
217
+ if (active) {
218
+ setPopoverStyle(_object_spread({
219
+ visibility: "hidden",
220
+ opacity: 0,
221
+ position: "absolute",
222
+ top: 0,
223
+ left: 0
224
+ }, zIndexOverride ? {
225
+ zIndex: zIndexOverride
226
+ } : {}));
227
+ }
228
+ }, [
229
+ active,
230
+ zIndexOverride
231
+ ]);
213
232
  (0, _react.useEffect)(function() {
214
233
  if (active) {
215
234
  _PopoverManager.default.open(idRef.current);
@@ -339,7 +358,8 @@ var styles = (0, _tailwindvariants.tv)({
339
358
  observer.disconnect();
340
359
  };
341
360
  }, [
342
- active
361
+ active,
362
+ debounceResizeObserver
343
363
  ]);
344
364
  (0, _react.useLayoutEffect)(function() {
345
365
  if (!active || !popoverRef.current) return;
@@ -384,7 +404,7 @@ var styles = (0, _tailwindvariants.tv)({
384
404
  }
385
405
  };
386
406
  var handleResize = function handleResize() {
387
- if (onClose) {
407
+ if (onClose && closeOnResize) {
388
408
  onClose();
389
409
  }
390
410
  };
@@ -427,7 +447,15 @@ var styles = (0, _tailwindvariants.tv)({
427
447
  className: "Litho-PopoverActivator ".concat(activatorDisplayType),
428
448
  children: memoizedActivator
429
449
  }),
430
- active && typeof children !== "undefined" && /*#__PURE__*/ (0, _reactdom.createPortal)(/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
450
+ active && typeof children !== "undefined" && (usePortal ? /*#__PURE__*/ (0, _reactdom.createPortal)(/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
451
+ className: "@container",
452
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
453
+ ref: popoverRef,
454
+ style: popoverStyle,
455
+ className: "".concat(classes).concat(className ? " ".concat(className) : ""),
456
+ children: children
457
+ })
458
+ }), document.body) : /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
431
459
  className: "@container",
432
460
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
433
461
  ref: popoverRef,
@@ -435,7 +463,7 @@ var styles = (0, _tailwindvariants.tv)({
435
463
  className: "".concat(classes).concat(className ? " ".concat(className) : ""),
436
464
  children: children
437
465
  })
438
- }), document.body)
466
+ }))
439
467
  ]
440
468
  });
441
469
  }
@@ -203,6 +203,10 @@ var contentStyles = (0, _tailwindvariants.tv)({
203
203
  }),
204
204
  labelAction && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Link.default, {
205
205
  onClick: labelAction.onAction,
206
+ insight: labelAction.insight,
207
+ icon: labelAction.insight ? _polarisicons.MagicMajor : undefined,
208
+ color: labelAction.insight ? "insight" : undefined,
209
+ disabled: labelAction.disabled,
206
210
  removeUnderline: true,
207
211
  children: labelAction.content
208
212
  })
@@ -99,9 +99,57 @@ var gradientOverlayStyles = (0, _tailwindvariants.tv)({
99
99
  }
100
100
  }
101
101
  });
102
+ var containerStyles = (0, _tailwindvariants.tv)({
103
+ base: "w-2 h-2 rounded-full relative overflow-hidden bg-tint-2 flex-shrink-0",
104
+ variants: {
105
+ readStatus: {
106
+ full: ""
107
+ }
108
+ },
109
+ defaultVariants: {
110
+ readStatus: "read"
111
+ }
112
+ });
113
+ var readStatusStyles = (0, _tailwindvariants.tv)({
114
+ base: "absolute w-full h-full",
115
+ variants: {
116
+ readStatus: {
117
+ read: "",
118
+ partiallyRead: "bg-brand-saturated",
119
+ unread: "bg-brand-saturated"
120
+ }
121
+ },
122
+ defaultVariants: {
123
+ readStatus: "read"
124
+ }
125
+ });
126
+ // Small read status indicator for tabs
127
+ function TabReadStatusIndicator(param) {
128
+ var readStatus = param.readStatus;
129
+ if (!readStatus || !readStatus.status) {
130
+ return null;
131
+ }
132
+ var status = readStatus.status;
133
+ // Don't show indicator for read threads
134
+ if (status === "read") {
135
+ return null;
136
+ }
137
+ var containerClasses = containerStyles({
138
+ readStatus: status
139
+ });
140
+ var readStatusClasses = readStatusStyles({
141
+ readStatus: status
142
+ });
143
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
144
+ className: containerClasses,
145
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
146
+ className: readStatusClasses
147
+ })
148
+ });
149
+ }
102
150
  // Component to handle truncation detection and tooltip
103
151
  function TabTitle(param) {
104
- var title = param.title, isActive = param.isActive, tabContainerRef = param.tabContainerRef;
152
+ var title = param.title, isActive = param.isActive, tabContainerRef = param.tabContainerRef, readStatus = param.readStatus;
105
153
  var _useState = _sliced_to_array((0, _react.useState)(false), 2), shouldShowTooltip = _useState[0], setShouldShowTooltip = _useState[1];
106
154
  (0, _react.useLayoutEffect)(function() {
107
155
  if (!title || !(tabContainerRef === null || tabContainerRef === void 0 ? void 0 : tabContainerRef.current)) {
@@ -138,16 +186,21 @@ function TabTitle(param) {
138
186
  title,
139
187
  tabContainerRef
140
188
  ]);
141
- var textElement = /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
142
- className: "overflow-hidden",
143
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Text.default, {
144
- variant: "bodyXs",
145
- className: textStyles({
146
- isActive: isActive
189
+ var textElement = /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
190
+ className: "overflow-hidden flex items-center gap-1.5 min-w-0",
191
+ children: [
192
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_Text.default, {
193
+ variant: "bodyXs",
194
+ className: "".concat(textStyles({
195
+ isActive: isActive
196
+ }), " min-w-0 flex-1"),
197
+ clampLines: 1,
198
+ children: title
147
199
  }),
148
- clampLines: 1,
149
- children: title
150
- })
200
+ readStatus && /*#__PURE__*/ (0, _jsxruntime.jsx)(TabReadStatusIndicator, {
201
+ readStatus: readStatus
202
+ })
203
+ ]
151
204
  });
152
205
  // Only show tooltip if text is likely truncated based on character count vs tab width
153
206
  if (shouldShowTooltip) {
@@ -266,7 +319,8 @@ function TabNavigation() {
266
319
  }) : /*#__PURE__*/ (0, _jsxruntime.jsx)(TabTitle, {
267
320
  title: tab.title,
268
321
  isActive: isActive,
269
- tabContainerRef: tabRef
322
+ tabContainerRef: tabRef,
323
+ readStatus: tab.readStatus
270
324
  }),
271
325
  /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
272
326
  className: "".concat(gradientOverlayStyles({
@@ -282,10 +282,11 @@ var clearButtonStyles = (0, _tailwindvariants.tv)({
282
282
  * @param {Function} [props.onKeyDown] - Handler for key down.
283
283
  * @param {ReactNode} [props.tooltip] - Tooltip content for the label.
284
284
  * @param {string} [props.className] - Additional CSS classes.
285
+ * @param {boolean} [props.disableFocusStyles=false] - Whether to disable focused styles when the input is focused.
285
286
  * @returns {JSX.Element} The rendered TextField component.
286
287
  */ function TextField() {
287
288
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
288
- var prefix = props.prefix, _suffix = props.suffix, placeholder = props.placeholder, _props_value = props.value, value = _props_value === void 0 ? "" : _props_value, helpText = props.helpText, label = props.label, _props_labelVariant = props.labelVariant, labelVariant = _props_labelVariant === void 0 ? "bodyMd" : _props_labelVariant, labelAction = props.labelAction, labelHidden = props.labelHidden, _props_disabled = props.disabled, disabled = _props_disabled === void 0 ? false : _props_disabled, clearButton = props.clearButton, readOnly = props.readOnly, autoFocus = props.autoFocus, _focused = props.focused, _props_multiline = props.multiline, multiline = _props_multiline === void 0 ? 1 : _props_multiline, _props_autoGrow = props.autoGrow, autoGrow = _props_autoGrow === void 0 ? false : _props_autoGrow, maxHeight = props.maxHeight, error = props.error, connectedRight = props.connectedRight, connectedLeft = props.connectedLeft, _props_type = props.type, type = _props_type === void 0 ? "text" : _props_type, _props_subdued = props.subdued, subdued = _props_subdued === void 0 ? false : _props_subdued, name = props.name, _id = props.id, role = props.role, step = props.step, _props_largeStep = props.largeStep, largeStep = _props_largeStep === void 0 ? 10 : _props_largeStep, autoComplete = props.autoComplete, max = props.max, maxLength = props.maxLength, min = props.min, minLength = props.minLength, _props_showCharacterCount = props.showCharacterCount, showCharacterCount = _props_showCharacterCount === void 0 ? false : _props_showCharacterCount, pattern = props.pattern, spellCheck = props.spellCheck, ariaOwns = props.ariaOwns, ariaControls = props.ariaControls, ariaExpanded = props.ariaExpanded, ariaActiveDescendant = props.ariaActiveDescendant, ariaAutocomplete = props.ariaAutocomplete, _props_align = props.align, align = _props_align === void 0 ? "left" : _props_align, requiredIndicator = props.requiredIndicator, selectTextOnFocus = props.selectTextOnFocus, onClearButtonClick = props.onClearButtonClick, onChange = props.onChange, onFocus = props.onFocus, onBlur = props.onBlur, tooltip = props.tooltip, className = props.className, _inputRef = props.inputRef, icon = props.icon, _props_transparent = props.transparent, transparent = _props_transparent === void 0 ? false : _props_transparent, _props_showNumberSteppers = props.showNumberSteppers, showNumberSteppers = _props_showNumberSteppers === void 0 ? true : _props_showNumberSteppers, onKeyDown = props.onKeyDown;
289
+ var prefix = props.prefix, _suffix = props.suffix, placeholder = props.placeholder, _props_value = props.value, value = _props_value === void 0 ? "" : _props_value, helpText = props.helpText, label = props.label, _props_labelVariant = props.labelVariant, labelVariant = _props_labelVariant === void 0 ? "bodyMd" : _props_labelVariant, labelAction = props.labelAction, labelHidden = props.labelHidden, _props_disabled = props.disabled, disabled = _props_disabled === void 0 ? false : _props_disabled, clearButton = props.clearButton, readOnly = props.readOnly, autoFocus = props.autoFocus, _focused = props.focused, _props_multiline = props.multiline, multiline = _props_multiline === void 0 ? 1 : _props_multiline, _props_autoGrow = props.autoGrow, autoGrow = _props_autoGrow === void 0 ? false : _props_autoGrow, maxHeight = props.maxHeight, error = props.error, connectedRight = props.connectedRight, connectedLeft = props.connectedLeft, _props_type = props.type, type = _props_type === void 0 ? "text" : _props_type, _props_subdued = props.subdued, subdued = _props_subdued === void 0 ? false : _props_subdued, name = props.name, _id = props.id, role = props.role, step = props.step, _props_largeStep = props.largeStep, largeStep = _props_largeStep === void 0 ? 10 : _props_largeStep, autoComplete = props.autoComplete, max = props.max, maxLength = props.maxLength, min = props.min, minLength = props.minLength, _props_showCharacterCount = props.showCharacterCount, showCharacterCount = _props_showCharacterCount === void 0 ? false : _props_showCharacterCount, pattern = props.pattern, spellCheck = props.spellCheck, ariaOwns = props.ariaOwns, ariaControls = props.ariaControls, ariaExpanded = props.ariaExpanded, ariaActiveDescendant = props.ariaActiveDescendant, ariaAutocomplete = props.ariaAutocomplete, _props_align = props.align, align = _props_align === void 0 ? "left" : _props_align, requiredIndicator = props.requiredIndicator, selectTextOnFocus = props.selectTextOnFocus, onClearButtonClick = props.onClearButtonClick, onChange = props.onChange, onFocus = props.onFocus, onBlur = props.onBlur, tooltip = props.tooltip, className = props.className, _inputRef = props.inputRef, icon = props.icon, _props_transparent = props.transparent, transparent = _props_transparent === void 0 ? false : _props_transparent, _props_showNumberSteppers = props.showNumberSteppers, showNumberSteppers = _props_showNumberSteppers === void 0 ? true : _props_showNumberSteppers, onKeyDown = props.onKeyDown, _props_disableFocusStyles = props.disableFocusStyles, disableFocusStyles = _props_disableFocusStyles === void 0 ? false : _props_disableFocusStyles;
289
290
  var suffix = maxLength && showCharacterCount ? "".concat(value.length, " / ").concat(maxLength) : _suffix;
290
291
  var _internalRef = (0, _react.useRef)(null);
291
292
  var inputRef = _inputRef || _internalRef;
@@ -344,7 +345,7 @@ var clearButtonStyles = (0, _tailwindvariants.tv)({
344
345
  var classes = styles({
345
346
  disabled: Boolean(disabled || readOnly),
346
347
  hasError: hasError,
347
- focused: Boolean(focused && !readOnly),
348
+ focused: Boolean(focused && !readOnly && !disableFocusStyles),
348
349
  subdued: subdued,
349
350
  transparent: transparent
350
351
  });
@@ -567,6 +568,7 @@ var clearButtonStyles = (0, _tailwindvariants.tv)({
567
568
  insight: labelAction.insight,
568
569
  icon: labelAction.insight ? _polarisicons.MagicMajor : undefined,
569
570
  color: labelAction.insight ? "insight" : undefined,
571
+ disabled: labelAction.disabled,
570
572
  removeUnderline: true,
571
573
  children: labelAction.content
572
574
  })
@@ -0,0 +1,368 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return _default;
10
+ }
11
+ });
12
+ var _jsxruntime = require("react/jsx-runtime");
13
+ var _react = require("react");
14
+ var _tailwindvariants = require("tailwind-variants");
15
+ var _Text = /*#__PURE__*/ _interop_require_default(require("./Text"));
16
+ var _Icon = /*#__PURE__*/ _interop_require_default(require("./Icon"));
17
+ var _polarisicons = require("@shopify/polaris-icons");
18
+ function _array_like_to_array(arr, len) {
19
+ if (len == null || len > arr.length) len = arr.length;
20
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
21
+ return arr2;
22
+ }
23
+ function _array_with_holes(arr) {
24
+ if (Array.isArray(arr)) return arr;
25
+ }
26
+ function _interop_require_default(obj) {
27
+ return obj && obj.__esModule ? obj : {
28
+ default: obj
29
+ };
30
+ }
31
+ function _iterable_to_array_limit(arr, i) {
32
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
33
+ if (_i == null) return;
34
+ var _arr = [];
35
+ var _n = true;
36
+ var _d = false;
37
+ var _s, _e;
38
+ try {
39
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
40
+ _arr.push(_s.value);
41
+ if (i && _arr.length === i) break;
42
+ }
43
+ } catch (err) {
44
+ _d = true;
45
+ _e = err;
46
+ } finally{
47
+ try {
48
+ if (!_n && _i["return"] != null) _i["return"]();
49
+ } finally{
50
+ if (_d) throw _e;
51
+ }
52
+ }
53
+ return _arr;
54
+ }
55
+ function _non_iterable_rest() {
56
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
57
+ }
58
+ function _sliced_to_array(arr, i) {
59
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
60
+ }
61
+ function _unsupported_iterable_to_array(o, minLen) {
62
+ if (!o) return;
63
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
64
+ var n = Object.prototype.toString.call(o).slice(8, -1);
65
+ if (n === "Object" && o.constructor) n = o.constructor.name;
66
+ if (n === "Map" || n === "Set") return Array.from(n);
67
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
68
+ }
69
+ var styles = (0, _tailwindvariants.tv)({
70
+ base: "Litho-ToastNotification group/toast pointer-events-auto min-w-60 max-w-85 bg-surface-highest/95 hover:bg-surface-highest rounded-md shadow-card border border-tint-2 p-2 flex items-start gap-2 transition-all duration-300 ease-in-out",
71
+ variants: {
72
+ position: {
73
+ topRight: "",
74
+ topLeft: "",
75
+ topCenter: "",
76
+ bottomRight: "",
77
+ bottomLeft: "",
78
+ bottomCenter: ""
79
+ },
80
+ fixed: {
81
+ true: "fixed z-[9999]",
82
+ false: "relative"
83
+ },
84
+ visible: {
85
+ true: "opacity-100 translate-y-0",
86
+ false: "opacity-0"
87
+ },
88
+ clickable: {
89
+ true: "cursor-pointer",
90
+ false: ""
91
+ }
92
+ },
93
+ defaultVariants: {
94
+ position: "topRight",
95
+ visible: true,
96
+ fixed: true,
97
+ clickable: false
98
+ },
99
+ compoundVariants: [
100
+ {
101
+ position: "topRight",
102
+ fixed: true,
103
+ class: "top-4 right-4"
104
+ },
105
+ {
106
+ position: "topLeft",
107
+ fixed: true,
108
+ class: "top-4 left-4"
109
+ },
110
+ {
111
+ position: "topCenter",
112
+ fixed: true,
113
+ class: "top-4 left-1/2 -translate-x-1/2"
114
+ },
115
+ {
116
+ position: "bottomRight",
117
+ fixed: true,
118
+ class: "bottom-4 right-4"
119
+ },
120
+ {
121
+ position: "bottomLeft",
122
+ fixed: true,
123
+ class: "bottom-4 left-4"
124
+ },
125
+ {
126
+ position: "bottomCenter",
127
+ fixed: true,
128
+ class: "bottom-4 left-1/2 -translate-x-1/2"
129
+ },
130
+ {
131
+ position: "topRight",
132
+ visible: false,
133
+ class: "translate-x-full"
134
+ },
135
+ {
136
+ position: "topLeft",
137
+ visible: false,
138
+ class: "-translate-x-full"
139
+ },
140
+ {
141
+ position: "topCenter",
142
+ visible: false,
143
+ class: "-translate-y-4"
144
+ },
145
+ {
146
+ position: "bottomRight",
147
+ visible: false,
148
+ class: "translate-x-full"
149
+ },
150
+ {
151
+ position: "bottomLeft",
152
+ visible: false,
153
+ class: "-translate-x-full"
154
+ },
155
+ {
156
+ position: "bottomCenter",
157
+ visible: false,
158
+ class: "translate-y-4"
159
+ }
160
+ ]
161
+ });
162
+ var closeButtonStyles = (0, _tailwindvariants.tv)({
163
+ base: "Litho-ToastNotification__Close flex-none p-0.5 rounded-md cursor-pointer hover:bg-tint-2 active:bg-tint-3 transition-colors opacity-0 group-hover/toast:opacity-100"
164
+ });
165
+ /**
166
+ * ToastNotification component for displaying temporary notifications to users.
167
+ * Automatically dismisses after the specified duration.
168
+ *
169
+ * @component
170
+ * @param {Object} props - The component props.
171
+ * @param {React.ReactNode} [props.prefix] - Optional prefix content (image, icon, or component) to display before the title.
172
+ * @param {Object|Function} [props.icon] - Optional icon source (from @shopify/polaris-icons) to display as prefix. Used as fallback if prefix is not provided.
173
+ * @param {string} props.title - The main title text of the toast.
174
+ * @param {string} [props.subtitle] - Optional subtitle text displayed below the title.
175
+ * @param {number} [props.duration=3000] - Duration in milliseconds before the toast auto-dismisses. Defaults to 2000ms (2 seconds).
176
+ * @param {'topRight' | 'topLeft' | 'topCenter' | 'bottomRight' | 'bottomLeft' | 'bottomCenter'} [props.position='topRight'] - Position of the toast on the screen.
177
+ * @param {Function} [props.onDismiss] - Callback function called when the toast is dismissed (either automatically or manually).
178
+ * @param {Function} [props.onClick] - Callback function called when the toast is clicked. Makes the entire toast clickable with cursor-pointer.
179
+ * @param {boolean} [props.dismissible=true] - Whether the toast can be manually dismissed via the close button.
180
+ * @param {boolean} [props.fixed=true] - Whether to use fixed positioning. Set to false when used within ToastProvider.
181
+ * @param {boolean} [props.isDismissing=false] - Whether the toast is in a dismissing state. Starts the exit animation immediately.
182
+ * @param {string} [props.className] - Additional CSS classes to apply to the toast container.
183
+ * @returns {JSX.Element|null} The rendered toast notification or null if dismissed.
184
+ *
185
+ * @example
186
+ * <ToastNotification
187
+ * prefix={<Icon source={TickMinor} color="success" />}
188
+ * title="Support ticket updated"
189
+ * subtitle="Your ticket has been resolved"
190
+ * duration={3000}
191
+ * position="topRight"
192
+ * onDismiss={() => console.log('Toast dismissed')}
193
+ * />
194
+ */ function ToastNotification() {
195
+ var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
196
+ var prefix = props.prefix, icon = props.icon, title = props.title, subtitle = props.subtitle, _props_duration = props.duration, duration = _props_duration === void 0 ? 3000 : _props_duration, _props_position = props.position, position = _props_position === void 0 ? "topRight" : _props_position, onDismiss = props.onDismiss, onClick = props.onClick, _props_dismissible = props.dismissible, dismissible = _props_dismissible === void 0 ? true : _props_dismissible, _props_fixed = props.fixed, fixed = _props_fixed === void 0 ? true : _props_fixed, _props_isDismissing = props.isDismissing, isDismissing = _props_isDismissing === void 0 ? false : _props_isDismissing, className = props.className;
197
+ var _useState = _sliced_to_array((0, _react.useState)(!isDismissing), 2), visible = _useState[0], setVisible = _useState[1];
198
+ var _useState1 = _sliced_to_array((0, _react.useState)(true), 2), shouldRender = _useState1[0], setShouldRender = _useState1[1];
199
+ var _useState2 = _sliced_to_array((0, _react.useState)(false), 2), isHovered = _useState2[0], setIsHovered = _useState2[1];
200
+ var timerRef = (0, _react.useRef)(null);
201
+ var startTimeRef = (0, _react.useRef)(null);
202
+ var remainingTimeRef = (0, _react.useRef)(duration);
203
+ var dismissStartedRef = (0, _react.useRef)(false);
204
+ // If isDismissing is true, start exit animation immediately
205
+ (0, _react.useEffect)(function() {
206
+ if (isDismissing) {
207
+ setVisible(false);
208
+ dismissStartedRef.current = true;
209
+ setTimeout(function() {
210
+ setShouldRender(false);
211
+ }, 300);
212
+ }
213
+ }, [
214
+ isDismissing
215
+ ]);
216
+ var handleDismiss = (0, _react.useCallback)(function() {
217
+ if (dismissStartedRef.current) {
218
+ return; // Already dismissing
219
+ }
220
+ dismissStartedRef.current = true;
221
+ setVisible(false);
222
+ // Wait for exit animation to complete before removing from DOM
223
+ setTimeout(function() {
224
+ setShouldRender(false);
225
+ if (onDismiss) {
226
+ onDismiss();
227
+ }
228
+ }, 300); // Match transition duration
229
+ }, [
230
+ onDismiss
231
+ ]);
232
+ // Initialize remaining time when duration changes
233
+ (0, _react.useEffect)(function() {
234
+ if (duration > 0) {
235
+ remainingTimeRef.current = duration;
236
+ }
237
+ }, [
238
+ duration
239
+ ]);
240
+ // Set up auto-dismiss timer
241
+ (0, _react.useEffect)(function() {
242
+ // Don't start timer if already dismissing, duration is 0, or hovered
243
+ if (isDismissing || duration <= 0 || isHovered || dismissStartedRef.current) {
244
+ return;
245
+ }
246
+ // Clear any existing timer
247
+ if (timerRef.current) {
248
+ clearTimeout(timerRef.current);
249
+ timerRef.current = null;
250
+ }
251
+ // Start timer with remaining time
252
+ startTimeRef.current = Date.now();
253
+ timerRef.current = setTimeout(function() {
254
+ handleDismiss();
255
+ }, remainingTimeRef.current);
256
+ return function() {
257
+ if (timerRef.current) {
258
+ clearTimeout(timerRef.current);
259
+ timerRef.current = null;
260
+ }
261
+ };
262
+ }, [
263
+ duration,
264
+ isDismissing,
265
+ isHovered,
266
+ handleDismiss
267
+ ]);
268
+ // Handle hover state changes
269
+ (0, _react.useEffect)(function() {
270
+ if (isHovered && timerRef.current && startTimeRef.current && !dismissStartedRef.current) {
271
+ // Pause: calculate remaining time and clear timer
272
+ var elapsed = Date.now() - startTimeRef.current;
273
+ remainingTimeRef.current = Math.max(0, remainingTimeRef.current - elapsed);
274
+ clearTimeout(timerRef.current);
275
+ timerRef.current = null;
276
+ } else if (!isHovered && !isDismissing && duration > 0 && remainingTimeRef.current > 0 && visible && !dismissStartedRef.current) {
277
+ // Resume: restart timer with remaining time
278
+ if (timerRef.current) {
279
+ clearTimeout(timerRef.current);
280
+ }
281
+ startTimeRef.current = Date.now();
282
+ timerRef.current = setTimeout(function() {
283
+ handleDismiss();
284
+ }, remainingTimeRef.current);
285
+ }
286
+ }, [
287
+ isHovered,
288
+ isDismissing,
289
+ duration,
290
+ visible,
291
+ handleDismiss
292
+ ]);
293
+ var handleMouseEnter = function() {
294
+ if (!isDismissing && visible && !dismissStartedRef.current) {
295
+ setIsHovered(true);
296
+ }
297
+ };
298
+ var handleMouseLeave = function() {
299
+ if (!isDismissing && visible && !dismissStartedRef.current) {
300
+ setIsHovered(false);
301
+ }
302
+ };
303
+ if (!shouldRender) {
304
+ return null;
305
+ }
306
+ var classes = styles({
307
+ position: position,
308
+ visible: visible,
309
+ fixed: fixed,
310
+ clickable: !!onClick
311
+ });
312
+ var closeClasses = closeButtonStyles();
313
+ var handleToastClick = function(e) {
314
+ if (onClick) {
315
+ onClick(e);
316
+ }
317
+ };
318
+ var handleCloseClick = function(e) {
319
+ e.stopPropagation(); // Prevent triggering toast onClick
320
+ handleDismiss();
321
+ };
322
+ // Determine what to render as prefix: use prefix if provided, otherwise fallback to icon
323
+ var prefixContent = prefix || (icon ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_Icon.default, {
324
+ source: icon,
325
+ color: "subdued"
326
+ }) : null);
327
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
328
+ className: "".concat(classes).concat(className ? " ".concat(className) : ""),
329
+ onClick: handleToastClick,
330
+ onMouseEnter: handleMouseEnter,
331
+ onMouseLeave: handleMouseLeave,
332
+ children: [
333
+ prefixContent && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
334
+ className: "Litho-ToastNotification__Prefix flex-none",
335
+ children: prefixContent
336
+ }),
337
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
338
+ className: "Litho-ToastNotification__Content flex-1 flex flex-col gap-0.5 min-w-0",
339
+ children: [
340
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_Text.default, {
341
+ fontWeight: "medium",
342
+ variant: "bodySm",
343
+ clampLines: 1,
344
+ children: title
345
+ }),
346
+ subtitle && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Text.default, {
347
+ variant: "bodySm",
348
+ color: "subdued",
349
+ clampLines: 2,
350
+ children: subtitle
351
+ })
352
+ ]
353
+ }),
354
+ dismissible && /*#__PURE__*/ (0, _jsxruntime.jsx)("button", {
355
+ type: "button",
356
+ onClick: handleCloseClick,
357
+ className: closeClasses,
358
+ "aria-label": "Dismiss notification",
359
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Icon.default, {
360
+ source: _polarisicons.CancelMinor,
361
+ size: "sm",
362
+ color: "subdued"
363
+ })
364
+ })
365
+ ]
366
+ });
367
+ }
368
+ var _default = ToastNotification;