@useloops/design-system 1.4.723 → 1.4.725

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.
@@ -1,3 +1,3 @@
1
1
  export { default } from '../systems/WebCore/FormBuilder/FormBuilder.js';
2
- export { BaseField, FormBuilderConfig, FormBuilderHandle, FormBuilderProps } from '../systems/WebCore/FormBuilder/types.js';
3
- export { DynamicFieldType, FieldType, FieldTypes, HtmlField } from '../systems/WebCore/FormBuilder/fieldRegistry.js';
2
+ export { FormBuilderConfig, FormBuilderHandle, FormBuilderProps } from '../systems/WebCore/FormBuilder/types.js';
3
+ export { ArrayActionsApi, ArrayField, ArrayItemField, ArrayRowApi, BaseField, DynamicFieldType, FieldType, FieldTypes, HtmlField } from '../systems/WebCore/FormBuilder/fieldRegistry.js';
@@ -0,0 +1 @@
1
+ import{jsxs as e,jsx as r}from"react/jsx-runtime";import{Stack as o,Collapse as t,Box as i}from"@mui/material";import{useState as n,useRef as a}from"react";import{useFieldArray as m,useFormState as d,Controller as s}from"react-hook-form";import"../../BrandCore/colorRamps.js";import"../../BrandCore/primitiveVariables.js";import"../../BrandCore/semanticColor.js";import"../../BrandCore/types.js";import"../../BrandCore/typography.js";import l from"../../BrandCore/Icon/Icon.js";import c from"../Button/Button.js";import p from"../IconButton/IconButton.js";import{CollapseMessage as u}from"./FieldMessage.js";import{getFieldDefinition as f,splitFieldProps as g}from"./fieldRegistry.js";const x=({field:x,control:h})=>{const{fields:v,append:j,remove:B}=m({control:h,name:x.name}),{errors:C}=d({control:h,name:x.name}),[I,b]=n(new Set),y=a(v);y.current=v;const M=a(!0),S=!M.current;M.current=!1;const w=v.length-I.size,F=w<=(x.minItems??0),R=void 0!==x.maxItems&&w>=x.maxItems,k=C?.[x.name],z=k?.root?.message??k?.message,A=e=>b(r=>new Set(r).add(e)),E=e=>j({value:e??x.defaultItem??""});return e(o,{children:[v.map((n,a)=>{const m=I.has(n.id),d=((e,r)=>"function"==typeof x.itemField?x.itemField(e,r):x.itemField)(a,{index:a,remove:()=>A(n.id),atMinimum:F,atMaximum:R}),c=f(d.fieldType);if(!c)return null;const v=c.component,j=g(d),C="none"===x.removeAction?{}:{endAdornment:r(p,{"aria-label":"Remove item",sizing:"xs",disabled:F||m,icon:r(l,{name:"delete"}),onClick:()=>A(n.id)})};return r(t,{in:!m,appear:S,timeout:"auto",onExited:()=>(e=>{const r=y.current.findIndex(r=>r.id===e);r>=0&&B(r),b(r=>{const o=new Set(r);return o.delete(e),o})})(n.id),children:r(i,{sx:{paddingBottom:"8px"},children:r(s,{name:`${x.name}.${a}.value`,control:h,render:({field:{ref:t,...i},fieldState:n})=>e(o,{children:[r(v,{fullWidth:!0,...C,...j,...i,inputRef:t,"aria-invalid":!!n.error||void 0}),r(u,{errorMessage:x.hideError||m?void 0:n.error?.message})]})})})},n.id)}),r(u,{errorMessage:x.hideError?void 0:z,edge:"bottom",gap:8,showicon:!0}),x.actions?x.actions({append:E,count:w,atMaximum:R}):r(c,{variation:"outlined",sizing:"sm",disabled:R,onClick:()=>E(),sx:{alignSelf:"flex-start"},children:x.addLabel??"Add"})]})};export{x as default};
@@ -1 +1 @@
1
- import{jsxs as r,jsx as e,Fragment as t}from"react/jsx-runtime";import{useTheme as o}from"@mui/material";import{mergeSx as i}from"merge-sx";import{memo as n}from"react";import{useWatch as l,Controller as m}from"react-hook-form";import{space as a}from"../../BrandCore/primitiveVariables.js";import s from"../Html/Html.js";import d from"../InputLabel/InputLabel.js";import p from"./components/StrengthIndicator/StrengthIndicator.js";import c from"./FieldCollapse.js";import f from"./FieldMessage.js";import{extractNoneOfThese as u,splitFieldProps as h,getFieldDefinition as g}from"./fieldRegistry.js";const x=n(({field:n,fieldRef:x,control:b})=>{const{custom:j}=o(),v=n,{fieldType:I,name:y,label:L,labelProps:S,helperText:T,helpTextProps:k,content:R,styleOverrides:w,strengthIndicator:C,hidden:F}=v,H=u(h(v)),M=l({control:b,name:y,disabled:!C}),P="checkbox"===I?`${"lg"===H.sizing?a[600]:a[500]}px`:void 0,$=`${y}-error`;return r(c,{hidden:F,sx:i({gap:j.margin.sm},w?.sxInputStack),children:["switch"!==I?L&&e(d,{...S,children:L}):null,(()=>{if("html"===I)return R?e(s,{children:R}):null;const o=g(I);if(!o)return null;const i=o.component;return e(m,{name:y,control:b,render:({field:{ref:n,...l},fieldState:m})=>r(t,{children:[e(i,{...H,...l,...o.adapt?.(v,l)??{},"aria-invalid":!!m.error||void 0,"aria-describedby":m.error?$:void 0,inputRef:r=>{n(r),((r,e)=>{"function"==typeof r?r(e):r&&(r.current=e)})(x,r)}}),C&&e(p,{value:M}),m.error&&e(f,{id:$,errorMessage:m.error.message,paddingLeft:P,showicon:!0})]})})})(),T?e(f,{helperText:T,paddingLeft:P,...k}):null]})});export{x as default};
1
+ import{jsxs as e,jsx as r,Fragment as o}from"react/jsx-runtime";import{useTheme as t}from"@mui/material";import{memo as n,useRef as i,useEffect as l}from"react";import{useWatch as a,Controller as s}from"react-hook-form";import{space as c}from"../../BrandCore/primitiveVariables.js";import d from"../Html/Html.js";import f from"../InputLabel/InputLabel.js";import p from"./ArrayFieldRows.js";import u from"./components/StrengthIndicator/StrengthIndicator.js";import m from"./FieldCollapse.js";import h,{CollapseMessage as g}from"./FieldMessage.js";import{extractNoneOfThese as v,splitFieldProps as y,getFieldDefinition as b}from"./fieldRegistry.js";const j=n(({field:n,fieldRef:j,control:x,appear:R=!1})=>{const{custom:B}=t(),I=n,{fieldType:S,name:F,label:L,labelProps:T,helperText:k,helpTextProps:w,content:P,styleOverrides:C,strengthIndicator:H,hidden:M,visibleWhen:O,deriveProps:$,hideError:z,focusOnReveal:A}=I,E=v(y(I)),V=Boolean(O)||Boolean($)||"function"==typeof L,W=a({control:x,disabled:!V}),q=Boolean(M)||!!O&&!O(W??{}),D=i(null),G=i(q),J=G.current&&!q;l(()=>{G.current=q});const K=Boolean(E.autoFocus)||Boolean(A)&&J;l(()=>{if(!K)return;const e=D.current;if(e&&"function"==typeof e.focus&&(e.focus(),"string"==typeof e.value&&"function"==typeof e.setSelectionRange))try{e.setSelectionRange(e.value.length,e.value.length)}catch{}},[K]);const N=$?$(W??{}):void 0,Q="function"==typeof L?L:void 0,U=Q?Q(W??{}):L,X=a({control:x,name:F,disabled:!H}),Y="checkbox"===S?`${"lg"===E.sizing?c[600]:c[500]}px`:void 0,Z=`${F}-error`;return e(m,{hidden:q,appear:R,sx:C?.sxInputStack,children:["switch"!==S?U&&r(f,{...T,children:U}):null,(()=>{if("html"===S)return P?r(d,{children:P}):null;if("array"===S)return r(p,{field:I,control:x});const t=b(S);if(!t)return null;const n=t.component;return r(s,{name:F,control:x,render:({field:{ref:i,...l},fieldState:a})=>e(o,{children:[r(n,{...E,...N,...l,...t.adapt?.({...I,label:U},l)??{},autoFocus:K,"aria-invalid":!!a.error||void 0,"aria-describedby":a.error?Z:void 0,inputRef:e=>{i(e),((e,r)=>{"function"==typeof e?e(r):e&&(e.current=r)})(j,e),D.current=e}}),H&&r(u,{value:X}),r(g,{id:Z,errorMessage:z?void 0:a.error?.message,paddingLeft:Y,showicon:!0})]})})})(),k?r(h,{helperText:k,paddingLeft:Y,...w}):null]})});export{j as default};
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import{Stack as i}from"@mui/material";import{useTheme as o}from"@mui/material/styles";import{mergeSx as r}from"merge-sx";import{motion as a,useReducedMotion as e,AnimatePresence as m}from"motion/react";import{useState as n}from"react";const c=a.create(i),s=[.32,.72,0,1],d=({hidden:i=!1,sx:a,children:d})=>{const{spacing:l,custom:p}=o(),u=e(),[h,f]=n(!1),g=Number.parseFloat(l(p.margin.md))||0,x=u?{duration:0}:{duration:.26,ease:s};return t(m,{initial:!1,children:!i&&t(c,{sx:r(a,{overflow:h?"hidden":"visible"}),initial:{height:0,opacity:0,marginBottom:0},animate:{height:"auto",opacity:1,marginBottom:g},exit:{height:0,opacity:0,marginBottom:0},transition:{...x,opacity:{...x,duration:.6*x.duration}},onAnimationStart:()=>f(!0),onAnimationComplete:()=>f(!1),children:d},"field")})};export{d as default};
1
+ import{jsx as r}from"react/jsx-runtime";import{Collapse as m,Stack as t}from"@mui/material";import{useTheme as i}from"@mui/material/styles";import{mergeSx as o}from"merge-sx";const a=({hidden:a=!1,appear:e=!1,sx:n,children:s})=>{const{spacing:p,custom:u}=i(),d=p(u.margin.md),{gridColumn:l,...c}="object"!=typeof n||null===n||Array.isArray(n)?{}:n;return r(m,{in:!a,appear:e,unmountOnExit:!0,timeout:"auto",sx:{gridColumn:l},children:r(t,{sx:o({gap:u.margin.sm,paddingBottom:d},c),children:s})})};export{a as default};
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import t from"../InputLabelHelp/InputLabelHelp.js";const r=({helperText:r,errorMessage:a,paddingLeft:l,id:d,...i})=>a?e(t,{id:d,role:"alert",showicon:!0,state:"negative",paddingLeft:l,children:a}):r?e(t,{state:"default",paddingLeft:l,...i,children:r}):null;export{r as default};
1
+ import{jsx as e}from"react/jsx-runtime";import{Collapse as t,Box as r}from"@mui/material";import{useRef as o}from"react";import a from"../InputLabelHelp/InputLabelHelp.js";const n=({errorMessage:a,gap:n=4,edge:p="top",...d})=>{const l=o(a);return a&&(l.current=a),e(t,{in:Boolean(a),appear:!0,unmountOnExit:!0,timeout:"auto",children:e(r,{sx:{["top"===p?"paddingTop":"paddingBottom"]:`${n}px`},children:e(i,{errorMessage:a??l.current,...d})})})},i=({helperText:t,errorMessage:r,paddingLeft:o,id:n,...i})=>r?e(a,{id:n,role:"alert",showicon:!0,state:"negative",paddingLeft:o,children:r}):t?e(a,{state:"default",paddingLeft:o,...i,children:t}):null;export{n as CollapseMessage,i as default};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import{zodResolver as t}from"@hookform/resolvers/zod";import{Box as o,Stack as i}from"@mui/material";import{mergeSx as s}from"merge-sx";import{forwardRef as m,useRef as n,useMemo as a,useEffect as l,useImperativeHandle as u}from"react";import{useForm as d,FormProvider as f}from"react-hook-form";import{usePrevious as c}from"../../../utils/usePrevious.js";import p from"./Field.js";import{getDefaultValues as h,getFieldDefault as g}from"./fieldRegistry.js";import b from"./FormActions.js";const v=m(({formConfig:m,onSubmit:v,onChange:V,onFormSubmit:x,onFormChange:F,submitButton:S,secondaryButton:y},B)=>{const{fields:C,mode:j,reValidateMode:I,autoComplete:k,formId:w,validateOnInit:R,disableInvalidSubmit:M,preserveHiddenValues:O,styleOverrides:T,schema:z,resolver:A}=m,E=v??x,G=V??F,H=c(C),N=n({isValid:!1,errors:{}}),P=d({mode:j||"onChange",reValidateMode:I,defaultValues:a(()=>h(C),[]),resolver:A??(z?t(z):void 0),shouldUnregister:!O}),{control:U,handleSubmit:q,reset:D,trigger:J,setValue:K,setFocus:L,getValues:Q,getFieldState:W,watch:X}=P;l(()=>{R&&J()},[]),l(()=>{if(!G)return;const e=X(()=>G(Q()));return()=>e.unsubscribe()},[X,Q,G]),l(()=>{if(void 0===H)return;const e=H.filter(({fieldType:e})=>"html"!==e).map(({name:e})=>e);C.filter(({name:r,fieldType:t})=>!e.includes(r)&&"html"!==t).forEach(e=>K(e.name,g(e)))},[C]);const Y=n(!1);return l(()=>{Y.current?D(h(C)):Y.current=!0},[w]),u(B,()=>({submit(){E&&q(E)()},reset(){D()},values:()=>Q(),valid:()=>N.current.isValid,errors:()=>N.current.errors,focus(e){L(e)},setValue:K,getFieldState:W,trigger:J,watch:X})),e(f,{...P,children:r(o,{component:"form",autoComplete:k,noValidate:!0,sx:T?.sxForm,...E&&{onSubmit:q(E)},children:[e(i,{sx:s({rowGap:0},T?.sxStack),children:C.map(r=>e(p,{field:r,fieldRef:r.ref,control:U},r.name))}),e(b,{control:U,stateRef:N,submitButton:S,secondaryButton:y,disableInvalidSubmit:M,sx:T?.sxButtons})]})})});v.displayName="FormBuilder";const V=v;export{V as default};
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import{zodResolver as t}from"@hookform/resolvers/zod";import{Box as o,Stack as i}from"@mui/material";import{mergeSx as s}from"merge-sx";import{forwardRef as m,useRef as a,useMemo as n,useEffect as l,useImperativeHandle as u}from"react";import{useForm as d,FormProvider as c}from"react-hook-form";import{usePrevious as f}from"../../../utils/usePrevious.js";import p from"./Field.js";import{getDefaultValues as h,getFieldDefault as g}from"./fieldRegistry.js";import b from"./FormActions.js";const v=m(({formConfig:m,onSubmit:v,onChange:V,onFormSubmit:x,onFormChange:F,submitButton:S,secondaryButton:y},B)=>{const{fields:C,mode:j,reValidateMode:I,autoComplete:k,formId:w,validateOnInit:R,disableInvalidSubmit:M,preserveHiddenValues:O,styleOverrides:T,schema:z,resolver:A}=m,E=v??x,G=V??F,H=f(C),N=a({isValid:!1,errors:{}}),P=d({mode:j||"onChange",reValidateMode:I,defaultValues:n(()=>h(C),[]),resolver:A??(z?t(z):void 0),shouldUnregister:!O}),{control:U,handleSubmit:q,reset:D,trigger:J,setValue:K,setFocus:L,getValues:Q,getFieldState:W,watch:X}=P;l(()=>{R&&J()},[]),l(()=>{if(!G)return;const e=X(()=>G(Q()));return()=>e.unsubscribe()},[X,Q,G]),l(()=>{if(void 0===H)return;const e=H.filter(({fieldType:e})=>"html"!==e).map(({name:e})=>e);C.filter(({name:r,fieldType:t})=>!e.includes(r)&&"html"!==t).forEach(e=>K(e.name,g(e)))},[C]);const Y=a(!1);return l(()=>{Y.current?D(h(C)):Y.current=!0},[w]),u(B,()=>({submit(){E&&q(E)()},reset(){D()},values:()=>Q(),valid:()=>N.current.isValid,errors:()=>N.current.errors,focus(e){L(e)},setValue:K,getFieldState:W,trigger:J,watch:X})),e(c,{...P,children:r(o,{component:"form",autoComplete:k,noValidate:!0,sx:T?.sxForm,...E&&{onSubmit:q(E)},children:[e(i,{sx:s({rowGap:0},T?.sxStack),children:C.map(r=>e(p,{field:r,fieldRef:r.ref,control:U,appear:Y.current},r.name))}),e(b,{control:U,stateRef:N,submitButton:S,secondaryButton:y,disableInvalidSubmit:M,sx:T?.sxButtons})]})})});v.displayName="FormBuilder";const V=v;export{V as default};
@@ -1 +1 @@
1
- import e from"../AutocompleteField/AutocompleteField.js";import t from"../Checkbox/Checkbox.js";import"../Checkbox/StyledCheckbox.js";import o from"../CheckboxGroup/CheckboxGroup.js";import l from"../CreatableAutocomplete/CreatableAutocomplete.js";import a from"../CustomField/CustomField.js";import r from"../Differential/Differential.js";import n from"../Likert/Likert.js";import u from"../NumberField/NumberField.js";import i from"../RadioGroup/RadioGroup.js";import f from"../Rank/Rank.js";import m from"../RichTextField/RichTextField.js";import"../SelectItem/SelectItem.js";import p from"../Select/Select.js";import d from"../Slider/Slider.js";import c from"../StarRating/StarRating.js";import s from"../Switch/Switch.js";import g from"../Textarea/Textarea.js";import h from"../TextField/TextField.js";const x={textfield:{component:h,getDefault:e=>e.defaultValue??""},numberfield:{component:u,getDefault:e=>e.defaultValue??0},textarea:{component:g,getDefault:e=>e.defaultValue??""},creatableautocomplete:{component:l,getDefault:e=>e.defaultValue??""},select:{component:p,getDefault:e=>e.defaultValue??""},autocomplete:{component:e,getDefault:e=>e.defaultValue,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},checkbox:{component:t,getDefault:e=>e.defaultValue??!1},checkboxGroup:{component:o,getDefault:e=>e.defaultValue??[]},switch:{component:s,getDefault:e=>e.defaultValue??!1,adapt:e=>({label:e.label})},slider:{component:d,getDefault:e=>Array.isArray(e.defaultValue)?e.defaultValue:e.defaultValue??e.min??0,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},starRating:{component:c,getDefault:e=>e.defaultValue??0,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},differential:{component:r,getDefault:e=>e.defaultValue??""},likert:{component:n,getDefault:e=>e.defaultValue??""},radioGroup:{component:i,getDefault:e=>e.defaultValue??""},ranking:{component:f,getDefault:e=>e.defaultValue?e.defaultValue.map(t=>e.options.find(e=>e.id===t)):e.options},richTextfield:{component:m,getDefault:e=>e.defaultValue??""},customfield:{component:a,getDefault:e=>e.defaultValue??""}},D=e=>x[e],V=e=>e.reduce((e,t)=>("html"!==t.fieldType&&(e[t.name]=x[t.fieldType].getDefault(t)),e),{}),b=e=>"html"===e.fieldType?void 0:x[e.fieldType].getDefault(e),j=["fieldType","name","ref","label","labelProps","helperText","helpTextProps","content","styleOverrides","strengthIndicator","defaultValue","hidden"],C=e=>{const t={};for(const o of Object.keys(e))j.includes(o)||(t[o]=e[o]);return t},T=e=>{if(e.noneOfThese)return!0;return(e.name||e.value||"").replace(/-/g,"_").includes("none_of_these")},k=e=>{if(!e.other?.enabled||!Array.isArray(e.options))return e;const t=e.options,o=t.findIndex(T);return-1===o?e:{...e,options:t.filter((e,t)=>t!==o),noneOfTheseOption:t[o]}};export{x as FIELD_REGISTRY,k as extractNoneOfThese,V as getDefaultValues,b as getFieldDefault,D as getFieldDefinition,C as splitFieldProps};
1
+ import e from"../AutocompleteField/AutocompleteField.js";import t from"../Checkbox/Checkbox.js";import"../Checkbox/StyledCheckbox.js";import o from"../CheckboxGroup/CheckboxGroup.js";import a from"../CreatableAutocomplete/CreatableAutocomplete.js";import l from"../CustomField/CustomField.js";import r from"../Differential/Differential.js";import n from"../Likert/Likert.js";import i from"../NumberField/NumberField.js";import u from"../RadioGroup/RadioGroup.js";import f from"../Rank/Rank.js";import m from"../RichTextField/RichTextField.js";import"../SelectItem/SelectItem.js";import d from"../Select/Select.js";import p from"../Slider/Slider.js";import c from"../StarRating/StarRating.js";import s from"../Switch/Switch.js";import h from"../Textarea/Textarea.js";import g from"../TextField/TextField.js";const b={textfield:{component:g,getDefault:e=>e.defaultValue??""},numberfield:{component:i,getDefault:e=>e.defaultValue??0},textarea:{component:h,getDefault:e=>e.defaultValue??""},creatableautocomplete:{component:a,getDefault:e=>e.defaultValue??""},select:{component:d,getDefault:e=>e.defaultValue??""},autocomplete:{component:e,getDefault:e=>e.defaultValue,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},checkbox:{component:t,getDefault:e=>e.defaultValue??!1},checkboxGroup:{component:o,getDefault:e=>e.defaultValue??[]},switch:{component:s,getDefault:e=>e.defaultValue??!1,adapt:e=>({label:e.label})},slider:{component:p,getDefault:e=>Array.isArray(e.defaultValue)?e.defaultValue:e.defaultValue??e.min??0,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},starRating:{component:c,getDefault:e=>e.defaultValue??0,adapt:(e,t)=>({onChange:(e,o)=>t.onChange(o)})},differential:{component:r,getDefault:e=>e.defaultValue??""},likert:{component:n,getDefault:e=>e.defaultValue??""},radioGroup:{component:u,getDefault:e=>e.defaultValue??""},ranking:{component:f,getDefault:e=>e.defaultValue?e.defaultValue.map(t=>e.options.find(e=>e.id===t)):e.options},richTextfield:{component:m,getDefault:e=>e.defaultValue??""},customfield:{component:l,getDefault:e=>e.defaultValue??""}},x=e=>b[e],V=e=>{if("html"!==e.fieldType)return"array"===e.fieldType?e.defaultValue??[]:b[e.fieldType].getDefault(e)},j=e=>e.reduce((e,t)=>("html"!==t.fieldType&&(e[t.name]=V(t)),e),{}),D=["fieldType","name","ref","label","labelProps","helperText","helpTextProps","content","styleOverrides","strengthIndicator","defaultValue","hidden","visibleWhen","hideError","focusOnReveal","itemField","minItems","maxItems","addLabel","defaultItem","removeAction","actions","deriveProps"],C=e=>{const t={};for(const o of Object.keys(e))D.includes(o)||(t[o]=e[o]);return t},T=e=>{if(e.noneOfThese)return!0;return(e.name||e.value||"").replace(/-/g,"_").includes("none_of_these")},k=e=>{if(!e.other?.enabled||!Array.isArray(e.options))return e;const t=e.options,o=t.findIndex(T);return-1===o?e:{...e,options:t.filter((e,t)=>t!==o),noneOfTheseOption:t[o]}};export{b as FIELD_REGISTRY,k as extractNoneOfThese,j as getDefaultValues,V as getFieldDefault,x as getFieldDefinition,C as splitFieldProps};
@@ -1 +1 @@
1
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import{useTheme as o,Stack as i}from"@mui/material";import{Placeholder as r}from"@tiptap/extension-placeholder";import{StarterKit as n}from"@tiptap/starter-kit";import{MenuButtonBold as l,MenuButtonItalic as a,MenuButtonUnderline as m,MenuButtonBulletedList as d,MenuButtonOrderedList as s}from"mui-tiptap";import{useRef as c}from"react";import p from"./StyledRichTextEditor.js";const u=({onChange:u,value:h,internalChange:f,minWidth:g=100,minHeight:x=100,maxHeight:b,placeholder:H,options:L={}})=>{const k=c(null);o();const{bold:C=!0,italic:R=!0,underline:j=!0,bulletList:v=!1,orderedList:w=!1}=L;return t(p,{sx:{"& .ProseMirror":{overflowY:"auto",minHeight:x,minWidth:g,maxHeight:b}},ref:k,onUpdate:({editor:t})=>{u&&u(t.getHTML()),f&&f()},enableInputRules:!1,extensions:[n.configure({strike:!1,code:!1,heading:!1,blockquote:!1,horizontalRule:!1,codeBlock:!1,bold:!!C&&{},italic:!!R&&{},listItem:!(!v&&!w)&&{},bulletList:!!v&&{},orderedList:!!w&&{}}),r.configure({placeholder:H})],content:h,renderControls:()=>e(i,{direction:"row",children:[C&&t(l,{}),R&&t(a,{}),j&&t(m,{}),v&&t(d,{}),w&&t(s,{})]})})};export{u as default};
1
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import{useTheme as o,Stack as i}from"@mui/material";import{Placeholder as r}from"@tiptap/extension-placeholder";import{StarterKit as n}from"@tiptap/starter-kit";import{MenuButtonBold as l,MenuButtonItalic as a,MenuButtonUnderline as m,MenuButtonBulletedList as d,MenuButtonOrderedList as s}from"mui-tiptap";import{useRef as c}from"react";import u from"./StyledRichTextEditor.js";const p=({onChange:p,value:h,internalChange:f,minWidth:g=100,minHeight:x=100,maxHeight:b,placeholder:H,options:L={},autoFocus:k=!1})=>{const C=c(null);o();const{bold:R=!0,italic:j=!0,underline:v=!0,bulletList:w=!1,orderedList:I=!1}=L;return t(u,{sx:{"& .ProseMirror":{overflowY:"auto",minHeight:x,minWidth:g,maxHeight:b}},ref:C,autofocus:!!k&&"end",onUpdate:({editor:t})=>{p&&p(t.getHTML()),f&&f()},enableInputRules:!1,extensions:[n.configure({strike:!1,code:!1,heading:!1,blockquote:!1,horizontalRule:!1,codeBlock:!1,bold:!!R&&{},italic:!!j&&{},listItem:!(!w&&!I)&&{},bulletList:!!w&&{},orderedList:!!I&&{}}),r.configure({placeholder:H})],content:h,renderControls:()=>e(i,{direction:"row",children:[R&&t(l,{}),j&&t(a,{}),v&&t(m,{}),w&&t(d,{}),I&&t(s,{})]})})};export{p as default};
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{InputAdornment as t}from"@mui/material";import{space as n}from"../../BrandCore/primitiveVariables.js";import r from"../InputFieldBase/InputFieldBase.js";const i=({startAdornment:i,endAdornment:o,placeholder:s,onChange:a,internalChange:l,inputRef:p,...d})=>e(r,{placeholder:s,sx:{height:n[500],"& .MuiOutlinedInput-input":{pl:i?1:2,pr:i?1:2}},inputRef:p,slotProps:{input:{startAdornment:i?e(t,{position:"start",disablePointerEvents:d.disabled,sx:{pl:1},children:i}):null,endAdornment:o?e(t,{position:"start",disablePointerEvents:d.disabled,sx:{pr:1},children:o}):null}},...d,onChange:e=>{a&&a(e),l&&l()}});export{i as default};
1
+ import{jsx as t}from"react/jsx-runtime";import{InputAdornment as e}from"@mui/material";import{space as n}from"../../BrandCore/primitiveVariables.js";import r from"../InputFieldBase/InputFieldBase.js";const i=({startAdornment:i,endAdornment:o,placeholder:s,onChange:l,internalChange:a,inputRef:p,slotProps:d,...m})=>t(r,{placeholder:s,sx:{height:n[500],"& .MuiOutlinedInput-input":{pl:i?1:2,pr:i?1:2}},inputRef:p,slotProps:{...d,input:{startAdornment:i?t(e,{position:"start",disablePointerEvents:m.disabled,sx:{pl:1},children:i}):null,endAdornment:o?t(e,{position:"start",disablePointerEvents:m.disabled,sx:{pr:1},children:o}):null,...d?.input??{}}},...m,onChange:t=>{l&&l(t),a&&a()}});export{i as default};
@@ -0,0 +1 @@
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("@mui/material"),i=require("react"),t=require("react-hook-form");require("../../BrandCore/colorRamps.js"),require("../../BrandCore/primitiveVariables.js"),require("../../BrandCore/semanticColor.js"),require("../../BrandCore/types.js"),require("../../BrandCore/typography.js");var n=require("../../BrandCore/Icon/Icon.js"),o=require("../Button/Button.js"),s=require("../IconButton/IconButton.js"),a=require("./FieldMessage.js"),d=require("./fieldRegistry.js");module.exports=({field:l,control:u})=>{const{fields:m,append:c,remove:x}=t.useFieldArray({control:u,name:l.name}),{errors:p}=t.useFormState({control:u,name:l.name}),[j,f]=i.useState(new Set),g=i.useRef(m);g.current=m;const v=i.useRef(!0),q=!v.current;v.current=!1;const h=m.length-j.size,C=h<=(l.minItems??0),B=void 0!==l.maxItems&&h>=l.maxItems,I=p?.[l.name],S=I?.root?.message??I?.message,F=e=>f(r=>new Set(r).add(e)),M=e=>c({value:e??l.defaultItem??""});return e.jsxs(r.Stack,{children:[m.map((i,o)=>{const m=j.has(i.id),c=((e,r)=>"function"==typeof l.itemField?l.itemField(e,r):l.itemField)(o,{index:o,remove:()=>F(i.id),atMinimum:C,atMaximum:B}),p=d.getFieldDefinition(c.fieldType);if(!p)return null;const v=p.component,h=d.splitFieldProps(c),I="none"===l.removeAction?{}:{endAdornment:e.jsx(s,{"aria-label":"Remove item",sizing:"xs",disabled:C||m,icon:e.jsx(n.default,{name:"delete"}),onClick:()=>F(i.id)})};return e.jsx(r.Collapse,{in:!m,appear:q,timeout:"auto",onExited:()=>(e=>{const r=g.current.findIndex(r=>r.id===e);r>=0&&x(r),f(r=>{const i=new Set(r);return i.delete(e),i})})(i.id),children:e.jsx(r.Box,{sx:{paddingBottom:"8px"},children:e.jsx(t.Controller,{name:`${l.name}.${o}.value`,control:u,render:({field:{ref:i,...t},fieldState:n})=>e.jsxs(r.Stack,{children:[e.jsx(v,{fullWidth:!0,...I,...h,...t,inputRef:i,"aria-invalid":!!n.error||void 0}),e.jsx(a.CollapseMessage,{errorMessage:l.hideError||m?void 0:n.error?.message})]})})})},i.id)}),e.jsx(a.CollapseMessage,{errorMessage:l.hideError?void 0:S,edge:"bottom",gap:8,showicon:!0}),l.actions?l.actions({append:M,count:h,atMaximum:B}):e.jsx(o,{variation:"outlined",sizing:"sm",disabled:B,onClick:()=>M(),sx:{alignSelf:"flex-start"},children:l.addLabel??"Add"})]})};
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),r=require("@mui/material"),i=require("merge-sx"),t=require("react"),s=require("react-hook-form"),n=require("../../BrandCore/primitiveVariables.js"),l=require("../Html/Html.js"),o=require("../InputLabel/InputLabel.js"),a=require("./components/StrengthIndicator/StrengthIndicator.js"),d=require("./FieldCollapse.js"),u=require("./FieldMessage.js"),c=require("./fieldRegistry.js");var p=t.memo(({field:t,fieldRef:p,control:m})=>{const{custom:x}=r.useTheme(),h=t,{fieldType:f,name:g,label:j,labelProps:q,helperText:b,helpTextProps:v,content:I,styleOverrides:T,strengthIndicator:y,hidden:F}=h,S=c.extractNoneOfThese(c.splitFieldProps(h)),L=s.useWatch({control:m,name:g,disabled:!y}),k="checkbox"===f?`${"lg"===S.sizing?n.space[600]:n.space[500]}px`:void 0,C=`${g}-error`;return e.jsxs(d,{hidden:F,sx:i.mergeSx({gap:x.margin.sm},T?.sxInputStack),children:["switch"!==f?j&&e.jsx(o,{...q,children:j}):null,(()=>{if("html"===f)return I?e.jsx(l,{children:I}):null;const r=c.getFieldDefinition(f);if(!r)return null;const i=r.component;return e.jsx(s.Controller,{name:g,control:m,render:({field:{ref:t,...s},fieldState:n})=>e.jsxs(e.Fragment,{children:[e.jsx(i,{...S,...s,...r.adapt?.(h,s)??{},"aria-invalid":!!n.error||void 0,"aria-describedby":n.error?C:void 0,inputRef:e=>{t(e),((e,r)=>{"function"==typeof e?e(r):e&&(e.current=r)})(p,e)}}),y&&e.jsx(a,{value:L}),n.error&&e.jsx(u,{id:C,errorMessage:n.error.message,paddingLeft:k,showicon:!0})]})})})(),b?e.jsx(u,{helperText:b,paddingLeft:k,...v}):null]})});module.exports=p;
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("@mui/material"),t=require("react"),n=require("react-hook-form"),o=require("../../BrandCore/primitiveVariables.js"),i=require("../Html/Html.js"),s=require("../InputLabel/InputLabel.js"),l=require("./ArrayFieldRows.js"),a=require("./components/StrengthIndicator/StrengthIndicator.js"),u=require("./FieldCollapse.js"),c=require("./FieldMessage.js"),d=require("./fieldRegistry.js");var f=t.memo(({field:f,fieldRef:p,control:h,appear:m=!1})=>{const{custom:x}=r.useTheme(),g=f,{fieldType:j,name:v,label:y,labelProps:b,helperText:q,helpTextProps:R,content:F,styleOverrides:B,strengthIndicator:I,hidden:S,visibleWhen:T,deriveProps:C,hideError:L,focusOnReveal:P}=g,k=d.extractNoneOfThese(d.splitFieldProps(g)),w=Boolean(T)||Boolean(C)||"function"==typeof y,E=n.useWatch({control:h,disabled:!w}),M=Boolean(S)||!!T&&!T(E??{}),O=t.useRef(null),W=t.useRef(M),H=W.current&&!M;t.useEffect(()=>{W.current=M});const $=Boolean(k.autoFocus)||Boolean(P)&&H;t.useEffect(()=>{if(!$)return;const e=O.current;if(e&&"function"==typeof e.focus&&(e.focus(),"string"==typeof e.value&&"function"==typeof e.setSelectionRange))try{e.setSelectionRange(e.value.length,e.value.length)}catch{}},[$]);const z=C?C(E??{}):void 0,A="function"==typeof y?y:void 0,D=A?A(E??{}):y,N=n.useWatch({control:h,name:v,disabled:!I}),V="checkbox"===j?`${"lg"===k.sizing?o.space[600]:o.space[500]}px`:void 0,G=`${v}-error`;return e.jsxs(u,{hidden:M,appear:m,sx:B?.sxInputStack,children:["switch"!==j?D&&e.jsx(s,{...b,children:D}):null,(()=>{if("html"===j)return F?e.jsx(i,{children:F}):null;if("array"===j)return e.jsx(l,{field:g,control:h});const r=d.getFieldDefinition(j);if(!r)return null;const t=r.component;return e.jsx(n.Controller,{name:v,control:h,render:({field:{ref:n,...o},fieldState:i})=>e.jsxs(e.Fragment,{children:[e.jsx(t,{...k,...z,...o,...r.adapt?.({...g,label:D},o)??{},autoFocus:$,"aria-invalid":!!i.error||void 0,"aria-describedby":i.error?G:void 0,inputRef:e=>{n(e),((e,r)=>{"function"==typeof e?e(r):e&&(e.current=r)})(p,e),O.current=e}}),I&&e.jsx(a,{value:N}),e.jsx(c.CollapseMessage,{id:G,errorMessage:L?void 0:i.error?.message,paddingLeft:V,showicon:!0})]})})})(),q?e.jsx(c.default,{helperText:q,paddingLeft:V,...R}):null]})});module.exports=f;
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),i=require("@mui/material"),t=require("@mui/material/styles"),r=require("merge-sx"),a=require("motion/react"),o=require("react");const n=a.motion.create(i.Stack),m=[.32,.72,0,1];module.exports=({hidden:i=!1,sx:s,children:u})=>{const{spacing:c,custom:d}=t.useTheme(),l=a.useReducedMotion(),[h,g]=o.useState(!1),x=Number.parseFloat(c(d.margin.md))||0,p=l?{duration:0}:{duration:.26,ease:m};return e.jsx(a.AnimatePresence,{initial:!1,children:!i&&e.jsx(n,{sx:r.mergeSx(s,{overflow:h?"hidden":"visible"}),initial:{height:0,opacity:0,marginBottom:0},animate:{height:"auto",opacity:1,marginBottom:x},exit:{height:0,opacity:0,marginBottom:0},transition:{...p,opacity:{...p,duration:.6*p.duration}},onAnimationStart:()=>g(!0),onAnimationComplete:()=>g(!1),children:u},"field")})};
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("@mui/material"),i=require("@mui/material/styles"),t=require("merge-sx");module.exports=({hidden:a=!1,appear:m=!1,sx:s,children:u})=>{const{spacing:n,custom:o}=i.useTheme(),l=n(o.margin.md),{gridColumn:d,...c}="object"!=typeof s||null===s||Array.isArray(s)?{}:s;return e.jsx(r.Collapse,{in:!a,appear:m,unmountOnExit:!0,timeout:"auto",sx:{gridColumn:d},children:e.jsx(r.Stack,{sx:t.mergeSx({gap:o.margin.sm,paddingBottom:l},c),children:u})})};
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("../InputLabelHelp/InputLabelHelp.js");module.exports=({helperText:r,errorMessage:a,paddingLeft:i,id:l,...d})=>a?e.jsx(t,{id:l,role:"alert",showicon:!0,state:"negative",paddingLeft:i,children:a}):r?e.jsx(t,{state:"default",paddingLeft:i,...d,children:r}):null;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("@mui/material"),t=require("react"),a=require("../InputLabelHelp/InputLabelHelp.js");const s=({helperText:r,errorMessage:t,paddingLeft:s,id:n,...o})=>t?e.jsx(a,{id:n,role:"alert",showicon:!0,state:"negative",paddingLeft:s,children:t}):r?e.jsx(a,{state:"default",paddingLeft:s,...o,children:r}):null;exports.CollapseMessage=({errorMessage:a,gap:n=4,edge:o="top",...i})=>{const l=t.useRef(a);return a&&(l.current=a),e.jsx(r.Collapse,{in:Boolean(a),appear:!0,unmountOnExit:!0,timeout:"auto",children:e.jsx(r.Box,{sx:{["top"===o?"paddingTop":"paddingBottom"]:`${n}px`},children:e.jsx(s,{errorMessage:a??l.current,...i})})})},exports.default=s;
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),r=require("@hookform/resolvers/zod"),t=require("@mui/material"),s=require("merge-sx"),o=require("react"),i=require("react-hook-form"),u=require("../../../utils/usePrevious.js"),a=require("./Field.js"),l=require("./fieldRegistry.js"),n=require("./FormActions.js");const d=o.forwardRef(({formConfig:d,onSubmit:m,onChange:c,onFormSubmit:f,onFormChange:g,submitButton:v,secondaryButton:h},x)=>{const{fields:b,mode:p,reValidateMode:F,autoComplete:V,formId:S,validateOnInit:j,disableInvalidSubmit:q,preserveHiddenValues:y,styleOverrides:B,schema:R,resolver:C}=d,E=m??f,I=c??g,k=u.usePrevious(b),w=o.useRef({isValid:!1,errors:{}}),D=i.useForm({mode:p||"onChange",reValidateMode:F,defaultValues:o.useMemo(()=>l.getDefaultValues(b),[]),resolver:C??(R?r.zodResolver(R):void 0),shouldUnregister:!y}),{control:M,handleSubmit:P,reset:z,trigger:H,setValue:O,setFocus:T,getValues:A,getFieldState:G,watch:N}=D;o.useEffect(()=>{j&&H()},[]),o.useEffect(()=>{if(!I)return;const e=N(()=>I(A()));return()=>e.unsubscribe()},[N,A,I]),o.useEffect(()=>{if(void 0===k)return;const e=k.filter(({fieldType:e})=>"html"!==e).map(({name:e})=>e);b.filter(({name:r,fieldType:t})=>!e.includes(r)&&"html"!==t).forEach(e=>O(e.name,l.getFieldDefault(e)))},[b]);const U=o.useRef(!1);return o.useEffect(()=>{U.current?z(l.getDefaultValues(b)):U.current=!0},[S]),o.useImperativeHandle(x,()=>({submit(){E&&P(E)()},reset(){z()},values:()=>A(),valid:()=>w.current.isValid,errors:()=>w.current.errors,focus(e){T(e)},setValue:O,getFieldState:G,trigger:H,watch:N})),e.jsx(i.FormProvider,{...D,children:e.jsxs(t.Box,{component:"form",autoComplete:V,noValidate:!0,sx:B?.sxForm,...E&&{onSubmit:P(E)},children:[e.jsx(t.Stack,{sx:s.mergeSx({rowGap:0},B?.sxStack),children:b.map(r=>e.jsx(a,{field:r,fieldRef:r.ref,control:M},r.name))}),e.jsx(n,{control:M,stateRef:w,submitButton:v,secondaryButton:h,disableInvalidSubmit:q,sx:B?.sxButtons})]})})});d.displayName="FormBuilder";const m=d;module.exports=m;
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("@hookform/resolvers/zod"),t=require("@mui/material"),s=require("merge-sx"),o=require("react"),i=require("react-hook-form"),u=require("../../../utils/usePrevious.js"),a=require("./Field.js"),l=require("./fieldRegistry.js"),n=require("./FormActions.js");const d=o.forwardRef(({formConfig:d,onSubmit:m,onChange:c,onFormSubmit:f,onFormChange:g,submitButton:v,secondaryButton:h},x)=>{const{fields:p,mode:b,reValidateMode:F,autoComplete:V,formId:S,validateOnInit:j,disableInvalidSubmit:q,preserveHiddenValues:y,styleOverrides:B,schema:R,resolver:C}=d,E=m??f,I=c??g,k=u.usePrevious(p),w=o.useRef({isValid:!1,errors:{}}),D=i.useForm({mode:b||"onChange",reValidateMode:F,defaultValues:o.useMemo(()=>l.getDefaultValues(p),[]),resolver:C??(R?r.zodResolver(R):void 0),shouldUnregister:!y}),{control:M,handleSubmit:P,reset:z,trigger:H,setValue:O,setFocus:T,getValues:A,getFieldState:G,watch:N}=D;o.useEffect(()=>{j&&H()},[]),o.useEffect(()=>{if(!I)return;const e=N(()=>I(A()));return()=>e.unsubscribe()},[N,A,I]),o.useEffect(()=>{if(void 0===k)return;const e=k.filter(({fieldType:e})=>"html"!==e).map(({name:e})=>e);p.filter(({name:r,fieldType:t})=>!e.includes(r)&&"html"!==t).forEach(e=>O(e.name,l.getFieldDefault(e)))},[p]);const U=o.useRef(!1);return o.useEffect(()=>{U.current?z(l.getDefaultValues(p)):U.current=!0},[S]),o.useImperativeHandle(x,()=>({submit(){E&&P(E)()},reset(){z()},values:()=>A(),valid:()=>w.current.isValid,errors:()=>w.current.errors,focus(e){T(e)},setValue:O,getFieldState:G,trigger:H,watch:N})),e.jsx(i.FormProvider,{...D,children:e.jsxs(t.Box,{component:"form",autoComplete:V,noValidate:!0,sx:B?.sxForm,...E&&{onSubmit:P(E)},children:[e.jsx(t.Stack,{sx:s.mergeSx({rowGap:0},B?.sxStack),children:p.map(r=>e.jsx(a,{field:r,fieldRef:r.ref,control:M,appear:U.current},r.name))}),e.jsx(n,{control:M,stateRef:w,submitButton:v,secondaryButton:h,disableInvalidSubmit:q,sx:B?.sxButtons})]})})});d.displayName="FormBuilder";const m=d;module.exports=m;
@@ -1,7 +1,7 @@
1
1
  import { CustomFieldProps } from '../CustomField/CustomField.js';
