infinity-ui-elements 1.4.1-beta.2 → 1.4.1-beta.4

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/index.js CHANGED
@@ -1011,6 +1011,303 @@ const Divider = React__namespace.forwardRef(({ className, orientation = "horizon
1011
1011
  });
1012
1012
  Divider.displayName = "Divider";
1013
1013
 
1014
+ const listItemVariants = classVarianceAuthority.cva("flex items-start gap-3 p-3 rounded-medium transition-colors cursor-pointer", {
1015
+ variants: {
1016
+ variant: {
1017
+ default: `hover:bg-action-fill-neutral-faded
1018
+ focus:bg-action-fill-neutral-faded
1019
+ focus:ring-2
1020
+ ring-action-outline-primary-faded-hover
1021
+ border border-transparent
1022
+ `,
1023
+ bordered: "border border-action-outline-primary-faded hover:bg-surface-fill-primary-subtle",
1024
+ primary: `hover:bg-action-fill-neutral-faded
1025
+ focus:bg-action-fill-neutral-faded
1026
+ focus:ring-2
1027
+ ring-action-outline-primary-faded-hover
1028
+ border border-transparent
1029
+ `,
1030
+ negative: `hover:bg-action-fill-negative-faded
1031
+ focus:bg-action-fill-negative-faded
1032
+ focus:ring-2 ring-action-outline-negative-faded-hover
1033
+ border border-transparent
1034
+ `,
1035
+ },
1036
+ isDisabled: {
1037
+ true: "cursor-not-allowed opacity-60",
1038
+ false: "",
1039
+ },
1040
+ isSelected: {
1041
+ true: "bg-action-fill-primary-faded border-action-outline-primary-faded",
1042
+ false: "",
1043
+ },
1044
+ },
1045
+ defaultVariants: {
1046
+ variant: "default",
1047
+ isDisabled: false,
1048
+ isSelected: false,
1049
+ },
1050
+ });
1051
+ const ChevronRightIcon = ({ className }) => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsxRuntime.jsx("path", { d: "M7.5 15L12.5 10L7.5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
1052
+ const ListItem = React__namespace.forwardRef(({ className, type = "single", leadingIcon, title, description, trailingIcon, showChevron = true, variant = "default", isDisabled = false, isSelected = false, onSelectionChange, checkboxSize = "small", containerClassName, contentClassName, onClick, ...props }, ref) => {
1053
+ const [internalSelected, setInternalSelected] = React__namespace.useState(isSelected);
1054
+ // Sync internal state with prop
1055
+ React__namespace.useEffect(() => {
1056
+ setInternalSelected(isSelected);
1057
+ }, [isSelected]);
1058
+ const handleClick = (e) => {
1059
+ if (isDisabled)
1060
+ return;
1061
+ if (type === "multiple") {
1062
+ const newSelected = !internalSelected;
1063
+ setInternalSelected(newSelected);
1064
+ onSelectionChange?.(newSelected);
1065
+ }
1066
+ onClick?.(e);
1067
+ };
1068
+ const handleCheckboxChange = (e) => {
1069
+ e.stopPropagation();
1070
+ if (isDisabled)
1071
+ return;
1072
+ const newSelected = e.target.checked;
1073
+ setInternalSelected(newSelected);
1074
+ onSelectionChange?.(newSelected);
1075
+ };
1076
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn(listItemVariants({
1077
+ variant,
1078
+ isDisabled,
1079
+ isSelected: type === "multiple" ? internalSelected : false,
1080
+ }), containerClassName), onClick: handleClick, role: type === "multiple" ? "checkbox" : "button", "aria-checked": type === "multiple" ? internalSelected : undefined, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, ...props, children: [type === "multiple" && (jsxRuntime.jsx(Checkbox, { checked: internalSelected, onChange: handleCheckboxChange, isDisabled: isDisabled, size: checkboxSize, className: "shrink-0 mt-0.5" })), leadingIcon && (jsxRuntime.jsx("div", { className: cn(`shrink-0 flex items-center justify-center mt-0.5`, variant === "primary"
1081
+ ? "text-action-ink-primary-normal"
1082
+ : variant === "negative"
1083
+ ? "text-action-ink-negative-normal"
1084
+ : "text-action-ink-neutral-subtle", isDisabled && "text-surface-ink-neutral-disabled"), children: leadingIcon })), jsxRuntime.jsxs("div", { className: cn("flex-1 min-w-0 flex flex-col justify-center", contentClassName), children: [jsxRuntime.jsx("div", { className: cn("text-body-medium-regular truncate", variant === "primary"
1085
+ ? "text-action-ink-primary-normal"
1086
+ : variant === "negative"
1087
+ ? "text-action-ink-negative-normal"
1088
+ : "text-action-ink-neutral-normal", isDisabled && "text-surface-ink-neutral-disabled"), children: title }), description && (jsxRuntime.jsx("div", { className: cn("text-body-small-regular text-surface-ink-neutral-muted mt-0.5 line-clamp-2", isDisabled && "text-surface-ink-neutral-disabled"), children: description }))] }), (trailingIcon || showChevron) && (jsxRuntime.jsx("div", { className: "shrink-0 self-center text-action-ink-neutral-subtle", children: trailingIcon || jsxRuntime.jsx(ChevronRightIcon, {}) }))] }));
1089
+ });
1090
+ ListItem.displayName = "ListItem";
1091
+
1092
+ const linkVariants = classVarianceAuthority.cva("inline-flex items-center gap-1 whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none decoration-1 underline-offset-4", {
1093
+ variants: {
1094
+ type: {
1095
+ anchor: "hover:underline",
1096
+ action: "no-underline cursor-pointer",
1097
+ },
1098
+ color: {
1099
+ primary: "",
1100
+ positive: "",
1101
+ negative: "",
1102
+ notice: "",
1103
+ info: "",
1104
+ neutral: "",
1105
+ },
1106
+ size: {
1107
+ xsmall: "text-body-xsmall-medium gap-1",
1108
+ small: "text-body-small-medium gap-1",
1109
+ medium: "text-body-medium-medium gap-1.5",
1110
+ large: "text-body-large-medium gap-1.5",
1111
+ },
1112
+ isIconOnly: {
1113
+ true: "no-underline",
1114
+ false: "",
1115
+ },
1116
+ isDisabled: {
1117
+ true: "cursor-not-allowed opacity-50",
1118
+ false: "cursor-pointer",
1119
+ },
1120
+ },
1121
+ compoundVariants: [
1122
+ // Primary color variants
1123
+ {
1124
+ color: "primary",
1125
+ class: `text-action-ink-primary-normal
1126
+ hover:text-action-ink-primary-subtle
1127
+ hover:decoration-action-outline-primary-hover
1128
+ disabled:text-action-ink-primary-disabled
1129
+ focus:text-action-ink-primary-hover
1130
+ `,
1131
+ },
1132
+ // Positive color variants
1133
+ {
1134
+ color: "positive",
1135
+ class: `text-action-ink-positive-normal
1136
+ hover:text-action-ink-positive-subtle
1137
+ hover:decoration-action-outline-positive-hover
1138
+ hover:text-action-ink-positive-hover
1139
+ disabled:text-action-ink-positive-disabled
1140
+ focus:text-action-ink-positive-hover
1141
+ `,
1142
+ },
1143
+ // Negative color variants
1144
+ {
1145
+ color: "negative",
1146
+ class: `text-action-ink-negative-normal
1147
+ hover:text-action-ink-negative-subtle
1148
+ hover:decoration-action-outline-negative-hover
1149
+ hover:text-action-ink-negative-hover
1150
+ disabled:text-action-ink-negative-disabled
1151
+ focus:text-action-ink-negative-hover
1152
+ `,
1153
+ },
1154
+ // Notice color variants
1155
+ {
1156
+ color: "notice",
1157
+ class: `text-action-ink-notice-normal
1158
+ hover:text-action-ink-notice-subtle
1159
+ hover:decoration-action-outline-notice-hover
1160
+ hover:text-action-ink-notice-hover
1161
+ disabled:text-action-ink-notice-disabled
1162
+ focus:text-action-ink-notice-hover
1163
+ `,
1164
+ },
1165
+ // Info color variants
1166
+ {
1167
+ color: "info",
1168
+ class: `text-action-ink-info-normal
1169
+ hover:text-action-ink-info-subtle
1170
+ hover:decoration-action-outline-info-hover
1171
+ hover:text-action-ink-info-hover
1172
+ disabled:text-action-ink-info-disabled
1173
+ focus:text-action-ink-info-hover
1174
+ `,
1175
+ },
1176
+ // Neutral color variants
1177
+ {
1178
+ color: "neutral",
1179
+ class: `text-action-ink-neutral-normal
1180
+ hover:text-action-ink-neutral-subtle
1181
+ hover:decoration-action-outline-neutral-hover
1182
+ hover:text-action-ink-neutral-hover
1183
+ disabled:text-action-ink-neutral-disabled
1184
+ focus:text-action-ink-neutral-hover
1185
+ `,
1186
+ },
1187
+ ],
1188
+ defaultVariants: {
1189
+ type: "anchor",
1190
+ color: "primary",
1191
+ size: "medium",
1192
+ isIconOnly: false,
1193
+ isDisabled: false,
1194
+ },
1195
+ });
1196
+ const Link = React__namespace.forwardRef(({ className, type = "anchor", color = "primary", size = "medium", isIconOnly = false, isDisabled = false, asChild = false, showIcon = false, icon, leadingIcon, trailingIcon, children, onClick, ...props }, ref) => {
1197
+ const Comp = asChild ? reactSlot.Slot : "a";
1198
+ const handleClick = (e) => {
1199
+ if (isDisabled) {
1200
+ e.preventDefault();
1201
+ return;
1202
+ }
1203
+ onClick?.(e);
1204
+ };
1205
+ // Icon size based on link size
1206
+ const iconSize = {
1207
+ xsmall: 12,
1208
+ small: 14,
1209
+ medium: 16,
1210
+ large: 18,
1211
+ }[size];
1212
+ // Determine what to show as trailing icon
1213
+ // Priority: trailingIcon > (showIcon && icon) > (showIcon && default ExternalLink)
1214
+ const finalTrailingIcon = trailingIcon || (showIcon && (icon || jsxRuntime.jsx(lucideReact.ExternalLink, { size: iconSize })));
1215
+ const linkContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [leadingIcon && !isIconOnly && (jsxRuntime.jsx("span", { className: "inline-flex items-center", children: leadingIcon })), !isIconOnly && children, isIconOnly && children, finalTrailingIcon && !isIconOnly && (jsxRuntime.jsx("span", { className: "inline-flex items-center", children: finalTrailingIcon })), isIconOnly &&
1216
+ (leadingIcon || finalTrailingIcon || (jsxRuntime.jsx(lucideReact.ExternalLink, { size: iconSize })))] }));
1217
+ return (jsxRuntime.jsx(Comp, { className: cn(linkVariants({
1218
+ type,
1219
+ color,
1220
+ size,
1221
+ isIconOnly,
1222
+ isDisabled,
1223
+ }), className), ref: ref, onClick: handleClick, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : undefined, ...props, children: linkContent }));
1224
+ });
1225
+ Link.displayName = "Link";
1226
+
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) => {
1228
+ const renderContent = () => {
1229
+ if (isLoading) {
1230
+ 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" }) }));
1231
+ }
1232
+ if (isEmpty || items.length === 0) {
1233
+ return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-8 px-6 text-center", children: [emptyIcon || (jsxRuntime.jsx(lucideReact.Search, { className: "w-12 h-12 text-surface-ink-neutral-muted mb-4" })), jsxRuntime.jsx(Text, { as: "h3", variant: "body", size: "small", weight: "semibold", className: "text-surface-ink-neutral-normal mb-2", children: emptyTitle }), jsxRuntime.jsx(Text, { as: "p", variant: "body", size: "small", weight: "regular", className: "text-surface-ink-neutral-muted mb-3", children: emptyDescription }), emptyLinkText && (jsxRuntime.jsx(Link, { type: "anchor", color: "primary", size: "small", onClick: onEmptyLinkClick, children: emptyLinkText }))] }));
1234
+ }
1235
+ return (jsxRuntime.jsxs("div", { className: "py-3 px-3 max-h-[400px] overflow-y-auto", children: [sectionHeading && (jsxRuntime.jsx(Text, { as: "div", variant: "body", size: "small", weight: "medium", className: "text-surface-ink-neutral-muted px-3 py-2 mb-1", children: sectionHeading })), jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children: items.map((item, index) => (jsxRuntime.jsx(ListItem, { title: item.title, description: item.description, leadingIcon: item.leadingIcon, trailingIcon: item.trailingIcon, showChevron: showChevron, isDisabled: item.isDisabled, isSelected: index === focusedIndex, onClick: () => {
1236
+ item.onClick?.();
1237
+ onClose?.();
1238
+ }, containerClassName: cn(index === focusedIndex && "bg-action-fill-primary-faded") }, item.id))) })] }));
1239
+ };
1240
+ const widthClass = width === "full" ? "w-full" : width === "auto" ? "w-auto" : "";
1241
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn("bg-surface-fill-primary-normal rounded-large overflow-hidden", widthClass, className), style: {
1242
+ boxShadow: "0 1px 2px rgba(25, 25, 30, 0.1), 0 2px 6px rgba(25, 25, 30, 0.06)",
1243
+ ...(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 items-center gap-3 p-4", 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
+ });
1246
+ DropdownMenu.displayName = "DropdownMenu";
1247
+
1248
+ const dropdownVariants = classVarianceAuthority.cva("bg-surface-fill-primary-normal border border-surface-outline-neutral-subtle rounded-large", {
1249
+ variants: {
1250
+ size: {
1251
+ small: "w-64",
1252
+ medium: "w-80",
1253
+ large: "w-96",
1254
+ },
1255
+ },
1256
+ defaultVariants: {
1257
+ size: "medium",
1258
+ },
1259
+ });
1260
+ const Dropdown = React__namespace.forwardRef(({ className, trigger, 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, size = "medium", open: controlledOpen, defaultOpen = false, onOpenChange, containerClassName, menuClassName, showChevron = false, emptyIcon, disableFooter = false, ...props }, ref) => {
1261
+ const [uncontrolledOpen, setUncontrolledOpen] = React__namespace.useState(defaultOpen);
1262
+ const isOpen = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen;
1263
+ const dropdownRef = React__namespace.useRef(null);
1264
+ const handleOpenChange = (newOpen) => {
1265
+ if (controlledOpen === undefined) {
1266
+ setUncontrolledOpen(newOpen);
1267
+ }
1268
+ onOpenChange?.(newOpen);
1269
+ };
1270
+ const toggleOpen = () => {
1271
+ handleOpenChange(!isOpen);
1272
+ };
1273
+ // Close dropdown when clicking outside
1274
+ React__namespace.useEffect(() => {
1275
+ const handleClickOutside = (event) => {
1276
+ if (dropdownRef.current &&
1277
+ !dropdownRef.current.contains(event.target)) {
1278
+ handleOpenChange(false);
1279
+ }
1280
+ };
1281
+ if (isOpen) {
1282
+ document.addEventListener("mousedown", handleClickOutside);
1283
+ return () => {
1284
+ document.removeEventListener("mousedown", handleClickOutside);
1285
+ };
1286
+ }
1287
+ }, [isOpen]);
1288
+ // Close on escape key
1289
+ React__namespace.useEffect(() => {
1290
+ const handleEscape = (event) => {
1291
+ if (event.key === "Escape") {
1292
+ handleOpenChange(false);
1293
+ }
1294
+ };
1295
+ if (isOpen) {
1296
+ document.addEventListener("keydown", handleEscape);
1297
+ return () => {
1298
+ document.removeEventListener("keydown", handleEscape);
1299
+ };
1300
+ }
1301
+ }, [isOpen]);
1302
+ const sizeMap = {
1303
+ small: "w-64",
1304
+ medium: "w-80",
1305
+ large: "w-96",
1306
+ };
1307
+ return (jsxRuntime.jsxs("div", { ref: dropdownRef, className: cn("relative inline-block", containerClassName), ...props, children: [trigger && (jsxRuntime.jsx("div", { onClick: toggleOpen, className: "cursor-pointer", children: trigger })), isOpen && (jsxRuntime.jsx(DropdownMenu, { ref: ref, items: items, sectionHeading: sectionHeading, isLoading: isLoading, isEmpty: isEmpty, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyLinkText: emptyLinkText, onEmptyLinkClick: onEmptyLinkClick, primaryButtonText: primaryButtonText, secondaryButtonText: secondaryButtonText, onPrimaryClick: onPrimaryClick, onSecondaryClick: onSecondaryClick, showChevron: showChevron, emptyIcon: emptyIcon, disableFooter: disableFooter, onClose: () => handleOpenChange(false), className: cn("absolute z-50 mt-2", menuClassName, className), width: sizeMap[size] }))] }));
1308
+ });
1309
+ Dropdown.displayName = "Dropdown";
1310
+
1014
1311
  const tooltipVariants = classVarianceAuthority.cva("fixed z-50 bg-popup-fill-intense text-action-ink-on-primary-normal rounded-medium border border-popup-outline-subtle flex flex-col p-4 rounded-xlarge min-w-[200px] max-w-[300px] transition-opacity duration-200", {
1015
1312
  variants: {
1016
1313
  isVisible: {
@@ -1260,218 +1557,10 @@ const FormHeader = React__namespace.forwardRef(({ label, size = "medium", isOpti
1260
1557
  gap: "gap-2.5",
1261
1558
  },
1262
1559
  };
1263
- const config = sizeConfig[size];
1264
- 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", className: "text-feedback-ink-negative-subtle ml-0.5", children: "*" })), isOptional && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", className: "text-surface-ink-neutral-muted 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 cursor-help", 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 }))] }));
1265
- });
1266
- FormHeader.displayName = "FormHeader";
1267
-
1268
- const linkVariants = classVarianceAuthority.cva("inline-flex items-center gap-1 whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none underline decoration-1 underline-offset-4", {
1269
- variants: {
1270
- type: {
1271
- anchor: "",
1272
- action: "cursor-pointer",
1273
- },
1274
- color: {
1275
- primary: "",
1276
- positive: "",
1277
- negative: "",
1278
- notice: "",
1279
- info: "",
1280
- neutral: "",
1281
- },
1282
- size: {
1283
- xsmall: "text-body-xsmall-medium gap-1",
1284
- small: "text-body-small-medium gap-1",
1285
- medium: "text-body-medium-medium gap-1.5",
1286
- large: "text-body-large-medium gap-1.5",
1287
- },
1288
- isIconOnly: {
1289
- true: "no-underline",
1290
- false: "",
1291
- },
1292
- isDisabled: {
1293
- true: "cursor-not-allowed opacity-50",
1294
- false: "cursor-pointer",
1295
- },
1296
- },
1297
- compoundVariants: [
1298
- // Primary color variants
1299
- {
1300
- color: "primary",
1301
- class: `text-action-ink-primary-normal
1302
- hover:text-action-ink-primary-hover
1303
- disabled:text-action-ink-primary-disabled
1304
- active:text-action-ink-primary-activated
1305
- focus:text-action-ink-primary-hover
1306
- `,
1307
- },
1308
- // Positive color variants
1309
- {
1310
- color: "positive",
1311
- class: `text-action-ink-positive-normal
1312
- hover:text-action-ink-positive-hover
1313
- disabled:text-action-ink-positive-disabled
1314
- active:text-action-ink-positive-activated
1315
- focus:text-action-ink-positive-hover
1316
- `,
1317
- },
1318
- // Negative color variants
1319
- {
1320
- color: "negative",
1321
- class: `text-action-ink-negative-normal
1322
- hover:text-action-ink-negative-hover
1323
- disabled:text-action-ink-negative-disabled
1324
- active:text-action-ink-negative-activated
1325
- focus:text-action-ink-negative-hover
1326
- `,
1327
- },
1328
- // Notice color variants
1329
- {
1330
- color: "notice",
1331
- class: `text-action-ink-notice-normal
1332
- hover:text-action-ink-notice-hover
1333
- disabled:text-action-ink-notice-disabled
1334
- active:text-action-ink-notice-activated
1335
- focus:text-action-ink-notice-hover
1336
- `,
1337
- },
1338
- // Info color variants
1339
- {
1340
- color: "info",
1341
- class: `text-action-ink-info-normal
1342
- hover:text-action-ink-info-hover
1343
- disabled:text-action-ink-info-disabled
1344
- active:text-action-ink-info-activated
1345
- focus:text-action-ink-info-hover
1346
- `,
1347
- },
1348
- // Neutral color variants
1349
- {
1350
- color: "neutral",
1351
- class: `text-action-ink-neutral-normal
1352
- hover:text-action-ink-neutral-hover
1353
- disabled:text-action-ink-neutral-disabled
1354
- active:text-action-ink-neutral-activated
1355
- focus:text-action-ink-neutral-hover
1356
- `,
1357
- },
1358
- ],
1359
- defaultVariants: {
1360
- type: "anchor",
1361
- color: "primary",
1362
- size: "medium",
1363
- isIconOnly: false,
1364
- isDisabled: false,
1365
- },
1366
- });
1367
- const Link = React__namespace.forwardRef(({ className, type = "anchor", color = "primary", size = "medium", isIconOnly = false, isDisabled = false, asChild = false, showIcon = false, icon, leadingIcon, trailingIcon, children, onClick, ...props }, ref) => {
1368
- const Comp = asChild ? reactSlot.Slot : "a";
1369
- const handleClick = (e) => {
1370
- if (isDisabled) {
1371
- e.preventDefault();
1372
- return;
1373
- }
1374
- onClick?.(e);
1375
- };
1376
- // Icon size based on link size
1377
- const iconSize = {
1378
- xsmall: 12,
1379
- small: 14,
1380
- medium: 16,
1381
- large: 18,
1382
- }[size];
1383
- // Determine what to show as trailing icon
1384
- // Priority: trailingIcon > (showIcon && icon) > (showIcon && default ExternalLink)
1385
- const finalTrailingIcon = trailingIcon || (showIcon && (icon || jsxRuntime.jsx(lucideReact.ExternalLink, { size: iconSize })));
1386
- const linkContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [leadingIcon && !isIconOnly && (jsxRuntime.jsx("span", { className: "inline-flex items-center", children: leadingIcon })), !isIconOnly && children, isIconOnly && children, finalTrailingIcon && !isIconOnly && (jsxRuntime.jsx("span", { className: "inline-flex items-center", children: finalTrailingIcon })), isIconOnly &&
1387
- (leadingIcon || finalTrailingIcon || (jsxRuntime.jsx(lucideReact.ExternalLink, { size: iconSize })))] }));
1388
- return (jsxRuntime.jsx(Comp, { className: cn(linkVariants({
1389
- type,
1390
- color,
1391
- size,
1392
- isIconOnly,
1393
- isDisabled,
1394
- }), className), ref: ref, onClick: handleClick, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : undefined, ...props, children: linkContent }));
1395
- });
1396
- Link.displayName = "Link";
1397
-
1398
- const listItemVariants = classVarianceAuthority.cva("flex items-start gap-3 p-3 rounded-medium transition-colors cursor-pointer", {
1399
- variants: {
1400
- variant: {
1401
- default: `hover:bg-action-fill-neutral-faded
1402
- focus:bg-action-fill-neutral-faded
1403
- focus:ring-2
1404
- ring-action-outline-primary-faded-hover
1405
- border border-transparent
1406
- `,
1407
- bordered: "border border-action-outline-primary-faded hover:bg-surface-fill-primary-subtle",
1408
- primary: `hover:bg-action-fill-neutral-faded
1409
- focus:bg-action-fill-neutral-faded
1410
- focus:ring-2
1411
- ring-action-outline-primary-faded-hover
1412
- border border-transparent
1413
- `,
1414
- negative: `hover:bg-action-fill-negative-faded
1415
- focus:bg-action-fill-negative-faded
1416
- focus:ring-2 ring-action-outline-negative-faded-hover
1417
- border border-transparent
1418
- `,
1419
- },
1420
- isDisabled: {
1421
- true: "cursor-not-allowed opacity-60",
1422
- false: "",
1423
- },
1424
- isSelected: {
1425
- true: "bg-action-fill-primary-faded border-action-outline-primary-faded",
1426
- false: "",
1427
- },
1428
- },
1429
- defaultVariants: {
1430
- variant: "default",
1431
- isDisabled: false,
1432
- isSelected: false,
1433
- },
1434
- });
1435
- const ChevronRightIcon = ({ className }) => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsxRuntime.jsx("path", { d: "M7.5 15L12.5 10L7.5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
1436
- const ListItem = React__namespace.forwardRef(({ className, type = "single", leadingIcon, title, description, trailingIcon, showChevron = true, variant = "default", isDisabled = false, isSelected = false, onSelectionChange, checkboxSize = "small", containerClassName, contentClassName, onClick, ...props }, ref) => {
1437
- const [internalSelected, setInternalSelected] = React__namespace.useState(isSelected);
1438
- // Sync internal state with prop
1439
- React__namespace.useEffect(() => {
1440
- setInternalSelected(isSelected);
1441
- }, [isSelected]);
1442
- const handleClick = (e) => {
1443
- if (isDisabled)
1444
- return;
1445
- if (type === "multiple") {
1446
- const newSelected = !internalSelected;
1447
- setInternalSelected(newSelected);
1448
- onSelectionChange?.(newSelected);
1449
- }
1450
- onClick?.(e);
1451
- };
1452
- const handleCheckboxChange = (e) => {
1453
- e.stopPropagation();
1454
- if (isDisabled)
1455
- return;
1456
- const newSelected = e.target.checked;
1457
- setInternalSelected(newSelected);
1458
- onSelectionChange?.(newSelected);
1459
- };
1460
- return (jsxRuntime.jsxs("div", { ref: ref, className: cn(listItemVariants({
1461
- variant,
1462
- isDisabled,
1463
- isSelected: type === "multiple" ? internalSelected : false,
1464
- }), containerClassName), onClick: handleClick, role: type === "multiple" ? "checkbox" : "button", "aria-checked": type === "multiple" ? internalSelected : undefined, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, ...props, children: [type === "multiple" && (jsxRuntime.jsx(Checkbox, { checked: internalSelected, onChange: handleCheckboxChange, isDisabled: isDisabled, size: checkboxSize, className: "shrink-0 mt-0.5" })), leadingIcon && (jsxRuntime.jsx("div", { className: cn(`shrink-0 flex items-center justify-center mt-0.5`, variant === "primary"
1465
- ? "text-action-ink-primary-normal"
1466
- : variant === "negative"
1467
- ? "text-action-ink-negative-normal"
1468
- : "text-action-ink-neutral-subtle", isDisabled && "text-surface-ink-neutral-disabled"), children: leadingIcon })), jsxRuntime.jsxs("div", { className: cn("flex-1 min-w-0 flex flex-col justify-center", contentClassName), children: [jsxRuntime.jsx("div", { className: cn("text-body-medium-regular truncate", variant === "primary"
1469
- ? "text-action-ink-primary-normal"
1470
- : variant === "negative"
1471
- ? "text-action-ink-negative-normal"
1472
- : "text-action-ink-neutral-normal", isDisabled && "text-surface-ink-neutral-disabled"), children: title }), description && (jsxRuntime.jsx("div", { className: cn("text-body-small-regular text-surface-ink-neutral-muted mt-0.5 line-clamp-2", isDisabled && "text-surface-ink-neutral-disabled"), children: description }))] }), (trailingIcon || showChevron) && (jsxRuntime.jsx("div", { className: "shrink-0 self-center text-action-ink-neutral-subtle", children: trailingIcon || jsxRuntime.jsx(ChevronRightIcon, {}) }))] }));
1560
+ 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", className: "text-feedback-ink-negative-subtle ml-0.5", children: "*" })), isOptional && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", className: "text-surface-ink-neutral-muted 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 cursor-help", 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 }))] }));
1473
1562
  });
