@k8slens/lds-form 0.53.2 → 0.53.4

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.
Files changed (32) hide show
  1. package/lib/cjs/FormErrorMessage/FormErrorMessage.d.ts +6 -2
  2. package/lib/cjs/FormErrorMessage/FormErrorMessage.js +1 -1
  3. package/lib/cjs/FormField/FormField.d.ts +13 -8
  4. package/lib/cjs/FormInput/FormInput.js +1 -1
  5. package/lib/cjs/FormLabel/FormLabel.d.ts +11 -3
  6. package/lib/cjs/FormSwitchGroup/FormSwitchGroup.d.ts +12 -0
  7. package/lib/cjs/FormSwitchGroup/FormSwitchGroup.js +1 -1
  8. package/lib/cjs/_virtual/_tslib.js +1 -1
  9. package/lib/cjs/common/useFieldIds.js +1 -1
  10. package/lib/cjs/common/useFormComponentData.js +1 -1
  11. package/lib/cjs/common/useInputErrorProps.js +1 -1
  12. package/lib/cjs/common/usePrevious.js +1 -1
  13. package/lib/cjs/node_modules/@k8slens/lds/lib/es/Input/Input.js +1 -1
  14. package/lib/cjs/node_modules/@k8slens/lds/lib/es/Textarea/Textarea.js +1 -1
  15. package/lib/cjs/node_modules/@k8slens/lds/lib/es/_virtual/_tslib.js +1 -1
  16. package/lib/es/FormErrorMessage/FormErrorMessage.d.ts +6 -2
  17. package/lib/es/FormErrorMessage/FormErrorMessage.js +1 -1
  18. package/lib/es/FormField/FormField.d.ts +13 -8
  19. package/lib/es/FormInput/FormInput.js +1 -1
  20. package/lib/es/FormLabel/FormLabel.d.ts +11 -3
  21. package/lib/es/FormSwitchGroup/FormSwitchGroup.d.ts +12 -0
  22. package/lib/es/FormSwitchGroup/FormSwitchGroup.js +1 -1
  23. package/lib/es/_virtual/_tslib.js +1 -1
  24. package/lib/es/common/useFieldIds.js +1 -1
  25. package/lib/es/common/useFormComponentData.js +1 -1
  26. package/lib/es/common/useInputErrorProps.js +1 -1
  27. package/lib/es/common/usePrevious.js +1 -1
  28. package/lib/es/node_modules/@k8slens/lds/lib/es/Input/Input.js +1 -1
  29. package/lib/es/node_modules/@k8slens/lds/lib/es/Textarea/Textarea.js +1 -1
  30. package/lib/es/node_modules/@k8slens/lds/lib/es/_virtual/_tslib.js +1 -1
  31. package/llms.txt +79 -28
  32. package/package.json +5 -5
@@ -1,13 +1,17 @@
1
1
  import React from "react";
2
+ /** Props for the FormErrorMessage component. */
2
3
  export interface FormErrorMessageProps extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "id" | "htmlFor"> {
4
+ /** HTML `id` for the error message element. */
3
5
  id: string;
6
+ /** `id` of the form control this error message describes. */
4
7
  forId: string;
8
+ /** List of error strings to display. */
5
9
  errors: Array<string>;
6
10
  }
7
11
  /**
8
- * Form error message component used by `FormField`
12
+ * Displays validation errors as a list associated with a form control.
9
13
  *
10
- * `import { FormErrorMessage } from @k8slens/lds-form`
14
+ * Usage: `import { FormErrorMessage } from "@k8slens/lds-form"`
11
15
  */
12
16
  declare const FormErrorMessage: ({ id, forId, errors, ...props }: FormErrorMessageProps) => React.JSX.Element;
13
17
  export default FormErrorMessage;
@@ -1 +1 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),t=require("clsx"),a=require("./FormErrorMessage.module.css.js");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=l(r),u=l(t);module.exports=function(r){var t=r.id,l=r.forId,o=r.errors,i=e.__rest(r,["id","forId","errors"]);return s.default.createElement("label",e.__assign({},i,{className:u.default(a.formErrorMessage,i.className),id:t,htmlFor:l}),s.default.createElement("ul",null,o.map((function(e){return s.default.createElement("li",{key:e},e)}))))};
1
+ "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),t=require("clsx"),a=require("./FormErrorMessage.module.css.js");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=l(r),u=l(t);module.exports=function(r){var t=r.id,l=r.forId,o=r.errors,i=e.__rest(r,["id","forId","errors"]);return s.default.createElement("label",e.__assign({},i,{className:u.default(a.formErrorMessage,i.className),id:t,htmlFor:l}),s.default.createElement("ul",null,o.map(function(e){return s.default.createElement("li",{key:e},e)})))};
@@ -3,20 +3,26 @@ import { FormLabelProps } from "../FormLabel/FormLabel";
3
3
  import { FormErrorMessageProps } from "../FormErrorMessage/FormErrorMessage";
4
4
  import { ErrorParser } from "../common/useFormComponentData";
5
5
  import { Validator } from "../common/validation";
6
+ /** Props for the FormField component. */
6
7
  export interface FormFieldProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "id"> {
7
- /** the `id` of the child form component (e.g. `input`) */
8
+ /** The `id` of the child form control (e.g. `<input>`). Optional because HeadlessUI Combobox omits it on first render. */
8
9
  id: string | undefined;
9
- /** the label text to be rendered in `<label>{label}</label>` */
10
+ /** Label text rendered inside a `<label>` element. */
10
11
  label: string;
11
- /** the identifier of the `<ErrorMessage id={labelId} />` of the child form component, should not be the same as `props.id` */
12
+ /** Unique `id` for the error message element. Must differ from `id`. */
12
13
  errorId: string;
13
- /** the identifier of the `<label id={labelId} />` of the child form component, should not be the same as `props.id` */
14
+ /** Unique `id` for the label element. Must differ from `id`. */
14
15
  labelId: string;
16
+ /** Whether the field is required. */
15
17
  required?: boolean;
18
+ /** Validation error strings to display. */
16
19
  errors?: Array<string>;
20
+ /** Props forwarded to the `FormLabel` component. */
17
21
  labelProps?: Partial<FormLabelProps>;
22
+ /** Props forwarded to the `FormErrorMessage` component. */
18
23
  errorProps?: Partial<Omit<FormErrorMessageProps, "forId" | "id">>;
19
24
  }
25
+ /** Shared props for form components that combine a field with validation and error display. */
20
26
  export interface FormFieldComponentProps<T,
21
27
  /** Custom error string(s) to be used in validation & error parser */
22
28
  CustomError extends string> extends Pick<FormFieldProps, "label" | "labelProps" | "errorProps"> {
@@ -24,13 +30,12 @@ CustomError extends string> extends Pick<FormFieldProps, "label" | "labelProps"
24
30
  validate?: Validator<T, CustomError>;
25
31
  /** Return error message for given error key. */
26
32
  errorParser?: ErrorParser<T, CustomError>;
33
+ /** Called when the value changes with the new value and its validity. */
27
34
  onChange?: (value: T, isValid: boolean) => void;
28
35
  }
29
36
  /**
30
- * Generic form field component with label and error message.
37
+ * Generic form field wrapper that renders a label, child control, and error messages.
31
38
  *
32
- * `import { FormField } from @k8slens/lds-form`
33
- *
34
- * See `FormComponent`for individual form components.
39
+ * Usage: `import { FormField } from "@k8slens/lds-form"`
35
40
  */
36
41
  export default function FormField({ id, label, labelId, errorId, required, errors, children, labelProps, errorProps, ...props }: PropsWithChildren<FormFieldProps>): React.JSX.Element;
