@ladder-ui/textarea 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,28 +1 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var jsxRuntime = require('react/jsx-runtime');
6
- var concatClassNames = require('@ladder-ui/core/concatClassNames');
7
- var react = require('react');
8
-
9
- function Textarea({ ref, className, size = "md", status = "default", fullWidth = true, resize = "vertical", autoResize = false, disabled, readOnly, onInput, style, ...props }) {
10
- const ariaInvalid = props["aria-invalid"] ?? (status === "error" ? true : undefined);
11
- // Track pending animation frame so rapid typing only triggers one resize per frame
12
- const rafRef = react.useRef(0);
13
- return (jsxRuntime.jsx("textarea", { ref: ref, className: concatClassNames("lui-textarea", `lui-textarea--${size}`, status !== "default" && `lui-textarea--${status}`, !autoResize && resize !== "vertical" && `lui-textarea--resize-${resize}`, fullWidth && "lui-textarea--full-width", className), disabled: disabled, readOnly: readOnly, "aria-invalid": ariaInvalid, onInput: (e) => {
14
- if (autoResize) {
15
- const el = e.currentTarget;
16
- cancelAnimationFrame(rafRef.current);
17
- rafRef.current = requestAnimationFrame(() => {
18
- el.style.height = "auto";
19
- el.style.height = `${el.scrollHeight}px`;
20
- });
21
- }
22
- onInput?.(e);
23
- }, style: autoResize ? { overflow: "hidden", resize: "none", ...style } : style, ...props }));
24
- }
25
- Textarea.displayName = "Textarea";
26
-
27
- exports.Textarea = Textarea;
28
- exports.default = Textarea;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("@ladder-ui/core"),a=require("react");const r=t.cva({base:"lui-textarea",variants:{size:{xs:"lui-textarea--xs",sm:"lui-textarea--sm",md:"lui-textarea--md",lg:"lui-textarea--lg",xl:"lui-textarea--xl"},status:{default:"",error:"lui-textarea--error",success:"lui-textarea--success",warning:"lui-textarea--warning"},resize:{vertical:"",none:"lui-textarea--resize-none",both:"lui-textarea--resize-both",horizontal:"lui-textarea--resize-horizontal"},fullWidth:{true:"lui-textarea--full-width",false:""}},defaultVariants:{size:"md",status:"default",resize:"vertical",fullWidth:!0}});function i({ref:t,className:i,size:s,status:l,fullWidth:u,resize:n,autoResize:o,disabled:d,readOnly:x,onInput:c,style:f,...h}){const z=h["aria-invalid"]??("error"===l||void 0),m=a.useRef(0);return e.jsx("textarea",{ref:t,className:r({size:s,status:l,resize:o?"none":n,fullWidth:u,className:i}),disabled:d,readOnly:x,"aria-invalid":z,onInput:e=>{if(o){const t=e.currentTarget;cancelAnimationFrame(m.current),m.current=requestAnimationFrame(()=>{t.style.height="auto",t.style.height=`${t.scrollHeight}px`})}c?.(e)},style:o?{overflow:"hidden",resize:"none",...f}:f,...h})}i.displayName="Textarea",exports.Textarea=i,exports.default=i;
package/dist/index.mjs CHANGED
@@ -1,23 +1 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import concatClassNames from '@ladder-ui/core/concatClassNames';
3
- import { useRef } from 'react';
4
-
5
- function Textarea({ ref, className, size = "md", status = "default", fullWidth = true, resize = "vertical", autoResize = false, disabled, readOnly, onInput, style, ...props }) {
6
- const ariaInvalid = props["aria-invalid"] ?? (status === "error" ? true : undefined);
7
- // Track pending animation frame so rapid typing only triggers one resize per frame
8
- const rafRef = useRef(0);
9
- return (jsx("textarea", { ref: ref, className: concatClassNames("lui-textarea", `lui-textarea--${size}`, status !== "default" && `lui-textarea--${status}`, !autoResize && resize !== "vertical" && `lui-textarea--resize-${resize}`, fullWidth && "lui-textarea--full-width", className), disabled: disabled, readOnly: readOnly, "aria-invalid": ariaInvalid, onInput: (e) => {
10
- if (autoResize) {
11
- const el = e.currentTarget;
12
- cancelAnimationFrame(rafRef.current);
13
- rafRef.current = requestAnimationFrame(() => {
14
- el.style.height = "auto";
15
- el.style.height = `${el.scrollHeight}px`;
16
- });
17
- }
18
- onInput?.(e);
19
- }, style: autoResize ? { overflow: "hidden", resize: "none", ...style } : style, ...props }));
20
- }
21
- Textarea.displayName = "Textarea";
22
-
23
- export { Textarea, Textarea as default };
1
+ import{jsx as e}from"react/jsx-runtime";import{cva as t}from"@ladder-ui/core";import{useRef as a}from"react";const r=t({base:"lui-textarea",variants:{size:{xs:"lui-textarea--xs",sm:"lui-textarea--sm",md:"lui-textarea--md",lg:"lui-textarea--lg",xl:"lui-textarea--xl"},status:{default:"",error:"lui-textarea--error",success:"lui-textarea--success",warning:"lui-textarea--warning"},resize:{vertical:"",none:"lui-textarea--resize-none",both:"lui-textarea--resize-both",horizontal:"lui-textarea--resize-horizontal"},fullWidth:{true:"lui-textarea--full-width",false:""}},defaultVariants:{size:"md",status:"default",resize:"vertical",fullWidth:!0}});function i({ref:t,className:i,size:l,status:s,fullWidth:u,resize:n,autoResize:o,disabled:d,readOnly:c,onInput:x,style:m,...f}){const h=f["aria-invalid"]??("error"===s||void 0),z=a(0);return e("textarea",{ref:t,className:r({size:l,status:s,resize:o?"none":n,fullWidth:u,className:i}),disabled:d,readOnly:c,"aria-invalid":h,onInput:e=>{if(o){const t=e.currentTarget;cancelAnimationFrame(z.current),z.current=requestAnimationFrame(()=>{t.style.height="auto",t.style.height=`${t.scrollHeight}px`})}x?.(e)},style:o?{overflow:"hidden",resize:"none",...m}:m,...f})}i.displayName="Textarea";export{i as Textarea,i as default};
package/dist/textarea.css CHANGED
@@ -1,86 +1 @@
1
- @layer components {
2
- .lui-textarea {
3
- display: block;
4
- width: 100%;
5
- min-height: 4rem;
6
- background-color: var(--lui-textarea-bg);
7
- color: var(--lui-textarea-text);
8
- border: var(--lui-border-width) solid var(--lui-textarea-border);
9
- border-radius: var(--lui-textarea-radius);
10
- font-family: var(--lui-font-family);
11
- font-weight: var(--lui-font-weight);
12
- line-height: 1.5;
13
- resize: vertical;
14
- outline: none;
15
- transition: var(--lui-transition);
16
- }
17
- .lui-textarea::placeholder {
18
- color: var(--lui-textarea-placeholder);
19
- }
20
- .lui-textarea:focus-visible {
21
- border-color: var(--lui-textarea-focus-border);
22
- box-shadow: 0 0 0 2px var(--lui-textarea-focus-ring-color);
23
- }
24
- .lui-textarea:disabled {
25
- opacity: var(--lui-disabled-opacity);
26
- cursor: var(--lui-disabled-cursor);
27
- pointer-events: none;
28
- }
29
- .lui-textarea[readonly] {
30
- cursor: default;
31
- background-color: var(--lui-surface-raised);
32
- }
33
- .lui-textarea--xs {
34
- padding: 0.25rem 0.5rem;
35
- font-size: var(--lui-font-size-xs);
36
- }
37
- .lui-textarea--sm {
38
- padding: 0.375rem 0.625rem;
39
- font-size: var(--lui-font-size-sm);
40
- }
41
- .lui-textarea--md {
42
- padding: 0.5rem 0.75rem;
43
- font-size: var(--lui-font-size-md);
44
- }
45
- .lui-textarea--lg {
46
- padding: 0.625rem 0.875rem;
47
- font-size: var(--lui-font-size-lg);
48
- }
49
- .lui-textarea--xl {
50
- padding: 0.75rem 1rem;
51
- font-size: var(--lui-font-size-xl);
52
- }
53
- .lui-textarea--error {
54
- border-color: var(--lui-error);
55
- }
56
- .lui-textarea--error:focus-visible {
57
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--lui-error) 40%, transparent);
58
- }
59
- .lui-textarea--success {
60
- border-color: var(--lui-success);
61
- }
62
- .lui-textarea--success:focus-visible {
63
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--lui-success) 40%, transparent);
64
- }
65
- .lui-textarea--warning {
66
- border-color: var(--lui-warning);
67
- }
68
- .lui-textarea--warning:focus-visible {
69
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--lui-warning) 40%, transparent);
70
- }
71
- .lui-textarea--resize-none {
72
- resize: none;
73
- }
74
- .lui-textarea--resize-both {
75
- resize: both;
76
- }
77
- .lui-textarea--resize-horizontal {
78
- resize: horizontal;
79
- }
80
- .lui-textarea--resize-vertical {
81
- resize: vertical;
82
- }
83
- .lui-textarea--full-width {
84
- width: 100%;
85
- }
86
- }
1
+ @layer components{.lui-textarea{background-color:var(--lui-textarea-bg);border:var(--lui-border-width) solid var(--lui-textarea-border);border-radius:var(--lui-textarea-radius);color:var(--lui-textarea-text);display:block;font-family:var(--lui-font-family);font-weight:var(--lui-font-weight);line-height:1.5;min-height:4rem;outline:none;resize:vertical;transition:var(--lui-transition);width:100%}.lui-textarea::placeholder{color:var(--lui-textarea-placeholder)}.lui-textarea:focus-visible{border-color:var(--lui-textarea-focus-border);box-shadow:0 0 0 2px var(--lui-textarea-focus-ring-color)}.lui-textarea:disabled{cursor:var(--lui-disabled-cursor);opacity:var(--lui-disabled-opacity);pointer-events:none}.lui-textarea[readonly]{background-color:var(--lui-bg-surface-raised);cursor:default}.lui-textarea--xs{font-size:var(--lui-font-size-xs);padding:.25rem .5rem}.lui-textarea--sm{font-size:var(--lui-font-size-sm);padding:.375rem .625rem}.lui-textarea--md{font-size:var(--lui-font-size-md);padding:.5rem .75rem}.lui-textarea--lg{font-size:var(--lui-font-size-lg);padding:.625rem .875rem}.lui-textarea--xl{font-size:var(--lui-font-size-xl);padding:.75rem 1rem}.lui-textarea--error{border-color:var(--lui-error)}.lui-textarea--error:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--lui-error) 40%,transparent)}.lui-textarea--success{border-color:var(--lui-success)}.lui-textarea--success:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--lui-success) 40%,transparent)}.lui-textarea--warning{border-color:var(--lui-warning)}.lui-textarea--warning:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--lui-warning) 40%,transparent)}.lui-textarea--resize-none{resize:none}.lui-textarea--resize-both{resize:both}.lui-textarea--resize-horizontal{resize:horizontal}.lui-textarea--resize-vertical{resize:vertical}.lui-textarea--full-width{width:100%}}
@@ -1,5 +1,33 @@
1
+ import { type VariantProps } from "@ladder-ui/core";
1
2
  import type { Ref } from "react";