1474
- ListItem.displayName = "ListItem";
1563
+ FormHeader.displayName = "FormHeader";
1475
1564
 
1476
1565
  const radioVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 border transition-all cursor-pointer rounded-full", {
1477
1566
  variants: {
@@ -1638,6 +1727,214 @@ const Radio = React__namespace.forwardRef(({ label, errorText, size = "medium",
1638
1727
  });
1639
1728
  Radio.displayName = "Radio";
1640
1729
 
1730
+ const textFieldVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-medium transition-all font-display font-size-100 leading-100", {
1731
+ variants: {
1732
+ size: {
1733
+ small: "h-[28px] px-3 text-xs gap-2",
1734
+ medium: "h-[36px] px-4 text-sm gap-2",
1735
+ large: "h-[44px] px-5 text-base gap-3",
1736
+ },
1737
+ validationState: {
1738
+ none: `
1739
+ border-action-outline-neutral-faded
1740
+ hover:border-action-outline-primary-hover
1741
+ focus-within:border-action-outline-primary-hover
1742
+ focus-within:ring-2
1743
+ ring-action-outline-primary-faded-hover`,
1744
+ positive: `
1745
+ border-action-outline-positive-default
1746
+ focus-within:border-action-outline-positive-hover
1747
+ focus-within:ring-2
1748
+ ring-action-outline-positive-faded-hover`,
1749
+ negative: `border-action-outline-negative-default
1750
+ focus-within:border-action-outline-negative-hover
1751
+ focus-within:ring-2
1752
+ ring-action-outline-negative-faded-hover`,
1753
+ },
1754
+ isDisabled: {
1755
+ true: `
1756
+ border-[var(--border-width-thinner)]
1757
+ hover:border-action-outline-neutral-disabled
1758
+ border-action-outline-neutral-disabled
1759
+ bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
1760
+ false: "bg-surface-fill-neutral-intense",
1761
+ },
1762
+ },
1763
+ defaultVariants: {
1764
+ size: "medium",
1765
+ validationState: "none",
1766
+ isDisabled: false,
1767
+ },
1768
+ });
1769
+ const TextField = React__namespace.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isRequired = false, isOptional = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, linkText, linkHref, onLinkClick, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
1770
+ const [internalValue, setInternalValue] = React__namespace.useState("");
1771
+ const inputValue = value !== undefined ? value : internalValue;
1772
+ const hasValue = inputValue && String(inputValue).length > 0;
1773
+ const handleChange = (e) => {
1774
+ if (onChange) {
1775
+ onChange(e);
1776
+ }
1777
+ else {
1778
+ setInternalValue(e.target.value);
1779
+ }
1780
+ };
1781
+ const handleClear = () => {
1782
+ if (onClear) {
1783
+ onClear();
1784
+ }
1785
+ else {
1786
+ setInternalValue("");
1787
+ }
1788
+ // Focus the input after clearing
1789
+ const input = document.getElementById(props.id || "");
1790
+ if (input) {
1791
+ input.focus();
1792
+ }
1793
+ };
1794
+ // Determine which helper text to show
1795
+ const displayHelperText = errorText || successText || helperText;
1796
+ const currentValidationState = errorText
1797
+ ? "negative"
1798
+ : successText
1799
+ ? "positive"
1800
+ : validationState;
1801
+ const sizeConfig = {
1802
+ small: {
1803
+ gap: "gap-2",
1804
+ },
1805
+ medium: {
1806
+ gap: "gap-2",
1807
+ },
1808
+ large: {
1809
+ gap: "gap-3",
1810
+ },
1811
+ };
1812
+ 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", { className: cn(textFieldVariants({
1813
+ size,
1814
+ validationState: currentValidationState,
1815
+ isDisabled,
1816
+ }), className), children: [prefix && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
1817
+ ? "text-surface-ink-neutral-disabled"
1818
+ : currentValidationState === "positive"
1819
+ ? "text-feedback-ink-positive-intense"
1820
+ : currentValidationState === "negative"
1821
+ ? "text-feedback-ink-negative-subtle"
1822
+ : "text-surface-ink-neutral-muted"), children: prefix })), jsxRuntime.jsx("input", { ref: ref, value: inputValue, onChange: handleChange, disabled: isDisabled, required: isRequired, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled font-display", inputClassName), ...props }), showClearButton && hasValue && !isDisabled && (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 && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
1823
+ ? "text-surface-ink-neutral-disabled"
1824
+ : currentValidationState === "positive"
1825
+ ? "text-feedback-ink-positive-intense"
1826
+ : currentValidationState === "negative"
1827
+ ? "text-feedback-ink-negative-subtle"
1828
+ : "text-surface-ink-neutral-muted"), children: suffix }))] }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
1829
+ ? "default"
1830
+ : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
1831
+ });
1832
+ TextField.displayName = "TextField";
1833
+
1834
+ const defaultFilter = (item, query) => {
1835
+ const searchQuery = query.toLowerCase();
1836
+ return (item.title.toLowerCase().includes(searchQuery) ||
1837
+ (item.description?.toLowerCase().includes(searchQuery) ?? false));
1838
+ };
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) => {
1840
+ const [uncontrolledSearchValue, setUncontrolledSearchValue] = React__namespace.useState(defaultSearchValue);
1841
+ const [isOpen, setIsOpen] = React__namespace.useState(false);
1842
+ const [focusedIndex, setFocusedIndex] = React__namespace.useState(-1);
1843
+ const dropdownRef = React__namespace.useRef(null);
1844
+ const inputRef = React__namespace.useRef(null);
1845
+ React__namespace.useImperativeHandle(ref, () => inputRef.current);
1846
+ const searchValue = controlledSearchValue !== undefined
1847
+ ? controlledSearchValue
1848
+ : uncontrolledSearchValue;
1849
+ const handleSearchChange = (e) => {
1850
+ const newValue = e.target.value;
1851
+ if (controlledSearchValue === undefined) {
1852
+ setUncontrolledSearchValue(newValue);
1853
+ }
1854
+ onSearchChange?.(newValue);
1855
+ // Show dropdown if minimum search length is met
1856
+ if (newValue.length >= minSearchLength) {
1857
+ setIsOpen(true);
1858
+ }
1859
+ else {
1860
+ setIsOpen(false);
1861
+ }
1862
+ };
1863
+ const handleFocus = () => {
1864
+ if (showOnFocus && searchValue.length >= minSearchLength) {
1865
+ setIsOpen(true);
1866
+ }
1867
+ };
1868
+ const handleItemSelect = (item) => {
1869
+ onItemSelect?.(item);
1870
+ if (controlledSearchValue === undefined) {
1871
+ setUncontrolledSearchValue(item.value || item.title);
1872
+ }
1873
+ setIsOpen(false);
1874
+ inputRef.current?.focus();
1875
+ };
1876
+ // Filter items based on search
1877
+ const filteredItems = React__namespace.useMemo(() => {
1878
+ if (!searchValue)
1879
+ return items;
1880
+ return items.filter((item) => filterFunction(item, searchValue));
1881
+ }, [items, searchValue, filterFunction]);
1882
+ // Close dropdown when clicking outside
1883
+ React__namespace.useEffect(() => {
1884
+ const handleClickOutside = (event) => {
1885
+ if (dropdownRef.current &&
1886
+ !dropdownRef.current.contains(event.target)) {
1887
+ setIsOpen(false);
1888
+ }
1889
+ };
1890
+ if (isOpen) {
1891
+ document.addEventListener("mousedown", handleClickOutside);
1892
+ return () => {
1893
+ document.removeEventListener("mousedown", handleClickOutside);
1894
+ };
1895
+ }
1896
+ }, [isOpen]);
1897
+ // Handle keyboard navigation
1898
+ const handleKeyDown = (e) => {
1899
+ if (!isOpen) {
1900
+ if (e.key === "ArrowDown" || e.key === "Enter") {
1901
+ setIsOpen(true);
1902
+ e.preventDefault();
1903
+ }
1904
+ return;
1905
+ }
1906
+ switch (e.key) {
1907
+ case "ArrowDown":
1908
+ e.preventDefault();
1909
+ setFocusedIndex((prev) => prev < filteredItems.length - 1 ? prev + 1 : prev);
1910
+ break;
1911
+ case "ArrowUp":
1912
+ e.preventDefault();
1913
+ setFocusedIndex((prev) => (prev > 0 ? prev - 1 : -1));
1914
+ break;
1915
+ case "Enter":
1916
+ e.preventDefault();
1917
+ if (focusedIndex >= 0 && filteredItems[focusedIndex]) {
1918
+ handleItemSelect(filteredItems[focusedIndex]);
1919
+ }
1920
+ break;
1921
+ case "Escape":
1922
+ e.preventDefault();
1923
+ setIsOpen(false);
1924
+ setFocusedIndex(-1);
1925
+ break;
1926
+ }
1927
+ };
1928
+ // Update items with onClick handlers that call handleItemSelect
1929
+ const itemsWithHandlers = filteredItems.map((item) => ({
1930
+ ...item,
1931
+ onClick: () => handleItemSelect(item),
1932
+ }));
1933
+ const showDropdown = isOpen && searchValue.length >= minSearchLength;
1934
+ return (jsxRuntime.jsxs("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 }), showDropdown && (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, onClose: () => setIsOpen(false), focusedIndex: focusedIndex, className: cn("absolute z-50 mt-2", dropdownClassName), width: dropdownWidth === "full" ? "full" : "auto" }))] }));
1935
+ });
1936
+ SearchableDropdown.displayName = "SearchableDropdown";
1937
+
1641
1938
  const switchVariants = classVarianceAuthority.cva("relative inline-flex items-center shrink-0 cursor-pointer rounded-full transition-all duration-200", {
1642
1939
  variants: {
1643
1940
  size: {
@@ -1980,121 +2277,20 @@ const TextArea = React__namespace.forwardRef(({ label, helperText, errorText, su
1980
2277
  });
1981
2278
  TextArea.displayName = "TextArea";
1982
2279
 
1983
- const textFieldVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-medium transition-all font-display font-size-100 leading-100", {
1984
- variants: {
1985
- size: {
1986
- small: "h-[28px] px-3 text-xs gap-2",
1987
- medium: "h-[36px] px-4 text-sm gap-2",
1988
- large: "h-[44px] px-5 text-base gap-3",
1989
- },
1990
- validationState: {
1991
- none: `
1992
- border-action-outline-neutral-faded
1993
- hover:border-action-outline-primary-hover
1994
- focus-within:border-action-outline-primary-hover
1995
- focus-within:ring-2
1996
- ring-action-outline-primary-faded-hover`,
1997
- positive: `
1998
- border-action-outline-positive-default
1999
- focus-within:border-action-outline-positive-hover
2000
- focus-within:ring-2
2001
- ring-action-outline-positive-faded-hover`,
2002
- negative: `border-action-outline-negative-default
2003
- focus-within:border-action-outline-negative-hover
2004
- focus-within:ring-2
2005
- ring-action-outline-negative-faded-hover`,
2006
- },
2007
- isDisabled: {
2008
- true: `
2009
- border-[var(--border-width-thinner)]
2010
- hover:border-action-outline-neutral-disabled
2011
- border-action-outline-neutral-disabled
2012
- bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
2013
- false: "bg-surface-fill-neutral-intense",
2014
- },
2015
- },
2016
- defaultVariants: {
2017
- size: "medium",
2018
- validationState: "none",
2019
- isDisabled: false,
2020
- },
2021
- });
2022
- const TextField = React__namespace.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isRequired = false, isOptional = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, linkText, linkHref, onLinkClick, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
2023
- const [internalValue, setInternalValue] = React__namespace.useState("");
2024
- const inputValue = value !== undefined ? value : internalValue;
2025
- const hasValue = inputValue && String(inputValue).length > 0;
2026
- const handleChange = (e) => {
2027
- if (onChange) {
2028
- onChange(e);
2029
- }
2030
- else {
2031
- setInternalValue(e.target.value);
2032
- }
2033
- };
2034
- const handleClear = () => {
2035
- if (onClear) {
2036
- onClear();
2037
- }
2038
- else {
2039
- setInternalValue("");
2040
- }
2041
- // Focus the input after clearing
2042
- const input = document.getElementById(props.id || "");
2043
- if (input) {
2044
- input.focus();
2045
- }
2046
- };
2047
- // Determine which helper text to show
2048
- const displayHelperText = errorText || successText || helperText;
2049
- const currentValidationState = errorText
2050
- ? "negative"
2051
- : successText
2052
- ? "positive"
2053
- : validationState;
2054
- const sizeConfig = {
2055
- small: {
2056
- gap: "gap-2",
2057
- },
2058
- medium: {
2059
- gap: "gap-2",
2060
- },
2061
- large: {
2062
- gap: "gap-3",
2063
- },
2064
- };
2065
- 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", { className: cn(textFieldVariants({
2066
- size,
2067
- validationState: currentValidationState,
2068
- isDisabled,
2069
- }), className), children: [prefix && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2070
- ? "text-surface-ink-neutral-disabled"
2071
- : currentValidationState === "positive"
2072
- ? "text-feedback-ink-positive-intense"
2073
- : currentValidationState === "negative"
2074
- ? "text-feedback-ink-negative-subtle"
2075
- : "text-surface-ink-neutral-muted"), children: prefix })), jsxRuntime.jsx("input", { ref: ref, value: inputValue, onChange: handleChange, disabled: isDisabled, required: isRequired, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled font-display", inputClassName), ...props }), showClearButton && hasValue && !isDisabled && (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 && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2076
- ? "text-surface-ink-neutral-disabled"
2077
- : currentValidationState === "positive"
2078
- ? "text-feedback-ink-positive-intense"
2079
- : currentValidationState === "negative"
2080
- ? "text-feedback-ink-negative-subtle"
2081
- : "text-surface-ink-neutral-muted"), children: suffix }))] }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
2082
- ? "default"
2083
- : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
2084
- });
2085
- TextField.displayName = "TextField";
2086
-
2087
2280
  exports.Badge = Badge;
