@dreamtree-org/twreact-ui 1.3.9 → 1.3.11
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/README.md +32 -0
- package/ai-skills/dreamtree-ui.md +12 -7
- package/dist/ai-schema.json +156 -29
- package/dist/charts/index.js +195 -66
- package/dist/components/blocks/AppShell.d.ts.map +1 -1
- package/dist/components/charts/CartesianChart.d.ts.map +1 -1
- package/dist/components/charts/ChartFrame.d.ts.map +1 -1
- package/dist/components/charts/useChartLayout.d.ts +25 -0
- package/dist/components/charts/useChartLayout.d.ts.map +1 -0
- package/dist/components/core/Accordion.d.ts.map +1 -1
- package/dist/components/core/Button.d.ts.map +1 -1
- package/dist/components/core/Checkbox.d.ts.map +1 -1
- package/dist/components/core/ColorPicker.d.ts.map +1 -1
- package/dist/components/core/DatePicker.d.ts.map +1 -1
- package/dist/components/core/Form.d.ts.map +1 -1
- package/dist/components/core/Input.d.ts.map +1 -1
- package/dist/components/core/Loader.d.ts.map +1 -1
- package/dist/components/core/LocationPicker.d.ts.map +1 -1
- package/dist/components/core/PriceRangePicker.d.ts +0 -29
- package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
- package/dist/components/core/ProgressBar.d.ts.map +1 -1
- package/dist/components/core/Radio.d.ts.map +1 -1
- package/dist/components/core/Rate.d.ts.map +1 -1
- package/dist/components/core/RoundedTag.d.ts.map +1 -1
- package/dist/components/core/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts.map +1 -1
- package/dist/components/core/SpeechToText.d.ts.map +1 -1
- package/dist/components/core/Switch.d.ts.map +1 -1
- package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
- package/dist/components/core/Table/Pagination.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Table/helpers.d.ts +2 -0
- package/dist/components/core/Table/helpers.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts +2 -5
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/TextToSpeech.d.ts +2 -7
- package/dist/components/core/TextToSpeech.d.ts.map +1 -1
- package/dist/components/core/Textarea.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/feedback/Alert.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/utility/Avatar.d.ts +8 -0
- package/dist/components/utility/Avatar.d.ts.map +1 -1
- package/dist/components/utility/AvatarGroup.d.ts +4 -0
- package/dist/components/utility/AvatarGroup.d.ts.map +1 -0
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/Card.d.ts.map +1 -1
- package/dist/components/utility/Carousel.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Pagination.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts.map +1 -1
- package/dist/components/utility/Stepper.d.ts.map +1 -1
- package/dist/esm/components/blocks/AppShell.js +24 -18
- package/dist/esm/components/blocks/EmptyState.js +1 -1
- package/dist/esm/components/blocks/ErrorState.js +1 -1
- package/dist/esm/components/blocks/LoadingState.js +4 -4
- package/dist/esm/components/blocks/StatCard.js +6 -6
- package/dist/esm/components/blocks/StatusPill.js +5 -8
- package/dist/esm/components/charts/CartesianChart.js +85 -62
- package/dist/esm/components/charts/ChartFrame.js +12 -5
- package/dist/esm/components/charts/useChartLayout.js +105 -0
- package/dist/esm/components/core/Accordion.js +40 -9
- package/dist/esm/components/core/Button.js +49 -25
- package/dist/esm/components/core/Checkbox.js +71 -45
- package/dist/esm/components/core/ColorPicker.js +49 -48
- package/dist/esm/components/core/DatePicker.js +97 -58
- package/dist/esm/components/core/Form.js +35 -8
- package/dist/esm/components/core/Input.js +89 -20
- package/dist/esm/components/core/Loader.js +30 -44
- package/dist/esm/components/core/LocationPicker.js +82 -16
- package/dist/esm/components/core/PriceRangePicker.js +205 -218
- package/dist/esm/components/core/ProgressBar.js +8 -12
- package/dist/esm/components/core/Radio.js +43 -15
- package/dist/esm/components/core/Rate.js +109 -50
- package/dist/esm/components/core/RoundedTag.js +27 -10
- package/dist/esm/components/core/Skeleton.js +13 -14
- package/dist/esm/components/core/Slider.js +24 -6
- package/dist/esm/components/core/SpeechToText.js +68 -16
- package/dist/esm/components/core/Switch.js +88 -16
- package/dist/esm/components/core/Table/ColumnMenu.js +2 -4
- package/dist/esm/components/core/Table/Pagination.js +15 -18
- package/dist/esm/components/core/Table/TableRow.js +2 -2
- package/dist/esm/components/core/Table/helpers.js +33 -1
- package/dist/esm/components/core/Tabs.js +185 -37
- package/dist/esm/components/core/TextToSpeech.js +121 -28
- package/dist/esm/components/core/Textarea.js +10 -2
- package/dist/esm/components/core/Tooltip.js +100 -28
- package/dist/esm/components/feedback/Alert.js +21 -11
- package/dist/esm/components/feedback/Dialog.js +44 -100
- package/dist/esm/components/feedback/Toast.js +24 -5
- package/dist/esm/components/navigation/Breadcrumbs.js +97 -35
- package/dist/esm/components/navigation/FootNav.js +102 -13
- package/dist/esm/components/navigation/Sidebar.js +13 -61
- package/dist/esm/components/utility/Avatar.js +37 -22
- package/dist/esm/components/utility/AvatarGroup.js +56 -0
- package/dist/esm/components/utility/Badge.js +43 -23
- package/dist/esm/components/utility/Card.js +32 -8
- package/dist/esm/components/utility/Carousel.js +165 -38
- package/dist/esm/components/utility/FileUpload.js +106 -31
- package/dist/esm/components/utility/Pagination.js +33 -15
- package/dist/esm/components/utility/Sortable.js +6 -2
- package/dist/esm/components/utility/Stepper.js +110 -47
- package/dist/esm/hooks/useFocusTrap.js +10 -2
- package/dist/esm/hooks/useSliderValues.js +8 -2
- package/dist/esm/hooks/useSortable.js +107 -5
- package/dist/esm/index.js +1 -0
- package/dist/esm/utils/touchTarget.js +4 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useSliderValues.d.ts +6 -2
- package/dist/hooks/useSliderValues.d.ts.map +1 -1
- package/dist/hooks/useSortable.d.ts +11 -1
- package/dist/hooks/useSortable.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +3734 -2174
- package/dist/index.js +3732 -2171
- package/dist/types/charts.d.ts +3 -1
- package/dist/types/charts.d.ts.map +1 -1
- package/dist/types/index.d.ts +64 -9
- package/dist/types/index.d.ts.map +1 -1
- package/doc/README.md +1 -0
- package/mcp/catalog.snapshot.json +350 -121
- package/package.json +1 -1
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
6
|
|
|
7
|
-
var _excluded = ["children", "variant", "size", "rounded", "className"];
|
|
7
|
+
var _excluded = ["children", "variant", "size", "rounded", "dot", "icon", "max", "className"];
|
|
8
|
+
// Light: 100 fill + 800 text (≥4.5:1). Dark: a tinted 900 fill + 200 text.
|
|
9
|
+
var variants = {
|
|
10
|
+
"default": 'bg-gray-100 text-primary-800 dark:bg-gray-800 dark:text-gray-100',
|
|
11
|
+
primary: 'bg-primary-100 text-primary-800 dark:bg-primary-900/40 dark:text-primary-200',
|
|
12
|
+
secondary: 'bg-secondary-100 text-secondary-800 dark:bg-secondary-800 dark:text-secondary-100',
|
|
13
|
+
success: 'bg-success-100 text-success-800 dark:bg-success-900/40 dark:text-success-200',
|
|
14
|
+
warning: 'bg-warning-100 text-warning-800 dark:bg-warning-900/40 dark:text-warning-200',
|
|
15
|
+
error: 'bg-error-100 text-error-800 dark:bg-error-900/40 dark:text-error-200',
|
|
16
|
+
info: 'bg-info-100 text-info-800 dark:bg-info-900/40 dark:text-info-200',
|
|
17
|
+
outline: 'border border-gray-300 text-gray-700 dark:border-gray-600 dark:text-gray-200'
|
|
18
|
+
};
|
|
19
|
+
var sizes = {
|
|
20
|
+
xs: 'px-1.5 py-px text-xs',
|
|
21
|
+
sm: 'px-2 py-0.5 text-xs',
|
|
22
|
+
md: 'px-2.5 py-0.5 text-sm',
|
|
23
|
+
lg: 'px-3 py-1 text-base',
|
|
24
|
+
xl: 'px-3.5 py-1 text-lg',
|
|
25
|
+
'2xl': 'px-4 py-1.5 text-xl'
|
|
26
|
+
};
|
|
27
|
+
// A numeric count above `max` reads `${max}+` (e.g. 99+).
|
|
28
|
+
var formatCount = function formatCount(children, max) {
|
|
29
|
+
return typeof children === 'number' && typeof max === 'number' && children > max ? "".concat(max, "+") : children;
|
|
30
|
+
};
|
|
8
31
|
var Badge = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
9
32
|
var children = _ref.children,
|
|
10
33
|
_ref$variant = _ref.variant,
|
|
@@ -13,34 +36,31 @@ var Badge = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
13
36
|
size = _ref$size === void 0 ? 'md' : _ref$size,
|
|
14
37
|
_ref$rounded = _ref.rounded,
|
|
15
38
|
rounded = _ref$rounded === void 0 ? true : _ref$rounded,
|
|
39
|
+
_ref$dot = _ref.dot,
|
|
40
|
+
dot = _ref$dot === void 0 ? false : _ref$dot,
|
|
41
|
+
icon = _ref.icon,
|
|
42
|
+
max = _ref.max,
|
|
16
43
|
className = _ref.className,
|
|
17
44
|
props = _objectWithoutProperties(_ref, _excluded);
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
primary: 'bg-primary-100 text-primary-800',
|
|
21
|
-
secondary: 'bg-secondary-100 text-secondary-800',
|
|
22
|
-
success: 'bg-success-100 text-success-800',
|
|
23
|
-
warning: 'bg-warning-100 text-warning-800',
|
|
24
|
-
error: 'bg-error-100 text-error-800',
|
|
25
|
-
info: 'bg-info-100 text-info-800',
|
|
26
|
-
outline: 'border border-gray-300'
|
|
27
|
-
};
|
|
28
|
-
var sizes = {
|
|
29
|
-
xs: 'px-1.5 py-px text-xs',
|
|
30
|
-
sm: 'px-2 py-0.5 text-xs',
|
|
31
|
-
md: 'px-2.5 py-0.5 text-sm',
|
|
32
|
-
lg: 'px-3 py-1 text-base',
|
|
33
|
-
xl: 'px-3.5 py-1 text-lg',
|
|
34
|
-
'2xl': 'px-4 py-1.5 text-xl'
|
|
35
|
-
};
|
|
36
|
-
return jsx("span", _objectSpread2(_objectSpread2({
|
|
45
|
+
var hasLead = dot || Boolean(icon);
|
|
46
|
+
return jsxs("span", _objectSpread2(_objectSpread2({
|
|
37
47
|
ref: ref,
|
|
38
48
|
className: cn('inline-flex items-center font-medium', variants[variant], sizes[size] || sizes.md, {
|
|
39
49
|
'rounded-full': rounded,
|
|
40
|
-
'rounded-md': !rounded
|
|
50
|
+
'rounded-md': !rounded,
|
|
51
|
+
'gap-1': hasLead
|
|
41
52
|
}, className)
|
|
42
53
|
}, props), {}, {
|
|
43
|
-
children:
|
|
54
|
+
children: [dot && jsx("span", {
|
|
55
|
+
className: "h-1.5 w-1.5 shrink-0 rounded-full bg-current",
|
|
56
|
+
"aria-hidden": "true",
|
|
57
|
+
"data-slot": "dot"
|
|
58
|
+
}), icon && jsx("span", {
|
|
59
|
+
className: "inline-flex h-3.5 w-3.5 shrink-0 items-center",
|
|
60
|
+
"aria-hidden": "true",
|
|
61
|
+
"data-slot": "icon",
|
|
62
|
+
children: icon
|
|
63
|
+
}), formatCount(children, max)]
|
|
44
64
|
}));
|
|
45
65
|
});
|
|
46
66
|
Badge.displayName = 'Badge';
|
|
@@ -1,26 +1,50 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2, defineProperty as _defineProperty } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
|
+
import { PRESS_FEEDBACK } from '../../utils/touchTarget.js';
|
|
6
7
|
|
|
7
|
-
var _excluded = ["children", "className", "hover"],
|
|
8
|
+
var _excluded = ["children", "className", "hover", "interactive", "onClick", "onKeyDown"],
|
|
8
9
|
_excluded2 = ["children", "className"],
|
|
9
10
|
_excluded3 = ["children", "className"],
|
|
10
11
|
_excluded4 = ["children", "className"],
|
|
11
12
|
_excluded5 = ["children", "className"],
|
|
12
13
|
_excluded6 = ["children", "className"];
|
|
14
|
+
// Interactive cards: hover lift, press shrink and a keyboard focus ring. The
|
|
15
|
+
// transition list covers both the shadow and the press transform.
|
|
16
|
+
var INTERACTIVE_CLASSES = cn('cursor-pointer hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-gray-900', PRESS_FEEDBACK, 'transition-[box-shadow,transform] duration-fast ease-standard motion-reduce:transition-none');
|
|
13
17
|
var Card = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
14
18
|
var children = _ref.children,
|
|
15
19
|
className = _ref.className,
|
|
16
20
|
_ref$hover = _ref.hover,
|
|
17
21
|
hover = _ref$hover === void 0 ? false : _ref$hover,
|
|
22
|
+
_ref$interactive = _ref.interactive,
|
|
23
|
+
interactive = _ref$interactive === void 0 ? false : _ref$interactive,
|
|
24
|
+
onClick = _ref.onClick,
|
|
25
|
+
onKeyDown = _ref.onKeyDown,
|
|
18
26
|
props = _objectWithoutProperties(_ref, _excluded);
|
|
27
|
+
// A clickable interactive card with no role of its own becomes a keyboard
|
|
28
|
+
// operable button (Tab to it, Enter / Space to activate).
|
|
29
|
+
var actsAsButton = interactive && typeof onClick === 'function' && props.role === undefined;
|
|
30
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
31
|
+
onKeyDown === null || onKeyDown === void 0 || onKeyDown(e);
|
|
32
|
+
if (!actsAsButton || e.defaultPrevented || e.target !== e.currentTarget) return;
|
|
33
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
onClick(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
19
38
|
return jsx("div", _objectSpread2(_objectSpread2({
|
|
20
39
|
ref: ref,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
role: actsAsButton ? 'button' : undefined,
|
|
41
|
+
tabIndex: actsAsButton ? 0 : undefined,
|
|
42
|
+
onClick: onClick,
|
|
43
|
+
onKeyDown: actsAsButton ? handleKeyDown : onKeyDown,
|
|
44
|
+
"data-interactive": interactive || undefined,
|
|
45
|
+
className: cn('rounded-card border border-line bg-surface shadow-sm', _defineProperty({
|
|
46
|
+
'hover:shadow-md transition-shadow': hover && !interactive
|
|
47
|
+
}, INTERACTIVE_CLASSES, interactive), className)
|
|
24
48
|
}, props), {}, {
|
|
25
49
|
children: children
|
|
26
50
|
}));
|
|
@@ -31,7 +55,7 @@ var CardHeader = function CardHeader(_ref2) {
|
|
|
31
55
|
className = _ref2.className,
|
|
32
56
|
props = _objectWithoutProperties(_ref2, _excluded2);
|
|
33
57
|
return jsx("div", _objectSpread2(_objectSpread2({
|
|
34
|
-
className: cn('px-6 py-4 border-b border-line', className)
|
|
58
|
+
className: cn('px-4 sm:px-6 py-4 border-b border-line', className)
|
|
35
59
|
}, props), {}, {
|
|
36
60
|
children: children
|
|
37
61
|
}));
|
|
@@ -61,7 +85,7 @@ var CardContent = function CardContent(_ref5) {
|
|
|
61
85
|
className = _ref5.className,
|
|
62
86
|
props = _objectWithoutProperties(_ref5, _excluded5);
|
|
63
87
|
return jsx("div", _objectSpread2(_objectSpread2({
|
|
64
|
-
className: cn('px-6 py-4', className)
|
|
88
|
+
className: cn('px-4 sm:px-6 py-4', className)
|
|
65
89
|
}, props), {}, {
|
|
66
90
|
children: children
|
|
67
91
|
}));
|
|
@@ -71,7 +95,7 @@ var CardFooter = function CardFooter(_ref6) {
|
|
|
71
95
|
className = _ref6.className,
|
|
72
96
|
props = _objectWithoutProperties(_ref6, _excluded6);
|
|
73
97
|
return jsx("div", _objectSpread2(_objectSpread2({
|
|
74
|
-
className: cn('px-6 py-4 border-t border-line', className)
|
|
98
|
+
className: cn('px-4 sm:px-6 py-4 border-t border-line', className)
|
|
75
99
|
}, props), {}, {
|
|
76
100
|
children: children
|
|
77
101
|
}));
|
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
6
6
|
import { cn } from '../../utils/cn.js';
|
|
7
|
+
import { TOUCH_TARGET, PRESS_FEEDBACK } from '../../utils/touchTarget.js';
|
|
8
|
+
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
|
|
9
|
+
import { useLatestRef } from '../../hooks/useLatestRef.js';
|
|
7
10
|
|
|
11
|
+
var _excluded = ["children", "autoPlay", "interval", "showDots", "className", "itemClassName", "onMouseEnter", "onMouseLeave", "onFocus", "onBlur", "onTouchStart", "onTouchEnd"];
|
|
12
|
+
// Arrows stay visible at rest (touch devices have no hover) and use the surface /
|
|
13
|
+
// foreground role tokens so they read on light and dark themes alike.
|
|
14
|
+
var ARROW_CLASSES = "absolute top-1/2 -translate-y-1/2 z-10 inline-flex items-center justify-center p-2 rounded-full bg-surface/80 backdrop-blur-md border border-line text-foreground shadow-lg transition-colors motion-reduce:transition-none hover:bg-surface focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500";
|
|
15
|
+
// The track is a native horizontal scroller with mandatory snap points, so
|
|
16
|
+
// touch users get momentum swipe for free. The scrollbar is hidden; the arrows,
|
|
17
|
+
// dots and keyboard (focus the track, then arrow keys) are the visible controls.
|
|
18
|
+
var TRACK_CLASSES = "flex overflow-x-auto snap-x snap-mandatory scroll-smooth motion-reduce:scroll-auto overscroll-x-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary-500";
|
|
19
|
+
function scrollTrackTo(track, slide, behavior) {
|
|
20
|
+
if (!track || !slide) return;
|
|
21
|
+
if (typeof track.scrollTo === "function") {
|
|
22
|
+
track.scrollTo({
|
|
23
|
+
left: slide.offsetLeft,
|
|
24
|
+
behavior: behavior
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
track.scrollLeft = slide.offsetLeft;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
8
30
|
var Carousel = /*#__PURE__*/React.forwardRef(function Carousel(props, ref) {
|
|
9
31
|
var children = props.children,
|
|
10
32
|
_props$autoPlay = props.autoPlay,
|
|
@@ -14,83 +36,188 @@ var Carousel = /*#__PURE__*/React.forwardRef(function Carousel(props, ref) {
|
|
|
14
36
|
_props$showDots = props.showDots,
|
|
15
37
|
showDots = _props$showDots === void 0 ? true : _props$showDots,
|
|
16
38
|
className = props.className,
|
|
17
|
-
itemClassName = props.itemClassName
|
|
39
|
+
itemClassName = props.itemClassName,
|
|
40
|
+
_onMouseEnter = props.onMouseEnter,
|
|
41
|
+
_onMouseLeave = props.onMouseLeave,
|
|
42
|
+
_onFocus = props.onFocus,
|
|
43
|
+
_onBlur = props.onBlur,
|
|
44
|
+
_onTouchStart = props.onTouchStart,
|
|
45
|
+
_onTouchEnd = props.onTouchEnd,
|
|
46
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
47
|
+
var reducedMotion = useReducedMotion();
|
|
18
48
|
var _React$useState = React.useState(0),
|
|
19
49
|
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
20
50
|
currentIndex = _React$useState2[0],
|
|
21
51
|
setCurrentIndex = _React$useState2[1];
|
|
22
52
|
var _React$useState3 = React.useState(false),
|
|
23
53
|
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var
|
|
54
|
+
hovered = _React$useState4[0],
|
|
55
|
+
setHovered = _React$useState4[1];
|
|
56
|
+
var _React$useState5 = React.useState(false),
|
|
57
|
+
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
|
58
|
+
focusWithin = _React$useState6[0],
|
|
59
|
+
setFocusWithin = _React$useState6[1];
|
|
60
|
+
var _React$useState7 = React.useState(false),
|
|
61
|
+
_React$useState8 = _slicedToArray(_React$useState7, 2),
|
|
62
|
+
touching = _React$useState8[0],
|
|
63
|
+
setTouching = _React$useState8[1];
|
|
64
|
+
var trackRef = React.useRef(null);
|
|
65
|
+
var slideRefs = React.useRef([]);
|
|
66
|
+
var indexRef = useLatestRef(currentIndex);
|
|
67
|
+
var childrenArray = React.Children.toArray(children);
|
|
68
|
+
var count = childrenArray.length;
|
|
69
|
+
var goTo = React.useCallback(function (index) {
|
|
70
|
+
if (count === 0) return;
|
|
71
|
+
var target = (index % count + count) % count;
|
|
72
|
+
indexRef.current = target;
|
|
73
|
+
setCurrentIndex(target);
|
|
74
|
+
scrollTrackTo(trackRef.current, slideRefs.current[target], reducedMotion ? "auto" : "smooth");
|
|
75
|
+
}, [count, reducedMotion, indexRef]);
|
|
27
76
|
var next = React.useCallback(function () {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
}, [children]);
|
|
77
|
+
return goTo(indexRef.current + 1);
|
|
78
|
+
}, [goTo, indexRef]);
|
|
32
79
|
var prev = React.useCallback(function () {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
80
|
+
return goTo(indexRef.current - 1);
|
|
81
|
+
}, [goTo, indexRef]);
|
|
82
|
+
// Swipes / native scrolling move the track without going through goTo(), so the
|
|
83
|
+
// active slide is whichever one is mostly in view.
|
|
84
|
+
React.useEffect(function () {
|
|
85
|
+
var track = trackRef.current;
|
|
86
|
+
if (!track || typeof IntersectionObserver === "undefined") return undefined;
|
|
87
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
88
|
+
entries.forEach(function (entry) {
|
|
89
|
+
if (entry.isIntersecting && entry.intersectionRatio >= 0.6) {
|
|
90
|
+
var index = Number(entry.target.getAttribute("data-index"));
|
|
91
|
+
if (!Number.isNaN(index)) setCurrentIndex(index);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}, {
|
|
95
|
+
root: track,
|
|
96
|
+
threshold: [0.6]
|
|
36
97
|
});
|
|
37
|
-
|
|
98
|
+
slideRefs.current.slice(0, count).forEach(function (slide) {
|
|
99
|
+
return slide && observer.observe(slide);
|
|
100
|
+
});
|
|
101
|
+
return function () {
|
|
102
|
+
return observer.disconnect();
|
|
103
|
+
};
|
|
104
|
+
}, [count]);
|
|
105
|
+
var isPaused = hovered || focusWithin || touching;
|
|
106
|
+
var isAutoPlaying = autoPlay && !reducedMotion && !isPaused && count > 1;
|
|
38
107
|
React.useEffect(function () {
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
}
|
|
108
|
+
if (!isAutoPlaying) return undefined;
|
|
109
|
+
var timer = setInterval(next, interval);
|
|
42
110
|
return function () {
|
|
43
|
-
|
|
111
|
+
return clearInterval(timer);
|
|
44
112
|
};
|
|
45
|
-
}, [
|
|
46
|
-
|
|
47
|
-
return jsxs("div", {
|
|
113
|
+
}, [isAutoPlaying, next, interval]);
|
|
114
|
+
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
48
115
|
ref: ref,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
116
|
+
role: "region",
|
|
117
|
+
"aria-roledescription": "carousel",
|
|
118
|
+
"aria-label": "Carousel",
|
|
119
|
+
className: cn("relative overflow-hidden rounded-xl bg-surface border border-line shadow-sm", className),
|
|
120
|
+
onMouseEnter: function onMouseEnter(e) {
|
|
121
|
+
setHovered(true);
|
|
122
|
+
_onMouseEnter === null || _onMouseEnter === void 0 || _onMouseEnter(e);
|
|
123
|
+
},
|
|
124
|
+
onMouseLeave: function onMouseLeave(e) {
|
|
125
|
+
setHovered(false);
|
|
126
|
+
_onMouseLeave === null || _onMouseLeave === void 0 || _onMouseLeave(e);
|
|
127
|
+
},
|
|
128
|
+
onFocus: function onFocus(e) {
|
|
129
|
+
setFocusWithin(true);
|
|
130
|
+
_onFocus === null || _onFocus === void 0 || _onFocus(e);
|
|
131
|
+
},
|
|
132
|
+
onBlur: function onBlur(e) {
|
|
133
|
+
if (!e.currentTarget.contains(e.relatedTarget)) setFocusWithin(false);
|
|
134
|
+
_onBlur === null || _onBlur === void 0 || _onBlur(e);
|
|
52
135
|
},
|
|
53
|
-
|
|
54
|
-
|
|
136
|
+
onTouchStart: function onTouchStart(e) {
|
|
137
|
+
setTouching(true);
|
|
138
|
+
_onTouchStart === null || _onTouchStart === void 0 || _onTouchStart(e);
|
|
55
139
|
},
|
|
140
|
+
onTouchEnd: function onTouchEnd(e) {
|
|
141
|
+
setTouching(false);
|
|
142
|
+
_onTouchEnd === null || _onTouchEnd === void 0 || _onTouchEnd(e);
|
|
143
|
+
},
|
|
144
|
+
onTouchCancel: function onTouchCancel() {
|
|
145
|
+
return setTouching(false);
|
|
146
|
+
}
|
|
147
|
+
}, rest), {}, {
|
|
56
148
|
children: [jsx("div", {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
149
|
+
ref: trackRef,
|
|
150
|
+
className: TRACK_CLASSES,
|
|
151
|
+
tabIndex: 0,
|
|
152
|
+
"aria-label": "Slides",
|
|
153
|
+
"data-carousel-track": "",
|
|
154
|
+
onKeyDown: function onKeyDown(e) {
|
|
155
|
+
if (e.key === "ArrowRight") {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
next();
|
|
158
|
+
} else if (e.key === "ArrowLeft") {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
prev();
|
|
161
|
+
}
|
|
60
162
|
},
|
|
61
163
|
children: childrenArray.map(function (child, index) {
|
|
62
164
|
return jsx("div", {
|
|
63
|
-
|
|
165
|
+
ref: function ref(node) {
|
|
166
|
+
slideRefs.current[index] = node;
|
|
167
|
+
},
|
|
168
|
+
"data-index": index,
|
|
169
|
+
role: "group",
|
|
170
|
+
"aria-roledescription": "slide",
|
|
171
|
+
"aria-label": "".concat(index + 1, " of ").concat(count),
|
|
172
|
+
className: cn("w-full flex-shrink-0 min-w-full snap-start snap-always", itemClassName),
|
|
64
173
|
children: child
|
|
65
174
|
}, index);
|
|
66
175
|
})
|
|
176
|
+
}), jsx("div", {
|
|
177
|
+
className: "sr-only",
|
|
178
|
+
"aria-live": isAutoPlaying ? "off" : "polite",
|
|
179
|
+
"aria-atomic": "true",
|
|
180
|
+
"data-carousel-status": "",
|
|
181
|
+
children: count > 0 ? "Slide ".concat(currentIndex + 1, " of ").concat(count) : ""
|
|
67
182
|
}), jsx("button", {
|
|
183
|
+
type: "button",
|
|
68
184
|
onClick: prev,
|
|
69
|
-
className: "
|
|
185
|
+
className: cn(ARROW_CLASSES, TOUCH_TARGET, "left-4"),
|
|
70
186
|
"aria-label": "Previous slide",
|
|
71
187
|
children: jsx(ChevronLeft, {
|
|
72
|
-
className: "w-5 h-5
|
|
188
|
+
className: "w-5 h-5",
|
|
189
|
+
"aria-hidden": "true"
|
|
73
190
|
})
|
|
74
191
|
}), jsx("button", {
|
|
192
|
+
type: "button",
|
|
75
193
|
onClick: next,
|
|
76
|
-
className: "
|
|
194
|
+
className: cn(ARROW_CLASSES, TOUCH_TARGET, "right-4"),
|
|
77
195
|
"aria-label": "Next slide",
|
|
78
196
|
children: jsx(ChevronRight, {
|
|
79
|
-
className: "w-5 h-5
|
|
197
|
+
className: "w-5 h-5",
|
|
198
|
+
"aria-hidden": "true"
|
|
80
199
|
})
|
|
81
200
|
}), showDots && jsx("div", {
|
|
82
|
-
className: "absolute bottom-
|
|
201
|
+
className: "absolute bottom-1 left-1/2 -translate-x-1/2 flex z-10",
|
|
83
202
|
children: childrenArray.map(function (_, index) {
|
|
203
|
+
var active = currentIndex === index;
|
|
84
204
|
return jsx("button", {
|
|
205
|
+
type: "button",
|
|
85
206
|
onClick: function onClick() {
|
|
86
|
-
return
|
|
207
|
+
return goTo(index);
|
|
87
208
|
},
|
|
88
|
-
className: cn("
|
|
89
|
-
"aria-label": "Go to slide ".concat(index + 1)
|
|
209
|
+
className: cn("group inline-flex h-11 min-w-11 items-center justify-center rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-inset", PRESS_FEEDBACK),
|
|
210
|
+
"aria-label": "Go to slide ".concat(index + 1),
|
|
211
|
+
"aria-current": active ? "true" : undefined,
|
|
212
|
+
children: jsx("span", {
|
|
213
|
+
"aria-hidden": "true",
|
|
214
|
+
"data-carousel-dot": "",
|
|
215
|
+
className: cn("block h-2 rounded-full transition-all duration-base ease-standard motion-reduce:transition-none", active ? "bg-primary-600 w-6" : "w-2 bg-muted/40 group-hover:bg-muted/70")
|
|
216
|
+
})
|
|
90
217
|
}, index);
|
|
91
218
|
})
|
|
92
219
|
})]
|
|
93
|
-
});
|
|
220
|
+
}));
|
|
94
221
|
});
|
|
95
222
|
Carousel.displayName = "Carousel";
|
|
96
223
|
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import React, { useState, useRef, useCallback } from 'react';
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
|
-
import { Upload, X, Image, FileText, File } from 'lucide-react';
|
|
6
|
+
import { Upload, Camera, X, Image, FileText, File } from 'lucide-react';
|
|
7
|
+
import { useMediaQuery } from '../../hooks/useMediaQuery.js';
|
|
8
|
+
import { PRESS_FEEDBACK, TOUCH_TARGET } from '../../utils/touchTarget.js';
|
|
7
9
|
|
|
8
|
-
var _excluded = ["accept", "multiple", "maxSize", "onFileSelect", "onFileRemove", "files", "disabled", "className"];
|
|
10
|
+
var _excluded = ["accept", "multiple", "maxSize", "onFileSelect", "onFileRemove", "files", "disabled", "capture", "className"];
|
|
11
|
+
var COARSE_POINTER_QUERY = '(pointer: coarse)';
|
|
12
|
+
// PRESS_FEEDBACK sets transition-transform; this keeps the colour transition as well.
|
|
13
|
+
var TRANSITION_WITH_PRESS = 'transition-[color,background-color,border-color,transform]';
|
|
14
|
+
var PICK_BUTTON_CLASSES = 'inline-flex min-h-11 items-center justify-center gap-2 rounded-control border border-line bg-surface px-4 text-sm font-medium text-foreground shadow-xs transition-colors duration-fast hover:bg-background disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-gray-900';
|
|
9
15
|
function formatFileSize(bytes) {
|
|
10
16
|
if (bytes === 0) return '0 Bytes';
|
|
11
17
|
var k = 1024;
|
|
@@ -24,6 +30,7 @@ var FileUpload = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
24
30
|
files = _ref$files === void 0 ? [] : _ref$files,
|
|
25
31
|
_ref$disabled = _ref.disabled,
|
|
26
32
|
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
33
|
+
capture = _ref.capture,
|
|
27
34
|
className = _ref.className,
|
|
28
35
|
props = _objectWithoutProperties(_ref, _excluded);
|
|
29
36
|
var _useState = useState(false),
|
|
@@ -35,6 +42,9 @@ var FileUpload = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
35
42
|
error = _useState4[0],
|
|
36
43
|
setError = _useState4[1];
|
|
37
44
|
var fileInputRef = useRef(null);
|
|
45
|
+
var cameraInputRef = useRef(null);
|
|
46
|
+
// Touch screens have no drag and drop; show explicit pick buttons instead.
|
|
47
|
+
var isCoarse = useMediaQuery(COARSE_POINTER_QUERY);
|
|
38
48
|
var validateFile = useCallback(function (file) {
|
|
39
49
|
if (maxSize && file.size > maxSize) {
|
|
40
50
|
setError("File size must be less than ".concat(formatFileSize(maxSize)));
|
|
@@ -97,20 +107,42 @@ var FileUpload = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
97
107
|
(_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 || _fileInputRef$current.click();
|
|
98
108
|
}
|
|
99
109
|
};
|
|
110
|
+
var openCamera = function openCamera() {
|
|
111
|
+
if (!disabled) {
|
|
112
|
+
var _cameraInputRef$curre;
|
|
113
|
+
(_cameraInputRef$curre = cameraInputRef.current) === null || _cameraInputRef$curre === void 0 || _cameraInputRef$curre.click();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var handleZoneKeyDown = function handleZoneKeyDown(e) {
|
|
117
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
openFileDialog();
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var hint = jsxs("p", {
|
|
123
|
+
className: "text-xs text-primary-500 dark:text-primary-300 mt-1",
|
|
124
|
+
children: [accept && "Accepted formats: ".concat(accept), maxSize && " \u2022 Max size: ".concat(formatFileSize(maxSize))]
|
|
125
|
+
});
|
|
100
126
|
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
101
127
|
ref: ref,
|
|
102
128
|
className: cn('w-full', className)
|
|
103
129
|
}, props), {}, {
|
|
104
130
|
children: [jsxs("div", {
|
|
105
|
-
className: cn('relative border-2 border-dashed rounded-lg p-6 text-center transition-colors
|
|
106
|
-
'
|
|
107
|
-
'border-
|
|
108
|
-
'border-gray-
|
|
131
|
+
className: cn('relative border-2 border-dashed rounded-lg p-6 text-center transition-colors duration-base motion-reduce:transition-none', {
|
|
132
|
+
'cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-gray-900': !isCoarse && !disabled,
|
|
133
|
+
'border-primary-500 bg-primary-50 dark:bg-primary-900/20': isDragOver && !disabled,
|
|
134
|
+
'border-gray-300 hover:border-gray-400 dark:border-gray-600 dark:hover:border-gray-500': !isDragOver && !disabled,
|
|
135
|
+
'border-gray-200 bg-gray-50 cursor-not-allowed dark:border-gray-700 dark:bg-gray-800/50': disabled
|
|
109
136
|
}),
|
|
110
137
|
onDrop: handleDrop,
|
|
111
138
|
onDragOver: handleDragOver,
|
|
112
139
|
onDragLeave: handleDragLeave,
|
|
113
|
-
onClick: openFileDialog,
|
|
140
|
+
onClick: isCoarse ? undefined : openFileDialog,
|
|
141
|
+
onKeyDown: isCoarse ? undefined : handleZoneKeyDown,
|
|
142
|
+
role: isCoarse ? undefined : 'button',
|
|
143
|
+
tabIndex: isCoarse || disabled ? undefined : 0,
|
|
144
|
+
"aria-disabled": !isCoarse && disabled ? true : undefined,
|
|
145
|
+
"data-coarse": isCoarse || undefined,
|
|
114
146
|
children: [jsx("input", {
|
|
115
147
|
ref: fileInputRef,
|
|
116
148
|
type: "file",
|
|
@@ -118,53 +150,96 @@ var FileUpload = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
118
150
|
multiple: multiple,
|
|
119
151
|
onChange: handleFileInputChange,
|
|
120
152
|
className: "hidden",
|
|
121
|
-
disabled: disabled
|
|
153
|
+
disabled: disabled,
|
|
154
|
+
tabIndex: -1
|
|
155
|
+
}), capture && jsx("input", {
|
|
156
|
+
ref: cameraInputRef,
|
|
157
|
+
type: "file",
|
|
158
|
+
accept: accept || 'image/*',
|
|
159
|
+
capture: capture,
|
|
160
|
+
onChange: handleFileInputChange,
|
|
161
|
+
className: "hidden",
|
|
162
|
+
disabled: disabled,
|
|
163
|
+
tabIndex: -1,
|
|
164
|
+
"data-capture-input": ""
|
|
122
165
|
}), jsx(Upload, {
|
|
123
166
|
className: cn('mx-auto h-12 w-12', {
|
|
124
167
|
'text-primary-500': !disabled,
|
|
125
168
|
'text-primary-400': disabled
|
|
126
|
-
})
|
|
127
|
-
|
|
169
|
+
}),
|
|
170
|
+
"aria-hidden": "true"
|
|
171
|
+
}), jsx("div", {
|
|
128
172
|
className: "mt-4",
|
|
129
|
-
children:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
173
|
+
children: isCoarse ? jsxs(Fragment, {
|
|
174
|
+
children: [jsxs("div", {
|
|
175
|
+
className: "flex flex-col items-stretch gap-2 sm:flex-row sm:justify-center",
|
|
176
|
+
children: [jsxs("button", {
|
|
177
|
+
type: "button",
|
|
178
|
+
className: cn(PICK_BUTTON_CLASSES, PRESS_FEEDBACK, TRANSITION_WITH_PRESS),
|
|
179
|
+
onClick: openFileDialog,
|
|
180
|
+
disabled: disabled,
|
|
181
|
+
children: [jsx(Upload, {
|
|
182
|
+
className: "h-4 w-4",
|
|
183
|
+
"aria-hidden": "true"
|
|
184
|
+
}), multiple ? 'Choose files' : 'Choose file']
|
|
185
|
+
}), capture && jsxs("button", {
|
|
186
|
+
type: "button",
|
|
187
|
+
className: cn(PICK_BUTTON_CLASSES, PRESS_FEEDBACK, TRANSITION_WITH_PRESS),
|
|
188
|
+
onClick: openCamera,
|
|
189
|
+
disabled: disabled,
|
|
190
|
+
children: [jsx(Camera, {
|
|
191
|
+
className: "h-4 w-4",
|
|
192
|
+
"aria-hidden": "true"
|
|
193
|
+
}), "Take photo"]
|
|
194
|
+
})]
|
|
195
|
+
}), hint]
|
|
196
|
+
}) : jsxs(Fragment, {
|
|
197
|
+
children: [jsx("p", {
|
|
198
|
+
className: cn('text-sm font-medium', {
|
|
199
|
+
'text-primary-900 dark:text-primary-100': !disabled,
|
|
200
|
+
'text-primary-500': disabled
|
|
201
|
+
}),
|
|
202
|
+
children: isDragOver ? 'Drop files here' : 'Click to upload or drag and drop'
|
|
203
|
+
}), hint]
|
|
204
|
+
})
|
|
139
205
|
})]
|
|
140
206
|
}), error && jsx("p", {
|
|
141
|
-
|
|
207
|
+
role: "alert",
|
|
208
|
+
className: "mt-2 text-sm text-error-600 dark:text-error-400",
|
|
142
209
|
children: error
|
|
143
|
-
}), files.length > 0 && jsx("
|
|
210
|
+
}), files.length > 0 && jsx("ul", {
|
|
144
211
|
className: "mt-4 space-y-2",
|
|
212
|
+
"aria-label": "Selected files",
|
|
145
213
|
children: files.map(function (file, index) {
|
|
146
|
-
return jsxs("
|
|
147
|
-
className: "flex items-center justify-between rounded-md border border-
|
|
214
|
+
return jsxs("li", {
|
|
215
|
+
className: "flex items-center justify-between gap-3 rounded-md border border-line bg-surface p-3",
|
|
148
216
|
children: [jsxs("div", {
|
|
149
|
-
className: "flex items-center space-x-3",
|
|
150
|
-
children: [
|
|
217
|
+
className: "flex min-w-0 items-center space-x-3",
|
|
218
|
+
children: [jsx("span", {
|
|
219
|
+
className: "shrink-0",
|
|
220
|
+
"aria-hidden": "true",
|
|
221
|
+
children: getFileIcon(file)
|
|
222
|
+
}), jsxs("div", {
|
|
223
|
+
className: "min-w-0",
|
|
151
224
|
children: [jsx("p", {
|
|
152
|
-
className: "text-sm font-medium text-
|
|
225
|
+
className: "truncate text-sm font-medium text-foreground",
|
|
153
226
|
children: file.name
|
|
154
227
|
}), jsx("p", {
|
|
155
|
-
className: "text-xs text-
|
|
228
|
+
className: "text-xs text-muted",
|
|
156
229
|
children: formatFileSize(file.size)
|
|
157
230
|
})]
|
|
158
231
|
})]
|
|
159
232
|
}), jsx("button", {
|
|
160
233
|
type: "button",
|
|
161
|
-
|
|
234
|
+
"aria-label": "Remove ".concat(file.name),
|
|
235
|
+
className: cn('inline-flex shrink-0 items-center justify-center rounded-md p-1 text-muted transition-colors duration-fast hover:text-foreground hover:bg-background disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500', TOUCH_TARGET, PRESS_FEEDBACK, TRANSITION_WITH_PRESS),
|
|
162
236
|
onClick: function onClick() {
|
|
163
237
|
return handleRemoveFile(index);
|
|
164
238
|
},
|
|
165
239
|
disabled: disabled,
|
|
166
240
|
children: jsx(X, {
|
|
167
|
-
className: "h-4 w-4"
|
|
241
|
+
className: "h-4 w-4",
|
|
242
|
+
"aria-hidden": "true"
|
|
168
243
|
})
|
|
169
244
|
})]
|
|
170
245
|
}, index);
|