2
2
  import { RichTextFieldProps } from '../RichTextField/RichTextField.js';
3
3
  import * as react from 'react';
4
- import { ComponentProps, ReactElement } from 'react';
4
+ import { Ref, ReactElement, ReactNode, ComponentProps } from 'react';
5
5
  import { RankProps } from '../Rank/types.js';
6
6
  import { RadioGroupProps } from '../RadioGroup/RadioGroup.js';
7
7
  import { LikertProps } from '../Likert/Likert.js';
@@ -11,15 +11,54 @@ import { SliderProps } from '../Slider/Slider.js';
11
11
  import { SwitchProps } from '../Switch/Switch.js';
12
12
  import { CheckboxGroupProps } from '../CheckboxGroup/CheckboxGroup.js';
13
13
  import { CheckboxProps } from '../Checkbox/Checkbox.js';
14
+ import { SxProps, Theme } from '@mui/material';
14
15
  import { AutocompleteFieldProps } from '../AutocompleteSingle/types.js';
15
16
  import { SelectProps } from '../Select/types.js';
16
17
  import { CreatableAutocompleteProps } from '../CreatableAutocomplete/CreatableAutocomplete.js';
17
18
  import { TextareaProps } from '../Textarea/Textarea.js';
18
19
  import { NumberFieldProps } from '../NumberField/types.js';