2
- export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ declare const textareaVariants: (props?: (import("packages/core/dist/cva").ConfigVariants<{
4
+ size: {
5
+ xs: string;
6
+ sm: string;
7
+ md: string;
8
+ lg: string;
9
+ xl: string;
10
+ };
11
+ status: {
12
+ default: string;
13
+ error: string;
14
+ success: string;
15
+ warning: string;
16
+ };
17
+ resize: {
18
+ vertical: string;
19
+ none: string;
20
+ both: string;
21
+ horizontal: string;
22
+ };
23
+ fullWidth: {
24
+ true: string;
25
+ false: string;
26
+ };
27
+ }> & {
28
+ className?: string;
29
+ }) | undefined) => string;
30
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, VariantProps<typeof textareaVariants> {
3
31
  /** React 19 ref — points to the native `<textarea>` element */
4
32
  ref?: Ref<HTMLTextAreaElement>;
5
33
  /** Size variant — controls padding and font size. @default "md" */
@@ -25,3 +53,4 @@ export declare function Textarea({ ref, className, size, status, fullWidth, resi
25
53
  export declare namespace Textarea {
26
54
  var displayName: string;
27
55
  }
56
+ export {};
@@ -1,14 +1 @@
1
- @layer textarea {
2
- :root {
3
- /* Background & text */
4
- --lui-textarea-bg: var(--lui-surface);
5
- --lui-textarea-text: var(--lui-surface-text);
6
- --lui-textarea-placeholder: color-mix(in srgb, var(--lui-surface-text) 40%, transparent);
7
- /* Border */
8
- --lui-textarea-border: color-mix(in srgb, var(--lui-surface-border) 93%, var(--lui-surface-text));
9
- --lui-textarea-focus-border: var(--lui-primary);
10
- --lui-textarea-focus-ring-color: color-mix(in srgb, var(--lui-primary) 40%, transparent);
11
- /* Shape */
12
- --lui-textarea-radius: var(--lui-radius-sm);
13
- }
14
- }
1
+ @layer textarea{:root{--lui-textarea-bg:var(--lui-bg-surface);--lui-textarea-text:var(--lui-text-primary);--lui-textarea-placeholder:color-mix(in srgb,var(--lui-text-primary) 40%,transparent);--lui-textarea-border:color-mix(in srgb,var(--lui-border-default) 93%,var(--lui-text-primary));--lui-textarea-focus-border:var(--lui-bg-interactive);--lui-textarea-focus-ring-color:color-mix(in srgb,var(--lui-bg-interactive) 40%,transparent);--lui-textarea-radius:var(--lui-radius-sm)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ladder-ui/textarea",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -30,7 +30,8 @@
30
30
  "license": "ISC",
31
31
  "repository": {
32
32
  "type": "git",
33
- "url": "git+ssh://git@github.com/ivelaval/ladder-ui.git"
33
+ "url": "https://github.com/ivelaval/ladder-ui.git",
34
+ "directory": "packages/textarea"
34
35
  },
35
36
  "bugs": {
36
37
  "url": "https://github.com/ivelaval/ladder-ui/issues"
@@ -47,7 +48,7 @@
47
48
  "sass": "^1.90.0",
48
49
  "tslib": "^2.6.2",
49
50
  "typescript": "^5.3.3",
50
- "@ladder-ui/core": "0.3.0"
51
+ "@ladder-ui/core": "0.5.0"
51
52
  },
52
53
  "peerDependencies": {
53
54
  "@ladder-ui/core": ">=0.0.0",