@heymantle/litho 0.0.14 → 0.0.15

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 (37) hide show
  1. package/README.md +52 -0
  2. package/dist/cjs/components/Card.js +1 -1
  3. package/dist/cjs/components/Disclosure.js +46 -15
  4. package/dist/cjs/components/DropZone.js +89 -37
  5. package/dist/cjs/components/Layout.js +4 -2
  6. package/dist/cjs/components/Modal.js +14 -3
  7. package/dist/cjs/components/Popover.js +26 -9
  8. package/dist/cjs/components/Table.js +27 -11
  9. package/dist/cjs/components/Tabs.js +33 -2
  10. package/dist/cjs/playwright.config.js +114 -0
  11. package/dist/cjs/styles/Table.js +2 -7
  12. package/dist/cjs/tests/visual/stories.spec.js +637 -0
  13. package/dist/cjs/utilities/dates.js +7 -7
  14. package/dist/esm/components/Card.js +1 -1
  15. package/dist/esm/components/Disclosure.js +36 -5
  16. package/dist/esm/components/DropZone.js +89 -37
  17. package/dist/esm/components/Layout.js +4 -2
  18. package/dist/esm/components/Modal.js +14 -3
  19. package/dist/esm/components/Popover.js +26 -9
  20. package/dist/esm/components/Table.js +27 -11
  21. package/dist/esm/components/Tabs.js +33 -2
  22. package/dist/esm/playwright.config.js +104 -0
  23. package/dist/esm/styles/Table.js +2 -7
  24. package/dist/esm/tests/visual/stories.spec.js +633 -0
  25. package/dist/esm/utilities/dates.js +7 -7
  26. package/dist/types/components/Disclosure.d.ts.map +1 -1
  27. package/dist/types/components/DropZone.d.ts +2 -0
  28. package/dist/types/components/DropZone.d.ts.map +1 -1
  29. package/dist/types/components/Layout.d.ts.map +1 -1
  30. package/dist/types/components/Modal.d.ts.map +1 -1
  31. package/dist/types/components/Popover.d.ts +2 -0
  32. package/dist/types/components/Popover.d.ts.map +1 -1
  33. package/dist/types/components/Table.d.ts.map +1 -1
  34. package/dist/types/components/Tabs.d.ts +45 -1
  35. package/dist/types/components/Tabs.d.ts.map +1 -1
  36. package/dist/types/styles/Table.d.ts.map +1 -1
  37. package/package.json +12 -3
@@ -139,7 +139,7 @@ var HOURLY_RANGE_PRESETS = [
139
139
  id: "last_30_minutes",
140
140
  label: "Last 30 minutes",
141
141
  value: {
142
- start: (0, _dayjs.default)().startOf("minute").subtract(29, "minutes").toDate(),
142
+ start: (0, _dayjs.default)().subtract(30, "minutes").startOf("minute").toDate(),
143
143
  end: (0, _dayjs.default)().endOf("minute").toDate()
144
144
  }
145
145
  },
@@ -173,7 +173,7 @@ var RANGE_PRESETS = [
173
173
  id: "last_12_hours",
174
174
  label: "Last 12 hours",
175
175
  value: {
176
- start: (0, _dayjs.default)().subtract(11, "hours").startOf("hour").toDate(),
176
+ start: (0, _dayjs.default)().subtract(12, "hours").startOf("hour").toDate(),
177
177
  end: (0, _dayjs.default)().endOf("hour").toDate()
178
178
  }
179
179
  },
@@ -182,7 +182,7 @@ var RANGE_PRESETS = [
182
182
  hideCalendar: true,
183
183
  label: "Last 24 hours",
184
184
  value: {
185
- start: (0, _dayjs.default)().subtract(23, "hours").startOf("hour").toDate(),
185
+ start: (0, _dayjs.default)().subtract(24, "hours").startOf("hour").toDate(),
186
186
  end: (0, _dayjs.default)().endOf("hour").toDate()
187
187
  }
188
188
  },
@@ -190,7 +190,7 @@ var RANGE_PRESETS = [
190
190
  id: "last_7_days",
191
191
  label: "Last 7 days",
192
192
  value: {
193
- start: (0, _dayjs.default)().subtract(6, "day").startOf("day").toDate(),
193
+ start: (0, _dayjs.default)().subtract(7, "day").startOf("day").toDate(),
194
194
  end: (0, _dayjs.default)().endOf("day").toDate()
195
195
  }
196
196
  },
@@ -198,7 +198,7 @@ var RANGE_PRESETS = [
198
198
  id: "last_14_days",
199
199
  label: "Last 14 days",
200
200
  value: {
201
- start: (0, _dayjs.default)().subtract(13, "day").startOf("day").toDate(),
201
+ start: (0, _dayjs.default)().subtract(14, "day").startOf("day").toDate(),
202
202
  end: (0, _dayjs.default)().endOf("day").toDate()
203
203
  }
204
204
  },
@@ -206,7 +206,7 @@ var RANGE_PRESETS = [
206
206
  id: "last_30_days",
207
207
  label: "Last 30 days",
208
208
  value: {
209
- start: (0, _dayjs.default)().subtract(29, "day").startOf("day").toDate(),
209
+ start: (0, _dayjs.default)().subtract(30, "day").startOf("day").toDate(),
210
210
  end: (0, _dayjs.default)().endOf("day").toDate()
211
211
  }
212
212
  },
