@dmsi/wedgekit-react 0.0.551 → 0.0.552

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 (137) hide show
  1. package/package.json +2 -3
  2. package/src/brand.css +0 -125
  3. package/src/classNames.ts +0 -174
  4. package/src/components/AccessChangerTabItem.tsx +0 -71
  5. package/src/components/Accordion.tsx +0 -108
  6. package/src/components/Alert.tsx +0 -81
  7. package/src/components/Breadcrumbs.tsx +0 -142
  8. package/src/components/Button.tsx +0 -216
  9. package/src/components/CalendarRange.tsx +0 -628
  10. package/src/components/Caption.tsx +0 -144
  11. package/src/components/Card.tsx +0 -88
  12. package/src/components/Checkbox.tsx +0 -206
  13. package/src/components/CompactImagesPreview.tsx +0 -135
  14. package/src/components/ContentTab.tsx +0 -84
  15. package/src/components/ContentTabs.tsx +0 -136
  16. package/src/components/DMSiLogo.tsx +0 -33
  17. package/src/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.tsx +0 -35
  18. package/src/components/DataGrid/ColumnSelectorHeaderCell/index.tsx +0 -74
  19. package/src/components/DataGrid/PinnedColumns.tsx +0 -183
  20. package/src/components/DataGrid/TableBody/LoadingCell.tsx +0 -44
  21. package/src/components/DataGrid/TableBody/TableBodyRow.tsx +0 -157
  22. package/src/components/DataGrid/TableBody/index.tsx +0 -185
  23. package/src/components/DataGrid/index.tsx +0 -756
  24. package/src/components/DataGrid/types.ts +0 -98
  25. package/src/components/DataGrid/utils.tsx +0 -15
  26. package/src/components/DataGridCell.tsx +0 -526
  27. package/src/components/DataTable.tsx +0 -881
  28. package/src/components/DateInput.tsx +0 -306
  29. package/src/components/DateRangeInput.tsx +0 -758
  30. package/src/components/DebugJson.tsx +0 -28
  31. package/src/components/Display.tsx +0 -66
  32. package/src/components/EditingContext.tsx +0 -43
  33. package/src/components/EmptyCartIcon.tsx +0 -18
  34. package/src/components/FilterGroup.tsx +0 -264
  35. package/src/components/FullViewportBox.tsx +0 -19
  36. package/src/components/Grid.tsx +0 -97
  37. package/src/components/Heading.tsx +0 -72
  38. package/src/components/HorizontalDivider.tsx +0 -22
  39. package/src/components/Icon.tsx +0 -39
  40. package/src/components/ImagePlaceholder.tsx +0 -22
  41. package/src/components/Input.tsx +0 -609
  42. package/src/components/InputGroup.tsx +0 -59
  43. package/src/components/Label.tsx +0 -46
  44. package/src/components/Link.tsx +0 -117
  45. package/src/components/List.tsx +0 -18
  46. package/src/components/ListGroup.tsx +0 -82
  47. package/src/components/LiveChatComponent.tsx +0 -56
  48. package/src/components/LoadingScrim.tsx +0 -33
  49. package/src/components/LogoAgilityTopBar.tsx +0 -54
  50. package/src/components/LogoDMSiTopBar.tsx +0 -33
  51. package/src/components/LogoMillworkTopBar.tsx +0 -119
  52. package/src/components/MainBar.tsx +0 -91
  53. package/src/components/MaxViewportBox.tsx +0 -19
  54. package/src/components/Menu.tsx +0 -316
  55. package/src/components/MenuOption.tsx +0 -330
  56. package/src/components/MobileDataGrid/ColumnList.tsx +0 -66
  57. package/src/components/MobileDataGrid/ColumnSelector/index.tsx +0 -97
  58. package/src/components/MobileDataGrid/GridContextProvider/GridContext.tsx +0 -25
  59. package/src/components/MobileDataGrid/GridContextProvider/index.tsx +0 -132
  60. package/src/components/MobileDataGrid/GridContextProvider/useGridContext.ts +0 -10
  61. package/src/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.tsx +0 -27
  62. package/src/components/MobileDataGrid/MobileDataGridCard/index.tsx +0 -138
  63. package/src/components/MobileDataGrid/MobileDataGridHeader.tsx +0 -81
  64. package/src/components/MobileDataGrid/RowDetailModalProvider/ModalContent.tsx +0 -42
  65. package/src/components/MobileDataGrid/RowDetailModalProvider/index.tsx +0 -68
  66. package/src/components/MobileDataGrid/dataGridReducer.ts +0 -55
  67. package/src/components/MobileDataGrid/index.tsx +0 -92
  68. package/src/components/MobileDataGrid/types.ts +0 -4
  69. package/src/components/Modal.tsx +0 -312
  70. package/src/components/ModalButtons.tsx +0 -62
  71. package/src/components/ModalContent.tsx +0 -31
  72. package/src/components/ModalHeader.tsx +0 -78
  73. package/src/components/ModalScrim.tsx +0 -42
  74. package/src/components/NavigationTab.tsx +0 -95
  75. package/src/components/NavigationTabs.tsx +0 -70
  76. package/src/components/NestedMenu.tsx +0 -131
  77. package/src/components/Notification.tsx +0 -128
  78. package/src/components/OptionPill.tsx +0 -139
  79. package/src/components/OrderCheckIcon.tsx +0 -19
  80. package/src/components/PDFViewer/DownloadIcon.tsx +0 -25
  81. package/src/components/PDFViewer/PDFElement.tsx +0 -90
  82. package/src/components/PDFViewer/PDFNavigation.tsx +0 -68
  83. package/src/components/PDFViewer/PDFPage.tsx +0 -34
  84. package/src/components/PDFViewer/index.tsx +0 -128
  85. package/src/components/Pagination.tsx +0 -182
  86. package/src/components/Paragraph.tsx +0 -55
  87. package/src/components/Password.tsx +0 -62
  88. package/src/components/ProductImagePreview/CarouselPagination.tsx +0 -54
  89. package/src/components/ProductImagePreview/MobileImageCarousel.tsx +0 -226
  90. package/src/components/ProductImagePreview/ProductPrimaryImage.tsx +0 -219
  91. package/src/components/ProductImagePreview/Thumbnail.tsx +0 -55
  92. package/src/components/ProductImagePreview/ZoomWindow.tsx +0 -136
  93. package/src/components/ProductImagePreview/index.tsx +0 -182
  94. package/src/components/ProductImagePreview/useProductImagePreview.ts +0 -211
  95. package/src/components/ProjectBar.tsx +0 -82
  96. package/src/components/Radio.tsx +0 -146
  97. package/src/components/Search.tsx +0 -152
  98. package/src/components/SearchResultImage/index.tsx +0 -39
  99. package/src/components/Select.tsx +0 -114
  100. package/src/components/SideMenu.tsx +0 -30
  101. package/src/components/SideMenuGroup.tsx +0 -95
  102. package/src/components/SideMenuItem.tsx +0 -109
  103. package/src/components/SimpleTable.tsx +0 -77
  104. package/src/components/SkeletonParagraph.tsx +0 -31
  105. package/src/components/Spinner.tsx +0 -32
  106. package/src/components/Stack.tsx +0 -347
  107. package/src/components/StatusPill.tsx +0 -59
  108. package/src/components/Stepper.tsx +0 -128
  109. package/src/components/Subheader.tsx +0 -50
  110. package/src/components/Surface.tsx +0 -37
  111. package/src/components/Swatch.tsx +0 -1341
  112. package/src/components/Textarea.tsx +0 -102
  113. package/src/components/Theme.tsx +0 -27
  114. package/src/components/Time.tsx +0 -460
  115. package/src/components/Toast.tsx +0 -268
  116. package/src/components/Tooltip.tsx +0 -159
  117. package/src/components/TopBar.tsx +0 -139
  118. package/src/components/Upload.tsx +0 -107
  119. package/src/components/WorldpayIframe.tsx +0 -7
  120. package/src/components/index.ts +0 -34
  121. package/src/components/useMenuSystem.tsx +0 -456
  122. package/src/components/useMounted.tsx +0 -14
  123. package/src/darkmode.css +0 -278
  124. package/src/fonts.css +0 -23
  125. package/src/hooks/index.ts +0 -4
  126. package/src/hooks/useInfiniteScroll.tsx +0 -40
  127. package/src/hooks/useKeydown.ts +0 -42
  128. package/src/hooks/useMatchesMedia.ts +0 -18
  129. package/src/hooks/useTableLayout.ts +0 -106
  130. package/src/index.css +0 -800
  131. package/src/index.tsx +0 -5
  132. package/src/types.ts +0 -150
  133. package/src/utils/date.ts +0 -236
  134. package/src/utils/formatting.tsx +0 -81
  135. package/src/utils/index.ts +0 -4
  136. package/src/utils/mergeObjectArrays.ts +0 -18
  137. package/src/utils.ts +0 -24