19
20
  import { TextFieldProps } from '../TextField/TextField.js';
20
- import { FieldValues } from 'react-hook-form';
21
- import { BaseField } from './types.js';
21
+ import { FieldValues, FieldPath } from 'react-hook-form';
22
+ import { InputLabelProps } from '../InputLabel/InputLabel.js';
23
+ import { InputLabelHelpProps } from '../InputLabelHelp/InputLabelHelp.js';
22
24
 
25
+ interface BaseField<TValues extends FieldValues = FieldValues> {
26
+ name: FieldPath<TValues>;
27
+ id?: string;
28
+ ref?: Ref<HTMLElement>;
29
+ /** A function label re-renders from the live form values — e.g. a toggle label that greys when off. */
30
+ label?: string | ReactElement | ((values: TValues) => string | ReactElement);
31
+ labelProps?: InputLabelProps;
32
+ helperText?: string | ReactNode;
33
+ helpTextProps?: InputLabelHelpProps;
34
+ hidden?: boolean;
35
+ /**
36
+ * Declarative visibility: the field shows only while this returns true for the live form values,
37
+ * animating in and out. The field stays registered while hidden unless the form unregisters hidden
38
+ * values (see `preserveHiddenValues`). Combines with `hidden` (either hides).
39
+ */
40
+ visibleWhen?: (values: TValues) => boolean;
41
+ /**
42
+ * Reactive props: recomputed from the live form values and merged over the field's static props —
43
+ * e.g. a select whose `selections` depend on how many rows another field holds.
44
+ */
45
+ deriveProps?: (values: TValues) => Record<string, unknown>;
46
+ /** Suppress the inline error message — for dense layouts that surface the error elsewhere. */
47
+ hideError?: boolean;
48
+ /**
49
+ * Focus the field (caret at the end for text inputs) when it becomes visible on a live form —
50
+ * pairs with `visibleWhen`/`hidden` so toggling a section drops the user straight into it.
51
+ */
52
+ focusOnReveal?: boolean;
53
+ /** Narrowed per control type in `DynamicField`; declared here so the union is uniformly readable. */
54
+ defaultValue?: unknown;
55
+ disabled?: boolean;
56
+ styleOverrides?: {
57
+ sxInputWrapper?: SxProps<Theme>;
58
+ sxInputBase?: SxProps<Theme>;
59
+ sxInputStack?: SxProps<Theme>;
60
+ };
61
+ }
23
62
  /** Props handed to a field's component on every render — supplied by the form, never the config. */