@@ -214,7 +214,7 @@ var RANGE_PRESETS = [
214
214
  id: "last_90_days",
215
215
  label: "Last 90 days",
216
216
  value: {
217
- start: (0, _dayjs.default)().subtract(89, "day").startOf("day").toDate(),
217
+ start: (0, _dayjs.default)().subtract(90, "day").startOf("day").toDate(),
218
218
  end: (0, _dayjs.default)().endOf("day").toDate()
219
219
  }
220
220
  },
@@ -501,7 +501,7 @@ var sectionBodyStyles = tv({
501
501
  };
502
502
  Card.Section.displayName = "Card.Section";
503
503
  var clickableRowStyles = tv({
504
- base: "Litho-Card__Row py-1.5 px-2.5 cursor-pointer rounded-md hover:bg-tint-2 active:bg-tint-3",
504
+ base: "Litho-Card__Row py-1.5 px-2.5 @md:px-3 cursor-pointer rounded-md hover:bg-tint-2 active:bg-tint-3",
505
505
  variants: {
506
506
  disabled: {
507
507
  true: "opacity-50 cursor-not-allowed pointer-events-none"
@@ -1,3 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { tv } from "tailwind-variants";
3
+ var styles = tv({
4
+ base: "Litho-Disclosure relative",
5
+ variants: {
6
+ flush: {
7
+ true: "pl-4",
8
+ false: "pl-7.5 @md:pl-7"
9
+ }
10
+ },
11
+ defaultVariants: {
12
+ flush: false
13
+ }
14
+ });
15
+ var borderStyles = tv({
16
+ base: "Litho-Disclosure__Border absolute top-0 w-px h-full bg-tint-5 dark:bg-tint-alt-5",
17
+ variants: {
18
+ flush: {
19
+ true: "left-0.5",
20
+ false: "left-[9px]"
21
+ }
22
+ },
23
+ defaultVariants: {
24
+ flush: false
25
+ }
26
+ });
1
27
  /**
2
28
  * Renders a Disclosure component that displays content with disclosure styling.
3
29
  *
@@ -18,15 +44,20 @@
18
44
  * <Disclosure className="mt-4">
19
45
  * <Text>This is disclosure content with margin</Text>
20
46
  * </Disclosure>
21
- */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
- function Disclosure() {
47
+ */ function Disclosure() {
23
48
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
24
- var children = props.children, className = props.className;
49
+ var children = props.children, className = props.className, _props_flush = props.flush, flush = _props_flush === void 0 ? false : _props_flush;
50
+ var classes = styles({
51
+ flush: flush
52
+ });
53
+ var borderClasses = borderStyles({
54
+ flush: flush
55
+ });
25
56
  return /*#__PURE__*/ _jsxs("div", {
26
- className: "relative pl-7.5 @md:pl-7".concat(className ? " ".concat(className) : ""),
57
+ className: "".concat(classes).concat(className ? " ".concat(className) : ""),
27
58
  children: [
28
59
  /*#__PURE__*/ _jsx("div", {
29
- className: "absolute left-[9px] top-0 w-px h-full bg-tint-5 dark:bg-tint-alt-5"
60
+ className: borderClasses
30
61
  }),
31
62
  /*#__PURE__*/ _jsx("div", {
32
63
  children: children
@@ -69,6 +69,42 @@ import SkeletonText from "./SkeletonText.js";
69
69
  import Spinner from "./Spinner.js";
70
70
  import Text from "./Text.js";
71
71
  import { CancelMajor, CircleAlertMajor, FileMinor, ImageMajor, ImagesMajor, MagicMajor } from "@shopify/polaris-icons";
72
+ var normalizeDropZoneAccept = function(accept) {
73
+ if (!accept) return [];
74
+ return typeof accept === "string" ? [
75
+ accept
76
+ ] : accept;
77
+ };
78
+ var isFileAcceptedForDropZone = function(file) {
79
+ var accept = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
80
+ if (!accept || accept.length === 0) return true;
81
+ return accept.some(function(type) {
82
+ if (!type) return false;
83
+ if (type === "*/*") return true;
84
+ if (type.endsWith("/*")) {
85
+ var _type_split = _sliced_to_array(type.split("/"), 1), prefix = _type_split[0];
86
+ if (prefix === "*") return true;
87
+ return !!(file === null || file === void 0 ? void 0 : file.type) && file.type.startsWith("".concat(prefix, "/"));
88
+ }
89
+ return (file === null || file === void 0 ? void 0 : file.type) === type;
90
+ });
91
+ };
92
+ var partitionFilesByDropZoneAccept = function(files) {
93
+ var accept = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
94
+ var acceptedFiles = [];
95
+ var rejectedFiles = [];
96
+ files.forEach(function(file) {
97
+ if (isFileAcceptedForDropZone(file, accept)) {
98
+ acceptedFiles.push(file);
99
+ } else {
100
+ rejectedFiles.push(file);
101
+ }
102
+ });
103
+ return {
104
+ acceptedFiles: acceptedFiles,
105
+ rejectedFiles: rejectedFiles
106
+ };
107
+ };
72
108
  var dropZoneStyles = tv({
73
109
  base: "Litho-DropZone w-full flex items-center justify-center p-4 border border-form-border border-dashed rounded-md focus:outline-hidden",
74
110
  variants: {
@@ -130,11 +166,7 @@ var dropZoneStyles = tv({
130
166
  */ function DropZone() {
131
167
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
132
168
  var id = props.id, label = props.label, labelHidden = props.labelHidden, labelAction = props.labelAction, tooltip = props.tooltip, labelVariant = props.labelVariant, _props_type = props.type, type = _props_type === void 0 ? "file" : _props_type, _accept = props.accept, _props_allowMultiple = props.allowMultiple, allowMultiple = _props_allowMultiple === void 0 ? false : _props_allowMultiple, _props_showDropZoneWhenDisabled = props.showDropZoneWhenDisabled, showDropZoneWhenDisabled = _props_showDropZoneWhenDisabled === void 0 ? true : _props_showDropZoneWhenDisabled, _disabled = props.disabled, onDrop = props.onDrop, onDropAccepted = props.onDropAccepted, onDropRejected = props.onDropRejected, helpText = props.helpText, error = props.error, _props_uploading = props.uploading, uploading = _props_uploading === void 0 ? false : _props_uploading, _props_uploadedFiles = props.uploadedFiles, uploadedFiles = _props_uploadedFiles === void 0 ? [] : _props_uploadedFiles, _props_uploadLabel = props.uploadLabel, uploadLabel = _props_uploadLabel === void 0 ? "Drag and drop files or click to upload" : _props_uploadLabel, _props_uploadingLabel = props.uploadingLabel, uploadingLabel = _props_uploadingLabel === void 0 ? "Uploading..." : _props_uploadingLabel, _props_dragLabel = props.dragLabel, dragLabel = _props_dragLabel === void 0 ? "Release to upload" : _props_dragLabel, tmp = props.showFilePreview, _showFilePreview = tmp === void 0 ? true : tmp, previewLoading = props.previewLoading, _props_previewRows = props.previewRows, previewRows = _props_previewRows === void 0 ? 2 : _props_previewRows, onRemove = props.onRemove, onFilePreviewClick = props.onFilePreviewClick, filename = props.filename;
133
- var accept = _accept ? typeof _accept === "string" ? [
134
- _accept
135
- ] : _accept : [
136
- "*/*"
137
- ];
169
+ var accept = normalizeDropZoneAccept(_accept);
138
170
  var inputRef = useRef(null);
139
171
  var _useState = _sliced_to_array(useState(false), 2), hasFocusWithin = _useState[0], setHasFocusWithin = _useState[1];
140
172
  var _useState1 = _sliced_to_array(useState(false), 2), isDraggingOver = _useState1[0], setIsDraggingOver = _useState1[1];
@@ -195,22 +227,7 @@ var dropZoneStyles = tv({
195
227
  setDragFileCount(0);
196
228
  if (disabled) return;
197
229
  var droppedFiles = Array.from(event.dataTransfer.files);
198
- var acceptedFiles = [];
199
- var rejectedFiles = [];
200
- droppedFiles.forEach(function(file) {
201
- var isValidType = typeAccept.length === 0 || typeAccept.some(function(type) {
202
- if (type.endsWith("/*")) {
203
- return file.type.startsWith("".concat(type.split("/")[0], "/"));
204
- }
205
- return file.type === type;
206
- });
207
- var isValid = isValidType;
208
- if (isValid) {
209
- acceptedFiles.push(file);
210
- } else {
211
- rejectedFiles.push(file);
212
- }
213
- });
230
+ var _partitionFilesByDropZoneAccept = partitionFilesByDropZoneAccept(droppedFiles, typeAccept), acceptedFiles = _partitionFilesByDropZoneAccept.acceptedFiles, rejectedFiles = _partitionFilesByDropZoneAccept.rejectedFiles;
214
231
  if (onDrop) {
215
232
  onDrop(droppedFiles);
216
233
  }
@@ -223,22 +240,7 @@ var dropZoneStyles = tv({
223
240
  };
224
241
  var handleFileChange = function(event) {
225
242
  var selectedFiles = Array.from(event.target.files);
226
- var acceptedFiles = [];
227
- var rejectedFiles = [];
228
- selectedFiles.forEach(function(file) {
229
- var isValidType = typeAccept.length === 0 || typeAccept.some(function(type) {
230
- if (type.endsWith("/*")) {
231
- return file.type.startsWith("".concat(type.split("/")[0], "/"));
232
- }
233
- return file.type === type;
234
- });
235
- var isValid = isValidType;
236
- if (isValid) {
237
- acceptedFiles.push(file);
238
- } else {
239
- rejectedFiles.push(file);
240
- }
241
- });
243
+ var _partitionFilesByDropZoneAccept = partitionFilesByDropZoneAccept(selectedFiles, typeAccept), acceptedFiles = _partitionFilesByDropZoneAccept.acceptedFiles, rejectedFiles = _partitionFilesByDropZoneAccept.rejectedFiles;
242
244
  if (onDrop) {
243
245
  onDrop(selectedFiles);
244
246
  }
@@ -358,6 +360,56 @@ var dropZoneStyles = tv({
358
360
  ]
359
361
  });
360
362
  }
363
+ var DropTarget = function() {
364
+ var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
365
+ var _accept = props.accept, _props_allowMultiple = props.allowMultiple, allowMultiple = _props_allowMultiple === void 0 ? true : _props_allowMultiple, _props_disabled = props.disabled, disabled = _props_disabled === void 0 ? false : _props_disabled, onDrop = props.onDrop, onDropAccepted = props.onDropAccepted, onDropRejected = props.onDropRejected, className = props.className, dragOverClassName = props.dragOverClassName, children = props.children;
366
+ var accept = normalizeDropZoneAccept(_accept);
367
+ var _useState = _sliced_to_array(useState(false), 2), isDraggingOver = _useState[0], setIsDraggingOver = _useState[1];
368
+ var handleDragOver = function(event) {
369
+ event.preventDefault();
370
+ event.stopPropagation();
371
+ if (!disabled) {
372
+ setIsDraggingOver(true);
373
+ }
374
+ };
375
+ var handleDragLeave = function(event) {
376
+ event.preventDefault();
377
+ event.stopPropagation();
378
+ setIsDraggingOver(false);
379
+ };
380
+ var handleDrop = function(event) {
381
+ event.preventDefault();
382
+ event.stopPropagation();
383
+ setIsDraggingOver(false);
384
+ if (disabled) return;
385
+ var droppedFiles = Array.from(event.dataTransfer.files);
386
+ if (allowMultiple === false) {
387
+ droppedFiles = droppedFiles.slice(0, 1);
388
+ }
389
+ var _partitionFilesByDropZoneAccept = partitionFilesByDropZoneAccept(droppedFiles, accept), acceptedFiles = _partitionFilesByDropZoneAccept.acceptedFiles, rejectedFiles = _partitionFilesByDropZoneAccept.rejectedFiles;
390
+ if (onDrop) {
391
+ onDrop(droppedFiles);
392
+ }
393
+ if (onDropAccepted && acceptedFiles.length > 0) {
394
+ onDropAccepted(acceptedFiles);
395
+ }
396
+ if (onDropRejected && rejectedFiles.length > 0) {
397
+ onDropRejected(rejectedFiles);
398
+ }
399
+ };
400
+ var dropTargetClassName = [
401
+ className,
402
+ isDraggingOver && dragOverClassName
403
+ ].filter(Boolean).join(" ");
404
+ return /*#__PURE__*/ _jsx("div", {
405
+ className: dropTargetClassName,
406
+ onDragOver: handleDragOver,
407
+ onDragLeave: handleDragLeave,
408
+ onDrop: handleDrop,
409
+ children: children
410
+ });
411
+ };
412
+ DropZone.DropTarget = DropTarget;
361
413
  var previewContainerStyles = tv({
362
414
  base: "flex flex-col",
363
415
  variants: {
@@ -147,11 +147,13 @@ var annotatedSectionStyles = tv({
147
147
  var annotatedSectionClasses = annotatedSectionStyles({
148
148
  embedded: embedded
149
149
  });
150
+ var annotationColSpan = embedded ? "@md-embed:col-span-4" : "@md:col-span-4";
151
+ var contentColSpan = embedded ? "@md-embed:col-span-8" : "@md:col-span-8";
150
152
  return /*#__PURE__*/ _jsxs("div", {
151
153
  className: annotatedSectionClasses,
152
154
  children: [
153
155
  /*#__PURE__*/ _jsxs("div", {
154
- className: "Litho-Layout__Annotation flex flex-col gap-1 @md:col-span-4 py-2",
156
+ className: "Litho-Layout__Annotation flex flex-col gap-1 ".concat(annotationColSpan, " py-2"),
155
157
  children: [
156
158
  title && (typeof title === "string" ? /*#__PURE__*/ _jsx(Text, {
157
159
  variant: "headingMd",
@@ -164,7 +166,7 @@ var annotatedSectionStyles = tv({
164
166
  ]
165
167
  }),
166
168
  /*#__PURE__*/ _jsx("div", {
167
- className: "Litho-Layout__AnnotationContent @md:col-span-8",
169
+ className: "Litho-Layout__AnnotationContent ".concat(contentColSpan),
168
170
  children: children
169
171
  })
170
172
  ]
@@ -63,7 +63,16 @@ import { useFrame } from "./Frame.js";
63
63
  import { useBodyScrollLock } from "../utilities/useBodyScrollLock.js";
64
64
  export var ModalContext = /*#__PURE__*/ createContext(false);
65
65
  var containerStyles = tv({
66
- base: "Litho-ModalContainer fixed inset-0 block flex flex-col justify-end md:justify-center items-center pointer-events-none"
66
+ base: "Litho-ModalContainer fixed inset-0 block flex flex-col justify-end md:justify-center items-center pointer-events-none",
67
+ variants: {
68
+ hidden: {
69
+ true: "hidden opacity-0 pointer-events-none",
70
+ false: ""
71
+ }
72
+ },
73
+ defaultVariants: {
74
+ hidden: false
75
+ }
67
76
  });
68
77
  var styles = tv({
69
78
  base: "Litho-Modal relative bg-surface-highest shadow-modal dark:shadow-modal-dark w-full mx-auto pointer-events-auto flex flex-col overflow-hidden",
@@ -142,7 +151,7 @@ var sectionStyles = tv({
142
151
  * @returns {React.ReactPortal|null} The rendered modal component or null if not open.
143
152
  */ function Modal() {
144
153
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
145
- var children = props.children, title = props.title, subtitle = props.subtitle, open = props.open, onClose = props.onClose, sectioned = props.sectioned, primaryAction = props.primaryAction, secondaryAction = props.secondaryAction, _props_secondaryActions = props.secondaryActions, secondaryActions = _props_secondaryActions === void 0 ? [] : _props_secondaryActions, destructiveAction = props.destructiveAction, loading = props.loading, _props_size = props.size, size = _props_size === void 0 ? "default" : _props_size, leftAccessory = props.leftAccessory, _props_hideCloseButton = props.hideCloseButton, hideCloseButton = _props_hideCloseButton === void 0 ? false : _props_hideCloseButton, backAction = props.backAction, zIndexOverride = props.zIndexOverride, _props_autoFocusFirstInput = props.autoFocusFirstInput, autoFocusFirstInput = _props_autoFocusFirstInput === void 0 ? true : _props_autoFocusFirstInput, bodyClassName = props.bodyClassName;
154
+ var children = props.children, title = props.title, subtitle = props.subtitle, open = props.open, _props_hidden = props.hidden, hidden = _props_hidden === void 0 ? false : _props_hidden, onClose = props.onClose, sectioned = props.sectioned, primaryAction = props.primaryAction, secondaryAction = props.secondaryAction, _props_secondaryActions = props.secondaryActions, secondaryActions = _props_secondaryActions === void 0 ? [] : _props_secondaryActions, destructiveAction = props.destructiveAction, loading = props.loading, _props_size = props.size, size = _props_size === void 0 ? "default" : _props_size, leftAccessory = props.leftAccessory, _props_hideCloseButton = props.hideCloseButton, hideCloseButton = _props_hideCloseButton === void 0 ? false : _props_hideCloseButton, backAction = props.backAction, zIndexOverride = props.zIndexOverride, _props_autoFocusFirstInput = props.autoFocusFirstInput, autoFocusFirstInput = _props_autoFocusFirstInput === void 0 ? true : _props_autoFocusFirstInput, bodyClassName = props.bodyClassName;
146
155
  var setModalIsOpen = useFrame().setModalIsOpen;
147
156
  var modalContentRef = useRef(null);
148
157
  var hasChildren = !!children;
@@ -150,7 +159,9 @@ var sectionStyles = tv({
150
159
  sectioned: sectioned,
151
160
  size: size
152
161
  });
153
- var containerClasses = containerStyles();
162
+ var containerClasses = containerStyles({
163
+ hidden: hidden
164
+ });
154
165
  var headerClasses = headerStyles({
155
166
  hasChildren: hasChildren
156
167
  });
@@ -133,18 +133,23 @@ var styles = tv({
133
133
  * @param {boolean} [props.sectioned=false] - Whether the popover content is sectioned with padding.
134
134
  * @param {string} [props.preferredAlignment="center"] - Preferred alignment for the popover (left, center, right).
135
135
  * @param {string} [props.preferredPosition="below"] - Preferred position for the popover (above, below, cover, left, right).
136
+ * @param {number} [props.horizontalOffset] - Custom horizontal offset in pixels to adjust the popover position.
136
137
  * @param {string} [props.className] - Additional class name for the popover.
137
138
  * @param {string} [props.containerClassName] - Additional class name for the popover container.
138
139
  * @returns {JSX.Element} The rendered popover component.
139
140
  */ function Popover() {
140
141
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
141
- 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;
142
+ 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, activeProp = 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_horizontalOffset = props.horizontalOffset, horizontalOffset = _props_horizontalOffset === void 0 ? 0 : _props_horizontalOffset, _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;
142
143
  var ActivatorWrapper = activatorWrapper || "div";
143
144
  var idValue = useId();
144
145
  var idRef = useRef(idValue);
145
146
  var initialWidthRef = useRef(null);
146
147
  var popoverRef = useRef(null);
147
148
  var activatorRef = useRef(null);
149
+ // Check if the activator is inside an inert element (e.g., table cells covered by fixed columns)
150
+ var isActivatorInert = activatorRef.current ? activatorRef.current.closest('[inert]') !== null : false;
151
+ // When disabled, prevent popover from opening
152
+ var active = isActivatorInert ? false : activeProp;
148
153
  var _useState = _sliced_to_array(useState(_object_spread({
149
154
  visibility: "hidden",
150
155
  opacity: 0,
@@ -227,7 +232,7 @@ var styles = tv({
227
232
  } else if (preferredAlignment === "right") {
228
233
  left = fixed ? activatorRect.right - popoverRect.width : activatorRect.right + window.scrollX - popoverRect.width;
229
234
  } else if (preferredAlignment === "center") {
230
- left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2;
235
+ left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset;
231
236
  }
232
237
  } else if (position === "above") {
233
238
  top = fixed ? activatorRect.top - popoverRect.height - TOP_SPACING : activatorRect.top + window.scrollY - popoverRect.height - TOP_SPACING;
@@ -236,7 +241,7 @@ var styles = tv({
236
241
  } else if (preferredAlignment === "right") {
237
242
  left = fixed ? activatorRect.right - popoverRect.width : activatorRect.right + window.scrollX - popoverRect.width;
238
243
  } else if (preferredAlignment === "center") {
239
- left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2;
244
+ left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset;
240
245
  }
241
246
  } else if (position === "cover") {
242
247
  top = fixed ? activatorRect.top : activatorRect.top + window.scrollY;
@@ -245,7 +250,7 @@ var styles = tv({
245
250
  } else if (preferredAlignment === "right") {
246
251
  left = fixed ? activatorRect.right - popoverRect.width : activatorRect.right + window.scrollX - popoverRect.width;
247
252
  } else if (preferredAlignment === "center") {
248
- left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2;
253
+ left = fixed ? activatorRect.left + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset : activatorRect.left + window.scrollX + activatorRect.width / 2 - popoverRect.width / 2 + horizontalOffset;
249
254
  }
250
255
  }
251
256
  // Fallback adjustments for vertical positioning (when not in left/right mode)
@@ -258,11 +263,23 @@ var styles = tv({
258
263
  }
259
264
  }
260
265
  // Fallback adjustments for horizontal positioning
261
- if (left + popoverRect.width > windowWidth) {
262
- left = windowWidth - popoverRect.width - EDGE_SPACING;
263
- }
264
- if (left < 0) {
265
- left = EDGE_SPACING;
266
+ // Only apply edge constraints if we're not using center alignment with custom offset
267
+ // This allows center alignment to work even near edges
268
+ if (preferredAlignment !== "center" || horizontalOffset === 0) {
269
+ if (left + popoverRect.width > windowWidth) {
270
+ left = windowWidth - popoverRect.width - EDGE_SPACING;
271
+ }
272
+ if (left < 0) {
273
+ left = EDGE_SPACING;
274
+ }
275
+ } else {
276
+ // For center alignment with offset, still respect edges but try to maintain centering
277
+ if (left + popoverRect.width > windowWidth) {
278
+ left = Math.max(EDGE_SPACING, windowWidth - popoverRect.width - EDGE_SPACING);
279
+ }
280
+ if (left < 0) {
281
+ left = EDGE_SPACING;
282
+ }
266
283
  }
267
284
  // Fallback adjustments for vertical positioning (when in left/right mode)
268
285
  if (position === "left" || position === "right") {
@@ -160,6 +160,7 @@ import Text from "./Text.js";
160
160
  import Tooltip from "./Tooltip.js";
161
161
  import { styles } from "../styles/Table.js";
162
162
  import { SelectionType } from "../utilities/useIndexResourceState.js";
163
+ import { useMobile } from "../utilities/useMobile.js";
163
164
  import { useMounted } from "../utilities/useMounted.js";
164
165
  import useTableScrollState from "../utilities/useTableScrollState.js";
165
166
  var TableContext = /*#__PURE__*/ createContext({});
@@ -447,6 +448,8 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
447
448
  var alignment = cellAlignment[indexAdjusted];
448
449
  var isSortable = sortable && sortable.length > 0 && sortable[indexAdjusted];
449
450
  var sortIndex = selectable ? indexAdjusted - 1 : indexAdjusted;
451
+ // Check if this cell is covered by a fixed overlay
452
+ var isCovered = !fixed && !reverseColumns && (fixedFirstColumns > 0 && indexAdjusted < fixedFirstColumns || fixedLastColumns > 0 && indexAdjusted >= headings.length - fixedLastColumns);
450
453
  var sortContent = isSortable ? /*#__PURE__*/ _jsx("div", {
451
454
  className: "min-h-5 ".concat(sort.index === sortIndex ? "opacity-100" : "opacity-0 group-hover:opacity-100"),
452
455
  children: /*#__PURE__*/ _jsx(Icon, {
@@ -481,6 +484,7 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
481
484
  ].includes(alignment) && sortContent
482
485
  ]
483
486
  });
487
+ var hasTooltip = (heading.tooltip || heading.tooltipContent) && !isCovered;
484
488
  return /*#__PURE__*/ _jsx(HeadingCell, {
485
489
  className: styles.headingStyles({
486
490
  hidden: hideCell,
@@ -498,7 +502,7 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
498
502
  className: styles.headingLabelContainerStyles({
499
503
  alignment: alignment
500
504
  }),
501
- children: heading.hidden ? null : heading.tooltip || heading.tooltipContent ? /*#__PURE__*/ _jsx(Tooltip, {
505
+ children: heading.hidden ? null : hasTooltip ? /*#__PURE__*/ _jsx(Tooltip, {
502
506
  content: heading.tooltip || heading.tooltipContent,
503
507
  preferredPosition: "above",
504
508
  children: labelContent
@@ -614,12 +618,16 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
614
618
  value: {
615
619
  columnsToRender: columnsToRender,
616
620
  reverseColumns: reverseColumns,
617
- hideCellsOnMobile: hideCellsOnMobile
621
+ hideCellsOnMobile: hideCellsOnMobile,
622
+ isFixedOverlay: fixed,
623
+ fixedFirstColumns: fixedFirstColumns,
624
+ fixedLastColumns: fixedLastColumns
618
625
  },
619
626
  children: /*#__PURE__*/ _jsxs("table", {
620
627
  className: styles.tableStyles(),
621
628
  children: [
622
629
  hasHeadings && renderHeadings({
630
+ fixed: fixed,
623
631
  hidden: true,
624
632
  columnsToRender: columnsToRender,
625
633
  reverseColumns: reverseColumns,
@@ -752,7 +760,8 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
752
760
  increasedTableDensity: increasedTableDensity,
753
761
  tableContainerRef: tableContainerRef,
754
762
  cellAlignment: cellAlignment,
755
- noBodyCellPadding: noBodyCellPadding
763
+ noBodyCellPadding: noBodyCellPadding,
764
+ columnWidths: columnWidths
756
765
  },
757
766
  children: /*#__PURE__*/ _jsxs("div", {
758
767
  "data-id": idRef.current,
@@ -803,8 +812,7 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
803
812
  children: renderTable({
804
813
  classes: "relative overflow-hidden",
805
814
  fixed: true,
806
- columnsToRender: fixedFirstColumns,
807
- hideCellsOnMobile: true
815
+ columnsToRender: fixedFirstColumns
808
816
  })
809
817
  }) : /*#__PURE__*/ _jsx("div", {
810
818
  className: styles.overflowShadowStyles({
@@ -822,8 +830,7 @@ var TableWrapperContext = /*#__PURE__*/ createContext({});
822
830
  classes: "relative overflow-hidden",
823
831
  fixed: true,
824
832
  columnsToRender: fixedLastColumns,
825
- reverseColumns: true,
826
- hideCellsOnMobile: true
833
+ reverseColumns: true
827
834
  })
828
835
  }) : /*#__PURE__*/ _jsx("div", {
829
836
  className: styles.overflowShadowStyles({
@@ -968,8 +975,11 @@ Table.Row.displayName = "Table.Row";
968
975
  */ function Cell(param) {
969
976
  var tmp = param.alignment, _alignment = tmp === void 0 ? "start" : tmp, children = param.children, _param_selectionCell = param.selectionCell, selectionCell = _param_selectionCell === void 0 ? false : _param_selectionCell;
970
977
  var _useContext = useContext(TableContext), cellAlignment = _useContext.cellAlignment, increasedTableDensity = _useContext.increasedTableDensity, selectable = _useContext.selectable, noBodyCellPadding = _useContext.noBodyCellPadding;
971
- var _useContext1 = useContext(TableWrapperContext), hideCellsOnMobile = _useContext1.hideCellsOnMobile, reverseColumns = _useContext1.reverseColumns, columnsToRender = _useContext1.columnsToRender;
978
+ var _useContext1 = useContext(TableWrapperContext), hideCellsOnMobile = _useContext1.hideCellsOnMobile, reverseColumns = _useContext1.reverseColumns, columnsToRender = _useContext1.columnsToRender, isFixedOverlay = _useContext1.isFixedOverlay, fixedFirstColumns = _useContext1.fixedFirstColumns, fixedLastColumns = _useContext1.fixedLastColumns;
979
+ var isMobile = useMobile();
972
980
  var columnCount = (cellAlignment === null || cellAlignment === void 0 ? void 0 : cellAlignment.length) || 0;
981
+ // Use state instead of ref so changes trigger re-render
982
+ var _useState = _sliced_to_array(useState(-1), 2), cellIndex = _useState[0], setCellIndex = _useState[1];
973
983
  var cellIndexRef = useRef(null);
974
984
  var setCellRef = useCallback(function(node) {
975
985
  if (!node || cellIndexRef.current !== null) return;
@@ -977,16 +987,21 @@ Table.Row.displayName = "Table.Row";
977
987
  if ((parentRow === null || parentRow === void 0 ? void 0 : parentRow.tagName) === "TR") {
978
988
  var totalCells = parentRow.children.length;
979
989
  var index = node.cellIndex;
980
- cellIndexRef.current = reverseColumns ? totalCells - columnsToRender + index - (totalCells - columnCount) : index;
990
+ var calculatedIndex = reverseColumns ? totalCells - columnsToRender + index - (totalCells - columnCount) : index;
991
+ cellIndexRef.current = calculatedIndex;
992
+ setCellIndex(calculatedIndex);
981
993
  }
982
994
  }, [
983
995
  reverseColumns,
984
996
  columnsToRender,
985
997
  columnCount
986
998
  ]);
987
- var _cellIndexRef_current;
988
- var cellIndex = (_cellIndexRef_current = cellIndexRef.current) !== null && _cellIndexRef_current !== void 0 ? _cellIndexRef_current : -1;
989
999
  var alignment = (cellAlignment === null || cellAlignment === void 0 ? void 0 : cellAlignment[cellIndex]) || _alignment;
1000
+ // Check if this cell is covered by a fixed overlay
1001
+ // When cellIndex is unknown (-1), conservatively assume the cell might be covered
1002
+ // if there are any fixed columns. This prevents duplicate popovers during the
1003
+ // brief window between initial render and when cellIndex is calculated.
1004
+ var isCoveredByFixedOverlay = !isFixedOverlay && !reverseColumns && (cellIndex === -1 ? fixedFirstColumns > 0 || fixedLastColumns > 0 : fixedFirstColumns > 0 && cellIndex < fixedFirstColumns || fixedLastColumns > 0 && cellIndex >= columnCount - fixedLastColumns);
990
1005
  return /*#__PURE__*/ _jsx("td", {
991
1006
  ref: setCellRef,
992
1007
  className: styles.cellStyles({
@@ -997,6 +1012,7 @@ Table.Row.displayName = "Table.Row";
997
1012
  tableIsSelectable: selectable,
998
1013
  noBodyCellPadding: noBodyCellPadding
999
1014
  }),
1015
+ inert: !isMobile && isCoveredByFixedOverlay || undefined,
1000
1016
  children: /*#__PURE__*/ _jsx("div", {
1001
1017
  className: styles.cellContentStyles({
1002
1018
  alignment: alignment
@@ -106,6 +106,7 @@ import Icon from "./Icon.js";
106
106
  import Popover from "./Popover.js";
107
107
  import { CaretDownMinor, CaretUpMinor } from "@shopify/polaris-icons";
108
108
  import * as PolarisIcons from "@shopify/polaris-icons";
109
+ import Badge from "./Badge.js";
109
110
  var styles = tv({
110
111
  base: "Litho-Tabs flex overflow-x-hidden whitespace-nowrap",
111
112
  variants: {
@@ -140,6 +141,8 @@ var containerStyles = tv({
140
141
  * @param {boolean} [props.padded=true] - If true, applies padding to the Tabs container.
141
142
  * @param {boolean} [props.borderBottom=true] - If true, applies a bottom border to the Tabs container.
142
143
  * @param {boolean} [props.simpleTabs=false] - If true, simplifies the styling for the selected tab.
144
+ * @param {number} [props.badgeCount] - The number of badges to display for the tab.
145
+ * @param {string} [props.badgeStatus="default"] - The status of the badge.
143
146
  * @returns {JSX.Element} The Tabs component.
144
147
  */ function Tabs() {
145
148
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
@@ -253,6 +256,8 @@ var containerStyles = tv({
253
256
  fullWidth: fullWidth,
254
257
  hidden: tab.hidden,
255
258
  simple: simpleTabs,
259
+ badgeCount: tab.badgeCount,
260
+ badgeStatus: tab.badgeStatus,
256
261
  children: tab.content
257
262
  }, "tab-".concat(tab.originalIndex));
258
263
  })
@@ -345,9 +350,30 @@ var tabStyles = tv({
345
350
  }
346
351
  ]
347
352
  });
348
- function Tab() {
353
+ /**
354
+ * Individual tab item component used within the Tabs component.
355
+ *
356
+ * @param {Object} props - Component props.
357
+ * @param {string} [props.id] - Unique identifier for the tab, used to generate the DOM element ID.
358
+ * @param {boolean} [props.active] - Whether the tab's disclosure popover is currently active/open.
359
+ * @param {boolean} [props.selected] - Whether this tab is currently selected.
360
+ * @param {number} [props.index] - The index position of this tab in the tabs array.
361
+ * @param {string|React.ReactNode} [props.icon] - Icon to display. Can be a Polaris icon name string or a custom React node.
362
+ * @param {Function} [props.onSelect] - Callback fired when the tab is selected, receives the tab's index.
363
+ * @param {Function} [props.onClick] - Custom click handler that overrides the default onSelect behavior.
364
+ * @param {React.ReactNode} [props.children] - The content/label to display inside the tab.
365
+ * @param {boolean} [props.fullWidth] - Whether the tab should expand to fill available space.
366
+ * @param {boolean} [props.hidden] - Whether the tab should be visually hidden (used for overflow handling).
367
+ * @param {boolean} [props.simple] - Whether to use simplified styling (no background, column layout).
368
+ * @param {boolean} [props.disclosure=false] - Whether to show a disclosure caret icon when selected.
369
+ * @param {boolean} [props.alwaysShowDisclosureIcon=false] - Whether to always show the disclosure icon regardless of selection state.
370
+ * @param {boolean} [props.disabled=false] - Whether the tab is disabled.
371
+ * @param {string} [props.badgeStatus="default"] - The status variant of the badge (e.g., "default", "success", "warning").
372
+ * @param {number} [props.badgeCount] - If provided (>= 0), displays a badge with this count.
373
+ * @returns {JSX.Element} The Tab component.
374
+ */ function Tab() {
349
375
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
350
- var id = props.id, active = props.active, selected = props.selected, index = props.index, icon = props.icon, onSelect = props.onSelect, onClick = props.onClick, children = props.children, fullWidth = props.fullWidth, hidden = props.hidden, simple = props.simple, _props_disclosure = props.disclosure, disclosure = _props_disclosure === void 0 ? false : _props_disclosure, _props_alwaysShowDisclosureIcon = props.alwaysShowDisclosureIcon, alwaysShowDisclosureIcon = _props_alwaysShowDisclosureIcon === void 0 ? false : _props_alwaysShowDisclosureIcon, _props_disabled = props.disabled, disabled = _props_disabled === void 0 ? false : _props_disabled;
376
+ var id = props.id, active = props.active, selected = props.selected, index = props.index, icon = props.icon, onSelect = props.onSelect, onClick = props.onClick, children = props.children, fullWidth = props.fullWidth, hidden = props.hidden, simple = props.simple, _props_disclosure = props.disclosure, disclosure = _props_disclosure === void 0 ? false : _props_disclosure, _props_alwaysShowDisclosureIcon = props.alwaysShowDisclosureIcon, alwaysShowDisclosureIcon = _props_alwaysShowDisclosureIcon === void 0 ? false : _props_alwaysShowDisclosureIcon, _props_disabled = props.disabled, disabled = _props_disabled === void 0 ? false : _props_disabled, _props_badgeStatus = props.badgeStatus, badgeStatus = _props_badgeStatus === void 0 ? "default" : _props_badgeStatus, badgeCount = props.badgeCount;
351
377
  var polarisIcon = typeof icon === "string" ? PolarisIcons[icon] : PolarisIcons[icon === null || icon === void 0 ? void 0 : icon.displayName];
352
378
  var showDisclosure = disclosure && (selected || alwaysShowDisclosureIcon);
353
379
  var tabClasses = tabStyles({
@@ -388,6 +414,11 @@ function Tab() {
388
414
  color: selected && simple ? "default" : selected ? "active" : "subdued",
389
415
  size: simple ? "lg" : undefined
390
416
  })
417
+ }),
418
+ badgeCount >= 0 && /*#__PURE__*/ _jsx(Badge, {
419
+ status: badgeStatus,
420
+ className: "ml-1",
421
+ children: badgeCount
391
422
  })
392
423
  ]
393
424
  });