@net-advantage/jo-ui-input 1.1.6 → 1.2.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/README.md CHANGED
@@ -24,6 +24,8 @@ flowchart LR
24
24
  | Model | [input.model.ts](src/input.model.ts) | Resolve kind behavior, parse text, and format on blur |
25
25
  | View-model | [input.view-model.ts](src/input.view-model.ts) | Own the draft while editing and map messages |
26
26
  | View | [Input.tsx](src/Input.tsx) | Render the field from the view-model |
27
+ | View | [DateField.tsx](src/DateField.tsx) | Date input with the same height, radius, and label wiring |
28
+ | View | [Textarea.tsx](src/Textarea.tsx) | Multiline field with the same control metrics |
27
29
  | Shared metadata | `@net-advantage/jo-ui-field-metadata` | Lay out the label, helper text, required marker, and nested input |
28
30
  | Wrappers | [semantic-inputs.tsx](src/semantic-inputs.tsx) | Set `kind` for email, integer, decimal, percentage, and currency |
29
31
 
@@ -45,6 +47,7 @@ flowchart TD
45
47
  - `parse` and `format` override the kind parser and formatter. Omit them and the model uses the kind defaults.
46
48
  - `labelPlacement` accepts `top` or `left`; `descriptionPlacement` accepts `below-label` or `below-control`.
47
49
  - Validation errors remain alerts below the input while ordinary helper text is rendered by `FieldMetadata`.
50
+ - `fullWidth` stretches a field. Inside `FormLayout`, fields are full width unless `fullWidth` is `false`. `DateField` and `Textarea` use the same control height and `--jo-radius-control` as the text input.
48
51
 
49
52
  ## Semantic input strategy
50
53
 