24
63
  interface RhfFieldProps {
25
64
  value: unknown;
@@ -124,7 +163,7 @@ type ControlField<K extends DynamicFieldType, TValues extends FieldValues = Fiel
124
163
  defaultValue?: ControlProps<K> extends {
125
164
  value?: infer V;
126
165
  } ? V : unknown;
127
- } & ExtrasFor<K> & Partial<Omit<ControlProps<K>, 'value' | 'onChange' | 'name' | 'inputRef' | 'internalChange' | 'defaultValue'>>;
166
+ } & ExtrasFor<K> & Partial<Omit<ControlProps<K>, 'value' | 'onChange' | 'name' | 'inputRef' | 'internalChange' | 'defaultValue' | 'label'>>;
128
167
  type DynamicField<TValues extends FieldValues = FieldValues> = {
129
168
  [K in DynamicFieldType]: ControlField<K, TValues>;
130
169
  }[DynamicFieldType];
@@ -133,8 +172,51 @@ type HtmlField<TValues extends FieldValues = FieldValues> = Omit<BaseField<TValu
133
172
  fieldType: 'html';
134
173
  content: ReactElement;
135
174
  };
136
- type FieldTypes<TValues extends FieldValues = FieldValues> = DynamicField<TValues> | HtmlField<TValues>;
175
+ /** Per-row control config for an `ArrayField` any registry control, minus the row-managed keys. */
176
+ type ArrayItemField = {
177
+ fieldType: DynamicFieldType;
178
+ } & Record<string, unknown>;
179
+ /** Handed to an `itemField` function so custom rows can own their remove action. */
180
+ interface ArrayRowApi {
181
+ index: number;
182
+ /** Collapse this row away, then remove it from the array. */
183
+ remove: () => void;
184
+ atMinimum: boolean;
185
+ atMaximum: boolean;
186
+ }
187
+ /** Handed to the `actions` slot so custom footers can append rows (e.g. an import button). */
188
+ interface ArrayActionsApi {
189
+ /** Append a row holding `value` (falls back to `defaultItem`, then `''`). */
190
+ append: (value?: unknown) => void;
191
+ count: number;
192
+ atMaximum: boolean;
193
+ }
194
+ /**
195
+ * A react-hook-form field array: `name` holds an array of `{ value }` rows (react-hook-form field arrays
196
+ * require object items), each rendered as an `itemField` control with a remove action, plus an append
197
+ * button. `itemField` may be a function of the row index (e.g. numbered placeholders) and receives the
198
+ * row's api for rows that render their own actions.
199
+ */
200
+ type ArrayField<TValues extends FieldValues = FieldValues> = Omit<BaseField<TValues>, 'defaultValue'> & {
201
+ fieldType: 'array';
202
+ defaultValue?: {
203
+ value: unknown;
204
+ }[];
205
+ itemField: ArrayItemField | ((index: number, row: ArrayRowApi) => ArrayItemField);
206
+ /** Row removal disables at this count. */
207
+ minItems?: number;
208
+ /** The append button disables at this count. */
209
+ maxItems?: number;
210
+ addLabel?: string;
211
+ /** Value a newly appended row starts with. Defaults to `''`. */
212
+ defaultItem?: unknown;
213
+ /** `'none'` skips injecting the delete `endAdornment` — for rows that render their own actions. */
214
+ removeAction?: 'endAdornment' | 'none';
215
+ /** Replaces the default append button — e.g. Add + Import side by side. */
216
+ actions?: (api: ArrayActionsApi) => ReactNode;
217
+ };
218
+ type FieldTypes<TValues extends FieldValues = FieldValues> = DynamicField<TValues> | HtmlField<TValues> | ArrayField<TValues>;
137
219
  type FieldType = FieldTypes['fieldType'];