@@ -1,144 +0,0 @@
1
- import clsx from "clsx";
2
- import { AsProps, IconSize, TextAttributes, TypographyProps } from "../types";
3
- import { typography } from "../classNames";
4
- import { Icon } from "./Icon";
5
-
6
- type Tags = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "span" | "p" | "li";
7
- type Style = {
8
- style?: "default" | "success" | "warning" | "error" | "info";
9
- };
10
-
11
- type CaptionProps = {
12
- as?: Tags;
13
- style?: Style["style"];
14
- id?: string;
15
- testid?: string;
16
- marginTopDesktop?: boolean;
17
- } & AsProps<Tags> &
18
- TextAttributes &
19
- TypographyProps;
20
-
21
- export const Caption = ({
22
- className,
23
- children,
24
- as = "span",
25
- style = "default",
26
- color,
27
- align,
28
- id,
29
- testid,
30
- marginTopDesktop,
31
- ...props
32
- }: CaptionProps) => {
33
- const Element = as;
34
-
35
- return (
36
- <div id={id} data-testid={testid} className="flex gap-1">
37
- <WhichIcon
38
- id={id}
39
- testid={testid}
40
- style={style}
41
- size={16}
42
- className="mt-[3px] desktop:mt-0"
43
- />
44
-
45
- <Element
46
- id={id ? `${id}-text` : undefined}
47
- data-testid={testid ? `${testid}-text` : undefined}
48
- className={clsx(
49
- typography.caption.replace("text-text-primary-normal", ""),
50
- (style === "default" || style === "info") &&
51
- "text-text-secondary-normal",
52
- style === "success" && "text-text-success-normal",
53
- style === "warning" && "text-text-warning-normal",
54
- style === "error" && "text-text-critical-normal",
55
- align === "left" && "text-left",
56
- align === "center" && "text-center",
57
- align === "right" && "text-right",
58
- className,
59
- marginTopDesktop && `desktop:mt-px`,
60
- )}
61
- {...props}
62
- style={{
63
- color: color ? `var(--color-${color})` : undefined,
64
- }}
65
- >
66
- {children}
67
- </Element>
68
- </div>
69
- );
70
- };
71
-
72
- const WhichIcon = ({
73
- style,
74
- size,
75
- className,
76
- id,
77
- testid,
78
- }: {
79
- style: Style["style"];
80
- size: IconSize;
81
- className?: string;
82
- id?: string;
83
- testid?: string;
84
- }) => {
85
- if (style === "success") {
86
- return (
87
- <span className="text-icon-success-normal contents">
88
- <Icon
89
- id={id ? `${id}-icon` : undefined}
90
- testid={testid ? `${testid}-icon` : undefined}
91
- className={className}
92
- name="check_circle"
93
- size={size}
94
- />
95
- </span>
96
- );
97
- }
98
-
99
- if (style === "warning") {
100
- return (
101
- <span className="text-icon-warning-normal contents">
102
- <Icon
103
- id={id ? `${id}-icon` : undefined}
104
- testid={testid ? `${testid}-icon` : undefined}
105
- className={className}
106
- name="warning"
107
- size={size}
108
- />
109
- </span>
110
- );
111
- }
112
-
113
- if (style === "error") {
114
- return (
115
- <span className="text-icon-critical-normal contents">
116
- <Icon
117
- id={id ? `${id}-icon` : undefined}
118
- testid={testid ? `${testid}-icon` : undefined}
119
- className={className}
120
- name="info"
121
- size={size}
122
- />
123
- </span>
124
- );
125
- }
126
-
127
- if (style === "info") {
128
- return (
129
- <span className="text-icon-primary-normal contents">
130
- <Icon
131
- id={id ? `${id}-icon` : undefined}
132
- testid={testid ? `${testid}-icon` : undefined}
133
- className={className}
134
- name="info"
135
- size={size}
136
- />
137
- </span>
138
- );
139
- }
140
-
141
- return null;
142
- };
143
-
144
- Caption.displayName = "Caption";
@@ -1,88 +0,0 @@
1
- import clsx from "clsx";
2
- import { HTMLProps } from "react";
3
-
4
- type Tags = "a" | "div" | React.ElementType;
5
- export function Card(
6
- props: HTMLProps<HTMLDivElement | HTMLAnchorElement> & {
7
- selected?: boolean;
8
- testid?: string;
9
- as?: Tags;
10
- /**
11
- * When true applies both horizontal and vertical padding using layout spacing tokens.
12
- * If none of padding / paddingX / paddingY are provided the original desktop-only padding class is applied for backward compatibility.
13
- */
14
- padding?: boolean;
15
- /** Horizontal only padding (overrides padding for X axis if both supplied). */
16
- paddingX?: boolean;
17
- /** Vertical only padding (overrides padding for Y axis if both supplied). */
18
- paddingY?: boolean;
19
- /** Bottom only padding */
20
- paddingBottom?: boolean;
21
- /** Top only padding */
22
- paddingTop?: boolean;
23
- /** Left only padding */
24
- paddingLeft?: boolean;
25
- /** Right only padding */
26
- paddingRight?: boolean;
27
- },
28
- ) {
29
- const {
30
- children,
31
- selected,
32
- testid,
33
- padding,
34
- paddingX,
35
- paddingY,
36
- paddingBottom,
37
- paddingTop,
38
- paddingLeft,
39
- paddingRight,
40
- ...rest
41
- } = props;
42
-
43
- const CardComponent = props.as || "div";
44
- const anyPaddingPropSpecified =
45
- padding !== undefined ||
46
- paddingX !== undefined ||
47
- paddingY !== undefined ||
48
- paddingBottom !== undefined ||
49
- paddingTop !== undefined ||
50
- paddingLeft !== undefined ||
51
- paddingRight !== undefined;
52
-
53
- const paddingClasses = clsx(
54
- // Backward compatibility: if no new padding props provided keep existing class.
55
- !anyPaddingPropSpecified && "p-desktop-layout-padding",
56
- // New responsive spacing tokens (mirrors Stack for layout sizing)
57
- padding &&
58
- "p-mobile-layout-padding desktop:p-desktop-layout-padding compact:p-desktop-compact-layout-padding",
59
- paddingX &&
60
- "px-mobile-layout-padding desktop:px-desktop-layout-padding compact:px-desktop-compact-layout-padding",
61
- paddingY &&
62
- "py-mobile-layout-padding desktop:py-desktop-layout-padding compact:py-desktop-compact-layout-padding",
63
- paddingBottom &&
64
- "pb-mobile-layout-padding desktop:pb-desktop-layout-padding compact:pb-desktop-compact-layout-padding",
65
- paddingTop &&
66
- "pt-mobile-layout-padding desktop:pt-desktop-layout-padding compact:pt-desktop-compact-layout-padding",
67
- paddingLeft &&
68
- "pl-mobile-layout-padding desktop:pl-desktop-layout-padding compact:pl-desktop-compact-layout-padding",
69
- paddingRight &&
70
- "pr-mobile-layout-padding desktop:pr-desktop-layout-padding compact:pr-desktop-compact-layout-padding",
71
- );
72
- return (
73
- <CardComponent
74
- {...rest}
75
- data-testid={testid}
76
- className={clsx(
77
- "rounded-sm",
78
- paddingClasses,
79
- selected
80
- ? "border-2 border-border-primary-focus"
81
- : "border border-border-primary-normal",
82
- rest.className,
83
- )}
84
- >
85
- {children}
86
- </CardComponent>
87
- );
88
- }
@@ -1,206 +0,0 @@
1
- "use client";
2
- import clsx from "clsx";
3
- import { ComponentProps } from "react";
4
- import { baseTransition, componentGap } from "../classNames";
5
- import { Icon } from "./Icon";
6
- import { Paragraph } from "./Paragraph";
7
-
8
- interface CheckboxProps
9
- extends Omit<
10
- ComponentProps<"input">,
11
- "type" | "className" | "children" | "dangerouslySetInnerHTML" | "id"
12
- > {
13
- label?: string;
14
- error?: boolean;
15
- indeterminate?: boolean;
16
- paragraphClassName?: string;
17
- id?: string;
18
- testid?: string;
19
- }
20
-
21
- export const Checkbox = ({
22
- label,
23
- error,
24
- disabled,
25
- readOnly,
26
- checked,
27
- onChange,
28
- indeterminate,
29
- paragraphClassName,
30
- id,
31
- testid,
32
- ...props
33
- }: CheckboxProps) => {
34
- const selected = indeterminate || checked;
35
-
36
- const normalClassName = clsx(
37
- !selected &&
38
- !error &&
39
- !disabled &&
40
- !readOnly &&
41
- "border-border-primary-normal bg-background-action-secondary-normal peer-hover:border-border-action-hover peer-hover:bg-background-action-secondary-hover peer-active:border-border-action-active peer-active:bg-background-action-secondary-active",
42
- );
43
-
44
- const normalSelectedClassName = clsx(
45
- selected &&
46
- !error &&
47
- !disabled &&
48
- !readOnly &&
49
- "bg-background-action-primary-normal border-background-action-primary-normal peer-hover:bg-background-action-primary-hover peer-hover:border-background-action-primary-hover peer-active:bg-background-action-primary-active peer-active:border-background-action-primary-active",
50
- );
51
-
52
- const errorClassName = clsx(
53
- error &&
54
- !selected &&
55
- "bg-background-action-critical-secondary-normal border-border-action-critical-normal peer-hover:border-border-action-critical-hover peer-hover:bg-background-action-critical-secondary-hover peer-active:border-border-action-critical-active peer-active:bg-background-action-secondary-active",
56
- );
57
-
58
- const errorSelectedClassName = clsx(
59
- error &&
60
- selected &&
61
- "bg-background-action-critical-primary-normal border-background-action-critical-primary-normal peer-hover:bg-background-action-critical-primary-hover peer-hover:border-background-action-critical-primary-hover peer-active:bg-background-action-critical-primary-active peer-active:border-background-action-critical-primary-active",
62
- );
63
-
64
- const disabledClassName = clsx(
65
- disabled &&
66
- !readOnly &&
67
- "border-border-primary-normal bg-background-action-secondary-disabled peer-checked:bg-icon-on-action-primary-disabled peer-checked:border-icon-on-action-primary-disabled",
68
- );
69
-
70
- const readOnlyClassName = clsx(
71
- readOnly &&
72
- "border-transparent bg-transparent peer-checked:bg-transparent peer-checked:border-transparent",
73
- );
74
-
75
- const checkColor = clsx(
76
- selected &&
77
- !disabled &&
78
- !readOnly &&
79
- "color-icon-on-action-primary-normal peer-hover:color-icon-on-action-primary-hover peer-active:color-icon-on-action-primary-active",
80
- selected && disabled && "color-background-action-primary-disabled",
81
- );
82
-
83
- return (
84
- <label
85
- id={id}
86
- data-testid={testid}
87
- htmlFor={id ? `${id}-input` : undefined}
88
- className={clsx(
89
- "flex items-center",
90
- componentGap,
91
- (disabled || (readOnly && error) || readOnly) && "cursor-default",
92
- !(readOnly && error) && !disabled && !readOnly && "cursor-pointer",
93
- )}
94
- >
95
- <div className="relative">
96
- <input
97
- id={id ? `${id}-input` : undefined}
98
- data-testid={testid ? `${testid}-input` : undefined}
99
- type="checkbox"
100
- className="sr-only peer"
101
- disabled={disabled}
102
- checked={selected}
103
- onChange={handleOnChange}
104
- data-indeterminate={indeterminate}
105
- {...props}
106
- />
107
-
108
- {error && (readOnly || disabled) ? (
109
- <div className={clsx("size-6", "flex items-center justify-center")}>
110
- {selected ? (
111
- indeterminate ? (
112
- <span className="text-icon-primary-normal contents">
113
- <Icon name="question_mark" />
114
- </span>
115
- ) : readOnly ? (
116
- <span className="text-success-400 contents">
117
- <Icon name="check" />
118
- </span>
119
- ) : (
120
- <span className="text-icon-on-action-primary-normal contents">
121
- <Icon name="check" className="pointer-events-none" />
122
- </span>
123
- )
124
- ) : (
125
- readOnly && (
126
- <span className="text-icon-primary-normal contents">
127
- <Icon name="close" />
128
- </span>
129
- )
130
- )}
131
- </div>
132
- ) : (
133
- <div
134
- className={clsx(
135
- "size-6 border rounded-base",
136
- "flex items-center justify-center",
137
- baseTransition,
138
- normalClassName,
139
- normalSelectedClassName,
140
- errorClassName,
141
- errorSelectedClassName,
142
- disabledClassName,
143
- readOnlyClassName,
144
- checkColor,
145
- )}
146
- >
147
- {selected ? (
148
- indeterminate ? (
149
- readOnly ? (
150
- <span className="text-icon-primary-normal contents">
151
- <Icon name="question_mark" />
152
- </span>
153
- ) : (
154
- <span className="text-icon-on-action-primary-normal contents">
155
- <Icon name="remove" className="pointer-events-none" />
156
- </span>
157
- )
158
- ) : readOnly ? (
159
- <span className="text-success-400 contents">
160
- <Icon name="check" />
161
- </span>
162
- ) : (
163
- <span className="text-icon-on-action-primary-normal contents">
164
- <Icon name="check" className="pointer-events-none" />
165
- </span>
166
- )
167
- ) : (
168
- readOnly && (
169
- <span className="text-icon-primary-normal contents">
170
- <Icon name="close" />
171
- </span>
172
- )
173
- )}
174
- </div>
175
- )}
176
- </div>
177
-
178
- {label && (
179
- <Paragraph
180
- id={id ? `${id}-label` : undefined}
181
- testid={testid ? `${testid}-label` : undefined}
182
- as="span"
183
- padded
184
- className={clsx(
185
- "text-nowrap",
186
- disabled && !error && "!text-text-primary-disabled",
187
- error && !disabled && !readOnly && "!text-text-primary-error",
188
- paragraphClassName,
189
- )}
190
- >
191
- {label}
192
- </Paragraph>
193
- )}
194
- </label>
195
- );
196
-
197
- function handleOnChange(e: React.ChangeEvent<HTMLInputElement>): void {
198
- if (disabled || readOnly || (readOnly && error) || !onChange) {
199
- return;
200
- }
201
-
202
- onChange(e);
203
- }
204
- };
205
-
206
- Checkbox.displayName = "Checkbox";
@@ -1,135 +0,0 @@
1
- import { useCallback } from "react";
2
- import { Stack } from "./Stack";
3
- import clsx from "clsx";
4
- import { useMatchesMobile } from "../hooks";
5
-
6
- type ImageSource = { uri: string; name: string };
7
-
8
- type CompactImagesPreviewProps = {
9
- sources: ImageSource[];
10
- currentSourceIndex: number;
11
- placeholderImageUri?: string;
12
- /**
13
- * Optional alt text to use when falling back to the placeholder image due to an image load error
14
- * or when there are no valid sources. Defaults to "placeholder image".
15
- */
16
- placeholderAlt?: string;
17
- activeImageWidth?: number | string;
18
- activeImageHeight?: number | string;
19
- thumbnailWidth?: number;
20
- thumbnailHeight?: number;
21
- enableThumbnailBorder?: boolean;
22
- onChangeSource: (newIndex: number) => void;
23
- onMainImageClick?: () => void;
24
- testid?: string;
25
- };
26
- export function CompactImagesPreview(props: CompactImagesPreviewProps) {
27
- const {
28
- sources,
29
- currentSourceIndex = 0,
30
- activeImageHeight = 243,
31
- activeImageWidth = 242,
32
- thumbnailWidth = 30.5,
33
- thumbnailHeight = 30,
34
- enableThumbnailBorder = false,
35
- placeholderImageUri,
36
- placeholderAlt = "placeholder image",
37
- onChangeSource,
38
- onMainImageClick,
39
- testid,
40
- } = props;
41
- const isMobile = useMatchesMobile();
42
- const imagesCount = sources.length;
43
-
44
- const handleImgError = useCallback(
45
- (e: React.SyntheticEvent<HTMLImageElement>) => {
46
- if (!placeholderImageUri) return;
47
- const img = e.currentTarget;
48
- // Prevent infinite loop if placeholder also 404s
49
- if (img.src === placeholderImageUri) return;
50
- img.src = placeholderImageUri;
51
- if (!img.alt) img.alt = placeholderAlt;
52
- },
53
- [placeholderImageUri, placeholderAlt],
54
- );
55
-
56
- const handleThumbnailClick = useCallback(
57
- (newIndex: number) => {
58
- if (newIndex === currentSourceIndex) return;
59
- if (newIndex < 0 || newIndex >= imagesCount) return;
60
- onChangeSource(newIndex);
61
- },
62
- [currentSourceIndex, onChangeSource, imagesCount],
63
- );
64
-
65
- if (
66
- !sources.length ||
67
- currentSourceIndex >= sources.length ||
68
- typeof isMobile === "undefined"
69
- )
70
- return (
71
- <img
72
- data-testid={testid ? `${testid}-placeholder` : undefined}
73
- className="object-center"
74
- style={{
75
- width: activeImageWidth,
76
- height: activeImageHeight,
77
- objectPosition: "center",
78
- objectFit: "cover",
79
- }}
80
- src={placeholderImageUri}
81
- alt={placeholderAlt}
82
- onError={handleImgError}
83
- onClick={onMainImageClick}
84
- />
85
- );
86
- const currentSource = sources[currentSourceIndex];
87
- return (
88
- <Stack data-testid={testid} sizing="layout">
89
- <img
90
- data-testid={testid ? `${testid}-main-image` : undefined}
91
- className={clsx("object-center", onMainImageClick && "cursor-pointer")}
92
- style={{
93
- width: isMobile ? "100%" : activeImageWidth,
94
- height: activeImageHeight,
95
- objectPosition: "center",
96
- objectFit: "cover",
97
- }}
98
- src={currentSource.uri}
99
- alt={currentSource.name}
100
- onError={handleImgError}
101
- onClick={onMainImageClick}
102
- />
103
- <div className="flex flex-row flex-wrap items-center gap-3">
104
- {sources.slice(0, 4).map((source, index) => (
105
- <button
106
- key={`compact-image-${source.uri}-${index}`}
107
- data-testid={testid ? `${testid}-thumbnail-${index}` : undefined}
108
- onClick={(e) => {
109
- e.preventDefault();
110
- handleThumbnailClick(index);
111
- }}
112
- className={clsx(
113
- "cursor-pointer",
114
- currentSourceIndex === index && enableThumbnailBorder
115
- ? "ring-2 ring-offset-2 ring-brand-400 transition-discrete duration-300"
116
- : "ring-brand-400/0",
117
- )}
118
- >
119
- <img
120
- src={source.uri}
121
- alt={source.name}
122
- style={{
123
- width: thumbnailWidth,
124
- height: thumbnailHeight,
125
- objectPosition: "center",
126
- objectFit: "cover",
127
- }}
128
- onError={handleImgError}
129
- />
130
- </button>
131
- ))}
132
- </div>
133
- </Stack>
134
- );
135
- }
@@ -1,84 +0,0 @@
1
- "use client";
2
-
3
- import clsx from "clsx";
4
- import React, { ComponentPropsWithRef, useCallback } from "react";
5
- import { Button } from "./Button";
6
-
7
- export type ContentTabProps = {
8
- label?: string;
9
- onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
10
- selected?: boolean;
11
- className?: string;
12
- fullWidth?: boolean;
13
- id?: string;
14
- testid?: string;
15
- } & Omit<ComponentPropsWithRef<"button">, "id">;
16
-
17
- export const ContentTab = ({
18
- label,
19
- selected = false,
20
- className,
21
- disabled = false,
22
- onClick,
23
- ref,
24
- fullWidth,
25
- id,
26
- testid,
27
- ...props
28
- }: ContentTabProps) => {
29
- const handleClick = useCallback(
30
- (e: React.MouseEvent<HTMLButtonElement>) => {
31
- if (!disabled) {
32
- onClick?.(e);
33
- }
34
- },
35
- [onClick, disabled],
36
- );
37
-
38
- const computedClassName = clsx(
39
- "absolute left-0 right-0 bottom-0 transition-colors duration-200 ease-in-out z-10",
40
- "rounded-px ",
41
- "h-0.5",
42
- !disabled && "bg-text-action-primary-normal peer-hover:bg-border-action-hover peer-active:bg-border-action-active",
43
- disabled && "bg-text-action-primary-disabled",
44
-
45
- className,
46
- );
47
-
48
- return (
49
- <div id={id} data-testid={testid} className={clsx(
50
- "relative",
51
- fullWidth && "flex-1"
52
- )}>
53
- <Button
54
- id={id ? `${id}-button` : undefined}
55
- testid={testid ? `${testid}-button` : undefined}
56
- block={fullWidth}
57
- ref={ref}
58
- variant="tertiary"
59
- disabled={disabled}
60
- onClick={handleClick}
61
- role="tab"
62
- aria-selected={selected}
63
- className={clsx(
64
- "peer",
65
- !selected && "!text-text-secondary-normal hover:!text-text-action-primary-hover active:!text-text-action-primary-active"
66
- )}
67
- {...props}
68
- >
69
- {label}
70
- </Button>
71
- {selected && (
72
- <div
73
- id={id ? `${id}-indicator` : undefined}
74
- data-testid={testid ? `${testid}-indicator` : undefined}
75
- className={computedClassName}
76
- >
77
- {" "}
78
- </div>
79
- )}
80
- </div>
81
- );
82
- };
83
-
84
- ContentTab.displayName = "ContentTab";