@sytechui/input 2.4.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ export { default as Input, InputProps } from './input.mjs';
2
+ export { TextAreaProps, default as Textarea } from './textarea.mjs';
3
+ export { useInput } from './use-input.mjs';
4
+ import '@sytechui/system';
5
+ import 'react';
6
+ import '@sytechui/theme';
7
+ import '@react-types/textfield';
@@ -0,0 +1,7 @@
1
+ export { default as Input, InputProps } from './input.js';
2
+ export { TextAreaProps, default as Textarea } from './textarea.js';
3
+ export { useInput } from './use-input.js';
4
+ import '@sytechui/system';
5
+ import 'react';
6
+ import '@sytechui/theme';
7
+ import '@react-types/textfield';
package/dist/index.js ADDED
@@ -0,0 +1,667 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ Input: () => input_default,
35
+ Textarea: () => textarea_default,
36
+ useInput: () => useInput
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/input.tsx
41
+ var import_shared_icons = require("@sytechui/shared-icons");
42
+ var import_react2 = require("react");
43
+ var import_system2 = require("@sytechui/system");
44
+
45
+ // src/use-input.ts
46
+ var import_system = require("@sytechui/system");
47
+ var import_use_safe_layout_effect = require("@sytechui/use-safe-layout-effect");
48
+ var import_focus = require("@react-aria/focus");
49
+ var import_theme = require("@sytechui/theme");
50
+ var import_react_utils = require("@sytechui/react-utils");
51
+ var import_interactions = require("@react-aria/interactions");
52
+ var import_shared_utils = require("@sytechui/shared-utils");
53
+ var import_utils = require("@react-stately/utils");
54
+ var import_react = require("react");
55
+ var import_textfield = require("@react-aria/textfield");
56
+ var import_form = require("@sytechui/form");
57
+ function useInput(originalProps) {
58
+ var _a, _b, _c, _d, _e, _f, _g;
59
+ const globalContext = (0, import_system.useProviderContext)();
60
+ const { validationBehavior: formValidationBehavior } = (0, import_form.useSlottedContext)(import_form.FormContext) || {};
61
+ const [props, variantProps] = (0, import_system.mapPropsVariants)(originalProps, import_theme.input.variantKeys);
62
+ const {
63
+ ref,
64
+ as,
65
+ type,
66
+ label,
67
+ baseRef,
68
+ wrapperRef,
69
+ description,
70
+ className,
71
+ classNames,
72
+ autoFocus,
73
+ startContent,
74
+ endContent,
75
+ onClear,
76
+ onChange,
77
+ validationState,
78
+ validationBehavior = (_a = formValidationBehavior != null ? formValidationBehavior : globalContext == null ? void 0 : globalContext.validationBehavior) != null ? _a : "native",
79
+ innerWrapperRef: innerWrapperRefProp,
80
+ onValueChange = () => {
81
+ },
82
+ ...otherProps
83
+ } = props;
84
+ const handleValueChange = (0, import_react.useCallback)(
85
+ (value) => {
86
+ onValueChange(value != null ? value : "");
87
+ },
88
+ [onValueChange]
89
+ );
90
+ const [isFocusWithin, setFocusWithin] = (0, import_react.useState)(false);
91
+ const Component = as || "div";
92
+ const disableAnimation = (_c = (_b = originalProps.disableAnimation) != null ? _b : globalContext == null ? void 0 : globalContext.disableAnimation) != null ? _c : false;
93
+ const domRef = (0, import_react_utils.useDOMRef)(ref);
94
+ const baseDomRef = (0, import_react_utils.useDOMRef)(baseRef);
95
+ const inputWrapperRef = (0, import_react_utils.useDOMRef)(wrapperRef);
96
+ const innerWrapperRef = (0, import_react_utils.useDOMRef)(innerWrapperRefProp);
97
+ const [inputValue, setInputValue] = (0, import_utils.useControlledState)(
98
+ props.value,
99
+ (_d = props.defaultValue) != null ? _d : "",
100
+ handleValueChange
101
+ );
102
+ const isFileTypeInput = type === "file";
103
+ const hasUploadedFiles = ((_g = (_f = (_e = domRef == null ? void 0 : domRef.current) == null ? void 0 : _e.files) == null ? void 0 : _f.length) != null ? _g : 0) > 0;
104
+ const isFilledByDefault = ["date", "time", "month", "week", "range"].includes(type);
105
+ const isFilled = !(0, import_shared_utils.isEmpty)(inputValue) || isFilledByDefault || hasUploadedFiles;
106
+ const isFilledWithin = isFilled || isFocusWithin;
107
+ const isHiddenType = type === "hidden";
108
+ const isMultiline = originalProps.isMultiline;
109
+ const baseStyles = (0, import_theme.cn)(classNames == null ? void 0 : classNames.base, className, isFilled ? "is-filled" : "");
110
+ const handleClear = (0, import_react.useCallback)(() => {
111
+ var _a2;
112
+ if (isFileTypeInput) {
113
+ domRef.current.value = "";
114
+ } else {
115
+ setInputValue("");
116
+ }
117
+ onClear == null ? void 0 : onClear();
118
+ (_a2 = domRef.current) == null ? void 0 : _a2.focus();
119
+ }, [setInputValue, onClear, isFileTypeInput]);
120
+ (0, import_use_safe_layout_effect.useSafeLayoutEffect)(() => {
121
+ if (!domRef.current) return;
122
+ setInputValue(domRef.current.value);
123
+ }, [domRef.current]);
124
+ const {
125
+ labelProps,
126
+ inputProps,
127
+ isInvalid: isAriaInvalid,
128
+ validationErrors,
129
+ validationDetails,
130
+ descriptionProps,
131
+ errorMessageProps
132
+ } = (0, import_textfield.useTextField)(
133
+ {
134
+ ...originalProps,
135
+ validationBehavior,
136
+ autoCapitalize: originalProps.autoCapitalize,
137
+ value: inputValue,
138
+ "aria-label": originalProps.label ? originalProps["aria-label"] : (0, import_shared_utils.safeAriaLabel)(originalProps["aria-label"], originalProps.placeholder),
139
+ inputElementType: isMultiline ? "textarea" : "input",
140
+ onChange: setInputValue
141
+ },
142
+ domRef
143
+ );
144
+ if (isFileTypeInput) {
145
+ delete inputProps.value;
146
+ delete inputProps.onChange;
147
+ }
148
+ const { isFocusVisible, isFocused, focusProps } = (0, import_focus.useFocusRing)({
149
+ autoFocus,
150
+ isTextInput: true
151
+ });
152
+ const { isHovered, hoverProps } = (0, import_interactions.useHover)({ isDisabled: !!(originalProps == null ? void 0 : originalProps.isDisabled) });
153
+ const { isHovered: isLabelHovered, hoverProps: labelHoverProps } = (0, import_interactions.useHover)({
154
+ isDisabled: !!(originalProps == null ? void 0 : originalProps.isDisabled)
155
+ });
156
+ const { focusProps: clearFocusProps, isFocusVisible: isClearButtonFocusVisible } = (0, import_focus.useFocusRing)();
157
+ const { focusWithinProps } = (0, import_interactions.useFocusWithin)({
158
+ onFocusWithinChange: setFocusWithin
159
+ });
160
+ const { pressProps: clearPressProps } = (0, import_interactions.usePress)({
161
+ isDisabled: !!(originalProps == null ? void 0 : originalProps.isDisabled) || !!(originalProps == null ? void 0 : originalProps.isReadOnly),
162
+ onPress: handleClear
163
+ });
164
+ const isInvalid = validationState === "invalid" || isAriaInvalid;
165
+ const labelPlacement = (0, import_system.useLabelPlacement)({
166
+ labelPlacement: originalProps.labelPlacement,
167
+ label
168
+ });
169
+ const errorMessage = typeof props.errorMessage === "function" ? props.errorMessage({ isInvalid, validationErrors, validationDetails }) : props.errorMessage || (validationErrors == null ? void 0 : validationErrors.join(" "));
170
+ const isClearable = !!onClear || originalProps.isClearable;
171
+ const hasElements = !!label || !!description || !!errorMessage;
172
+ const hasPlaceholder = !!props.placeholder;
173
+ const hasLabel = !!label;
174
+ const hasHelper = !!description || !!errorMessage;
175
+ const isOutsideLeft = labelPlacement === "outside-left";
176
+ const isOutsideTop = labelPlacement === "outside-top";
177
+ const shouldLabelBeOutside = (
178
+ // label is outside only when some placeholder is there
179
+ labelPlacement === "outside" || // label is outside regardless of placeholder
180
+ isOutsideLeft || isOutsideTop
181
+ );
182
+ const shouldLabelBeInside = labelPlacement === "inside";
183
+ const isPlaceholderShown = domRef.current ? (!domRef.current.value || domRef.current.value === "" || !inputValue || inputValue === "") && hasPlaceholder : false;
184
+ const hasStartContent = !!startContent;
185
+ const isLabelOutside = shouldLabelBeOutside ? isOutsideLeft || isOutsideTop || hasPlaceholder || labelPlacement === "outside" && hasStartContent : false;
186
+ const isLabelOutsideAsPlaceholder = labelPlacement === "outside" && !hasPlaceholder && !hasStartContent;
187
+ const slots = (0, import_react.useMemo)(
188
+ () => (0, import_theme.input)({
189
+ ...variantProps,
190
+ isInvalid,
191
+ labelPlacement,
192
+ isClearable,
193
+ disableAnimation
194
+ }),
195
+ [
196
+ (0, import_shared_utils.objectToDeps)(variantProps),
197
+ isInvalid,
198
+ labelPlacement,
199
+ isClearable,
200
+ hasStartContent,
201
+ disableAnimation
202
+ ]
203
+ );
204
+ const getBaseProps = (0, import_react.useCallback)(
205
+ (props2 = {}) => {
206
+ return {
207
+ ref: baseDomRef,
208
+ className: slots.base({ class: baseStyles }),
209
+ "data-slot": "base",
210
+ "data-filled": (0, import_shared_utils.dataAttr)(
211
+ isFilled || hasPlaceholder || hasStartContent || isPlaceholderShown || isFileTypeInput
212
+ ),
213
+ "data-filled-within": (0, import_shared_utils.dataAttr)(
214
+ isFilledWithin || hasPlaceholder || hasStartContent || isPlaceholderShown || isFileTypeInput
215
+ ),
216
+ "data-focus-within": (0, import_shared_utils.dataAttr)(isFocusWithin),
217
+ "data-focus-visible": (0, import_shared_utils.dataAttr)(isFocusVisible),
218
+ "data-readonly": (0, import_shared_utils.dataAttr)(originalProps.isReadOnly),
219
+ "data-focus": (0, import_shared_utils.dataAttr)(isFocused),
220
+ "data-hover": (0, import_shared_utils.dataAttr)(isHovered || isLabelHovered),
221
+ "data-required": (0, import_shared_utils.dataAttr)(originalProps.isRequired),
222
+ "data-invalid": (0, import_shared_utils.dataAttr)(isInvalid),
223
+ "data-disabled": (0, import_shared_utils.dataAttr)(originalProps.isDisabled),
224
+ "data-has-elements": (0, import_shared_utils.dataAttr)(hasElements),
225
+ "data-has-helper": (0, import_shared_utils.dataAttr)(hasHelper),
226
+ "data-has-label": (0, import_shared_utils.dataAttr)(hasLabel),
227
+ "data-has-value": (0, import_shared_utils.dataAttr)(!isPlaceholderShown),
228
+ "data-hidden": (0, import_shared_utils.dataAttr)(isHiddenType),
229
+ ...focusWithinProps,
230
+ ...props2
231
+ };
232
+ },
233
+ [
234
+ slots,
235
+ baseStyles,
236
+ isFilled,
237
+ isFocused,
238
+ isHovered,
239
+ isLabelHovered,
240
+ isInvalid,
241
+ hasHelper,
242
+ hasLabel,
243
+ hasElements,
244
+ isPlaceholderShown,
245
+ hasStartContent,
246
+ isFocusWithin,
247
+ isFocusVisible,
248
+ isFilledWithin,
249
+ hasPlaceholder,
250
+ focusWithinProps,
251
+ isHiddenType,
252
+ originalProps.isReadOnly,
253
+ originalProps.isRequired,
254
+ originalProps.isDisabled
255
+ ]
256
+ );
257
+ const getLabelProps = (0, import_react.useCallback)(
258
+ (props2 = {}) => {
259
+ return {
260
+ "data-slot": "label",
261
+ className: slots.label({ class: classNames == null ? void 0 : classNames.label }),
262
+ ...(0, import_shared_utils.mergeProps)(labelProps, labelHoverProps, props2)
263
+ };
264
+ },
265
+ [slots, isLabelHovered, labelProps, classNames == null ? void 0 : classNames.label]
266
+ );
267
+ const handleKeyDown = (0, import_react.useCallback)(
268
+ (e) => {
269
+ if (e.key === "Escape" && inputValue && (isClearable || onClear) && !originalProps.isReadOnly) {
270
+ setInputValue("");
271
+ onClear == null ? void 0 : onClear();
272
+ }
273
+ },
274
+ [inputValue, setInputValue, onClear, isClearable, originalProps.isReadOnly]
275
+ );
276
+ const getInputProps = (0, import_react.useCallback)(
277
+ (props2 = {}) => {
278
+ return {
279
+ "data-slot": "input",
280
+ "data-filled": (0, import_shared_utils.dataAttr)(isFilled),
281
+ "data-filled-within": (0, import_shared_utils.dataAttr)(isFilledWithin),
282
+ "data-has-start-content": (0, import_shared_utils.dataAttr)(hasStartContent),
283
+ "data-has-end-content": (0, import_shared_utils.dataAttr)(!!endContent),
284
+ "data-type": type,
285
+ className: slots.input({
286
+ class: (0, import_theme.cn)(
287
+ classNames == null ? void 0 : classNames.input,
288
+ isFilled ? "is-filled" : "",
289
+ isMultiline ? "pe-0" : "",
290
+ type === "password" ? "[&::-ms-reveal]:hidden" : ""
291
+ )
292
+ }),
293
+ ...(0, import_shared_utils.mergeProps)(
294
+ focusProps,
295
+ inputProps,
296
+ (0, import_react_utils.filterDOMProps)(otherProps, {
297
+ enabled: true,
298
+ labelable: true,
299
+ omitEventNames: new Set(Object.keys(inputProps))
300
+ }),
301
+ props2
302
+ ),
303
+ "aria-readonly": (0, import_shared_utils.dataAttr)(originalProps.isReadOnly),
304
+ onChange: (0, import_shared_utils.chain)(inputProps.onChange, onChange),
305
+ onKeyDown: (0, import_shared_utils.chain)(inputProps.onKeyDown, props2.onKeyDown, handleKeyDown),
306
+ ref: domRef
307
+ };
308
+ },
309
+ [
310
+ slots,
311
+ inputValue,
312
+ focusProps,
313
+ inputProps,
314
+ otherProps,
315
+ isFilled,
316
+ isFilledWithin,
317
+ hasStartContent,
318
+ endContent,
319
+ classNames == null ? void 0 : classNames.input,
320
+ originalProps.isReadOnly,
321
+ originalProps.isRequired,
322
+ onChange,
323
+ handleKeyDown
324
+ ]
325
+ );
326
+ const getInputWrapperProps = (0, import_react.useCallback)(
327
+ (props2 = {}) => {
328
+ return {
329
+ ref: inputWrapperRef,
330
+ "data-slot": "input-wrapper",
331
+ "data-hover": (0, import_shared_utils.dataAttr)(isHovered || isLabelHovered),
332
+ "data-focus-visible": (0, import_shared_utils.dataAttr)(isFocusVisible),
333
+ "data-focus": (0, import_shared_utils.dataAttr)(isFocused),
334
+ className: slots.inputWrapper({
335
+ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.inputWrapper, isFilled ? "is-filled" : "")
336
+ }),
337
+ ...(0, import_shared_utils.mergeProps)(props2, hoverProps),
338
+ onClick: (e) => {
339
+ if (domRef.current && e.currentTarget === e.target) {
340
+ domRef.current.focus();
341
+ }
342
+ },
343
+ style: {
344
+ cursor: "text",
345
+ ...props2.style
346
+ }
347
+ };
348
+ },
349
+ [
350
+ slots,
351
+ isHovered,
352
+ isLabelHovered,
353
+ isFocusVisible,
354
+ isFocused,
355
+ inputValue,
356
+ classNames == null ? void 0 : classNames.inputWrapper
357
+ ]
358
+ );
359
+ const getInnerWrapperProps = (0, import_react.useCallback)(
360
+ (props2 = {}) => {
361
+ return {
362
+ ...props2,
363
+ ref: innerWrapperRef,
364
+ "data-slot": "inner-wrapper",
365
+ onClick: (e) => {
366
+ if (domRef.current && e.currentTarget === e.target) {
367
+ domRef.current.focus();
368
+ }
369
+ },
370
+ className: slots.innerWrapper({
371
+ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.innerWrapper, props2 == null ? void 0 : props2.className)
372
+ })
373
+ };
374
+ },
375
+ [slots, classNames == null ? void 0 : classNames.innerWrapper]
376
+ );
377
+ const getMainWrapperProps = (0, import_react.useCallback)(
378
+ (props2 = {}) => {
379
+ return {
380
+ ...props2,
381
+ "data-slot": "main-wrapper",
382
+ className: slots.mainWrapper({
383
+ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.mainWrapper, props2 == null ? void 0 : props2.className)
384
+ })
385
+ };
386
+ },
387
+ [slots, classNames == null ? void 0 : classNames.mainWrapper]
388
+ );
389
+ const getHelperWrapperProps = (0, import_react.useCallback)(
390
+ (props2 = {}) => {
391
+ return {
392
+ ...props2,
393
+ "data-slot": "helper-wrapper",
394
+ className: slots.helperWrapper({
395
+ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.helperWrapper, props2 == null ? void 0 : props2.className)
396
+ })
397
+ };
398
+ },
399
+ [slots, classNames == null ? void 0 : classNames.helperWrapper]
400
+ );
401
+ const getDescriptionProps = (0, import_react.useCallback)(
402
+ (props2 = {}) => {
403
+ return {
404
+ ...props2,
405
+ ...descriptionProps,
406
+ "data-slot": "description",
407
+ className: slots.description({ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.description, props2 == null ? void 0 : props2.className) })
408
+ };
409
+ },
410
+ [slots, classNames == null ? void 0 : classNames.description]
411
+ );
412
+ const getErrorMessageProps = (0, import_react.useCallback)(
413
+ (props2 = {}) => {
414
+ return {
415
+ ...props2,
416
+ ...errorMessageProps,
417
+ "data-slot": "error-message",
418
+ className: slots.errorMessage({ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.errorMessage, props2 == null ? void 0 : props2.className) })
419
+ };
420
+ },
421
+ [slots, errorMessageProps, classNames == null ? void 0 : classNames.errorMessage]
422
+ );
423
+ const getClearButtonProps = (0, import_react.useCallback)(
424
+ (props2 = {}) => {
425
+ return {
426
+ ...props2,
427
+ type: "button",
428
+ tabIndex: -1,
429
+ disabled: originalProps.isDisabled,
430
+ "aria-label": "clear input",
431
+ "data-slot": "clear-button",
432
+ "data-focus-visible": (0, import_shared_utils.dataAttr)(isClearButtonFocusVisible),
433
+ className: slots.clearButton({
434
+ class: (0, import_theme.cn)(classNames == null ? void 0 : classNames.clearButton, props2 == null ? void 0 : props2.className)
435
+ }),
436
+ ...(0, import_shared_utils.mergeProps)(clearPressProps, clearFocusProps)
437
+ };
438
+ },
439
+ [slots, isClearButtonFocusVisible, clearPressProps, clearFocusProps, classNames == null ? void 0 : classNames.clearButton]
440
+ );
441
+ return {
442
+ Component,
443
+ classNames,
444
+ domRef,
445
+ label,
446
+ description,
447
+ startContent,
448
+ endContent,
449
+ labelPlacement,
450
+ isClearable,
451
+ hasHelper,
452
+ hasStartContent,
453
+ isLabelOutside,
454
+ isOutsideLeft,
455
+ isOutsideTop,
456
+ isLabelOutsideAsPlaceholder,
457
+ shouldLabelBeOutside,
458
+ shouldLabelBeInside,
459
+ hasPlaceholder,
460
+ isInvalid,
461
+ errorMessage,
462
+ getBaseProps,
463
+ getLabelProps,
464
+ getInputProps,
465
+ getMainWrapperProps,
466
+ getInputWrapperProps,
467
+ getInnerWrapperProps,
468
+ getHelperWrapperProps,
469
+ getDescriptionProps,
470
+ getErrorMessageProps,
471
+ getClearButtonProps
472
+ };
473
+ }
474
+
475
+ // src/input.tsx
476
+ var import_jsx_runtime = require("react/jsx-runtime");
477
+ var Input = (0, import_system2.forwardRef)((props, ref) => {
478
+ const {
479
+ Component,
480
+ label,
481
+ description,
482
+ isClearable,
483
+ startContent,
484
+ endContent,
485
+ labelPlacement,
486
+ hasHelper,
487
+ isOutsideLeft,
488
+ isOutsideTop,
489
+ shouldLabelBeOutside,
490
+ errorMessage,
491
+ isInvalid,
492
+ getBaseProps,
493
+ getLabelProps,
494
+ getInputProps,
495
+ getInnerWrapperProps,
496
+ getInputWrapperProps,
497
+ getMainWrapperProps,
498
+ getHelperWrapperProps,
499
+ getDescriptionProps,
500
+ getErrorMessageProps,
501
+ getClearButtonProps
502
+ } = useInput({ ...props, ref });
503
+ const labelContent = label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { ...getLabelProps(), children: label }) : null;
504
+ const end = (0, import_react2.useMemo)(() => {
505
+ if (isClearable) {
506
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ...getClearButtonProps(), children: endContent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_shared_icons.CloseFilledIcon, {}) });
507
+ }
508
+ return endContent;
509
+ }, [isClearable, getClearButtonProps]);
510
+ const helperWrapper = (0, import_react2.useMemo)(() => {
511
+ const shouldShowError = isInvalid && errorMessage;
512
+ const hasContent = shouldShowError || description;
513
+ if (!hasHelper || !hasContent) return null;
514
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...getHelperWrapperProps(), children: shouldShowError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...getErrorMessageProps(), children: errorMessage }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...getDescriptionProps(), children: description }) });
515
+ }, [
516
+ hasHelper,
517
+ isInvalid,
518
+ errorMessage,
519
+ description,
520
+ getHelperWrapperProps,
521
+ getErrorMessageProps,
522
+ getDescriptionProps
523
+ ]);
524
+ const innerWrapper = (0, import_react2.useMemo)(() => {
525
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ...getInnerWrapperProps(), children: [
526
+ startContent,
527
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { ...getInputProps() }),
528
+ end
529
+ ] });
530
+ }, [startContent, end, getInputProps, getInnerWrapperProps]);
531
+ const mainWrapper = (0, import_react2.useMemo)(() => {
532
+ if (shouldLabelBeOutside) {
533
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ...getMainWrapperProps(), children: [
534
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ...getInputWrapperProps(), children: [
535
+ !isOutsideLeft && !isOutsideTop ? labelContent : null,
536
+ innerWrapper
537
+ ] }),
538
+ helperWrapper
539
+ ] });
540
+ }
541
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
542
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ...getInputWrapperProps(), children: [
543
+ labelContent,
544
+ innerWrapper
545
+ ] }),
546
+ helperWrapper
547
+ ] });
548
+ }, [
549
+ labelPlacement,
550
+ helperWrapper,
551
+ shouldLabelBeOutside,
552
+ labelContent,
553
+ innerWrapper,
554
+ errorMessage,
555
+ description,
556
+ getMainWrapperProps,
557
+ getInputWrapperProps,
558
+ getErrorMessageProps,
559
+ getDescriptionProps
560
+ ]);
561
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Component, { ...getBaseProps(), children: [
562
+ isOutsideLeft || isOutsideTop ? labelContent : null,
563
+ mainWrapper
564
+ ] });
565
+ });
566
+ Input.displayName = "HeroUI.Input";
567
+ var input_default = Input;
568
+
569
+ // src/textarea.tsx
570
+ var import_shared_utils2 = require("@sytechui/shared-utils");
571
+ var import_system3 = require("@sytechui/system");
572
+ var import_react3 = require("react");
573
+ var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
574
+ var import_shared_icons2 = require("@sytechui/shared-icons");
575
+ var import_jsx_runtime2 = require("react/jsx-runtime");
576
+ var Textarea = (0, import_system3.forwardRef)(
577
+ ({
578
+ style,
579
+ minRows = 3,
580
+ maxRows = 8,
581
+ cacheMeasurements = false,
582
+ disableAutosize = false,
583
+ onHeightChange,
584
+ ...otherProps
585
+ }, ref) => {
586
+ const {
587
+ Component,
588
+ label,
589
+ description,
590
+ startContent,
591
+ endContent,
592
+ hasHelper,
593
+ shouldLabelBeOutside,
594
+ shouldLabelBeInside,
595
+ isInvalid,
596
+ errorMessage,
597
+ getBaseProps,
598
+ getLabelProps,
599
+ getInputProps,
600
+ getInnerWrapperProps,
601
+ getInputWrapperProps,
602
+ getHelperWrapperProps,
603
+ getDescriptionProps,
604
+ getErrorMessageProps,
605
+ isClearable,
606
+ getClearButtonProps
607
+ } = useInput({ ...otherProps, ref, isMultiline: true });
608
+ const [hasMultipleRows, setIsHasMultipleRows] = (0, import_react3.useState)(minRows > 1);
609
+ const [isLimitReached, setIsLimitReached] = (0, import_react3.useState)(false);
610
+ const labelContent = label ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { ...getLabelProps(), children: label }) : null;
611
+ const inputProps = getInputProps();
612
+ const handleHeightChange = (height, meta) => {
613
+ if (minRows === 1) {
614
+ setIsHasMultipleRows(height >= meta.rowHeight * 2);
615
+ }
616
+ if (maxRows > minRows) {
617
+ const limitReached = height >= maxRows * meta.rowHeight;
618
+ setIsLimitReached(limitReached);
619
+ }
620
+ onHeightChange == null ? void 0 : onHeightChange(height, meta);
621
+ };
622
+ const content = disableAutosize ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("textarea", { ...inputProps, style: (0, import_shared_utils2.mergeProps)(inputProps.style, style != null ? style : {}) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
623
+ import_react_textarea_autosize.default,
624
+ {
625
+ ...inputProps,
626
+ cacheMeasurements,
627
+ "data-hide-scroll": (0, import_shared_utils2.dataAttr)(!isLimitReached),
628
+ maxRows,
629
+ minRows,
630
+ style: (0, import_shared_utils2.mergeProps)(inputProps.style, style != null ? style : {}),
631
+ onHeightChange: handleHeightChange
632
+ }
633
+ );
634
+ const clearButtonContent = (0, import_react3.useMemo)(() => {
635
+ return isClearable ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { ...getClearButtonProps(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_shared_icons2.CloseFilledIcon, {}) }) : null;
636
+ }, [isClearable, getClearButtonProps]);
637
+ const innerWrapper = (0, import_react3.useMemo)(() => {
638
+ if (startContent || endContent) {
639
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...getInnerWrapperProps(), children: [
640
+ startContent,
641
+ content,
642
+ endContent
643
+ ] });
644
+ }
645
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ...getInnerWrapperProps(), children: content });
646
+ }, [startContent, inputProps, endContent, getInnerWrapperProps]);
647
+ const shouldShowError = isInvalid && errorMessage;
648
+ const hasHelperContent = shouldShowError || description;
649
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Component, { ...getBaseProps(), children: [
650
+ shouldLabelBeOutside ? labelContent : null,
651
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...getInputWrapperProps(), "data-has-multiple-rows": (0, import_shared_utils2.dataAttr)(hasMultipleRows), children: [
652
+ shouldLabelBeInside ? labelContent : null,
653
+ innerWrapper,
654
+ clearButtonContent
655
+ ] }),
656
+ hasHelper && hasHelperContent ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ...getHelperWrapperProps(), children: shouldShowError ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ...getErrorMessageProps(), children: errorMessage }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ...getDescriptionProps(), children: description }) }) : null
657
+ ] });
658
+ }
659
+ );
660
+ Textarea.displayName = "HeroUI.Textarea";
661
+ var textarea_default = Textarea;
662
+ // Annotate the CommonJS export names for ESM import in node:
663
+ 0 && (module.exports = {
664
+ Input,
665
+ Textarea,
666
+ useInput
667
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import {
3
+ input_default
4
+ } from "./chunk-PPYXCOZH.mjs";
5
+ import {
6
+ textarea_default
7
+ } from "./chunk-ZTVVBFTB.mjs";
8
+ import {
9
+ useInput
10
+ } from "./chunk-6SGLJYRO.mjs";
11
+ export {
12
+ input_default as Input,
13
+ textarea_default as Textarea,
14
+ useInput
15
+ };