138
220
 
139
221
  export { FIELD_REGISTRY };
140
- export type { DynamicField, DynamicFieldType, FieldType, FieldTypes, HtmlField };
222
+ export type { ArrayActionsApi, ArrayField, ArrayItemField, ArrayRowApi, BaseField, DynamicField, DynamicFieldType, FieldType, FieldTypes, HtmlField };
@@ -1 +1 @@
1
- "use strict";var e=require("../AutocompleteField/AutocompleteField.js"),t=require("../Checkbox/Checkbox.js");require("../Checkbox/StyledCheckbox.js");var l=require("../CheckboxGroup/CheckboxGroup.js"),a=require("../CreatableAutocomplete/CreatableAutocomplete.js"),u=require("../CustomField/CustomField.js"),r=require("../Differential/Differential.js"),o=require("../Likert/Likert.js"),n=require("../NumberField/NumberField.js"),i=require("../RadioGroup/RadioGroup.js"),f=require("../Rank/Rank.js"),d=require("../RichTextField/RichTextField.js");require("../SelectItem/SelectItem.js");var s=require("../Select/Select.js"),c=require("../Slider/Slider.js"),p=require("../StarRating/StarRating.js"),m=require("../Switch/Switch.js"),g=require("../Textarea/Textarea.js");const h={textfield:{component:require("../TextField/TextField.js"),getDefault:e=>e.defaultValue??""},numberfield:{component:n.default,getDefault:e=>e.defaultValue??0},textarea:{component:g,getDefault:e=>e.defaultValue??""},creatableautocomplete:{component:a,getDefault:e=>e.defaultValue??""},select:{component:s,getDefault:e=>e.defaultValue??""},autocomplete:{component:e,getDefault:e=>e.defaultValue,adapt:(e,t)=>({onChange:(e,l)=>t.onChange(l)})},checkbox:{component:t,getDefault:e=>e.defaultValue??!1},checkboxGroup:{component:l,getDefault:e=>e.defaultValue??[]},switch:{component:m,getDefault:e=>e.defaultValue??!1,adapt:e=>({label:e.label})},slider:{component:c,getDefault:e=>Array.isArray(e.defaultValue)?e.defaultValue:e.defaultValue??e.min??0,adapt:(e,t)=>({onChange:(e,l)=>t.onChange(l)})},starRating:{component:p,getDefault:e=>e.defaultValue??0,adapt:(e,t)=>({onChange:(e,l)=>t.onChange(l)})},differential:{component:r,getDefault:e=>e.defaultValue??""},likert:{component:o,getDefault:e=>e.defaultValue??""},radioGroup:{component:i,getDefault:e=>e.defaultValue??""},ranking:{component:f,getDefault:e=>e.defaultValue?e.defaultValue.map(t=>e.options.find(e=>e.id===t)):e.options},richTextfield:{component:d,getDefault:e=>e.defaultValue??""},customfield:{component:u,getDefault:e=>e.defaultValue??""}},x=["fieldType","name","ref","label","labelProps","helperText","helpTextProps","content","styleOverrides","strengthIndicator","defaultValue","hidden"],D=e=>{if(e.noneOfThese)return!0;return(e.name||e.value||"").replace(/-/g,"_").includes("none_of_these")};exports.FIELD_REGISTRY=h,exports.extractNoneOfThese=e=>{if(!e.other?.enabled||!Array.isArray(e.options))return e;const t=e.options,l=t.findIndex(D);return-1===l?e:{...e,options:t.filter((e,t)=>t!==l),noneOfTheseOption:t[l]}},exports.getDefaultValues=e=>e.reduce((e,t)=>("html"!==t.fieldType&&(e[t.name]=h[t.fieldType].getDefault(t)),e),{}),exports.getFieldDefault=e=>"html"===e.fieldType?void 0:h[e.fieldType].getDefault(e),exports.getFieldDefinition=e=>h[e],exports.splitFieldProps=e=>{const t={};for(const l of Object.keys(e))x.includes(l)||(t[l]=e[l]);return t};
1
+ "use strict";var e=require("../AutocompleteField/AutocompleteField.js"),t=require("../Checkbox/Checkbox.js");require("../Checkbox/StyledCheckbox.js");var a=require("../CheckboxGroup/CheckboxGroup.js"),l=require("../CreatableAutocomplete/CreatableAutocomplete.js"),r=require("../CustomField/CustomField.js"),u=require("../Differential/Differential.js"),o=require("../Likert/Likert.js"),n=require("../NumberField/NumberField.js"),i=require("../RadioGroup/RadioGroup.js"),d=require("../Rank/Rank.js"),f=require("../RichTextField/RichTextField.js");require("../SelectItem/SelectItem.js");var s=require("../Select/Select.js"),c=require("../Slider/Slider.js"),p=require("../StarRating/StarRating.js"),m=require("../Switch/Switch.js"),g=require("../Textarea/Textarea.js");const h={textfield:{component:require("../TextField/TextField.js"),getDefault:e=>e.defaultValue??""},numberfield:{component:n.default,getDefault:e=>e.defaultValue??0},textarea:{component:g,getDefault:e=>e.defaultValue??""},creatableautocomplete:{component:l,getDefault:e=>e.defaultValue??""},select:{component:s,getDefault:e=>e.defaultValue??""},autocomplete:{component:e,getDefault:e=>e.defaultValue,adapt:(e,t)=>({onChange:(e,a)=>t.onChange(a)})},checkbox:{component:t,getDefault:e=>e.defaultValue??!1},checkboxGroup:{component:a,getDefault:e=>e.defaultValue??[]},switch:{component:m,getDefault:e=>e.defaultValue??!1,adapt:e=>({label:e.label})},slider:{component:c,getDefault:e=>Array.isArray(e.defaultValue)?e.defaultValue:e.defaultValue??e.min??0,adapt:(e,t)=>({onChange:(e,a)=>t.onChange(a)})},starRating:{component:p,getDefault:e=>e.defaultValue??0,adapt:(e,t)=>({onChange:(e,a)=>t.onChange(a)})},differential:{component:u,getDefault:e=>e.defaultValue??""},likert:{component:o,getDefault:e=>e.defaultValue??""},radioGroup:{component:i,getDefault:e=>e.defaultValue??""},ranking:{component:d,getDefault:e=>e.defaultValue?e.defaultValue.map(t=>e.options.find(e=>e.id===t)):e.options},richTextfield:{component:f,getDefault:e=>e.defaultValue??""},customfield:{component:r,getDefault:e=>e.defaultValue??""}},x=e=>{if("html"!==e.fieldType)return"array"===e.fieldType?e.defaultValue??[]:h[e.fieldType].getDefault(e)},D=["fieldType","name","ref","label","labelProps","helperText","helpTextProps","content","styleOverrides","strengthIndicator","defaultValue","hidden","visibleWhen","hideError","focusOnReveal","itemField","minItems","maxItems","addLabel","defaultItem","removeAction","actions","deriveProps"],V=e=>{if(e.noneOfThese)return!0;return(e.name||e.value||"").replace(/-/g,"_").includes("none_of_these")};exports.FIELD_REGISTRY=h,exports.extractNoneOfThese=e=>{if(!e.other?.enabled||!Array.isArray(e.options))return e;const t=e.options,a=t.findIndex(V);return-1===a?e:{...e,options:t.filter((e,t)=>t!==a),noneOfTheseOption:t[a]}},exports.getDefaultValues=e=>e.reduce((e,t)=>("html"!==t.fieldType&&(e[t.name]=x(t)),e),{}),exports.getFieldDefault=x,exports.getFieldDefinition=e=>h[e],exports.splitFieldProps=e=>{const t={};for(const a of Object.keys(e))D.includes(a)||(t[a]=e[a]);return t};
@@ -1,30 +1,10 @@
1
1
  import { SxProps, Theme } from '@mui/material';
