@xsolla/xui-table 0.151.0-pr273.1778117489

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.
package/web/index.mjs ADDED
@@ -0,0 +1,756 @@
1
+ // src/Table.tsx
2
+ import React3, {
3
+ createContext,
4
+ forwardRef,
5
+ useCallback,
6
+ useContext,
7
+ useEffect,
8
+ useMemo,
9
+ useState
10
+ } from "react";
11
+
12
+ // ../../foundation/primitives-web/src/Box.tsx
13
+ import React2 from "react";
14
+ import styled from "styled-components";
15
+
16
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
17
+ import React from "react";
18
+
19
+ // ../../../node_modules/@emotion/memoize/dist/memoize.esm.js
20
+ function memoize(fn) {
21
+ var cache = {};
22
+ return function(arg) {
23
+ if (cache[arg] === void 0) cache[arg] = fn(arg);
24
+ return cache[arg];
25
+ };
26
+ }
27
+ var memoize_esm_default = memoize;
28
+
29
+ // ../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js
30
+ var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;
31
+ var index = memoize_esm_default(
32
+ function(prop) {
33
+ return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
34
+ }
35
+ /* Z+1 */
36
+ );
37
+ var is_prop_valid_esm_default = index;
38
+
39
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
40
+ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
41
+ // RN-only event handlers (pass isPropValid's on* pattern)
42
+ "onPress",
43
+ "onChangeText",
44
+ "onLayout",
45
+ "onMoveShouldSetResponder",
46
+ "onResponderGrant",
47
+ "onResponderMove",
48
+ "onResponderRelease",
49
+ "onResponderTerminate",
50
+ // SVG attributes that pass isPropValid
51
+ "strokeWidth",
52
+ // CSS properties that pass isPropValid but are used as component props
53
+ "overflow",
54
+ "cursor",
55
+ "fontSize",
56
+ "fontWeight",
57
+ "fontFamily",
58
+ "textDecoration"
59
+ ]);
60
+ function shouldForwardProp(key) {
61
+ if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;
62
+ return is_prop_valid_esm_default(key);
63
+ }
64
+ function createFilteredElement(defaultTag) {
65
+ const Component = React.forwardRef(
66
+ ({ children, elementType, ...props }, ref) => {
67
+ const Tag = elementType || defaultTag;
68
+ const htmlProps = {};
69
+ for (const key of Object.keys(props)) {
70
+ if (shouldForwardProp(key)) {
71
+ htmlProps[key] = props[key];
72
+ }
73
+ }
74
+ return React.createElement(
75
+ Tag,
76
+ { ref, ...htmlProps },
77
+ children
78
+ );
79
+ }
80
+ );
81
+ Component.displayName = `Filtered(${defaultTag})`;
82
+ return Component;
83
+ }
84
+
85
+ // ../../foundation/primitives-web/src/Box.tsx
86
+ import { jsx } from "react/jsx-runtime";
87
+ var FilteredDiv = createFilteredElement("div");
88
+ var StyledBox = styled(FilteredDiv)`
89
+ display: flex;
90
+ box-sizing: border-box;
91
+ background-color: ${(props) => props.backgroundColor || "transparent"};
92
+ border-color: ${(props) => props.borderColor || "transparent"};
93
+ border-width: ${(props) => typeof props.borderWidth === "number" ? `${props.borderWidth}px` : props.borderWidth || 0};
94
+
95
+ ${(props) => props.borderBottomWidth !== void 0 && `
96
+ border-bottom-width: ${typeof props.borderBottomWidth === "number" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};
97
+ border-bottom-color: ${props.borderBottomColor || props.borderColor || "transparent"};
98
+ border-bottom-style: solid;
99
+ `}
100
+ ${(props) => props.borderTopWidth !== void 0 && `
101
+ border-top-width: ${typeof props.borderTopWidth === "number" ? `${props.borderTopWidth}px` : props.borderTopWidth};
102
+ border-top-color: ${props.borderTopColor || props.borderColor || "transparent"};
103
+ border-top-style: solid;
104
+ `}
105
+ ${(props) => props.borderLeftWidth !== void 0 && `
106
+ border-left-width: ${typeof props.borderLeftWidth === "number" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};
107
+ border-left-color: ${props.borderLeftColor || props.borderColor || "transparent"};
108
+ border-left-style: solid;
109
+ `}
110
+ ${(props) => props.borderRightWidth !== void 0 && `
111
+ border-right-width: ${typeof props.borderRightWidth === "number" ? `${props.borderRightWidth}px` : props.borderRightWidth};
112
+ border-right-color: ${props.borderRightColor || props.borderColor || "transparent"};
113
+ border-right-style: solid;
114
+ `}
115
+
116
+ border-style: ${(props) => props.borderStyle || (props.borderWidth || props.borderBottomWidth || props.borderTopWidth || props.borderLeftWidth || props.borderRightWidth ? "solid" : "none")};
117
+ border-radius: ${(props) => typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius || 0};
118
+ height: ${(props) => typeof props.height === "number" ? `${props.height}px` : props.height || "auto"};
119
+ width: ${(props) => typeof props.width === "number" ? `${props.width}px` : props.width || "auto"};
120
+ min-width: ${(props) => typeof props.minWidth === "number" ? `${props.minWidth}px` : props.minWidth || "auto"};
121
+ min-height: ${(props) => typeof props.minHeight === "number" ? `${props.minHeight}px` : props.minHeight || "auto"};
122
+ max-width: ${(props) => typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth || "none"};
123
+ max-height: ${(props) => typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight || "none"};
124
+
125
+ padding: ${(props) => typeof props.padding === "number" ? `${props.padding}px` : props.padding || 0};
126
+ ${(props) => props.paddingHorizontal && `
127
+ padding-left: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
128
+ padding-right: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
129
+ `}
130
+ ${(props) => props.paddingVertical && `
131
+ padding-top: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
132
+ padding-bottom: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
133
+ `}
134
+ ${(props) => props.paddingTop !== void 0 && `padding-top: ${typeof props.paddingTop === "number" ? `${props.paddingTop}px` : props.paddingTop};`}
135
+ ${(props) => props.paddingBottom !== void 0 && `padding-bottom: ${typeof props.paddingBottom === "number" ? `${props.paddingBottom}px` : props.paddingBottom};`}
136
+ ${(props) => props.paddingLeft !== void 0 && `padding-left: ${typeof props.paddingLeft === "number" ? `${props.paddingLeft}px` : props.paddingLeft};`}
137
+ ${(props) => props.paddingRight !== void 0 && `padding-right: ${typeof props.paddingRight === "number" ? `${props.paddingRight}px` : props.paddingRight};`}
138
+
139
+ margin: ${(props) => typeof props.margin === "number" ? `${props.margin}px` : props.margin || 0};
140
+ ${(props) => props.marginTop !== void 0 && `margin-top: ${typeof props.marginTop === "number" ? `${props.marginTop}px` : props.marginTop};`}
141
+ ${(props) => props.marginBottom !== void 0 && `margin-bottom: ${typeof props.marginBottom === "number" ? `${props.marginBottom}px` : props.marginBottom};`}
142
+ ${(props) => props.marginLeft !== void 0 && `margin-left: ${typeof props.marginLeft === "number" ? `${props.marginLeft}px` : props.marginLeft};`}
143
+ ${(props) => props.marginRight !== void 0 && `margin-right: ${typeof props.marginRight === "number" ? `${props.marginRight}px` : props.marginRight};`}
144
+
145
+ flex-direction: ${(props) => props.flexDirection || "column"};
146
+ flex-wrap: ${(props) => props.flexWrap || "nowrap"};
147
+ align-items: ${(props) => props.alignItems || "stretch"};
148
+ justify-content: ${(props) => props.justifyContent || "flex-start"};
149
+ cursor: ${(props) => props.cursor ? props.cursor : props.onClick || props.onPress ? "pointer" : "inherit"};
150
+ position: ${(props) => props.position || "static"};
151
+ top: ${(props) => typeof props.top === "number" ? `${props.top}px` : props.top};
152
+ bottom: ${(props) => typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom};
153
+ left: ${(props) => typeof props.left === "number" ? `${props.left}px` : props.left};
154
+ right: ${(props) => typeof props.right === "number" ? `${props.right}px` : props.right};
155
+ flex: ${(props) => props.flex};
156
+ flex-shrink: ${(props) => props.flexShrink ?? 1};
157
+ gap: ${(props) => typeof props.gap === "number" ? `${props.gap}px` : props.gap || 0};
158
+ align-self: ${(props) => props.alignSelf || "auto"};
159
+ overflow: ${(props) => props.overflow || "visible"};
160
+ overflow-x: ${(props) => props.overflowX || "visible"};
161
+ overflow-y: ${(props) => props.overflowY || "visible"};
162
+ z-index: ${(props) => props.zIndex};
163
+ opacity: ${(props) => props.disabled ? 0.5 : 1};
164
+ pointer-events: ${(props) => props.disabled ? "none" : "auto"};
165
+
166
+ &:hover {
167
+ ${(props) => props.hoverStyle?.backgroundColor && `background-color: ${props.hoverStyle.backgroundColor};`}
168
+ ${(props) => props.hoverStyle?.borderColor && `border-color: ${props.hoverStyle.borderColor};`}
169
+ }
170
+
171
+ &:active {
172
+ ${(props) => props.pressStyle?.backgroundColor && `background-color: ${props.pressStyle.backgroundColor};`}
173
+ }
174
+ `;
175
+ var Box = React2.forwardRef(
176
+ ({
177
+ children,
178
+ onPress,
179
+ onKeyDown,
180
+ onKeyUp,
181
+ role,
182
+ "aria-label": ariaLabel,
183
+ "aria-labelledby": ariaLabelledBy,
184
+ "aria-current": ariaCurrent,
185
+ "aria-disabled": ariaDisabled,
186
+ "aria-live": ariaLive,
187
+ "aria-busy": ariaBusy,
188
+ "aria-describedby": ariaDescribedBy,
189
+ "aria-expanded": ariaExpanded,
190
+ "aria-haspopup": ariaHasPopup,
191
+ "aria-pressed": ariaPressed,
192
+ "aria-controls": ariaControls,
193
+ tabIndex,
194
+ as,
195
+ src,
196
+ alt,
197
+ onError,
198
+ onLoad,
199
+ type,
200
+ disabled,
201
+ id,
202
+ testID,
203
+ "data-testid": dataTestId,
204
+ ...props
205
+ }, ref) => {
206
+ if (as === "img" && src) {
207
+ return /* @__PURE__ */ jsx(
208
+ "img",
209
+ {
210
+ src,
211
+ alt: alt || "",
212
+ onError,
213
+ onLoad,
214
+ style: {
215
+ display: "block",
216
+ objectFit: "cover",
217
+ width: typeof props.width === "number" ? `${props.width}px` : props.width,
218
+ height: typeof props.height === "number" ? `${props.height}px` : props.height,
219
+ borderRadius: typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius,
220
+ position: props.position,
221
+ top: typeof props.top === "number" ? `${props.top}px` : props.top,
222
+ left: typeof props.left === "number" ? `${props.left}px` : props.left,
223
+ right: typeof props.right === "number" ? `${props.right}px` : props.right,
224
+ bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom
225
+ }
226
+ }
227
+ );
228
+ }
229
+ return /* @__PURE__ */ jsx(
230
+ StyledBox,
231
+ {
232
+ ref,
233
+ elementType: as,
234
+ id,
235
+ type: as === "button" ? type || "button" : void 0,
236
+ disabled: as === "button" ? disabled : void 0,
237
+ onClick: onPress,
238
+ onKeyDown,
239
+ onKeyUp,
240
+ role,
241
+ "aria-label": ariaLabel,
242
+ "aria-labelledby": ariaLabelledBy,
243
+ "aria-current": ariaCurrent,
244
+ "aria-disabled": ariaDisabled,
245
+ "aria-busy": ariaBusy,
246
+ "aria-describedby": ariaDescribedBy,
247
+ "aria-expanded": ariaExpanded,
248
+ "aria-haspopup": ariaHasPopup,
249
+ "aria-pressed": ariaPressed,
250
+ "aria-controls": ariaControls,
251
+ "aria-live": ariaLive,
252
+ tabIndex: tabIndex !== void 0 ? tabIndex : void 0,
253
+ "data-testid": dataTestId || testID,
254
+ ...props,
255
+ children
256
+ }
257
+ );
258
+ }
259
+ );
260
+ Box.displayName = "Box";
261
+
262
+ // ../../foundation/primitives-web/src/Text.tsx
263
+ import styled2 from "styled-components";
264
+ import { jsx as jsx2 } from "react/jsx-runtime";
265
+ var FilteredSpan = createFilteredElement("span");
266
+ var StyledText = styled2(FilteredSpan)`
267
+ color: ${(props) => props.color || "inherit"};
268
+ font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
269
+ font-weight: ${(props) => props.fontWeight || "normal"};
270
+ font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
271
+ line-height: ${(props) => typeof props.lineHeight === "number" ? `${props.lineHeight}px` : props.lineHeight || "inherit"};
272
+ white-space: ${(props) => props.whiteSpace || "normal"};
273
+ text-align: ${(props) => props.textAlign || "inherit"};
274
+ text-decoration: ${(props) => props.textDecoration || "none"};
275
+ `;
276
+ var Text = ({
277
+ style,
278
+ className,
279
+ id,
280
+ role,
281
+ numberOfLines: _numberOfLines,
282
+ ...props
283
+ }) => {
284
+ return /* @__PURE__ */ jsx2(
285
+ StyledText,
286
+ {
287
+ ...props,
288
+ style,
289
+ className,
290
+ id,
291
+ role
292
+ }
293
+ );
294
+ };
295
+
296
+ // src/Table.tsx
297
+ import { useResolvedTheme, isNative } from "@xsolla/xui-core";
298
+ import { Sort } from "@xsolla/xui-icons-base";
299
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
300
+ var TableRowGroupContext = createContext("body");
301
+ var RowRevealContext = createContext({
302
+ revealed: true
303
+ });
304
+ var useHoverCapable = () => {
305
+ const [hoverCapable, setHoverCapable] = useState(true);
306
+ useEffect(() => {
307
+ if (isNative) return;
308
+ if (typeof window === "undefined" || !window.matchMedia) return;
309
+ const mq = window.matchMedia("(hover: hover)");
310
+ setHoverCapable(mq.matches);
311
+ const onChange = (e) => setHoverCapable(e.matches);
312
+ mq.addEventListener?.("change", onChange);
313
+ return () => mq.removeEventListener?.("change", onChange);
314
+ }, []);
315
+ return hoverCapable;
316
+ };
317
+ var Divider = ({ color }) => /* @__PURE__ */ jsx3(
318
+ Box,
319
+ {
320
+ width: "100%",
321
+ height: 1,
322
+ backgroundColor: color,
323
+ style: { flexShrink: 0 }
324
+ }
325
+ );
326
+ var TableRoot = forwardRef(
327
+ ({ children, themeMode, themeProductContext }, ref) => {
328
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
329
+ const sizing = theme.sizing.table;
330
+ return /* @__PURE__ */ jsx3(
331
+ Box,
332
+ {
333
+ ref,
334
+ flexDirection: "column",
335
+ alignItems: "stretch",
336
+ gap: sizing.containerGap,
337
+ paddingVertical: sizing.containerPaddingVertical,
338
+ backgroundColor: theme.colors.background.primary,
339
+ borderRadius: sizing.containerRadius,
340
+ width: "100%",
341
+ role: "table",
342
+ style: {
343
+ color: theme.colors.content.primary,
344
+ overflow: "clip"
345
+ },
346
+ children
347
+ }
348
+ );
349
+ }
350
+ );
351
+ TableRoot.displayName = "Table";
352
+ var TableCaption = forwardRef(
353
+ ({ children, themeMode, themeProductContext, style, ...props }, ref) => {
354
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
355
+ const sizing = theme.sizing.table;
356
+ return /* @__PURE__ */ jsx3(
357
+ Box,
358
+ {
359
+ ref,
360
+ flexDirection: "row",
361
+ alignItems: "center",
362
+ paddingHorizontal: sizing.headerRowPaddingHorizontal,
363
+ width: "100%",
364
+ ...props,
365
+ style,
366
+ children: typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx3(
367
+ Text,
368
+ {
369
+ fontSize: sizing.captionFontSize,
370
+ lineHeight: sizing.captionLineHeight,
371
+ color: theme.colors.content.secondary,
372
+ children
373
+ }
374
+ ) : children
375
+ }
376
+ );
377
+ }
378
+ );
379
+ TableCaption.displayName = "Table.Caption";
380
+ var TableHeader = forwardRef(
381
+ ({ children, themeMode, themeProductContext, style, ...props }, ref) => {
382
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
383
+ return /* @__PURE__ */ jsx3(TableRowGroupContext.Provider, { value: "header", children: /* @__PURE__ */ jsxs(
384
+ Box,
385
+ {
386
+ ref,
387
+ flexDirection: "column",
388
+ alignItems: "stretch",
389
+ width: "100%",
390
+ role: "rowgroup",
391
+ ...props,
392
+ style: {
393
+ position: "sticky",
394
+ top: 0,
395
+ zIndex: 1,
396
+ backgroundColor: theme.colors.background.primary,
397
+ ...style
398
+ },
399
+ children: [
400
+ children,
401
+ /* @__PURE__ */ jsx3(Divider, { color: theme.colors.border.secondary })
402
+ ]
403
+ }
404
+ ) });
405
+ }
406
+ );
407
+ TableHeader.displayName = "Table.Header";
408
+ var TableBody = forwardRef(
409
+ ({ children, style, minRows, themeMode, themeProductContext, ...props }, ref) => {
410
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
411
+ const sizing = theme.sizing.table;
412
+ const DIVIDER_HEIGHT = 1;
413
+ const computedMinHeight = minRows ? minRows * sizing.rowHeight + (minRows - 1) * DIVIDER_HEIGHT : void 0;
414
+ let renderedChildren = children;
415
+ if (minRows) {
416
+ const childArray = React3.Children.toArray(children);
417
+ const hasOnlyRowChildren = childArray.length > 0 && childArray.every((c) => React3.isValidElement(c) && c.type === TableRow);
418
+ const realRowCount = hasOnlyRowChildren ? childArray.length : 0;
419
+ const placeholderCount = hasOnlyRowChildren ? Math.max(0, minRows - realRowCount) : 0;
420
+ if (placeholderCount > 0) {
421
+ const patchedRows = childArray.map((child, i) => {
422
+ if (!React3.isValidElement(child)) return child;
423
+ const isLastRealRow = i === realRowCount - 1;
424
+ return React3.cloneElement(child, {
425
+ hideDivider: isLastRealRow ? false : child.props.hideDivider
426
+ });
427
+ });
428
+ const placeholders = Array.from({ length: placeholderCount }).map(
429
+ (_, i) => {
430
+ const isLast = i === placeholderCount - 1;
431
+ return /* @__PURE__ */ jsx3(
432
+ Box,
433
+ {
434
+ "aria-hidden": true,
435
+ style: {
436
+ height: isLast ? sizing.rowHeight : sizing.rowHeight + DIVIDER_HEIGHT,
437
+ flexShrink: 0
438
+ }
439
+ },
440
+ `__table-body-placeholder-${i}`
441
+ );
442
+ }
443
+ );
444
+ renderedChildren = /* @__PURE__ */ jsxs(Fragment, { children: [
445
+ patchedRows,
446
+ placeholders
447
+ ] });
448
+ }
449
+ }
450
+ return /* @__PURE__ */ jsx3(TableRowGroupContext.Provider, { value: "body", children: /* @__PURE__ */ jsx3(
451
+ Box,
452
+ {
453
+ ref,
454
+ flexDirection: "column",
455
+ alignItems: "stretch",
456
+ width: "100%",
457
+ role: "rowgroup",
458
+ ...props,
459
+ style: {
460
+ ...computedMinHeight !== void 0 && {
461
+ minHeight: computedMinHeight
462
+ },
463
+ ...style
464
+ },
465
+ children: renderedChildren
466
+ }
467
+ ) });
468
+ }
469
+ );
470
+ TableBody.displayName = "Table.Body";
471
+ var TableRow = forwardRef(
472
+ ({
473
+ children,
474
+ hoverable: hoverableProp,
475
+ selected,
476
+ hideDivider: hideDividerProp,
477
+ onPress,
478
+ themeMode,
479
+ themeProductContext,
480
+ style,
481
+ onMouseEnter,
482
+ onMouseLeave,
483
+ onFocus,
484
+ onBlur,
485
+ ...props
486
+ }, ref) => {
487
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
488
+ const sizing = theme.sizing.table;
489
+ const rowGroup = useContext(TableRowGroupContext);
490
+ const hoverCapable = useHoverCapable();
491
+ const isHeaderRow = rowGroup === "header";
492
+ const hoverable = hoverableProp ?? !isHeaderRow;
493
+ const hideDivider = hideDividerProp ?? isHeaderRow;
494
+ const [hovered, setHovered] = useState(false);
495
+ const [focusedWithin, setFocusedWithin] = useState(false);
496
+ const revealed = hoverCapable ? hovered || focusedWithin : true;
497
+ const handleMouseEnter = useCallback(
498
+ (e) => {
499
+ setHovered(true);
500
+ onMouseEnter?.(e);
501
+ },
502
+ [onMouseEnter]
503
+ );
504
+ const handleMouseLeave = useCallback(
505
+ (e) => {
506
+ setHovered(false);
507
+ onMouseLeave?.(e);
508
+ },
509
+ [onMouseLeave]
510
+ );
511
+ const handleFocus = useCallback(
512
+ (e) => {
513
+ setFocusedWithin(true);
514
+ onFocus?.(e);
515
+ },
516
+ [onFocus]
517
+ );
518
+ const handleBlur = useCallback(
519
+ (e) => {
520
+ if (e.relatedTarget instanceof Node && e.currentTarget.contains(e.relatedTarget)) {
521
+ onBlur?.(e);
522
+ return;
523
+ }
524
+ setFocusedWithin(false);
525
+ onBlur?.(e);
526
+ },
527
+ [onBlur]
528
+ );
529
+ const baseBg = selected ? theme.colors.background.secondary : theme.colors.background.primary;
530
+ const rowHeight = isHeaderRow ? sizing.headerRowHeight : sizing.rowHeight;
531
+ const rowPaddingHorizontal = isHeaderRow ? sizing.headerRowPaddingHorizontal : sizing.rowPaddingHorizontal;
532
+ const ctxValue = useMemo(() => ({ revealed }), [revealed]);
533
+ return /* @__PURE__ */ jsxs(RowRevealContext.Provider, { value: ctxValue, children: [
534
+ /* @__PURE__ */ jsx3(
535
+ Box,
536
+ {
537
+ ref,
538
+ flexDirection: "row",
539
+ alignItems: "center",
540
+ height: rowHeight,
541
+ paddingHorizontal: rowPaddingHorizontal,
542
+ width: "100%",
543
+ gap: sizing.cellGap,
544
+ backgroundColor: baseBg,
545
+ cursor: onPress ? "pointer" : void 0,
546
+ hoverStyle: hoverable ? { backgroundColor: theme.colors.background.secondary } : void 0,
547
+ onPress,
548
+ role: "row",
549
+ "aria-selected": selected || void 0,
550
+ onMouseEnter: handleMouseEnter,
551
+ onMouseLeave: handleMouseLeave,
552
+ onFocus: handleFocus,
553
+ onBlur: handleBlur,
554
+ ...props,
555
+ style,
556
+ children
557
+ }
558
+ ),
559
+ !hideDivider && /* @__PURE__ */ jsx3(Divider, { color: theme.colors.border.secondary })
560
+ ] });
561
+ }
562
+ );
563
+ TableRow.displayName = "Table.Row";
564
+ var positionToFlex = (position) => {
565
+ switch (position) {
566
+ case "left":
567
+ return { flexShrink: 0 };
568
+ case "right":
569
+ return { flexShrink: 0, marginLeft: "auto" };
570
+ default:
571
+ return {};
572
+ }
573
+ };
574
+ var alignToJustify = (align) => {
575
+ switch (align) {
576
+ case "right":
577
+ return "flex-end";
578
+ case "center":
579
+ return "center";
580
+ default:
581
+ return "flex-start";
582
+ }
583
+ };
584
+ var TableCell = forwardRef(
585
+ ({
586
+ children,
587
+ align = "left",
588
+ position = "default",
589
+ width,
590
+ grow,
591
+ revealOnHover,
592
+ themeMode,
593
+ themeProductContext,
594
+ style,
595
+ ...props
596
+ }, ref) => {
597
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
598
+ const sizing = theme.sizing.table;
599
+ const { revealed } = useContext(RowRevealContext);
600
+ const positionStyle = useMemo(() => positionToFlex(position), [position]);
601
+ const revealStyle = revealOnHover && !revealed ? { opacity: 0, pointerEvents: "none" } : revealOnHover ? { opacity: 1, transition: "opacity 0.15s ease" } : {};
602
+ return /* @__PURE__ */ jsx3(
603
+ Box,
604
+ {
605
+ ref,
606
+ flexDirection: "row",
607
+ alignItems: "center",
608
+ justifyContent: alignToJustify(align),
609
+ gap: 8,
610
+ height: "100%",
611
+ width,
612
+ role: "cell",
613
+ ...props,
614
+ style: {
615
+ flex: width != null ? "0 0 auto" : grow ?? 1,
616
+ minWidth: 0,
617
+ ...positionStyle,
618
+ ...revealStyle,
619
+ ...style
620
+ },
621
+ children: typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx3(
622
+ Text,
623
+ {
624
+ fontSize: sizing.cellFontSize,
625
+ lineHeight: sizing.cellLineHeight,
626
+ color: theme.colors.content.primary,
627
+ style: {
628
+ overflow: "hidden",
629
+ textOverflow: "ellipsis",
630
+ whiteSpace: "nowrap",
631
+ maxWidth: "100%"
632
+ },
633
+ children
634
+ }
635
+ ) : children
636
+ }
637
+ );
638
+ }
639
+ );
640
+ TableCell.displayName = "Table.Cell";
641
+ var SortIcon = ({ direction, color, size }) => /* @__PURE__ */ jsx3(
642
+ Box,
643
+ {
644
+ style: {
645
+ flexShrink: 0,
646
+ opacity: direction === "none" ? 0.4 : 1,
647
+ transition: "opacity 0.15s ease"
648
+ },
649
+ children: /* @__PURE__ */ jsx3(Sort, { variant: "line", size, color, "aria-hidden": true })
650
+ }
651
+ );
652
+ var TableHead = forwardRef(
653
+ ({
654
+ children,
655
+ align = "left",
656
+ position = "default",
657
+ width,
658
+ grow,
659
+ sort,
660
+ onSortToggle,
661
+ themeMode,
662
+ themeProductContext,
663
+ style,
664
+ ...props
665
+ }, ref) => {
666
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
667
+ const sizing = theme.sizing.table;
668
+ const positionStyle = useMemo(() => positionToFlex(position), [position]);
669
+ const sortable = sort != null;
670
+ const ariaSort = sortable ? sort : void 0;
671
+ return /* @__PURE__ */ jsxs(
672
+ Box,
673
+ {
674
+ ref,
675
+ flexDirection: "row",
676
+ alignItems: "center",
677
+ justifyContent: alignToJustify(align),
678
+ gap: sizing.headerCellGap,
679
+ height: "100%",
680
+ width,
681
+ role: "columnheader",
682
+ "aria-sort": ariaSort,
683
+ cursor: sortable ? "pointer" : void 0,
684
+ onPress: sortable ? onSortToggle : void 0,
685
+ ...props,
686
+ style: {
687
+ flex: width != null ? "0 0 auto" : grow ?? 1,
688
+ minWidth: 0,
689
+ ...positionStyle,
690
+ ...style
691
+ },
692
+ children: [
693
+ sortable && /* @__PURE__ */ jsx3(
694
+ SortIcon,
695
+ {
696
+ direction: sort,
697
+ color: theme.colors.content.secondary,
698
+ size: sizing.headerCellFontSize + 2
699
+ }
700
+ ),
701
+ typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx3(
702
+ Text,
703
+ {
704
+ fontSize: sizing.headerCellFontSize,
705
+ lineHeight: sizing.headerCellLineHeight,
706
+ color: theme.colors.content.secondary,
707
+ fontWeight: "500",
708
+ style: {
709
+ overflow: "hidden",
710
+ textOverflow: "ellipsis",
711
+ whiteSpace: "nowrap"
712
+ },
713
+ children
714
+ }
715
+ ) : children
716
+ ]
717
+ }
718
+ );
719
+ }
720
+ );
721
+ TableHead.displayName = "Table.Head";
722
+ var TableFooter = forwardRef(
723
+ ({ children, style, ...props }, ref) => {
724
+ const { theme } = useResolvedTheme();
725
+ const sizing = theme.sizing.table;
726
+ return /* @__PURE__ */ jsx3(
727
+ Box,
728
+ {
729
+ ref,
730
+ flexDirection: "row",
731
+ alignItems: "center",
732
+ justifyContent: "center",
733
+ gap: sizing.paginationGap,
734
+ paddingHorizontal: sizing.paginationPaddingHorizontal,
735
+ width: "100%",
736
+ ...props,
737
+ style,
738
+ children
739
+ }
740
+ );
741
+ }
742
+ );
743
+ TableFooter.displayName = "Table.Footer";
744
+ var Table = Object.assign(TableRoot, {
745
+ Caption: TableCaption,
746
+ Header: TableHeader,
747
+ Body: TableBody,
748
+ Footer: TableFooter,
749
+ Row: TableRow,
750
+ Head: TableHead,
751
+ Cell: TableCell
752
+ });
753
+ export {
754
+ Table
755
+ };
756
+ //# sourceMappingURL=index.mjs.map