@gridui/input 3.0.1 → 4.0.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 +6 -0
- package/dist/index.js +354 -18
- package/dist/index.js.map +4 -4
- package/dist/input/style.d.ts +9 -0
- package/dist/styles.css +150 -25
- package/dist/textarea/resize-handle.d.ts +14 -0
- package/dist/textarea/style.d.ts +10 -0
- package/dist/textarea/textarea.d.ts +6 -1
- package/dist/textarea/use-textarea-footer-height.d.ts +10 -0
- package/dist/textarea/use-textarea-resize.d.ts +19 -0
- package/docs/catalog.json +4 -1
- package/docs/reference/input.md +2 -2
- package/docs/reference/textarea.md +20 -0
- package/docs/textarea.md +62 -23
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -56,3 +56,9 @@ Fetching, debouncing, caching and form submission remain application-owned.
|
|
|
56
56
|
For both compositions, ref, className, style, name and native attributes target
|
|
57
57
|
the input; `rootClassName` styles the group. Standard and small densities remain
|
|
58
58
|
available. `Field` and `useField` from Form can associate labels and help text.
|
|
59
|
+
|
|
60
|
+
Textarea's `resizeHandle` selects `edge` (default), `corner`, `footer`, or `false`.
|
|
61
|
+
Automatic sizing hides the handle. Its optional `footer` slot composes counters
|
|
62
|
+
or actions. Unlike the single-line compositions above, Textarea's className/style
|
|
63
|
+
style its structural frame; the ref and native attributes still target the native
|
|
64
|
+
textarea. See the [Textarea migration contract](docs/textarea.md#frame-styling-and-migration).
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,17 @@ var controlVariants = cva(controlStyles(), {
|
|
|
32
32
|
defaultVariants: { size: "standard" }
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
// src/input/style.ts
|
|
36
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
37
|
+
var inputStyles = cva2("", {
|
|
38
|
+
variants: {
|
|
39
|
+
grouped: {
|
|
40
|
+
true: "gridui-u-input--flex-1 gridui-u-input--w-0 gridui-u-input--border-0 gridui-u-input--bg-transparent",
|
|
41
|
+
false: ""
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
35
46
|
// src/input/input.tsx
|
|
36
47
|
import { cn as cn2 } from "@gridui/style-utils";
|
|
37
48
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -54,7 +65,7 @@ var Input = (props) => {
|
|
|
54
65
|
onChange?.(event);
|
|
55
66
|
onValueChange?.(event.currentTarget.value);
|
|
56
67
|
},
|
|
57
|
-
className: cn2(controlVariants({ size: controlSize }),
|
|
68
|
+
className: cn2(controlVariants({ size: controlSize }), inputStyles({ grouped: groupSize !== null }), className)
|
|
58
69
|
}
|
|
59
70
|
);
|
|
60
71
|
};
|
|
@@ -117,12 +128,12 @@ var InputGroupButton = (props) => {
|
|
|
117
128
|
|
|
118
129
|
// src/label/style.ts
|
|
119
130
|
import { cn as cn6 } from "@gridui/style-utils";
|
|
120
|
-
import { cva as
|
|
121
|
-
var labelStyles =
|
|
131
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
132
|
+
var labelStyles = cva3(cn6(
|
|
122
133
|
"gridui-label",
|
|
123
134
|
"gridui-u-input--inline-flex gridui-u-input--items-center gridui-u-input--gap-gridui-4 gridui-u-input--type-ui"
|
|
124
135
|
));
|
|
125
|
-
var labelIconStyles =
|
|
136
|
+
var labelIconStyles = cva3("gridui-u-input--inline-flex gridui-u-input--shrink-0 gridui-u-input--text-foreground gridui-u-input--[&>svg]:size-gridui-16");
|
|
126
137
|
|
|
127
138
|
// src/label/label.tsx
|
|
128
139
|
import { cn as cn7 } from "@gridui/style-utils";
|
|
@@ -305,11 +316,257 @@ var SearchInput = (props) => {
|
|
|
305
316
|
);
|
|
306
317
|
};
|
|
307
318
|
|
|
319
|
+
// src/textarea/resize-handle.tsx
|
|
320
|
+
import { GripHorizontal, MoveVertical } from "lucide-react";
|
|
321
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
322
|
+
var ResizeHandle = (props) => {
|
|
323
|
+
const { variant, label, controlId, dragging, ...restProps } = props;
|
|
324
|
+
const Icon = variant === "edge" ? GripHorizontal : MoveVertical;
|
|
325
|
+
return /* @__PURE__ */ jsx8(
|
|
326
|
+
"button",
|
|
327
|
+
{
|
|
328
|
+
...restProps,
|
|
329
|
+
type: "button",
|
|
330
|
+
className: "gridui-textarea-resize-handle",
|
|
331
|
+
"data-variant": variant,
|
|
332
|
+
"data-dragging": dragging || void 0,
|
|
333
|
+
"aria-label": label,
|
|
334
|
+
"aria-controls": controlId,
|
|
335
|
+
"aria-keyshortcuts": "ArrowUp ArrowDown Home End Enter Space",
|
|
336
|
+
children: /* @__PURE__ */ jsx8(
|
|
337
|
+
Icon,
|
|
338
|
+
{
|
|
339
|
+
size: 16,
|
|
340
|
+
"aria-hidden": "true"
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// src/textarea/style.ts
|
|
348
|
+
import { cva as cva4 } from "class-variance-authority";
|
|
349
|
+
var textareaStyles = cva4(controlStyles(), {
|
|
350
|
+
variants: {
|
|
351
|
+
invalid: {
|
|
352
|
+
true: "gridui-u-input--border-danger-foreground",
|
|
353
|
+
false: ""
|
|
354
|
+
},
|
|
355
|
+
grouped: {
|
|
356
|
+
true: "gridui-u-input--border-0 gridui-u-input--border-inherit gridui-u-input--bg-transparent",
|
|
357
|
+
false: ""
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// src/textarea/use-textarea-footer-height.ts
|
|
363
|
+
import { useLayoutEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
364
|
+
var useTextareaFooterHeight = (visible) => {
|
|
365
|
+
const ref = useRef2(null);
|
|
366
|
+
const [
|
|
367
|
+
height,
|
|
368
|
+
setHeight
|
|
369
|
+
] = useState2();
|
|
370
|
+
useLayoutEffect(() => {
|
|
371
|
+
const footer = ref.current;
|
|
372
|
+
if (!visible || !footer) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const measure = () => {
|
|
376
|
+
setHeight(parseFloat(footer.ownerDocument.defaultView.getComputedStyle(footer).height));
|
|
377
|
+
};
|
|
378
|
+
measure();
|
|
379
|
+
const observer = new ResizeObserver(measure);
|
|
380
|
+
observer.observe(footer);
|
|
381
|
+
return () => {
|
|
382
|
+
observer.disconnect();
|
|
383
|
+
};
|
|
384
|
+
}, [visible]);
|
|
385
|
+
return {
|
|
386
|
+
ref,
|
|
387
|
+
height: visible ? height : void 0
|
|
388
|
+
};
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// src/textarea/use-textarea-resize.ts
|
|
392
|
+
import { isComposingKeyEvent, listenForDragCancellation } from "@gridui/interaction";
|
|
393
|
+
import { useCallback, useEffect, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState3 } from "react";
|
|
394
|
+
var getResizeGeometry = (frame) => {
|
|
395
|
+
const style = frame.ownerDocument.defaultView.getComputedStyle(frame);
|
|
396
|
+
return {
|
|
397
|
+
height: parseFloat(style.height),
|
|
398
|
+
maximum: style.maxHeight === "none" ? void 0 : style.maxHeight,
|
|
399
|
+
scale: frame.getBoundingClientRect().height / frame.offsetHeight || 1
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
var releaseDrag = (drag) => {
|
|
403
|
+
drag.cleanup();
|
|
404
|
+
if (drag.handle.hasPointerCapture(drag.pointerId)) {
|
|
405
|
+
drag.handle.releasePointerCapture(drag.pointerId);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
var useTextareaResize = ({ frame, input, enabled, disabled }) => {
|
|
409
|
+
const [
|
|
410
|
+
height,
|
|
411
|
+
setHeight
|
|
412
|
+
] = useState3();
|
|
413
|
+
const [
|
|
414
|
+
dragging,
|
|
415
|
+
setDragging
|
|
416
|
+
] = useState3(false);
|
|
417
|
+
const drag = useRef3(null);
|
|
418
|
+
const blocked = () => {
|
|
419
|
+
return !enabled || disabled || !input.current || input.current.matches(":disabled") || input.current.inert;
|
|
420
|
+
};
|
|
421
|
+
const finish = (restore) => {
|
|
422
|
+
const active = drag.current;
|
|
423
|
+
if (!active) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
drag.current = null;
|
|
427
|
+
releaseDrag(active);
|
|
428
|
+
if (restore) {
|
|
429
|
+
setHeight(active.previousHeight);
|
|
430
|
+
}
|
|
431
|
+
setDragging(false);
|
|
432
|
+
};
|
|
433
|
+
const cancel = useRef3(() => {
|
|
434
|
+
return;
|
|
435
|
+
});
|
|
436
|
+
useLayoutEffect2(() => {
|
|
437
|
+
cancel.current = () => {
|
|
438
|
+
finish(true);
|
|
439
|
+
};
|
|
440
|
+
if (blocked()) {
|
|
441
|
+
finish(true);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
useLayoutEffect2(() => {
|
|
445
|
+
if (!enabled) {
|
|
446
|
+
setHeight(void 0);
|
|
447
|
+
}
|
|
448
|
+
}, [enabled]);
|
|
449
|
+
useEffect(() => {
|
|
450
|
+
return () => {
|
|
451
|
+
cancel.current();
|
|
452
|
+
};
|
|
453
|
+
}, []);
|
|
454
|
+
const handleRef = useCallback((handle) => {
|
|
455
|
+
if (!handle) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
return () => {
|
|
459
|
+
if (handle.ownerDocument.activeElement === handle) {
|
|
460
|
+
input.current?.focus({ preventScroll: true });
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
}, [input]);
|
|
464
|
+
const update = (next) => {
|
|
465
|
+
if (blocked() || !frame.current) {
|
|
466
|
+
finish(true);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
setHeight(typeof next === "number" ? Math.max(0, next) : next);
|
|
470
|
+
};
|
|
471
|
+
const reset = () => {
|
|
472
|
+
if (!blocked()) {
|
|
473
|
+
finish(false);
|
|
474
|
+
setHeight(void 0);
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
const handleProps = {
|
|
478
|
+
ref: handleRef,
|
|
479
|
+
onPointerDown: (event) => {
|
|
480
|
+
if (blocked() || event.button !== 0 || !event.isPrimary || drag.current || !frame.current) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const bounds = getResizeGeometry(frame.current);
|
|
484
|
+
const handle = event.currentTarget;
|
|
485
|
+
event.preventDefault();
|
|
486
|
+
handle.focus({ preventScroll: true });
|
|
487
|
+
drag.current = {
|
|
488
|
+
pointerId: event.pointerId,
|
|
489
|
+
startY: event.clientY,
|
|
490
|
+
startHeight: bounds.height,
|
|
491
|
+
previousHeight: height,
|
|
492
|
+
scale: bounds.scale,
|
|
493
|
+
handle,
|
|
494
|
+
cleanup: listenForDragCancellation(handle, () => {
|
|
495
|
+
cancel.current();
|
|
496
|
+
})
|
|
497
|
+
};
|
|
498
|
+
handle.setPointerCapture(event.pointerId);
|
|
499
|
+
setDragging(true);
|
|
500
|
+
},
|
|
501
|
+
onPointerMove: (event) => {
|
|
502
|
+
const active = drag.current;
|
|
503
|
+
if (active?.pointerId === event.pointerId) {
|
|
504
|
+
update(active.startHeight + (event.clientY - active.startY) / active.scale);
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
onPointerUp: (event) => {
|
|
508
|
+
if (drag.current?.pointerId === event.pointerId) {
|
|
509
|
+
finish(blocked());
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
onPointerCancel: (event) => {
|
|
513
|
+
if (drag.current?.pointerId === event.pointerId) {
|
|
514
|
+
finish(true);
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
onLostPointerCapture: (event) => {
|
|
518
|
+
if (drag.current?.pointerId === event.pointerId) {
|
|
519
|
+
finish(true);
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
onKeyDown: (event) => {
|
|
523
|
+
if (blocked() || drag.current || !frame.current || isComposingKeyEvent(event.nativeEvent)) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const bounds = getResizeGeometry(frame.current);
|
|
527
|
+
const step = event.shiftKey ? 64 : 16;
|
|
528
|
+
let next;
|
|
529
|
+
switch (event.key) {
|
|
530
|
+
case "ArrowUp":
|
|
531
|
+
next = bounds.height - step;
|
|
532
|
+
break;
|
|
533
|
+
case "ArrowDown":
|
|
534
|
+
next = bounds.height + step;
|
|
535
|
+
break;
|
|
536
|
+
case "Home":
|
|
537
|
+
next = 0;
|
|
538
|
+
break;
|
|
539
|
+
case "End":
|
|
540
|
+
if (bounds.maximum === void 0) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
next = bounds.maximum;
|
|
544
|
+
break;
|
|
545
|
+
default:
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
event.preventDefault();
|
|
549
|
+
update(next);
|
|
550
|
+
},
|
|
551
|
+
onClick: (event) => {
|
|
552
|
+
if (event.detail === 0) {
|
|
553
|
+
reset();
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
onDoubleClick: reset
|
|
557
|
+
};
|
|
558
|
+
return {
|
|
559
|
+
height,
|
|
560
|
+
dragging,
|
|
561
|
+
handleProps
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
|
|
308
565
|
// src/textarea/textarea.tsx
|
|
309
566
|
import { useScrollbars } from "@gridui/overlay";
|
|
310
567
|
import { cn as cn8 } from "@gridui/style-utils";
|
|
311
|
-
import "react";
|
|
312
|
-
import { jsx as
|
|
568
|
+
import { useId, useImperativeHandle as useImperativeHandle2, useRef as useRef4 } from "react";
|
|
569
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
313
570
|
var Textarea = (props) => {
|
|
314
571
|
const groupSize = useInputGroupSize();
|
|
315
572
|
const {
|
|
@@ -323,6 +580,9 @@ var Textarea = (props) => {
|
|
|
323
580
|
maxRows,
|
|
324
581
|
rows = 2,
|
|
325
582
|
style,
|
|
583
|
+
resizeHandle = "edge",
|
|
584
|
+
resizeLabel = "Resize text area",
|
|
585
|
+
footer,
|
|
326
586
|
...restProps
|
|
327
587
|
} = props;
|
|
328
588
|
if (maxHeight !== void 0 && (!Number.isFinite(maxHeight) || maxHeight <= 0)) {
|
|
@@ -334,27 +594,103 @@ var Textarea = (props) => {
|
|
|
334
594
|
if (maxHeight !== void 0 && maxRows !== void 0) {
|
|
335
595
|
throw new RangeError("Textarea accepts either maxRows or maxHeight, not both.");
|
|
336
596
|
}
|
|
337
|
-
const
|
|
597
|
+
const frame = useRef4(null);
|
|
598
|
+
const input = useRef4(null);
|
|
599
|
+
const generatedId = useId();
|
|
600
|
+
const inputId = restProps.id ?? generatedId;
|
|
601
|
+
useImperativeHandle2(ref, () => {
|
|
602
|
+
return input.current;
|
|
603
|
+
}, []);
|
|
604
|
+
const scrollRef = useScrollbars({ ref: input });
|
|
605
|
+
const manual = !autoSize && resizeHandle !== false;
|
|
606
|
+
const resize = useTextareaResize({
|
|
607
|
+
frame,
|
|
608
|
+
input,
|
|
609
|
+
enabled: manual,
|
|
610
|
+
disabled: Boolean(restProps.disabled)
|
|
611
|
+
});
|
|
612
|
+
const hasFooter = footer !== void 0 && footer !== null && typeof footer !== "boolean";
|
|
613
|
+
const showFooter = hasFooter || manual && resizeHandle === "footer";
|
|
614
|
+
const footerLayout = useTextareaFooterHeight(showFooter);
|
|
615
|
+
const handle = manual ? /* @__PURE__ */ jsx9(
|
|
616
|
+
ResizeHandle,
|
|
617
|
+
{
|
|
618
|
+
...resize.handleProps,
|
|
619
|
+
variant: resizeHandle,
|
|
620
|
+
label: resizeLabel,
|
|
621
|
+
controlId: inputId,
|
|
622
|
+
dragging: resize.dragging,
|
|
623
|
+
disabled: restProps.disabled
|
|
624
|
+
}
|
|
625
|
+
) : null;
|
|
338
626
|
const sizing = {
|
|
339
627
|
"--_gridui-textarea-rows": rows,
|
|
340
628
|
"--_gridui-textarea-max-rows": maxRows,
|
|
629
|
+
"--_gridui-textarea-footer-height": footerLayout.height === void 0 ? void 0 : `${footerLayout.height}px`,
|
|
341
630
|
...style,
|
|
342
|
-
...
|
|
631
|
+
...maxHeight !== void 0 ? { maxHeight } : {},
|
|
632
|
+
...manual && resize.height !== void 0 ? { height: resize.height } : {}
|
|
343
633
|
};
|
|
344
|
-
return /* @__PURE__ */
|
|
345
|
-
"
|
|
634
|
+
return /* @__PURE__ */ jsxs4(
|
|
635
|
+
"div",
|
|
346
636
|
{
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
637
|
+
ref: frame,
|
|
638
|
+
dir: restProps.dir,
|
|
639
|
+
lang: restProps.lang,
|
|
640
|
+
hidden: restProps.hidden,
|
|
641
|
+
inert: restProps.inert,
|
|
350
642
|
style: sizing,
|
|
643
|
+
className: cn8(textareaStyles({
|
|
644
|
+
invalid: Boolean(restProps["aria-invalid"]) && restProps["aria-invalid"] !== "false",
|
|
645
|
+
grouped: groupSize !== null
|
|
646
|
+
}), "gridui-textarea-frame", className),
|
|
647
|
+
"data-gridui-outline-target": groupSize === null ? "" : void 0,
|
|
648
|
+
"data-control-size": controlSize,
|
|
649
|
+
"data-grouped": groupSize !== null || void 0,
|
|
351
650
|
"data-autosize": autoSize || void 0,
|
|
352
651
|
"data-max-rows": maxRows !== void 0 || void 0,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
652
|
+
"data-resize-handle": manual ? resizeHandle : void 0,
|
|
653
|
+
"data-footer": hasFooter || void 0,
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsx9(
|
|
656
|
+
"textarea",
|
|
657
|
+
{
|
|
658
|
+
...restProps,
|
|
659
|
+
id: inputId,
|
|
660
|
+
ref: scrollRef,
|
|
661
|
+
rows,
|
|
662
|
+
onChange: (event) => {
|
|
663
|
+
onChange?.(event);
|
|
664
|
+
onValueChange?.(event.currentTarget.value);
|
|
665
|
+
},
|
|
666
|
+
className: "gridui-textarea"
|
|
667
|
+
}
|
|
668
|
+
),
|
|
669
|
+
manual && resizeHandle !== "footer" && /* @__PURE__ */ jsx9(
|
|
670
|
+
"div",
|
|
671
|
+
{
|
|
672
|
+
className: "gridui-textarea-resize-row",
|
|
673
|
+
children: handle
|
|
674
|
+
}
|
|
675
|
+
),
|
|
676
|
+
showFooter && /* @__PURE__ */ jsxs4(
|
|
677
|
+
"div",
|
|
678
|
+
{
|
|
679
|
+
ref: footerLayout.ref,
|
|
680
|
+
className: "gridui-textarea-footer",
|
|
681
|
+
children: [
|
|
682
|
+
/* @__PURE__ */ jsx9(
|
|
683
|
+
"div",
|
|
684
|
+
{
|
|
685
|
+
className: "gridui-textarea-footer-content",
|
|
686
|
+
children: footer
|
|
687
|
+
}
|
|
688
|
+
),
|
|
689
|
+
resizeHandle === "footer" && handle
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
)
|
|
693
|
+
]
|
|
358
694
|
}
|
|
359
695
|
);
|
|
360
696
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/shared/input-group-context.ts", "../src/shared/style.ts", "../src/input/input.tsx", "../src/input-group/input-group.tsx", "../src/input-group-addon/input-group-addon.tsx", "../src/input-group-button/input-group-button.tsx", "../src/label/style.ts", "../src/label/label.tsx", "../src/password-input/password-input.tsx", "../src/search-input/search-input.tsx", "../src/textarea/textarea.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * @author WMXPY\n * @package Input\n * @namespace Shared\n * @description Input Group Context\n */\n\nimport { createContext, useContext } from \"react\";\n\nexport const inputGroupContext = createContext<\"standard\" | \"small\" | null>(null);\nexport const useInputGroupSize = () => {\n return useContext(inputGroupContext);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const controlStyles = cva(cn(\n \"gridui-control\",\n \"gridui-u-input--min-w-0 gridui-u-input--w-full gridui-u-input--box-border gridui-u-input--border gridui-u-input--border-solid gridui-u-input--border-border gridui-u-input--rounded-control gridui-u-input--text-foreground gridui-u-input--bg-background gridui-u-input--type-input\",\n \"gridui-u-input--disabled:opacity-50 gridui-u-input--disabled:cursor-not-allowed\",\n \"gridui-u-input--aria-invalid:border-danger-foreground\",\n));\n\nexport const controlStandardStyles = cva(cn(\n \"gridui-control-standard\",\n \"gridui-u-input--p-gridui-8 gridui-u-input--min-h-gridui-control\",\n));\n\nexport const controlSmallStyles = cva(cn(\n \"gridui-control-small\",\n \"gridui-u-input--py-gridui-4 gridui-u-input--px-gridui-8 gridui-u-input--min-h-gridui-control-small\",\n));\n\nexport const controlVariants = cva(controlStyles(), {\n variants: {\n size: {\n standard: controlStandardStyles(),\n small: controlSmallStyles(),\n },\n },\n defaultVariants: { size: \"standard\" },\n});\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Input\n * @description Input\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport { controlVariants } from \"../shared/style\";\nimport type { TextControlOptions } from \"../shared/text-control-options\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputProps = ComponentPropsWithRef<\"input\"> & TextControlOptions;\n\nexport const Input: FC<InputProps> = (props: InputProps) => {\n const groupSize = useInputGroupSize();\n const {\n size,\n controlSize = groupSize ?? \"standard\",\n className,\n onChange,\n onValueChange,\n ...restProps\n } = props;\n return (<input\n {...restProps}\n size={size}\n onChange={(event) => {\n onChange?.(event);\n onValueChange?.(event.currentTarget.value);\n }}\n className={cn(controlVariants({ size: controlSize }), groupSize && \"gridui-u-input--flex-1 gridui-u-input--w-0 gridui-u-input--border-0 gridui-u-input--bg-transparent\", className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroup\n * @description Input Group\n */\n\nimport { inputGroupContext } from \"../shared/input-group-context\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputGroupProps = ComponentPropsWithRef<\"div\"> & {\n readonly controlSize?: \"standard\" | \"small\";\n};\nexport const InputGroup: FC<InputGroupProps> = (props: InputGroupProps) => {\n const { controlSize = \"standard\", className, children, ...restProps } = props;\n return (<inputGroupContext.Provider\n value={controlSize}\n >\n <div\n {...restProps}\n data-control-size={controlSize}\n data-gridui-outline-target=\"\"\n className={cn(\"gridui-input-group\", className)}\n >\n {children}\n </div>\n </inputGroupContext.Provider>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroupAddon\n * @description Input Group Addon\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputGroupAddonProps = ComponentPropsWithRef<\"div\"> & {\n readonly align?: \"inline-start\" | \"inline-end\" | \"block-start\" | \"block-end\";\n};\nexport const InputGroupAddon: FC<InputGroupAddonProps> = (props: InputGroupAddonProps) => {\n const { align = \"inline-start\", className, ...restProps } = props;\n return (<div\n {...restProps}\n data-align={align}\n className={cn(\"gridui-input-group-addon\", className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroupButton\n * @description Input Group Button\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport { Button, type ButtonProps } from \"@gridui/button\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { FC } from \"react\";\n\nexport type InputGroupButtonProps = ButtonProps;\nexport const InputGroupButton: FC<InputGroupButtonProps> = (props: InputGroupButtonProps) => {\n const size = useInputGroupSize() ?? \"standard\";\n const { className, ...restProps } = props;\n return (<Button\n variant=\"quiet\"\n size={size}\n {...restProps}\n className={cn(\"gridui-input-group-button\", className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Label\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const labelStyles = cva(cn(\n \"gridui-label\",\n \"gridui-u-input--inline-flex gridui-u-input--items-center gridui-u-input--gap-gridui-4 gridui-u-input--type-ui\",\n));\n\nexport const labelIconStyles = cva(\"gridui-u-input--inline-flex gridui-u-input--shrink-0 gridui-u-input--text-foreground gridui-u-input--[&>svg]:size-gridui-16\");\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Label\n * @description Label\n */\n\nimport { labelIconStyles, labelStyles } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\n\nexport type LabelProps = ComponentPropsWithRef<\"label\"> & {\n readonly icon?: ReactNode;\n};\n\nexport const Label: FC<LabelProps> = (props: LabelProps) => {\n const { icon, children, className, ...restProps } = props;\n return (<label\n {...restProps}\n className={cn(labelStyles(), className)}\n >\n {icon && (<span\n aria-hidden=\"true\"\n className={labelIconStyles()}\n >\n {icon}\n </span>)}\n {children}\n </label>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace PasswordInput\n * @description Password Input\n */\n\nimport { Input, type InputProps } from \"../input/input\";\nimport { InputGroup } from \"../input-group/input-group\";\nimport { InputGroupAddon } from \"../input-group-addon/input-group-addon\";\nimport { InputGroupButton } from \"../input-group-button/input-group-button\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { type FC, useState } from \"react\";\n\nexport type PasswordInputProps = Omit<InputProps, \"type\"> & {\n readonly showLabel: string;\n readonly hideLabel: string;\n readonly rootClassName?: string;\n};\nexport const PasswordInput: FC<PasswordInputProps> = (props: PasswordInputProps) => {\n const { showLabel, hideLabel, rootClassName, controlSize = \"standard\", ...restProps } = props;\n const [\n visible,\n setVisible,\n ] = useState(false);\n return (<InputGroup\n controlSize={controlSize}\n dir={restProps.dir}\n className={rootClassName}\n >\n <Input\n {...restProps}\n type={visible ? \"text\" : \"password\"}\n />\n <InputGroupAddon\n align=\"inline-end\"\n >\n <InputGroupButton\n layout=\"icon\"\n aria-label={visible ? hideLabel : showLabel}\n disabled={restProps.disabled}\n onClick={() => {\n setVisible(current => {\n return !current;\n });\n }}\n >\n {visible ? (<EyeOff\n aria-hidden=\"true\"\n />) : (<Eye\n aria-hidden=\"true\"\n />)}\n </InputGroupButton>\n </InputGroupAddon>\n </InputGroup>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace SearchInput\n * @description Search Input\n */\n\nimport { Input, type InputProps } from \"../input/input\";\nimport { InputGroup } from \"../input-group/input-group\";\nimport { InputGroupAddon } from \"../input-group-addon/input-group-addon\";\nimport { InputGroupButton } from \"../input-group-button/input-group-button\";\nimport { Search, X } from \"lucide-react\";\nimport { type FC, useImperativeHandle, useRef } from \"react\";\n\nexport type SearchInputProps = Omit<InputProps, \"type\"> & {\n readonly clearLabel: string;\n readonly loading?: boolean;\n readonly loadingLabel?: string;\n readonly rootClassName?: string;\n};\nexport const SearchInput: FC<SearchInputProps> = (props: SearchInputProps) => {\n const { clearLabel, loading = false, loadingLabel, rootClassName, controlSize = \"standard\", ref,\n onValueChange, ...restProps } = props;\n const input = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => {\n return input.current!;\n });\n return (<InputGroup\n controlSize={controlSize}\n dir={restProps.dir}\n className={rootClassName}\n >\n <Input\n {...restProps}\n ref={input}\n type=\"search\"\n aria-busy={loading || restProps[\"aria-busy\"]}\n onValueChange={(next) => {\n onValueChange?.(next);\n }}\n />\n <InputGroupAddon\n aria-hidden=\"true\"\n >\n <Search\n size={16}\n />\n </InputGroupAddon>\n <InputGroupAddon\n align=\"inline-end\"\n >\n {loading && (<span\n role=\"status\"\n >\n {loadingLabel}\n </span>)}\n <InputGroupButton\n layout=\"icon\"\n aria-label={clearLabel}\n disabled={restProps.disabled || restProps.readOnly}\n onClick={() => {\n const element = input.current;\n if (!element || element.matches(\":disabled\") || element.readOnly) {\n return;\n }\n if (element.value !== \"\") {\n if (restProps.value === undefined) {\n element.value = \"\";\n }\n onValueChange?.(\"\");\n }\n element.focus();\n }}\n >\n <X\n aria-hidden=\"true\"\n />\n </InputGroupButton>\n </InputGroupAddon>\n </InputGroup>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Textarea\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport { controlVariants } from \"../shared/style\";\nimport type { TextControlOptions } from \"../shared/text-control-options\";\nimport { useScrollbars } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { type ComponentPropsWithRef, type CSSProperties, type FC } from \"react\";\n\nexport type TextareaProps = ComponentPropsWithRef<\"textarea\"> & TextControlOptions & {\n readonly autoSize?: boolean;\n readonly maxHeight?: number;\n readonly maxRows?: number;\n};\nexport const Textarea: FC<TextareaProps> = (props: TextareaProps) => {\n const groupSize = useInputGroupSize();\n const { controlSize = groupSize ?? \"standard\", className, onChange, onValueChange, ref, autoSize = false,\n maxHeight, maxRows, rows = 2, style, ...restProps } = props;\n if (maxHeight !== undefined && (!Number.isFinite(maxHeight) || maxHeight <= 0)) {\n throw new RangeError(\"Textarea maxHeight must be finite and positive.\");\n }\n if (maxRows !== undefined && (!Number.isSafeInteger(maxRows) || maxRows < rows)) {\n throw new RangeError(\"Textarea maxRows must be an integer at least as large as rows.\");\n }\n if (maxHeight !== undefined && maxRows !== undefined) {\n throw new RangeError(\"Textarea accepts either maxRows or maxHeight, not both.\");\n }\n const scrollRef = useScrollbars<HTMLTextAreaElement>({ ref });\n const sizing: CSSProperties & Record<`--${string}`, string | number | undefined> = {\n \"--_gridui-textarea-rows\": rows,\n \"--_gridui-textarea-max-rows\": maxRows,\n ...style,\n ...(autoSize && maxHeight !== undefined ? { maxHeight } : {}),\n };\n return (<textarea\n {...restProps}\n ref={scrollRef}\n rows={rows}\n style={sizing}\n data-autosize={autoSize || undefined}\n data-max-rows={maxRows !== undefined || undefined}\n onChange={(event) => {\n onChange?.(event);\n onValueChange?.(event.currentTarget.value);\n }}\n className={cn(controlVariants({ size: controlSize }), \"gridui-textarea gridui-u-input--overflow-auto\", groupSize && \"gridui-u-input--border-0 gridui-u-input--bg-transparent\", autoSize ? \"gridui-u-input--resize-none gridui-u-input--min-h-(--_gridui-textarea-min-height)\" : \"gridui-u-input--resize-y\", className)}\n />);\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["cn", "cn", "jsx", "cn", "jsx", "cn", "jsx", "cn", "cva", "cn", "jsx", "jsx", "jsxs", "jsx", "jsxs", "cn", "jsx"]
|
|
3
|
+
"sources": ["../src/shared/input-group-context.ts", "../src/shared/style.ts", "../src/input/style.ts", "../src/input/input.tsx", "../src/input-group/input-group.tsx", "../src/input-group-addon/input-group-addon.tsx", "../src/input-group-button/input-group-button.tsx", "../src/label/style.ts", "../src/label/label.tsx", "../src/password-input/password-input.tsx", "../src/search-input/search-input.tsx", "../src/textarea/resize-handle.tsx", "../src/textarea/style.ts", "../src/textarea/use-textarea-footer-height.ts", "../src/textarea/use-textarea-resize.ts", "../src/textarea/textarea.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * @author WMXPY\n * @package Input\n * @namespace Shared\n * @description Input Group Context\n */\n\nimport { createContext, useContext } from \"react\";\n\nexport const inputGroupContext = createContext<\"standard\" | \"small\" | null>(null);\nexport const useInputGroupSize = () => {\n return useContext(inputGroupContext);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const controlStyles = cva(cn(\n \"gridui-control\",\n \"gridui-u-input--min-w-0 gridui-u-input--w-full gridui-u-input--box-border gridui-u-input--border gridui-u-input--border-solid gridui-u-input--border-border gridui-u-input--rounded-control gridui-u-input--text-foreground gridui-u-input--bg-background gridui-u-input--type-input\",\n \"gridui-u-input--disabled:opacity-50 gridui-u-input--disabled:cursor-not-allowed\",\n \"gridui-u-input--aria-invalid:border-danger-foreground\",\n));\n\nexport const controlStandardStyles = cva(cn(\n \"gridui-control-standard\",\n \"gridui-u-input--p-gridui-8 gridui-u-input--min-h-gridui-control\",\n));\n\nexport const controlSmallStyles = cva(cn(\n \"gridui-control-small\",\n \"gridui-u-input--py-gridui-4 gridui-u-input--px-gridui-8 gridui-u-input--min-h-gridui-control-small\",\n));\n\nexport const controlVariants = cva(controlStyles(), {\n variants: {\n size: {\n standard: controlStandardStyles(),\n small: controlSmallStyles(),\n },\n },\n defaultVariants: { size: \"standard\" },\n});\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Input\n * @description Style\n */\n\nimport { cva } from \"class-variance-authority\";\n\nexport const inputStyles = cva(\"\", {\n variants: {\n grouped: {\n true: \"gridui-u-input--flex-1 gridui-u-input--w-0 gridui-u-input--border-0 gridui-u-input--bg-transparent\",\n false: \"\",\n },\n },\n});\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Input\n * @description Input\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport { controlVariants } from \"../shared/style\";\nimport type { TextControlOptions } from \"../shared/text-control-options\";\nimport { inputStyles } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputProps = ComponentPropsWithRef<\"input\"> & TextControlOptions;\n\nexport const Input: FC<InputProps> = (props: InputProps) => {\n const groupSize = useInputGroupSize();\n const {\n size,\n controlSize = groupSize ?? \"standard\",\n className,\n onChange,\n onValueChange,\n ...restProps\n } = props;\n return (<input\n {...restProps}\n size={size}\n onChange={(event) => {\n onChange?.(event);\n onValueChange?.(event.currentTarget.value);\n }}\n className={cn(controlVariants({ size: controlSize }), inputStyles({ grouped: groupSize !== null }), className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroup\n * @description Input Group\n */\n\nimport { inputGroupContext } from \"../shared/input-group-context\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputGroupProps = ComponentPropsWithRef<\"div\"> & {\n readonly controlSize?: \"standard\" | \"small\";\n};\nexport const InputGroup: FC<InputGroupProps> = (props: InputGroupProps) => {\n const { controlSize = \"standard\", className, children, ...restProps } = props;\n return (<inputGroupContext.Provider\n value={controlSize}\n >\n <div\n {...restProps}\n data-control-size={controlSize}\n data-gridui-outline-target=\"\"\n className={cn(\"gridui-input-group\", className)}\n >\n {children}\n </div>\n </inputGroupContext.Provider>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroupAddon\n * @description Input Group Addon\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type InputGroupAddonProps = ComponentPropsWithRef<\"div\"> & {\n readonly align?: \"inline-start\" | \"inline-end\" | \"block-start\" | \"block-end\";\n};\nexport const InputGroupAddon: FC<InputGroupAddonProps> = (props: InputGroupAddonProps) => {\n const { align = \"inline-start\", className, ...restProps } = props;\n return (<div\n {...restProps}\n data-align={align}\n className={cn(\"gridui-input-group-addon\", className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace InputGroupButton\n * @description Input Group Button\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport { Button, type ButtonProps } from \"@gridui/button\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { FC } from \"react\";\n\nexport type InputGroupButtonProps = ButtonProps;\nexport const InputGroupButton: FC<InputGroupButtonProps> = (props: InputGroupButtonProps) => {\n const size = useInputGroupSize() ?? \"standard\";\n const { className, ...restProps } = props;\n return (<Button\n variant=\"quiet\"\n size={size}\n {...restProps}\n className={cn(\"gridui-input-group-button\", className)}\n />);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Label\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva } from \"class-variance-authority\";\n\nexport const labelStyles = cva(cn(\n \"gridui-label\",\n \"gridui-u-input--inline-flex gridui-u-input--items-center gridui-u-input--gap-gridui-4 gridui-u-input--type-ui\",\n));\n\nexport const labelIconStyles = cva(\"gridui-u-input--inline-flex gridui-u-input--shrink-0 gridui-u-input--text-foreground gridui-u-input--[&>svg]:size-gridui-16\");\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Label\n * @description Label\n */\n\nimport { labelIconStyles, labelStyles } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\n\nexport type LabelProps = ComponentPropsWithRef<\"label\"> & {\n readonly icon?: ReactNode;\n};\n\nexport const Label: FC<LabelProps> = (props: LabelProps) => {\n const { icon, children, className, ...restProps } = props;\n return (<label\n {...restProps}\n className={cn(labelStyles(), className)}\n >\n {icon && (<span\n aria-hidden=\"true\"\n className={labelIconStyles()}\n >\n {icon}\n </span>)}\n {children}\n </label>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace PasswordInput\n * @description Password Input\n */\n\nimport { Input, type InputProps } from \"../input/input\";\nimport { InputGroup } from \"../input-group/input-group\";\nimport { InputGroupAddon } from \"../input-group-addon/input-group-addon\";\nimport { InputGroupButton } from \"../input-group-button/input-group-button\";\nimport { Eye, EyeOff } from \"lucide-react\";\nimport { type FC, useState } from \"react\";\n\nexport type PasswordInputProps = Omit<InputProps, \"type\"> & {\n readonly showLabel: string;\n readonly hideLabel: string;\n readonly rootClassName?: string;\n};\nexport const PasswordInput: FC<PasswordInputProps> = (props: PasswordInputProps) => {\n const { showLabel, hideLabel, rootClassName, controlSize = \"standard\", ...restProps } = props;\n const [\n visible,\n setVisible,\n ] = useState(false);\n return (<InputGroup\n controlSize={controlSize}\n dir={restProps.dir}\n className={rootClassName}\n >\n <Input\n {...restProps}\n type={visible ? \"text\" : \"password\"}\n />\n <InputGroupAddon\n align=\"inline-end\"\n >\n <InputGroupButton\n layout=\"icon\"\n aria-label={visible ? hideLabel : showLabel}\n disabled={restProps.disabled}\n onClick={() => {\n setVisible(current => {\n return !current;\n });\n }}\n >\n {visible ? (<EyeOff\n aria-hidden=\"true\"\n />) : (<Eye\n aria-hidden=\"true\"\n />)}\n </InputGroupButton>\n </InputGroupAddon>\n </InputGroup>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace SearchInput\n * @description Search Input\n */\n\nimport { Input, type InputProps } from \"../input/input\";\nimport { InputGroup } from \"../input-group/input-group\";\nimport { InputGroupAddon } from \"../input-group-addon/input-group-addon\";\nimport { InputGroupButton } from \"../input-group-button/input-group-button\";\nimport { Search, X } from \"lucide-react\";\nimport { type FC, useImperativeHandle, useRef } from \"react\";\n\nexport type SearchInputProps = Omit<InputProps, \"type\"> & {\n readonly clearLabel: string;\n readonly loading?: boolean;\n readonly loadingLabel?: string;\n readonly rootClassName?: string;\n};\nexport const SearchInput: FC<SearchInputProps> = (props: SearchInputProps) => {\n const { clearLabel, loading = false, loadingLabel, rootClassName, controlSize = \"standard\", ref,\n onValueChange, ...restProps } = props;\n const input = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => {\n return input.current!;\n });\n return (<InputGroup\n controlSize={controlSize}\n dir={restProps.dir}\n className={rootClassName}\n >\n <Input\n {...restProps}\n ref={input}\n type=\"search\"\n aria-busy={loading || restProps[\"aria-busy\"]}\n onValueChange={(next) => {\n onValueChange?.(next);\n }}\n />\n <InputGroupAddon\n aria-hidden=\"true\"\n >\n <Search\n size={16}\n />\n </InputGroupAddon>\n <InputGroupAddon\n align=\"inline-end\"\n >\n {loading && (<span\n role=\"status\"\n >\n {loadingLabel}\n </span>)}\n <InputGroupButton\n layout=\"icon\"\n aria-label={clearLabel}\n disabled={restProps.disabled || restProps.readOnly}\n onClick={() => {\n const element = input.current;\n if (!element || element.matches(\":disabled\") || element.readOnly) {\n return;\n }\n if (element.value !== \"\") {\n if (restProps.value === undefined) {\n element.value = \"\";\n }\n onValueChange?.(\"\");\n }\n element.focus();\n }}\n >\n <X\n aria-hidden=\"true\"\n />\n </InputGroupButton>\n </InputGroupAddon>\n </InputGroup>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Resize Handle\n */\n\nimport { GripHorizontal, MoveVertical } from \"lucide-react\";\nimport type { ComponentPropsWithRef, FC } from \"react\";\n\nexport type ResizeHandleProps = ComponentPropsWithRef<\"button\"> & {\n readonly variant: \"corner\" | \"edge\" | \"footer\";\n readonly label: string;\n readonly controlId: string;\n readonly dragging: boolean;\n};\n\nexport const ResizeHandle: FC<ResizeHandleProps> = (props: ResizeHandleProps) => {\n const { variant, label, controlId, dragging, ...restProps } = props;\n const Icon = variant === \"edge\" ? GripHorizontal : MoveVertical;\n return (<button\n {...restProps}\n type=\"button\"\n className=\"gridui-textarea-resize-handle\"\n data-variant={variant}\n data-dragging={dragging || undefined}\n aria-label={label}\n aria-controls={controlId}\n aria-keyshortcuts=\"ArrowUp ArrowDown Home End Enter Space\"\n >\n <Icon\n size={16}\n aria-hidden=\"true\"\n />\n </button>);\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Style\n */\n\nimport { controlStyles } from \"../shared/style\";\nimport { cva } from \"class-variance-authority\";\n\nexport const textareaStyles = cva(controlStyles(), {\n variants: {\n invalid: {\n true: \"gridui-u-input--border-danger-foreground\",\n false: \"\",\n },\n grouped: {\n true: \"gridui-u-input--border-0 gridui-u-input--border-inherit gridui-u-input--bg-transparent\",\n false: \"\",\n },\n },\n});\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Use Textarea Footer Height\n */\n\nimport { useLayoutEffect, useRef, useState } from \"react\";\n\nexport const useTextareaFooterHeight = (visible: boolean) => {\n const ref = useRef<HTMLDivElement>(null);\n const [\n height,\n setHeight,\n ] = useState<number>();\n useLayoutEffect(() => {\n const footer = ref.current;\n if (!visible || !footer) {\n return;\n }\n const measure = () => {\n setHeight(parseFloat(footer.ownerDocument.defaultView!.getComputedStyle(footer).height));\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(footer);\n return () => {\n observer.disconnect();\n };\n }, [visible]);\n return {\n ref,\n height: visible ? height : undefined,\n };\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Use Textarea Resize\n */\n\nimport { isComposingKeyEvent, listenForDragCancellation } from \"@gridui/interaction\";\nimport { type ComponentPropsWithRef, type CSSProperties, type RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\ntype ResizeOptions = {\n readonly frame: RefObject<HTMLDivElement | null>;\n readonly input: RefObject<HTMLTextAreaElement | null>;\n readonly enabled: boolean;\n readonly disabled: boolean;\n};\n\ntype Drag = {\n readonly pointerId: number;\n readonly startY: number;\n readonly startHeight: number;\n readonly previousHeight: CSSProperties[\"height\"];\n readonly scale: number;\n readonly handle: HTMLButtonElement;\n readonly cleanup: () => void;\n};\n\nconst getResizeGeometry = (frame: HTMLDivElement) => {\n const style = frame.ownerDocument.defaultView!.getComputedStyle(frame);\n return {\n height: parseFloat(style.height),\n maximum: style.maxHeight === \"none\" ? undefined : style.maxHeight,\n scale: frame.getBoundingClientRect().height / frame.offsetHeight || 1,\n };\n};\n\nconst releaseDrag = (drag: Drag): void => {\n drag.cleanup();\n if (drag.handle.hasPointerCapture(drag.pointerId)) {\n drag.handle.releasePointerCapture(drag.pointerId);\n }\n};\n\nexport const useTextareaResize = ({ frame, input, enabled, disabled }: ResizeOptions): {\n height: CSSProperties[\"height\"];\n dragging: boolean;\n handleProps: ComponentPropsWithRef<\"button\">;\n} => {\n const [\n height,\n setHeight,\n ] = useState<CSSProperties[\"height\"]>();\n const [\n dragging,\n setDragging,\n ] = useState(false);\n const drag = useRef<Drag | null>(null);\n const blocked = (): boolean => {\n return !enabled || disabled || !input.current || input.current.matches(\":disabled\") || input.current.inert;\n };\n const finish = (restore: boolean): void => {\n const active = drag.current;\n if (!active) {\n return;\n }\n drag.current = null;\n releaseDrag(active);\n if (restore) {\n setHeight(active.previousHeight);\n }\n setDragging(false);\n };\n const cancel = useRef(() => {\n return;\n });\n useLayoutEffect(() => {\n cancel.current = () => {\n finish(true);\n };\n if (blocked()) {\n finish(true);\n }\n });\n useLayoutEffect(() => {\n if (!enabled) {\n setHeight(undefined);\n }\n }, [enabled]);\n useEffect(() => {\n return () => {\n cancel.current();\n };\n }, []);\n const handleRef = useCallback((handle: HTMLButtonElement | null) => {\n if (!handle) {\n return;\n }\n return () => {\n if (handle.ownerDocument.activeElement === handle) {\n input.current?.focus({ preventScroll: true });\n }\n };\n }, [input]);\n const update = (next: CSSProperties[\"height\"]): void => {\n if (blocked() || !frame.current) {\n finish(true);\n return;\n }\n // CSS resolves constraints, including percentages and content-dependent minima.\n setHeight(typeof next === \"number\" ? Math.max(0, next) : next);\n };\n const reset = (): void => {\n if (!blocked()) {\n finish(false);\n setHeight(undefined);\n }\n };\n const handleProps: ComponentPropsWithRef<\"button\"> = {\n ref: handleRef,\n onPointerDown: (event) => {\n if (blocked() || event.button !== 0 || !event.isPrimary || drag.current || !frame.current) {\n return;\n }\n const bounds = getResizeGeometry(frame.current);\n const handle = event.currentTarget;\n event.preventDefault();\n handle.focus({ preventScroll: true });\n drag.current = {\n pointerId: event.pointerId,\n startY: event.clientY,\n startHeight: bounds.height,\n previousHeight: height,\n scale: bounds.scale,\n handle,\n cleanup: listenForDragCancellation(handle, () => {\n cancel.current();\n }),\n };\n handle.setPointerCapture(event.pointerId);\n setDragging(true);\n },\n onPointerMove: (event) => {\n const active = drag.current;\n if (active?.pointerId === event.pointerId) {\n update(active.startHeight + (event.clientY - active.startY) / active.scale);\n }\n },\n onPointerUp: (event) => {\n if (drag.current?.pointerId === event.pointerId) {\n finish(blocked());\n }\n },\n onPointerCancel: (event) => {\n if (drag.current?.pointerId === event.pointerId) {\n finish(true);\n }\n },\n onLostPointerCapture: (event) => {\n if (drag.current?.pointerId === event.pointerId) {\n finish(true);\n }\n },\n onKeyDown: (event) => {\n if (blocked() || drag.current || !frame.current || isComposingKeyEvent(event.nativeEvent)) {\n return;\n }\n const bounds = getResizeGeometry(frame.current);\n const step = event.shiftKey ? 64 : 16;\n let next: CSSProperties[\"height\"];\n switch (event.key) {\n case \"ArrowUp\": next = bounds.height - step; break;\n case \"ArrowDown\": next = bounds.height + step; break;\n case \"Home\": next = 0; break;\n case \"End\":\n if (bounds.maximum === undefined) {\n return;\n }\n next = bounds.maximum;\n break;\n default: return;\n }\n event.preventDefault();\n update(next);\n },\n onClick: (event) => {\n // Keyboard and assistive-technology activation restore the natural height.\n if (event.detail === 0) {\n reset();\n }\n },\n onDoubleClick: reset,\n };\n return {\n height,\n dragging,\n handleProps,\n };\n};\n", "/**\n * @author WMXPY\n * @package Input\n * @namespace Textarea\n * @description Textarea\n */\n\nimport { useInputGroupSize } from \"../shared/input-group-context\";\nimport type { TextControlOptions } from \"../shared/text-control-options\";\nimport { ResizeHandle } from \"./resize-handle\";\nimport { textareaStyles } from \"./style\";\nimport { useTextareaFooterHeight } from \"./use-textarea-footer-height\";\nimport { useTextareaResize } from \"./use-textarea-resize\";\nimport { useScrollbars } from \"@gridui/overlay\";\nimport { cn } from \"@gridui/style-utils\";\nimport { type ComponentPropsWithRef, type CSSProperties, type FC, type ReactNode, useId, useImperativeHandle, useRef } from \"react\";\n\nexport type TextareaProps = ComponentPropsWithRef<\"textarea\"> & TextControlOptions & {\n readonly autoSize?: boolean;\n readonly maxHeight?: number;\n readonly maxRows?: number;\n /** Manual resize affordance. Automatic sizing always hides it. */\n readonly resizeHandle?: \"corner\" | \"edge\" | \"footer\" | false;\n readonly resizeLabel?: string;\n /** Caller-owned footer content; footer handles share this row. */\n readonly footer?: ReactNode;\n};\nexport const Textarea: FC<TextareaProps> = (props: TextareaProps) => {\n const groupSize = useInputGroupSize();\n const { controlSize = groupSize ?? \"standard\", className, onChange, onValueChange, ref, autoSize = false,\n maxHeight, maxRows, rows = 2, style, resizeHandle = \"edge\", resizeLabel = \"Resize text area\", footer, ...restProps } = props;\n if (maxHeight !== undefined && (!Number.isFinite(maxHeight) || maxHeight <= 0)) {\n throw new RangeError(\"Textarea maxHeight must be finite and positive.\");\n }\n if (maxRows !== undefined && (!Number.isSafeInteger(maxRows) || maxRows < rows)) {\n throw new RangeError(\"Textarea maxRows must be an integer at least as large as rows.\");\n }\n if (maxHeight !== undefined && maxRows !== undefined) {\n throw new RangeError(\"Textarea accepts either maxRows or maxHeight, not both.\");\n }\n const frame = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLTextAreaElement>(null);\n const generatedId = useId();\n const inputId = restProps.id ?? generatedId;\n useImperativeHandle(ref, () => {\n return input.current!;\n }, []);\n const scrollRef = useScrollbars<HTMLTextAreaElement>({ ref: input });\n const manual = !autoSize && resizeHandle !== false;\n const resize = useTextareaResize({\n frame,\n input,\n enabled: manual,\n disabled: Boolean(restProps.disabled),\n });\n const hasFooter = footer !== undefined && footer !== null && typeof footer !== \"boolean\";\n const showFooter = hasFooter || manual && resizeHandle === \"footer\";\n const footerLayout = useTextareaFooterHeight(showFooter);\n const handle = manual ? (<ResizeHandle\n {...resize.handleProps}\n variant={resizeHandle}\n label={resizeLabel}\n controlId={inputId}\n dragging={resize.dragging}\n disabled={restProps.disabled}\n />) : null;\n const sizing: CSSProperties & Record<`--${string}`, string | number | undefined> = {\n \"--_gridui-textarea-rows\": rows,\n \"--_gridui-textarea-max-rows\": maxRows,\n \"--_gridui-textarea-footer-height\": footerLayout.height === undefined ? undefined : `${footerLayout.height}px`,\n ...style,\n ...(maxHeight !== undefined ? { maxHeight } : {}),\n ...(manual && resize.height !== undefined ? { height: resize.height } : {}),\n };\n return (<div\n ref={frame}\n dir={restProps.dir}\n lang={restProps.lang}\n hidden={restProps.hidden}\n inert={restProps.inert}\n style={sizing}\n className={cn(textareaStyles({\n invalid: Boolean(restProps[\"aria-invalid\"]) && restProps[\"aria-invalid\"] !== \"false\",\n grouped: groupSize !== null,\n }), \"gridui-textarea-frame\", className)}\n data-gridui-outline-target={groupSize === null ? \"\" : undefined}\n data-control-size={controlSize}\n data-grouped={groupSize !== null || undefined}\n data-autosize={autoSize || undefined}\n data-max-rows={maxRows !== undefined || undefined}\n data-resize-handle={manual ? resizeHandle : undefined}\n data-footer={hasFooter || undefined}\n >\n <textarea\n {...restProps}\n id={inputId}\n ref={scrollRef}\n rows={rows}\n onChange={(event) => {\n onChange?.(event);\n onValueChange?.(event.currentTarget.value);\n }}\n className=\"gridui-textarea\"\n />\n {manual && resizeHandle !== \"footer\" && (<div\n className=\"gridui-textarea-resize-row\"\n >\n {handle}\n </div>)}\n {showFooter && (<div\n ref={footerLayout.ref}\n className=\"gridui-textarea-footer\"\n >\n <div\n className=\"gridui-textarea-footer-content\"\n >\n {footer}\n </div>\n {resizeHandle === \"footer\" && handle}\n </div>)}\n </div>);\n};\n"],
|
|
5
|
+
"mappings": ";AAOA,SAAS,eAAe,kBAAkB;AAEnC,IAAM,oBAAoB,cAA2C,IAAI;AACzE,IAAM,oBAAoB,MAAM;AACnC,SAAO,WAAW,iBAAiB;AACvC;;;ACLA,SAAS,UAAU;AACnB,SAAS,WAAW;AAEb,IAAM,gBAAgB,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,wBAAwB,IAAI;AAAA,EACrC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,qBAAqB,IAAI;AAAA,EAClC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,kBAAkB,IAAI,cAAc,GAAG;AAAA,EAChD,UAAU;AAAA,IACN,MAAM;AAAA,MACF,UAAU,sBAAsB;AAAA,MAChC,OAAO,mBAAmB;AAAA,IAC9B;AAAA,EACJ;AAAA,EACA,iBAAiB,EAAE,MAAM,WAAW;AACxC,CAAC;;;AC5BD,SAAS,OAAAA,YAAW;AAEb,IAAM,cAAcA,KAAI,IAAI;AAAA,EAC/B,UAAU;AAAA,IACN,SAAS;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACX;AAAA,EACJ;AACJ,CAAC;;;ACLD,SAAS,MAAAC,WAAU;AAeP;AAVL,IAAM,QAAwB,CAAC,UAAsB;AACxD,QAAM,YAAY,kBAAkB;AACpC,QAAM;AAAA,IACF;AAAA,IACA,cAAc,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACP,IAAI;AACJ,SAAQ;AAAA,IAAC;AAAA;AAAA,MACJ,GAAG;AAAA,MACJ;AAAA,MACA,UAAU,CAAC,UAAU;AACjB,mBAAW,KAAK;AAChB,wBAAgB,MAAM,cAAc,KAAK;AAAA,MAC7C;AAAA,MACA,WAAWA,IAAG,gBAAgB,EAAE,MAAM,YAAY,CAAC,GAAG,YAAY,EAAE,SAAS,cAAc,KAAK,CAAC,GAAG,SAAS;AAAA;AAAA,EACjH;AACJ;;;AC3BA,SAAS,MAAAC,WAAU;AAWX,gBAAAC,YAAA;AALD,IAAM,aAAkC,CAAC,UAA2B;AACvE,QAAM,EAAE,cAAc,YAAY,WAAW,UAAU,GAAG,UAAU,IAAI;AACxE,SAAQ,gBAAAA;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACL,OAAO;AAAA,MAEP,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACI,GAAG;AAAA,UACJ,qBAAmB;AAAA,UACnB,8BAA2B;AAAA,UAC3B,WAAWD,IAAG,sBAAsB,SAAS;AAAA,UAE5C;AAAA;AAAA,MACL;AAAA;AAAA,EACJ;AACJ;;;ACrBA,SAAS,MAAAE,WAAU;AAQP,gBAAAC,YAAA;AAFL,IAAM,kBAA4C,CAAC,UAAgC;AACtF,QAAM,EAAE,QAAQ,gBAAgB,WAAW,GAAG,UAAU,IAAI;AAC5D,SAAQ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACJ,GAAG;AAAA,MACJ,cAAY;AAAA,MACZ,WAAWD,IAAG,4BAA4B,SAAS;AAAA;AAAA,EACvD;AACJ;;;ACZA,SAAS,cAAgC;AACzC,SAAS,MAAAE,WAAU;AAOP,gBAAAC,YAAA;AAHL,IAAM,mBAA8C,CAAC,UAAiC;AACzF,QAAM,OAAO,kBAAkB,KAAK;AACpC,QAAM,EAAE,WAAW,GAAG,UAAU,IAAI;AACpC,SAAQ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACL,SAAQ;AAAA,MACR;AAAA,MACC,GAAG;AAAA,MACJ,WAAWD,IAAG,6BAA6B,SAAS;AAAA;AAAA,EACxD;AACJ;;;ACfA,SAAS,MAAAE,WAAU;AACnB,SAAS,OAAAC,YAAW;AAEb,IAAM,cAAcA,KAAID;AAAA,EAC3B;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,kBAAkBC,KAAI,6HAA6H;;;ACPhK,SAAS,MAAAC,WAAU;AASP,SAIM,OAAAC,MAJN;AAFL,IAAM,QAAwB,CAAC,UAAsB;AACxD,QAAM,EAAE,MAAM,UAAU,WAAW,GAAG,UAAU,IAAI;AACpD,SAAQ;AAAA,IAAC;AAAA;AAAA,MACJ,GAAG;AAAA,MACJ,WAAWD,IAAG,YAAY,GAAG,SAAS;AAAA,MAErC;AAAA,gBAAS,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACP,eAAY;AAAA,YACZ,WAAW,gBAAgB;AAAA,YAE1B;AAAA;AAAA,QACL;AAAA,QACC;AAAA;AAAA;AAAA,EACL;AACJ;;;AClBA,SAAS,KAAK,cAAc;AAC5B,SAAkB,gBAAgB;AAatB,SAKJ,OAAAC,MALI,QAAAC,aAAA;AANL,IAAM,gBAAwC,CAAC,UAA8B;AAChF,QAAM,EAAE,WAAW,WAAW,eAAe,cAAc,YAAY,GAAG,UAAU,IAAI;AACxF,QAAM;AAAA,IACF;AAAA,IACA;AAAA,EACJ,IAAI,SAAS,KAAK;AAClB,SAAQ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACL;AAAA,MACA,KAAK,UAAU;AAAA,MACf,WAAW;AAAA,MAEX;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACI,GAAG;AAAA,YACJ,MAAM,UAAU,SAAS;AAAA;AAAA,QAC7B;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACG,OAAM;AAAA,YAEN,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACG,QAAO;AAAA,gBACP,cAAY,UAAU,YAAY;AAAA,gBAClC,UAAU,UAAU;AAAA,gBACpB,SAAS,MAAM;AACX,6BAAW,aAAW;AAClB,2BAAO,CAAC;AAAA,kBACZ,CAAC;AAAA,gBACL;AAAA,gBAEC,oBAAW,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACT,eAAY;AAAA;AAAA,gBAChB,IAAO,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACJ,eAAY;AAAA;AAAA,gBAChB;AAAA;AAAA,YACJ;AAAA;AAAA,QACJ;AAAA;AAAA;AAAA,EACJ;AACJ;;;AC5CA,SAAS,QAAQ,SAAS;AAC1B,SAAkB,qBAAqB,cAAc;AAoB7C,gBAAAE,MAgBA,QAAAC,aAhBA;AAZD,IAAM,cAAoC,CAAC,UAA4B;AAC1E,QAAM;AAAA,IAAE;AAAA,IAAY,UAAU;AAAA,IAAO;AAAA,IAAc;AAAA,IAAe,cAAc;AAAA,IAAY;AAAA,IACxF;AAAA,IAAe,GAAG;AAAA,EAAU,IAAI;AACpC,QAAM,QAAQ,OAAyB,IAAI;AAC3C,sBAAoB,KAAK,MAAM;AAC3B,WAAO,MAAM;AAAA,EACjB,CAAC;AACD,SAAQ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACL;AAAA,MACA,KAAK,UAAU;AAAA,MACf,WAAW;AAAA,MAEX;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACI,GAAG;AAAA,YACJ,KAAK;AAAA,YACL,MAAK;AAAA,YACL,aAAW,WAAW,UAAU,WAAW;AAAA,YAC3C,eAAe,CAAC,SAAS;AACrB,8BAAgB,IAAI;AAAA,YACxB;AAAA;AAAA,QACJ;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACG,eAAY;AAAA,YAEZ,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACG,MAAM;AAAA;AAAA,YACV;AAAA;AAAA,QACJ;AAAA,QACA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACG,OAAM;AAAA,YAEL;AAAA,yBAAY,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACV,MAAK;AAAA,kBAEJ;AAAA;AAAA,cACL;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACG,QAAO;AAAA,kBACP,cAAY;AAAA,kBACZ,UAAU,UAAU,YAAY,UAAU;AAAA,kBAC1C,SAAS,MAAM;AACX,0BAAM,UAAU,MAAM;AACtB,wBAAI,CAAC,WAAW,QAAQ,QAAQ,WAAW,KAAK,QAAQ,UAAU;AAC9D;AAAA,oBACJ;AACA,wBAAI,QAAQ,UAAU,IAAI;AACtB,0BAAI,UAAU,UAAU,QAAW;AAC/B,gCAAQ,QAAQ;AAAA,sBACpB;AACA,sCAAgB,EAAE;AAAA,oBACtB;AACA,4BAAQ,MAAM;AAAA,kBAClB;AAAA,kBAEA,0BAAAA;AAAA,oBAAC;AAAA;AAAA,sBACG,eAAY;AAAA;AAAA,kBAChB;AAAA;AAAA,cACJ;AAAA;AAAA;AAAA,QACJ;AAAA;AAAA;AAAA,EACJ;AACJ;;;ACzEA,SAAS,gBAAgB,oBAAoB;AAuBrC,gBAAAE,YAAA;AAbD,IAAM,eAAsC,CAAC,UAA6B;AAC7E,QAAM,EAAE,SAAS,OAAO,WAAW,UAAU,GAAG,UAAU,IAAI;AAC9D,QAAM,OAAO,YAAY,SAAS,iBAAiB;AACnD,SAAQ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACJ,GAAG;AAAA,MACJ,MAAK;AAAA,MACL,WAAU;AAAA,MACV,gBAAc;AAAA,MACd,iBAAe,YAAY;AAAA,MAC3B,cAAY;AAAA,MACZ,iBAAe;AAAA,MACf,qBAAkB;AAAA,MAElB,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACG,MAAM;AAAA,UACN,eAAY;AAAA;AAAA,MAChB;AAAA;AAAA,EACJ;AACJ;;;AC3BA,SAAS,OAAAC,YAAW;AAEb,IAAM,iBAAiBA,KAAI,cAAc,GAAG;AAAA,EAC/C,UAAU;AAAA,IACN,SAAS;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACX;AAAA,EACJ;AACJ,CAAC;;;ACdD,SAAS,iBAAiB,UAAAC,SAAQ,YAAAC,iBAAgB;AAE3C,IAAM,0BAA0B,CAAC,YAAqB;AACzD,QAAM,MAAMD,QAAuB,IAAI;AACvC,QAAM;AAAA,IACF;AAAA,IACA;AAAA,EACJ,IAAIC,UAAiB;AACrB,kBAAgB,MAAM;AAClB,UAAM,SAAS,IAAI;AACnB,QAAI,CAAC,WAAW,CAAC,QAAQ;AACrB;AAAA,IACJ;AACA,UAAM,UAAU,MAAM;AAClB,gBAAU,WAAW,OAAO,cAAc,YAAa,iBAAiB,MAAM,EAAE,MAAM,CAAC;AAAA,IAC3F;AACA,YAAQ;AACR,UAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,aAAS,QAAQ,MAAM;AACvB,WAAO,MAAM;AACT,eAAS,WAAW;AAAA,IACxB;AAAA,EACJ,GAAG,CAAC,OAAO,CAAC;AACZ,SAAO;AAAA,IACH;AAAA,IACA,QAAQ,UAAU,SAAS;AAAA,EAC/B;AACJ;;;AC3BA,SAAS,qBAAqB,iCAAiC;AAC/D,SAAyE,aAAa,WAAW,mBAAAC,kBAAiB,UAAAC,SAAQ,YAAAC,iBAAgB;AAmB1I,IAAM,oBAAoB,CAAC,UAA0B;AACjD,QAAM,QAAQ,MAAM,cAAc,YAAa,iBAAiB,KAAK;AACrE,SAAO;AAAA,IACH,QAAQ,WAAW,MAAM,MAAM;AAAA,IAC/B,SAAS,MAAM,cAAc,SAAS,SAAY,MAAM;AAAA,IACxD,OAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,gBAAgB;AAAA,EACxE;AACJ;AAEA,IAAM,cAAc,CAAC,SAAqB;AACtC,OAAK,QAAQ;AACb,MAAI,KAAK,OAAO,kBAAkB,KAAK,SAAS,GAAG;AAC/C,SAAK,OAAO,sBAAsB,KAAK,SAAS;AAAA,EACpD;AACJ;AAEO,IAAM,oBAAoB,CAAC,EAAE,OAAO,OAAO,SAAS,SAAS,MAI/D;AACD,QAAM;AAAA,IACF;AAAA,IACA;AAAA,EACJ,IAAIA,UAAkC;AACtC,QAAM;AAAA,IACF;AAAA,IACA;AAAA,EACJ,IAAIA,UAAS,KAAK;AAClB,QAAM,OAAOD,QAAoB,IAAI;AACrC,QAAM,UAAU,MAAe;AAC3B,WAAO,CAAC,WAAW,YAAY,CAAC,MAAM,WAAW,MAAM,QAAQ,QAAQ,WAAW,KAAK,MAAM,QAAQ;AAAA,EACzG;AACA,QAAM,SAAS,CAAC,YAA2B;AACvC,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,QAAQ;AACT;AAAA,IACJ;AACA,SAAK,UAAU;AACf,gBAAY,MAAM;AAClB,QAAI,SAAS;AACT,gBAAU,OAAO,cAAc;AAAA,IACnC;AACA,gBAAY,KAAK;AAAA,EACrB;AACA,QAAM,SAASA,QAAO,MAAM;AACxB;AAAA,EACJ,CAAC;AACD,EAAAD,iBAAgB,MAAM;AAClB,WAAO,UAAU,MAAM;AACnB,aAAO,IAAI;AAAA,IACf;AACA,QAAI,QAAQ,GAAG;AACX,aAAO,IAAI;AAAA,IACf;AAAA,EACJ,CAAC;AACD,EAAAA,iBAAgB,MAAM;AAClB,QAAI,CAAC,SAAS;AACV,gBAAU,MAAS;AAAA,IACvB;AAAA,EACJ,GAAG,CAAC,OAAO,CAAC;AACZ,YAAU,MAAM;AACZ,WAAO,MAAM;AACT,aAAO,QAAQ;AAAA,IACnB;AAAA,EACJ,GAAG,CAAC,CAAC;AACL,QAAM,YAAY,YAAY,CAAC,WAAqC;AAChE,QAAI,CAAC,QAAQ;AACT;AAAA,IACJ;AACA,WAAO,MAAM;AACT,UAAI,OAAO,cAAc,kBAAkB,QAAQ;AAC/C,cAAM,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,MAChD;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,KAAK,CAAC;AACV,QAAM,SAAS,CAAC,SAAwC;AACpD,QAAI,QAAQ,KAAK,CAAC,MAAM,SAAS;AAC7B,aAAO,IAAI;AACX;AAAA,IACJ;AAEA,cAAU,OAAO,SAAS,WAAW,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI;AAAA,EACjE;AACA,QAAM,QAAQ,MAAY;AACtB,QAAI,CAAC,QAAQ,GAAG;AACZ,aAAO,KAAK;AACZ,gBAAU,MAAS;AAAA,IACvB;AAAA,EACJ;AACA,QAAM,cAA+C;AAAA,IACjD,KAAK;AAAA,IACL,eAAe,CAAC,UAAU;AACtB,UAAI,QAAQ,KAAK,MAAM,WAAW,KAAK,CAAC,MAAM,aAAa,KAAK,WAAW,CAAC,MAAM,SAAS;AACvF;AAAA,MACJ;AACA,YAAM,SAAS,kBAAkB,MAAM,OAAO;AAC9C,YAAM,SAAS,MAAM;AACrB,YAAM,eAAe;AACrB,aAAO,MAAM,EAAE,eAAe,KAAK,CAAC;AACpC,WAAK,UAAU;AAAA,QACX,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,aAAa,OAAO;AAAA,QACpB,gBAAgB;AAAA,QAChB,OAAO,OAAO;AAAA,QACd;AAAA,QACA,SAAS,0BAA0B,QAAQ,MAAM;AAC7C,iBAAO,QAAQ;AAAA,QACnB,CAAC;AAAA,MACL;AACA,aAAO,kBAAkB,MAAM,SAAS;AACxC,kBAAY,IAAI;AAAA,IACpB;AAAA,IACA,eAAe,CAAC,UAAU;AACtB,YAAM,SAAS,KAAK;AACpB,UAAI,QAAQ,cAAc,MAAM,WAAW;AACvC,eAAO,OAAO,eAAe,MAAM,UAAU,OAAO,UAAU,OAAO,KAAK;AAAA,MAC9E;AAAA,IACJ;AAAA,IACA,aAAa,CAAC,UAAU;AACpB,UAAI,KAAK,SAAS,cAAc,MAAM,WAAW;AAC7C,eAAO,QAAQ,CAAC;AAAA,MACpB;AAAA,IACJ;AAAA,IACA,iBAAiB,CAAC,UAAU;AACxB,UAAI,KAAK,SAAS,cAAc,MAAM,WAAW;AAC7C,eAAO,IAAI;AAAA,MACf;AAAA,IACJ;AAAA,IACA,sBAAsB,CAAC,UAAU;AAC7B,UAAI,KAAK,SAAS,cAAc,MAAM,WAAW;AAC7C,eAAO,IAAI;AAAA,MACf;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,UAAU;AAClB,UAAI,QAAQ,KAAK,KAAK,WAAW,CAAC,MAAM,WAAW,oBAAoB,MAAM,WAAW,GAAG;AACvF;AAAA,MACJ;AACA,YAAM,SAAS,kBAAkB,MAAM,OAAO;AAC9C,YAAM,OAAO,MAAM,WAAW,KAAK;AACnC,UAAI;AACJ,cAAQ,MAAM,KAAK;AAAA,QACf,KAAK;AAAW,iBAAO,OAAO,SAAS;AAAM;AAAA,QAC7C,KAAK;AAAa,iBAAO,OAAO,SAAS;AAAM;AAAA,QAC/C,KAAK;AAAQ,iBAAO;AAAG;AAAA,QACvB,KAAK;AACD,cAAI,OAAO,YAAY,QAAW;AAC9B;AAAA,UACJ;AACA,iBAAO,OAAO;AACd;AAAA,QACJ;AAAS;AAAA,MACb;AACA,YAAM,eAAe;AACrB,aAAO,IAAI;AAAA,IACf;AAAA,IACA,SAAS,CAAC,UAAU;AAEhB,UAAI,MAAM,WAAW,GAAG;AACpB,cAAM;AAAA,MACV;AAAA,IACJ;AAAA,IACA,eAAe;AAAA,EACnB;AACA,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;ACxLA,SAAS,qBAAqB;AAC9B,SAAS,MAAAG,WAAU;AACnB,SAAkF,OAAO,uBAAAC,sBAAqB,UAAAC,eAAc;AA2C/F,gBAAAC,MAmDL,QAAAC,aAnDK;AA/BtB,IAAM,WAA8B,CAAC,UAAyB;AACjE,QAAM,YAAY,kBAAkB;AACpC,QAAM;AAAA,IAAE,cAAc,aAAa;AAAA,IAAY;AAAA,IAAW;AAAA,IAAU;AAAA,IAAe;AAAA,IAAK,WAAW;AAAA,IAC/F;AAAA,IAAW;AAAA,IAAS,OAAO;AAAA,IAAG;AAAA,IAAO,eAAe;AAAA,IAAQ,cAAc;AAAA,IAAoB;AAAA,IAAQ,GAAG;AAAA,EAAU,IAAI;AAC3H,MAAI,cAAc,WAAc,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa,IAAI;AAC5E,UAAM,IAAI,WAAW,iDAAiD;AAAA,EAC1E;AACA,MAAI,YAAY,WAAc,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,OAAO;AAC7E,UAAM,IAAI,WAAW,gEAAgE;AAAA,EACzF;AACA,MAAI,cAAc,UAAa,YAAY,QAAW;AAClD,UAAM,IAAI,WAAW,yDAAyD;AAAA,EAClF;AACA,QAAM,QAAQF,QAAuB,IAAI;AACzC,QAAM,QAAQA,QAA4B,IAAI;AAC9C,QAAM,cAAc,MAAM;AAC1B,QAAM,UAAU,UAAU,MAAM;AAChC,EAAAD,qBAAoB,KAAK,MAAM;AAC3B,WAAO,MAAM;AAAA,EACjB,GAAG,CAAC,CAAC;AACL,QAAM,YAAY,cAAmC,EAAE,KAAK,MAAM,CAAC;AACnE,QAAM,SAAS,CAAC,YAAY,iBAAiB;AAC7C,QAAM,SAAS,kBAAkB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU,QAAQ,UAAU,QAAQ;AAAA,EACxC,CAAC;AACD,QAAM,YAAY,WAAW,UAAa,WAAW,QAAQ,OAAO,WAAW;AAC/E,QAAM,aAAa,aAAa,UAAU,iBAAiB;AAC3D,QAAM,eAAe,wBAAwB,UAAU;AACvD,QAAM,SAAS,SAAU,gBAAAE;AAAA,IAAC;AAAA;AAAA,MACrB,GAAG,OAAO;AAAA,MACX,SAAS;AAAA,MACT,OAAO;AAAA,MACP,WAAW;AAAA,MACX,UAAU,OAAO;AAAA,MACjB,UAAU,UAAU;AAAA;AAAA,EACxB,IAAM;AACN,QAAM,SAA6E;AAAA,IAC/E,2BAA2B;AAAA,IAC3B,+BAA+B;AAAA,IAC/B,oCAAoC,aAAa,WAAW,SAAY,SAAY,GAAG,aAAa,MAAM;AAAA,IAC1G,GAAG;AAAA,IACH,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAI,UAAU,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,EAC7E;AACA,SAAQ,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AAAA,MACf,MAAM,UAAU;AAAA,MAChB,QAAQ,UAAU;AAAA,MAClB,OAAO,UAAU;AAAA,MACjB,OAAO;AAAA,MACP,WAAWJ,IAAG,eAAe;AAAA,QACzB,SAAS,QAAQ,UAAU,cAAc,CAAC,KAAK,UAAU,cAAc,MAAM;AAAA,QAC7E,SAAS,cAAc;AAAA,MAC3B,CAAC,GAAG,yBAAyB,SAAS;AAAA,MACtC,8BAA4B,cAAc,OAAO,KAAK;AAAA,MACtD,qBAAmB;AAAA,MACnB,gBAAc,cAAc,QAAQ;AAAA,MACpC,iBAAe,YAAY;AAAA,MAC3B,iBAAe,YAAY,UAAa;AAAA,MACxC,sBAAoB,SAAS,eAAe;AAAA,MAC5C,eAAa,aAAa;AAAA,MAE1B;AAAA,wBAAAG;AAAA,UAAC;AAAA;AAAA,YACI,GAAG;AAAA,YACJ,IAAI;AAAA,YACJ,KAAK;AAAA,YACL;AAAA,YACA,UAAU,CAAC,UAAU;AACjB,yBAAW,KAAK;AAChB,8BAAgB,MAAM,cAAc,KAAK;AAAA,YAC7C;AAAA,YACA,WAAU;AAAA;AAAA,QACd;AAAA,QACC,UAAU,iBAAiB,YAAa,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACtC,WAAU;AAAA,YAET;AAAA;AAAA,QACL;AAAA,QACC,cAAe,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACb,KAAK,aAAa;AAAA,YAClB,WAAU;AAAA,YAEV;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACG,WAAU;AAAA,kBAET;AAAA;AAAA,cACL;AAAA,cACC,iBAAiB,YAAY;AAAA;AAAA;AAAA,QAClC;AAAA;AAAA;AAAA,EACJ;AACJ;",
|
|
6
|
+
"names": ["cva", "cn", "cn", "jsx", "cn", "jsx", "cn", "jsx", "cn", "cva", "cn", "jsx", "jsx", "jsxs", "jsx", "jsxs", "jsx", "cva", "useRef", "useState", "useLayoutEffect", "useRef", "useState", "cn", "useImperativeHandle", "useRef", "jsx", "jsxs"]
|
|
7
7
|
}
|
package/dist/styles.css
CHANGED
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
.gridui-u-input--inline-flex {
|
|
9
9
|
display: inline-flex;
|
|
10
10
|
}
|
|
11
|
-
.gridui-u-input--min-h-\(--_gridui-textarea-min-height\) {
|
|
12
|
-
min-height: var(--_gridui-textarea-min-height);
|
|
13
|
-
}
|
|
14
11
|
.gridui-u-input--min-h-gridui-control {
|
|
15
12
|
min-height: var(--gridui-control-min-height);
|
|
16
13
|
}
|
|
@@ -32,21 +29,12 @@
|
|
|
32
29
|
.gridui-u-input--shrink-0 {
|
|
33
30
|
flex-shrink: 0;
|
|
34
31
|
}
|
|
35
|
-
.gridui-u-input--resize-none {
|
|
36
|
-
resize: none;
|
|
37
|
-
}
|
|
38
|
-
.gridui-u-input--resize-y {
|
|
39
|
-
resize: vertical;
|
|
40
|
-
}
|
|
41
32
|
.gridui-u-input--items-center {
|
|
42
33
|
align-items: center;
|
|
43
34
|
}
|
|
44
35
|
.gridui-u-input--gap-gridui-4 {
|
|
45
36
|
gap: var(--gridui-space-4);
|
|
46
37
|
}
|
|
47
|
-
.gridui-u-input--overflow-auto {
|
|
48
|
-
overflow: auto;
|
|
49
|
-
}
|
|
50
38
|
.gridui-u-input--rounded-control {
|
|
51
39
|
border-radius: var(--gridui-control-radius);
|
|
52
40
|
}
|
|
@@ -65,6 +53,12 @@
|
|
|
65
53
|
.gridui-u-input--border-border {
|
|
66
54
|
border-color: var(--gridui-border);
|
|
67
55
|
}
|
|
56
|
+
.gridui-u-input--border-danger-foreground {
|
|
57
|
+
border-color: var(--gridui-danger-foreground);
|
|
58
|
+
}
|
|
59
|
+
.gridui-u-input--border-inherit {
|
|
60
|
+
border-color: inherit;
|
|
61
|
+
}
|
|
68
62
|
.gridui-u-input--bg-background {
|
|
69
63
|
background-color: var(--gridui-background);
|
|
70
64
|
}
|
|
@@ -130,20 +124,20 @@
|
|
|
130
124
|
background: transparent;
|
|
131
125
|
outline: none;
|
|
132
126
|
}
|
|
133
|
-
>
|
|
127
|
+
> .gridui-textarea-frame {
|
|
134
128
|
flex-basis: 100%;
|
|
135
129
|
width: 100%;
|
|
136
130
|
}
|
|
137
|
-
&:has(> .gridui-control:focus-visible) {
|
|
131
|
+
&:has(> .gridui-control:focus-visible, > .gridui-textarea-frame > textarea:focus-visible) {
|
|
138
132
|
z-index: var(--gridui-z-interaction);
|
|
139
133
|
outline: var(--gridui-focus-width) solid var(--gridui-focus-color);
|
|
140
134
|
outline-offset: var(--gridui-focus-offset);
|
|
141
135
|
}
|
|
142
|
-
&:has(> .gridui-control[aria-invalid="true"]) {
|
|
136
|
+
&:has(> .gridui-control[aria-invalid="true"], > .gridui-textarea-frame > textarea[aria-invalid="true"]) {
|
|
143
137
|
border-color: var(--gridui-danger-foreground);
|
|
144
138
|
}
|
|
145
139
|
@media (hover: hover) and (pointer: fine) {
|
|
146
|
-
&:has(> .gridui-control:hover:not(:disabled, [readonly])):not(:has(:focus-visible)) {
|
|
140
|
+
&:has(> .gridui-control:not(.gridui-textarea-frame):hover:not(:disabled, [readonly]), > .gridui-textarea-frame > textarea:hover:not(:disabled, [readonly])):not(:has(:focus-visible)) {
|
|
147
141
|
outline: var(--gridui-hover-width) solid var(--gridui-focus-color);
|
|
148
142
|
@supports (color: color-mix(in lab, red, red)) {
|
|
149
143
|
outline: var(--gridui-hover-width) solid color-mix(in srgb, var(--gridui-focus-color) var(--gridui-hover-opacity), transparent);
|
|
@@ -177,18 +171,149 @@
|
|
|
177
171
|
.gridui-input-group-button {
|
|
178
172
|
flex: none;
|
|
179
173
|
}
|
|
180
|
-
.gridui-textarea
|
|
181
|
-
--_gridui-textarea-
|
|
182
|
-
--_gridui-textarea-minimum: var(--gridui-control-min-height);
|
|
174
|
+
.gridui-textarea-frame {
|
|
175
|
+
--_gridui-textarea-padding: var(--gridui-space-8);
|
|
176
|
+
--_gridui-textarea-control-minimum: var(--gridui-control-min-height);
|
|
177
|
+
--_gridui-textarea-resize-height: 0px;
|
|
178
|
+
--_gridui-textarea-footer-height: 0px;
|
|
179
|
+
--_gridui-textarea-border: 2px;
|
|
180
|
+
--_gridui-textarea-min-body: max(calc(var(--_gridui-textarea-control-minimum) - 2px), calc(var(--_gridui-textarea-rows) * 1lh + 2 * var(--_gridui-textarea-padding)));
|
|
181
|
+
--_gridui-textarea-chrome: calc(var(--_gridui-textarea-resize-height) + var(--_gridui-textarea-footer-height) + var(--_gridui-textarea-border));
|
|
182
|
+
position: relative;
|
|
183
|
+
display: flex;
|
|
184
|
+
flex-direction: column;
|
|
185
|
+
min-height: calc(var(--_gridui-textarea-min-body) + var(--_gridui-textarea-chrome));
|
|
186
|
+
padding: 0;
|
|
187
|
+
&[data-control-size="small"] {
|
|
188
|
+
--_gridui-textarea-padding: var(--gridui-space-4);
|
|
189
|
+
--_gridui-textarea-control-minimum: var(--gridui-control-min-height-small);
|
|
190
|
+
}
|
|
191
|
+
&[data-grouped] {
|
|
192
|
+
--_gridui-textarea-border: 0px;
|
|
193
|
+
}
|
|
194
|
+
&[data-resize-handle="edge"] {
|
|
195
|
+
--_gridui-textarea-resize-height: var(--gridui-space-24);
|
|
196
|
+
}
|
|
197
|
+
&[data-resize-handle="corner"] {
|
|
198
|
+
--_gridui-textarea-resize-height: var(--gridui-space-32);
|
|
199
|
+
}
|
|
200
|
+
&:is([data-resize-handle="footer"], [data-footer]) {
|
|
201
|
+
--_gridui-textarea-footer-height: var(--gridui-control-min-height);
|
|
202
|
+
}
|
|
203
|
+
&[data-max-rows] {
|
|
204
|
+
max-height: calc(var(--_gridui-textarea-max-rows) * 1lh + 2 * var(--_gridui-textarea-padding) + var(--_gridui-textarea-chrome));
|
|
205
|
+
}
|
|
206
|
+
&:not([data-grouped]):has(> textarea:focus-visible) {
|
|
207
|
+
outline: var(--gridui-focus-width) solid var(--gridui-focus-color);
|
|
208
|
+
outline-offset: var(--gridui-focus-offset);
|
|
209
|
+
}
|
|
210
|
+
@media (hover: hover) and (pointer: fine) {
|
|
211
|
+
&:not([data-grouped]):has(> textarea:hover:not(:disabled, [readonly])):not(:has(:focus-visible)) {
|
|
212
|
+
outline: var(--gridui-hover-width) solid var(--gridui-focus-color);
|
|
213
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
214
|
+
outline: var(--gridui-hover-width) solid color-mix(in srgb, var(--gridui-focus-color) var(--gridui-hover-opacity), transparent);
|
|
215
|
+
}
|
|
216
|
+
outline-offset: var(--gridui-hover-offset);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
.gridui-textarea {
|
|
221
|
+
display: block;
|
|
222
|
+
flex: 1 1 auto;
|
|
223
|
+
min-width: 0;
|
|
224
|
+
min-height: 0;
|
|
225
|
+
width: 100%;
|
|
226
|
+
margin: 0;
|
|
227
|
+
padding: var(--_gridui-textarea-padding) var(--gridui-space-8);
|
|
228
|
+
border: 0;
|
|
229
|
+
border-radius: 0;
|
|
230
|
+
color: inherit;
|
|
231
|
+
background: transparent;
|
|
232
|
+
font: inherit;
|
|
233
|
+
resize: none;
|
|
234
|
+
outline: none;
|
|
235
|
+
overflow: auto;
|
|
236
|
+
box-sizing: border-box;
|
|
237
|
+
&:disabled {
|
|
238
|
+
opacity: 0.5;
|
|
239
|
+
cursor: not-allowed;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
.gridui-textarea-frame[data-autosize] > .gridui-textarea {
|
|
183
243
|
field-sizing: content;
|
|
184
244
|
height: auto;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
245
|
+
}
|
|
246
|
+
.gridui-textarea-resize-row {
|
|
247
|
+
display: flex;
|
|
248
|
+
flex: none;
|
|
249
|
+
justify-content: flex-end;
|
|
250
|
+
height: var(--_gridui-textarea-resize-height);
|
|
251
|
+
border-color: inherit;
|
|
252
|
+
}
|
|
253
|
+
.gridui-textarea-footer {
|
|
254
|
+
display: flex;
|
|
255
|
+
flex: none;
|
|
256
|
+
align-items: stretch;
|
|
257
|
+
min-height: var(--gridui-control-min-height);
|
|
258
|
+
border-top: 1px solid;
|
|
259
|
+
border-color: inherit;
|
|
260
|
+
background: var(--gridui-surface);
|
|
261
|
+
box-sizing: border-box;
|
|
262
|
+
}
|
|
263
|
+
.gridui-textarea-footer-content {
|
|
264
|
+
display: flex;
|
|
265
|
+
flex: 1;
|
|
266
|
+
flex-wrap: wrap;
|
|
267
|
+
align-items: center;
|
|
268
|
+
gap: var(--gridui-space-8);
|
|
269
|
+
min-width: 0;
|
|
270
|
+
padding: var(--gridui-space-8);
|
|
271
|
+
}
|
|
272
|
+
.gridui-textarea-resize-handle {
|
|
273
|
+
display: flex;
|
|
274
|
+
flex: none;
|
|
275
|
+
align-items: center;
|
|
276
|
+
justify-content: center;
|
|
277
|
+
width: var(--gridui-control-min-height);
|
|
278
|
+
margin: 0;
|
|
279
|
+
padding: 0;
|
|
280
|
+
border: 0;
|
|
281
|
+
border-radius: 0;
|
|
282
|
+
border-color: inherit;
|
|
283
|
+
color: var(--gridui-muted);
|
|
284
|
+
background: transparent;
|
|
285
|
+
cursor: ns-resize;
|
|
286
|
+
touch-action: none;
|
|
287
|
+
user-select: none;
|
|
288
|
+
&[data-variant="edge"] {
|
|
289
|
+
width: 100%;
|
|
290
|
+
border-top: 1px solid;
|
|
291
|
+
border-color: inherit;
|
|
292
|
+
background: var(--gridui-surface);
|
|
189
293
|
}
|
|
190
|
-
&[data-
|
|
191
|
-
|
|
294
|
+
&[data-variant="corner"] {
|
|
295
|
+
border-top: 1px solid;
|
|
296
|
+
border-inline-start: 1px solid;
|
|
297
|
+
border-color: inherit;
|
|
298
|
+
}
|
|
299
|
+
&[data-variant="footer"] {
|
|
300
|
+
border-inline-start: 1px solid;
|
|
301
|
+
border-color: inherit;
|
|
302
|
+
}
|
|
303
|
+
&:disabled {
|
|
304
|
+
cursor: not-allowed;
|
|
305
|
+
> svg {
|
|
306
|
+
opacity: 0.5;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
&:is(:hover, [data-dragging]):not(:disabled) {
|
|
310
|
+
color: var(--gridui-foreground);
|
|
311
|
+
background: var(--gridui-surface);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
@media (pointer: coarse) {
|
|
315
|
+
.gridui-textarea-frame:is([data-resize-handle="corner"], [data-resize-handle="edge"]) {
|
|
316
|
+
--_gridui-textarea-resize-height: var(--gridui-control-min-height);
|
|
192
317
|
}
|
|
193
318
|
}
|
|
194
319
|
.gridui-input-group > input[type="search"]::-webkit-search-cancel-button {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Input
|
|
4
|
+
* @namespace Textarea
|
|
5
|
+
* @description Resize Handle
|
|
6
|
+
*/
|
|
7
|
+
import type { ComponentPropsWithRef, FC } from "react";
|
|
8
|
+
export type ResizeHandleProps = ComponentPropsWithRef<"button"> & {
|
|
9
|
+
readonly variant: "corner" | "edge" | "footer";
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly controlId: string;
|
|
12
|
+
readonly dragging: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare const ResizeHandle: FC<ResizeHandleProps>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Input
|
|
4
|
+
* @namespace Textarea
|
|
5
|
+
* @description Style
|
|
6
|
+
*/
|
|
7
|
+
export declare const textareaStyles: (props?: ({
|
|
8
|
+
invalid?: boolean | null | undefined;
|
|
9
|
+
grouped?: boolean | null | undefined;
|
|
10
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* @description Textarea
|
|
6
6
|
*/
|
|
7
7
|
import type { TextControlOptions } from "../shared/text-control-options";
|
|
8
|
-
import { type ComponentPropsWithRef, type FC } from "react";
|
|
8
|
+
import { type ComponentPropsWithRef, type FC, type ReactNode } from "react";
|
|
9
9
|
export type TextareaProps = ComponentPropsWithRef<"textarea"> & TextControlOptions & {
|
|
10
10
|
readonly autoSize?: boolean;
|
|
11
11
|
readonly maxHeight?: number;
|
|
12
12
|
readonly maxRows?: number;
|
|
13
|
+
/** Manual resize affordance. Automatic sizing always hides it. */
|
|
14
|
+
readonly resizeHandle?: "corner" | "edge" | "footer" | false;
|
|
15
|
+
readonly resizeLabel?: string;
|
|
16
|
+
/** Caller-owned footer content; footer handles share this row. */
|
|
17
|
+
readonly footer?: ReactNode;
|
|
13
18
|
};
|
|
14
19
|
export declare const Textarea: FC<TextareaProps>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Input
|
|
4
|
+
* @namespace Textarea
|
|
5
|
+
* @description Use Textarea Footer Height
|
|
6
|
+
*/
|
|
7
|
+
export declare const useTextareaFooterHeight: (visible: boolean) => {
|
|
8
|
+
ref: import("react").RefObject<HTMLDivElement | null>;
|
|
9
|
+
height: number | undefined;
|
|
10
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Input
|
|
4
|
+
* @namespace Textarea
|
|
5
|
+
* @description Use Textarea Resize
|
|
6
|
+
*/
|
|
7
|
+
import { type ComponentPropsWithRef, type CSSProperties, type RefObject } from "react";
|
|
8
|
+
type ResizeOptions = {
|
|
9
|
+
readonly frame: RefObject<HTMLDivElement | null>;
|
|
10
|
+
readonly input: RefObject<HTMLTextAreaElement | null>;
|
|
11
|
+
readonly enabled: boolean;
|
|
12
|
+
readonly disabled: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare const useTextareaResize: ({ frame, input, enabled, disabled }: ResizeOptions) => {
|
|
15
|
+
height: CSSProperties["height"];
|
|
16
|
+
dragging: boolean;
|
|
17
|
+
handleProps: ComponentPropsWithRef<"button">;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
package/docs/catalog.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "@gridui/input",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.1",
|
|
5
5
|
"category": "core",
|
|
6
6
|
"description": "GridUI React input",
|
|
7
7
|
"usage": "`Label` owns inline label alignment and an optional decorative `icon` slot. Icons use the standard 16px token size without an ancestor layout styling labels.",
|
|
@@ -114,10 +114,13 @@
|
|
|
114
114
|
],
|
|
115
115
|
"examples": [
|
|
116
116
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/addons.mdx",
|
|
117
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/getting-started.mdx",
|
|
117
118
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/multiline.mdx",
|
|
118
119
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/password-entry.mdx",
|
|
119
120
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/search-entry.mdx",
|
|
121
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/text-fields.mdx",
|
|
120
122
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/input-group.stories.tsx",
|
|
123
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/input.stories.tsx",
|
|
121
124
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/password-input.stories.tsx",
|
|
122
125
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/search-input.stories.tsx",
|
|
123
126
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/textarea.stories.tsx"
|
package/docs/reference/input.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
|
|
2
2
|
# Input
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Start with a labeled native text input. Add a Form composition when submission or validation needs its own workflow.
|
|
5
5
|
|
|
6
6
|
Import from ``@gridui/input`` and load Theme before this family's stylesheet.
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ import "@gridui/input/styles.css";
|
|
|
13
13
|
|
|
14
14
|
Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/README.md) for shared behavior and stylesheet dependencies.
|
|
15
15
|
|
|
16
|
-
The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/
|
|
16
|
+
The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/input/stories/input.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
|
|
17
17
|
|
|
18
18
|
## API
|
|
19
19
|
|
|
@@ -87,3 +87,23 @@ Default: ``false``
|
|
|
87
87
|
|
|
88
88
|
``number | undefined`` · Optional
|
|
89
89
|
|
|
90
|
+
### resizeHandle
|
|
91
|
+
|
|
92
|
+
``false | "footer" | "corner" | "edge" | undefined`` · Optional
|
|
93
|
+
|
|
94
|
+
Default: ``"edge"``
|
|
95
|
+
|
|
96
|
+
Manual resize affordance. Automatic sizing always hides it.
|
|
97
|
+
|
|
98
|
+
### resizeLabel
|
|
99
|
+
|
|
100
|
+
``string | undefined`` · Optional
|
|
101
|
+
|
|
102
|
+
Default: ``"Resize text area"``
|
|
103
|
+
|
|
104
|
+
### footer
|
|
105
|
+
|
|
106
|
+
``ReactNode`` · Optional
|
|
107
|
+
|
|
108
|
+
Caller-owned footer content; footer handles share this row.
|
|
109
|
+
|
package/docs/textarea.md
CHANGED
|
@@ -1,35 +1,74 @@
|
|
|
1
1
|
# Textarea
|
|
2
2
|
|
|
3
|
-
Textarea
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Textarea composes a native multiline input, one structural frame, and an optional
|
|
4
|
+
resize handle/footer. Native props, events and refs target the textarea, including
|
|
5
|
+
id, name, form, value/defaultValue, rows, required, maxLength and ARIA. onChange
|
|
6
|
+
runs before onValueChange. Enter and IME retain native multiline behavior.
|
|
6
7
|
Applications own labels, validation, persistence and submission.
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
+
## Resize handles
|
|
9
10
|
|
|
10
|
-
`
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
`resizeHandle` selects `edge` (default), `corner`, `footer`, or `false`. All variants
|
|
12
|
+
resize vertically and share interaction and constraints. Native browser resizing
|
|
13
|
+
is disabled. Read-only content can still resize; disabled controls and disabled
|
|
14
|
+
fieldsets cannot. `resizeLabel` names the handle for assistive technology and can
|
|
15
|
+
be localized; its default is `Resize text area`.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
Drag the handle or focus it and use ArrowUp/ArrowDown (16px, 64px with Shift).
|
|
18
|
+
Home reaches the CSS minimum; End reaches a finite configured maximum. Enter,
|
|
19
|
+
Space, or double-click restores natural height. Escape, pointer cancellation,
|
|
20
|
+
capture loss, and window blur cancel an active drag and restore its prior height.
|
|
21
|
+
The handle is a non-submitting button; it never edits or submits the text.
|
|
22
|
+
Native form reset restores the text but retains a manually chosen height, just
|
|
23
|
+
like native textarea resizing.
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
```tsx
|
|
26
|
+
<Textarea aria-label="Notes" resizeHandle="corner" />
|
|
27
|
+
<Textarea aria-label="Notes" resizeHandle="edge" maxHeight={320} />
|
|
28
|
+
<Textarea aria-label="Notes" resizeHandle="footer" footer={<span>Plain text</span>} />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`footer` is caller-owned content, such as a Form FieldCounter or existing buttons.
|
|
32
|
+
The footer handle shares its row. With corner/edge handles, supplied footer content
|
|
33
|
+
occupies a separate row below the handle. Without manual resizing, footer content
|
|
34
|
+
remains visible. No count, format selector, sending behavior, or business action
|
|
35
|
+
is built into Textarea. Use InputGroup for additional surrounding addons; it owns
|
|
36
|
+
the outer border and outline when grouped. Textarea owns its internal seams.
|
|
37
|
+
|
|
38
|
+
## Size and automatic height
|
|
39
|
+
|
|
40
|
+
`rows` (default 2) sets the minimum text area through inherited line-height and
|
|
41
|
+
control density. Choose either a positive finite pixel `maxHeight` or an integer
|
|
42
|
+
`maxRows >= rows`. These limits apply to both manual and automatic sizing.
|
|
43
|
+
`maxHeight` caps the whole frame; `maxRows` caps text rows and includes space for
|
|
44
|
+
the handle/footer. Footer height follows its actual content, wrapping and font
|
|
45
|
+
metrics, so it does not consume the reserved text rows. CSS minimum height wins
|
|
46
|
+
over a smaller maximum. The browser resolves CSS limits, including percentages
|
|
47
|
+
and calc() expressions; percentage heights need a definite containing-block height.
|
|
48
|
+
|
|
49
|
+
`autoSize` uses CSS `field-sizing: content` and requires browser support for that
|
|
50
|
+
property. It hides the handle and clears manual height without replacing the
|
|
51
|
+
native input. Content, width, fonts, controlled updates and native form reset
|
|
52
|
+
participate in browser layout. Overflow remains auto at a maximum. Avoid a
|
|
53
|
+
competing fixed height when using automatic sizing.
|
|
28
54
|
|
|
29
55
|
```tsx
|
|
30
56
|
<Textarea aria-label="Notes" autoSize rows={3} maxRows={8} />
|
|
31
57
|
```
|
|
32
58
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
59
|
+
## Frame styling and migration
|
|
60
|
+
|
|
61
|
+
`className` and `style` now target the structural frame, including width, height,
|
|
62
|
+
min/max size, border, colors and typography. The native input inherits typography
|
|
63
|
+
and colors. The pixel maxHeight prop overrides style.maxHeight; otherwise caller
|
|
64
|
+
CSS limits remain effective. A manually chosen height overrides style.height until
|
|
65
|
+
reset or automatic sizing. Keep geometry and border overrides on the frame.
|
|
66
|
+
Input-specific padding, placeholder and background styling can target the native
|
|
67
|
+
textarea through its caller-owned id. Keep line-height on the frame so row limits
|
|
68
|
+
and the inherited input typography agree.
|
|
69
|
+
|
|
70
|
+
This is a DOM contract change from the previous bare textarea. Ref, id, native
|
|
71
|
+
attributes and events still target the actual textarea. Update direct-child CSS
|
|
72
|
+
selectors to use the frame or the public InputGroup composition. Browser-native
|
|
73
|
+
resize utilities no longer control the handle; use resizeHandle or autoSize.
|
|
74
|
+
Composer continues to own sending and uses automatic sizing without a handle.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/input",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "GridUI React input",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -27,17 +27,18 @@
|
|
|
27
27
|
"react-dom": "^19.2.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gridui/button": "^
|
|
31
|
-
"@gridui/
|
|
30
|
+
"@gridui/button": "^5.0.1",
|
|
31
|
+
"@gridui/interaction": "^1.2.1",
|
|
32
|
+
"@gridui/overlay": "^2.2.0",
|
|
32
33
|
"@gridui/style-utils": "^4.0.0",
|
|
33
|
-
"@gridui/theme": "^2.
|
|
34
|
+
"@gridui/theme": "^2.6.0",
|
|
34
35
|
"class-variance-authority": "0.7.1",
|
|
35
|
-
"lucide-react": "1.
|
|
36
|
+
"lucide-react": "1.72.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@gridui-internal/configuration": "0.0.0-internal",
|
|
39
40
|
"@jest/globals": "30.5.2",
|
|
40
|
-
"@storybook/react-vite": "10.6.
|
|
41
|
+
"@storybook/react-vite": "10.6.7",
|
|
41
42
|
"@types/jest": "30.0.0",
|
|
42
43
|
"@types/node": "26.6.6",
|
|
43
44
|
"@types/react": "19.3.0",
|
|
@@ -50,7 +51,6 @@
|
|
|
50
51
|
"scripts": {
|
|
51
52
|
"build": "node ../../scripts/compilation/package.ts",
|
|
52
53
|
"compile": "tsc --project tsconfig.json",
|
|
53
|
-
"test": "jest"
|
|
54
|
-
"coverage": "jest --coverage"
|
|
54
|
+
"test": "jest"
|
|
55
55
|
}
|
|
56
56
|
}
|