@@ -0,0 +1,3 @@
1
+ import type { DateFieldProps } from './date-field.types';
2
+ import './input.css';
3
+ export declare function DateField(props: DateFieldProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import type { TextareaProps } from './textarea.types';
2
+ import './input.css';
3
+ export declare function Textarea(props: TextareaProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export declare function dateFieldClassName(fullWidth: boolean | undefined, className?: string): string;
2
+ export declare function dateControlClassName(hasError: boolean): string;
3
+ export declare function dateDescribedBy(id: string, hasError: boolean, errorText?: string, helperText?: string): string | undefined;
@@ -0,0 +1,45 @@
1
+ import type { ChangeEvent, InputHTMLAttributes } from 'react';
2
+ import type { FieldMetadataDescriptionPlacement, FieldMetadataLabelPlacement } from '@net-advantage/jo-ui-field-metadata';
3
+ export interface DateFieldProps {
4
+ readonly id: string;
5
+ readonly label?: string;
6
+ readonly labelPlacement?: FieldMetadataLabelPlacement;
7
+ readonly descriptionPlacement?: FieldMetadataDescriptionPlacement;
8
+ readonly value?: string;
9
+ readonly defaultValue?: string;
10
+ readonly min?: string;
11
+ readonly max?: string;
12
+ readonly disabled?: boolean;
13
+ readonly readOnly?: boolean;
14
+ readonly required?: boolean;
15
+ readonly hasError?: boolean;
16
+ readonly helperText?: string;
17
+ readonly errorText?: string;
18
+ readonly fullWidth?: boolean;
19
+ readonly className?: string;
20
+ readonly inputProps?: Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'type' | 'value' | 'defaultValue' | 'disabled' | 'readOnly' | 'required' | 'className'>;
21
+ readonly onValueChange?: (value: string) => void;
22
+ }
23
+ export interface DateFieldViewModel {
24
+ readonly id: string;
25
+ readonly label?: string;
26
+ readonly labelPlacement: FieldMetadataLabelPlacement;
27
+ readonly descriptionPlacement: FieldMetadataDescriptionPlacement;
28
+ readonly labelId?: string;
29
+ readonly value?: string;
30
+ readonly defaultValue?: string;
31
+ readonly min?: string;
32
+ readonly max?: string;
33
+ readonly disabled: boolean;
34
+ readonly readOnly: boolean;
35
+ readonly required: boolean;
36
+ readonly hasError: boolean;
37
+ readonly helperText?: string;
38
+ readonly errorText?: string;
39
+ readonly rootClassName: string;
40
+ readonly inputClassName: string;
41
+ readonly describedBy?: string;
42
+ readonly messageId?: string;
43
+ readonly inputProps?: DateFieldProps['inputProps'];
44
+ readonly onChange: (event: ChangeEvent<HTMLInputElement>) => void;
45
+ }
@@ -0,0 +1,2 @@
1
+ import type { DateFieldProps, DateFieldViewModel } from './date-field.types';
2
+ export declare function useDateFieldViewModel(props: DateFieldProps): DateFieldViewModel;
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);let t=require("@net-advantage/jo-ui-field-metadata"),n=require("react");var r=[`text`,`email`,`password`,`search`,`tel`,`url`],i=[`text`,`email`,`password`,`search`,`tel`,`url`,`integer`,`decimal`,`percentage`,`currency`];function a(e){return e&&r.includes(e)?e:`text`}function o(e,t){return e&&i.includes(e)?e:a(t)}function s(e){switch(e){case`email`:case`password`:case`search`:case`tel`:case`url`:return{type:e};case`integer`:return{type:`text`,inputMode:`numeric`,pattern:`[0-9]*`};case`decimal`:case`percentage`:case`currency`:return{type:`text`,inputMode:`decimal`};default:return{type:`text`}}}function c(e){return e===`integer`||e===`decimal`||e===`percentage`||e===`currency`}function l(e,t){let n=t??`USD`;return new Intl.NumberFormat(e,{style:`currency`,currency:n,minimumFractionDigits:0,maximumFractionDigits:0}).formatToParts(0).find(e=>e.type===`currency`)?.value??n}function u(e){return e==null?``:String(e).trim()}function d(e,t){if(!c(e))return{isNumeric:!1};let n=u(t?.maxValueHint),r=t?.maximumFractionDigits??t?.minimumFractionDigits??(e===`integer`?0:2),i=n.length>0?n:e===`currency`?`9999999.99`:e===`percentage`?`100.00`:e===`integer`?`999999`:`999999.99`,a=`${i}${r>0&&!i.includes(`.`)?`.${`9`.repeat(r)}`:``}`.replace(/\s/g,``),o=Math.max(6,a.length+1);return e===`currency`?{isNumeric:!0,prefixSymbol:l(t?.locale,t?.currency),widthCh:o}:e===`percentage`?{isNumeric:!0,suffixSymbol:`%`,widthCh:o}:{isNumeric:!0,widthCh:o}}function f(e,t){if(!t.trim())return null;switch(e){case`integer`:{let e=Number.parseInt(t,10);return Number.isNaN(e)?null:e}case`decimal`:{let e=Number.parseFloat(t);return Number.isNaN(e)?null:e}case`percentage`:{let e=t.replace(`%`,``).trim(),n=Number.parseFloat(e);return Number.isNaN(n)?null:n}case`currency`:{let e=t.replace(/[^0-9.-]/g,``),n=Number.parseFloat(e);return Number.isNaN(n)?null:n}default:return t}}function p(e,t,n){if(!t.trim())return t;if(e===`percentage`){let r=f(e,t);return typeof r==`number`?new Intl.NumberFormat(n?.locale,{minimumFractionDigits:n?.minimumFractionDigits??0,maximumFractionDigits:n?.maximumFractionDigits??2}).format(r):t}if(e===`currency`){let r=f(e,t);return typeof r==`number`?new Intl.NumberFormat(n?.locale,{style:`decimal`,minimumFractionDigits:n?.minimumFractionDigits,maximumFractionDigits:n?.maximumFractionDigits}).format(r):t}return t}function m(e){let t=e.labelPlacement??`top`,r=e.descriptionPlacement??`below-control`,i=e.hasError??!1,a=o(e.kind,e.type),c=s(a),l=e.value!==void 0,[u,m]=(0,n.useState)(!1),[h,g]=(0,n.useState)(e.value??``);(0,n.useEffect)(()=>{l&&!u&&g(e.value)},[l,u,e.value]);let _=(0,n.useMemo)(()=>d(a,{locale:e.locale,currency:e.currency,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,maxValueHint:e.maxValueHint??e.inputProps?.max}),[a,e.currency,e.inputProps?.max,e.locale,e.maximumFractionDigits,e.maxValueHint,e.minimumFractionDigits]),v=i?e.errorText?`${e.id}__error`:void 0:e.helperText?`${e.id}__helper`:void 0,y=_.isNumeric&&_.widthCh?{"--jo-ui-input-numeric-width-ch":String(_.widthCh)}:void 0,b=(0,n.useCallback)(t=>{m(!0),l&&g(t.currentTarget.value),e.inputProps?.onFocus?.(t)},[l,e.inputProps]),x=(0,n.useCallback)(t=>{let n=t.target.value,r=e.parse?.(n)??f(a,n);l&&g(n),e.inputProps?.onChange?.(t),e.onValueChange?.(n),e.onParsedValueChange?.(r)},[l,a,e]),S=(0,n.useCallback)(t=>{let n=t.currentTarget.value,r=e.format?.(n)??p(a,n,{locale:e.locale,currency:e.currency,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits});r!==n&&(e.onValueChange?.(r),l&&g(r)),m(!1),e.inputProps?.onBlur?.(t)},[l,a,e]);return{id:e.id,label:e.label,labelPlacement:t,descriptionPlacement:r,labelId:e.label?`${e.id}__label`:void 0,value:e.value,defaultValue:e.defaultValue,placeholder:e.placeholder,kind:a,type:c.type,isNumeric:_.isNumeric,prefixSymbol:_.prefixSymbol,suffixSymbol:_.suffixSymbol,controlStyle:{...e.inputProps?.style,...y},inputMode:c.inputMode,pattern:c.pattern,disabled:e.disabled??!1,readOnly:e.readOnly??!1,required:e.required??!1,hasError:i,helperText:e.helperText,errorText:e.errorText,rootClassName:[`jo-ui-input`,e.className??``].filter(Boolean).join(` `),inputClassName:[`jo-ui-input__control`,_.isNumeric?`jo-ui-input__control--numeric`:``,i?`jo-ui-input__control--error`:``].filter(Boolean).join(` `),describedBy:v,messageId:v,renderedValue:l?u?h:e.value:void 0,inputProps:e.inputProps,onFocus:b,onChange:x,onBlur:S}}var h=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),g=e((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===k?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`;case O:return`ViewTransition`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=A.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(j.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){P||(P=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return F[e]||(F[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0){if(o){if(M(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`)}else f(p)}if(j.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,R[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);let t=require("@net-advantage/jo-ui-field-metadata"),n=require("react");var r=[`text`,`email`,`password`,`search`,`tel`,`url`],i=[`text`,`email`,`password`,`search`,`tel`,`url`,`integer`,`decimal`,`percentage`,`currency`];function a(e){return e&&r.includes(e)?e:`text`}function o(e,t){return e&&i.includes(e)?e:a(t)}function s(e){switch(e){case`email`:case`password`:case`search`:case`tel`:case`url`:return{type:e};case`integer`:return{type:`text`,inputMode:`numeric`,pattern:`[0-9]*`};case`decimal`:case`percentage`:case`currency`:return{type:`text`,inputMode:`decimal`};default:return{type:`text`}}}function c(e){return e===`integer`||e===`decimal`||e===`percentage`||e===`currency`}function l(e,t){let n=t??`USD`;return new Intl.NumberFormat(e,{style:`currency`,currency:n,minimumFractionDigits:0,maximumFractionDigits:0}).formatToParts(0).find(e=>e.type===`currency`)?.value??n}function u(e){return e==null?``:String(e).trim()}function d(e,t){if(!c(e))return{isNumeric:!1};let n=u(t?.maxValueHint),r=t?.maximumFractionDigits??t?.minimumFractionDigits??(e===`integer`?0:2),i=n.length>0?n:e===`currency`?`9999999.99`:e===`percentage`?`100.00`:e===`integer`?`999999`:`999999.99`,a=`${i}${r>0&&!i.includes(`.`)?`.${`9`.repeat(r)}`:``}`.replace(/\s/g,``),o=Math.max(6,a.length+1);return e===`currency`?{isNumeric:!0,prefixSymbol:l(t?.locale,t?.currency),widthCh:o}:e===`percentage`?{isNumeric:!0,suffixSymbol:`%`,widthCh:o}:{isNumeric:!0,widthCh:o}}function f(e,t){if(!t.trim())return null;switch(e){case`integer`:{let e=Number.parseInt(t,10);return Number.isNaN(e)?null:e}case`decimal`:{let e=Number.parseFloat(t);return Number.isNaN(e)?null:e}case`percentage`:{let e=t.replace(`%`,``).trim(),n=Number.parseFloat(e);return Number.isNaN(n)?null:n}case`currency`:{let e=t.replace(/[^0-9.-]/g,``),n=Number.parseFloat(e);return Number.isNaN(n)?null:n}default:return t}}function p(e,t,n){if(!t.trim())return t;if(e===`percentage`){let r=f(e,t);return typeof r==`number`?new Intl.NumberFormat(n?.locale,{minimumFractionDigits:n?.minimumFractionDigits??0,maximumFractionDigits:n?.maximumFractionDigits??2}).format(r):t}if(e===`currency`){let r=f(e,t);return typeof r==`number`?new Intl.NumberFormat(n?.locale,{style:`decimal`,minimumFractionDigits:n?.minimumFractionDigits,maximumFractionDigits:n?.maximumFractionDigits}).format(r):t}return t}function m(e){return e===!0?`jo-ui-input--full`:e===!1?`jo-ui-input--inline`:``}function h(e,t,n,r){return t?n?`${e}__error`:void 0:r?`${e}__helper`:void 0}function g(e){return e===void 0||!Number.isFinite(e)||e<1?3:Math.floor(e)}function _(e,t){return[`jo-ui-input`,`jo-ui-date-field`,m(e),t??``].filter(Boolean).join(` `)}function v(e){return[`jo-ui-input__control`,`jo-ui-date-field__control`,e?`jo-ui-input__control--error`:``].filter(Boolean).join(` `)}function y(e,t,n,r){return h(e,t,n,r)}function b(e){let t=e.hasError??!1,r=y(e.id,t,e.errorText,e.helperText),i=(0,n.useCallback)(t=>{e.inputProps?.onChange?.(t),e.onValueChange?.(t.target.value)},[e.inputProps,e.onValueChange]);return{id:e.id,label:e.label,labelPlacement:e.labelPlacement??`top`,descriptionPlacement:e.descriptionPlacement??`below-control`,labelId:e.label?`${e.id}__label`:void 0,value:e.value,defaultValue:e.defaultValue,min:e.min,max:e.max,disabled:e.disabled??!1,readOnly:e.readOnly??!1,required:e.required??!1,hasError:t,helperText:e.helperText,errorText:e.errorText,rootClassName:_(e.fullWidth,e.className),inputClassName:v(t),describedBy:r,messageId:r,inputProps:e.inputProps,onChange:i}}var x=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),S=e((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===k?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`;case O:return`ViewTransition`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=A.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(j.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){P||(P=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return F[e]||(F[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0){if(o){if(M(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`)}else f(p)}if(j.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,R[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
2
2
  let props = %s;
3
3
  <%s {...props} />
4
4
  React keys must be passed directly to JSX without using spread:
5
5
  let props = %s;
6
- <%s key={someKey} {...props} />`,o,p,m,p),R[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.view_transition`),k=Symbol.for(`react.client.reference`),A=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,j=Object.prototype.hasOwnProperty,M=Array.isArray,N=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var P,F={},I=m.react_stack_bottom_frame.bind(m,o)(),L=N(i(o)),R={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>A.recentlyCreatedOwnerStacks++;if(r){var a=Error.stackTraceLimit;Error.stackTraceLimit=10;var o=Error(`react-stack-top-frame`);Error.stackTraceLimit=a}else o=I;return d(e,t,n,!1,o,r?N(i(e)):L)},e.jsxs=function(e,t,n){var r=1e4>A.recentlyCreatedOwnerStacks++;if(r){var a=Error.stackTraceLimit;Error.stackTraceLimit=10;var o=Error(`react-stack-top-frame`);Error.stackTraceLimit=a}else o=I;return d(e,t,n,!0,o,r?N(i(e)):L)}})()})),_=e(((e,t)=>{t.exports=process.env.NODE_ENV===`production`?h():g()}))();function v(e){let n=m(e);return(0,_.jsx)(`div`,{className:n.rootClassName,children:(0,_.jsx)(t.FieldMetadata,{id:n.id,label:n.label,helperText:n.hasError?void 0:n.helperText,required:n.required,labelPlacement:n.labelPlacement,descriptionPlacement:n.descriptionPlacement,children:(0,_.jsxs)(`div`,{className:`jo-ui-input__field`,children:[(0,_.jsxs)(`div`,{className:`jo-ui-input__control-wrap`,children:[n.prefixSymbol?(0,_.jsx)(`span`,{className:`jo-ui-input__symbol jo-ui-input__symbol--prefix`,"aria-hidden":`true`,children:n.prefixSymbol}):null,(0,_.jsx)(`input`,{...n.inputProps,id:n.id,type:n.type,inputMode:n.inputMode,pattern:n.pattern,className:n.inputClassName,style:n.controlStyle,value:n.renderedValue,defaultValue:n.renderedValue===void 0?n.defaultValue:void 0,placeholder:n.placeholder,disabled:n.disabled,readOnly:n.readOnly,required:n.required,"aria-invalid":n.hasError||void 0,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,onFocus:n.onFocus,onChange:n.onChange,onBlur:n.onBlur}),n.suffixSymbol?(0,_.jsx)(`span`,{className:`jo-ui-input__symbol jo-ui-input__symbol--suffix`,"aria-hidden":`true`,children:n.suffixSymbol}):null]}),n.hasError&&n.errorText?(0,_.jsx)(`span`,{id:n.messageId,className:`jo-ui-input__message jo-ui-input__message--error`,role:`alert`,children:n.errorText}):null]})})})}function y(e){return(0,_.jsx)(v,{...e,kind:`email`})}function b(e){return(0,_.jsx)(v,{...e,kind:`integer`})}function x(e){return(0,_.jsx)(v,{...e,kind:`decimal`})}function S(e){return(0,_.jsx)(v,{...e,kind:`percentage`,maximumFractionDigits:e.maximumFractionDigits??2})}function C(e){return(0,_.jsx)(v,{...e,kind:`currency`,currency:e.currency??`USD`,minimumFractionDigits:e.minimumFractionDigits??2,maximumFractionDigits:e.maximumFractionDigits??2})}exports.CurrencyInput=C,exports.DecimalInput=x,exports.EmailInput=y,exports.InputField=v,exports.IntegerInput=b,exports.PercentageInput=S;
6
+ <%s key={someKey} {...props} />`,o,p,m,p),R[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.view_transition`),k=Symbol.for(`react.client.reference`),A=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,j=Object.prototype.hasOwnProperty,M=Array.isArray,N=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var P,F={},I=m.react_stack_bottom_frame.bind(m,o)(),L=N(i(o)),R={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>A.recentlyCreatedOwnerStacks++;if(r){var a=Error.stackTraceLimit;Error.stackTraceLimit=10;var o=Error(`react-stack-top-frame`);Error.stackTraceLimit=a}else o=I;return d(e,t,n,!1,o,r?N(i(e)):L)},e.jsxs=function(e,t,n){var r=1e4>A.recentlyCreatedOwnerStacks++;if(r){var a=Error.stackTraceLimit;Error.stackTraceLimit=10;var o=Error(`react-stack-top-frame`);Error.stackTraceLimit=a}else o=I;return d(e,t,n,!0,o,r?N(i(e)):L)}})()})),C=e(((e,t)=>{t.exports=process.env.NODE_ENV===`production`?x():S()}))();function w(e){let n=b(e);return(0,C.jsx)(`div`,{className:n.rootClassName,children:(0,C.jsx)(t.FieldMetadata,{id:n.id,label:n.label,helperText:n.hasError?void 0:n.helperText,required:n.required,labelPlacement:n.labelPlacement,descriptionPlacement:n.descriptionPlacement,children:(0,C.jsxs)(`div`,{className:`jo-ui-input__field`,children:[(0,C.jsx)(`div`,{className:`jo-ui-input__control-wrap`,children:(0,C.jsx)(`input`,{...n.inputProps,id:n.id,type:`date`,className:n.inputClassName,value:n.value,defaultValue:n.value===void 0?n.defaultValue:void 0,min:n.min,max:n.max,disabled:n.disabled,readOnly:n.readOnly,required:n.required,"aria-invalid":n.hasError||void 0,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,onChange:n.onChange})}),n.hasError&&n.errorText?(0,C.jsx)(`span`,{id:n.messageId,className:`jo-ui-input__message jo-ui-input__message--error`,role:`alert`,children:n.errorText}):null]})})})}function T(e){let t=e.labelPlacement??`top`,r=e.descriptionPlacement??`below-control`,i=e.hasError??!1,a=o(e.kind,e.type),c=s(a),l=e.value!==void 0,[u,g]=(0,n.useState)(!1),[_,v]=(0,n.useState)(e.value??``);(0,n.useEffect)(()=>{l&&!u&&v(e.value)},[l,u,e.value]);let y=(0,n.useMemo)(()=>d(a,{locale:e.locale,currency:e.currency,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,maxValueHint:e.maxValueHint??e.inputProps?.max}),[a,e.currency,e.inputProps?.max,e.locale,e.maximumFractionDigits,e.maxValueHint,e.minimumFractionDigits]),b=h(e.id,i,e.errorText,e.helperText),x=y.isNumeric&&y.widthCh?{"--jo-ui-input-numeric-width-ch":String(y.widthCh)}:void 0,S=(0,n.useCallback)(t=>{g(!0),l&&v(t.currentTarget.value),e.inputProps?.onFocus?.(t)},[l,e.inputProps]),C=(0,n.useCallback)(t=>{let n=t.target.value,r=e.parse?.(n)??f(a,n);l&&v(n),e.inputProps?.onChange?.(t),e.onValueChange?.(n),e.onParsedValueChange?.(r)},[l,a,e]),w=(0,n.useCallback)(t=>{let n=t.currentTarget.value,r=e.format?.(n)??p(a,n,{locale:e.locale,currency:e.currency,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits});r!==n&&(e.onValueChange?.(r),l&&v(r)),g(!1),e.inputProps?.onBlur?.(t)},[l,a,e]);return{id:e.id,label:e.label,labelPlacement:t,descriptionPlacement:r,labelId:e.label?`${e.id}__label`:void 0,value:e.value,defaultValue:e.defaultValue,placeholder:e.placeholder,kind:a,type:c.type,isNumeric:y.isNumeric,prefixSymbol:y.prefixSymbol,suffixSymbol:y.suffixSymbol,controlStyle:{...e.inputProps?.style,...x},inputMode:c.inputMode,pattern:c.pattern,disabled:e.disabled??!1,readOnly:e.readOnly??!1,required:e.required??!1,hasError:i,helperText:e.helperText,errorText:e.errorText,rootClassName:[`jo-ui-input`,m(e.fullWidth),e.className??``].filter(Boolean).join(` `),inputClassName:[`jo-ui-input__control`,y.isNumeric?`jo-ui-input__control--numeric`:``,i?`jo-ui-input__control--error`:``].filter(Boolean).join(` `),describedBy:b,messageId:b,renderedValue:l?u?_:e.value:void 0,inputProps:e.inputProps,onFocus:S,onChange:C,onBlur:w}}function E(e){let n=T(e);return(0,C.jsx)(`div`,{className:n.rootClassName,children:(0,C.jsx)(t.FieldMetadata,{id:n.id,label:n.label,helperText:n.hasError?void 0:n.helperText,required:n.required,labelPlacement:n.labelPlacement,descriptionPlacement:n.descriptionPlacement,children:(0,C.jsxs)(`div`,{className:`jo-ui-input__field`,children:[(0,C.jsxs)(`div`,{className:`jo-ui-input__control-wrap`,children:[n.prefixSymbol?(0,C.jsx)(`span`,{className:`jo-ui-input__symbol jo-ui-input__symbol--prefix`,"aria-hidden":`true`,children:n.prefixSymbol}):null,(0,C.jsx)(`input`,{...n.inputProps,id:n.id,type:n.type,inputMode:n.inputMode,pattern:n.pattern,className:n.inputClassName,style:n.controlStyle,value:n.renderedValue,defaultValue:n.renderedValue===void 0?n.defaultValue:void 0,placeholder:n.placeholder,disabled:n.disabled,readOnly:n.readOnly,required:n.required,"aria-invalid":n.hasError||void 0,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,onFocus:n.onFocus,onChange:n.onChange,onBlur:n.onBlur}),n.suffixSymbol?(0,C.jsx)(`span`,{className:`jo-ui-input__symbol jo-ui-input__symbol--suffix`,"aria-hidden":`true`,children:n.suffixSymbol}):null]}),n.hasError&&n.errorText?(0,C.jsx)(`span`,{id:n.messageId,className:`jo-ui-input__message jo-ui-input__message--error`,role:`alert`,children:n.errorText}):null]})})})}function D(e,t){return[`jo-ui-input`,`jo-ui-textarea`,m(e),t??``].filter(Boolean).join(` `)}function O(e){return[`jo-ui-input__control`,`jo-ui-textarea__control`,e?`jo-ui-input__control--error`:``].filter(Boolean).join(` `)}function k(e,t,n,r){return h(e,t,n,r)}function A(e){let t=e.hasError??!1,r=k(e.id,t,e.errorText,e.helperText),i=(0,n.useCallback)(t=>{e.textareaProps?.onChange?.(t),e.onValueChange?.(t.target.value)},[e.onValueChange,e.textareaProps]);return{id:e.id,label:e.label,labelPlacement:e.labelPlacement??`top`,descriptionPlacement:e.descriptionPlacement??`below-control`,labelId:e.label?`${e.id}__label`:void 0,value:e.value,defaultValue:e.defaultValue,placeholder:e.placeholder,rows:g(e.rows),disabled:e.disabled??!1,readOnly:e.readOnly??!1,required:e.required??!1,hasError:t,helperText:e.helperText,errorText:e.errorText,rootClassName:D(e.fullWidth,e.className),controlClassName:O(t),describedBy:r,messageId:r,textareaProps:e.textareaProps,onChange:i}}function j(e){let n=A(e);return(0,C.jsx)(`div`,{className:n.rootClassName,children:(0,C.jsx)(t.FieldMetadata,{id:n.id,label:n.label,helperText:n.hasError?void 0:n.helperText,required:n.required,labelPlacement:n.labelPlacement,descriptionPlacement:n.descriptionPlacement,children:(0,C.jsxs)(`div`,{className:`jo-ui-input__field`,children:[(0,C.jsx)(`textarea`,{...n.textareaProps,id:n.id,className:n.controlClassName,value:n.value,defaultValue:n.value===void 0?n.defaultValue:void 0,placeholder:n.placeholder,rows:n.rows,disabled:n.disabled,readOnly:n.readOnly,required:n.required,"aria-invalid":n.hasError||void 0,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,onChange:n.onChange}),n.hasError&&n.errorText?(0,C.jsx)(`span`,{id:n.messageId,className:`jo-ui-input__message jo-ui-input__message--error`,role:`alert`,children:n.errorText}):null]})})})}function M(e){return(0,C.jsx)(E,{...e,kind:`email`})}function N(e){return(0,C.jsx)(E,{...e,kind:`integer`})}function P(e){return(0,C.jsx)(E,{...e,kind:`decimal`})}function F(e){return(0,C.jsx)(E,{...e,kind:`percentage`,maximumFractionDigits:e.maximumFractionDigits??2})}function I(e){return(0,C.jsx)(E,{...e,kind:`currency`,currency:e.currency??`USD`,minimumFractionDigits:e.minimumFractionDigits??2,maximumFractionDigits:e.maximumFractionDigits??2})}exports.CurrencyInput=I,exports.DateField=w,exports.DecimalInput=P,exports.EmailInput=M,exports.InputField=E,exports.IntegerInput=N,exports.PercentageInput=F,exports.Textarea=j;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ export { DateField } from './DateField';
1
2
  export { InputField } from './Input';