2088
2281
  exports.Button = Button;
2089
2282
  exports.Checkbox = Checkbox;
2090
2283
  exports.Counter = Counter;
2091
2284
  exports.Divider = Divider;
2285
+ exports.Dropdown = Dropdown;
2286
+ exports.DropdownMenu = DropdownMenu;
2092
2287
  exports.FormFooter = FormFooter;
2093
2288
  exports.FormHeader = FormHeader;
2094
2289
  exports.Icon = Icon;
2095
2290
  exports.Link = Link;
2096
2291
  exports.ListItem = ListItem;
2097
2292
  exports.Radio = Radio;
2293
+ exports.SearchableDropdown = SearchableDropdown;
2098
2294
  exports.Switch = Switch;
2099
2295
  exports.TabItem = TabItem;
2100
2296
  exports.Tabs = Tabs;
@@ -2107,6 +2303,7 @@ exports.buttonVariants = buttonVariants;
2107
2303
  exports.checkboxVariants = checkboxVariants;
2108
2304
  exports.cn = cn;
2109
2305
  exports.counterVariants = counterVariants;
2306
+ exports.dropdownVariants = dropdownVariants;
2110
2307
  exports.getAvailableIcons = getAvailableIcons;
2111
2308
  exports.hasIcon = hasIcon;
2112
2309
  exports.iconRegistry = iconRegistry;