infinity-ui-elements 1.8.30 → 1.8.33
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/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.stories.d.ts +1 -0
- package/dist/components/DatePicker/DatePicker.stories.d.ts.map +1 -1
- package/dist/components/Radio/RadioGroup.d.ts.map +1 -1
- package/dist/components/Radio/RadioGroup.stories.d.ts +7 -0
- package/dist/components/Radio/RadioGroup.stories.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +185 -24
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +185 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,9 +8,9 @@ var reactSpinners = require('react-spinners');
|
|
|
8
8
|
var clsx = require('clsx');
|
|
9
9
|
var tailwindMerge = require('tailwind-merge');
|
|
10
10
|
var lucideReact = require('lucide-react');
|
|
11
|
+
var reactDom = require('react-dom');
|
|
11
12
|
var Calendar = require('react-calendar');
|
|
12
13
|
require('react-calendar/dist/Calendar.css');
|
|
13
|
-
var reactDom = require('react-dom');
|
|
14
14
|
var reactTable = require('@tanstack/react-table');
|
|
15
15
|
|
|
16
16
|
function _interopNamespaceDefault(e) {
|
|
@@ -2098,16 +2098,64 @@ const formatDateDefault = (date) => {
|
|
|
2098
2098
|
day: "numeric",
|
|
2099
2099
|
});
|
|
2100
2100
|
};
|
|
2101
|
-
|
|
2101
|
+
// Helper function to format date based on format string
|
|
2102
|
+
const formatDateByPattern = (date, format) => {
|
|
2103
|
+
const day = date.getDate();
|
|
2104
|
+
const month = date.getMonth() + 1; // getMonth() returns 0-11
|
|
2105
|
+
const year = date.getFullYear();
|
|
2106
|
+
const monthNames = [
|
|
2107
|
+
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
2108
|
+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
2109
|
+
];
|
|
2110
|
+
const monthNamesFull = [
|
|
2111
|
+
"January", "February", "March", "April", "May", "June",
|
|
2112
|
+
"July", "August", "September", "October", "November", "December"
|
|
2113
|
+
];
|
|
2114
|
+
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2115
|
+
const dayNamesFull = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
2116
|
+
// Pad numbers with leading zeros
|
|
2117
|
+
const pad = (n, length = 2) => {
|
|
2118
|
+
return n.toString().padStart(length, "0");
|
|
2119
|
+
};
|
|
2120
|
+
let formatted = format;
|
|
2121
|
+
// Replace format patterns
|
|
2122
|
+
formatted = formatted.replace(/YYYY/g, year.toString());
|
|
2123
|
+
formatted = formatted.replace(/YY/g, year.toString().slice(-2));
|
|
2124
|
+
formatted = formatted.replace(/MMMM/g, monthNamesFull[month - 1]);
|
|
2125
|
+
formatted = formatted.replace(/MMM/g, monthNames[month - 1]);
|
|
2126
|
+
formatted = formatted.replace(/MM/g, pad(month));
|
|
2127
|
+
formatted = formatted.replace(/M/g, month.toString());
|
|
2128
|
+
formatted = formatted.replace(/DDDD/g, dayNamesFull[date.getDay()]);
|
|
2129
|
+
formatted = formatted.replace(/DDD/g, dayNames[date.getDay()]);
|
|
2130
|
+
formatted = formatted.replace(/DD/g, pad(day));
|
|
2131
|
+
formatted = formatted.replace(/D/g, day.toString());
|
|
2132
|
+
return formatted;
|
|
2133
|
+
};
|
|
2134
|
+
const DatePicker = React__namespace.forwardRef(({ className, value: controlledValue, defaultValue, onChange, placeholder = "Select a date", label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, size = "medium", showClearButton = true, onClear, containerClassName, labelClassName, triggerClassName, calendarClassName, minDate, maxDate, formatDate = formatDateDefault, format, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
|
|
2102
2135
|
const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(parseDate(defaultValue));
|
|
2103
2136
|
const [isOpen, setIsOpen] = React__namespace.useState(false);
|
|
2104
2137
|
const datePickerRef = React__namespace.useRef(null);
|
|
2105
2138
|
const calendarRef = React__namespace.useRef(null);
|
|
2106
2139
|
const [dropdownPlacement, setDropdownPlacement] = React__namespace.useState("bottom");
|
|
2140
|
+
const [isInsideModal, setIsInsideModal] = React__namespace.useState(false);
|
|
2141
|
+
const [position, setPosition] = React__namespace.useState({
|
|
2142
|
+
top: 0,
|
|
2143
|
+
left: 0,
|
|
2144
|
+
width: 0,
|
|
2145
|
+
bottom: 0,
|
|
2146
|
+
});
|
|
2147
|
+
const [calendarHeight, setCalendarHeight] = React__namespace.useState(300); // Default height estimate
|
|
2107
2148
|
const value = controlledValue !== undefined
|
|
2108
2149
|
? parseDate(controlledValue)
|
|
2109
2150
|
: uncontrolledValue;
|
|
2110
2151
|
const hasValue = value !== null;
|
|
2152
|
+
// Create a formatter function that uses format prop if provided, otherwise formatDate
|
|
2153
|
+
const formatDateValue = React__namespace.useCallback((date) => {
|
|
2154
|
+
if (format) {
|
|
2155
|
+
return formatDateByPattern(date, format);
|
|
2156
|
+
}
|
|
2157
|
+
return formatDate(date);
|
|
2158
|
+
}, [format, formatDate]);
|
|
2111
2159
|
// Determine which helper text to show
|
|
2112
2160
|
const displayHelperText = errorText || successText || helperText;
|
|
2113
2161
|
const currentValidationState = errorText
|
|
@@ -2179,13 +2227,74 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
|
|
|
2179
2227
|
setDropdownPlacement("top");
|
|
2180
2228
|
}
|
|
2181
2229
|
}, []);
|
|
2230
|
+
// Check if date picker is inside a modal
|
|
2231
|
+
React__namespace.useEffect(() => {
|
|
2232
|
+
if (isOpen && datePickerRef.current) {
|
|
2233
|
+
let element = datePickerRef.current;
|
|
2234
|
+
let foundModal = false;
|
|
2235
|
+
while (element && !foundModal) {
|
|
2236
|
+
const styles = window.getComputedStyle(element);
|
|
2237
|
+
const zIndex = parseInt(styles.zIndex, 10);
|
|
2238
|
+
// Check if element has modal z-index (10000) or is a modal container
|
|
2239
|
+
if (zIndex === 10000 || element.getAttribute("role") === "dialog") {
|
|
2240
|
+
foundModal = true;
|
|
2241
|
+
setIsInsideModal(true);
|
|
2242
|
+
break;
|
|
2243
|
+
}
|
|
2244
|
+
element = element.parentElement;
|
|
2245
|
+
}
|
|
2246
|
+
if (!foundModal) {
|
|
2247
|
+
setIsInsideModal(false);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
}, [isOpen]);
|
|
2251
|
+
// Update position when calendar opens or window resizes
|
|
2252
|
+
React__namespace.useEffect(() => {
|
|
2253
|
+
if (isOpen && datePickerRef.current) {
|
|
2254
|
+
const updatePosition = () => {
|
|
2255
|
+
const rect = datePickerRef.current?.getBoundingClientRect();
|
|
2256
|
+
if (rect) {
|
|
2257
|
+
setPosition({
|
|
2258
|
+
top: rect.top,
|
|
2259
|
+
left: rect.left,
|
|
2260
|
+
width: rect.width,
|
|
2261
|
+
bottom: rect.bottom,
|
|
2262
|
+
});
|
|
2263
|
+
// Update dropdown placement based on available space
|
|
2264
|
+
updateDropdownPlacement();
|
|
2265
|
+
}
|
|
2266
|
+
};
|
|
2267
|
+
updatePosition();
|
|
2268
|
+
window.addEventListener("resize", updatePosition);
|
|
2269
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
2270
|
+
return () => {
|
|
2271
|
+
window.removeEventListener("resize", updatePosition);
|
|
2272
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
}, [isOpen, updateDropdownPlacement]);
|
|
2182
2276
|
React__namespace.useEffect(() => {
|
|
2183
2277
|
if (!isOpen)
|
|
2184
2278
|
return;
|
|
2185
2279
|
if (typeof window === "undefined")
|
|
2186
2280
|
return;
|
|
2187
|
-
|
|
2188
|
-
|
|
2281
|
+
// Use requestAnimationFrame to ensure calendar is rendered before calculating placement
|
|
2282
|
+
let rafId = requestAnimationFrame(() => {
|
|
2283
|
+
updateDropdownPlacement();
|
|
2284
|
+
});
|
|
2285
|
+
const handleUpdate = () => {
|
|
2286
|
+
updateDropdownPlacement();
|
|
2287
|
+
// Also update position when scrolling/resizing
|
|
2288
|
+
if (datePickerRef.current) {
|
|
2289
|
+
const rect = datePickerRef.current.getBoundingClientRect();
|
|
2290
|
+
setPosition({
|
|
2291
|
+
top: rect.top,
|
|
2292
|
+
left: rect.left,
|
|
2293
|
+
width: rect.width,
|
|
2294
|
+
bottom: rect.bottom,
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
};
|
|
2189
2298
|
window.addEventListener("resize", handleUpdate);
|
|
2190
2299
|
window.addEventListener("scroll", handleUpdate, true);
|
|
2191
2300
|
return () => {
|
|
@@ -2196,14 +2305,44 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
|
|
|
2196
2305
|
}, [isOpen, updateDropdownPlacement]);
|
|
2197
2306
|
React__namespace.useEffect(() => {
|
|
2198
2307
|
if (isOpen) {
|
|
2199
|
-
|
|
2308
|
+
// Delay to ensure calendar is rendered
|
|
2309
|
+
const timer = setTimeout(() => {
|
|
2310
|
+
updateDropdownPlacement();
|
|
2311
|
+
}, 0);
|
|
2312
|
+
return () => clearTimeout(timer);
|
|
2200
2313
|
}
|
|
2201
2314
|
}, [isOpen, updateDropdownPlacement]);
|
|
2315
|
+
// Measure calendar height and adjust position after render
|
|
2316
|
+
React__namespace.useLayoutEffect(() => {
|
|
2317
|
+
if (isOpen && calendarRef.current && datePickerRef.current) {
|
|
2318
|
+
const measuredHeight = calendarRef.current.offsetHeight;
|
|
2319
|
+
setCalendarHeight(measuredHeight);
|
|
2320
|
+
const rect = datePickerRef.current.getBoundingClientRect();
|
|
2321
|
+
// Recalculate placement if needed based on actual calendar height
|
|
2322
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
2323
|
+
const spaceAbove = rect.top;
|
|
2324
|
+
if (measuredHeight > spaceBelow && spaceAbove > spaceBelow) {
|
|
2325
|
+
setDropdownPlacement("top");
|
|
2326
|
+
}
|
|
2327
|
+
else {
|
|
2328
|
+
setDropdownPlacement("bottom");
|
|
2329
|
+
}
|
|
2330
|
+
// Update position
|
|
2331
|
+
setPosition({
|
|
2332
|
+
top: rect.top,
|
|
2333
|
+
left: rect.left,
|
|
2334
|
+
width: rect.width,
|
|
2335
|
+
bottom: rect.bottom,
|
|
2336
|
+
});
|
|
2337
|
+
}
|
|
2338
|
+
}, [isOpen]);
|
|
2202
2339
|
// Close calendar when clicking outside
|
|
2203
2340
|
React__namespace.useEffect(() => {
|
|
2204
2341
|
const handleClickOutside = (event) => {
|
|
2205
2342
|
if (datePickerRef.current &&
|
|
2206
|
-
!datePickerRef.current.contains(event.target)
|
|
2343
|
+
!datePickerRef.current.contains(event.target) &&
|
|
2344
|
+
calendarRef.current &&
|
|
2345
|
+
!calendarRef.current.contains(event.target)) {
|
|
2207
2346
|
handleOpenChange(false);
|
|
2208
2347
|
}
|
|
2209
2348
|
};
|
|
@@ -2251,9 +2390,23 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
|
|
|
2251
2390
|
? "text-feedback-ink-positive-intense"
|
|
2252
2391
|
: currentValidationState === "negative"
|
|
2253
2392
|
? "text-feedback-ink-negative-subtle"
|
|
2254
|
-
: "text-surface-ink-neutral-muted") }), jsxRuntime.jsx("span", { className: cn("flex-1 text-left truncate", !hasValue && "text-surface-ink-neutral-muted", isDisabled && "text-surface-ink-neutral-disabled"), children: hasValue && value ?
|
|
2255
|
-
|
|
2256
|
-
|
|
2393
|
+
: "text-surface-ink-neutral-muted") }), jsxRuntime.jsx("span", { className: cn("flex-1 text-left truncate", !hasValue && "text-surface-ink-neutral-muted", isDisabled && "text-surface-ink-neutral-disabled"), children: hasValue && value ? formatDateValue(value) : placeholder }), 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, "aria-label": "Clear date", children: jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" }) }))] }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
|
|
2394
|
+
? "default"
|
|
2395
|
+
: currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" }), typeof document !== "undefined" &&
|
|
2396
|
+
isOpen &&
|
|
2397
|
+
!isDisabled &&
|
|
2398
|
+
(() => {
|
|
2399
|
+
// Calculate calendar position using fixed positioning (viewport-relative)
|
|
2400
|
+
const gap = 4; // 4px gap between trigger and calendar
|
|
2401
|
+
const calendarTop = dropdownPlacement === "bottom"
|
|
2402
|
+
? position.bottom + gap
|
|
2403
|
+
: position.top - calendarHeight - gap;
|
|
2404
|
+
const calendarPopup = (jsxRuntime.jsx("div", { ref: calendarRef, style: {
|
|
2405
|
+
position: "fixed",
|
|
2406
|
+
top: `${calendarTop}px`,
|
|
2407
|
+
left: `${position.left}px`,
|
|
2408
|
+
zIndex: isInsideModal ? 10001 : 9999,
|
|
2409
|
+
}, className: cn("bg-surface-fill-neutral-intense rounded-large shadow-lg p-4 w-fit", calendarClassName), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx("div", { className: "react-calendar-wrapper w-fit", children: jsxRuntime.jsx(Calendar, { onChange: handleCalendarChange, value: value ?? null, minDate: minDateParsed ?? undefined, maxDate: maxDateParsed ?? undefined, locale: "en-US", formatShortWeekday: (locale, date) => {
|
|
2257
2410
|
const weekdayNames = [
|
|
2258
2411
|
"Su",
|
|
2259
2412
|
"Mo",
|
|
@@ -2264,9 +2417,9 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
|
|
|
2264
2417
|
"Sa",
|
|
2265
2418
|
];
|
|
2266
2419
|
return weekdayNames[date.getDay()];
|
|
2267
|
-
} }) }) }))
|
|
2268
|
-
|
|
2269
|
-
|
|
2420
|
+
} }) }) }));
|
|
2421
|
+
return reactDom.createPortal(calendarPopup, document.body);
|
|
2422
|
+
})()] }));
|
|
2270
2423
|
});
|
|
2271
2424
|
DatePicker.displayName = "DatePicker";
|
|
2272
2425
|
|
|
@@ -3145,8 +3298,16 @@ const RadioGroup = React__namespace.forwardRef(({ value: controlledValue, defaul
|
|
|
3145
3298
|
if (currentIndex === -1)
|
|
3146
3299
|
return;
|
|
3147
3300
|
const direction = orientation === "horizontal"
|
|
3148
|
-
?
|
|
3149
|
-
|
|
3301
|
+
? e.key === "ArrowRight"
|
|
3302
|
+
? 1
|
|
3303
|
+
: e.key === "ArrowLeft"
|
|
3304
|
+
? -1
|
|
3305
|
+
: 0
|
|
3306
|
+
: e.key === "ArrowDown"
|
|
3307
|
+
? 1
|
|
3308
|
+
: e.key === "ArrowUp"
|
|
3309
|
+
? -1
|
|
3310
|
+
: 0;
|
|
3150
3311
|
if (direction === 0)
|
|
3151
3312
|
return;
|
|
3152
3313
|
e.preventDefault();
|
|
@@ -3214,20 +3375,14 @@ const RadioGroup = React__namespace.forwardRef(({ value: controlledValue, defaul
|
|
|
3214
3375
|
...child.props,
|
|
3215
3376
|
ref: (el) => {
|
|
3216
3377
|
radioRefs.current[index] = el;
|
|
3217
|
-
// Preserve original ref if it exists
|
|
3218
|
-
const originalRef = child.ref;
|
|
3219
|
-
if (typeof originalRef === "function") {
|
|
3220
|
-
originalRef(el);
|
|
3221
|
-
}
|
|
3222
|
-
else if (originalRef && "current" in originalRef) {
|
|
3223
|
-
originalRef.current = el;
|
|
3224
|
-
}
|
|
3225
3378
|
},
|
|
3226
3379
|
name,
|
|
3227
3380
|
checked: isChecked,
|
|
3228
3381
|
onChange: (e) => {
|
|
3229
3382
|
if (e.target.checked) {
|
|
3230
|
-
handleChange(childValue
|
|
3383
|
+
handleChange(typeof childValue === "string"
|
|
3384
|
+
? childValue
|
|
3385
|
+
: String(childValue || ""));
|
|
3231
3386
|
}
|
|
3232
3387
|
// Call original onChange if it exists
|
|
3233
3388
|
if (child.props.onChange) {
|
|
@@ -3241,7 +3396,13 @@ const RadioGroup = React__namespace.forwardRef(({ value: controlledValue, defaul
|
|
|
3241
3396
|
});
|
|
3242
3397
|
});
|
|
3243
3398
|
};
|
|
3244
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), ...props, children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { ref: groupRef, role: "radiogroup", "aria-label": label, "aria-required": isRequired, "aria-invalid": currentValidationState === "error", "aria-disabled": isDisabled, className: cn("flex", orientation === "horizontal"
|
|
3399
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), ...props, children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { ref: groupRef, role: "radiogroup", "aria-label": label, "aria-required": isRequired, "aria-invalid": currentValidationState === "error", "aria-disabled": isDisabled, className: cn("flex", orientation === "horizontal"
|
|
3400
|
+
? "flex-row items-center"
|
|
3401
|
+
: "flex-col items-start", spacingConfig[spacing], groupClassName, className), onKeyDown: handleKeyDown, id: id, children: options ? renderOptions() : renderChildren() }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
|
|
3402
|
+
? "default"
|
|
3403
|
+
: currentValidationState === "error"
|
|
3404
|
+
? "negative"
|
|
3405
|
+
: "default", size: size, isDisabled: isDisabled, className: "mt-1" })] }));
|
|
3245
3406
|
});
|
|
3246
3407
|
RadioGroup.displayName = "RadioGroup";
|
|
3247
3408
|
|