3
+ export { Textarea } from './Textarea';
2
4
  export { CurrencyInput, DecimalInput, EmailInput, IntegerInput, PercentageInput, } from './semantic-inputs';
5
+ export type { DateFieldProps, DateFieldViewModel } from './date-field.types';
6
+ export type { TextareaProps, TextareaViewModel } from './textarea.types';
3
7
  export type { InputHtmlType, InputKind, ParsedInputValue, InputProps, InputViewModel, } from './input.types';
package/dist/index.js CHANGED
@@ -123,97 +123,68 @@ function _(e, t, n) {
123
123
  }
124
124
  return t;
125
125
  }
126
- //#endregion
127
- //#region src/input.view-model.ts
128
126
  function v(e) {
129
- let a = e.labelPlacement ?? "top", o = e.descriptionPlacement ?? "below-control", s = e.hasError ?? !1, c = u(e.kind, e.type), l = d(c), f = e.value !== void 0, [p, m] = i(!1), [v, y] = i(e.value ?? "");
130
- n(() => {
131
- f && !p && y(e.value);
132
- }, [
133
- f,
134
- p,
135
- e.value
136
- ]);
137
- let b = r(() => h(c, {
138
- locale: e.locale,
139
- currency: e.currency,
140
- minimumFractionDigits: e.minimumFractionDigits,
141
- maximumFractionDigits: e.maximumFractionDigits,
142
- maxValueHint: e.maxValueHint ?? e.inputProps?.max
143
- }), [
144
- c,
145
- e.currency,
146
- e.inputProps?.max,
147
- e.locale,
148
- e.maximumFractionDigits,
149
- e.maxValueHint,
150
- e.minimumFractionDigits
151
- ]), x = s ? e.errorText ? `${e.id}__error` : void 0 : e.helperText ? `${e.id}__helper` : void 0, S = b.isNumeric && b.widthCh ? { "--jo-ui-input-numeric-width-ch": String(b.widthCh) } : void 0, C = t((t) => {
152
- m(!0), f && y(t.currentTarget.value), e.inputProps?.onFocus?.(t);
153
- }, [f, e.inputProps]), w = t((t) => {
154
- let n = t.target.value, r = e.parse?.(n) ?? g(c, n);
155
- f && y(n), e.inputProps?.onChange?.(t), e.onValueChange?.(n), e.onParsedValueChange?.(r);
156
- }, [
157
- f,
158
- c,
159
- e
160
- ]), T = t((t) => {
161
- let n = t.currentTarget.value, r = e.format?.(n) ?? _(c, n, {
162
- locale: e.locale,
163
- currency: e.currency,
164
- minimumFractionDigits: e.minimumFractionDigits,
165
- maximumFractionDigits: e.maximumFractionDigits
166
- });
167
- r !== n && (e.onValueChange?.(r), f && y(r)), m(!1), e.inputProps?.onBlur?.(t);
168
- }, [
169
- f,
170
- c,
171
- e
172
- ]);
127
+ return e === !0 ? "jo-ui-input--full" : e === !1 ? "jo-ui-input--inline" : "";
128
+ }
129
+ function y(e, t, n, r) {
130
+ return t ? n ? `${e}__error` : void 0 : r ? `${e}__helper` : void 0;
131
+ }
132
+ function b(e) {
133
+ return e === void 0 || !Number.isFinite(e) || e < 1 ? 3 : Math.floor(e);
134
+ }
135
+ //#endregion
136
+ //#region src/date-field.model.ts
137
+ function x(e, t) {
138
+ return [
139
+ "jo-ui-input",
140
+ "jo-ui-date-field",
141
+ v(e),
142
+ t ?? ""
143
+ ].filter(Boolean).join(" ");
144
+ }
145
+ function S(e) {
146
+ return [
147
+ "jo-ui-input__control",
148
+ "jo-ui-date-field__control",
149
+ e ? "jo-ui-input__control--error" : ""
150
+ ].filter(Boolean).join(" ");
151
+ }
152
+ function C(e, t, n, r) {
153
+ return y(e, t, n, r);
154
+ }
155
+ //#endregion
156
+ //#region src/date-field.view-model.ts
157
+ function w(e) {
158
+ let n = e.hasError ?? !1, r = C(e.id, n, e.errorText, e.helperText), i = t((t) => {
159
+ e.inputProps?.onChange?.(t), e.onValueChange?.(t.target.value);
160
+ }, [e.inputProps, e.onValueChange]);
173
161
  return {
174
162
  id: e.id,
175
163
  label: e.label,
176
- labelPlacement: a,
177
- descriptionPlacement: o,
164
+ labelPlacement: e.labelPlacement ?? "top",
165
+ descriptionPlacement: e.descriptionPlacement ?? "below-control",
178
166
  labelId: e.label ? `${e.id}__label` : void 0,
179
167
  value: e.value,
180
168
  defaultValue: e.defaultValue,
181
- placeholder: e.placeholder,
182
- kind: c,
183
- type: l.type,
184
- isNumeric: b.isNumeric,
185
- prefixSymbol: b.prefixSymbol,
186
- suffixSymbol: b.suffixSymbol,
187
- controlStyle: {
188
- ...e.inputProps?.style,
189
- ...S
190
- },
191
- inputMode: l.inputMode,
192
- pattern: l.pattern,
169
+ min: e.min,
170
+ max: e.max,
193
171
  disabled: e.disabled ?? !1,
194
172
  readOnly: e.readOnly ?? !1,
195
173
  required: e.required ?? !1,
196
- hasError: s,
174
+ hasError: n,
197
175
  helperText: e.helperText,
198
176
  errorText: e.errorText,
199
- rootClassName: ["jo-ui-input", e.className ?? ""].filter(Boolean).join(" "),
200
- inputClassName: [
201
- "jo-ui-input__control",
202
- b.isNumeric ? "jo-ui-input__control--numeric" : "",
203
- s ? "jo-ui-input__control--error" : ""
204
- ].filter(Boolean).join(" "),
205
- describedBy: x,
206
- messageId: x,
207
- renderedValue: f ? p ? v : e.value : void 0,
177
+ rootClassName: x(e.fullWidth, e.className),
178
+ inputClassName: S(n),
179
+ describedBy: r,
180
+ messageId: r,
208
181
  inputProps: e.inputProps,
209
- onFocus: C,
210
- onChange: w,
211
- onBlur: T
182
+ onChange: i
212
183
  };
213
184
  }