2
- import { Ref, ReactElement, ReactNode } from 'react';
3
- import { FieldValues, FieldPath, Resolver, SubmitHandler, FieldErrors, UseFormSetValue, UseFormGetFieldState, UseFormTrigger, UseFormWatch } from 'react-hook-form';
4
- import '../../../index.js';
5
- import '../Text/types.js';
2
+ import { ReactElement } from 'react';
3
+ import { FieldValues, Resolver, SubmitHandler, FieldErrors, FieldPath, UseFormSetValue, UseFormGetFieldState, UseFormTrigger, UseFormWatch } from 'react-hook-form';
6
4
  import { ZodType } from 'zod';
7
5
  import { FieldTypes } from './fieldRegistry.js';
8
- export { DynamicFieldType, FieldType, HtmlField } from './fieldRegistry.js';
9
- import { InputLabelProps } from '../InputLabel/InputLabel.js';
10
- import { InputLabelHelpProps } from '../InputLabelHelp/InputLabelHelp.js';
6
+ export { ArrayActionsApi, ArrayField, ArrayItemField, ArrayRowApi, BaseField, DynamicFieldType, FieldType, HtmlField } from './fieldRegistry.js';
11
7
 
12
- interface BaseField<TValues extends FieldValues = FieldValues> {
13
- name: FieldPath<TValues>;
14
- id?: string;
15
- ref?: Ref<HTMLElement>;
16
- label?: string | ReactElement;
17
- labelProps?: InputLabelProps;
18
- helperText?: string | ReactNode;
19
- helpTextProps?: InputLabelHelpProps;
20
- hidden?: boolean;
21
- disabled?: boolean;
22
- styleOverrides?: {
23
- sxInputWrapper?: SxProps<Theme>;
24
- sxInputBase?: SxProps<Theme>;
25
- sxInputStack?: SxProps<Theme>;
26
- };
27
- }
28
8
  interface FormBuilderConfig<TValues extends FieldValues = FieldValues> {
29
9
  fields: FieldTypes<TValues>[];
30
10
  schema?: ZodType<TValues>;
@@ -67,4 +47,4 @@ interface FormBuilderProps<TValues extends FieldValues = FieldValues> {
67
47
  }
68
48
 
69
49
  export { FieldTypes };
70
- export type { BaseField, FormBuilderConfig, FormBuilderHandle, FormBuilderProps };
50
+ export type { FormBuilderConfig, FormBuilderHandle, FormBuilderProps };
@@ -19,9 +19,9 @@ import { SwitchProps } from '../Switch/Switch.js';
19
19
  import { TextareaProps } from '../Textarea/Textarea.js';
20
20
  import { NumberFieldProps } from '../NumberField/types.js';
21
21
  import { TextFieldProps } from '../TextField/TextField.js';
22
- import { HtmlProps } from '../Html/Html.js';
23
22
  import { InputLabelProps } from '../InputLabel/InputLabel.js';
24
23
  import { InputLabelHelpProps } from '../InputLabelHelp/InputLabelHelp.js';
24
+ import { HtmlProps } from '../Html/Html.js';
25
25
 
26
26
  /**
27
27
  * Form Generator Core Types
@@ -16,6 +16,8 @@ type RichTextFieldProps = Omit<InputFieldBaseProps, 'value' | 'onChange'> & {
16
16
  maxHeight?: number;
17
17
  value: string;
18
18
  options?: RichTextFieldOptions;
19
+ /** Focus the editor on mount, with the caret at the end of the content. */
20
+ autoFocus?: boolean;
19
21
  };
