@dreamtree-org/twreact-ui 1.3.0 → 1.3.1
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 +179 -10
- package/ai-skills/dreamtree-ui.md +71 -12
- package/dist/ai-schema.json +452 -17
- 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/DateRangePicker.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/LocationPicker.d.ts.map +1 -1
- package/dist/components/core/Popover.d.ts +4 -0
- package/dist/components/core/Popover.d.ts.map +1 -0
- 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/Select.d.ts.map +1 -1
- package/dist/components/core/Skeleton.d.ts.map +1 -1
- package/dist/components/core/Slider.d.ts +4 -0
- package/dist/components/core/Slider.d.ts.map +1 -0
- 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/ActionMenu.d.ts.map +1 -1
- package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
- package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
- package/dist/components/core/Table/MobileCard.d.ts +2 -2
- package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
- package/dist/components/core/Table/Table.d.ts.map +1 -1
- package/dist/components/core/Table/TableRow.d.ts +4 -2
- package/dist/components/core/Table/TableRow.d.ts.map +1 -1
- package/dist/components/core/Tabs.d.ts.map +1 -1
- package/dist/components/core/Textarea.d.ts +4 -0
- package/dist/components/core/Textarea.d.ts.map +1 -0
- package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
- package/dist/components/core/Tooltip.d.ts.map +1 -1
- package/dist/components/feedback/Dialog.d.ts.map +1 -1
- package/dist/components/feedback/Drawer.d.ts +4 -0
- package/dist/components/feedback/Drawer.d.ts.map +1 -0
- package/dist/components/feedback/Toast.d.ts +14 -5
- package/dist/components/feedback/Toast.d.ts.map +1 -1
- package/dist/components/feedback/Tour.d.ts +4 -0
- package/dist/components/feedback/Tour.d.ts.map +1 -0
- package/dist/components/feedback/TourSpotlight.d.ts +9 -0
- package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
- package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/FootNav.d.ts.map +1 -1
- package/dist/components/navigation/Navbar.d.ts.map +1 -1
- package/dist/components/navigation/Sidebar.d.ts +8 -2
- package/dist/components/navigation/Sidebar.d.ts.map +1 -1
- package/dist/components/utility/Badge.d.ts.map +1 -1
- package/dist/components/utility/FileUpload.d.ts.map +1 -1
- package/dist/components/utility/Sortable.d.ts +4 -0
- package/dist/components/utility/Sortable.d.ts.map +1 -0
- package/dist/esm/_vendor/object-assign/index.js +99 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
- package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
- package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
- package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
- package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
- package/dist/esm/_vendor/prop-types/index.js +30 -0
- package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
- package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
- package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
- package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
- package/dist/esm/_virtual/index.js +3 -0
- package/dist/esm/_virtual/index2.js +3 -0
- package/dist/esm/_virtual/react-is.development.js +3 -0
- package/dist/esm/_virtual/react-is.production.min.js +3 -0
- package/dist/esm/components/blocks/AppShell.js +205 -0
- package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
- package/dist/esm/components/blocks/EmptyState.js +44 -0
- package/dist/esm/components/blocks/ErrorState.js +53 -0
- package/dist/esm/components/blocks/LoadingState.js +134 -0
- package/dist/esm/components/blocks/PageHeader.js +51 -0
- package/dist/esm/components/blocks/StatCard.js +79 -0
- package/dist/esm/components/blocks/StatusPill.js +55 -0
- package/dist/esm/components/core/Accordion.js +260 -0
- package/dist/esm/components/core/Button.js +59 -0
- package/dist/esm/components/core/Checkbox.js +188 -0
- package/dist/esm/components/core/ColorPicker.js +348 -0
- package/dist/esm/components/core/DatePicker.js +436 -0
- package/dist/esm/components/core/DateRangePicker.js +494 -0
- package/dist/esm/components/core/Form.js +522 -0
- package/dist/esm/components/core/Input.js +179 -0
- package/dist/esm/components/core/Loader.js +141 -0
- package/dist/esm/components/core/LocationPicker.js +161 -0
- package/dist/esm/components/core/Popover.js +171 -0
- package/dist/esm/components/core/PriceRangePicker.js +376 -0
- package/dist/esm/components/core/ProgressBar.js +152 -0
- package/dist/esm/components/core/Radio.js +156 -0
- package/dist/esm/components/core/Rate.js +197 -0
- package/dist/esm/components/core/RoundedTag.js +118 -0
- package/dist/esm/components/core/Select.js +857 -0
- package/dist/esm/components/core/Skeleton.js +100 -0
- package/dist/esm/components/core/Slider.js +134 -0
- package/dist/esm/components/core/SpeechToText.js +226 -0
- package/dist/esm/components/core/Switch.js +207 -0
- package/dist/esm/components/core/Table/ActionMenu.js +251 -0
- package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
- package/dist/esm/components/core/Table/FieldInput.js +157 -0
- package/dist/esm/components/core/Table/MobileCard.js +187 -0
- package/dist/esm/components/core/Table/MobileFilters.js +72 -0
- package/dist/esm/components/core/Table/Pagination.js +157 -0
- package/dist/esm/components/core/Table/Table.js +1533 -0
- package/dist/esm/components/core/Table/TableRow.js +254 -0
- package/dist/esm/components/core/Table/constants.js +35 -0
- package/dist/esm/components/core/Table/helpers.js +124 -0
- package/dist/esm/components/core/Table/useClickOutside.js +26 -0
- package/dist/esm/components/core/Tabs.js +289 -0
- package/dist/esm/components/core/TextToSpeech.js +52 -0
- package/dist/esm/components/core/Textarea.js +125 -0
- package/dist/esm/components/core/ThreeDotPopover.js +160 -0
- package/dist/esm/components/core/Tooltip.js +372 -0
- package/dist/esm/components/feedback/Alert.js +96 -0
- package/dist/esm/components/feedback/Dialog.js +200 -0
- package/dist/esm/components/feedback/Drawer.js +171 -0
- package/dist/esm/components/feedback/Toast.js +362 -0
- package/dist/esm/components/feedback/Tour.js +214 -0
- package/dist/esm/components/feedback/TourSpotlight.js +71 -0
- package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
- package/dist/esm/components/navigation/Dropdown.js +53 -0
- package/dist/esm/components/navigation/FootNav.js +51 -0
- package/dist/esm/components/navigation/Navbar.js +437 -0
- package/dist/esm/components/navigation/Sidebar.js +567 -0
- package/dist/esm/components/utility/Avatar.js +89 -0
- package/dist/esm/components/utility/Badge.js +47 -0
- package/dist/esm/components/utility/Card.js +85 -0
- package/dist/esm/components/utility/Carousel.js +97 -0
- package/dist/esm/components/utility/Condition.js +9 -0
- package/dist/esm/components/utility/FileUpload.js +177 -0
- package/dist/esm/components/utility/Pagination.js +111 -0
- package/dist/esm/components/utility/Sortable.js +190 -0
- package/dist/esm/components/utility/Stepper.js +101 -0
- package/dist/esm/hooks/useApi.js +169 -0
- package/dist/esm/hooks/useControllableState.js +32 -0
- package/dist/esm/hooks/useFocusTrap.js +85 -0
- package/dist/esm/hooks/useLatestRef.js +20 -0
- package/dist/esm/hooks/useMixins.js +100 -0
- package/dist/esm/hooks/useScrollLock.js +26 -0
- package/dist/esm/hooks/useSliderValues.js +135 -0
- package/dist/esm/hooks/useSortable.js +188 -0
- package/dist/esm/hooks/useTheme.js +53 -0
- package/dist/esm/hooks/useTourTarget.js +92 -0
- package/dist/esm/index.js +65 -0
- package/dist/esm/store/index.js +26 -0
- package/dist/esm/store/store.js +107 -0
- package/dist/esm/store/storeSlice.js +45 -0
- package/dist/esm/utils/cn.js +11 -0
- package/dist/esm/utils/emitter.js +169 -0
- package/dist/esm/utils/helpers.js +161 -0
- package/dist/esm/utils/position.js +134 -0
- package/dist/hooks/useApi.d.ts +2 -1
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useControllableState.d.ts +11 -0
- package/dist/hooks/useControllableState.d.ts.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +15 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/hooks/useLatestRef.d.ts +8 -0
- package/dist/hooks/useLatestRef.d.ts.map +1 -0
- package/dist/hooks/useMixins.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.d.ts +2 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -0
- package/dist/hooks/useSliderValues.d.ts +43 -0
- package/dist/hooks/useSliderValues.d.ts.map +1 -0
- package/dist/hooks/useSortable.d.ts +32 -0
- package/dist/hooks/useSortable.d.ts.map +1 -0
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useTourTarget.d.ts +15 -0
- package/dist/hooks/useTourTarget.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +4800 -2212
- package/dist/index.js +4805 -2210
- package/dist/types/index.d.ts +193 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/position.d.ts +30 -0
- package/dist/utils/position.d.ts.map +1 -0
- package/doc/README.md +7 -1
- package/mcp/catalog.snapshot.json +911 -212
- package/package.json +14 -2
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useId, useRef, useCallback, useState } from 'react';
|
|
5
|
+
import { Search, EyeOff, Eye, X } from 'lucide-react';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
|
|
8
|
+
var _excluded = ["id", "className", "type", "label", "placeholder", "error", "success", "helperText", "disabled", "required", "clearable", "icon", "iconPosition", "onClear", "showCount", "maxLength", "readOnly", "onChange", "value", "defaultValue"];
|
|
9
|
+
var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
|
|
10
|
+
var id = props.id,
|
|
11
|
+
className = props.className,
|
|
12
|
+
_props$type = props.type,
|
|
13
|
+
type = _props$type === void 0 ? "text" : _props$type,
|
|
14
|
+
label = props.label,
|
|
15
|
+
placeholder = props.placeholder,
|
|
16
|
+
error = props.error,
|
|
17
|
+
success = props.success,
|
|
18
|
+
helperText = props.helperText,
|
|
19
|
+
_props$disabled = props.disabled,
|
|
20
|
+
disabled = _props$disabled === void 0 ? false : _props$disabled,
|
|
21
|
+
_props$required = props.required,
|
|
22
|
+
required = _props$required === void 0 ? false : _props$required,
|
|
23
|
+
_props$clearable = props.clearable,
|
|
24
|
+
clearable = _props$clearable === void 0 ? false : _props$clearable,
|
|
25
|
+
icon = props.icon,
|
|
26
|
+
_props$iconPosition = props.iconPosition,
|
|
27
|
+
iconPosition = _props$iconPosition === void 0 ? "left" : _props$iconPosition,
|
|
28
|
+
onClear = props.onClear,
|
|
29
|
+
_props$showCount = props.showCount,
|
|
30
|
+
showCount = _props$showCount === void 0 ? false : _props$showCount,
|
|
31
|
+
maxLength = props.maxLength,
|
|
32
|
+
_props$readOnly = props.readOnly,
|
|
33
|
+
readOnly = _props$readOnly === void 0 ? false : _props$readOnly,
|
|
34
|
+
onChange = props.onChange,
|
|
35
|
+
value = props.value,
|
|
36
|
+
defaultValue = props.defaultValue,
|
|
37
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
38
|
+
var internalId = useId();
|
|
39
|
+
var inputId = id || "input-".concat(internalId);
|
|
40
|
+
var isSearch = type === "search";
|
|
41
|
+
var isPassword = type === "password";
|
|
42
|
+
var localRef = useRef(null);
|
|
43
|
+
// Keep our own ref for imperative work (clear/focus) and forward the node
|
|
44
|
+
// to the consumer's ref, whether it is an object ref or a callback ref.
|
|
45
|
+
var setRefs = useCallback(function (node) {
|
|
46
|
+
localRef.current = node;
|
|
47
|
+
if (typeof forwardedRef === "function") forwardedRef(node);else if (forwardedRef) forwardedRef.current = node;
|
|
48
|
+
}, [forwardedRef]);
|
|
49
|
+
// track visibility (password)
|
|
50
|
+
var _useState = useState(false),
|
|
51
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
52
|
+
showPassword = _useState2[0],
|
|
53
|
+
setShowPassword = _useState2[1];
|
|
54
|
+
// value length (controlled: derived from `value`; uncontrolled: tracked on change)
|
|
55
|
+
var isControlled = typeof value !== "undefined";
|
|
56
|
+
var _useState3 = useState(function () {
|
|
57
|
+
return typeof defaultValue !== "undefined" ? String(defaultValue !== null && defaultValue !== void 0 ? defaultValue : "").length : 0;
|
|
58
|
+
}),
|
|
59
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
60
|
+
uncontrolledLength = _useState4[0],
|
|
61
|
+
setUncontrolledLength = _useState4[1];
|
|
62
|
+
var currentLength = isControlled ? String(value !== null && value !== void 0 ? value : "").length : uncontrolledLength;
|
|
63
|
+
var handleChange = function handleChange(e) {
|
|
64
|
+
var _e$target$value;
|
|
65
|
+
var val = (_e$target$value = e.target.value) !== null && _e$target$value !== void 0 ? _e$target$value : "";
|
|
66
|
+
if (!isControlled) setUncontrolledLength(val.length);
|
|
67
|
+
onChange === null || onChange === void 0 || onChange(e);
|
|
68
|
+
};
|
|
69
|
+
var handleClear = function handleClear(e) {
|
|
70
|
+
var _localRef$current, _localRef$current$foc;
|
|
71
|
+
e === null || e === void 0 || e.preventDefault();
|
|
72
|
+
if (isControlled) {
|
|
73
|
+
// controlled — notify parent
|
|
74
|
+
onChange === null || onChange === void 0 || onChange({
|
|
75
|
+
target: {
|
|
76
|
+
value: ""
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
} else if (localRef.current) {
|
|
80
|
+
localRef.current.value = "";
|
|
81
|
+
// update local state
|
|
82
|
+
setUncontrolledLength(0);
|
|
83
|
+
}
|
|
84
|
+
(_localRef$current = localRef.current) === null || _localRef$current === void 0 || (_localRef$current$foc = _localRef$current.focus) === null || _localRef$current$foc === void 0 || _localRef$current$foc.call(_localRef$current);
|
|
85
|
+
onClear === null || onClear === void 0 || onClear();
|
|
86
|
+
};
|
|
87
|
+
// padding logic: left and right padding depend on icons/buttons visible
|
|
88
|
+
var leftHasIcon = Boolean(icon && iconPosition === "left") || isSearch;
|
|
89
|
+
var rightHasIcon = Boolean(icon && iconPosition === "right") || isPassword || clearable && currentLength > 0;
|
|
90
|
+
var paddingClass = cn(leftHasIcon ? "pl-10" : "pl-3", rightHasIcon ? "pr-12" : "pr-3");
|
|
91
|
+
var baseClasses = cn("w-full rounded-md border bg-white text-sm placeholder-gray-400 disabled:opacity-50", "h-10 leading-10",
|
|
92
|
+
// consistent height
|
|
93
|
+
paddingClass, error ? "border-red-500 focus:ring-red-500" : "border-gray-300", success ? "border-green-500 focus:ring-green-500" : "", className);
|
|
94
|
+
var inputType = isPassword && showPassword ? "text" : type;
|
|
95
|
+
return jsxs("div", {
|
|
96
|
+
className: "w-full",
|
|
97
|
+
children: [label && jsxs("label", {
|
|
98
|
+
htmlFor: inputId,
|
|
99
|
+
className: "block text-sm font-medium mb-1",
|
|
100
|
+
children: [label, required && jsx("span", {
|
|
101
|
+
className: "text-error-500 ml-1",
|
|
102
|
+
children: "*"
|
|
103
|
+
})]
|
|
104
|
+
}), jsxs("div", {
|
|
105
|
+
className: "relative",
|
|
106
|
+
children: [leftHasIcon && jsx("div", {
|
|
107
|
+
className: "absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none",
|
|
108
|
+
children: isSearch ? jsx(Search, {
|
|
109
|
+
className: "h-4 w-4 text-primary-400"
|
|
110
|
+
}) : jsx("span", {
|
|
111
|
+
className: "text-primary-400",
|
|
112
|
+
children: icon
|
|
113
|
+
})
|
|
114
|
+
}), jsx("input", _objectSpread2({
|
|
115
|
+
id: inputId,
|
|
116
|
+
ref: setRefs,
|
|
117
|
+
type: inputType,
|
|
118
|
+
className: baseClasses,
|
|
119
|
+
placeholder: placeholder,
|
|
120
|
+
disabled: disabled,
|
|
121
|
+
readOnly: readOnly,
|
|
122
|
+
"aria-invalid": !!error,
|
|
123
|
+
"aria-describedby": error ? "".concat(inputId, "-error") : success ? "".concat(inputId, "-success") : helperText ? "".concat(inputId, "-helper") : undefined,
|
|
124
|
+
maxLength: maxLength,
|
|
125
|
+
onChange: handleChange,
|
|
126
|
+
value: value,
|
|
127
|
+
defaultValue: defaultValue
|
|
128
|
+
}, rest)), icon && iconPosition === "right" && !isPassword && !(clearable && currentLength > 0) && jsx("div", {
|
|
129
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none text-primary-400",
|
|
130
|
+
children: icon
|
|
131
|
+
}), isPassword && jsx("button", {
|
|
132
|
+
type: "button",
|
|
133
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-primary-500",
|
|
134
|
+
onClick: function onClick() {
|
|
135
|
+
return setShowPassword(function (s) {
|
|
136
|
+
return !s;
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
140
|
+
disabled: disabled,
|
|
141
|
+
children: showPassword ? jsx(EyeOff, {
|
|
142
|
+
className: "h-4 w-4"
|
|
143
|
+
}) : jsx(Eye, {
|
|
144
|
+
className: "h-4 w-4"
|
|
145
|
+
})
|
|
146
|
+
}), clearable && currentLength > 0 && !isPassword && jsx("button", {
|
|
147
|
+
type: "button",
|
|
148
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-primary-500",
|
|
149
|
+
onClick: handleClear,
|
|
150
|
+
"aria-label": "Clear input",
|
|
151
|
+
disabled: disabled,
|
|
152
|
+
children: jsx(X, {
|
|
153
|
+
className: "h-4 w-4"
|
|
154
|
+
})
|
|
155
|
+
})]
|
|
156
|
+
}), error && jsx("p", {
|
|
157
|
+
id: "".concat(inputId, "-error"),
|
|
158
|
+
className: "mt-1 text-sm text-error-600",
|
|
159
|
+
"aria-live": "polite",
|
|
160
|
+
children: error
|
|
161
|
+
}), !error && success && jsx("p", {
|
|
162
|
+
id: "".concat(inputId, "-success"),
|
|
163
|
+
className: "mt-1 text-sm text-success-600",
|
|
164
|
+
"aria-live": "polite",
|
|
165
|
+
children: success
|
|
166
|
+
}), !error && !success && helperText && jsx("p", {
|
|
167
|
+
id: "".concat(inputId, "-helper"),
|
|
168
|
+
className: "mt-1 text-sm text-muted",
|
|
169
|
+
children: helperText
|
|
170
|
+
}), showCount && maxLength && jsxs("div", {
|
|
171
|
+
className: "mt-1 text-right text-xs text-primary-500",
|
|
172
|
+
"aria-hidden": true,
|
|
173
|
+
children: [currentLength, "/", maxLength]
|
|
174
|
+
})]
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
Input.displayName = "Input";
|
|
178
|
+
|
|
179
|
+
export { Input as default };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
var _excluded = ["size", "speed", "thickness", "color", "secondaryColor", "variant", "className", "inline", "ariaLabel", "text", "reverse", "style"];
|
|
8
|
+
var sizeToPx = function sizeToPx(size) {
|
|
9
|
+
if (!size) return 24;
|
|
10
|
+
if (typeof size === "number") return size;
|
|
11
|
+
switch (size) {
|
|
12
|
+
case "sm":
|
|
13
|
+
return 14;
|
|
14
|
+
case "md":
|
|
15
|
+
return 20;
|
|
16
|
+
case "lg":
|
|
17
|
+
return 36;
|
|
18
|
+
default:
|
|
19
|
+
return 24;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var Loader = /*#__PURE__*/forwardRef(function Loader(_ref, ref) {
|
|
23
|
+
var _ref$size = _ref.size,
|
|
24
|
+
size = _ref$size === void 0 ? "md" : _ref$size,
|
|
25
|
+
_ref$speed = _ref.speed,
|
|
26
|
+
speed = _ref$speed === void 0 ? 0.9 : _ref$speed,
|
|
27
|
+
_ref$thickness = _ref.thickness,
|
|
28
|
+
thickness = _ref$thickness === void 0 ? 2.5 : _ref$thickness,
|
|
29
|
+
_ref$color = _ref.color,
|
|
30
|
+
color = _ref$color === void 0 ? "currentColor" : _ref$color,
|
|
31
|
+
_ref$secondaryColor = _ref.secondaryColor,
|
|
32
|
+
secondaryColor = _ref$secondaryColor === void 0 ? "rgba(0,0,0,0.08)" : _ref$secondaryColor,
|
|
33
|
+
_ref$variant = _ref.variant,
|
|
34
|
+
variant = _ref$variant === void 0 ? "spinner" : _ref$variant,
|
|
35
|
+
_ref$className = _ref.className,
|
|
36
|
+
className = _ref$className === void 0 ? "" : _ref$className,
|
|
37
|
+
_ref$inline = _ref.inline,
|
|
38
|
+
inline = _ref$inline === void 0 ? false : _ref$inline,
|
|
39
|
+
_ref$ariaLabel = _ref.ariaLabel,
|
|
40
|
+
ariaLabel = _ref$ariaLabel === void 0 ? "Loading" : _ref$ariaLabel,
|
|
41
|
+
text = _ref.text,
|
|
42
|
+
_ref$reverse = _ref.reverse,
|
|
43
|
+
reverse = _ref$reverse === void 0 ? false : _ref$reverse,
|
|
44
|
+
style = _ref.style,
|
|
45
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
46
|
+
var px = sizeToPx(size);
|
|
47
|
+
var wrapperClass = cn(inline ? "inline-flex" : "flex", "items-center gap-2", className);
|
|
48
|
+
// animation attributes for SVG rotate
|
|
49
|
+
var animDur = "".concat(speed, "s");
|
|
50
|
+
var rotateFrom = reverse ? "360 12 12" : "0 12 12";
|
|
51
|
+
var rotateTo = reverse ? "0 12 12" : "360 12 12";
|
|
52
|
+
return jsxs("div", _objectSpread2(_objectSpread2({
|
|
53
|
+
ref: ref,
|
|
54
|
+
role: "progressbar",
|
|
55
|
+
"aria-label": ariaLabel,
|
|
56
|
+
className: wrapperClass,
|
|
57
|
+
style: style
|
|
58
|
+
}, rest), {}, {
|
|
59
|
+
children: [jsx("style", {
|
|
60
|
+
children: "\n @keyframes loader-bounce {\n 0%, 80%, 100% { transform: translateY(0); opacity: 0.9 }\n 40% { transform: translateY(-6px); opacity: 1 }\n }\n @keyframes loader-bar {\n 0% { transform: translateX(-35%); }\n 100% { transform: translateX(135%); }\n }\n "
|
|
61
|
+
}), variant === "spinner" && jsxs("svg", {
|
|
62
|
+
width: px,
|
|
63
|
+
height: px,
|
|
64
|
+
viewBox: "0 0 24 24",
|
|
65
|
+
fill: "none",
|
|
66
|
+
style: {
|
|
67
|
+
display: "block"
|
|
68
|
+
},
|
|
69
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
70
|
+
children: [jsx("circle", {
|
|
71
|
+
cx: "12",
|
|
72
|
+
cy: "12",
|
|
73
|
+
r: 10 - thickness,
|
|
74
|
+
stroke: secondaryColor,
|
|
75
|
+
strokeWidth: thickness
|
|
76
|
+
}), jsx("path", {
|
|
77
|
+
d: "M22 12a10 10 0 0 0-10-10",
|
|
78
|
+
stroke: color,
|
|
79
|
+
strokeWidth: thickness,
|
|
80
|
+
strokeLinecap: "round",
|
|
81
|
+
strokeLinejoin: "round",
|
|
82
|
+
strokeDasharray: "24",
|
|
83
|
+
children: jsx("animateTransform", {
|
|
84
|
+
attributeName: "transform",
|
|
85
|
+
attributeType: "XML",
|
|
86
|
+
type: "rotate",
|
|
87
|
+
from: rotateFrom,
|
|
88
|
+
to: rotateTo,
|
|
89
|
+
dur: animDur,
|
|
90
|
+
repeatCount: "indefinite"
|
|
91
|
+
})
|
|
92
|
+
})]
|
|
93
|
+
}), variant === "dots" && jsx("div", {
|
|
94
|
+
style: {
|
|
95
|
+
display: "inline-flex",
|
|
96
|
+
alignItems: "center",
|
|
97
|
+
gap: Math.max(2, Math.round(px / 8))
|
|
98
|
+
},
|
|
99
|
+
children: [0, 1, 2].map(function (i) {
|
|
100
|
+
return jsx("span", {
|
|
101
|
+
"aria-hidden": true,
|
|
102
|
+
style: {
|
|
103
|
+
width: px / 4,
|
|
104
|
+
height: px / 4,
|
|
105
|
+
borderRadius: "9999px",
|
|
106
|
+
display: "inline-block",
|
|
107
|
+
background: color,
|
|
108
|
+
animation: "loader-bounce ".concat(speed, "s ").concat(i * (speed / 6), "s infinite ease-in-out")
|
|
109
|
+
}
|
|
110
|
+
}, i);
|
|
111
|
+
})
|
|
112
|
+
}), variant === "bar" && jsx("div", {
|
|
113
|
+
"aria-hidden": true,
|
|
114
|
+
style: {
|
|
115
|
+
width: Math.max(72, px * 2.5),
|
|
116
|
+
height: Math.max(6, px / 6),
|
|
117
|
+
background: secondaryColor,
|
|
118
|
+
overflow: "hidden",
|
|
119
|
+
borderRadius: 9999,
|
|
120
|
+
position: "relative"
|
|
121
|
+
},
|
|
122
|
+
children: jsx("div", {
|
|
123
|
+
style: {
|
|
124
|
+
position: "absolute",
|
|
125
|
+
left: 0,
|
|
126
|
+
top: 0,
|
|
127
|
+
bottom: 0,
|
|
128
|
+
width: "35%",
|
|
129
|
+
background: "linear-gradient(90deg, ".concat(color, ", ").concat(secondaryColor, ")"),
|
|
130
|
+
transform: "translateX(-35%)",
|
|
131
|
+
animation: "loader-bar ".concat(speed, "s linear infinite")
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}), text && jsx("span", {
|
|
135
|
+
className: "text-sm text-primary-500",
|
|
136
|
+
children: text
|
|
137
|
+
})]
|
|
138
|
+
}));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export { Loader as default };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import React, { forwardRef, useState, cloneElement } from 'react';
|
|
5
|
+
import { cn } from '../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
var _excluded = ["value", "onChange", "inputProps", "icon", "iconProps", "iconPosition", "placeholder", "className"];
|
|
8
|
+
function formatCoords(coords) {
|
|
9
|
+
if (!coords) return "";
|
|
10
|
+
var lat = Number(coords.lat);
|
|
11
|
+
var lng = Number(coords.lng);
|
|
12
|
+
if (!isFinite(lat) || !isFinite(lng)) return "";
|
|
13
|
+
return "".concat(lat.toFixed(6), ", ").concat(lng.toFixed(6));
|
|
14
|
+
}
|
|
15
|
+
function parseCoords(str) {
|
|
16
|
+
if (!str || typeof str !== "string") return null;
|
|
17
|
+
var parts = str.split(",").map(function (p) {
|
|
18
|
+
return p.trim();
|
|
19
|
+
}).filter(Boolean);
|
|
20
|
+
if (parts.length < 2) return null;
|
|
21
|
+
var lat = parseFloat(parts[0]);
|
|
22
|
+
var lng = parseFloat(parts[1]);
|
|
23
|
+
if (!isFinite(lat) || !isFinite(lng)) return null;
|
|
24
|
+
return {
|
|
25
|
+
lat: lat,
|
|
26
|
+
lng: lng
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
var LocationPicker = /*#__PURE__*/forwardRef(function LocationPicker(_ref, ref) {
|
|
30
|
+
var _ref$value = _ref.value,
|
|
31
|
+
value = _ref$value === void 0 ? null : _ref$value,
|
|
32
|
+
onChange = _ref.onChange,
|
|
33
|
+
_ref$inputProps = _ref.inputProps,
|
|
34
|
+
inputProps = _ref$inputProps === void 0 ? {} : _ref$inputProps,
|
|
35
|
+
_ref$icon = _ref.icon,
|
|
36
|
+
icon = _ref$icon === void 0 ? null : _ref$icon,
|
|
37
|
+
_ref$iconProps = _ref.iconProps,
|
|
38
|
+
iconProps = _ref$iconProps === void 0 ? {} : _ref$iconProps,
|
|
39
|
+
_ref$iconPosition = _ref.iconPosition,
|
|
40
|
+
iconPosition = _ref$iconPosition === void 0 ? "right" : _ref$iconPosition,
|
|
41
|
+
_ref$placeholder = _ref.placeholder,
|
|
42
|
+
placeholder = _ref$placeholder === void 0 ? "lat, lng" : _ref$placeholder,
|
|
43
|
+
className = _ref.className,
|
|
44
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
45
|
+
var _useState = useState(function () {
|
|
46
|
+
return formatCoords(value);
|
|
47
|
+
}),
|
|
48
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
49
|
+
text = _useState2[0],
|
|
50
|
+
setText = _useState2[1];
|
|
51
|
+
// Re-sync the text when the external `value` changes (adjust-during-render
|
|
52
|
+
// pattern, avoids a cascading effect render).
|
|
53
|
+
var _useState3 = useState(value),
|
|
54
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
55
|
+
prevValue = _useState4[0],
|
|
56
|
+
setPrevValue = _useState4[1];
|
|
57
|
+
if (value !== prevValue) {
|
|
58
|
+
setPrevValue(value);
|
|
59
|
+
setText(formatCoords(value));
|
|
60
|
+
}
|
|
61
|
+
var handleInputChange = function handleInputChange(e) {
|
|
62
|
+
var newText = e.target.value;
|
|
63
|
+
setText(newText);
|
|
64
|
+
if (typeof inputProps.onChange === "function") {
|
|
65
|
+
try {
|
|
66
|
+
inputProps.onChange(e);
|
|
67
|
+
} catch (_unused) {
|
|
68
|
+
// ignore errors thrown by consumer handlers
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
var parsed = parseCoords(newText);
|
|
72
|
+
if (parsed && typeof onChange === "function") onChange(parsed);else if (newText.trim() === "" && typeof onChange === "function") onChange(null);
|
|
73
|
+
};
|
|
74
|
+
var handleGeoSuccess = function handleGeoSuccess(position) {
|
|
75
|
+
var coords = {
|
|
76
|
+
lat: Number(position.coords.latitude),
|
|
77
|
+
lng: Number(position.coords.longitude)
|
|
78
|
+
};
|
|
79
|
+
setText(formatCoords(coords));
|
|
80
|
+
if (typeof onChange === "function") onChange(coords);
|
|
81
|
+
};
|
|
82
|
+
var handleGeoError = function handleGeoError(err) {
|
|
83
|
+
console.error("LocationPicker geolocation error:", err);
|
|
84
|
+
};
|
|
85
|
+
var handleIconClick = function handleIconClick(e) {
|
|
86
|
+
var _navigator;
|
|
87
|
+
if (!((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.geolocation)) {
|
|
88
|
+
console.error("LocationPicker: geolocation not supported in this browser");
|
|
89
|
+
if (typeof iconProps.onClick === "function") {
|
|
90
|
+
try {
|
|
91
|
+
iconProps.onClick(e);
|
|
92
|
+
} catch (_unused2) {
|
|
93
|
+
// ignore errors thrown by consumer handlers
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError, {
|
|
99
|
+
enableHighAccuracy: true,
|
|
100
|
+
timeout: 10000
|
|
101
|
+
});
|
|
102
|
+
if (typeof iconProps.onClick === "function") {
|
|
103
|
+
try {
|
|
104
|
+
iconProps.onClick(e);
|
|
105
|
+
} catch (_unused3) {
|
|
106
|
+
// ignore errors thrown by consumer handlers
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var DefaultIcon = jsxs("svg", {
|
|
111
|
+
className: "w-4 h-4",
|
|
112
|
+
viewBox: "0 0 24 24",
|
|
113
|
+
fill: "none",
|
|
114
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
children: [jsx("path", {
|
|
117
|
+
d: "M12 2C8.686 2 6 4.686 6 8c0 5.25 6 12 6 12s6-6.75 6-12c0-3.314-2.686-6-6-6z",
|
|
118
|
+
stroke: "currentColor",
|
|
119
|
+
strokeWidth: "1.2",
|
|
120
|
+
strokeLinecap: "round",
|
|
121
|
+
strokeLinejoin: "round"
|
|
122
|
+
}), jsx("circle", {
|
|
123
|
+
cx: "12",
|
|
124
|
+
cy: "8",
|
|
125
|
+
r: "2.2",
|
|
126
|
+
stroke: "currentColor",
|
|
127
|
+
strokeWidth: "1.2"
|
|
128
|
+
})]
|
|
129
|
+
});
|
|
130
|
+
var iconButton = jsx("button", _objectSpread2(_objectSpread2({
|
|
131
|
+
type: "button",
|
|
132
|
+
onClick: handleIconClick
|
|
133
|
+
}, iconProps), {}, {
|
|
134
|
+
"aria-label": iconProps["aria-label"] || "Use my location",
|
|
135
|
+
className: "inline-flex items-center justify-center p-1 focus:outline-none ".concat(iconProps.className || ""),
|
|
136
|
+
children: icon ? /*#__PURE__*/React.isValidElement(icon) ? /*#__PURE__*/cloneElement(icon) : icon : DefaultIcon
|
|
137
|
+
}));
|
|
138
|
+
var inputPaddingClass = iconPosition === "right" ? "pr-10" : "pl-10";
|
|
139
|
+
return jsx("div", _objectSpread2(_objectSpread2({
|
|
140
|
+
className: cn("inline-flex items-center", className)
|
|
141
|
+
}, rest), {}, {
|
|
142
|
+
children: jsxs("div", {
|
|
143
|
+
className: "relative",
|
|
144
|
+
children: [jsx("input", _objectSpread2(_objectSpread2({
|
|
145
|
+
ref: ref,
|
|
146
|
+
type: "text",
|
|
147
|
+
placeholder: placeholder
|
|
148
|
+
}, inputProps), {}, {
|
|
149
|
+
value: text,
|
|
150
|
+
onChange: handleInputChange,
|
|
151
|
+
className: cn("min-w-[200px] rounded-md border border-gray-300 bg-white py-2 px-3 text-sm placeholder-gray-400 shadow-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500", inputProps.className, inputPaddingClass)
|
|
152
|
+
})), jsx("div", {
|
|
153
|
+
className: cn("absolute inset-y-0 flex items-center", iconPosition === "right" ? "right-2" : "left-2"),
|
|
154
|
+
children: iconButton
|
|
155
|
+
})]
|
|
156
|
+
})
|
|
157
|
+
}));
|
|
158
|
+
});
|
|
159
|
+
LocationPicker.displayName = "LocationPicker";
|
|
160
|
+
|
|
161
|
+
export { LocationPicker as default };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
3
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import React, { useRef, useId, useCallback, useEffect, useLayoutEffect } from 'react';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
import { setRefs, computePosition } from '../../utils/position.js';
|
|
8
|
+
import { useFocusTrap, getFocusable } from '../../hooks/useFocusTrap.js';
|
|
9
|
+
import { useControllableState } from '../../hooks/useControllableState.js';
|
|
10
|
+
|
|
11
|
+
var _excluded = ["trigger", "children", "open", "defaultOpen", "onOpenChange", "placement", "offset", "title", "initialFocusRef", "disabled", "id", "className"];
|
|
12
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
13
|
+
function usePopoverPosition(open, anchorRef, panelRef, placement, offset) {
|
|
14
|
+
useIsomorphicLayoutEffect(function () {
|
|
15
|
+
if (!open) return undefined;
|
|
16
|
+
var update = function update() {
|
|
17
|
+
var _anchorRef$current;
|
|
18
|
+
var anchor = ((_anchorRef$current = anchorRef.current) === null || _anchorRef$current === void 0 ? void 0 : _anchorRef$current.firstElementChild) || anchorRef.current;
|
|
19
|
+
var panel = panelRef.current;
|
|
20
|
+
if (!anchor || !panel) return;
|
|
21
|
+
var size = {
|
|
22
|
+
width: panel.offsetWidth,
|
|
23
|
+
height: panel.offsetHeight
|
|
24
|
+
};
|
|
25
|
+
var _computePosition = computePosition(anchor.getBoundingClientRect(), size, {
|
|
26
|
+
placement: placement,
|
|
27
|
+
offset: offset
|
|
28
|
+
}),
|
|
29
|
+
top = _computePosition.top,
|
|
30
|
+
left = _computePosition.left,
|
|
31
|
+
side = _computePosition.side;
|
|
32
|
+
panel.style.top = "".concat(top, "px");
|
|
33
|
+
panel.style.left = "".concat(left, "px");
|
|
34
|
+
panel.setAttribute("data-side", side);
|
|
35
|
+
};
|
|
36
|
+
update();
|
|
37
|
+
window.addEventListener("resize", update);
|
|
38
|
+
window.addEventListener("scroll", update, true);
|
|
39
|
+
return function () {
|
|
40
|
+
window.removeEventListener("resize", update);
|
|
41
|
+
window.removeEventListener("scroll", update, true);
|
|
42
|
+
};
|
|
43
|
+
}, [open, placement, offset, anchorRef, panelRef]);
|
|
44
|
+
}
|
|
45
|
+
function useOutsideClose(open, anchorRef, panelRef, close) {
|
|
46
|
+
useEffect(function () {
|
|
47
|
+
if (!open) return undefined;
|
|
48
|
+
var onDown = function onDown(e) {
|
|
49
|
+
var _panelRef$current, _anchorRef$current2;
|
|
50
|
+
if ((_panelRef$current = panelRef.current) !== null && _panelRef$current !== void 0 && _panelRef$current.contains(e.target) || (_anchorRef$current2 = anchorRef.current) !== null && _anchorRef$current2 !== void 0 && _anchorRef$current2.contains(e.target)) return;
|
|
51
|
+
close();
|
|
52
|
+
};
|
|
53
|
+
document.addEventListener("mousedown", onDown);
|
|
54
|
+
document.addEventListener("touchstart", onDown);
|
|
55
|
+
return function () {
|
|
56
|
+
document.removeEventListener("mousedown", onDown);
|
|
57
|
+
document.removeEventListener("touchstart", onDown);
|
|
58
|
+
};
|
|
59
|
+
}, [open, anchorRef, panelRef, close]);
|
|
60
|
+
}
|
|
61
|
+
var Popover = /*#__PURE__*/React.forwardRef(function (_ref, _ref2) {
|
|
62
|
+
var _triggerElement$props;
|
|
63
|
+
var trigger = _ref.trigger,
|
|
64
|
+
children = _ref.children,
|
|
65
|
+
openProp = _ref.open,
|
|
66
|
+
_ref$defaultOpen = _ref.defaultOpen,
|
|
67
|
+
defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
|
|
68
|
+
onOpenChange = _ref.onOpenChange,
|
|
69
|
+
_ref$placement = _ref.placement,
|
|
70
|
+
placement = _ref$placement === void 0 ? "bottom-start" : _ref$placement,
|
|
71
|
+
_ref$offset = _ref.offset,
|
|
72
|
+
offset = _ref$offset === void 0 ? 8 : _ref$offset,
|
|
73
|
+
title = _ref.title,
|
|
74
|
+
initialFocusRef = _ref.initialFocusRef,
|
|
75
|
+
_ref$disabled = _ref.disabled,
|
|
76
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
77
|
+
idProp = _ref.id,
|
|
78
|
+
className = _ref.className,
|
|
79
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
80
|
+
var anchorRef = useRef(null);
|
|
81
|
+
var panelRef = useRef(null);
|
|
82
|
+
var reactId = useId();
|
|
83
|
+
var panelId = idProp || "popover-".concat(reactId);
|
|
84
|
+
var titleId = "".concat(panelId, "-title");
|
|
85
|
+
var _useControllableState = useControllableState({
|
|
86
|
+
value: openProp,
|
|
87
|
+
defaultValue: defaultOpen,
|
|
88
|
+
onChange: onOpenChange
|
|
89
|
+
}),
|
|
90
|
+
_useControllableState2 = _slicedToArray(_useControllableState, 2),
|
|
91
|
+
open = _useControllableState2[0],
|
|
92
|
+
setOpen = _useControllableState2[1];
|
|
93
|
+
var close = useCallback(function () {
|
|
94
|
+
return setOpen(false);
|
|
95
|
+
}, [setOpen]);
|
|
96
|
+
var focusTrigger = function focusTrigger() {
|
|
97
|
+
var _getFocusable$;
|
|
98
|
+
return (_getFocusable$ = getFocusable(anchorRef.current)[0]) === null || _getFocusable$ === void 0 ? void 0 : _getFocusable$.focus();
|
|
99
|
+
};
|
|
100
|
+
usePopoverPosition(open, anchorRef, panelRef, placement, offset);
|
|
101
|
+
useOutsideClose(open, anchorRef, panelRef, close);
|
|
102
|
+
useFocusTrap(panelRef, {
|
|
103
|
+
active: open,
|
|
104
|
+
trap: false,
|
|
105
|
+
initialFocusRef: initialFocusRef,
|
|
106
|
+
onEscape: function onEscape() {
|
|
107
|
+
close();
|
|
108
|
+
focusTrigger();
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// Non-modal: tabbing past either end leaves the popover and closes it, with
|
|
112
|
+
// focus continuing from the trigger as if the panel sat right after it.
|
|
113
|
+
var handlePanelKeyDown = function handlePanelKeyDown(e) {
|
|
114
|
+
if (e.key !== "Tab") return;
|
|
115
|
+
var items = getFocusable(panelRef.current);
|
|
116
|
+
var atStart = !items.length || document.activeElement === items[0] || document.activeElement === panelRef.current;
|
|
117
|
+
var atEnd = !items.length || document.activeElement === items[items.length - 1];
|
|
118
|
+
if (e.shiftKey && atStart) {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
close();
|
|
121
|
+
focusTrigger();
|
|
122
|
+
} else if (!e.shiftKey && atEnd) {
|
|
123
|
+
close();
|
|
124
|
+
focusTrigger();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var triggerElement = /*#__PURE__*/React.isValidElement(trigger) ? trigger : jsx("button", {
|
|
128
|
+
type: "button",
|
|
129
|
+
children: trigger
|
|
130
|
+
});
|
|
131
|
+
var triggerNode = /*#__PURE__*/React.cloneElement(triggerElement, {
|
|
132
|
+
"aria-haspopup": "dialog",
|
|
133
|
+
"aria-expanded": open,
|
|
134
|
+
"aria-controls": open ? panelId : undefined,
|
|
135
|
+
disabled: (_triggerElement$props = triggerElement.props.disabled) !== null && _triggerElement$props !== void 0 ? _triggerElement$props : disabled,
|
|
136
|
+
onClick: function onClick(e) {
|
|
137
|
+
var _triggerElement$props2, _triggerElement$props3;
|
|
138
|
+
(_triggerElement$props2 = (_triggerElement$props3 = triggerElement.props).onClick) === null || _triggerElement$props2 === void 0 || _triggerElement$props2.call(_triggerElement$props3, e);
|
|
139
|
+
if (!e.defaultPrevented && !disabled) setOpen(!open);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
var content = typeof children === "function" ? children({
|
|
143
|
+
close: close
|
|
144
|
+
}) : children;
|
|
145
|
+
return jsxs(Fragment, {
|
|
146
|
+
children: [jsx("span", {
|
|
147
|
+
ref: anchorRef,
|
|
148
|
+
className: "inline-flex",
|
|
149
|
+
children: triggerNode
|
|
150
|
+
}), open && typeof document !== "undefined" && /*#__PURE__*/createPortal(jsxs("div", _objectSpread2(_objectSpread2({
|
|
151
|
+
ref: function ref(node) {
|
|
152
|
+
return setRefs(node, panelRef, _ref2);
|
|
153
|
+
},
|
|
154
|
+
id: panelId,
|
|
155
|
+
role: "dialog",
|
|
156
|
+
"aria-labelledby": title ? titleId : undefined,
|
|
157
|
+
tabIndex: -1,
|
|
158
|
+
onKeyDown: handlePanelKeyDown,
|
|
159
|
+
className: cn("fixed left-0 top-0 z-50 min-w-[12rem] max-w-sm rounded-lg border border-gray-200 bg-white p-4 text-sm text-gray-900 shadow-lg focus:outline-none", "dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100", "animate-fade-in motion-reduce:animate-none", className)
|
|
160
|
+
}, props), {}, {
|
|
161
|
+
children: [title && jsx("h2", {
|
|
162
|
+
id: titleId,
|
|
163
|
+
className: "mb-2 text-sm font-semibold",
|
|
164
|
+
children: title
|
|
165
|
+
}), content]
|
|
166
|
+
})), document.body)]
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
Popover.displayName = "Popover";
|
|
170
|
+
|
|
171
|
+
export { Popover as default };
|