214
185
  //#endregion
215
186
  //#region ../../node_modules/.pnpm/react@19.3.0/node_modules/react/cjs/react-jsx-runtime.production.js
216
- var y = /* @__PURE__ */ a(((e) => {
187
+ var T = /* @__PURE__ */ a(((e) => {
217
188
  var t = Symbol.for("react.transitional.element"), n = Symbol.for("react.fragment");
218
189
  function r(e, n, r) {
219
190
  var i = null;
@@ -228,7 +199,7 @@ var y = /* @__PURE__ */ a(((e) => {
228
199
  };
229
200
  }
230
201
  e.Fragment = n, e.jsx = r, e.jsxs = r;
231
- })), b = /* @__PURE__ */ a(((e) => {
202
+ })), E = /* @__PURE__ */ a(((e) => {
232
203
  process.env.NODE_ENV !== "production" && (function() {
233
204
  function t(e) {
234
205
  if (e == null) return null;
@@ -402,31 +373,167 @@ var y = /* @__PURE__ */ a(((e) => {
402
373
  return f(e, t, n, !0, o, r ? P(i(e)) : R);
403
374
  };
404
375
  })();
405
- })), x = (/* @__PURE__ */ a(((e, t) => {
406
- t.exports = process.env.NODE_ENV === "production" ? y() : b();
376
+ })), D = (/* @__PURE__ */ a(((e, t) => {
377
+ t.exports = process.env.NODE_ENV === "production" ? T() : E();
407
378
  })))();
408
- function S(t) {
409
- let n = v(t);
410
- return /* @__PURE__ */ (0, x.jsx)("div", {
379
+ function O(t) {
380
+ let n = w(t);
381
+ return /* @__PURE__ */ (0, D.jsx)("div", {
411
382
  className: n.rootClassName,
412
- children: /* @__PURE__ */ (0, x.jsx)(e, {
383
+ children: /* @__PURE__ */ (0, D.jsx)(e, {
413
384
  id: n.id,
414
385
  label: n.label,
415
386
  helperText: n.hasError ? void 0 : n.helperText,
416
387
  required: n.required,
417
388
  labelPlacement: n.labelPlacement,
418
389
  descriptionPlacement: n.descriptionPlacement,
419
- children: /* @__PURE__ */ (0, x.jsxs)("div", {
390
+ children: /* @__PURE__ */ (0, D.jsxs)("div", {
420
391
  className: "jo-ui-input__field",
421
- children: [/* @__PURE__ */ (0, x.jsxs)("div", {
392
+ children: [/* @__PURE__ */ (0, D.jsx)("div", {
393
+ className: "jo-ui-input__control-wrap",
394
+ children: /* @__PURE__ */ (0, D.jsx)("input", {
395
+ ...n.inputProps,
396
+ id: n.id,
397
+ type: "date",
398
+ className: n.inputClassName,
399
+ value: n.value,
400
+ defaultValue: n.value === void 0 ? n.defaultValue : void 0,
401
+ min: n.min,
402
+ max: n.max,
403
+ disabled: n.disabled,
404
+ readOnly: n.readOnly,
405
+ required: n.required,
406
+ "aria-invalid": n.hasError || void 0,
407
+ "aria-labelledby": n.labelId,
408
+ "aria-describedby": n.describedBy,
409
+ onChange: n.onChange
410
+ })
411
+ }), n.hasError && n.errorText ? /* @__PURE__ */ (0, D.jsx)("span", {
412
+ id: n.messageId,
413
+ className: "jo-ui-input__message jo-ui-input__message--error",
414
+ role: "alert",
415
+ children: n.errorText
416
+ }) : null]
417
+ })
418
+ })
419
+ });
420
+ }
421
+ //#endregion
422
+ //#region src/input.view-model.ts
423
+ function k(e) {
424
+ let a = e.labelPlacement ?? "top", o = e.descriptionPlacement ?? "below-control", s = e.hasError ?? !1, c = u(e.kind, e.type), l = d(c), f = e.value !== void 0, [p, m] = i(!1), [b, x] = i(e.value ?? "");
425
+ n(() => {
426
+ f && !p && x(e.value);
427
+ }, [
428
+ f,
429
+ p,
430
+ e.value
431
+ ]);
432
+ let S = r(() => h(c, {
433
+ locale: e.locale,
434
+ currency: e.currency,
435
+ minimumFractionDigits: e.minimumFractionDigits,
436
+ maximumFractionDigits: e.maximumFractionDigits,
437
+ maxValueHint: e.maxValueHint ?? e.inputProps?.max
438
+ }), [
439
+ c,
440
+ e.currency,
441
+ e.inputProps?.max,
442
+ e.locale,
443
+ e.maximumFractionDigits,
444
+ e.maxValueHint,
445
+ e.minimumFractionDigits
446
+ ]), C = y(e.id, s, e.errorText, e.helperText), w = S.isNumeric && S.widthCh ? { "--jo-ui-input-numeric-width-ch": String(S.widthCh) } : void 0, T = t((t) => {
447
+ m(!0), f && x(t.currentTarget.value), e.inputProps?.onFocus?.(t);
448
+ }, [f, e.inputProps]), E = t((t) => {
449
+ let n = t.target.value, r = e.parse?.(n) ?? g(c, n);
450
+ f && x(n), e.inputProps?.onChange?.(t), e.onValueChange?.(n), e.onParsedValueChange?.(r);
451
+ }, [
452
+ f,
453
+ c,
454
+ e
455
+ ]), D = t((t) => {
456
+ let n = t.currentTarget.value, r = e.format?.(n) ?? _(c, n, {
457
+ locale: e.locale,
458
+ currency: e.currency,
459
+ minimumFractionDigits: e.minimumFractionDigits,
460
+ maximumFractionDigits: e.maximumFractionDigits
461
+ });
462
+ r !== n && (e.onValueChange?.(r), f && x(r)), m(!1), e.inputProps?.onBlur?.(t);
463
+ }, [
464
+ f,
465
+ c,
466
+ e
467
+ ]);
468
+ return {
469
+ id: e.id,
470
+ label: e.label,
471
+ labelPlacement: a,
472
+ descriptionPlacement: o,
473
+ labelId: e.label ? `${e.id}__label` : void 0,
474
+ value: e.value,
475
+ defaultValue: e.defaultValue,
476
+ placeholder: e.placeholder,
477
+ kind: c,
478
+ type: l.type,
479
+ isNumeric: S.isNumeric,
480
+ prefixSymbol: S.prefixSymbol,
481
+ suffixSymbol: S.suffixSymbol,
482
+ controlStyle: {
483
+ ...e.inputProps?.style,
484
+ ...w
485
+ },
486
+ inputMode: l.inputMode,
487
+ pattern: l.pattern,
488
+ disabled: e.disabled ?? !1,
489
+ readOnly: e.readOnly ?? !1,
490
+ required: e.required ?? !1,
491
+ hasError: s,
492
+ helperText: e.helperText,
493
+ errorText: e.errorText,
494
+ rootClassName: [
495
+ "jo-ui-input",
496
+ v(e.fullWidth),
497
+ e.className ?? ""
498
+ ].filter(Boolean).join(" "),
499
+ inputClassName: [
500
+ "jo-ui-input__control",
501
+ S.isNumeric ? "jo-ui-input__control--numeric" : "",
502
+ s ? "jo-ui-input__control--error" : ""
503
+ ].filter(Boolean).join(" "),
504
+ describedBy: C,
505
+ messageId: C,
506
+ renderedValue: f ? p ? b : e.value : void 0,
507
+ inputProps: e.inputProps,
508
+ onFocus: T,
509
+ onChange: E,
510
+ onBlur: D
511
+ };
512
+ }
513
+ //#endregion
514
+ //#region src/Input.tsx
515
+ function A(t) {
516
+ let n = k(t);
517
+ return /* @__PURE__ */ (0, D.jsx)("div", {
518
+ className: n.rootClassName,
519
+ children: /* @__PURE__ */ (0, D.jsx)(e, {
520
+ id: n.id,
521
+ label: n.label,
522
+ helperText: n.hasError ? void 0 : n.helperText,
523
+ required: n.required,
524
+ labelPlacement: n.labelPlacement,
525
+ descriptionPlacement: n.descriptionPlacement,
526
+ children: /* @__PURE__ */ (0, D.jsxs)("div", {
527
+ className: "jo-ui-input__field",
528
+ children: [/* @__PURE__ */ (0, D.jsxs)("div", {
422
529
  className: "jo-ui-input__control-wrap",
423
530
  children: [
424
- n.prefixSymbol ? /* @__PURE__ */ (0, x.jsx)("span", {
531
+ n.prefixSymbol ? /* @__PURE__ */ (0, D.jsx)("span", {
425
532
  className: "jo-ui-input__symbol jo-ui-input__symbol--prefix",
426
533
  "aria-hidden": "true",
427
534
  children: n.prefixSymbol
428
535
  }) : null,
429
- /* @__PURE__ */ (0, x.jsx)("input", {
536
+ /* @__PURE__ */ (0, D.jsx)("input", {
430
537
  ...n.inputProps,
431
538
  id: n.id,
432
539
  type: n.type,
@@ -447,13 +554,103 @@ function S(t) {
447
554
  onChange: n.onChange,
448
555
  onBlur: n.onBlur
449
556
  }),
450
- n.suffixSymbol ? /* @__PURE__ */ (0, x.jsx)("span", {
557
+ n.suffixSymbol ? /* @__PURE__ */ (0, D.jsx)("span", {
451
558
  className: "jo-ui-input__symbol jo-ui-input__symbol--suffix",
452
559
  "aria-hidden": "true",
453
560
  children: n.suffixSymbol
454
561
  }) : null
455
562
  ]
456
- }), n.hasError && n.errorText ? /* @__PURE__ */ (0, x.jsx)("span", {
563
+ }), n.hasError && n.errorText ? /* @__PURE__ */ (0, D.jsx)("span", {
564
+ id: n.messageId,
565
+ className: "jo-ui-input__message jo-ui-input__message--error",
566
+ role: "alert",
567
+ children: n.errorText
568
+ }) : null]
569
+ })
570
+ })
571
+ });
572
+ }
573
+ //#endregion
574
+ //#region src/textarea.model.ts
575
+ function j(e, t) {
576
+ return [
577
+ "jo-ui-input",
578
+ "jo-ui-textarea",
579
+ v(e),
580
+ t ?? ""
581
+ ].filter(Boolean).join(" ");
582
+ }
583
+ function M(e) {
584
+ return [
585
+ "jo-ui-input__control",
586
+ "jo-ui-textarea__control",
587
+ e ? "jo-ui-input__control--error" : ""
588
+ ].filter(Boolean).join(" ");
589
+ }
590
+ function N(e, t, n, r) {
591
+ return y(e, t, n, r);
592
+ }
593
+ //#endregion
594
+ //#region src/textarea.view-model.ts
595
+ function P(e) {
596
+ let n = e.hasError ?? !1, r = N(e.id, n, e.errorText, e.helperText), i = t((t) => {
597
+ e.textareaProps?.onChange?.(t), e.onValueChange?.(t.target.value);
598
+ }, [e.onValueChange, e.textareaProps]);
599
+ return {
600
+ id: e.id,
601
+ label: e.label,
602
+ labelPlacement: e.labelPlacement ?? "top",
603
+ descriptionPlacement: e.descriptionPlacement ?? "below-control",
604
+ labelId: e.label ? `${e.id}__label` : void 0,
605
+ value: e.value,
606
+ defaultValue: e.defaultValue,
607
+ placeholder: e.placeholder,
608
+ rows: b(e.rows),
609
+ disabled: e.disabled ?? !1,
610
+ readOnly: e.readOnly ?? !1,
611
+ required: e.required ?? !1,
612
+ hasError: n,
613
+ helperText: e.helperText,
614
+ errorText: e.errorText,
615
+ rootClassName: j(e.fullWidth, e.className),
616
+ controlClassName: M(n),
617
+ describedBy: r,
618
+ messageId: r,
619
+ textareaProps: e.textareaProps,
620
+ onChange: i
621
+ };
622
+ }
623
+ //#endregion
624
+ //#region src/Textarea.tsx
625
+ function F(t) {
626
+ let n = P(t);
627
+ return /* @__PURE__ */ (0, D.jsx)("div", {
628
+ className: n.rootClassName,
629
+ children: /* @__PURE__ */ (0, D.jsx)(e, {
630
+ id: n.id,
631
+ label: n.label,
632
+ helperText: n.hasError ? void 0 : n.helperText,
633
+ required: n.required,
634
+ labelPlacement: n.labelPlacement,
635
+ descriptionPlacement: n.descriptionPlacement,
636
+ children: /* @__PURE__ */ (0, D.jsxs)("div", {
637
+ className: "jo-ui-input__field",
638
+ children: [/* @__PURE__ */ (0, D.jsx)("textarea", {
639
+ ...n.textareaProps,
640
+ id: n.id,
641
+ className: n.controlClassName,
642
+ value: n.value,
643
+ defaultValue: n.value === void 0 ? n.defaultValue : void 0,
644
+ placeholder: n.placeholder,
645
+ rows: n.rows,
646
+ disabled: n.disabled,
647
+ readOnly: n.readOnly,
648
+ required: n.required,
649
+ "aria-invalid": n.hasError || void 0,
650
+ "aria-labelledby": n.labelId,
651
+ "aria-describedby": n.describedBy,
652
+ onChange: n.onChange
653
+ }), n.hasError && n.errorText ? /* @__PURE__ */ (0, D.jsx)("span", {
457
654
  id: n.messageId,
458
655
  className: "jo-ui-input__message jo-ui-input__message--error",
459
656
  role: "alert",
@@ -465,33 +662,33 @@ function S(t) {
465
662
  }
466
663
  //#endregion
467
664
  //#region src/semantic-inputs.tsx
468
- function C(e) {
469
- return /* @__PURE__ */ (0, x.jsx)(S, {
665
+ function I(e) {
666
+ return /* @__PURE__ */ (0, D.jsx)(A, {
470
667
  ...e,
471
668
  kind: "email"
472
669
  });
473
670
  }
474
- function w(e) {
475
- return /* @__PURE__ */ (0, x.jsx)(S, {
671
+ function L(e) {
672
+ return /* @__PURE__ */ (0, D.jsx)(A, {
476
673
  ...e,
477
674
  kind: "integer"
478
675
  });
479
676
  }
480
- function T(e) {
481
- return /* @__PURE__ */ (0, x.jsx)(S, {
677
+ function R(e) {
678
+ return /* @__PURE__ */ (0, D.jsx)(A, {
482
679
  ...e,
483
680
  kind: "decimal"
484
681
  });
485
682
  }
486
- function E(e) {
487
- return /* @__PURE__ */ (0, x.jsx)(S, {
683
+ function z(e) {
684
+ return /* @__PURE__ */ (0, D.jsx)(A, {
488
685
  ...e,
489
686
  kind: "percentage",
490
687
  maximumFractionDigits: e.maximumFractionDigits ?? 2
491
688
  });
492
689
  }
493
- function D(e) {
494
- return /* @__PURE__ */ (0, x.jsx)(S, {
690
+ function B(e) {
691
+ return /* @__PURE__ */ (0, D.jsx)(A, {
495
692
  ...e,
496
693
  kind: "currency",
497
694
  currency: e.currency ?? "USD",
@@ -500,4 +697,4 @@ function D(e) {
500
697
  });
501
698
  }
502
699
  //#endregion
503
- export { D as CurrencyInput, T as DecimalInput, C as EmailInput, S as InputField, w as IntegerInput, E as PercentageInput };
700
+ export { B as CurrencyInput, O as DateField, R as DecimalInput, I as EmailInput, A as InputField, L as IntegerInput, z as PercentageInput, F as Textarea };
@@ -32,3 +32,6 @@ export declare function resolveNumericPresentation(kind: InputKind, options?: {
32
32
  }): NumericPresentation;
33
33
  export declare function parseKindValue(kind: InputKind, value: string): ParsedInputValue;
34
34
  export declare function formatKindValue(kind: InputKind, value: string, options?: NumberFormatOptions | CurrencyFormatOptions): string;
35
+ export declare function inputWidthClass(fullWidth: boolean | undefined): string;
36
+ export declare function fieldMessageId(id: string, hasError: boolean, errorText?: string, helperText?: string): string | undefined;
37
+ export declare function controlRows(rows: number | undefined): number;
@@ -26,6 +26,7 @@ export interface InputProps {
26
26
  readonly hasError?: boolean;
27
27
  readonly helperText?: string;
28
28
  readonly errorText?: string;
29
+ readonly fullWidth?: boolean;
29
30
  readonly className?: string;
30
31
  readonly inputProps?: Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'type' | 'value' | 'defaultValue' | 'placeholder' | 'disabled' | 'readOnly' | 'required' | 'className'>;
31
32
  readonly onValueChange?: (value: string) => void;
@@ -1,2 +1,2 @@
1
- .jo-ui-input{--jo-ui-input-font-family:Inter,"Segoe UI",system-ui,sans-serif;--jo-ui-input-label:oklch(55.1% .027 264.364);--jo-ui-input-bg:transparent;--jo-ui-input-fg:#1c2333;--jo-ui-input-border:oklch(92.8% .006 264.531);--jo-ui-input-placeholder:oklch(70.7% .022 261.325);--jo-ui-input-focus:#14224a;--jo-ui-input-error-border:#c55262;--jo-ui-input-helper:oklch(70.7% .022 261.325);--jo-ui-input-error:#c55262;--jo-ui-input-required:#f87171;--jo-ui-input-disabled-bg:#f1f5f9;--jo-ui-input-disabled-fg:#94a3b8;font-family:var(--jo-ui-input-font-family);display:block}.theme-dark .jo-ui-input{--jo-ui-input-label:#9ca8bf;--jo-ui-input-bg:transparent;--jo-ui-input-fg:#e7ecf8;--jo-ui-input-border:#2f4268;--jo-ui-input-placeholder:#9ca8bf;--jo-ui-input-helper:#9ca8bf;--jo-ui-input-focus:#88a5ff;--jo-ui-input-disabled-bg:#1a2a49;--jo-ui-input-disabled-fg:#8ea0c1}.jo-ui-input__control-wrap{align-items:center;gap:.5rem;display:inline-flex}.jo-ui-input__symbol{color:var(--jo-ui-input-label);font-size:13px;line-height:19.5px}.jo-ui-input__symbol--prefix{padding-right:.25rem}.jo-ui-input__symbol--suffix{padding-left:.25rem}.jo-ui-input__control{outline-offset:2px;width:100%;font-size:13px;line-height:19.5px;font-family:var(--jo-ui-input-font-family);border-width:1px;border-color:var(--jo-ui-input-border);background:var(--jo-ui-input-bg);color:var(--jo-ui-input-fg);border-radius:.5rem;outline:2px solid #0000;padding:.5rem .75rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.jo-ui-input__control::placeholder{color:var(--jo-ui-input-placeholder);font-size:13px;line-height:19.5px}.jo-ui-input__control--numeric{text-align:right;width:calc(var(--jo-ui-input-numeric-width-ch,10)*1ch + 1.75rem);min-width:8rem}.jo-ui-input__control:focus-visible{outline-offset:2px;border-color:var(--jo-ui-input-focus);outline:2px solid #0000}.jo-ui-input__control:disabled{cursor:not-allowed;background:var(--jo-ui-input-disabled-bg);color:var(--jo-ui-input-disabled-fg);opacity:1}.jo-ui-input__control--error{border-color:var(--jo-ui-input-error-border)}.jo-ui-input__control--error:focus-visible{--tw-ring-color:var(--jo-ui-input-error-border);border-color:var(--jo-ui-input-error-border)}.jo-ui-input__message{font-size:10.5px;line-height:15.75px;font-family:var(--jo-ui-input-font-family);color:var(--jo-ui-input-helper);margin-top:.5rem;display:block}.jo-ui-input__message--error{color:var(--jo-ui-input-error)}.mb-1{margin-bottom:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.block{display:block}.inline-flex{display:inline-flex}.grid{display:grid}.min-h-10{min-height:2.5rem}.w-full{width:100%}.cursor-not-allowed{cursor:not-allowed}.items-center{align-items:center}.gap-1{gap:.25rem}.rounded-2xl{border-radius:1rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.px-3{padding-left:.75rem;padding-right:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pt-0{padding-top:0}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10\.5px\]{font-size:10.5px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-\[15\.75px\]{line-height:15.75px}.leading-\[19\.5px\]{line-height:19.5px}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.outline{outline-style:solid}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-1,.ring-2{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}
1
+ .jo-ui-input{--jo-ui-input-font-family:Inter,"Segoe UI",system-ui,sans-serif;--jo-ui-input-label:oklch(55.1% .027 264.364);--jo-ui-input-bg:transparent;--jo-ui-input-fg:#1c2333;--jo-ui-input-border:oklch(92.8% .006 264.531);--jo-ui-input-placeholder:oklch(70.7% .022 261.325);--jo-ui-input-focus:#14224a;--jo-ui-input-error-border:#c55262;--jo-ui-input-helper:oklch(70.7% .022 261.325);--jo-ui-input-error:#c55262;--jo-ui-input-required:#f87171;--jo-ui-input-disabled-bg:#f1f5f9;--jo-ui-input-disabled-fg:#94a3b8;font-family:var(--jo-ui-input-font-family);display:block}.theme-dark .jo-ui-input{--jo-ui-input-label:#9ca8bf;--jo-ui-input-bg:transparent;--jo-ui-input-fg:#e7ecf8;--jo-ui-input-border:#2f4268;--jo-ui-input-placeholder:#9ca8bf;--jo-ui-input-helper:#9ca8bf;--jo-ui-input-focus:#88a5ff;--jo-ui-input-disabled-bg:#1a2a49;--jo-ui-input-disabled-fg:#8ea0c1}.jo-ui-input__control-wrap{align-items:center;gap:.5rem;display:inline-flex}.jo-ui-input__symbol{color:var(--jo-ui-input-label);font-size:13px;line-height:19.5px}.jo-ui-input__symbol--prefix{padding-right:.25rem}.jo-ui-input__symbol--suffix{padding-left:.25rem}.jo-ui-input__control{outline-offset:2px;box-sizing:border-box;border-radius:var(--jo-radius-control,12px);width:100%;height:2.5rem;font-size:13px;line-height:calc(2.5rem - 2px);font-family:var(--jo-ui-input-font-family);border-width:1px;border-color:var(--jo-ui-input-border);background:var(--jo-ui-input-bg);color:var(--jo-ui-input-fg);outline:2px solid #0000;padding:0 .75rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.jo-ui-input__control,.jo-ui-textarea__control{min-height:2.5rem}.jo-ui-textarea__control{height:auto;padding-top:.5rem;padding-bottom:.5rem;line-height:1.25rem}.jo-ui-input__control::placeholder{color:var(--jo-ui-input-placeholder);font-size:13px;line-height:19.5px}.jo-ui-input__control--numeric{text-align:right;width:calc(var(--jo-ui-input-numeric-width-ch,10)*1ch + 1.75rem);min-width:8rem}.jo-ui-input__control:focus-visible{outline-offset:2px;border-color:var(--jo-ui-input-focus);outline:2px solid #0000}.jo-ui-input__control:disabled{cursor:not-allowed;background:var(--jo-ui-input-disabled-bg);color:var(--jo-ui-input-disabled-fg);opacity:1}.jo-ui-input__control--error{border-color:var(--jo-ui-input-error-border)}.jo-ui-input__control--error:focus-visible{--tw-ring-color:var(--jo-ui-input-error-border);border-color:var(--jo-ui-input-error-border)}.jo-ui-input__message{font-size:10.5px;line-height:15.75px;font-family:var(--jo-ui-input-font-family);color:var(--jo-ui-input-helper);margin-top:.5rem;display:block}.jo-ui-input__message--error{color:var(--jo-ui-input-error)}.jo-ui-form-layout .jo-ui-input:not(.jo-ui-input--inline),.jo-ui-input--full{width:100%}.jo-ui-form-layout .jo-ui-input:not(.jo-ui-input--inline) .jo-ui-input__control-wrap,.jo-ui-input--full .jo-ui-input__control-wrap{width:100%;display:flex}.jo-ui-input--inline,.jo-ui-input--inline .jo-ui-input__control-wrap{width:auto}.mb-1{margin-bottom:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.min-h-10{min-height:2.5rem}.w-full{width:100%}.cursor-not-allowed{cursor:not-allowed}.items-center{align-items:center}.gap-1{gap:.25rem}.rounded-2xl{border-radius:1rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.px-3{padding-left:.75rem;padding-right:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pt-0{padding-top:0}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10\.5px\]{font-size:10.5px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-\[15\.75px\]{line-height:15.75px}.leading-\[19\.5px\]{line-height:19.5px}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.outline{outline-style:solid}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-1,.ring-2{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}
2
2
  /*$vite$:1*/
@@ -0,0 +1,3 @@
1
+ export declare function textareaClassName(fullWidth: boolean | undefined, className?: string): string;
2
+ export declare function textareaControlClassName(hasError: boolean): string;
3
+ export declare function textareaDescribedBy(id: string, hasError: boolean, errorText?: string, helperText?: string): string | undefined;
@@ -0,0 +1,45 @@
1
+ import type { ChangeEvent, TextareaHTMLAttributes } from 'react';
2
+ import type { FieldMetadataDescriptionPlacement, FieldMetadataLabelPlacement } from '@net-advantage/jo-ui-field-metadata';
3
+ export interface TextareaProps {
4
+ readonly id: string;
5
+ readonly label?: string;
6
+ readonly labelPlacement?: FieldMetadataLabelPlacement;
7
+ readonly descriptionPlacement?: FieldMetadataDescriptionPlacement;
8
+ readonly value?: string;
9
+ readonly defaultValue?: string;
10
+ readonly placeholder?: string;
11
+ readonly rows?: number;
12
+ readonly disabled?: boolean;
13
+ readonly readOnly?: boolean;
14
+ readonly required?: boolean;
15
+ readonly hasError?: boolean;
16
+ readonly helperText?: string;
17
+ readonly errorText?: string;
18
+ readonly fullWidth?: boolean;
19
+ readonly className?: string;
20
+ readonly textareaProps?: Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'id' | 'value' | 'defaultValue' | 'placeholder' | 'rows' | 'disabled' | 'readOnly' | 'required' | 'className'>;
21
+ readonly onValueChange?: (value: string) => void;
22
+ }
23
+ export interface TextareaViewModel {
24
+ readonly id: string;
25
+ readonly label?: string;
26
+ readonly labelPlacement: FieldMetadataLabelPlacement;
27
+ readonly descriptionPlacement: FieldMetadataDescriptionPlacement;
28
+ readonly labelId?: string;
29
+ readonly value?: string;
30
+ readonly defaultValue?: string;
31
+ readonly placeholder?: string;
32
+ readonly rows: number;
33
+ readonly disabled: boolean;
34
+ readonly readOnly: boolean;
35
+ readonly required: boolean;
36
+ readonly hasError: boolean;
37
+ readonly helperText?: string;
38
+ readonly errorText?: string;
39
+ readonly rootClassName: string;
40
+ readonly controlClassName: string;
41
+ readonly describedBy?: string;
42
+ readonly messageId?: string;
43
+ readonly textareaProps?: TextareaProps['textareaProps'];
44
+ readonly onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;
45
+ }
@@ -0,0 +1,2 @@
1
+ import type { TextareaProps, TextareaViewModel } from './textarea.types';
2
+ export declare function useTextareaViewModel(props: TextareaProps): TextareaViewModel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@net-advantage/jo-ui-input",
3
- "version": "1.1.6",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -22,7 +22,7 @@
22
22
  "**/*.css"
23
23
  ],
24
24
  "dependencies": {
25
- "@net-advantage/jo-ui-field-metadata": "1.1.6"
25
+ "@net-advantage/jo-ui-field-metadata": "1.2.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^19.0.0",