infinity-ui-elements 1.5.1-beta.0 → 1.5.1-beta.2
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/dist/components/Avatar/Avatar.d.ts +59 -0
- package/dist/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar/Avatar.stories.d.ts +119 -0
- package/dist/components/Avatar/Avatar.stories.d.ts.map +1 -0
- package/dist/components/Avatar/index.d.ts +3 -0
- package/dist/components/Avatar/index.d.ts.map +1 -0
- package/dist/components/Badge/Badge.d.ts +1 -1
- package/dist/components/Button/Button.d.ts +1 -1
- package/dist/components/ButtonGroup/ButtonGroup.d.ts +26 -0
- package/dist/components/ButtonGroup/ButtonGroup.d.ts.map +1 -0
- package/dist/components/ButtonGroup/ButtonGroup.stories.d.ts +102 -0
- package/dist/components/ButtonGroup/ButtonGroup.stories.d.ts.map +1 -0
- package/dist/components/ButtonGroup/index.d.ts +3 -0
- package/dist/components/ButtonGroup/index.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/components/Counter/Counter.d.ts +1 -1
- package/dist/components/Dropdown/Dropdown.d.ts +1 -1
- package/dist/components/Dropdown/Dropdown.stories.d.ts +1 -1
- package/dist/components/Dropdown/DropdownMenu.d.ts +4 -0
- package/dist/components/Dropdown/DropdownMenu.d.ts.map +1 -1
- package/dist/components/FormHeader/FormHeader.d.ts.map +1 -1
- package/dist/components/Link/Link.d.ts +1 -1
- package/dist/components/Modal/Modal.d.ts +78 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Modal/Modal.stories.d.ts +20 -0
- package/dist/components/Modal/Modal.stories.d.ts.map +1 -0
- package/dist/components/Modal/index.d.ts +3 -0
- package/dist/components/Modal/index.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.d.ts +81 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.stories.d.ts +22 -0
- package/dist/components/Pagination/Pagination.stories.d.ts.map +1 -0
- package/dist/components/Pagination/index.d.ts +3 -0
- package/dist/components/Pagination/index.d.ts.map +1 -0
- package/dist/components/Radio/Radio.d.ts +1 -1
- package/dist/components/SearchableDropdown/SearchableDropdown.d.ts +4 -0
- package/dist/components/SearchableDropdown/SearchableDropdown.d.ts.map +1 -1
- package/dist/components/SearchableDropdown/SearchableDropdown.stories.d.ts +10 -9
- package/dist/components/SearchableDropdown/SearchableDropdown.stories.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts +148 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.stories.d.ts +32 -0
- package/dist/components/Select/Select.stories.d.ts.map +1 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Switch/Switch.d.ts +1 -1
- package/dist/components/TabItem/TabItem.d.ts +1 -1
- package/dist/components/Table/DetailPanel.d.ts +10 -0
- package/dist/components/Table/DetailPanel.d.ts.map +1 -0
- package/dist/components/Table/Table.d.ts +39 -0
- package/dist/components/Table/Table.d.ts.map +1 -0
- package/dist/components/Table/Table.refactored.d.ts +39 -0
- package/dist/components/Table/Table.refactored.d.ts.map +1 -0
- package/dist/components/Table/Table.stories.d.ts +23 -0
- package/dist/components/Table/Table.stories.d.ts.map +1 -0
- package/dist/components/Table/TableBody.d.ts +18 -0
- package/dist/components/Table/TableBody.d.ts.map +1 -0
- package/dist/components/Table/TableCellTypes.d.ts +32 -0
- package/dist/components/Table/TableCellTypes.d.ts.map +1 -0
- package/dist/components/Table/TableDetailPanel.d.ts +25 -0
- package/dist/components/Table/TableDetailPanel.d.ts.map +1 -0
- package/dist/components/Table/TableHeader.d.ts +18 -0
- package/dist/components/Table/TableHeader.d.ts.map +1 -0
- package/dist/components/Table/index.d.ts +6 -0
- package/dist/components/Table/index.d.ts.map +1 -0
- package/dist/components/Table/tableHelpers.d.ts +7 -0
- package/dist/components/Table/tableHelpers.d.ts.map +1 -0
- package/dist/components/Table/tableVariants.d.ts +12 -0
- package/dist/components/Table/tableVariants.d.ts.map +1 -0
- package/dist/components/TextArea/TextArea.d.ts +1 -1
- package/dist/components/TextField/TextField.d.ts +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +893 -42
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +910 -40
- package/dist/index.js.map +1 -1
- package/dist/lib/icons.d.ts +5 -1
- package/dist/lib/icons.d.ts.map +1 -1
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ var tailwindMerge = require('tailwind-merge');
|
|
|
8
8
|
var reactSlot = require('@radix-ui/react-slot');
|
|
9
9
|
var reactSpinners = require('react-spinners');
|
|
10
10
|
var lucideReact = require('lucide-react');
|
|
11
|
+
var reactDom = require('react-dom');
|
|
12
|
+
var reactTable = require('@tanstack/react-table');
|
|
11
13
|
|
|
12
14
|
function _interopNamespaceDefault(e) {
|
|
13
15
|
var n = Object.create(null);
|
|
@@ -67,6 +69,106 @@ function cn(...inputs) {
|
|
|
67
69
|
return clsx.clsx(mergedStandard, customClasses);
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
// Helper function to get the text utility class name
|
|
73
|
+
function getTextClassName(variant = "body", size = "medium", weight = "regular", color = "default") {
|
|
74
|
+
// Build the base class name
|
|
75
|
+
let baseClass = `text-${variant}`;
|
|
76
|
+
// Add size
|
|
77
|
+
if (size) {
|
|
78
|
+
baseClass += `-${size}`;
|
|
79
|
+
}
|
|
80
|
+
// Add weight
|
|
81
|
+
if (weight) {
|
|
82
|
+
baseClass += `-${weight}`;
|
|
83
|
+
}
|
|
84
|
+
// Add color class separately
|
|
85
|
+
const colorClass = `text-color-${color}`;
|
|
86
|
+
return `${baseClass} ${colorClass}`;
|
|
87
|
+
}
|
|
88
|
+
const Text = React__namespace.forwardRef(({ className, variant = "body", size = "medium", weight = "regular", color = "default", as = "p", children, ...props }, ref) => {
|
|
89
|
+
const Component = as;
|
|
90
|
+
const textClass = getTextClassName(variant, size, weight, color);
|
|
91
|
+
return React__namespace.createElement(Component, {
|
|
92
|
+
className: cn(textClass, className),
|
|
93
|
+
ref,
|
|
94
|
+
...props,
|
|
95
|
+
}, children);
|
|
96
|
+
});
|
|
97
|
+
Text.displayName = "Text";
|
|
98
|
+
|
|
99
|
+
const avatarVariants = classVarianceAuthority.cva("inline-flex items-center justify-center font-medium text-center select-none", {
|
|
100
|
+
variants: {
|
|
101
|
+
color: {
|
|
102
|
+
a1: "bg-avatar-fill-a1-bg text-avatar-fill-a1-on-bg",
|
|
103
|
+
a2: "bg-avatar-fill-a2-bg text-avatar-fill-a2-on-bg",
|
|
104
|
+
a3: "bg-avatar-fill-a3-bg text-avatar-fill-a3-on-bg",
|
|
105
|
+
a4: "bg-avatar-fill-a4-bg text-avatar-fill-a4-on-bg",
|
|
106
|
+
a5: "bg-avatar-fill-a5-bg text-avatar-fill-a5-on-bg",
|
|
107
|
+
},
|
|
108
|
+
size: {
|
|
109
|
+
small: "h-[24px] w-[24px] text-body-medium-regular rounded-large",
|
|
110
|
+
medium: "h-[32px] w-[32px] text-body-medium-regular rounded-xlarge",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
defaultVariants: {
|
|
114
|
+
color: "a1",
|
|
115
|
+
size: "medium",
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
const statusVariants = classVarianceAuthority.cva("absolute flex items-center justify-center rounded-full border-2 border-surface-fill-neutral-intense", {
|
|
119
|
+
variants: {
|
|
120
|
+
size: {
|
|
121
|
+
small: "h-5 w-5 -bottom-0.5 -right-0.5",
|
|
122
|
+
medium: "h-6 w-6 -bottom-1 -right-1",
|
|
123
|
+
},
|
|
124
|
+
statusColor: {
|
|
125
|
+
positive: "bg-action-fill-positive-default",
|
|
126
|
+
negative: "bg-action-fill-negative-default",
|
|
127
|
+
notice: "bg-action-fill-notice-default",
|
|
128
|
+
info: "bg-action-fill-info-default",
|
|
129
|
+
neutral: "bg-action-fill-neutral-default",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
defaultVariants: {
|
|
133
|
+
size: "medium",
|
|
134
|
+
statusColor: "notice",
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
const Avatar = React__namespace.forwardRef(({ className, color, size, children, src, alt, showStatus = false, statusColor = "notice", statusIcon, label, trailingComponent, containerClassName, ...props }, ref) => {
|
|
138
|
+
const [imageError, setImageError] = React__namespace.useState(false);
|
|
139
|
+
const handleImageError = () => {
|
|
140
|
+
setImageError(true);
|
|
141
|
+
};
|
|
142
|
+
const getStatusIconSize = () => {
|
|
143
|
+
switch (size) {
|
|
144
|
+
case "small":
|
|
145
|
+
return "h-3.5 w-3.5";
|
|
146
|
+
case "medium":
|
|
147
|
+
return "h-4 w-4";
|
|
148
|
+
default:
|
|
149
|
+
return "h-4 w-4";
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const getTextSize = () => {
|
|
153
|
+
switch (size) {
|
|
154
|
+
case "small":
|
|
155
|
+
return "small";
|
|
156
|
+
case "medium":
|
|
157
|
+
return "medium";
|
|
158
|
+
default:
|
|
159
|
+
return "medium";
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const avatarElement = (jsxRuntime.jsxs("div", { className: "relative inline-block", children: [jsxRuntime.jsx("div", { className: cn(avatarVariants({ color, size }), className), ...props, children: src && !imageError ? (jsxRuntime.jsx("img", { src: src, alt: alt || "Avatar", className: cn("h-full w-full object-cover", size === "small" ? "rounded-large" : "rounded-xlarge"), onError: handleImageError })) : (children) }), showStatus && (jsxRuntime.jsx("div", { className: cn(statusVariants({ size, statusColor })), children: statusIcon && (jsxRuntime.jsx("span", { className: cn("text-action-ink-on-primary-normal", getStatusIconSize()), children: statusIcon })) }))] }));
|
|
163
|
+
// If no label or trailing component, return just the avatar
|
|
164
|
+
if (!label && !trailingComponent) {
|
|
165
|
+
return jsxRuntime.jsx("div", { ref: ref, children: avatarElement });
|
|
166
|
+
}
|
|
167
|
+
// Otherwise, return avatar with label and/or trailing component
|
|
168
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("inline-flex items-center gap-3", containerClassName), children: [avatarElement, label && (jsxRuntime.jsx(Text, { variant: "body", size: getTextSize(), weight: "medium", color: "default", as: "span", children: label })), trailingComponent && (jsxRuntime.jsx("span", { className: "ml-auto", children: trailingComponent }))] }));
|
|
169
|
+
});
|
|
170
|
+
Avatar.displayName = "Avatar";
|
|
171
|
+
|
|
70
172
|
const badgeVariants = classVarianceAuthority.cva("inline-flex items-center whitespace-nowrap transition-colors", {
|
|
71
173
|
variants: {
|
|
72
174
|
variant: {
|
|
@@ -483,32 +585,145 @@ const Button = React__namespace.forwardRef(({ className, variant = "primary", co
|
|
|
483
585
|
});
|
|
484
586
|
Button.displayName = "Button";
|
|
485
587
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
588
|
+
const buttonGroupVariants = classVarianceAuthority.cva("inline-flex", {
|
|
589
|
+
variants: {
|
|
590
|
+
variant: {
|
|
591
|
+
attached: "",
|
|
592
|
+
separated: "",
|
|
593
|
+
},
|
|
594
|
+
orientation: {
|
|
595
|
+
horizontal: "flex-row",
|
|
596
|
+
vertical: "flex-col",
|
|
597
|
+
},
|
|
598
|
+
size: {
|
|
599
|
+
xsmall: "",
|
|
600
|
+
small: "",
|
|
601
|
+
medium: "",
|
|
602
|
+
large: "",
|
|
603
|
+
},
|
|
604
|
+
isFullWidth: {
|
|
605
|
+
true: "w-full",
|
|
606
|
+
false: "w-fit",
|
|
607
|
+
},
|
|
608
|
+
isDisabled: {
|
|
609
|
+
true: "pointer-events-none opacity-50",
|
|
610
|
+
false: "",
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
compoundVariants: [
|
|
614
|
+
{
|
|
615
|
+
variant: "separated",
|
|
616
|
+
orientation: "horizontal",
|
|
617
|
+
class: "gap-2",
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
variant: "separated",
|
|
621
|
+
orientation: "vertical",
|
|
622
|
+
class: "gap-2",
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
defaultVariants: {
|
|
626
|
+
variant: "attached",
|
|
627
|
+
orientation: "horizontal",
|
|
628
|
+
size: "medium",
|
|
629
|
+
isFullWidth: false,
|
|
630
|
+
isDisabled: false,
|
|
631
|
+
},
|
|
510
632
|
});
|
|
511
|
-
|
|
633
|
+
const ButtonGroup = React__namespace.forwardRef(({ className, variant = "attached", orientation = "horizontal", size = "medium", isDisabled = false, isFullWidth = false, value, onChange, children, ...props }, ref) => {
|
|
634
|
+
const childrenArray = React__namespace.Children.toArray(children);
|
|
635
|
+
const isControlled = value !== undefined && onChange !== undefined;
|
|
636
|
+
return (jsxRuntime.jsx("div", { ref: ref, className: cn(buttonGroupVariants({
|
|
637
|
+
variant,
|
|
638
|
+
orientation,
|
|
639
|
+
size,
|
|
640
|
+
isDisabled,
|
|
641
|
+
isFullWidth,
|
|
642
|
+
}), className), role: "group", ...props, children: childrenArray.map((child, index) => {
|
|
643
|
+
if (!React__namespace.isValidElement(child)) {
|
|
644
|
+
return child;
|
|
645
|
+
}
|
|
646
|
+
const isFirst = index === 0;
|
|
647
|
+
const isLast = index === childrenArray.length - 1;
|
|
648
|
+
const isMiddle = !isFirst && !isLast;
|
|
649
|
+
// Get value from child props for controlled mode
|
|
650
|
+
const childValue = child.props.value;
|
|
651
|
+
const isSelected = isControlled && childValue === value;
|
|
652
|
+
// Build classes to apply border radius removal and borders
|
|
653
|
+
let groupClasses = "";
|
|
654
|
+
// Only apply connected styling for "attached" variant
|
|
655
|
+
if (variant === "attached") {
|
|
656
|
+
if (orientation === "horizontal") {
|
|
657
|
+
if (isFirst) {
|
|
658
|
+
groupClasses = "rounded-r-none border-r-0";
|
|
659
|
+
}
|
|
660
|
+
else if (isLast) {
|
|
661
|
+
groupClasses = "rounded-l-none";
|
|
662
|
+
}
|
|
663
|
+
else if (isMiddle) {
|
|
664
|
+
groupClasses = "rounded-none border-r-0";
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
// vertical
|
|
669
|
+
if (isFirst) {
|
|
670
|
+
groupClasses = "rounded-b-none border-b-0";
|
|
671
|
+
}
|
|
672
|
+
else if (isLast) {
|
|
673
|
+
groupClasses = "rounded-t-none";
|
|
674
|
+
}
|
|
675
|
+
else if (isMiddle) {
|
|
676
|
+
groupClasses = "rounded-none border-b-0";
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
// Determine the variant to use
|
|
681
|
+
const childVariant = child.props.variant;
|
|
682
|
+
const hasExplicitVariant = childVariant !== undefined;
|
|
683
|
+
// For controlled mode with explicit variant, maintain the variant
|
|
684
|
+
// and add styling classes for selected state
|
|
685
|
+
let finalVariant = childVariant;
|
|
686
|
+
let selectedStateClasses = "";
|
|
687
|
+
if (isControlled) {
|
|
688
|
+
if (hasExplicitVariant) {
|
|
689
|
+
// Keep the child's variant and add selected state styling
|
|
690
|
+
if (isSelected && childVariant === "tertiary") {
|
|
691
|
+
selectedStateClasses = "bg-action-fill-primary-faded";
|
|
692
|
+
}
|
|
693
|
+
else if (isSelected && childVariant === "secondary") {
|
|
694
|
+
selectedStateClasses =
|
|
695
|
+
"bg-action-fill-primary-faded border-action-outline-primary-faded";
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
// No explicit variant: use primary for selected, secondary for unselected
|
|
700
|
+
finalVariant = isSelected ? "primary" : "secondary";
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// Clone child and add our classes and handlers
|
|
704
|
+
return React__namespace.cloneElement(child, {
|
|
705
|
+
...child.props,
|
|
706
|
+
className: cn(child.props.className, groupClasses, isFullWidth && "flex-1",
|
|
707
|
+
// For attached variant, ensure proper layering
|
|
708
|
+
variant === "attached" && "relative", variant === "attached" && !isSelected && "hover:z-10 focus:z-10", variant === "attached" && isSelected && "z-20",
|
|
709
|
+
// Apply selected state classes for explicit variants
|
|
710
|
+
selectedStateClasses),
|
|
711
|
+
disabled: isDisabled || child.props.disabled,
|
|
712
|
+
size: size || child.props.size,
|
|
713
|
+
// If controlled and has value, handle click
|
|
714
|
+
onClick: isControlled && childValue !== undefined
|
|
715
|
+
? (e) => {
|
|
716
|
+
child.props.onClick?.(e);
|
|
717
|
+
if (!isDisabled && !child.props.disabled) {
|
|
718
|
+
onChange(childValue);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
: child.props.onClick,
|
|
722
|
+
variant: finalVariant,
|
|
723
|
+
});
|
|
724
|
+
}) }));
|
|
725
|
+
});
|
|
726
|
+
ButtonGroup.displayName = "ButtonGroup";
|
|
512
727
|
|
|
513
728
|
const FormFooter = React__namespace.forwardRef(({ helperText, trailingText, validationState = "default", size = "medium", isDisabled = false, className, helperTextClassName, trailingTextClassName, }, ref) => {
|
|
514
729
|
// Size-based configurations
|
|
@@ -583,6 +798,9 @@ const iconRegistry = {
|
|
|
583
798
|
// Alias: check points to the same icon as tick
|
|
584
799
|
check: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
585
800
|
<path d="M10.364 15.1924L19.5564 6L20.9706 7.41421L10.364 18.0208L4 11.6569L5.41422 10.2427L10.364 15.1924Z" fill="#081416"/>
|
|
801
|
+
</svg>`,
|
|
802
|
+
add: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
|
803
|
+
<path d="M12.9 11.0999L21 11.0997V12.8997L12.9 12.8999V21H11.1V12.8999L3.00004 12.9001L3 11.1001L11.1 11.0999L11.0999 3.00001L12.8999 3L12.9 11.0999Z" fill="#081416"/>
|
|
586
804
|
</svg>`,
|
|
587
805
|
};
|
|
588
806
|
const Icon = ({ name, size = 24, className = "", style = {}, ...props }) => {
|
|
@@ -600,17 +818,17 @@ const Icon = ({ name, size = 24, className = "", style = {}, ...props }) => {
|
|
|
600
818
|
console.error(`Invalid SVG content for icon "${String(name)}"`);
|
|
601
819
|
return null;
|
|
602
820
|
}
|
|
603
|
-
//
|
|
821
|
+
// Get the viewBox for proper scaling
|
|
604
822
|
const viewBox = svgElement.getAttribute("viewBox") || "0 0 24 24";
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
//
|
|
608
|
-
|
|
823
|
+
// Get all SVG content as string and replace hardcoded colors with currentColor
|
|
824
|
+
let innerSVG = svgElement.innerHTML;
|
|
825
|
+
// Replace common hardcoded colors with currentColor
|
|
826
|
+
// This allows the icon to inherit text color from parent
|
|
827
|
+
innerSVG = innerSVG
|
|
609
828
|
.replace(/fill="[^"]*"/g, 'fill="currentColor"')
|
|
610
829
|
.replace(/stroke="[^"]*"/g, 'stroke="currentColor"');
|
|
611
|
-
return (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: viewBox,
|
|
830
|
+
return (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: viewBox, className: className, style: style, xmlns: "http://www.w3.org/2000/svg", ...props, dangerouslySetInnerHTML: { __html: innerSVG } }));
|
|
612
831
|
};
|
|
613
|
-
Icon.displayName = "Icon";
|
|
614
832
|
/**
|
|
615
833
|
* Get all available icon names from the registry
|
|
616
834
|
* @returns Array of registered icon names
|
|
@@ -1224,7 +1442,7 @@ const Link = React__namespace.forwardRef(({ className, type = "anchor", color =
|
|
|
1224
1442
|
});
|
|
1225
1443
|
Link.displayName = "Link";
|
|
1226
1444
|
|
|
1227
|
-
const DropdownMenu = React__namespace.forwardRef(({ items = [], sectionHeading, isLoading = false, isEmpty = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, showChevron = false, emptyIcon, disableFooter = false, onClose, focusedIndex = -1, className, width = "auto", }, ref) => {
|
|
1445
|
+
const DropdownMenu = React__namespace.forwardRef(({ items = [], sectionHeading, isLoading = false, isEmpty = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, showChevron = false, emptyIcon, disableFooter = false, footerLayout = "horizontal", onClose, focusedIndex = -1, className, width = "auto", }, ref) => {
|
|
1228
1446
|
const renderContent = () => {
|
|
1229
1447
|
if (isLoading) {
|
|
1230
1448
|
return (jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center py-12 px-6", children: jsxRuntime.jsx(lucideReact.Loader2, { className: "w-12 h-12 text-action-ink-primary-normal mb-4 animate-spin" }) }));
|
|
@@ -1238,10 +1456,12 @@ const DropdownMenu = React__namespace.forwardRef(({ items = [], sectionHeading,
|
|
|
1238
1456
|
}, containerClassName: cn(index === focusedIndex && "bg-action-fill-primary-faded") }, item.id))) })] }));
|
|
1239
1457
|
};
|
|
1240
1458
|
const widthClass = width === "full" ? "w-full" : width === "auto" ? "w-auto" : "";
|
|
1241
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("bg-
|
|
1459
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("bg-white rounded-large overflow-hidden", widthClass, className), style: {
|
|
1242
1460
|
boxShadow: "0 1px 2px rgba(25, 25, 30, 0.1), 0 2px 6px rgba(25, 25, 30, 0.06)",
|
|
1243
1461
|
...(width !== "full" && width !== "auto" ? { width } : {}),
|
|
1244
|
-
}, children: [renderContent(), !disableFooter && (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(Divider, { thickness: "thin", variant: "muted" }), jsxRuntime.jsxs("div", { className: "flex
|
|
1462
|
+
}, children: [renderContent(), !disableFooter && (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(Divider, { thickness: "thin", variant: "muted" }), jsxRuntime.jsxs("div", { className: cn("flex gap-3 p-4", footerLayout === "vertical"
|
|
1463
|
+
? "flex-col"
|
|
1464
|
+
: "items-center flex-row"), children: [jsxRuntime.jsx(Button, { variant: "secondary", color: "primary", size: "medium", isFullWidth: true, onClick: onSecondaryClick, children: secondaryButtonText }), jsxRuntime.jsx(Button, { variant: "primary", color: "primary", size: "medium", isFullWidth: true, onClick: onPrimaryClick, children: primaryButtonText })] })] }))] }));
|
|
1245
1465
|
});
|
|
1246
1466
|
DropdownMenu.displayName = "DropdownMenu";
|
|
1247
1467
|
|
|
@@ -1558,10 +1778,370 @@ const FormHeader = React__namespace.forwardRef(({ label, size = "medium", isOpti
|
|
|
1558
1778
|
},
|
|
1559
1779
|
};
|
|
1560
1780
|
const config = sizeConfig[size];
|
|
1561
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("flex items-center justify-between px-1", config.gap, className), children: [jsxRuntime.jsxs("div", { className: cn("flex items-center", config.gap), children: [jsxRuntime.jsxs("label", { htmlFor: htmlFor, className: cn("flex items-center", labelClassName), children: [jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold", color: "subtle", children: label }), isRequired && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold",
|
|
1781
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("flex items-center justify-between px-1", config.gap, className), children: [jsxRuntime.jsxs("div", { className: cn("flex items-center", config.gap), children: [jsxRuntime.jsxs("label", { htmlFor: htmlFor, className: cn("flex items-center", labelClassName), children: [jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold", color: "subtle", children: label }), isRequired && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold", color: "negative", className: "ml-0.5", children: "*" })), isOptional && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", className: "text-surface-ink-neutral-muted italic ml-1", children: "(optional)" }))] }), infoDescription && (jsxRuntime.jsx(Tooltip, { description: infoDescription, heading: infoHeading, children: jsxRuntime.jsxs("svg", { width: config.iconSize, height: config.iconSize, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "text-surface-ink-neutral-muted", children: [jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "6", stroke: "currentColor", strokeWidth: "1" }), jsxRuntime.jsx("path", { d: "M7 6V10M7 4.5V4", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round" })] }) }))] }), linkText && (jsxRuntime.jsx("a", { href: linkHref, onClick: onLinkClick, className: cn("text-surface-ink-primary-normal hover:text-surface-ink-primary-hover transition-colors cursor-pointer font-display font-semibold leading-tight shrink-0", size === "small" && "text-xs", size === "medium" && "text-xs", size === "large" && "text-sm", linkClassName), children: linkText }))] }));
|
|
1562
1782
|
});
|
|
1563
1783
|
FormHeader.displayName = "FormHeader";
|
|
1564
1784
|
|
|
1785
|
+
const Modal = React__namespace.forwardRef(({ isOpen, onClose, title, description, footer, children, size = "medium", showCloseButton = true, closeOnOverlayClick = true, closeOnEscape = true, className, contentClassName, headerClassName, bodyClassName, footerClassName, overlayClassName, ariaLabel, ariaDescribedBy, }, ref) => {
|
|
1786
|
+
const modalRef = React__namespace.useRef(null);
|
|
1787
|
+
const contentRef = ref || modalRef;
|
|
1788
|
+
// Size configurations
|
|
1789
|
+
const sizeConfig = {
|
|
1790
|
+
small: "max-w-sm",
|
|
1791
|
+
medium: "max-w-md",
|
|
1792
|
+
large: "max-w-lg",
|
|
1793
|
+
xlarge: "max-w-2xl",
|
|
1794
|
+
};
|
|
1795
|
+
// Handle escape key
|
|
1796
|
+
React__namespace.useEffect(() => {
|
|
1797
|
+
if (!isOpen || !closeOnEscape)
|
|
1798
|
+
return;
|
|
1799
|
+
const handleEscape = (e) => {
|
|
1800
|
+
if (e.key === "Escape") {
|
|
1801
|
+
onClose();
|
|
1802
|
+
}
|
|
1803
|
+
};
|
|
1804
|
+
document.addEventListener("keydown", handleEscape);
|
|
1805
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
1806
|
+
}, [isOpen, closeOnEscape, onClose]);
|
|
1807
|
+
// Prevent body scroll when modal is open
|
|
1808
|
+
React__namespace.useEffect(() => {
|
|
1809
|
+
if (isOpen) {
|
|
1810
|
+
document.body.style.overflow = "hidden";
|
|
1811
|
+
}
|
|
1812
|
+
else {
|
|
1813
|
+
document.body.style.overflow = "";
|
|
1814
|
+
}
|
|
1815
|
+
return () => {
|
|
1816
|
+
document.body.style.overflow = "";
|
|
1817
|
+
};
|
|
1818
|
+
}, [isOpen]);
|
|
1819
|
+
// Handle overlay click
|
|
1820
|
+
const handleOverlayClick = (e) => {
|
|
1821
|
+
if (closeOnOverlayClick && e.target === e.currentTarget) {
|
|
1822
|
+
onClose();
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
// Don't render if not open
|
|
1826
|
+
if (!isOpen)
|
|
1827
|
+
return null;
|
|
1828
|
+
const hasHeader = title || description;
|
|
1829
|
+
return (jsxRuntime.jsxs("div", { className: cn("fixed inset-0 z-50 flex items-center justify-center p-4", className), role: "dialog", "aria-modal": "true", "aria-label": ariaLabel || title, "aria-describedby": ariaDescribedBy, children: [jsxRuntime.jsx("div", { className: cn("absolute inset-0 bg-black/50 backdrop-blur-sm transition-opacity", overlayClassName), onClick: handleOverlayClick, "aria-hidden": "true" }), jsxRuntime.jsxs("div", { ref: contentRef, className: cn("relative w-full bg-white rounded-large shadow-xl transition-all", "flex flex-col max-h-[90vh]", sizeConfig[size], contentClassName), children: [hasHeader && (jsxRuntime.jsxs("div", { className: cn("flex items-start justify-between gap-4 px-6 pt-6", !description && "pb-4", description && "pb-2", headerClassName), children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [title && (jsxRuntime.jsx(Text, { as: "h2", variant: "body", size: "large", weight: "semibold", color: "default", children: title })), description && (jsxRuntime.jsx(Text, { as: "p", variant: "body", size: "small", weight: "regular", color: "subtle", className: "mt-1", children: description }))] }), showCloseButton && (jsxRuntime.jsx("button", { type: "button", onClick: onClose, className: cn("shrink-0 rounded-medium p-1.5 transition-colors", "text-surface-ink-neutral-muted hover:text-surface-ink-neutral-default", "hover:bg-surface-fill-neutral-faded focus:outline-none focus:ring-2", "focus:ring-action-outline-primary-default focus:ring-offset-2"), "aria-label": "Close modal", children: jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" }) }))] })), !hasHeader && showCloseButton && (jsxRuntime.jsx("div", { className: "absolute top-4 right-4 z-10", children: jsxRuntime.jsx("button", { type: "button", onClick: onClose, className: cn("shrink-0 rounded-medium p-1.5 transition-colors", "text-surface-ink-neutral-muted hover:text-surface-ink-neutral-default", "hover:bg-surface-fill-neutral-faded focus:outline-none focus:ring-2", "focus:ring-action-outline-primary-default focus:ring-offset-2"), "aria-label": "Close modal", children: jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" }) }) })), jsxRuntime.jsx("div", { className: cn("flex-1 overflow-y-auto px-6", hasHeader ? "py-4" : "pt-6 pb-4", !footer && "pb-6", bodyClassName), children: children }), footer && (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(Divider, { thickness: "thin", variant: "muted" }), jsxRuntime.jsx("div", { className: cn("flex items-center justify-end gap-3 px-6 py-4", footerClassName), children: footer })] }))] })] }));
|
|
1830
|
+
});
|
|
1831
|
+
Modal.displayName = "Modal";
|
|
1832
|
+
|
|
1833
|
+
const selectVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-medium transition-all font-display font-size-100 leading-100", {
|
|
1834
|
+
variants: {
|
|
1835
|
+
size: {
|
|
1836
|
+
small: "h-[28px] px-3 text-xs gap-2",
|
|
1837
|
+
medium: "h-[36px] px-4 text-sm gap-2",
|
|
1838
|
+
large: "h-[44px] px-5 text-base gap-3",
|
|
1839
|
+
},
|
|
1840
|
+
validationState: {
|
|
1841
|
+
none: `
|
|
1842
|
+
border-action-outline-neutral-faded
|
|
1843
|
+
hover:border-action-outline-primary-hover
|
|
1844
|
+
focus-within:border-action-outline-primary-hover
|
|
1845
|
+
focus-within:ring-2
|
|
1846
|
+
ring-action-outline-primary-faded-hover`,
|
|
1847
|
+
positive: `
|
|
1848
|
+
border-action-outline-positive-default
|
|
1849
|
+
focus-within:border-action-outline-positive-hover
|
|
1850
|
+
focus-within:ring-2
|
|
1851
|
+
ring-action-outline-positive-faded-hover`,
|
|
1852
|
+
negative: `border-action-outline-negative-default
|
|
1853
|
+
focus-within:border-action-outline-negative-hover
|
|
1854
|
+
focus-within:ring-2
|
|
1855
|
+
ring-action-outline-negative-faded-hover`,
|
|
1856
|
+
},
|
|
1857
|
+
isDisabled: {
|
|
1858
|
+
true: `
|
|
1859
|
+
border-[var(--border-width-thinner)]
|
|
1860
|
+
hover:border-action-outline-neutral-disabled
|
|
1861
|
+
border-action-outline-neutral-disabled
|
|
1862
|
+
bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
|
|
1863
|
+
false: "bg-surface-fill-neutral-intense",
|
|
1864
|
+
},
|
|
1865
|
+
},
|
|
1866
|
+
defaultVariants: {
|
|
1867
|
+
size: "medium",
|
|
1868
|
+
validationState: "none",
|
|
1869
|
+
isDisabled: false,
|
|
1870
|
+
},
|
|
1871
|
+
});
|
|
1872
|
+
const Select = React__namespace.forwardRef(({ className, options = [], value: controlledValue, defaultValue, onChange, placeholder = "Select an option", label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, isLoading = false, size = "medium", prefix, suffix, showClearButton = false, onClear, containerClassName, labelClassName, triggerClassName, menuClassName, menuWidth = "full", sectionHeading, emptyTitle = "No options available", emptyDescription = "There are no options to select from.", emptyIcon, infoHeading, infoDescription, linkText, linkHref, onLinkClick, ...props }, ref) => {
|
|
1873
|
+
const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(defaultValue);
|
|
1874
|
+
const [isOpen, setIsOpen] = React__namespace.useState(false);
|
|
1875
|
+
const selectRef = React__namespace.useRef(null);
|
|
1876
|
+
const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
|
|
1877
|
+
// Find the selected option
|
|
1878
|
+
const selectedOption = options.find((opt) => opt.value === value);
|
|
1879
|
+
const hasValue = value !== undefined && value !== "";
|
|
1880
|
+
// Determine which helper text to show
|
|
1881
|
+
const displayHelperText = errorText || successText || helperText;
|
|
1882
|
+
const currentValidationState = errorText
|
|
1883
|
+
? "negative"
|
|
1884
|
+
: successText
|
|
1885
|
+
? "positive"
|
|
1886
|
+
: validationState;
|
|
1887
|
+
const handleOpenChange = (newOpen) => {
|
|
1888
|
+
if (!isDisabled && !isLoading) {
|
|
1889
|
+
setIsOpen(newOpen);
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
const toggleOpen = () => {
|
|
1893
|
+
handleOpenChange(!isOpen);
|
|
1894
|
+
};
|
|
1895
|
+
const handleSelect = (option) => {
|
|
1896
|
+
if (controlledValue === undefined) {
|
|
1897
|
+
setUncontrolledValue(option.value);
|
|
1898
|
+
}
|
|
1899
|
+
onChange?.(option.value, option);
|
|
1900
|
+
setIsOpen(false);
|
|
1901
|
+
};
|
|
1902
|
+
const handleClear = (e) => {
|
|
1903
|
+
e.stopPropagation();
|
|
1904
|
+
if (onClear) {
|
|
1905
|
+
onClear();
|
|
1906
|
+
}
|
|
1907
|
+
else {
|
|
1908
|
+
if (controlledValue === undefined) {
|
|
1909
|
+
setUncontrolledValue(undefined);
|
|
1910
|
+
}
|
|
1911
|
+
onChange?.("", {});
|
|
1912
|
+
}
|
|
1913
|
+
};
|
|
1914
|
+
// Close dropdown when clicking outside
|
|
1915
|
+
React__namespace.useEffect(() => {
|
|
1916
|
+
const handleClickOutside = (event) => {
|
|
1917
|
+
if (selectRef.current &&
|
|
1918
|
+
!selectRef.current.contains(event.target)) {
|
|
1919
|
+
handleOpenChange(false);
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
if (isOpen) {
|
|
1923
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1924
|
+
return () => {
|
|
1925
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
}, [isOpen]);
|
|
1929
|
+
// Close on escape key
|
|
1930
|
+
React__namespace.useEffect(() => {
|
|
1931
|
+
const handleEscape = (event) => {
|
|
1932
|
+
if (event.key === "Escape") {
|
|
1933
|
+
handleOpenChange(false);
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
if (isOpen) {
|
|
1937
|
+
document.addEventListener("keydown", handleEscape);
|
|
1938
|
+
return () => {
|
|
1939
|
+
document.removeEventListener("keydown", handleEscape);
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
}, [isOpen]);
|
|
1943
|
+
// Handle keyboard navigation
|
|
1944
|
+
React__namespace.useEffect(() => {
|
|
1945
|
+
const handleKeyDown = (event) => {
|
|
1946
|
+
if (isDisabled || isLoading)
|
|
1947
|
+
return;
|
|
1948
|
+
if (!isOpen && (event.key === "Enter" || event.key === " ")) {
|
|
1949
|
+
event.preventDefault();
|
|
1950
|
+
setIsOpen(true);
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
if (isOpen) {
|
|
1954
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
1955
|
+
event.preventDefault();
|
|
1956
|
+
const currentIndex = options.findIndex((opt) => opt.value === value);
|
|
1957
|
+
const nextIndex = event.key === "ArrowDown"
|
|
1958
|
+
? Math.min(currentIndex + 1, options.length - 1)
|
|
1959
|
+
: Math.max(currentIndex - 1, 0);
|
|
1960
|
+
if (options[nextIndex] && !options[nextIndex].isDisabled) {
|
|
1961
|
+
handleSelect(options[nextIndex]);
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1966
|
+
if (selectRef.current) {
|
|
1967
|
+
selectRef.current.addEventListener("keydown", handleKeyDown);
|
|
1968
|
+
return () => {
|
|
1969
|
+
selectRef.current?.removeEventListener("keydown", handleKeyDown);
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
}, [isOpen, value, options, isDisabled, isLoading]);
|
|
1973
|
+
// Transform options to dropdown menu items
|
|
1974
|
+
const menuItems = options.map((option) => ({
|
|
1975
|
+
...option,
|
|
1976
|
+
onClick: () => handleSelect(option),
|
|
1977
|
+
}));
|
|
1978
|
+
const widthStyle = menuWidth === "full" ? "100%" : menuWidth === "auto" ? "auto" : menuWidth;
|
|
1979
|
+
const sizeConfig = {
|
|
1980
|
+
small: {
|
|
1981
|
+
gap: "gap-2",
|
|
1982
|
+
},
|
|
1983
|
+
medium: {
|
|
1984
|
+
gap: "gap-2",
|
|
1985
|
+
},
|
|
1986
|
+
large: {
|
|
1987
|
+
gap: "gap-3",
|
|
1988
|
+
},
|
|
1989
|
+
};
|
|
1990
|
+
return (jsxRuntime.jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsxs("div", { ref: selectRef, className: cn(selectVariants({
|
|
1991
|
+
size,
|
|
1992
|
+
validationState: currentValidationState,
|
|
1993
|
+
isDisabled,
|
|
1994
|
+
}), "relative w-full cursor-pointer", className), onClick: !isDisabled && !isLoading ? toggleOpen : undefined, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-disabled": isDisabled, ...props, children: [prefix && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
|
|
1995
|
+
? "text-surface-ink-neutral-disabled"
|
|
1996
|
+
: currentValidationState === "positive"
|
|
1997
|
+
? "text-feedback-ink-positive-intense"
|
|
1998
|
+
: currentValidationState === "negative"
|
|
1999
|
+
? "text-feedback-ink-negative-subtle"
|
|
2000
|
+
: "text-surface-ink-neutral-muted"), children: prefix })), jsxRuntime.jsx("span", { className: cn("flex-1 text-left truncate", !selectedOption && "text-surface-ink-neutral-muted", isDisabled && "text-surface-ink-neutral-disabled"), children: isLoading
|
|
2001
|
+
? "Loading..."
|
|
2002
|
+
: selectedOption?.label || selectedOption?.title || placeholder }), showClearButton && hasValue && !isDisabled && !isLoading && (jsxRuntime.jsx("button", { type: "button", onClick: handleClear, className: "shrink-0 flex items-center justify-center text-surface-ink-neutral-muted hover:text-surface-ink-neutral-normal transition-colors", tabIndex: -1, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && !showClearButton && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
|
|
2003
|
+
? "text-surface-ink-neutral-disabled"
|
|
2004
|
+
: currentValidationState === "positive"
|
|
2005
|
+
? "text-feedback-ink-positive-intense"
|
|
2006
|
+
: currentValidationState === "negative"
|
|
2007
|
+
? "text-feedback-ink-negative-subtle"
|
|
2008
|
+
: "text-surface-ink-neutral-muted"), children: suffix })), jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn("shrink-0 w-4 h-4 transition-transform", isDisabled
|
|
2009
|
+
? "text-surface-ink-neutral-disabled"
|
|
2010
|
+
: currentValidationState === "positive"
|
|
2011
|
+
? "text-feedback-ink-positive-intense"
|
|
2012
|
+
: currentValidationState === "negative"
|
|
2013
|
+
? "text-feedback-ink-negative-subtle"
|
|
2014
|
+
: "text-surface-ink-neutral-muted", isOpen && "transform rotate-180") }), isOpen && !isDisabled && !isLoading && (jsxRuntime.jsx("div", { className: "absolute z-50 left-0 right-0 top-full mt-1", children: jsxRuntime.jsx(DropdownMenu, { ref: ref, items: menuItems, sectionHeading: sectionHeading, isEmpty: options.length === 0, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyIcon: emptyIcon, disableFooter: true, onClose: () => handleOpenChange(false), className: menuClassName, width: widthStyle }) }))] }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
|
|
2015
|
+
? "default"
|
|
2016
|
+
: currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
|
|
2017
|
+
});
|
|
2018
|
+
Select.displayName = "Select";
|
|
2019
|
+
|
|
2020
|
+
const paginationVariants = classVarianceAuthority.cva("flex items-center gap-4 font-display text-body-medium-medium", {
|
|
2021
|
+
variants: {
|
|
2022
|
+
size: {
|
|
2023
|
+
small: "text-xs gap-2",
|
|
2024
|
+
medium: "text-sm gap-4",
|
|
2025
|
+
large: "text-base gap-5",
|
|
2026
|
+
},
|
|
2027
|
+
},
|
|
2028
|
+
defaultVariants: {
|
|
2029
|
+
size: "medium",
|
|
2030
|
+
},
|
|
2031
|
+
});
|
|
2032
|
+
const Pagination = React__namespace.forwardRef(({ className, currentPage: controlledCurrentPage, totalPages, rowsPerPage: controlledRowsPerPage, rowsPerPageOptions = [5, 10, 15, 20, 25, 50, 100], showRowsPerPage = true, onPageChange, onRowsPerPageChange, size = "medium", isDisabled = false, rowsPerPageLabel = "Row per page", ofLabel = "of", prevLabel = "Prev", nextLabel = "Next", showPrevNext = true, showPageJumper = true, showPageNumber = true, pageStatus, maxPageButtons = 5, ...props }, ref) => {
|
|
2033
|
+
const [uncontrolledCurrentPage, setUncontrolledCurrentPage] = React__namespace.useState(1);
|
|
2034
|
+
const [uncontrolledRowsPerPage, setUncontrolledRowsPerPage] = React__namespace.useState(rowsPerPageOptions[0] || 10);
|
|
2035
|
+
const currentPage = controlledCurrentPage !== undefined
|
|
2036
|
+
? controlledCurrentPage
|
|
2037
|
+
: uncontrolledCurrentPage;
|
|
2038
|
+
const rowsPerPage = controlledRowsPerPage !== undefined
|
|
2039
|
+
? controlledRowsPerPage
|
|
2040
|
+
: uncontrolledRowsPerPage;
|
|
2041
|
+
// Generate rows per page options
|
|
2042
|
+
const rowsPerPageSelectOptions = rowsPerPageOptions.map((value) => {
|
|
2043
|
+
const valueStr = String(value);
|
|
2044
|
+
// Pad with leading zero if needed (manual implementation for compatibility)
|
|
2045
|
+
const label = valueStr.length < 2 ? "0" + valueStr : valueStr;
|
|
2046
|
+
return {
|
|
2047
|
+
id: `rows-${valueStr}`,
|
|
2048
|
+
value: valueStr,
|
|
2049
|
+
label: label,
|
|
2050
|
+
title: valueStr,
|
|
2051
|
+
};
|
|
2052
|
+
});
|
|
2053
|
+
// Generate page options
|
|
2054
|
+
const pageOptions = Array.from({ length: totalPages }, (_, i) => {
|
|
2055
|
+
const pageNum = i + 1;
|
|
2056
|
+
const pageStr = String(pageNum);
|
|
2057
|
+
return {
|
|
2058
|
+
id: `page-${pageStr}`,
|
|
2059
|
+
value: pageStr,
|
|
2060
|
+
label: pageStr,
|
|
2061
|
+
title: `Page ${pageNum}`,
|
|
2062
|
+
};
|
|
2063
|
+
});
|
|
2064
|
+
const handlePageChange = (newPage) => {
|
|
2065
|
+
if (newPage < 1 || newPage > totalPages)
|
|
2066
|
+
return;
|
|
2067
|
+
if (controlledCurrentPage === undefined) {
|
|
2068
|
+
setUncontrolledCurrentPage(newPage);
|
|
2069
|
+
}
|
|
2070
|
+
onPageChange?.(newPage);
|
|
2071
|
+
};
|
|
2072
|
+
const handleRowsPerPageChange = (value) => {
|
|
2073
|
+
const newRowsPerPage = typeof value === "string" ? parseInt(value) : value;
|
|
2074
|
+
if (controlledRowsPerPage === undefined) {
|
|
2075
|
+
setUncontrolledRowsPerPage(newRowsPerPage);
|
|
2076
|
+
}
|
|
2077
|
+
onRowsPerPageChange?.(newRowsPerPage);
|
|
2078
|
+
// Reset to first page when rows per page changes
|
|
2079
|
+
handlePageChange(1);
|
|
2080
|
+
};
|
|
2081
|
+
const handlePrevPage = () => {
|
|
2082
|
+
handlePageChange(currentPage - 1);
|
|
2083
|
+
};
|
|
2084
|
+
const handleNextPage = () => {
|
|
2085
|
+
handlePageChange(currentPage + 1);
|
|
2086
|
+
};
|
|
2087
|
+
const isPrevDisabled = currentPage <= 1 || isDisabled;
|
|
2088
|
+
const isNextDisabled = currentPage >= totalPages || isDisabled;
|
|
2089
|
+
const selectSize = size === "small" ? "small" : size === "large" ? "large" : "medium";
|
|
2090
|
+
// Map pagination size to button size
|
|
2091
|
+
const buttonSize = size === "small" ? "xsmall" : size === "large" ? "large" : "small";
|
|
2092
|
+
// Generate page numbers to display
|
|
2093
|
+
const getPageNumbers = () => {
|
|
2094
|
+
if (totalPages <= maxPageButtons) {
|
|
2095
|
+
// Show all pages if total is less than max
|
|
2096
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
2097
|
+
}
|
|
2098
|
+
// Determine page status if not provided
|
|
2099
|
+
const effectivePageStatus = pageStatus ||
|
|
2100
|
+
(currentPage <= 2
|
|
2101
|
+
? "first"
|
|
2102
|
+
: currentPage >= totalPages - 1
|
|
2103
|
+
? "last"
|
|
2104
|
+
: "middle");
|
|
2105
|
+
if (effectivePageStatus === "first") {
|
|
2106
|
+
// Show first pages: 1, 2, 3, 4, 5
|
|
2107
|
+
return Array.from({ length: Math.min(maxPageButtons, totalPages) }, (_, i) => i + 1);
|
|
2108
|
+
}
|
|
2109
|
+
else if (effectivePageStatus === "last") {
|
|
2110
|
+
// Show last pages
|
|
2111
|
+
const start = totalPages - maxPageButtons + 1;
|
|
2112
|
+
return Array.from({ length: maxPageButtons }, (_, i) => start + i);
|
|
2113
|
+
}
|
|
2114
|
+
else if (effectivePageStatus === "middle") {
|
|
2115
|
+
// Show pages around current page
|
|
2116
|
+
const halfMax = Math.floor(maxPageButtons / 2);
|
|
2117
|
+
let start = currentPage - halfMax;
|
|
2118
|
+
let end = currentPage + halfMax;
|
|
2119
|
+
// Adjust if at boundaries
|
|
2120
|
+
if (start < 1) {
|
|
2121
|
+
end += 1 - start;
|
|
2122
|
+
start = 1;
|
|
2123
|
+
}
|
|
2124
|
+
if (end > totalPages) {
|
|
2125
|
+
start -= end - totalPages;
|
|
2126
|
+
end = totalPages;
|
|
2127
|
+
}
|
|
2128
|
+
start = Math.max(1, start);
|
|
2129
|
+
end = Math.min(totalPages, end);
|
|
2130
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
2131
|
+
}
|
|
2132
|
+
// pageStatus === "none" - don't show any page numbers
|
|
2133
|
+
return [];
|
|
2134
|
+
};
|
|
2135
|
+
const pageNumbers = getPageNumbers();
|
|
2136
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn(paginationVariants({ size }), className), ...props, children: [showRowsPerPage && (jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx("span", { className: "text-surface-ink-neutral-muted whitespace-nowrap", children: rowsPerPageLabel }), jsxRuntime.jsx("div", { className: "w-[80px]", children: jsxRuntime.jsx(Select, { value: rowsPerPage.toString(), options: rowsPerPageSelectOptions, onChange: handleRowsPerPageChange, size: selectSize, isDisabled: isDisabled, menuWidth: "auto" }) })] })), jsxRuntime.jsxs("div", { className: "flex items-center gap-3 ml-auto", children: [showPrevNext && (jsxRuntime.jsx(Button, { variant: "tertiary", color: "neutral", size: buttonSize, onClick: handlePrevPage, isDisabled: isPrevDisabled, leadingIcon: jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "w-4 h-4" }), "aria-label": "Previous page", children: prevLabel })), showPageJumper ? (
|
|
2137
|
+
// Show page dropdown selector
|
|
2138
|
+
jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx("div", { className: "w-[80px]", children: jsxRuntime.jsx(Select, { value: currentPage.toString(), options: pageOptions, onChange: (value) => handlePageChange(typeof value === "string" ? parseInt(value) : value), size: selectSize, isDisabled: isDisabled, menuWidth: "auto" }) }), jsxRuntime.jsxs("span", { className: "text-surface-ink-neutral-muted whitespace-nowrap", children: [ofLabel, " ", totalPages] })] })) : (
|
|
2139
|
+
// Show numbered page buttons
|
|
2140
|
+
showPageNumber &&
|
|
2141
|
+
pageNumbers.length > 0 && (jsxRuntime.jsx(ButtonGroup, { variant: "separated", size: buttonSize, isDisabled: isDisabled, value: currentPage, onChange: (value) => handlePageChange(value), children: pageNumbers.map((pageNum) => (jsxRuntime.jsx(Button, { value: pageNum, variant: "tertiary", color: "primary", "aria-label": `Page ${pageNum}`, "aria-current": pageNum === currentPage ? "page" : undefined, children: pageNum }, pageNum))) }))), showPrevNext && (jsxRuntime.jsx(Button, { variant: "tertiary", color: "neutral", size: buttonSize, onClick: handleNextPage, isDisabled: isNextDisabled, trailingIcon: jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-4 h-4" }), "aria-label": "Next page", children: nextLabel }))] })] }));
|
|
2142
|
+
});
|
|
2143
|
+
Pagination.displayName = "Pagination";
|
|
2144
|
+
|
|
1565
2145
|
const radioVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 border transition-all cursor-pointer rounded-full", {
|
|
1566
2146
|
variants: {
|
|
1567
2147
|
size: {
|
|
@@ -1836,13 +2416,30 @@ const defaultFilter = (item, query) => {
|
|
|
1836
2416
|
return (item.title.toLowerCase().includes(searchQuery) ||
|
|
1837
2417
|
(item.description?.toLowerCase().includes(searchQuery) ?? false));
|
|
1838
2418
|
};
|
|
1839
|
-
const SearchableDropdown = React__namespace.forwardRef(({ className, items = [], sectionHeading, isLoading = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, dropdownWidth = "full", showChevron = false, emptyIcon, disableFooter = false, onSearchChange, onItemSelect, filterFunction = defaultFilter, searchValue: controlledSearchValue, defaultSearchValue = "", dropdownClassName, minSearchLength = 0, showOnFocus = true, containerClassName, ...textFieldProps }, ref) => {
|
|
2419
|
+
const SearchableDropdown = React__namespace.forwardRef(({ className, items = [], sectionHeading, isLoading = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, dropdownWidth = "full", showChevron = false, emptyIcon, disableFooter = false, footerLayout = "horizontal", onSearchChange, onItemSelect, filterFunction = defaultFilter, searchValue: controlledSearchValue, defaultSearchValue = "", dropdownClassName, minSearchLength = 0, showOnFocus = true, containerClassName, ...textFieldProps }, ref) => {
|
|
1840
2420
|
const [uncontrolledSearchValue, setUncontrolledSearchValue] = React__namespace.useState(defaultSearchValue);
|
|
1841
2421
|
const [isOpen, setIsOpen] = React__namespace.useState(false);
|
|
1842
2422
|
const [focusedIndex, setFocusedIndex] = React__namespace.useState(-1);
|
|
1843
2423
|
const dropdownRef = React__namespace.useRef(null);
|
|
1844
2424
|
const inputRef = React__namespace.useRef(null);
|
|
2425
|
+
const menuRef = React__namespace.useRef(null);
|
|
2426
|
+
const [position, setPosition] = React__namespace.useState({
|
|
2427
|
+
top: 0,
|
|
2428
|
+
left: 0,
|
|
2429
|
+
width: 0,
|
|
2430
|
+
});
|
|
1845
2431
|
React__namespace.useImperativeHandle(ref, () => inputRef.current);
|
|
2432
|
+
// Update position when dropdown opens or window resizes
|
|
2433
|
+
React__namespace.useEffect(() => {
|
|
2434
|
+
if (isOpen && dropdownRef.current) {
|
|
2435
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
2436
|
+
setPosition({
|
|
2437
|
+
top: rect.bottom + window.scrollY,
|
|
2438
|
+
left: rect.left + window.scrollX,
|
|
2439
|
+
width: rect.width,
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
}, [isOpen]);
|
|
1846
2443
|
const searchValue = controlledSearchValue !== undefined
|
|
1847
2444
|
? controlledSearchValue
|
|
1848
2445
|
: uncontrolledSearchValue;
|
|
@@ -1868,7 +2465,7 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
1868
2465
|
const handleItemSelect = (item) => {
|
|
1869
2466
|
onItemSelect?.(item);
|
|
1870
2467
|
if (controlledSearchValue === undefined) {
|
|
1871
|
-
setUncontrolledSearchValue(item.
|
|
2468
|
+
setUncontrolledSearchValue(item.title);
|
|
1872
2469
|
}
|
|
1873
2470
|
setIsOpen(false);
|
|
1874
2471
|
inputRef.current?.focus();
|
|
@@ -1883,7 +2480,9 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
1883
2480
|
React__namespace.useEffect(() => {
|
|
1884
2481
|
const handleClickOutside = (event) => {
|
|
1885
2482
|
if (dropdownRef.current &&
|
|
1886
|
-
!dropdownRef.current.contains(event.target)
|
|
2483
|
+
!dropdownRef.current.contains(event.target) &&
|
|
2484
|
+
menuRef.current &&
|
|
2485
|
+
!menuRef.current.contains(event.target)) {
|
|
1887
2486
|
setIsOpen(false);
|
|
1888
2487
|
}
|
|
1889
2488
|
};
|
|
@@ -1931,7 +2530,16 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
1931
2530
|
onClick: () => handleItemSelect(item),
|
|
1932
2531
|
}));
|
|
1933
2532
|
const showDropdown = isOpen && searchValue.length >= minSearchLength;
|
|
1934
|
-
|
|
2533
|
+
const dropdownMenu = showDropdown && (jsxRuntime.jsx("div", { ref: menuRef, style: {
|
|
2534
|
+
position: "absolute",
|
|
2535
|
+
top: `${position.top + 8}px`,
|
|
2536
|
+
left: `${position.left}px`,
|
|
2537
|
+
width: dropdownWidth === "full" ? `${position.width}px` : "auto",
|
|
2538
|
+
zIndex: 9999,
|
|
2539
|
+
}, children: jsxRuntime.jsx(DropdownMenu, { items: itemsWithHandlers, sectionHeading: sectionHeading, isLoading: isLoading, isEmpty: filteredItems.length === 0, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyLinkText: emptyLinkText, onEmptyLinkClick: onEmptyLinkClick, primaryButtonText: primaryButtonText, secondaryButtonText: secondaryButtonText, onPrimaryClick: onPrimaryClick, onSecondaryClick: onSecondaryClick, showChevron: showChevron, emptyIcon: emptyIcon, disableFooter: disableFooter, footerLayout: footerLayout, onClose: () => setIsOpen(false), focusedIndex: focusedIndex, className: dropdownClassName, width: dropdownWidth === "full" ? "full" : "auto" }) }));
|
|
2540
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: dropdownRef, className: cn("relative", containerClassName), children: jsxRuntime.jsx(TextField, { ref: inputRef, value: searchValue, onChange: handleSearchChange, onFocus: handleFocus, onKeyDown: handleKeyDown, containerClassName: "mb-0", ...textFieldProps }) }), typeof document !== "undefined" &&
|
|
2541
|
+
dropdownMenu &&
|
|
2542
|
+
reactDom.createPortal(dropdownMenu, document.body)] }));
|
|
1935
2543
|
});
|
|
1936
2544
|
SearchableDropdown.displayName = "SearchableDropdown";
|
|
1937
2545
|
|
|
@@ -2075,6 +2683,249 @@ const Switch = React__namespace.forwardRef(({ label, size = "medium", isDisabled
|
|
|
2075
2683
|
});
|
|
2076
2684
|
Switch.displayName = "Switch";
|
|
2077
2685
|
|
|
2686
|
+
const tableVariants = classVarianceAuthority.cva("w-full border-collapse", {
|
|
2687
|
+
variants: {
|
|
2688
|
+
variant: {
|
|
2689
|
+
default: "border-separate border-spacing-0",
|
|
2690
|
+
bordered: "border-separate border-spacing-0",
|
|
2691
|
+
striped: "border-separate border-spacing-0",
|
|
2692
|
+
},
|
|
2693
|
+
size: {
|
|
2694
|
+
small: "text-body-small-medium",
|
|
2695
|
+
medium: "text-body-medium-medium",
|
|
2696
|
+
large: "text-body-large-medium",
|
|
2697
|
+
},
|
|
2698
|
+
},
|
|
2699
|
+
defaultVariants: {
|
|
2700
|
+
variant: "default",
|
|
2701
|
+
size: "medium",
|
|
2702
|
+
},
|
|
2703
|
+
});
|
|
2704
|
+
const tableHeaderVariants = classVarianceAuthority.cva("text-body-medium-regular text-left text-surface-ink-neutral-normal border-b border-surface-outline-neutral-muted", {
|
|
2705
|
+
variants: {
|
|
2706
|
+
size: {
|
|
2707
|
+
small: "px-3 py-2 h-[32px]",
|
|
2708
|
+
medium: "px-4 py-3 h-[40px]",
|
|
2709
|
+
large: "px-6 py-4 h-[48px]",
|
|
2710
|
+
},
|
|
2711
|
+
},
|
|
2712
|
+
defaultVariants: {
|
|
2713
|
+
size: "medium",
|
|
2714
|
+
},
|
|
2715
|
+
});
|
|
2716
|
+
const tableCellVariants = classVarianceAuthority.cva("text-body-medium-regular border-b border-surface-outline-neutral-muted text-surface-ink-neutral-normal transition-colors duration-150", {
|
|
2717
|
+
variants: {
|
|
2718
|
+
size: {
|
|
2719
|
+
small: "px-3 py-2 h-[40px]",
|
|
2720
|
+
medium: "px-4 py-3 h-[72px]",
|
|
2721
|
+
large: "px-6 py-4 h-[56px]",
|
|
2722
|
+
},
|
|
2723
|
+
state: {
|
|
2724
|
+
default: "",
|
|
2725
|
+
focus: "",
|
|
2726
|
+
// focus:
|
|
2727
|
+
// "outline outline-2 outline-action-outline-primary-default outline-offset-[-2px]",
|
|
2728
|
+
},
|
|
2729
|
+
},
|
|
2730
|
+
defaultVariants: {
|
|
2731
|
+
size: "medium",
|
|
2732
|
+
state: "default",
|
|
2733
|
+
},
|
|
2734
|
+
});
|
|
2735
|
+
|
|
2736
|
+
function TableHeader({ headerGroups, enableRowSelection, enableSelectAll, showHeaderBackground, stickyHeader, size, headerClassName, isDetailPanelOpen, visibleHeadersCount, onToggleAllRows, isAllRowsSelected, isSomeRowsSelected, }) {
|
|
2737
|
+
return (jsxRuntime.jsx("thead", { className: cn(showHeaderBackground && "bg-surface-fill-neutral-moderate", stickyHeader && "sticky top-0 z-10"), children: headerGroups.map((headerGroup) => (jsxRuntime.jsxs("tr", { children: [enableRowSelection && enableSelectAll && (jsxRuntime.jsx("th", { className: cn(tableHeaderVariants({ size }), showHeaderBackground && "bg-surface-fill-neutral-moderate", "w-10 rounded-tl-xlarge rounded-bl-xlarge", headerClassName), children: jsxRuntime.jsx(Checkbox, { checked: isAllRowsSelected, isIndeterminate: isSomeRowsSelected, onChange: onToggleAllRows, "aria-label": "Select all rows" }) })), headerGroup.headers.map((header, index) => {
|
|
2738
|
+
const shouldHideColumn = isDetailPanelOpen && index >= visibleHeadersCount;
|
|
2739
|
+
const isLastVisibleColumn = isDetailPanelOpen
|
|
2740
|
+
? index === visibleHeadersCount - 1
|
|
2741
|
+
: index === headerGroup.headers.length - 1;
|
|
2742
|
+
return (jsxRuntime.jsx("th", { className: cn(tableHeaderVariants({ size }), showHeaderBackground &&
|
|
2743
|
+
"bg-surface-fill-neutral-moderate border-none", !enableRowSelection &&
|
|
2744
|
+
index === 0 &&
|
|
2745
|
+
"rounded-tl-xlarge rounded-bl-xlarge", isLastVisibleColumn && "rounded-tr-xlarge rounded-br-xlarge", header.column.columnDef.meta?.headerClassName, headerClassName, "transition-all duration-300 ease-in-out", shouldHideColumn
|
|
2746
|
+
? "opacity-0 translate-x-8 pointer-events-none"
|
|
2747
|
+
: "opacity-100 translate-x-0"), style: {
|
|
2748
|
+
width: header.getSize(),
|
|
2749
|
+
minWidth: header.column.columnDef.minSize,
|
|
2750
|
+
maxWidth: header.column.columnDef.maxSize,
|
|
2751
|
+
}, children: header.isPlaceholder ? null : (jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", header.column.getCanSort() && "cursor-pointer select-none"), onClick: header.column.getToggleSortingHandler(), children: [reactTable.flexRender(header.column.columnDef.header, header.getContext()), header.column.getCanSort() && (jsxRuntime.jsx("span", { className: "text-surface-ink-neutral-muted", children: {
|
|
2752
|
+
asc: "↑",
|
|
2753
|
+
desc: "↓",
|
|
2754
|
+
}[header.column.getIsSorted()] ?? "↕" }))] })) }, header.id));
|
|
2755
|
+
})] }, headerGroup.id))) }));
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
function TableBody({ rows, enableRowSelection, size, variant, showRowHover, cellClassName, isDetailPanelOpen, visibleHeadersCount, effectiveSelectedRowId, onRowClick, getRowClassName, handleRowClick, }) {
|
|
2759
|
+
const [focusedCell, setFocusedCell] = React__namespace.useState(null);
|
|
2760
|
+
const [hoveredRow, setHoveredRow] = React__namespace.useState(null);
|
|
2761
|
+
return (jsxRuntime.jsx("tbody", { className: "bg-surface-fill-neutral-intense", children: rows.map((row) => {
|
|
2762
|
+
const isRowSelected = row.id === effectiveSelectedRowId;
|
|
2763
|
+
const isRowHovered = hoveredRow === row.id;
|
|
2764
|
+
const handleClick = () => handleRowClick(row.original, row.id);
|
|
2765
|
+
return (jsxRuntime.jsxs("tr", { className: cn(variant === "striped" &&
|
|
2766
|
+
row.index % 2 === 1 &&
|
|
2767
|
+
"bg-surface-fill-neutral-moderate", onRowClick && "cursor-pointer", isRowSelected && "bg-action-fill-primary-faded", isRowHovered &&
|
|
2768
|
+
showRowHover &&
|
|
2769
|
+
"bg-surface-fill-neutral-moderate", getRowClassName(row.original)), onClick: handleClick, onMouseEnter: () => setHoveredRow(row.id), onMouseLeave: () => setHoveredRow(null), children: [enableRowSelection && (jsxRuntime.jsx("td", { className: cn(tableCellVariants({ size }), "w-10", cellClassName), children: jsxRuntime.jsx(Checkbox, { checked: row.getIsSelected(), isIndeterminate: row.getIsSomeSelected(), onChange: row.getToggleSelectedHandler(), onClick: (e) => e.stopPropagation(), "aria-label": `Select row ${row.id}` }) })), row.getVisibleCells().map((cell, cellIndex) => {
|
|
2770
|
+
const shouldHideColumn = isDetailPanelOpen && cellIndex >= visibleHeadersCount;
|
|
2771
|
+
const isCellFocused = focusedCell?.rowId === row.id &&
|
|
2772
|
+
focusedCell?.cellId === cell.id;
|
|
2773
|
+
const cellState = isCellFocused ? "focus" : "default";
|
|
2774
|
+
return (jsxRuntime.jsx("td", { className: cn(tableCellVariants({ size, state: cellState }), cell.column.columnDef.meta?.cellClassName, cellClassName, "transition-all duration-300 ease-in-out", shouldHideColumn
|
|
2775
|
+
? "opacity-0 translate-x-8 pointer-events-none"
|
|
2776
|
+
: "opacity-100 translate-x-0"), style: {
|
|
2777
|
+
width: cell.column.getSize(),
|
|
2778
|
+
minWidth: cell.column.columnDef.minSize,
|
|
2779
|
+
maxWidth: cell.column.columnDef.maxSize,
|
|
2780
|
+
}, tabIndex: 0, onFocus: () => setFocusedCell({ rowId: row.id, cellId: cell.id }), onBlur: () => setFocusedCell(null), children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
|
|
2781
|
+
})] }, row.id));
|
|
2782
|
+
}) }));
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
function DetailPanel({ isOpen, content, data, onClose, }) {
|
|
2786
|
+
return (jsxRuntime.jsx("div", { className: cn("absolute top-0 right-0 h-full z-20 transition-all duration-300 ease-in-out", isOpen
|
|
2787
|
+
? "translate-x-0 opacity-100"
|
|
2788
|
+
: "translate-x-full opacity-0 pointer-events-none"), style: { width: "332px", paddingLeft: "12px" }, children: jsxRuntime.jsx("div", { className: "w-full h-full bg-white border border-surface-outline-neutral-muted rounded-tr-xlarge rounded-br-xlarge overflow-hidden", children: jsxRuntime.jsx("div", { className: "w-full h-full overflow-auto", children: data && (jsxRuntime.jsxs("div", { className: "relative h-full", children: [jsxRuntime.jsx("button", { onClick: (e) => {
|
|
2789
|
+
e.stopPropagation();
|
|
2790
|
+
onClose();
|
|
2791
|
+
}, className: "absolute top-4 right-4 z-10 p-2 rounded-medium hover:bg-surface-fill-neutral-faded transition-colors", "aria-label": "Close detail panel", children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "text-surface-ink-neutral-muted", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4l8 8", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }), content(data)] })) }) }) }));
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
function renderDefaultLoadingState({ colSpan }) {
|
|
2795
|
+
return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: colSpan, className: "text-center py-12 text-surface-ink-neutral-muted", children: jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2", children: [jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-action-fill-primary-default" }), jsxRuntime.jsx("span", { children: "Loading..." })] }) }) }));
|
|
2796
|
+
}
|
|
2797
|
+
function renderDefaultEmptyState({ colSpan }) {
|
|
2798
|
+
return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: colSpan, className: "text-center py-12 text-surface-ink-neutral-muted", children: "No data available" }) }));
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2801
|
+
// ==================== Component ====================
|
|
2802
|
+
function TableComponent({ className, wrapperClassName, containerClassName, variant, size = "medium", table, enableRowSelection = false, enableSelectAll = false, isLoading = false, loadingComponent, emptyComponent, enableHorizontalScroll = false, stickyHeader = false, maxHeight, showRowHover = true, onRowClick, rowClassName, headerClassName, cellClassName, showHeaderBackground = true, detailPanel, hideColumnsOnDetailOpen = 3, selectedRowId, onRowSelectionChange, ...props }, ref) {
|
|
2803
|
+
// ==================== State ====================
|
|
2804
|
+
const [internalSelectedRowId, setInternalSelectedRowId] = React__namespace.useState(null);
|
|
2805
|
+
const selectedRowIdRef = React__namespace.useRef(null);
|
|
2806
|
+
const effectiveSelectedRowId = selectedRowId !== undefined ? selectedRowId : internalSelectedRowId;
|
|
2807
|
+
const isDetailPanelOpen = Boolean(effectiveSelectedRowId);
|
|
2808
|
+
// ==================== Effects ====================
|
|
2809
|
+
// Keep ref in sync
|
|
2810
|
+
React__namespace.useEffect(() => {
|
|
2811
|
+
selectedRowIdRef.current = effectiveSelectedRowId;
|
|
2812
|
+
}, [effectiveSelectedRowId]);
|
|
2813
|
+
// Clear selection if selected row is not in current data
|
|
2814
|
+
React__namespace.useEffect(() => {
|
|
2815
|
+
if (effectiveSelectedRowId) {
|
|
2816
|
+
const rowExists = table
|
|
2817
|
+
.getRowModel()
|
|
2818
|
+
.rows.some((r) => r.id === effectiveSelectedRowId);
|
|
2819
|
+
if (!rowExists) {
|
|
2820
|
+
if (selectedRowId === undefined) {
|
|
2821
|
+
setInternalSelectedRowId(null);
|
|
2822
|
+
}
|
|
2823
|
+
if (onRowSelectionChange) {
|
|
2824
|
+
onRowSelectionChange(null);
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
}, [
|
|
2829
|
+
table.getRowModel().rows,
|
|
2830
|
+
effectiveSelectedRowId,
|
|
2831
|
+
selectedRowId,
|
|
2832
|
+
onRowSelectionChange,
|
|
2833
|
+
]);
|
|
2834
|
+
// ==================== Computed Values ====================
|
|
2835
|
+
const hasData = table.getRowModel().rows?.length > 0;
|
|
2836
|
+
const headerGroups = table.getHeaderGroups();
|
|
2837
|
+
const headers = headerGroups[0]?.headers || [];
|
|
2838
|
+
const visibleHeadersCount = React__namespace.useMemo(() => {
|
|
2839
|
+
return isDetailPanelOpen
|
|
2840
|
+
? headers.length - hideColumnsOnDetailOpen
|
|
2841
|
+
: headers.length;
|
|
2842
|
+
}, [isDetailPanelOpen, headers.length, hideColumnsOnDetailOpen]);
|
|
2843
|
+
// ==================== Callbacks ====================
|
|
2844
|
+
const getRowClassName = React__namespace.useCallback((row) => {
|
|
2845
|
+
if (typeof rowClassName === "function") {
|
|
2846
|
+
return rowClassName(row);
|
|
2847
|
+
}
|
|
2848
|
+
return rowClassName || "";
|
|
2849
|
+
}, [rowClassName]);
|
|
2850
|
+
const handleRowClickInternal = React__namespace.useCallback((row, rowId) => {
|
|
2851
|
+
const currentSelectedId = selectedRowIdRef.current;
|
|
2852
|
+
const newSelectedId = currentSelectedId === rowId ? null : rowId;
|
|
2853
|
+
if (selectedRowId === undefined) {
|
|
2854
|
+
setInternalSelectedRowId(newSelectedId);
|
|
2855
|
+
}
|
|
2856
|
+
if (onRowSelectionChange) {
|
|
2857
|
+
onRowSelectionChange(newSelectedId);
|
|
2858
|
+
}
|
|
2859
|
+
if (onRowClick) {
|
|
2860
|
+
onRowClick(row);
|
|
2861
|
+
}
|
|
2862
|
+
}, [selectedRowId, onRowSelectionChange, onRowClick]);
|
|
2863
|
+
const getSelectedRowData = () => {
|
|
2864
|
+
if (!effectiveSelectedRowId)
|
|
2865
|
+
return null;
|
|
2866
|
+
const row = table
|
|
2867
|
+
.getRowModel()
|
|
2868
|
+
.rows.find((r) => r.id === effectiveSelectedRowId);
|
|
2869
|
+
return row ? row.original : null;
|
|
2870
|
+
};
|
|
2871
|
+
const handleDetailPanelClose = () => {
|
|
2872
|
+
if (selectedRowId === undefined) {
|
|
2873
|
+
setInternalSelectedRowId(null);
|
|
2874
|
+
}
|
|
2875
|
+
if (onRowSelectionChange) {
|
|
2876
|
+
onRowSelectionChange(null);
|
|
2877
|
+
}
|
|
2878
|
+
};
|
|
2879
|
+
// ==================== Render Helpers ====================
|
|
2880
|
+
const renderLoadingState = () => {
|
|
2881
|
+
if (loadingComponent)
|
|
2882
|
+
return loadingComponent;
|
|
2883
|
+
return renderDefaultLoadingState({ colSpan: table.getAllColumns().length });
|
|
2884
|
+
};
|
|
2885
|
+
const renderEmptyState = () => {
|
|
2886
|
+
if (emptyComponent)
|
|
2887
|
+
return emptyComponent;
|
|
2888
|
+
return renderDefaultEmptyState({ colSpan: table.getAllColumns().length });
|
|
2889
|
+
};
|
|
2890
|
+
// ==================== Render ====================
|
|
2891
|
+
return (jsxRuntime.jsx("div", { ref: ref, className: cn("w-full", wrapperClassName), ...props, children: jsxRuntime.jsxs("div", { className: cn("relative overflow-x-hidden", maxHeight && "overflow-y-auto", containerClassName), style: maxHeight ? { maxHeight } : undefined, children: [jsxRuntime.jsxs("table", { className: cn(tableVariants({ variant, size }), className), children: [jsxRuntime.jsx(TableHeader, { headerGroups: headerGroups, enableRowSelection: enableRowSelection, enableSelectAll: enableSelectAll, showHeaderBackground: showHeaderBackground, stickyHeader: stickyHeader, size: size || "medium", headerClassName: headerClassName, isDetailPanelOpen: isDetailPanelOpen, visibleHeadersCount: visibleHeadersCount, onToggleAllRows: (e) => table.getToggleAllRowsSelectedHandler()(e), isAllRowsSelected: table.getIsAllRowsSelected(), isSomeRowsSelected: table.getIsSomeRowsSelected() }), isLoading ? (jsxRuntime.jsx("tbody", { children: renderLoadingState() })) : !hasData ? (jsxRuntime.jsx("tbody", { children: renderEmptyState() })) : (jsxRuntime.jsx(TableBody, { rows: table.getRowModel().rows, enableRowSelection: enableRowSelection, size: size || "medium", variant: variant || "default", showRowHover: showRowHover, cellClassName: cellClassName, isDetailPanelOpen: isDetailPanelOpen, visibleHeadersCount: visibleHeadersCount, effectiveSelectedRowId: effectiveSelectedRowId, onRowClick: onRowClick, getRowClassName: getRowClassName, handleRowClick: handleRowClickInternal }))] }), detailPanel && (jsxRuntime.jsx(DetailPanel, { isOpen: isDetailPanelOpen, content: detailPanel, data: getSelectedRowData(), onClose: handleDetailPanelClose }))] }) }));
|
|
2892
|
+
}
|
|
2893
|
+
// ==================== Export ====================
|
|
2894
|
+
const Table = React__namespace.forwardRef(TableComponent);
|
|
2895
|
+
Table.displayName = "Table";
|
|
2896
|
+
|
|
2897
|
+
const TableDetailPanel = React__namespace.forwardRef(({ isOpen, onClose, children, className, width = "400px" }, ref) => {
|
|
2898
|
+
return (jsxRuntime.jsx("div", { ref: ref, className: cn("absolute top-0 right-0 h-full bg-white border border-surface-outline-neutral-muted transition-transform duration-300 ease-in-out overflow-auto", isOpen ? "translate-x-0" : "translate-x-full", className), style: { width }, children: children }));
|
|
2899
|
+
});
|
|
2900
|
+
TableDetailPanel.displayName = "TableDetailPanel";
|
|
2901
|
+
|
|
2902
|
+
function NumberCell({ value, currency, subtitle, className, }) {
|
|
2903
|
+
return (jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [jsxRuntime.jsxs("div", { className: "text-body-medium-medium text-surface-ink-neutral-normal", children: [currency, " ", value.toLocaleString("en-IN", {
|
|
2904
|
+
minimumFractionDigits: 2,
|
|
2905
|
+
maximumFractionDigits: 2,
|
|
2906
|
+
})] }), subtitle && (jsxRuntime.jsx("div", { className: "text-body-small-regular text-surface-ink-neutral-muted", children: subtitle }))] }));
|
|
2907
|
+
}
|
|
2908
|
+
function IconCell({ icon, background = "neutral", className, }) {
|
|
2909
|
+
const backgrounds = {
|
|
2910
|
+
neutral: "bg-surface-fill-neutral-faded",
|
|
2911
|
+
primary: "bg-action-fill-primary-faded",
|
|
2912
|
+
success: "bg-action-fill-positive-faded",
|
|
2913
|
+
warning: "bg-action-fill-warning-faded",
|
|
2914
|
+
danger: "bg-action-fill-negative-faded",
|
|
2915
|
+
};
|
|
2916
|
+
return (jsxRuntime.jsx("div", { className: cn("inline-flex items-center justify-center w-10 h-10 rounded-medium", backgrounds[background], className), children: icon }));
|
|
2917
|
+
}
|
|
2918
|
+
// ==================== Spacer Cell ====================
|
|
2919
|
+
function SpacerCell() {
|
|
2920
|
+
return jsxRuntime.jsx("div", { className: "w-full h-full" });
|
|
2921
|
+
}
|
|
2922
|
+
function SlotCell({ onDragStart, onDragEnd, className }) {
|
|
2923
|
+
return (jsxRuntime.jsx("div", { draggable: true, onDragStart: onDragStart, onDragEnd: onDragEnd, className: cn("flex items-center justify-center cursor-grab active:cursor-grabbing", className), children: jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "text-surface-ink-neutral-muted", children: [jsxRuntime.jsx("path", { d: "M6 4C6 3.44772 5.55228 3 5 3C4.44772 3 4 3.44772 4 4C4 4.55228 4.44772 5 5 5C5.55228 5 6 4.55228 6 4Z", fill: "currentColor" }), jsxRuntime.jsx("path", { d: "M6 8C6 7.44772 5.55228 7 5 7C4.44772 7 4 7.44772 4 8C4 8.55228 4.44772 9 5 9C5.55228 9 6 8.55228 6 8Z", fill: "currentColor" }), jsxRuntime.jsx("path", { d: "M6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 12.5523 4.44772 13 5 13C5.55228 13 6 12.5523 6 12Z", fill: "currentColor" }), jsxRuntime.jsx("path", { d: "M12 4C12 3.44772 11.5523 3 11 3C10.4477 3 10 3.44772 10 4C10 4.55228 10.4477 5 11 5C11.5523 5 12 4.55228 12 4Z", fill: "currentColor" }), jsxRuntime.jsx("path", { d: "M12 8C12 7.44772 11.5523 7 11 7C10.4477 7 10 7.44772 10 8C10 8.55228 10.4477 9 11 9C11.5523 9 12 8.55228 12 8Z", fill: "currentColor" }), jsxRuntime.jsx("path", { d: "M12 12C12 11.4477 11.5523 11 11 11C10.4477 11 10 11.4477 10 12C10 12.5523 10.4477 13 11 13C11.5523 13 12 12.5523 12 12Z", fill: "currentColor" })] }) }));
|
|
2924
|
+
}
|
|
2925
|
+
function AvatarCell({ name, initials, avatar, subtitle, color = "a1", className, }) {
|
|
2926
|
+
return (jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3", className), children: [avatar ? (jsxRuntime.jsx("img", { src: avatar, alt: name, className: "w-10 h-10 rounded-full object-cover" })) : (jsxRuntime.jsx("div", { className: cn("w-10 h-10 rounded-full flex items-center justify-center text-body-medium-medium", `bg-${color}`), children: initials || name.charAt(0).toUpperCase() })), jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx("div", { className: "text-body-medium-medium text-surface-ink-neutral-normal", children: name }), subtitle && (jsxRuntime.jsx("div", { className: "text-body-small-regular text-surface-ink-neutral-muted", children: subtitle }))] })] }));
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2078
2929
|
const tabItemVariants = classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 relative cursor-pointer", {
|
|
2079
2930
|
variants: {
|
|
2080
2931
|
variant: {
|
|
@@ -2277,8 +3128,11 @@ const TextArea = React__namespace.forwardRef(({ label, helperText, errorText, su
|
|
|
2277
3128
|
});
|
|
2278
3129
|
TextArea.displayName = "TextArea";
|
|
2279
3130
|
|
|
3131
|
+
exports.Avatar = Avatar;
|
|
3132
|
+
exports.AvatarCell = AvatarCell;
|
|
2280
3133
|
exports.Badge = Badge;
|
|
2281
3134
|
exports.Button = Button;
|
|
3135
|
+
exports.ButtonGroup = ButtonGroup;
|
|
2282
3136
|
exports.Checkbox = Checkbox;
|
|
2283
3137
|
exports.Counter = Counter;
|
|
2284
3138
|
exports.Divider = Divider;
|
|
@@ -2287,18 +3141,29 @@ exports.DropdownMenu = DropdownMenu;
|
|
|
2287
3141
|
exports.FormFooter = FormFooter;
|
|
2288
3142
|
exports.FormHeader = FormHeader;
|
|
2289
3143
|
exports.Icon = Icon;
|
|
3144
|
+
exports.IconCell = IconCell;
|
|
2290
3145
|
exports.Link = Link;
|
|
2291
3146
|
exports.ListItem = ListItem;
|
|
3147
|
+
exports.Modal = Modal;
|
|
3148
|
+
exports.NumberCell = NumberCell;
|
|
3149
|
+
exports.Pagination = Pagination;
|
|
2292
3150
|
exports.Radio = Radio;
|
|
2293
3151
|
exports.SearchableDropdown = SearchableDropdown;
|
|
3152
|
+
exports.Select = Select;
|
|
3153
|
+
exports.SlotCell = SlotCell;
|
|
3154
|
+
exports.SpacerCell = SpacerCell;
|
|
2294
3155
|
exports.Switch = Switch;
|
|
2295
3156
|
exports.TabItem = TabItem;
|
|
3157
|
+
exports.Table = Table;
|
|
3158
|
+
exports.TableDetailPanel = TableDetailPanel;
|
|
2296
3159
|
exports.Tabs = Tabs;
|
|
2297
3160
|
exports.Text = Text;
|
|
2298
3161
|
exports.TextArea = TextArea;
|
|
2299
3162
|
exports.TextField = TextField;
|
|
2300
3163
|
exports.Tooltip = Tooltip;
|
|
3164
|
+
exports.avatarVariants = avatarVariants;
|
|
2301
3165
|
exports.badgeVariants = badgeVariants;
|
|
3166
|
+
exports.buttonGroupVariants = buttonGroupVariants;
|
|
2302
3167
|
exports.buttonVariants = buttonVariants;
|
|
2303
3168
|
exports.checkboxVariants = checkboxVariants;
|
|
2304
3169
|
exports.cn = cn;
|
|
@@ -2309,8 +3174,13 @@ exports.hasIcon = hasIcon;
|
|
|
2309
3174
|
exports.iconRegistry = iconRegistry;
|
|
2310
3175
|
exports.linkVariants = linkVariants;
|
|
2311
3176
|
exports.listItemVariants = listItemVariants;
|
|
3177
|
+
exports.paginationVariants = paginationVariants;
|
|
2312
3178
|
exports.radioVariants = radioVariants;
|
|
3179
|
+
exports.selectVariants = selectVariants;
|
|
2313
3180
|
exports.switchVariants = switchVariants;
|
|
3181
|
+
exports.tableCellVariants = tableCellVariants;
|
|
3182
|
+
exports.tableHeaderVariants = tableHeaderVariants;
|
|
3183
|
+
exports.tableVariants = tableVariants;
|
|
2314
3184
|
exports.textAreaVariants = textAreaVariants;
|
|
2315
3185
|
exports.textFieldVariants = textFieldVariants;
|
|
2316
3186
|
exports.tooltipVariants = tooltipVariants;
|