@@ -1 +1 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),l=require("../common/usePrevious.js"),a=require("../common/useFieldIds.js"),u=require("../common/useInputErrorProps.js"),i=require("../common/useFormComponentData.js"),o=require("../FormField/FormField.js"),n=require("../common/helpers.js"),t=require("../node_modules/@k8slens/lds/lib/es/Input/Input.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=s(r);var v=function(e,r,l,a,u){void 0===u&&(u={valid:!0});var i=u;if(a&&null!==a&&(i=n.getInputValidity(a)),l){var o=l(e,i,r.name,r);"string"==typeof o?(i[o]=!0,i.valid=!1):o&&(o.forEach((function(e){i[e]=!0})),i.valid=!1)}return i};module.exports=function(s){var p=s.id,c=s.label,f=s.wrapperProps,m=s.labelProps,P=s.validate,_=s.errorParser,b=void 0===_?i.defaultErrorParser:_,y=s.errorProps,g=s.value,I=s.onChange,q=s.type,j=e.__rest(s,["id","label","wrapperProps","labelProps","validate","errorParser","errorProps","value","onChange","type"]),F=l.usePrevious(g),E=r.useRef(null),C=a.useFieldIds(p),V=C.id,h=C.labelId,k=C.errorId,w=i.useFormComponentData({value:g,errorParser:b,constraints:j,label:c}),D=w.currentValue,x=w.setCurrentValue,N=w.errors,R=u.useInputErrorProps({id:k,errors:N}),z=r.useCallback((function(r){var l=r.target,a=function(e,r){return"number"===r?parseFloat(e):e}(l.value,q),u=v(a,j,P,l,e.__assign({},l.validity));x({value:a,validity:e.__assign({},u)}),null==I||I(a,null==u?void 0:u.valid)}),[q,P,I,x,j]);return r.useEffect((function(){var r,l;if(F!==g&&g!==D.value){var a=g;E.current&&n.setNativeValue(E.current,a);var i=v(a,u.useInputErrorProps,P,E.current),o=null===(r=D.validity)||void 0===r?void 0:r.valid,t=null==i?void 0:i.valid;x({value:a,validity:i}),o!==t&&I(a,t)}else if(D.validity){var s=v(D.value,j,P,E.current);(o=null===(l=D.validity)||void 0===l?void 0:l.valid)!==(t=null==s?void 0:s.valid)&&(x((function(r){return e.__assign(e.__assign({},r),{validity:s})})),I(D.value,t))}}),[P,g,F,D,x,I,j]),d.default.createElement(o,e.__assign({id:V,label:c,labelId:h,errorId:k,errors:N,required:j.required,labelProps:m,errorProps:y},f),d.default.createElement(t,e.__assign({ref:E,id:V,"aria-labelledby":h},R,j,{type:q,defaultValue:null==j?void 0:j.defaultValue,value:null==D?void 0:D.value,onChange:z})))};
1
+ "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),l=require("../common/usePrevious.js"),a=require("../common/useFieldIds.js"),u=require("../common/useInputErrorProps.js"),i=require("../common/useFormComponentData.js"),o=require("../FormField/FormField.js"),n=require("../common/helpers.js"),t=require("../node_modules/@k8slens/lds/lib/es/Input/Input.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=s(r);var v=function(e,r,l,a,u){void 0===u&&(u={valid:!0});var i=u;if(a&&null!==a&&(i=n.getInputValidity(a)),l){var o=l(e,i,r.name,r);"string"==typeof o?(i[o]=!0,i.valid=!1):o&&(o.forEach(function(e){i[e]=!0}),i.valid=!1)}return i};module.exports=function(s){var p=s.id,c=s.label,f=s.wrapperProps,m=s.labelProps,P=s.validate,_=s.errorParser,b=void 0===_?i.defaultErrorParser:_,y=s.errorProps,g=s.value,I=s.onChange,q=s.type,j=e.__rest(s,["id","label","wrapperProps","labelProps","validate","errorParser","errorProps","value","onChange","type"]),F=l.usePrevious(g),E=r.useRef(null),C=a.useFieldIds(p),V=C.id,h=C.labelId,k=C.errorId,w=i.useFormComponentData({value:g,errorParser:b,constraints:j,label:c}),D=w.currentValue,x=w.setCurrentValue,N=w.errors,R=u.useInputErrorProps({id:k,errors:N}),z=r.useCallback(function(r){var l=r.target,a=function(e,r){return"number"===r?parseFloat(e):e}(l.value,q),u=v(a,j,P,l,e.__assign({},l.validity));x({value:a,validity:e.__assign({},u)}),null==I||I(a,null==u?void 0:u.valid)},[q,P,I,x,j]);return r.useEffect(function(){var r,l;if(F!==g&&g!==D.value){var a=g;E.current&&n.setNativeValue(E.current,a);var i=v(a,u.useInputErrorProps,P,E.current),o=null===(r=D.validity)||void 0===r?void 0:r.valid,t=null==i?void 0:i.valid;x({value:a,validity:i}),o!==t&&I(a,t)}else if(D.validity){var s=v(D.value,j,P,E.current);(o=null===(l=D.validity)||void 0===l?void 0:l.valid)!==(t=null==s?void 0:s.valid)&&(x(function(r){return e.__assign(e.__assign({},r),{validity:s})}),I(D.value,t))}},[P,g,F,D,x,I,j]),d.default.createElement(o,e.__assign({id:V,label:c,labelId:h,errorId:k,errors:N,required:j.required,labelProps:m,errorProps:y},f),d.default.createElement(t,e.__assign({ref:E,id:V,"aria-labelledby":h},R,j,{type:q,defaultValue:null==j?void 0:j.defaultValue,value:null==D?void 0:D.value,onChange:z})))};
@@ -1,16 +1,24 @@
1
1
  import React, { type ReactElement } from "react";
2
+ /** Props for the FormLabel component. */
2
3
  export interface FormLabelProps extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "id" | "htmlFor"> {
4
+ /** HTML `id` for the label element. */
3
5
  id: string;
6
+ /** `id` of the form control this label is for. */
4
7
  forId: string;
8
+ /** Label content — a string or React element. */
5
9
  label: ReactElement | string;
10
+ /** Whether the associated field is required (used together with `showRequired`). */
6
11
  required?: boolean;
7
- /** Show required asterisk and visually hidden "required" text. Default: false */
12
+ /**
13
+ * Show required asterisk and visually hidden "required" text.
14
+ * @default false
15
+ */
8
16
  showRequired?: boolean;
9
17
  }
10
18
  /**
11
- * Form label component used by `FormField`
19
+ * A `<label>` element with optional required indicator. Used internally by `FormField`.
12
20
  *
13
- * `import { FormLabel } from @k8slens/lds-form`
21
+ * Usage: `import { FormLabel } from "@k8slens/lds-form"`
14
22
  */
15
23
  declare const FormLabel: ({ id, forId, label, showRequired, required, ...props }: FormLabelProps) => React.JSX.Element;
16
24
  export default FormLabel;
@@ -1,18 +1,30 @@
1
1
  import React, { PropsWithChildren, ReactNode } from "react";
2
2
  import { type SwitchProps } from "@k8slens/lds/lib/es/Switch/Switch.d";
3
3
  import { FormFieldComponentProps } from "../FormField/FormField";
4
+ /** Describes a single switch within a `FormSwitchGroup`. */
4
5
  export declare type SwitchValue = {
6
+ /** Unique identifier for this switch. */
5
7
  id: string;
8
+ /** Label displayed next to the switch. */
6
9
  label: string;
10
+ /** Whether the switch is on. */
7
11
  checked: boolean | undefined;
12
+ /** Whether this individual switch is disabled. */
8
13
  disabled?: boolean;
14
+ /** Optional description rendered below the label. */
9
15
  description?: string | ReactNode;
10
16
  };
17
+ /** Props for the FormSwitchGroup component. */
11
18
  export interface FormSwitchGroupProps<CustomError extends string> extends Omit<FormFieldComponentProps<number, CustomError>, "onChange" | "value">, Omit<SwitchProps, "value" | "onChange" | "label"> {
19
+ /** HTML `id` attribute for the field. */
12
20
  id?: string;
21
+ /** Props forwarded to the wrapper div. */
13
22
  wrapperProps?: React.HTMLAttributes<HTMLDivElement>;
23
+ /** Array of switch items to render. */
14
24
  values: Array<SwitchValue>;
25
+ /** Called when any switch changes with the full array and the IDs that changed. */
15
26
  onChange(values: Array<SwitchValue>, updatedKeys: Array<string>): void;
27
+ /** Validation error strings to display. */
16
28
  errors?: Array<string>;
17
29
  }
18
30
  /**
@@ -1 +1 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),a=require("clsx"),s=require("../FormField/FormField.js"),l=require("../common/useFieldIds.js"),t=require("../common/useInputErrorProps.js"),i=require("./FormSwitchGroup.module.css.js"),o=require("../node_modules/@k8slens/lds/lib/es/Switch/Switch.js");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=d(r),u=d(a);module.exports=function(a){var d=a.id,c=a.label,p=a.wrapperProps,m=a.labelProps;a.validate;var _=a.errorProps,b=a.values,f=a.onChange;a.type;var v=a.errors,g=a.disabled,h=e.__rest(a,["id","label","wrapperProps","labelProps","validate","errorProps","values","onChange","type","errors","disabled"]),N=l.useFieldIds(d),P=N.id,w=N.labelId,q=N.errorId,E=t.useInputErrorProps({id:q,errors:v}),F=r.useCallback((function(r,a){var s=b.map((function(s){return s.id===r?e.__assign(e.__assign({},s),{checked:a}):s}));f(s,[r])}),[b,f]);return n.default.createElement(s,e.__assign({id:P,className:i.formSwitchGroup,label:c,labelId:w,errorId:q,errors:v,labelProps:e.__assign(e.__assign({},m),{className:u.default(i.groupLabel,null==m?void 0:m.className)}),errorProps:e.__assign(e.__assign({},E),{className:u.default(i.error,null==_?void 0:_.className)})},p),b.map((function(a){var s=a.id,l=a.label,t=a.checked,d=a.description,c=a.disabled;return n.default.createElement(r.Fragment,{key:s},n.default.createElement(o.Switch,e.__assign({key:s,id:s,checked:t,onChange:function(e){return F(s,e)},disabled:g||c},h,{className:u.default(h.className,i.switch)}),n.default.createElement("span",{className:i.labelWrapper},n.default.createElement("span",{className:i.switchLabel},l),d&&n.default.createElement("p",{className:i.description},d))))})))};
1
+ "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),a=require("clsx"),s=require("../FormField/FormField.js"),l=require("../common/useFieldIds.js"),t=require("../common/useInputErrorProps.js"),i=require("./FormSwitchGroup.module.css.js"),o=require("../node_modules/@k8slens/lds/lib/es/Switch/Switch.js");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=d(r),u=d(a);module.exports=function(a){var d=a.id,c=a.label,p=a.wrapperProps,m=a.labelProps;a.validate;var _=a.errorProps,b=a.values,f=a.onChange;a.type;var v=a.errors,g=a.disabled,h=e.__rest(a,["id","label","wrapperProps","labelProps","validate","errorProps","values","onChange","type","errors","disabled"]),N=l.useFieldIds(d),P=N.id,w=N.labelId,q=N.errorId,E=t.useInputErrorProps({id:q,errors:v}),F=r.useCallback(function(r,a){var s=b.map(function(s){return s.id===r?e.__assign(e.__assign({},s),{checked:a}):s});f(s,[r])},[b,f]);return n.default.createElement(s,e.__assign({id:P,className:i.formSwitchGroup,label:c,labelId:w,errorId:q,errors:v,labelProps:e.__assign(e.__assign({},m),{className:u.default(i.groupLabel,null==m?void 0:m.className)}),errorProps:e.__assign(e.__assign({},E),{className:u.default(i.error,null==_?void 0:_.className)})},p),b.map(function(a){var s=a.id,l=a.label,t=a.checked,d=a.description,c=a.disabled;return n.default.createElement(r.Fragment,{key:s},n.default.createElement(o.Switch,e.__assign({key:s,id:s,checked:t,onChange:function(e){return F(s,e)},disabled:g||c},h,{className:u.default(h.className,i.switch)}),n.default.createElement("span",{className:i.labelWrapper},n.default.createElement("span",{className:i.switchLabel},l),d&&n.default.createElement("p",{className:i.description},d))))}))};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__assign=function(){return exports.__assign=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},exports.__assign.apply(this,arguments)},exports.__rest=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]])}return r};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__assign=function(){return exports.__assign=Object.assign||function(r){for(var e,t=1,o=arguments.length;t<o;t++)for(var n in e=arguments[t])Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r},exports.__assign.apply(this,arguments)},"function"==typeof SuppressedError&&SuppressedError,exports.__rest=function(r,e){var t={};for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&e.indexOf(o)<0&&(t[o]=r[o]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(r);n<o.length;n++)e.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(r,o[n])&&(t[o[n]]=r[o[n]])}return t};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("lodash");exports.useFieldIds=function(o){var t=e.useMemo((function(){return o||r.uniqueId("form-field-")}),[o]);return{id:t,labelId:"".concat(t,"-label"),errorId:"".concat(t,"-error")}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("lodash");exports.useFieldIds=function(o){var t=e.useMemo(function(){return o||r.uniqueId("form-field-")},[o]);return{id:t,labelId:"".concat(t,"-label"),errorId:"".concat(t,"-error")}};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("lodash");exports.defaultErrorParser=function(e,t,r){var n=r.min,a=r.max,o=r.minLength,u=r.maxLength,l={valueMissing:"Required",tooShort:"Min. length is ".concat(o," chars"),tooLong:"Max. length is ".concat(u," chars"),rangeUnderflow:"Value should be at least ".concat(n),rangeOverflow:"Value should be no more than ".concat(a),default:"Value is invalid"};return l[t]||l.default},exports.useFormComponentData=function(r){var n=r.value,a=r.errorParser,o=r.constraints,u=void 0===o?{}:o,l=r.label,i=e.useState({value:n}),s=i[0],c=i[1],h=e.useMemo((function(){for(var e=s.value,r=s.validity,n=[],o=Object.keys(r||{}).filter((function(e){return"valid"!==e})),i=0,c=o;i<c.length;i++){var h=c[i],g=void 0;switch(h){case"tooShort":r&&(r[h]||"string"==typeof e&&u.minLength&&e.length<u.minLength)&&(g=a(e,h,u,l));break;case"tooLong":r&&(r[h]||"string"==typeof e&&u.maxLength&&e.length>u.maxLength)&&(g=a(e,h,u,l));break;default:r&&r[h]&&(g=a(e,h,u,l))}g&&n.push(g)}!1!==(null==r?void 0:r.valid)||n.length||(g=a(e,"unknown",u,l))&&n.push(g);return t.uniq(n)}),[s,u,a,l]);return{currentValue:s,setCurrentValue:c,errors:h}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("lodash");exports.defaultErrorParser=function(e,t,r){var n=r.min,a=r.max,o=r.minLength,u=r.maxLength,l={valueMissing:"Required",tooShort:"Min. length is ".concat(o," chars"),tooLong:"Max. length is ".concat(u," chars"),rangeUnderflow:"Value should be at least ".concat(n),rangeOverflow:"Value should be no more than ".concat(a),default:"Value is invalid"};return l[t]||l.default},exports.useFormComponentData=function(r){var n=r.value,a=r.errorParser,o=r.constraints,u=void 0===o?{}:o,l=r.label,i=e.useState({value:n}),s=i[0],c=i[1],h=e.useMemo(function(){for(var e=s.value,r=s.validity,n=[],o=Object.keys(r||{}).filter(function(e){return"valid"!==e}),i=0,c=o;i<c.length;i++){var h=c[i],g=void 0;switch(h){case"tooShort":r&&(r[h]||"string"==typeof e&&u.minLength&&e.length<u.minLength)&&(g=a(e,h,u,l));break;case"tooLong":r&&(r[h]||"string"==typeof e&&u.maxLength&&e.length>u.maxLength)&&(g=a(e,h,u,l));break;default:r&&r[h]&&(g=a(e,h,u,l))}g&&n.push(g)}!1!==(null==r?void 0:r.valid)||n.length||(g=a(e,"unknown",u,l))&&n.push(g);return t.uniq(n)},[s,u,a,l]);return{currentValue:s,setCurrentValue:c,errors:h}};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r=require("react");exports.useInputErrorProps=function(e){var i=e.id,t=e.errors;return r.useMemo((function(){return(null==t?void 0:t.length)?{"aria-invalid":!0,"aria-errormessage":i,"aria-describedby":i}:{}}),[t,i])};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r=require("react");exports.useInputErrorProps=function(e){var i=e.id,t=e.errors;return r.useMemo(function(){return(null==t?void 0:t.length)?{"aria-invalid":!0,"aria-errormessage":i,"aria-describedby":i}:{}},[t,i])};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.usePrevious=function(r){var t=e.useRef();return e.useEffect((function(){t.current=r}),[r]),t.current};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.usePrevious=function(r){var t=e.useRef();return e.useEffect(function(){t.current=r},[r]),t.current};
@@ -1 +1 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),a=require("clsx"),t=require("./Input.module.css.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var l=s(r),u=s(a),i=r.forwardRef((function(r,a){var s,i=r.icon,n=r.wrapperProps,c=e.__rest(r,["icon","wrapperProps"]);return l.default.createElement("div",e.__assign({},n,{className:u.default(t.wrapper,null==n?void 0:n.className,(s={},s[t.withIcon]=i,s))}),l.default.createElement("input",e.__assign({ref:a},c,{className:u.default(t.input,(null==c?void 0:c.className)||"")})),i&&l.default.createElement(i,{className:t.icon}))}));module.exports=i;
1
+ "use strict";var e=require("../_virtual/_tslib.js"),r=require("react"),a=require("clsx"),t=require("./Input.module.css.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var l=s(r),u=s(a),i=r.forwardRef(function(r,a){var s,i=r.icon,n=r.wrapperProps,c=e.__rest(r,["icon","wrapperProps"]);return l.default.createElement("div",e.__assign({},n,{className:u.default(t.wrapper,null==n?void 0:n.className,(s={},s[t.withIcon]=i,s))}),l.default.createElement("input",e.__assign({ref:a},c,{className:u.default(t.input,(null==c?void 0:c.className)||"")})),i&&l.default.createElement(i,{className:t.icon}))});module.exports=i;
@@ -1 +1 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),t=require("react"),a=require("clsx"),l=require("./Textarea.module.css.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(t),r=n(a),s=t.forwardRef((function(a,n){var s,c,i=a.icon,o=a.autoResize,f=void 0!==o&&o,g=a.wrapperProps,d=a.maxLength,p=a.className,h=a.onChange,m=a.value,v=a.defaultValue,x=e.__rest(a,["icon","autoResize","wrapperProps","maxLength","className","onChange","value","defaultValue"]),_=t.useRef(null),y=t.useState((function(){return"string"==typeof m?m.length:"string"==typeof v?v.length:0})),N=y[0],C=y[1],E=t.useCallback((function(e){_.current=e,"function"==typeof n?n(e):n&&(n.current=e)}),[n]),b=t.useCallback((function(){var e=_.current;e&&f&&(e.style.height="auto",e.style.height="".concat(e.scrollHeight,"px"))}),[f]);t.useEffect((function(){b()}),[m,b]),t.useEffect((function(){"string"==typeof m&&null!=d&&C(m.length)}),[m,d]);var w=t.useCallback((function(e){null!=d&&C(e.target.value.length),b(),null==h||h(e)}),[h,b,d]);return u.default.createElement("div",e.__assign({},g,{className:r.default(l.wrapper,null==g?void 0:g.className,(s={},s[l.withIcon]=i,s))}),u.default.createElement("textarea",e.__assign({ref:E},x,{value:m,defaultValue:v,maxLength:d,onChange:w,className:r.default(l.textarea,p,(c={},c[l.autoResize]=f,c))})),i&&u.default.createElement(i,{className:l.icon}),null!=d&&u.default.createElement("span",{className:l.counter,"aria-live":"polite"},N,"/",d))}));module.exports=s;
1
+ "use strict";var e=require("../_virtual/_tslib.js"),t=require("react"),a=require("clsx"),l=require("./Textarea.module.css.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(t),r=n(a),s=t.forwardRef(function(a,n){var s,c,i=a.icon,o=a.autoResize,f=void 0!==o&&o,g=a.wrapperProps,d=a.maxLength,p=a.className,h=a.onChange,m=a.value,v=a.defaultValue,x=e.__rest(a,["icon","autoResize","wrapperProps","maxLength","className","onChange","value","defaultValue"]),_=t.useRef(null),y=t.useState(function(){return"string"==typeof m?m.length:"string"==typeof v?v.length:0}),N=y[0],C=y[1],E=t.useCallback(function(e){_.current=e,"function"==typeof n?n(e):n&&(n.current=e)},[n]),b=t.useCallback(function(){var e=_.current;e&&f&&(e.style.height="auto",e.style.height="".concat(e.scrollHeight,"px"))},[f]);t.useEffect(function(){b()},[m,b]),t.useEffect(function(){"string"==typeof m&&null!=d&&C(m.length)},[m,d]);var w=t.useCallback(function(e){null!=d&&C(e.target.value.length),b(),null==h||h(e)},[h,b,d]);return u.default.createElement("div",e.__assign({},g,{className:r.default(l.wrapper,null==g?void 0:g.className,(s={},s[l.withIcon]=i,s))}),u.default.createElement("textarea",e.__assign({ref:E},x,{value:m,defaultValue:v,maxLength:d,onChange:w,className:r.default(l.textarea,p,(c={},c[l.autoResize]=f,c))})),i&&u.default.createElement(i,{className:l.icon}),null!=d&&u.default.createElement("span",{className:l.counter,"aria-live":"polite"},N,"/",d))});module.exports=s;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__assign=function(){return exports.__assign=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},exports.__assign.apply(this,arguments)},exports.__rest=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]])}return r};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__assign=function(){return exports.__assign=Object.assign||function(r){for(var e,t=1,o=arguments.length;t<o;t++)for(var n in e=arguments[t])Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r},exports.__assign.apply(this,arguments)},"function"==typeof SuppressedError&&SuppressedError,exports.__rest=function(r,e){var t={};for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&e.indexOf(o)<0&&(t[o]=r[o]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(r);n<o.length;n++)e.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(r,o[n])&&(t[o[n]]=r[o[n]])}return t};
@@ -1,13 +1,17 @@
1
1
  import React from "react";
2
+ /** Props for the FormErrorMessage component. */
2
3
  export interface FormErrorMessageProps extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "id" | "htmlFor"> {
4
+ /** HTML `id` for the error message element. */
3
5
  id: string;
6
+ /** `id` of the form control this error message describes. */
4
7
  forId: string;
8
+ /** List of error strings to display. */
5
9
  errors: Array<string>;
6
10
  }
7
11
  /**
8
- * Form error message component used by `FormField`
12
+ * Displays validation errors as a list associated with a form control.
9
13
  *
10
- * `import { FormErrorMessage } from @k8slens/lds-form`
14
+ * Usage: `import { FormErrorMessage } from "@k8slens/lds-form"`
11
15
  */
12
16
  declare const FormErrorMessage: ({ id, forId, errors, ...props }: FormErrorMessageProps) => React.JSX.Element;
13
17
  export default FormErrorMessage;
@@ -1 +1 @@
1
- import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import o from"react";import t from"clsx";import m from"./FormErrorMessage.module.css.js";var a=function(a){var l=a.id,s=a.forId,i=a.errors,c=r(a,["id","forId","errors"]);return o.createElement("label",e({},c,{className:t(m.formErrorMessage,c.className),id:l,htmlFor:s}),o.createElement("ul",null,i.map((function(r){return o.createElement("li",{key:r},r)}))))};export{a as default};
1
+ import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import o from"react";import t from"clsx";import m from"./FormErrorMessage.module.css.js";var a=function(a){var l=a.id,s=a.forId,i=a.errors,c=r(a,["id","forId","errors"]);return o.createElement("label",e({},c,{className:t(m.formErrorMessage,c.className),id:l,htmlFor:s}),o.createElement("ul",null,i.map(function(r){return o.createElement("li",{key:r},r)})))};export{a as default};
@@ -3,20 +3,26 @@ import { FormLabelProps } from "../FormLabel/FormLabel";
3
3
  import { FormErrorMessageProps } from "../FormErrorMessage/FormErrorMessage";
4
4
  import { ErrorParser } from "../common/useFormComponentData";
5
5
  import { Validator } from "../common/validation";
6
+ /** Props for the FormField component. */
6
7
  export interface FormFieldProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "id"> {
7
- /** the `id` of the child form component (e.g. `input`) */
8
+ /** The `id` of the child form control (e.g. `<input>`). Optional because HeadlessUI Combobox omits it on first render. */
8
9
  id: string | undefined;
9
- /** the label text to be rendered in `<label>{label}</label>` */
10
+ /** Label text rendered inside a `<label>` element. */
10
11
  label: string;
11
- /** the identifier of the `<ErrorMessage id={labelId} />` of the child form component, should not be the same as `props.id` */
12
+ /** Unique `id` for the error message element. Must differ from `id`. */
12
13
  errorId: string;
13
- /** the identifier of the `<label id={labelId} />` of the child form component, should not be the same as `props.id` */
14
+ /** Unique `id` for the label element. Must differ from `id`. */
14
15
  labelId: string;
16
+ /** Whether the field is required. */
15
17
  required?: boolean;
18
+ /** Validation error strings to display. */
16
19
  errors?: Array<string>;
20
+ /** Props forwarded to the `FormLabel` component. */
17
21
  labelProps?: Partial<FormLabelProps>;
22
+ /** Props forwarded to the `FormErrorMessage` component. */
18
23
  errorProps?: Partial<Omit<FormErrorMessageProps, "forId" | "id">>;
19
24
  }
25
+ /** Shared props for form components that combine a field with validation and error display. */
20
26
  export interface FormFieldComponentProps<T,
21
27
  /** Custom error string(s) to be used in validation & error parser */
22
28
  CustomError extends string> extends Pick<FormFieldProps, "label" | "labelProps" | "errorProps"> {
@@ -24,13 +30,12 @@ CustomError extends string> extends Pick<FormFieldProps, "label" | "labelProps"
24
30
  validate?: Validator<T, CustomError>;
25
31
  /** Return error message for given error key. */
26
32
  errorParser?: ErrorParser<T, CustomError>;
33
+ /** Called when the value changes with the new value and its validity. */
27
34
  onChange?: (value: T, isValid: boolean) => void;
28
35
  }
29
36
  /**
30
- * Generic form field component with label and error message.
37
+ * Generic form field wrapper that renders a label, child control, and error messages.
31
38
  *
32
- * `import { FormField } from @k8slens/lds-form`
33
- *
34
- * See `FormComponent`for individual form components.
39
+ * Usage: `import { FormField } from "@k8slens/lds-form"`
35
40
  */
36
41
  export default function FormField({ id, label, labelId, errorId, required, errors, children, labelProps, errorProps, ...props }: PropsWithChildren<FormFieldProps>): React.JSX.Element;
@@ -1 +1 @@
1
- import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import l,{useRef as o,useCallback as a,useEffect as i}from"react";import{usePrevious as t}from"../common/usePrevious.js";import{useFieldIds as n}from"../common/useFieldIds.js";import{useInputErrorProps as u}from"../common/useInputErrorProps.js";import{useFormComponentData as d,defaultErrorParser as v}from"../common/useFormComponentData.js";import s from"../FormField/FormField.js";import{setNativeValue as m,getInputValidity as p}from"../common/helpers.js";import f from"../node_modules/@k8slens/lds/lib/es/Input/Input.js";var c=function(r,e,l,o,a){void 0===a&&(a={valid:!0});var i=a;if(o&&null!==o&&(i=p(o)),l){var t=l(r,i,e.name,e);"string"==typeof t?(i[t]=!0,i.valid=!1):t&&(t.forEach((function(r){i[r]=!0})),i.valid=!1)}return i};function b(p){var b=p.id,P=p.label,y=p.wrapperProps,j=p.labelProps,I=p.validate,F=p.errorParser,g=void 0===F?v:F,h=p.errorProps,C=p.value,E=p.onChange,V=p.type,_=r(p,["id","label","wrapperProps","labelProps","validate","errorParser","errorProps","value","onChange","type"]),q=t(C),w=o(null),k=n(b),x=k.id,D=k.labelId,z=k.errorId,A=d({value:C,errorParser:g,constraints:_,label:P}),B=A.currentValue,G=A.setCurrentValue,H=A.errors,J=u({id:z,errors:H}),K=a((function(r){var l=r.target,o=function(r,e){return"number"===e?parseFloat(r):r}(l.value,V),a=c(o,_,I,l,e({},l.validity));G({value:o,validity:e({},a)}),null==E||E(o,null==a?void 0:a.valid)}),[V,I,E,G,_]);return i((function(){var r,l;if(q!==C&&C!==B.value){var o=C;w.current&&m(w.current,o);var a=c(o,u,I,w.current),i=null===(r=B.validity)||void 0===r?void 0:r.valid,t=null==a?void 0:a.valid;G({value:o,validity:a}),i!==t&&E(o,t)}else if(B.validity){var n=c(B.value,_,I,w.current);(i=null===(l=B.validity)||void 0===l?void 0:l.valid)!==(t=null==n?void 0:n.valid)&&(G((function(r){return e(e({},r),{validity:n})})),E(B.value,t))}}),[I,C,q,B,G,E,_]),l.createElement(s,e({id:x,label:P,labelId:D,errorId:z,errors:H,required:_.required,labelProps:j,errorProps:h},y),l.createElement(f,e({ref:w,id:x,"aria-labelledby":D},J,_,{type:V,defaultValue:null==_?void 0:_.defaultValue,value:null==B?void 0:B.value,onChange:K})))}export{b as default};
1
+ import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import l,{useRef as o,useCallback as a,useEffect as i}from"react";import{usePrevious as t}from"../common/usePrevious.js";import{useFieldIds as n}from"../common/useFieldIds.js";import{useInputErrorProps as u}from"../common/useInputErrorProps.js";import{useFormComponentData as d,defaultErrorParser as v}from"../common/useFormComponentData.js";import s from"../FormField/FormField.js";import{setNativeValue as m,getInputValidity as p}from"../common/helpers.js";import f from"../node_modules/@k8slens/lds/lib/es/Input/Input.js";var c=function(r,e,l,o,a){void 0===a&&(a={valid:!0});var i=a;if(o&&null!==o&&(i=p(o)),l){var t=l(r,i,e.name,e);"string"==typeof t?(i[t]=!0,i.valid=!1):t&&(t.forEach(function(r){i[r]=!0}),i.valid=!1)}return i};function b(p){var b=p.id,P=p.label,y=p.wrapperProps,j=p.labelProps,I=p.validate,F=p.errorParser,g=void 0===F?v:F,h=p.errorProps,C=p.value,E=p.onChange,V=p.type,_=r(p,["id","label","wrapperProps","labelProps","validate","errorParser","errorProps","value","onChange","type"]),q=t(C),w=o(null),k=n(b),x=k.id,D=k.labelId,z=k.errorId,A=d({value:C,errorParser:g,constraints:_,label:P}),B=A.currentValue,G=A.setCurrentValue,H=A.errors,J=u({id:z,errors:H}),K=a(function(r){var l=r.target,o=function(r,e){return"number"===e?parseFloat(r):r}(l.value,V),a=c(o,_,I,l,e({},l.validity));G({value:o,validity:e({},a)}),null==E||E(o,null==a?void 0:a.valid)},[V,I,E,G,_]);return i(function(){var r,l;if(q!==C&&C!==B.value){var o=C;w.current&&m(w.current,o);var a=c(o,u,I,w.current),i=null===(r=B.validity)||void 0===r?void 0:r.valid,t=null==a?void 0:a.valid;G({value:o,validity:a}),i!==t&&E(o,t)}else if(B.validity){var n=c(B.value,_,I,w.current);(i=null===(l=B.validity)||void 0===l?void 0:l.valid)!==(t=null==n?void 0:n.valid)&&(G(function(r){return e(e({},r),{validity:n})}),E(B.value,t))}},[I,C,q,B,G,E,_]),l.createElement(s,e({id:x,label:P,labelId:D,errorId:z,errors:H,required:_.required,labelProps:j,errorProps:h},y),l.createElement(f,e({ref:w,id:x,"aria-labelledby":D},J,_,{type:V,defaultValue:null==_?void 0:_.defaultValue,value:null==B?void 0:B.value,onChange:K})))}export{b as default};
@@ -1,16 +1,24 @@
1
1
  import React, { type ReactElement } from "react";
2
+ /** Props for the FormLabel component. */
2
3
  export interface FormLabelProps extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "id" | "htmlFor"> {
4
+ /** HTML `id` for the label element. */
3
5
  id: string;
6
+ /** `id` of the form control this label is for. */
4
7
  forId: string;
8
+ /** Label content — a string or React element. */
5
9
  label: ReactElement | string;
10
+ /** Whether the associated field is required (used together with `showRequired`). */
6
11
  required?: boolean;
7
- /** Show required asterisk and visually hidden "required" text. Default: false */
12
+ /**
13
+ * Show required asterisk and visually hidden "required" text.
14
+ * @default false
15
+ */
8
16
  showRequired?: boolean;
9
17
  }
10
18
  /**
11
- * Form label component used by `FormField`
19
+ * A `<label>` element with optional required indicator. Used internally by `FormField`.
12
20
  *
13
- * `import { FormLabel } from @k8slens/lds-form`
21
+ * Usage: `import { FormLabel } from "@k8slens/lds-form"`
14
22
  */
15
23
  declare const FormLabel: ({ id, forId, label, showRequired, required, ...props }: FormLabelProps) => React.JSX.Element;
16
24
  export default FormLabel;
@@ -1,18 +1,30 @@
1
1
  import React, { PropsWithChildren, ReactNode } from "react";
2
2
  import { type SwitchProps } from "@k8slens/lds/lib/es/Switch/Switch.d";
3
3
  import { FormFieldComponentProps } from "../FormField/FormField";
4
+ /** Describes a single switch within a `FormSwitchGroup`. */
4
5
  export declare type SwitchValue = {
6
+ /** Unique identifier for this switch. */
5
7
  id: string;
8
+ /** Label displayed next to the switch. */
6
9
  label: string;
10
+ /** Whether the switch is on. */
7
11
  checked: boolean | undefined;
12
+ /** Whether this individual switch is disabled. */
8
13
  disabled?: boolean;
14
+ /** Optional description rendered below the label. */
9
15
  description?: string | ReactNode;
10
16
  };
17
+ /** Props for the FormSwitchGroup component. */
11
18
  export interface FormSwitchGroupProps<CustomError extends string> extends Omit<FormFieldComponentProps<number, CustomError>, "onChange" | "value">, Omit<SwitchProps, "value" | "onChange" | "label"> {
19
+ /** HTML `id` attribute for the field. */
12
20
  id?: string;
21
+ /** Props forwarded to the wrapper div. */
13
22
  wrapperProps?: React.HTMLAttributes<HTMLDivElement>;
23
+ /** Array of switch items to render. */
14
24
  values: Array<SwitchValue>;
25
+ /** Called when any switch changes with the full array and the IDs that changed. */
15
26
  onChange(values: Array<SwitchValue>, updatedKeys: Array<string>): void;
27
+ /** Validation error strings to display. */
16
28
  errors?: Array<string>;
17
29
  }
18
30
  /**
@@ -1 +1 @@
1
- import{__rest as e,__assign as r}from"../_virtual/_tslib.js";import a,{useCallback as s,Fragment as o}from"react";import l from"clsx";import t from"../FormField/FormField.js";import{useFieldIds as i}from"../common/useFieldIds.js";import{useInputErrorProps as m}from"../common/useInputErrorProps.js";import c from"./FormSwitchGroup.module.css.js";import{Switch as d}from"../node_modules/@k8slens/lds/lib/es/Switch/Switch.js";function n(n){var p=n.id,u=n.label,b=n.wrapperProps,f=n.labelProps;n.validate;var h=n.errorProps,v=n.values,N=n.onChange;n.type;var w=n.errors,P=n.disabled,E=e(n,["id","label","wrapperProps","labelProps","validate","errorProps","values","onChange","type","errors","disabled"]),j=i(p),k=j.id,F=j.labelId,I=j.errorId,S=m({id:I,errors:w}),g=s((function(e,a){var s=v.map((function(s){return s.id===e?r(r({},s),{checked:a}):s}));N(s,[e])}),[v,N]);return a.createElement(t,r({id:k,className:c.formSwitchGroup,label:u,labelId:F,errorId:I,errors:w,labelProps:r(r({},f),{className:l(c.groupLabel,null==f?void 0:f.className)}),errorProps:r(r({},S),{className:l(c.error,null==h?void 0:h.className)})},b),v.map((function(e){var s=e.id,t=e.label,i=e.checked,m=e.description,n=e.disabled;return a.createElement(o,{key:s},a.createElement(d,r({key:s,id:s,checked:i,onChange:function(e){return g(s,e)},disabled:P||n},E,{className:l(E.className,c.switch)}),a.createElement("span",{className:c.labelWrapper},a.createElement("span",{className:c.switchLabel},t),m&&a.createElement("p",{className:c.description},m))))})))}export{n as default};
1
+ import{__rest as e,__assign as r}from"../_virtual/_tslib.js";import a,{useCallback as s,Fragment as o}from"react";import l from"clsx";import t from"../FormField/FormField.js";import{useFieldIds as i}from"../common/useFieldIds.js";import{useInputErrorProps as m}from"../common/useInputErrorProps.js";import c from"./FormSwitchGroup.module.css.js";import{Switch as d}from"../node_modules/@k8slens/lds/lib/es/Switch/Switch.js";function n(n){var p=n.id,u=n.label,b=n.wrapperProps,f=n.labelProps;n.validate;var h=n.errorProps,v=n.values,N=n.onChange;n.type;var w=n.errors,P=n.disabled,E=e(n,["id","label","wrapperProps","labelProps","validate","errorProps","values","onChange","type","errors","disabled"]),j=i(p),k=j.id,F=j.labelId,I=j.errorId,S=m({id:I,errors:w}),g=s(function(e,a){var s=v.map(function(s){return s.id===e?r(r({},s),{checked:a}):s});N(s,[e])},[v,N]);return a.createElement(t,r({id:k,className:c.formSwitchGroup,label:u,labelId:F,errorId:I,errors:w,labelProps:r(r({},f),{className:l(c.groupLabel,null==f?void 0:f.className)}),errorProps:r(r({},S),{className:l(c.error,null==h?void 0:h.className)})},b),v.map(function(e){var s=e.id,t=e.label,i=e.checked,m=e.description,n=e.disabled;return a.createElement(o,{key:s},a.createElement(d,r({key:s,id:s,checked:i,onChange:function(e){return g(s,e)},disabled:P||n},E,{className:l(E.className,c.switch)}),a.createElement("span",{className:c.labelWrapper},a.createElement("span",{className:c.switchLabel},t),m&&a.createElement("p",{className:c.description},m))))}))}export{n as default};
@@ -1 +1 @@
1
- var r=function(){return r=Object.assign||function(r){for(var t,e=1,n=arguments.length;e<n;e++)for(var o in t=arguments[e])Object.prototype.hasOwnProperty.call(t,o)&&(r[o]=t[o]);return r},r.apply(this,arguments)};function t(r,t){var e={};for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&t.indexOf(n)<0&&(e[n]=r[n]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(r);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(r,n[o])&&(e[n[o]]=r[n[o]])}return e}export{r as __assign,t as __rest};
1
+ var r=function(){return r=Object.assign||function(r){for(var t,e=1,o=arguments.length;e<o;e++)for(var n in t=arguments[e])Object.prototype.hasOwnProperty.call(t,n)&&(r[n]=t[n]);return r},r.apply(this,arguments)};function t(r,t){var e={};for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&t.indexOf(o)<0&&(e[o]=r[o]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(r);n<o.length;n++)t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(r,o[n])&&(e[o[n]]=r[o[n]])}return e}"function"==typeof SuppressedError&&SuppressedError;export{r as __assign,t as __rest};
@@ -1 +1 @@
1
- import{useMemo as r}from"react";import{uniqueId as o}from"lodash";var t=function(t){var e=r((function(){return t||o("form-field-")}),[t]);return{id:e,labelId:"".concat(e,"-label"),errorId:"".concat(e,"-error")}};export{t as useFieldIds};
1
+ import{useMemo as r}from"react";import{uniqueId as o}from"lodash";var t=function(t){var e=r(function(){return t||o("form-field-")},[t]);return{id:e,labelId:"".concat(e,"-label"),errorId:"".concat(e,"-error")}};export{t as useFieldIds};
@@ -1 +1 @@
1
- import{useState as e,useMemo as t}from"react";import{uniq as n}from"lodash";var r=function(e,t,n){var r=n.min,a=n.max,o=n.minLength,l=n.maxLength,i={valueMissing:"Required",tooShort:"Min. length is ".concat(o," chars"),tooLong:"Max. length is ".concat(l," chars"),rangeUnderflow:"Value should be at least ".concat(r),rangeOverflow:"Value should be no more than ".concat(a),default:"Value is invalid"};return i[t]||i.default},a=function(r){var a=r.value,o=r.errorParser,l=r.constraints,i=void 0===l?{}:l,u=r.label,s=e({value:a}),h=s[0],c=s[1],g=t((function(){for(var e=h.value,t=h.validity,r=[],a=Object.keys(t||{}).filter((function(e){return"valid"!==e})),l=0,s=a;l<s.length;l++){var c=s[l],g=void 0;switch(c){case"tooShort":t&&(t[c]||"string"==typeof e&&i.minLength&&e.length<i.minLength)&&(g=o(e,c,i,u));break;case"tooLong":t&&(t[c]||"string"==typeof e&&i.maxLength&&e.length>i.maxLength)&&(g=o(e,c,i,u));break;default:t&&t[c]&&(g=o(e,c,i,u))}g&&r.push(g)}!1!==(null==t?void 0:t.valid)||r.length||(g=o(e,"unknown",i,u))&&r.push(g);return n(r)}),[h,i,o,u]);return{currentValue:h,setCurrentValue:c,errors:g}};export{r as defaultErrorParser,a as useFormComponentData};
1
+ import{useState as e,useMemo as t}from"react";import{uniq as n}from"lodash";var r=function(e,t,n){var r=n.min,a=n.max,o=n.minLength,l=n.maxLength,i={valueMissing:"Required",tooShort:"Min. length is ".concat(o," chars"),tooLong:"Max. length is ".concat(l," chars"),rangeUnderflow:"Value should be at least ".concat(r),rangeOverflow:"Value should be no more than ".concat(a),default:"Value is invalid"};return i[t]||i.default},a=function(r){var a=r.value,o=r.errorParser,l=r.constraints,i=void 0===l?{}:l,u=r.label,s=e({value:a}),h=s[0],c=s[1],g=t(function(){for(var e=h.value,t=h.validity,r=[],a=Object.keys(t||{}).filter(function(e){return"valid"!==e}),l=0,s=a;l<s.length;l++){var c=s[l],g=void 0;switch(c){case"tooShort":t&&(t[c]||"string"==typeof e&&i.minLength&&e.length<i.minLength)&&(g=o(e,c,i,u));break;case"tooLong":t&&(t[c]||"string"==typeof e&&i.maxLength&&e.length>i.maxLength)&&(g=o(e,c,i,u));break;default:t&&t[c]&&(g=o(e,c,i,u))}g&&r.push(g)}!1!==(null==t?void 0:t.valid)||r.length||(g=o(e,"unknown",i,u))&&r.push(g);return n(r)},[h,i,o,u]);return{currentValue:h,setCurrentValue:c,errors:g}};export{r as defaultErrorParser,a as useFormComponentData};
@@ -1 +1 @@
1
- import{useMemo as r}from"react";var a=function(a){var e=a.id,i=a.errors;return r((function(){return(null==i?void 0:i.length)?{"aria-invalid":!0,"aria-errormessage":e,"aria-describedby":e}:{}}),[i,e])};export{a as useInputErrorProps};
1
+ import{useMemo as r}from"react";var a=function(a){var e=a.id,i=a.errors;return r(function(){return(null==i?void 0:i.length)?{"aria-invalid":!0,"aria-errormessage":e,"aria-describedby":e}:{}},[i,e])};export{a as useInputErrorProps};
@@ -1 +1 @@
1
- import{useRef as r,useEffect as t}from"react";function n(n){var c=r();return t((function(){c.current=n}),[n]),c.current}export{n as usePrevious};
1
+ import{useRef as r,useEffect as t}from"react";function n(n){var c=r();return t(function(){c.current=n},[n]),c.current}export{n as usePrevious};
@@ -1 +1 @@
1
- import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import a,{forwardRef as s}from"react";import t from"clsx";import o from"./Input.module.css.js";var i=s((function(s,i){var l,m=s.icon,c=s.wrapperProps,n=r(s,["icon","wrapperProps"]);return a.createElement("div",e({},c,{className:t(o.wrapper,null==c?void 0:c.className,(l={},l[o.withIcon]=m,l))}),a.createElement("input",e({ref:i},n,{className:t(o.input,(null==n?void 0:n.className)||"")})),m&&a.createElement(m,{className:o.icon}))}));export{i as default};
1
+ import{__rest as r,__assign as e}from"../_virtual/_tslib.js";import a,{forwardRef as s}from"react";import t from"clsx";import o from"./Input.module.css.js";var i=s(function(s,i){var l,m=s.icon,c=s.wrapperProps,n=r(s,["icon","wrapperProps"]);return a.createElement("div",e({},c,{className:t(o.wrapper,null==c?void 0:c.className,(l={},l[o.withIcon]=m,l))}),a.createElement("input",e({ref:i},n,{className:t(o.input,(null==n?void 0:n.className)||"")})),m&&a.createElement(m,{className:o.icon}))});export{i as default};
@@ -1 +1 @@
1
- import{__rest as e,__assign as t}from"../_virtual/_tslib.js";import a,{forwardRef as n,useRef as r,useState as l,useCallback as o,useEffect as s}from"react";import u from"clsx";import i from"./Textarea.module.css.js";var c=n((function(n,c){var m,f,p=n.icon,g=n.autoResize,h=void 0!==g&&g,v=n.wrapperProps,x=n.maxLength,d=n.className,N=n.onChange,y=n.value,_=n.defaultValue,w=e(n,["icon","autoResize","wrapperProps","maxLength","className","onChange","value","defaultValue"]),E=r(null),z=l((function(){return"string"==typeof y?y.length:"string"==typeof _?_.length:0})),C=z[0],L=z[1],R=o((function(e){E.current=e,"function"==typeof c?c(e):c&&(c.current=e)}),[c]),V=o((function(){var e=E.current;e&&h&&(e.style.height="auto",e.style.height="".concat(e.scrollHeight,"px"))}),[h]);s((function(){V()}),[y,V]),s((function(){"string"==typeof y&&null!=x&&L(y.length)}),[y,x]);var j=o((function(e){null!=x&&L(e.target.value.length),V(),null==N||N(e)}),[N,V,x]);return a.createElement("div",t({},v,{className:u(i.wrapper,null==v?void 0:v.className,(m={},m[i.withIcon]=p,m))}),a.createElement("textarea",t({ref:R},w,{value:y,defaultValue:_,maxLength:x,onChange:j,className:u(i.textarea,d,(f={},f[i.autoResize]=h,f))})),p&&a.createElement(p,{className:i.icon}),null!=x&&a.createElement("span",{className:i.counter,"aria-live":"polite"},C,"/",x))}));export{c as default};
1
+ import{__rest as e,__assign as t}from"../_virtual/_tslib.js";import a,{forwardRef as n,useRef as r,useState as l,useCallback as o,useEffect as s}from"react";import u from"clsx";import i from"./Textarea.module.css.js";var c=n(function(n,c){var m,f,p=n.icon,g=n.autoResize,h=void 0!==g&&g,v=n.wrapperProps,x=n.maxLength,d=n.className,N=n.onChange,y=n.value,_=n.defaultValue,w=e(n,["icon","autoResize","wrapperProps","maxLength","className","onChange","value","defaultValue"]),E=r(null),z=l(function(){return"string"==typeof y?y.length:"string"==typeof _?_.length:0}),C=z[0],L=z[1],R=o(function(e){E.current=e,"function"==typeof c?c(e):c&&(c.current=e)},[c]),V=o(function(){var e=E.current;e&&h&&(e.style.height="auto",e.style.height="".concat(e.scrollHeight,"px"))},[h]);s(function(){V()},[y,V]),s(function(){"string"==typeof y&&null!=x&&L(y.length)},[y,x]);var j=o(function(e){null!=x&&L(e.target.value.length),V(),null==N||N(e)},[N,V,x]);return a.createElement("div",t({},v,{className:u(i.wrapper,null==v?void 0:v.className,(m={},m[i.withIcon]=p,m))}),a.createElement("textarea",t({ref:R},w,{value:y,defaultValue:_,maxLength:x,onChange:j,className:u(i.textarea,d,(f={},f[i.autoResize]=h,f))})),p&&a.createElement(p,{className:i.icon}),null!=x&&a.createElement("span",{className:i.counter,"aria-live":"polite"},C,"/",x))});export{c as default};
@@ -1 +1 @@
1
- var r=function(){return r=Object.assign||function(r){for(var t,e=1,n=arguments.length;e<n;e++)for(var o in t=arguments[e])Object.prototype.hasOwnProperty.call(t,o)&&(r[o]=t[o]);return r},r.apply(this,arguments)};function t(r,t){var e={};for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&t.indexOf(n)<0&&(e[n]=r[n]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(r);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(r,n[o])&&(e[n[o]]=r[n[o]])}return e}export{r as __assign,t as __rest};
1
+ var r=function(){return r=Object.assign||function(r){for(var t,e=1,n=arguments.length;e<n;e++)for(var o in t=arguments[e])Object.prototype.hasOwnProperty.call(t,o)&&(r[o]=t[o]);return r},r.apply(this,arguments)};function t(r,t){var e={};for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&t.indexOf(n)<0&&(e[n]=r[n]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(r);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(r,n[o])&&(e[n[o]]=r[n[o]])}return e}"function"==typeof SuppressedError&&SuppressedError;export{r as __assign,t as __rest};
package/llms.txt CHANGED
@@ -29,53 +29,87 @@ import "@k8slens/lds-form/lib/es/index.css";
29
29
 
30
30
  ### FormField
31
31
 
32
- Wrapper component that groups label, input, and error message.
32
+ Generic form field wrapper that renders a label, child control, and error messages.
33
33
 
34
34
  ```tsx
35
35
  import { FormField, FormLabel, FormInput, FormErrorMessage } from "@k8slens/lds-form";
36
36
 
37
- <FormField>
38
- <FormLabel>Email</FormLabel>
39
- <FormInput type="email" />
40
- <FormErrorMessage>Please enter a valid email</FormErrorMessage>
37
+ <FormField id="email" label="Email" labelId="email-label" errorId="email-error">
38
+ <input id="email" type="email" />
41
39
  </FormField>
42
40
  ```
43
41
 
42
+ **FormFieldProps**
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | `id` | `string \| undefined` | — | The `id` of the child form control. Optional because HeadlessUI Combobox omits it on first render. |
47
+ | `label` | `string` | — | Label text rendered inside a `<label>` element. |
48
+ | `errorId` | `string` | — | Unique `id` for the error message element. Must differ from `id`. |
49
+ | `labelId` | `string` | — | Unique `id` for the label element. Must differ from `id`. |
50
+ | `required` | `boolean` | — | Whether the field is required. |
51
+ | `errors` | `Array<string>` | — | Validation error strings to display. |
52
+ | `labelProps` | `Partial<FormLabelProps>` | — | Props forwarded to the `FormLabel` component. |
53
+ | `errorProps` | `Partial<Omit<FormErrorMessageProps, "forId" \| "id">>` | — | Props forwarded to the `FormErrorMessage` component. |
54
+
55
+ **FormFieldComponentProps** — shared props for form components combining a field with validation:
56
+
57
+ | Prop | Type | Description |
58
+ |------|------|-------------|
59
+ | `label` | `string` | Label text. |
60
+ | `labelProps` | `Partial<FormLabelProps>` | Props forwarded to `FormLabel`. |
61
+ | `errorProps` | `Partial<...>` | Props forwarded to `FormErrorMessage`. |
62
+ | `validate` | `Validator<T, CustomError>` | Validation function — return `undefined` if valid, error key(s) if invalid. |
63
+ | `errorParser` | `ErrorParser<T, CustomError>` | Return error message string for a given error key. |
64
+ | `onChange` | `(value: T, isValid: boolean) => void` | Called when value changes with new value and validity. |
65
+
44
66
  ### FormInput
45
67
 
46
- Input with label, validation, and error handling. Wraps core Input in FormField.
68
+ Input with label, validation, and error handling. Wraps core `Input` in `FormField`.
47
69
 
48
70
  ```tsx
49
- import { FormInput } from "@k8slens/lds-form";
50
-
51
71
  <FormInput name="email" type="email" label="Email" value={email} onChange={setEmail} />
52
72
  ```
53
73
 
54
74
  ### FormLabel
55
75
 
56
- Label component for form fields.
76
+ A `<label>` element with optional required indicator. Used internally by `FormField`.
57
77
 
58
- ### FormErrorMessage
78
+ ```tsx
79
+ <FormLabel id="email-label" forId="email" label="Email" required showRequired />
80
+ ```
59
81
 
60
- Displays validation error messages.
82
+ **FormLabelProps**
61
83
 
62
- ### FormSwitchGroup
84
+ | Prop | Type | Default | Description |
85
+ |------|------|---------|-------------|
86
+ | `id` | `string` | — | HTML `id` for the label element. |
87
+ | `forId` | `string` | — | `id` of the form control this label is for. |
88
+ | `label` | `ReactElement \| string` | — | Label content — a string or React element. |
89
+ | `required` | `boolean` | — | Whether the associated field is required (used together with `showRequired`). |
90
+ | `showRequired` | `boolean` | `false` | Show required asterisk and visually hidden "required" text. |
63
91
 
64
- Multiple toggle switches with shared label and error handling.
92
+ ### FormErrorMessage
65
93
 
66
- ```tsx
67
- import { FormSwitchGroup } from "@k8slens/lds-form";
94
+ Displays validation errors as a list associated with a form control.
68
95
 
69
- <FormSwitchGroup label="Notifications" values={options} onChange={setOptions} />
96
+ ```tsx
97
+ <FormErrorMessage id="email-error" forId="email" errors={["Please enter a valid email"]} />
70
98
  ```
71
99
 
100
+ **FormErrorMessageProps**
101
+
102
+ | Prop | Type | Description |
103
+ |------|------|-------------|
104
+ | `id` | `string` | HTML `id` for the error message element. |
105
+ | `forId` | `string` | `id` of the form control this error message describes. |
106
+ | `errors` | `Array<string>` | List of error strings to display. |
107
+
72
108
  ### FormTextarea
73
109
 
74
110
  Textarea wrapped in a FormField with label and error handling. Combines FormField + Textarea from @k8slens/lds.
75
111
 
76
112
  ```tsx
77
- import { FormTextarea } from "@k8slens/lds-form";
78
-
79
113
  <FormTextarea
80
114
  name="description"
81
115
  label="Description"
@@ -86,16 +120,33 @@ import { FormTextarea } from "@k8slens/lds-form";
86
120
  />
87
121
  ```
88
122
 
89
- **FormTextarea Props:**
90
- - Extends `TextareaProps` from @k8slens/lds Textarea component
91
- - `name` (required) - Field name for form submission
92
- - `label` - Field label text
93
- - `labelProps` - Props passed to FormLabel
94
- - `errorProps` - Props passed to FormErrorMessage
95
- - `errors` - Array of error messages to display
96
- - `required` (default: false) - Whether the field is required
97
- - `id` - Optional field ID (auto-generated if not provided)
98
- - All Textarea props: `maxLength`, `autoResize`, `icon`, `placeholder`, etc.
123
+ **Props:** Extends `TextareaProps` from @k8slens/lds + `FormFieldComponentProps`. Adds `name` (required) for form submission. Accepts all Textarea props (`maxLength`, `autoResize`, `icon`, `placeholder`, etc.).
124
+
125
+ ### FormSwitchGroup
126
+
127
+ Multiple toggle switches with shared label and error handling.
128
+
129
+ ```tsx
130
+ <FormSwitchGroup label="Notifications" values={options} onChange={setOptions} />
131
+ ```
132
+
133
+ **SwitchValue** — describes a single switch item:
134
+
135
+ | Field | Type | Description |
136
+ |-------|------|-------------|
137
+ | `id` | `string` | Unique identifier for this switch. |
138
+ | `label` | `string` | Label displayed next to the switch. |
139
+ | `checked` | `boolean \| undefined` | Whether the switch is on. |
140
+ | `disabled` | `boolean` | Whether this individual switch is disabled. |
141
+ | `description` | `string \| ReactNode` | Optional description rendered below the label. |
142
+
143
+ **FormSwitchGroupProps** — extends `FormFieldComponentProps`:
144
+
145
+ | Prop | Type | Description |
146
+ |------|------|-------------|
147
+ | `values` | `Array<SwitchValue>` | Array of switch items to render. |
148
+ | `onChange` | `(values: Array<SwitchValue>, updatedKeys: Array<string>) => void` | Called when any switch changes with the full array and the IDs that changed. |
149
+ | `wrapperProps` | `React.HTMLAttributes<HTMLDivElement>` | Props forwarded to the wrapper div. |
99
150
 
100
151
  ## Hooks
101
152
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k8slens/lds-form",
3
- "version": "0.53.2",
3
+ "version": "0.53.4",
4
4
  "description": "Lens Design System – React Form components",
5
5
  "author": "Mirantis Inc",
6
6
  "license": "MIT",
@@ -29,12 +29,12 @@
29
29
  "format": "oxlint --fix . && prettier --write ."
30
30
  },
31
31
  "dependencies": {
32
- "@k8slens/lds": "^0.58.2"
32
+ "@k8slens/lds": "^0.58.4"
33
33
  },
34
34
  "devDependencies": {
35
- "@k8slens/lds-tokens": "^0.59.2",
35
+ "@k8slens/lds-tokens": "^0.59.4",
36
36
  "@rollup/plugin-node-resolve": "15.0.2",
37
- "@storybook/react": "6.5.16",
37
+ "@storybook/react": "10.2.15",
38
38
  "@testing-library/react": "14.0.0",
39
39
  "typescript": "4.8.4"
40
40
  },
@@ -56,5 +56,5 @@
56
56
  "\\.svg": "<rootDir>/../../__mocks__/SVGStub.js"
57
57
  }
58
58
  },
59
- "gitHead": "1f889df45a91e8b67494c6e5e45197639861a84f"
59
+ "gitHead": "4d79cf509073c250bbc49794d459230e41de28e6"
60
60
  }