@papernote/ui 1.10.4 → 1.10.6
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/DataTable.d.ts.map +1 -1
- package/dist/components/SwipeableListItem.d.ts +66 -0
- package/dist/components/SwipeableListItem.d.ts.map +1 -0
- package/dist/components/TimezoneSelector.d.ts +102 -0
- package/dist/components/TimezoneSelector.d.ts.map +1 -0
- package/dist/components/Toast.d.ts +7 -1
- package/dist/components/Toast.d.ts.map +1 -1
- package/dist/components/index.d.ts +5 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +172 -4
- package/dist/index.esm.js +577 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +580 -4
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/DataTable.tsx +7 -3
- package/src/components/SwipeableListItem.stories.tsx +442 -0
- package/src/components/SwipeableListItem.tsx +425 -0
- package/src/components/TimezoneSelector.stories.tsx +314 -0
- package/src/components/TimezoneSelector.tsx +393 -0
- package/src/components/Toast.stories.tsx +449 -0
- package/src/components/Toast.tsx +23 -1
- package/src/components/index.ts +7 -1
- package/src/styles/index.css +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -2161,6 +2161,286 @@ const validationMessageColors = {
|
|
|
2161
2161
|
warning: 'text-warning-600',
|
|
2162
2162
|
};
|
|
2163
2163
|
|
|
2164
|
+
/**
|
|
2165
|
+
* Get the current UTC offset for a timezone
|
|
2166
|
+
*/
|
|
2167
|
+
function getTimezoneOffset(timezone) {
|
|
2168
|
+
try {
|
|
2169
|
+
const now = new Date();
|
|
2170
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
2171
|
+
timeZone: timezone,
|
|
2172
|
+
timeZoneName: 'longOffset',
|
|
2173
|
+
});
|
|
2174
|
+
const parts = formatter.formatToParts(now);
|
|
2175
|
+
const tzPart = parts.find(p => p.type === 'timeZoneName');
|
|
2176
|
+
if (tzPart?.value) {
|
|
2177
|
+
// Extract offset from format like "GMT-05:00" or "GMT+05:30"
|
|
2178
|
+
const match = tzPart.value.match(/GMT([+-]\d{2}:\d{2})/);
|
|
2179
|
+
if (match) {
|
|
2180
|
+
const offsetStr = match[1];
|
|
2181
|
+
const [hours, minutes] = offsetStr.split(':').map(Number);
|
|
2182
|
+
const sign = offsetStr.startsWith('-') ? -1 : 1;
|
|
2183
|
+
const totalMinutes = sign * (Math.abs(hours) * 60 + minutes);
|
|
2184
|
+
return {
|
|
2185
|
+
offset: `UTC${offsetStr}`,
|
|
2186
|
+
offsetMinutes: totalMinutes,
|
|
2187
|
+
};
|
|
2188
|
+
}
|
|
2189
|
+
// Handle "GMT" (UTC+00:00)
|
|
2190
|
+
if (tzPart.value === 'GMT') {
|
|
2191
|
+
return { offset: 'UTC+00:00', offsetMinutes: 0 };
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
// Fallback: calculate manually
|
|
2195
|
+
const utcDate = new Date(now.toLocaleString('en-US', { timeZone: 'UTC' }));
|
|
2196
|
+
const tzDate = new Date(now.toLocaleString('en-US', { timeZone: timezone }));
|
|
2197
|
+
const diffMinutes = (tzDate.getTime() - utcDate.getTime()) / 60000;
|
|
2198
|
+
const hours = Math.floor(Math.abs(diffMinutes) / 60);
|
|
2199
|
+
const mins = Math.abs(diffMinutes) % 60;
|
|
2200
|
+
const sign = diffMinutes >= 0 ? '+' : '-';
|
|
2201
|
+
const offset = `UTC${sign}${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}`;
|
|
2202
|
+
return { offset, offsetMinutes: diffMinutes };
|
|
2203
|
+
}
|
|
2204
|
+
catch {
|
|
2205
|
+
return { offset: 'UTC+00:00', offsetMinutes: 0 };
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Comprehensive list of common timezones organized by region
|
|
2210
|
+
*/
|
|
2211
|
+
const TIMEZONE_DATA = {
|
|
2212
|
+
Africa: [
|
|
2213
|
+
'Africa/Cairo',
|
|
2214
|
+
'Africa/Casablanca',
|
|
2215
|
+
'Africa/Johannesburg',
|
|
2216
|
+
'Africa/Lagos',
|
|
2217
|
+
'Africa/Nairobi',
|
|
2218
|
+
'Africa/Tunis',
|
|
2219
|
+
],
|
|
2220
|
+
America: [
|
|
2221
|
+
'America/Anchorage',
|
|
2222
|
+
'America/Argentina/Buenos_Aires',
|
|
2223
|
+
'America/Bogota',
|
|
2224
|
+
'America/Caracas',
|
|
2225
|
+
'America/Chicago',
|
|
2226
|
+
'America/Denver',
|
|
2227
|
+
'America/Halifax',
|
|
2228
|
+
'America/Lima',
|
|
2229
|
+
'America/Los_Angeles',
|
|
2230
|
+
'America/Mexico_City',
|
|
2231
|
+
'America/New_York',
|
|
2232
|
+
'America/Phoenix',
|
|
2233
|
+
'America/Santiago',
|
|
2234
|
+
'America/Sao_Paulo',
|
|
2235
|
+
'America/Toronto',
|
|
2236
|
+
'America/Vancouver',
|
|
2237
|
+
],
|
|
2238
|
+
Antarctica: [
|
|
2239
|
+
'Antarctica/McMurdo',
|
|
2240
|
+
'Antarctica/Palmer',
|
|
2241
|
+
'Antarctica/Syowa',
|
|
2242
|
+
],
|
|
2243
|
+
Asia: [
|
|
2244
|
+
'Asia/Bangkok',
|
|
2245
|
+
'Asia/Colombo',
|
|
2246
|
+
'Asia/Dhaka',
|
|
2247
|
+
'Asia/Dubai',
|
|
2248
|
+
'Asia/Hong_Kong',
|
|
2249
|
+
'Asia/Jakarta',
|
|
2250
|
+
'Asia/Jerusalem',
|
|
2251
|
+
'Asia/Karachi',
|
|
2252
|
+
'Asia/Kathmandu',
|
|
2253
|
+
'Asia/Kolkata',
|
|
2254
|
+
'Asia/Kuala_Lumpur',
|
|
2255
|
+
'Asia/Manila',
|
|
2256
|
+
'Asia/Qatar',
|
|
2257
|
+
'Asia/Riyadh',
|
|
2258
|
+
'Asia/Seoul',
|
|
2259
|
+
'Asia/Shanghai',
|
|
2260
|
+
'Asia/Singapore',
|
|
2261
|
+
'Asia/Taipei',
|
|
2262
|
+
'Asia/Tehran',
|
|
2263
|
+
'Asia/Tokyo',
|
|
2264
|
+
],
|
|
2265
|
+
Atlantic: [
|
|
2266
|
+
'Atlantic/Azores',
|
|
2267
|
+
'Atlantic/Bermuda',
|
|
2268
|
+
'Atlantic/Canary',
|
|
2269
|
+
'Atlantic/Cape_Verde',
|
|
2270
|
+
'Atlantic/Reykjavik',
|
|
2271
|
+
],
|
|
2272
|
+
Australia: [
|
|
2273
|
+
'Australia/Adelaide',
|
|
2274
|
+
'Australia/Brisbane',
|
|
2275
|
+
'Australia/Darwin',
|
|
2276
|
+
'Australia/Hobart',
|
|
2277
|
+
'Australia/Melbourne',
|
|
2278
|
+
'Australia/Perth',
|
|
2279
|
+
'Australia/Sydney',
|
|
2280
|
+
],
|
|
2281
|
+
Europe: [
|
|
2282
|
+
'Europe/Amsterdam',
|
|
2283
|
+
'Europe/Athens',
|
|
2284
|
+
'Europe/Berlin',
|
|
2285
|
+
'Europe/Brussels',
|
|
2286
|
+
'Europe/Bucharest',
|
|
2287
|
+
'Europe/Budapest',
|
|
2288
|
+
'Europe/Copenhagen',
|
|
2289
|
+
'Europe/Dublin',
|
|
2290
|
+
'Europe/Helsinki',
|
|
2291
|
+
'Europe/Istanbul',
|
|
2292
|
+
'Europe/Lisbon',
|
|
2293
|
+
'Europe/London',
|
|
2294
|
+
'Europe/Madrid',
|
|
2295
|
+
'Europe/Moscow',
|
|
2296
|
+
'Europe/Oslo',
|
|
2297
|
+
'Europe/Paris',
|
|
2298
|
+
'Europe/Prague',
|
|
2299
|
+
'Europe/Rome',
|
|
2300
|
+
'Europe/Stockholm',
|
|
2301
|
+
'Europe/Vienna',
|
|
2302
|
+
'Europe/Warsaw',
|
|
2303
|
+
'Europe/Zurich',
|
|
2304
|
+
],
|
|
2305
|
+
Indian: [
|
|
2306
|
+
'Indian/Maldives',
|
|
2307
|
+
'Indian/Mauritius',
|
|
2308
|
+
],
|
|
2309
|
+
Pacific: [
|
|
2310
|
+
'Pacific/Auckland',
|
|
2311
|
+
'Pacific/Fiji',
|
|
2312
|
+
'Pacific/Guam',
|
|
2313
|
+
'Pacific/Honolulu',
|
|
2314
|
+
'Pacific/Noumea',
|
|
2315
|
+
'Pacific/Pago_Pago',
|
|
2316
|
+
'Pacific/Tahiti',
|
|
2317
|
+
],
|
|
2318
|
+
};
|
|
2319
|
+
/**
|
|
2320
|
+
* Region display names
|
|
2321
|
+
*/
|
|
2322
|
+
const REGION_LABELS = {
|
|
2323
|
+
Africa: 'Africa',
|
|
2324
|
+
America: 'Americas',
|
|
2325
|
+
Antarctica: 'Antarctica',
|
|
2326
|
+
Asia: 'Asia',
|
|
2327
|
+
Atlantic: 'Atlantic',
|
|
2328
|
+
Australia: 'Australia',
|
|
2329
|
+
Europe: 'Europe',
|
|
2330
|
+
Indian: 'Indian Ocean',
|
|
2331
|
+
Pacific: 'Pacific',
|
|
2332
|
+
};
|
|
2333
|
+
/**
|
|
2334
|
+
* Get the user's local timezone
|
|
2335
|
+
*/
|
|
2336
|
+
function getLocalTimezone() {
|
|
2337
|
+
try {
|
|
2338
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
2339
|
+
}
|
|
2340
|
+
catch {
|
|
2341
|
+
return 'UTC';
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Check if a timezone string is valid
|
|
2346
|
+
*/
|
|
2347
|
+
function isValidTimezone(timezone) {
|
|
2348
|
+
try {
|
|
2349
|
+
Intl.DateTimeFormat(undefined, { timeZone: timezone });
|
|
2350
|
+
return true;
|
|
2351
|
+
}
|
|
2352
|
+
catch {
|
|
2353
|
+
return false;
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
/**
|
|
2357
|
+
* TimezoneSelector - A searchable dropdown for selecting timezones
|
|
2358
|
+
*
|
|
2359
|
+
* Provides a user-friendly way to select from IANA timezones, organized by
|
|
2360
|
+
* geographic region with UTC offset display.
|
|
2361
|
+
*
|
|
2362
|
+
* @example Basic usage
|
|
2363
|
+
* ```tsx
|
|
2364
|
+
* const [timezone, setTimezone] = useState('America/New_York');
|
|
2365
|
+
*
|
|
2366
|
+
* <TimezoneSelector
|
|
2367
|
+
* label="Select Timezone"
|
|
2368
|
+
* value={timezone}
|
|
2369
|
+
* onChange={setTimezone}
|
|
2370
|
+
* />
|
|
2371
|
+
* ```
|
|
2372
|
+
*
|
|
2373
|
+
* @example With local timezone detection
|
|
2374
|
+
* ```tsx
|
|
2375
|
+
* import { TimezoneSelector, getLocalTimezone } from 'notebook-ui';
|
|
2376
|
+
*
|
|
2377
|
+
* const [timezone, setTimezone] = useState(getLocalTimezone());
|
|
2378
|
+
*
|
|
2379
|
+
* <TimezoneSelector
|
|
2380
|
+
* value={timezone}
|
|
2381
|
+
* onChange={setTimezone}
|
|
2382
|
+
* includeUTC
|
|
2383
|
+
* clearable
|
|
2384
|
+
* />
|
|
2385
|
+
* ```
|
|
2386
|
+
*
|
|
2387
|
+
* @example Filter to specific regions
|
|
2388
|
+
* ```tsx
|
|
2389
|
+
* <TimezoneSelector
|
|
2390
|
+
* value={timezone}
|
|
2391
|
+
* onChange={setTimezone}
|
|
2392
|
+
* regions={['America', 'Europe']}
|
|
2393
|
+
* placeholder="Select US or European timezone..."
|
|
2394
|
+
* />
|
|
2395
|
+
* ```
|
|
2396
|
+
*/
|
|
2397
|
+
const TimezoneSelector = React__default.forwardRef(({ value, onChange, label, helperText, error, disabled = false, placeholder = 'Select timezone...', clearable = false, loading = false, size = 'md', includeUTC = true, regions, showOffset = true, }, ref) => {
|
|
2398
|
+
// Build timezone options grouped by region
|
|
2399
|
+
const groups = useMemo(() => {
|
|
2400
|
+
const result = [];
|
|
2401
|
+
// Add UTC as a special option at the top
|
|
2402
|
+
if (includeUTC) {
|
|
2403
|
+
result.push({
|
|
2404
|
+
label: 'Universal',
|
|
2405
|
+
options: [
|
|
2406
|
+
{
|
|
2407
|
+
value: 'UTC',
|
|
2408
|
+
label: showOffset ? 'UTC (UTC+00:00)' : 'UTC',
|
|
2409
|
+
},
|
|
2410
|
+
],
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
// Determine which regions to include
|
|
2414
|
+
const activeRegions = regions || Object.keys(TIMEZONE_DATA);
|
|
2415
|
+
// Build groups for each region
|
|
2416
|
+
for (const region of activeRegions) {
|
|
2417
|
+
const timezones = TIMEZONE_DATA[region];
|
|
2418
|
+
if (!timezones)
|
|
2419
|
+
continue;
|
|
2420
|
+
// Build options with offset info and sort by offset
|
|
2421
|
+
const options = timezones
|
|
2422
|
+
.map(tz => {
|
|
2423
|
+
const { offset, offsetMinutes } = getTimezoneOffset(tz);
|
|
2424
|
+
const city = tz.split('/').pop()?.replace(/_/g, ' ') || tz;
|
|
2425
|
+
return {
|
|
2426
|
+
value: tz,
|
|
2427
|
+
label: showOffset ? `${city} (${offset})` : city,
|
|
2428
|
+
offsetMinutes,
|
|
2429
|
+
};
|
|
2430
|
+
})
|
|
2431
|
+
.sort((a, b) => a.offsetMinutes - b.offsetMinutes)
|
|
2432
|
+
.map(({ value, label }) => ({ value, label }));
|
|
2433
|
+
result.push({
|
|
2434
|
+
label: REGION_LABELS[region],
|
|
2435
|
+
options,
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
return result;
|
|
2439
|
+
}, [includeUTC, regions, showOffset]);
|
|
2440
|
+
return (jsx(Select, { ref: ref, groups: groups, value: value, onChange: onChange, label: label, helperText: helperText, error: error, disabled: disabled, placeholder: placeholder, clearable: clearable, loading: loading, size: size, searchable: true, virtualized: false }));
|
|
2441
|
+
});
|
|
2442
|
+
TimezoneSelector.displayName = 'TimezoneSelector';
|
|
2443
|
+
|
|
2164
2444
|
/**
|
|
2165
2445
|
* Combobox component - searchable select with typeahead and custom value support.
|
|
2166
2446
|
*
|
|
@@ -3066,7 +3346,7 @@ const toastStyles = {
|
|
|
3066
3346
|
icon: jsx(Info, { className: "h-5 w-5 text-primary-600" }),
|
|
3067
3347
|
},
|
|
3068
3348
|
};
|
|
3069
|
-
function Toast({ id, type, title, message, duration = 5000, onClose }) {
|
|
3349
|
+
function Toast({ id, type, title, message, duration = 5000, onClose, action }) {
|
|
3070
3350
|
const [isExiting, setIsExiting] = useState(false);
|
|
3071
3351
|
const styles = toastStyles[type];
|
|
3072
3352
|
const handleClose = useCallback(() => {
|
|
@@ -3075,13 +3355,19 @@ function Toast({ id, type, title, message, duration = 5000, onClose }) {
|
|
|
3075
3355
|
onClose(id);
|
|
3076
3356
|
}, 300); // Match animation duration
|
|
3077
3357
|
}, [id, onClose]);
|
|
3358
|
+
const handleAction = useCallback(() => {
|
|
3359
|
+
if (action) {
|
|
3360
|
+
action.onClick();
|
|
3361
|
+
handleClose();
|
|
3362
|
+
}
|
|
3363
|
+
}, [action, handleClose]);
|
|
3078
3364
|
useEffect(() => {
|
|
3079
3365
|
const timer = setTimeout(() => {
|
|
3080
3366
|
handleClose();
|
|
3081
3367
|
}, duration);
|
|
3082
3368
|
return () => clearTimeout(timer);
|
|
3083
3369
|
}, [duration, handleClose]);
|
|
3084
|
-
return (jsx("div", { className: `${styles.bg} ${styles.border} bg-subtle-grain rounded-lg shadow-lg p-4 min-w-[320px] max-w-md transition-all duration-300 ${isExiting ? 'opacity-0 translate-x-full' : 'opacity-100 translate-x-0 animate-slide-in-right'}`, children: jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: styles.icon }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("h4", { className: "text-sm font-medium text-ink-900 mb-1", children: title }), jsx("p", { className: "text-sm text-ink-600", children: message })] }), jsx("button", { onClick: handleClose, className: "flex-shrink-0 text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close notification", children: jsx(X, { className: "h-4 w-4" }) })] }) }));
|
|
3370
|
+
return (jsx("div", { className: `${styles.bg} ${styles.border} bg-subtle-grain rounded-lg shadow-lg p-4 min-w-[320px] max-w-md transition-all duration-300 ${isExiting ? 'opacity-0 translate-x-full' : 'opacity-100 translate-x-0 animate-slide-in-right'}`, children: jsxs("div", { className: "flex items-start gap-3", children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: styles.icon }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("h4", { className: "text-sm font-medium text-ink-900 mb-1", children: title }), jsx("p", { className: "text-sm text-ink-600", children: message }), action && (jsx("button", { onClick: handleAction, className: "mt-2 text-sm font-medium text-accent-600 hover:text-accent-700 transition-colors", children: action.label }))] }), jsx("button", { onClick: handleClose, className: "flex-shrink-0 text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close notification", children: jsx(X, { className: "h-4 w-4" }) })] }) }));
|
|
3085
3371
|
}
|
|
3086
3372
|
const positionStyles = {
|
|
3087
3373
|
'top-right': 'top-20 right-6',
|
|
@@ -7816,6 +8102,289 @@ function SwipeableCard({ children, onSwipeRight, onSwipeLeft, rightAction = {
|
|
|
7816
8102
|
}, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, onMouseDown: handleMouseDown, role: "button", "aria-label": `Swipeable card. ${onSwipeRight ? `Swipe right to ${rightAction.label}.` : ''} ${onSwipeLeft ? `Swipe left to ${leftAction.label}.` : ''}`, tabIndex: disabled ? -1 : 0, children: children })] }));
|
|
7817
8103
|
}
|
|
7818
8104
|
|
|
8105
|
+
// Color classes for action backgrounds
|
|
8106
|
+
const getColorClass = (color) => {
|
|
8107
|
+
const colorMap = {
|
|
8108
|
+
destructive: 'bg-error-500',
|
|
8109
|
+
warning: 'bg-warning-500',
|
|
8110
|
+
success: 'bg-success-500',
|
|
8111
|
+
primary: 'bg-accent-500',
|
|
8112
|
+
};
|
|
8113
|
+
return colorMap[color] || color;
|
|
8114
|
+
};
|
|
8115
|
+
/**
|
|
8116
|
+
* SwipeableListItem - List item with swipe-to-action functionality
|
|
8117
|
+
*
|
|
8118
|
+
* Designed for mobile workflows with keyboard accessibility:
|
|
8119
|
+
* - Swipe right to approve/confirm
|
|
8120
|
+
* - Swipe left to dismiss/delete
|
|
8121
|
+
* - Arrow keys for keyboard navigation
|
|
8122
|
+
* - Async callback support with loading state
|
|
8123
|
+
*
|
|
8124
|
+
* @example
|
|
8125
|
+
* ```tsx
|
|
8126
|
+
* <SwipeableListItem
|
|
8127
|
+
* onSwipeRight={() => handleApprove()}
|
|
8128
|
+
* onSwipeLeft={() => handleDismiss()}
|
|
8129
|
+
* rightAction={{
|
|
8130
|
+
* icon: Check,
|
|
8131
|
+
* color: 'success',
|
|
8132
|
+
* label: 'Approve'
|
|
8133
|
+
* }}
|
|
8134
|
+
* leftAction={{
|
|
8135
|
+
* icon: X,
|
|
8136
|
+
* color: 'destructive',
|
|
8137
|
+
* label: 'Dismiss'
|
|
8138
|
+
* }}
|
|
8139
|
+
* >
|
|
8140
|
+
* <div className="p-4">List item content</div>
|
|
8141
|
+
* </SwipeableListItem>
|
|
8142
|
+
* ```
|
|
8143
|
+
*/
|
|
8144
|
+
function SwipeableListItem({ children, onSwipeRight, onSwipeLeft, rightAction, leftAction, swipeThreshold = 100, disabled = false, className = '', }) {
|
|
8145
|
+
const containerRef = useRef(null);
|
|
8146
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
8147
|
+
const [offsetX, setOffsetX] = useState(0);
|
|
8148
|
+
const [isTriggered, setIsTriggered] = useState(null);
|
|
8149
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
8150
|
+
const [keyboardDirection, setKeyboardDirection] = useState(null);
|
|
8151
|
+
const startX = useRef(0);
|
|
8152
|
+
const startY = useRef(0);
|
|
8153
|
+
const isHorizontalSwipe = useRef(null);
|
|
8154
|
+
// Trigger haptic feedback
|
|
8155
|
+
const triggerHaptic = useCallback((style = 'medium') => {
|
|
8156
|
+
if ('vibrate' in navigator) {
|
|
8157
|
+
const patterns = {
|
|
8158
|
+
light: 10,
|
|
8159
|
+
medium: 25,
|
|
8160
|
+
heavy: [50, 30, 50],
|
|
8161
|
+
};
|
|
8162
|
+
navigator.vibrate(patterns[style]);
|
|
8163
|
+
}
|
|
8164
|
+
}, []);
|
|
8165
|
+
// Execute action with async support
|
|
8166
|
+
const executeAction = useCallback(async (direction) => {
|
|
8167
|
+
const handler = direction === 'right' ? onSwipeRight : onSwipeLeft;
|
|
8168
|
+
if (!handler)
|
|
8169
|
+
return;
|
|
8170
|
+
setIsLoading(true);
|
|
8171
|
+
triggerHaptic('heavy');
|
|
8172
|
+
// Animate out
|
|
8173
|
+
const slideDistance = direction === 'right' ? window.innerWidth : -window.innerWidth;
|
|
8174
|
+
setOffsetX(slideDistance);
|
|
8175
|
+
try {
|
|
8176
|
+
await handler();
|
|
8177
|
+
}
|
|
8178
|
+
finally {
|
|
8179
|
+
// Reset state after animation
|
|
8180
|
+
setTimeout(() => {
|
|
8181
|
+
setOffsetX(0);
|
|
8182
|
+
setIsTriggered(null);
|
|
8183
|
+
setIsLoading(false);
|
|
8184
|
+
setKeyboardDirection(null);
|
|
8185
|
+
}, 200);
|
|
8186
|
+
}
|
|
8187
|
+
}, [onSwipeRight, onSwipeLeft, triggerHaptic]);
|
|
8188
|
+
// Handle drag start
|
|
8189
|
+
const handleDragStart = useCallback((clientX, clientY) => {
|
|
8190
|
+
if (disabled || isLoading)
|
|
8191
|
+
return;
|
|
8192
|
+
setIsDragging(true);
|
|
8193
|
+
startX.current = clientX;
|
|
8194
|
+
startY.current = clientY;
|
|
8195
|
+
isHorizontalSwipe.current = null;
|
|
8196
|
+
}, [disabled, isLoading]);
|
|
8197
|
+
// Handle drag move
|
|
8198
|
+
const handleDragMove = useCallback((clientX, clientY) => {
|
|
8199
|
+
if (!isDragging || disabled || isLoading)
|
|
8200
|
+
return;
|
|
8201
|
+
const deltaX = clientX - startX.current;
|
|
8202
|
+
const deltaY = clientY - startY.current;
|
|
8203
|
+
// Determine if this is a horizontal swipe on first significant movement
|
|
8204
|
+
if (isHorizontalSwipe.current === null) {
|
|
8205
|
+
const absDeltaX = Math.abs(deltaX);
|
|
8206
|
+
const absDeltaY = Math.abs(deltaY);
|
|
8207
|
+
if (absDeltaX > 10 || absDeltaY > 10) {
|
|
8208
|
+
isHorizontalSwipe.current = absDeltaX > absDeltaY;
|
|
8209
|
+
}
|
|
8210
|
+
}
|
|
8211
|
+
// Only process horizontal swipes
|
|
8212
|
+
if (isHorizontalSwipe.current !== true)
|
|
8213
|
+
return;
|
|
8214
|
+
// Check if we should allow this direction
|
|
8215
|
+
const canSwipeRight = onSwipeRight !== undefined && rightAction !== undefined;
|
|
8216
|
+
const canSwipeLeft = onSwipeLeft !== undefined && leftAction !== undefined;
|
|
8217
|
+
let newOffset = deltaX;
|
|
8218
|
+
// Limit swipe direction based on available actions
|
|
8219
|
+
if (!canSwipeRight && deltaX > 0)
|
|
8220
|
+
newOffset = 0;
|
|
8221
|
+
if (!canSwipeLeft && deltaX < 0)
|
|
8222
|
+
newOffset = 0;
|
|
8223
|
+
// Add resistance when exceeding threshold
|
|
8224
|
+
const maxSwipe = swipeThreshold * 1.5;
|
|
8225
|
+
if (Math.abs(newOffset) > swipeThreshold) {
|
|
8226
|
+
const overflow = Math.abs(newOffset) - swipeThreshold;
|
|
8227
|
+
const resistance = overflow * 0.3;
|
|
8228
|
+
newOffset = newOffset > 0
|
|
8229
|
+
? swipeThreshold + resistance
|
|
8230
|
+
: -(swipeThreshold + resistance);
|
|
8231
|
+
newOffset = Math.max(-maxSwipe, Math.min(maxSwipe, newOffset));
|
|
8232
|
+
}
|
|
8233
|
+
setOffsetX(newOffset);
|
|
8234
|
+
// Check for threshold crossing and trigger haptic
|
|
8235
|
+
const newTriggered = Math.abs(newOffset) >= swipeThreshold
|
|
8236
|
+
? (newOffset > 0 ? 'right' : 'left')
|
|
8237
|
+
: null;
|
|
8238
|
+
if (newTriggered !== isTriggered) {
|
|
8239
|
+
if (newTriggered) {
|
|
8240
|
+
triggerHaptic('medium');
|
|
8241
|
+
}
|
|
8242
|
+
setIsTriggered(newTriggered);
|
|
8243
|
+
}
|
|
8244
|
+
}, [isDragging, disabled, isLoading, onSwipeRight, onSwipeLeft, rightAction, leftAction, swipeThreshold, isTriggered, triggerHaptic]);
|
|
8245
|
+
// Handle drag end
|
|
8246
|
+
const handleDragEnd = useCallback(() => {
|
|
8247
|
+
if (!isDragging)
|
|
8248
|
+
return;
|
|
8249
|
+
setIsDragging(false);
|
|
8250
|
+
// Check if action should be triggered
|
|
8251
|
+
if (Math.abs(offsetX) >= swipeThreshold) {
|
|
8252
|
+
if (offsetX > 0 && onSwipeRight && rightAction) {
|
|
8253
|
+
executeAction('right');
|
|
8254
|
+
return;
|
|
8255
|
+
}
|
|
8256
|
+
else if (offsetX < 0 && onSwipeLeft && leftAction) {
|
|
8257
|
+
executeAction('left');
|
|
8258
|
+
return;
|
|
8259
|
+
}
|
|
8260
|
+
}
|
|
8261
|
+
// Snap back
|
|
8262
|
+
setOffsetX(0);
|
|
8263
|
+
setIsTriggered(null);
|
|
8264
|
+
}, [isDragging, offsetX, swipeThreshold, onSwipeRight, onSwipeLeft, rightAction, leftAction, executeAction]);
|
|
8265
|
+
// Touch event handlers
|
|
8266
|
+
const handleTouchStart = (e) => {
|
|
8267
|
+
handleDragStart(e.touches[0].clientX, e.touches[0].clientY);
|
|
8268
|
+
};
|
|
8269
|
+
const handleTouchMove = (e) => {
|
|
8270
|
+
handleDragMove(e.touches[0].clientX, e.touches[0].clientY);
|
|
8271
|
+
// Prevent vertical scroll if horizontal swipe
|
|
8272
|
+
if (isHorizontalSwipe.current === true) {
|
|
8273
|
+
e.preventDefault();
|
|
8274
|
+
}
|
|
8275
|
+
};
|
|
8276
|
+
const handleTouchEnd = () => {
|
|
8277
|
+
handleDragEnd();
|
|
8278
|
+
};
|
|
8279
|
+
// Mouse event handlers (for desktop testing)
|
|
8280
|
+
const handleMouseDown = (e) => {
|
|
8281
|
+
handleDragStart(e.clientX, e.clientY);
|
|
8282
|
+
};
|
|
8283
|
+
useEffect(() => {
|
|
8284
|
+
if (!isDragging)
|
|
8285
|
+
return;
|
|
8286
|
+
const handleMouseMove = (e) => {
|
|
8287
|
+
handleDragMove(e.clientX, e.clientY);
|
|
8288
|
+
};
|
|
8289
|
+
const handleMouseUp = () => {
|
|
8290
|
+
handleDragEnd();
|
|
8291
|
+
};
|
|
8292
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
8293
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
8294
|
+
return () => {
|
|
8295
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
8296
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
8297
|
+
};
|
|
8298
|
+
}, [isDragging, handleDragMove, handleDragEnd]);
|
|
8299
|
+
// Keyboard event handlers
|
|
8300
|
+
const handleKeyDown = useCallback((e) => {
|
|
8301
|
+
if (disabled || isLoading)
|
|
8302
|
+
return;
|
|
8303
|
+
const canSwipeRight = onSwipeRight !== undefined && rightAction !== undefined;
|
|
8304
|
+
const canSwipeLeft = onSwipeLeft !== undefined && leftAction !== undefined;
|
|
8305
|
+
switch (e.key) {
|
|
8306
|
+
case 'ArrowRight':
|
|
8307
|
+
if (canSwipeRight) {
|
|
8308
|
+
e.preventDefault();
|
|
8309
|
+
setKeyboardDirection('right');
|
|
8310
|
+
setOffsetX(swipeThreshold);
|
|
8311
|
+
setIsTriggered('right');
|
|
8312
|
+
triggerHaptic('medium');
|
|
8313
|
+
}
|
|
8314
|
+
break;
|
|
8315
|
+
case 'ArrowLeft':
|
|
8316
|
+
if (canSwipeLeft) {
|
|
8317
|
+
e.preventDefault();
|
|
8318
|
+
setKeyboardDirection('left');
|
|
8319
|
+
setOffsetX(-swipeThreshold);
|
|
8320
|
+
setIsTriggered('left');
|
|
8321
|
+
triggerHaptic('medium');
|
|
8322
|
+
}
|
|
8323
|
+
break;
|
|
8324
|
+
case 'Enter':
|
|
8325
|
+
if (keyboardDirection) {
|
|
8326
|
+
e.preventDefault();
|
|
8327
|
+
executeAction(keyboardDirection);
|
|
8328
|
+
}
|
|
8329
|
+
break;
|
|
8330
|
+
case 'Escape':
|
|
8331
|
+
if (keyboardDirection) {
|
|
8332
|
+
e.preventDefault();
|
|
8333
|
+
setKeyboardDirection(null);
|
|
8334
|
+
setOffsetX(0);
|
|
8335
|
+
setIsTriggered(null);
|
|
8336
|
+
}
|
|
8337
|
+
break;
|
|
8338
|
+
}
|
|
8339
|
+
}, [disabled, isLoading, onSwipeRight, onSwipeLeft, rightAction, leftAction, swipeThreshold, keyboardDirection, executeAction, triggerHaptic]);
|
|
8340
|
+
// Reset keyboard state on blur
|
|
8341
|
+
const handleBlur = useCallback(() => {
|
|
8342
|
+
if (keyboardDirection) {
|
|
8343
|
+
setKeyboardDirection(null);
|
|
8344
|
+
setOffsetX(0);
|
|
8345
|
+
setIsTriggered(null);
|
|
8346
|
+
}
|
|
8347
|
+
}, [keyboardDirection]);
|
|
8348
|
+
// Calculate action opacity based on swipe distance
|
|
8349
|
+
const rightActionOpacity = offsetX > 0 ? Math.min(1, offsetX / swipeThreshold) : 0;
|
|
8350
|
+
const leftActionOpacity = offsetX < 0 ? Math.min(1, Math.abs(offsetX) / swipeThreshold) : 0;
|
|
8351
|
+
// Build aria-label
|
|
8352
|
+
const ariaLabel = [
|
|
8353
|
+
'Swipeable list item.',
|
|
8354
|
+
rightAction && onSwipeRight ? `Swipe right or press Arrow Right to ${rightAction.label}.` : '',
|
|
8355
|
+
leftAction && onSwipeLeft ? `Swipe left or press Arrow Left to ${leftAction.label}.` : '',
|
|
8356
|
+
keyboardDirection ? `Press Enter to confirm or Escape to cancel.` : '',
|
|
8357
|
+
].filter(Boolean).join(' ');
|
|
8358
|
+
return (jsxs("div", { ref: containerRef, className: `relative overflow-hidden ${className}`, children: [rightAction && onSwipeRight && (jsx("div", { className: `
|
|
8359
|
+
absolute inset-y-0 left-0 flex items-center justify-start pl-6
|
|
8360
|
+
${getColorClass(rightAction.color)}
|
|
8361
|
+
transition-opacity duration-100
|
|
8362
|
+
`, style: {
|
|
8363
|
+
opacity: rightActionOpacity,
|
|
8364
|
+
width: Math.abs(offsetX) + 20,
|
|
8365
|
+
}, "aria-hidden": "true", children: jsx("div", { className: `
|
|
8366
|
+
text-white transform transition-transform duration-200
|
|
8367
|
+
${isTriggered === 'right' ? 'scale-125' : 'scale-100'}
|
|
8368
|
+
`, children: isLoading && isTriggered === 'right' ? (jsx(Loader2, { className: "h-6 w-6 animate-spin" })) : (jsx(rightAction.icon, { className: "h-6 w-6" })) }) })), leftAction && onSwipeLeft && (jsx("div", { className: `
|
|
8369
|
+
absolute inset-y-0 right-0 flex items-center justify-end pr-6
|
|
8370
|
+
${getColorClass(leftAction.color)}
|
|
8371
|
+
transition-opacity duration-100
|
|
8372
|
+
`, style: {
|
|
8373
|
+
opacity: leftActionOpacity,
|
|
8374
|
+
width: Math.abs(offsetX) + 20,
|
|
8375
|
+
}, "aria-hidden": "true", children: jsx("div", { className: `
|
|
8376
|
+
text-white transform transition-transform duration-200
|
|
8377
|
+
${isTriggered === 'left' ? 'scale-125' : 'scale-100'}
|
|
8378
|
+
`, children: isLoading && isTriggered === 'left' ? (jsx(Loader2, { className: "h-6 w-6 animate-spin" })) : (jsx(leftAction.icon, { className: "h-6 w-6" })) }) })), jsx("div", { className: `
|
|
8379
|
+
relative bg-white
|
|
8380
|
+
${isDragging ? '' : 'transition-transform duration-200 ease-out'}
|
|
8381
|
+
${disabled ? 'opacity-50 pointer-events-none' : ''}
|
|
8382
|
+
${keyboardDirection ? 'ring-2 ring-accent-500 ring-inset' : ''}
|
|
8383
|
+
`, style: {
|
|
8384
|
+
transform: `translateX(${offsetX}px)`,
|
|
8385
|
+
}, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, onMouseDown: handleMouseDown, onKeyDown: handleKeyDown, onBlur: handleBlur, role: "button", "aria-label": ariaLabel, tabIndex: disabled ? -1 : 0, children: children })] }));
|
|
8386
|
+
}
|
|
8387
|
+
|
|
7819
8388
|
/**
|
|
7820
8389
|
* NotificationBanner - Dismissible banner for important alerts
|
|
7821
8390
|
*
|
|
@@ -11510,14 +12079,17 @@ mobileView = 'auto', cardConfig, cardGap = 'md', cardClassName, }) {
|
|
|
11510
12079
|
const columnKey = String(column.key);
|
|
11511
12080
|
const dynamicWidth = columnWidths[columnKey];
|
|
11512
12081
|
return (jsx("col", { style: getColumnStyle(column, dynamicWidth) }, index));
|
|
11513
|
-
})] }), jsx("thead", { className: `bg-paper-100 sticky top-0 z-10 ${headerClassName}`, children: jsxs("tr", { className: "table-header-row", children: [selectable && (jsx("th", { className: `sticky left-0 bg-paper-100 ${currentDensity.header} border-b ${borderColor} z-20 w-12 ${bordered ? `border ${borderColor}` : ''}`, children: jsx("input", { type: "checkbox", checked: selectedRowsSet.size === data.length && data.length > 0, onChange: handleSelectAll, className: "w-4 h-4 text-accent-600 border-paper-300 rounded focus:ring-accent-400", "aria-label": "Select all rows" }) })), ((expandable || expandedRowConfig) && showExpandChevron) && (jsx("th", { className: `sticky left-0 bg-paper-100 px-2 ${currentDensity.header} border-b ${borderColor} z-19 w-10 ${bordered ? `border ${borderColor}` : ''}` })), allActions.length > 0 && (jsx("th", { className: `sticky left-0 bg-paper-100
|
|
12082
|
+
})] }), jsx("thead", { className: `bg-paper-100 sticky top-0 z-10 ${headerClassName}`, children: jsxs("tr", { className: "table-header-row", children: [selectable && (jsx("th", { className: `sticky left-0 bg-paper-100 ${currentDensity.header} border-b ${borderColor} z-20 w-12 ${bordered ? `border ${borderColor}` : ''}`, children: jsx("input", { type: "checkbox", checked: selectedRowsSet.size === data.length && data.length > 0, onChange: handleSelectAll, className: "w-4 h-4 text-accent-600 border-paper-300 rounded focus:ring-accent-400", "aria-label": "Select all rows" }) })), ((expandable || expandedRowConfig) && showExpandChevron) && (jsx("th", { className: `sticky left-0 bg-paper-100 px-2 ${currentDensity.header} border-b ${borderColor} z-19 w-10 ${bordered ? `border ${borderColor}` : ''}` })), allActions.length > 0 && (jsx("th", { className: `sticky left-0 bg-paper-100 text-center text-xs font-medium text-ink-700 uppercase tracking-wider border-b ${borderColor} z-20 ${bordered ? `border ${borderColor}` : ''}`, style: { width: '28px', padding: '0' } })), visibleColumns.map((column, colIdx) => {
|
|
11514
12083
|
const columnKey = String(column.key);
|
|
11515
12084
|
const dynamicWidth = columnWidths[columnKey];
|
|
11516
12085
|
const thRef = useRef(null);
|
|
11517
12086
|
const isDragging = draggingColumn === columnKey;
|
|
11518
12087
|
const isDragOver = dragOverColumn === columnKey;
|
|
12088
|
+
// Reduce left padding on first column when there are action buttons (match body cells)
|
|
12089
|
+
const isFirstColumn = colIdx === 0;
|
|
12090
|
+
const headerPaddingClass = isFirstColumn && allActions.length > 0 ? 'pl-3' : '';
|
|
11519
12091
|
return (jsxs("th", { ref: thRef, draggable: reorderable, onDragStart: (e) => reorderable && handleDragStart(e, columnKey), onDragOver: (e) => reorderable && handleDragOver(e, columnKey), onDragEnd: handleDragEnd, onDrop: (e) => reorderable && handleDrop(e, columnKey), className: `
|
|
11520
|
-
${currentDensity.header} text-left border-b ${borderColor} ${bordered ? `border ${borderColor}` : ''} relative
|
|
12092
|
+
${currentDensity.header} ${headerPaddingClass} text-left border-b ${borderColor} ${bordered ? `border ${borderColor}` : ''} relative
|
|
11521
12093
|
${reorderable ? 'cursor-move' : ''}
|
|
11522
12094
|
${isDragging ? 'opacity-50' : ''}
|
|
11523
12095
|
${isDragOver ? 'bg-accent-100' : ''}
|
|
@@ -58193,5 +58765,5 @@ function Responsive({ mobile, tablet, desktop, }) {
|
|
|
58193
58765
|
return jsx(Fragment, { children: mobile || tablet || desktop });
|
|
58194
58766
|
}
|
|
58195
58767
|
|
|
58196
|
-
export { Accordion, ActionBar, ActionBarCenter, ActionBarLeft, ActionBarRight, ActionButton, AdminModal, Alert, AlertDialog, AppLayout, Autocomplete, Avatar, BREAKPOINTS, Badge, BottomNavigation, BottomNavigationSpacer, BottomSheet, BottomSheetActions, BottomSheetContent, BottomSheetHeader, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, Checkbox, CheckboxList, Chip, ChipGroup, Collapsible, ColorPicker, Combobox, ComingSoon, CommandPalette, CompactStat, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, CurrencyInput, Dashboard, DashboardContent, DashboardHeader, DataGrid, DataTable, DataTableCardView, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, DesktopOnly, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, ErrorBoundary, ExpandablePanel, ExpandablePanelContainer, ExpandablePanelSpacer, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FORMULA_CATEGORIES, FORMULA_DEFINITIONS, FORMULA_NAMES, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, FloatingActionButton, Form, FormContext, FormControl, FormWizard, Grid, GridItem, Hide, HorizontalScroll, HoverCard, InfiniteScroll, Input, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, Menu, MenuDivider, MobileHeader, MobileHeaderSpacer, MobileLayout, MobileOnly, MobileProvider, Modal, ModalFooter, MultiSelect, NotificationBanner, NotificationBar, NotificationBell, NotificationIndicator, NumberInput, Page, PageHeader, PageLayout, PageNavigation, Pagination, PasswordInput, Popover, Progress, PullToRefresh, QueryTransparency, RadioGroup, Rating, Responsive, RichTextEditor, SearchBar, SearchableList, Select, Separator, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard$1 as SkeletonCard, SkeletonTable, Slider, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, SwipeActions, SwipeableCard, Switch, Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger, Text, Textarea, ThemeToggle, TimePicker, Timeline, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createMultiSheetExcel, createPageControlsSection, createQueryDetailsSection, exportDataTableToExcel, exportToExcel, formatStatisticValue, formatStatistics, getFormula, getFormulasByCategory, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, searchFormulas, statusManager, useBreadcrumbReset, useBreakpoint, useBreakpointValue, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useFABScroll, useFormContext, useIsDesktop, useIsMobile, useIsTablet, useIsTouchDevice, useMediaQuery, useMobileContext, useOrientation, usePrefersMobile, useResponsiveCallback, useSafeAreaInsets, useViewportSize, withMobileContext };
|
|
58768
|
+
export { Accordion, ActionBar, ActionBarCenter, ActionBarLeft, ActionBarRight, ActionButton, AdminModal, Alert, AlertDialog, AppLayout, Autocomplete, Avatar, BREAKPOINTS, Badge, BottomNavigation, BottomNavigationSpacer, BottomSheet, BottomSheetActions, BottomSheetContent, BottomSheetHeader, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, Checkbox, CheckboxList, Chip, ChipGroup, Collapsible, ColorPicker, Combobox, ComingSoon, CommandPalette, CompactStat, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, CurrencyInput, Dashboard, DashboardContent, DashboardHeader, DataGrid, DataTable, DataTableCardView, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, DesktopOnly, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, ErrorBoundary, ExpandablePanel, ExpandablePanelContainer, ExpandablePanelSpacer, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FORMULA_CATEGORIES, FORMULA_DEFINITIONS, FORMULA_NAMES, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, FloatingActionButton, Form, FormContext, FormControl, FormWizard, Grid, GridItem, Hide, HorizontalScroll, HoverCard, InfiniteScroll, Input, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, Menu, MenuDivider, MobileHeader, MobileHeaderSpacer, MobileLayout, MobileOnly, MobileProvider, Modal, ModalFooter, MultiSelect, NotificationBanner, NotificationBar, NotificationBell, NotificationIndicator, NumberInput, Page, PageHeader, PageLayout, PageNavigation, Pagination, PasswordInput, Popover, Progress, PullToRefresh, QueryTransparency, RadioGroup, Rating, Responsive, RichTextEditor, SearchBar, SearchableList, Select, Separator, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard$1 as SkeletonCard, SkeletonTable, Slider, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, SwipeActions, SwipeableCard, SwipeableListItem, Switch, Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger, Text, Textarea, ThemeToggle, TimePicker, Timeline, TimezoneSelector, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createMultiSheetExcel, createPageControlsSection, createQueryDetailsSection, exportDataTableToExcel, exportToExcel, formatStatisticValue, formatStatistics, getFormula, getFormulasByCategory, getLocalTimezone, isValidTimezone, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, searchFormulas, statusManager, useBreadcrumbReset, useBreakpoint, useBreakpointValue, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useFABScroll, useFormContext, useIsDesktop, useIsMobile, useIsTablet, useIsTouchDevice, useMediaQuery, useMobileContext, useOrientation, usePrefersMobile, useResponsiveCallback, useSafeAreaInsets, useViewportSize, withMobileContext };
|
|
58197
58769
|
//# sourceMappingURL=index.esm.js.map
|