20
22
  declare const RichTextField: FunctionComponent<RichTextFieldProps>;
21
23
 
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("@mui/material"),r=require("@tiptap/extension-placeholder"),i=require("@tiptap/starter-kit"),n=require("mui-tiptap"),o=require("react"),l=require("./StyledRichTextEditor.js");module.exports=({onChange:u,value:s,internalChange:a,minWidth:d=100,minHeight:c=100,maxHeight:h,placeholder:x,options:m={}})=>{const p=o.useRef(null);t.useTheme();const{bold:g=!0,italic:j=!0,underline:q=!0,bulletList:B=!1,orderedList:L=!1}=m;return e.jsx(l,{sx:{"& .ProseMirror":{overflowY:"auto",minHeight:c,minWidth:d,maxHeight:h}},ref:p,onUpdate:({editor:e})=>{u&&u(e.getHTML()),a&&a()},enableInputRules:!1,extensions:[i.StarterKit.configure({strike:!1,code:!1,heading:!1,blockquote:!1,horizontalRule:!1,codeBlock:!1,bold:!!g&&{},italic:!!j&&{},listItem:!(!B&&!L)&&{},bulletList:!!B&&{},orderedList:!!L&&{}}),r.Placeholder.configure({placeholder:x})],content:s,renderControls:()=>e.jsxs(t.Stack,{direction:"row",children:[g&&e.jsx(n.MenuButtonBold,{}),j&&e.jsx(n.MenuButtonItalic,{}),q&&e.jsx(n.MenuButtonUnderline,{}),B&&e.jsx(n.MenuButtonBulletedList,{}),L&&e.jsx(n.MenuButtonOrderedList,{})]})})};
1
+ "use strict";var e=require("react/jsx-runtime"),t=require("@mui/material"),r=require("@tiptap/extension-placeholder"),i=require("@tiptap/starter-kit"),o=require("mui-tiptap"),n=require("react"),u=require("./StyledRichTextEditor.js");module.exports=({onChange:l,value:s,internalChange:a,minWidth:d=100,minHeight:c=100,maxHeight:h,placeholder:x,options:m={},autoFocus:p=!1})=>{const g=n.useRef(null);t.useTheme();const{bold:j=!0,italic:q=!0,underline:B=!0,bulletList:L=!1,orderedList:M=!1}=m;return e.jsx(u,{sx:{"& .ProseMirror":{overflowY:"auto",minHeight:c,minWidth:d,maxHeight:h}},ref:g,autofocus:!!p&&"end",onUpdate:({editor:e})=>{l&&l(e.getHTML()),a&&a()},enableInputRules:!1,extensions:[i.StarterKit.configure({strike:!1,code:!1,heading:!1,blockquote:!1,horizontalRule:!1,codeBlock:!1,bold:!!j&&{},italic:!!q&&{},listItem:!(!L&&!M)&&{},bulletList:!!L&&{},orderedList:!!M&&{}}),r.Placeholder.configure({placeholder:x})],content:s,renderControls:()=>e.jsxs(t.Stack,{direction:"row",children:[j&&e.jsx(o.MenuButtonBold,{}),q&&e.jsx(o.MenuButtonItalic,{}),B&&e.jsx(o.MenuButtonUnderline,{}),L&&e.jsx(o.MenuButtonBulletedList,{}),M&&e.jsx(o.MenuButtonOrderedList,{})]})})};
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),n=require("@mui/material"),t=require("../../BrandCore/primitiveVariables.js"),r=require("../InputFieldBase/InputFieldBase.js");module.exports=({startAdornment:i,endAdornment:s,placeholder:a,onChange:l,internalChange:d,inputRef:o,...p})=>e.jsx(r,{placeholder:a,sx:{height:t.space[500],"& .MuiOutlinedInput-input":{pl:i?1:2,pr:i?1:2}},inputRef:o,slotProps:{input:{startAdornment:i?e.jsx(n.InputAdornment,{position:"start",disablePointerEvents:p.disabled,sx:{pl:1},children:i}):null,endAdornment:s?e.jsx(n.InputAdornment,{position:"start",disablePointerEvents:p.disabled,sx:{pr:1},children:s}):null}},...p,onChange:e=>{l&&l(e),d&&d()}});
1
+ "use strict";var e=require("react/jsx-runtime"),n=require("@mui/material"),t=require("../../BrandCore/primitiveVariables.js"),r=require("../InputFieldBase/InputFieldBase.js");module.exports=({startAdornment:i,endAdornment:s,placeholder:l,onChange:a,internalChange:d,inputRef:o,slotProps:p,...u})=>e.jsx(r,{placeholder:l,sx:{height:t.space[500],"& .MuiOutlinedInput-input":{pl:i?1:2,pr:i?1:2}},inputRef:o,slotProps:{...p,input:{startAdornment:i?e.jsx(n.InputAdornment,{position:"start",disablePointerEvents:u.disabled,sx:{pl:1},children:i}):null,endAdornment:s?e.jsx(n.InputAdornment,{position:"start",disablePointerEvents:u.disabled,sx:{pr:1},children:s}):null,...p?.input??{}}},...u,onChange:e=>{a&&a(e),d&&d()}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useloops/design-system",
3
- "version": "1.4.723",
3
+ "version": "1.4.725",
4
4
  "description": "The official React based Loops design system",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -245,7 +245,7 @@
245
245
  "merge-sx": "^3.5.0",
246
246
  "motion": "^12.40.0",
247
247
  "mui-tiptap": "^1.31.0",
248
- "react-hook-form": "^7.78.0",
248
+ "react-hook-form": "^7.81.0",
249
249
  "react-intersection-observer": "^9.16.0",
250
250
  "react-number-format": "^5.4.5",
251
251
  "react-phone-number-input": "^3.4.17",