@khanacademy/wonder-blocks-form 7.2.0 → 7.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @khanacademy/wonder-blocks-form@7.2.0 build:css /home/runner/work/wonder-blocks/wonder-blocks/packages/wonder-blocks-form
2
+ > @khanacademy/wonder-blocks-form@7.2.1 build:css /home/runner/work/wonder-blocks/wonder-blocks/packages/wonder-blocks-form
3
3
  > pnpm exec wonder-blocks-tokens .
4
4
 
5
5
  CSS variables generated successfully in: /home/runner/work/wonder-blocks/wonder-blocks/packages/wonder-blocks-form/dist/css
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @khanacademy/wonder-blocks-form
2
2
 
3
+ ## 7.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - e21e448: Use typography styles for TextField and TextArea
8
+ - 6b05521: Update semantic color token usage, sizing token usage, and use global focus styles for TextField and TextArea
9
+ - dddbe55: Support TB styling in TextField and TextArea
10
+ - Updated dependencies [a98fe6c]
11
+ - Updated dependencies [e21e448]
12
+ - Updated dependencies [e21e448]
13
+ - Updated dependencies [dddbe55]
14
+ - @khanacademy/wonder-blocks-tokens@11.3.0
15
+ - @khanacademy/wonder-blocks-typography@4.2.10
16
+ - @khanacademy/wonder-blocks-clickable@7.1.14
17
+ - @khanacademy/wonder-blocks-icon@5.2.8
18
+ - @khanacademy/wonder-blocks-layout@3.1.25
19
+
3
20
  ## 7.2.0
4
21
 
5
22
  ### Minor Changes
package/dist/css/vars.css CHANGED
@@ -1,5 +1,17 @@
1
1
  :root {--wb-c-form-choice-inputWrapper-layout-padding: var(--wb-sizing-size_0);
2
- --wb-c-form-choice-inputWrapper-layout-margin: var(--wb-sizing-size_0);}
2
+ --wb-c-form-choice-inputWrapper-layout-margin: var(--wb-sizing-size_0);
3
+ --wb-c-form-field-border-radius: var(--wb-border-radius-radius_040);
4
+ --wb-c-form-field-border-width-error: var(--wb-border-width-thin);
5
+ --wb-c-form-field-border-width-press: var(--wb-border-width-none);
6
+ --wb-c-form-field-sizing-height: var(--wb-sizing-size_400);
7
+ --wb-c-form-field-layout-paddingBlock: var(--wb-sizing-size_100);
8
+ --wb-c-form-field-layout-paddingInline: var(--wb-sizing-size_160);}
3
9
 
4
10
  [data-wb-theme='thunderblocks'] {--wb-c-form-choice-inputWrapper-layout-padding: var(--wb-sizing-size_040);
5
- --wb-c-form-choice-inputWrapper-layout-margin: calc(var(--wb-sizing-size_040) * -1);}
11
+ --wb-c-form-choice-inputWrapper-layout-margin: calc(var(--wb-sizing-size_040) * -1);
12
+ --wb-c-form-field-border-radius: var(--wb-border-radius-radius_080);
13
+ --wb-c-form-field-border-width-error: var(--wb-border-width-medium);
14
+ --wb-c-form-field-border-width-press: var(--wb-border-width-thin);
15
+ --wb-c-form-field-sizing-height: var(--wb-sizing-size_440);
16
+ --wb-c-form-field-layout-paddingBlock: var(--wb-sizing-size_100);
17
+ --wb-c-form-field-layout-paddingInline: var(--wb-sizing-size_120);}
package/dist/es/index.js CHANGED
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { useId } from 'react';
4
4
  import { StyleSheet } from 'aphrodite';
5
5
  import { addStyle, View, Id, useOnMountEffect } from '@khanacademy/wonder-blocks-core';
6
- import { sizing, mapValuesToCssVars, semanticColor, border, spacing, font } from '@khanacademy/wonder-blocks-tokens';
6
+ import { sizing, border, mapValuesToCssVars, semanticColor, spacing, font } from '@khanacademy/wonder-blocks-tokens';
7
7
  import { BodyText, styles as styles$7, LabelMedium, LabelSmall } from '@khanacademy/wonder-blocks-typography';
8
8
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
9
9
  import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
@@ -11,7 +11,7 @@ import minusIcon from '@phosphor-icons/core/bold/minus-bold.svg';
11
11
  import { focusStyles } from '@khanacademy/wonder-blocks-styles';
12
12
  import { Strut } from '@khanacademy/wonder-blocks-layout';
13
13
 
14
- var themeDefault = {choice:{inputWrapper:{layout:{padding:sizing.size_0,margin:sizing.size_0}}}};
14
+ var themeDefault = {choice:{inputWrapper:{layout:{padding:sizing.size_0,margin:sizing.size_0}}},field:{border:{radius:border.radius.radius_040,width:{error:border.width.thin,press:border.width.none}},sizing:{height:sizing.size_400},layout:{paddingBlock:sizing.size_100,paddingInline:sizing.size_160}}};
15
15
 
16
16
  var theme = mapValuesToCssVars(themeDefault,"--wb-c-form-");
17
17
 
@@ -37,12 +37,12 @@ const StyledFieldset=addStyle("fieldset");const StyledLegend=addStyle("legend");
37
37
 
38
38
  const defaultErrorMessage="This field is required.";const useFieldValidation=({value,disabled=false,validate,onValidate,required=false,instantValidation=true})=>{const[errorMessage,setErrorMessage]=React.useState(()=>validate&&value!==""&&!disabled&&validate(value)||null);const onChangeValidation=newValue=>{if(instantValidation){handleValidation(newValue);}else {setErrorMessage(null);if(onValidate){onValidate(null);}}};const onBlurValidation=newValue=>{if(!instantValidation){if(newValue||required){handleValidation(newValue);}}};const handleValidation=newValue=>{if(disabled){return}if(validate){const error=validate(newValue)||null;setErrorMessage(error);if(onValidate){onValidate(error);}}else if(required){const requiredString=typeof required==="string"?required:defaultErrorMessage;const error=newValue?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}};useOnMountEffect(()=>{if(value!==""){handleValidation(value);}});return {errorMessage,onBlurValidation,onChangeValidation}};
39
39
 
40
- const StyledInput=addStyle("input");const TextField=props=>{const{id,type="text",value,name,disabled=false,error,validate,onValidate,required,placeholder,style,testId,readOnly,autoFocus,autoComplete,forwardedRef,instantValidation=true,onKeyDown,onChange,onFocus,onBlur,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,required,disabled,instantValidation,validate,onValidate});const hasError=error||!!errorMessage;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleFocus=event=>{if(onFocus){onFocus(event);}};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsx(Id,{id:id,children:uniqueId=>jsx(StyledInput,{style:[styles$2.input,styles$7.LabelMedium,styles$2.default,!disabled&&styles$2.defaultFocus,disabled&&styles$2.disabled,hasError&&styles$2.error,style],id:uniqueId,type:type,placeholder:placeholder,value:value,name:name,"aria-disabled":disabled,"aria-required":!!required,onChange:handleChange,onKeyDown:disabled?undefined:onKeyDown,onFocus:handleFocus,onBlur:handleBlur,"data-testid":testId,readOnly:readOnly||disabled,autoFocus:autoFocus,autoComplete:autoComplete,ref:forwardedRef,"aria-invalid":hasError,...otherProps})})};const styles$2=StyleSheet.create({input:{width:"100%",height:40,borderRadius:border.radius.radius_040,boxSizing:"border-box",paddingLeft:spacing.medium_16,margin:0},default:{background:semanticColor.input.default.background,border:`${border.width.thin} solid ${semanticColor.input.default.border}`,color:semanticColor.input.default.foreground,"::placeholder":{color:semanticColor.input.default.placeholder}},defaultFocus:{":focus-visible":{borderColor:semanticColor.focus.outer,outline:`${border.width.thin} solid ${semanticColor.focus.outer}`,outlineOffset:-2}},error:{background:semanticColor.input.error.background,border:`${border.width.thin} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground,"::placeholder":{color:semanticColor.input.default.placeholder},":focus-visible":{outlineColor:semanticColor.focus.outer,outline:`${border.width.medium} solid ${semanticColor.focus.outer}`}},disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground,"::placeholder":{color:semanticColor.input.disabled.placeholder},cursor:"not-allowed",":focus-visible":{outline:`${border.width.medium} solid ${semanticColor.focus.outer}`,outlineOffset:-3}}});var TextField$1 = React.forwardRef((props,ref)=>jsx(TextField,{...props,forwardedRef:ref}));
40
+ const StyledInput=addStyle("input");const TextField=props=>{const{id,type="text",value,name,disabled=false,error,validate,onValidate,required,placeholder,style,testId,readOnly,autoFocus,autoComplete,forwardedRef,instantValidation=true,onKeyDown,onChange,onFocus,onBlur,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,required,disabled,instantValidation,validate,onValidate});const hasError=error||!!errorMessage;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleFocus=event=>{if(onFocus){onFocus(event);}};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsx(Id,{id:id,children:uniqueId=>jsx(StyledInput,{style:[styles$2.input,styles$7.BodyTextMediumMediumWeight,styles$2.default,disabled&&styles$2.disabled,hasError&&styles$2.error,readOnly&&styles$2.readOnly,style],id:uniqueId,type:type,placeholder:placeholder,value:value,name:name,"aria-disabled":disabled,"aria-required":!!required,onChange:handleChange,onKeyDown:disabled?undefined:onKeyDown,onFocus:handleFocus,onBlur:handleBlur,"data-testid":testId,readOnly:readOnly||disabled,autoFocus:autoFocus,autoComplete:autoComplete,ref:forwardedRef,"aria-invalid":hasError,...otherProps})})};const styles$2=StyleSheet.create({input:{width:"100%",height:theme.field.sizing.height,borderRadius:theme.field.border.radius,boxSizing:"border-box",paddingInline:theme.field.layout.paddingInline,paddingBlock:theme.field.layout.paddingBlock,margin:sizing.size_0},readOnly:{background:semanticColor.input.readOnly.background,color:semanticColor.input.readOnly.text},default:{background:semanticColor.input.default.background,border:`${border.width.thin} solid ${semanticColor.input.default.border}`,color:semanticColor.input.default.foreground,"::placeholder":{color:semanticColor.input.default.placeholder},...focusStyles.focus,[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:`0 0 0 ${theme.field.border.width.press} ${semanticColor.input.default.border}`}},error:{background:semanticColor.input.error.background,border:`${theme.field.border.width.error} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground,"::placeholder":{color:semanticColor.input.default.placeholder}},disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground,"::placeholder":{color:semanticColor.input.disabled.placeholder},cursor:"not-allowed"}});var TextField$1 = React.forwardRef((props,ref)=>jsx(TextField,{...props,forwardedRef:ref}));
41
41
 
42
42
  const StyledSpan=addStyle("span");class FieldHeading extends React.Component{renderLabel(){const{label,id,required,testId}=this.props;const requiredIcon=jsxs(StyledSpan,{style:styles$1.required,"aria-hidden":true,children:[" ","*"]});return jsxs(React.Fragment,{children:[jsxs(LabelMedium,{style:styles$1.label,tag:"label",htmlFor:id&&`${id}-field`,testId:testId&&`${testId}-label`,children:[label,required&&requiredIcon]}),jsx(Strut,{size:spacing.xxxSmall_4})]})}maybeRenderDescription(){const{description,testId}=this.props;if(!description){return null}return jsxs(React.Fragment,{children:[jsx(LabelSmall,{style:styles$1.description,testId:testId&&`${testId}-description`,children:description}),jsx(Strut,{size:spacing.xxxSmall_4})]})}maybeRenderError(){const{error,id,testId}=this.props;if(!error){return null}return jsxs(React.Fragment,{children:[jsx(Strut,{size:spacing.small_12}),jsx(LabelSmall,{style:styles$1.error,role:"alert",id:id&&`${id}-error`,testId:testId&&`${testId}-error`,children:error})]})}render(){const{field,style}=this.props;return jsxs(View,{style:style,children:[this.renderLabel(),this.maybeRenderDescription(),jsx(Strut,{size:spacing.xSmall_8}),field,this.maybeRenderError()]})}}const styles$1=StyleSheet.create({label:{color:semanticColor.text.primary},description:{color:semanticColor.text.secondary},error:{color:semanticColor.status.critical.foreground},required:{color:semanticColor.status.critical.foreground}});
43
43
 
44
44
  class LabeledTextField extends React.Component{render(){const{id,type,label,description,value,disabled,required,validate,onChange,onKeyDown,placeholder,style,testId,readOnly,autoComplete,forwardedRef,ariaDescribedby,name,onValidate,onFocus,onBlur,...otherProps}=this.props;return jsx(Id,{id:id,children:uniqueId=>jsx(FieldHeading,{id:uniqueId,testId:testId,style:style,field:jsx(TextField$1,{id:`${uniqueId}-field`,"aria-describedby":ariaDescribedby?ariaDescribedby:`${uniqueId}-error`,"aria-required":required?"true":"false",required:required,testId:testId&&`${testId}-field`,type:type,value:value,placeholder:placeholder,disabled:disabled,validate:validate,onValidate:this.handleValidate,onChange:onChange,onKeyDown:onKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur,readOnly:readOnly,autoComplete:autoComplete,ref:forwardedRef,name:name,...otherProps}),label:label,description:description,required:!!required,error:!this.state.focused&&this.state.error||""})})}constructor(props){super(props),this.handleValidate=errorMessage=>{const{onValidate}=this.props;this.setState({error:errorMessage},()=>{if(onValidate){onValidate(errorMessage);}});},this.handleFocus=event=>{const{onFocus}=this.props;this.setState({focused:true},()=>{if(onFocus){onFocus(event);}});},this.handleBlur=event=>{const{onBlur}=this.props;this.setState({focused:false},()=>{if(onBlur){onBlur(event);}});};this.state={error:null,focused:false};}}LabeledTextField.defaultProps={type:"text",disabled:false};var labeledTextField = React.forwardRef((props,ref)=>jsx(LabeledTextField,{...props,forwardedRef:ref}));
45
45
 
46
- const StyledTextarea=addStyle("textarea");const TextArea=React.forwardRef(function TextArea(props,ref){const{onChange,value,placeholder,disabled,id,testId,style,readOnly,autoComplete,name,className,autoFocus,rows,spellCheck,wrap,minLength,maxLength,onClick,onKeyDown,onKeyUp,onFocus,onBlur,validate,onValidate,required,resizeType,rootStyle,error,instantValidation=true,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,disabled,validate,onValidate,required,instantValidation});const hasError=error||!!errorMessage;const generatedUniqueId=useId();const uniqueId=id??generatedUniqueId;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsx(View,{style:[{width:"100%"},rootStyle],children:jsx(StyledTextarea,{id:uniqueId,"data-testid":testId,ref:ref,className:className,style:[styles.textarea,styles$7.LabelMedium,resizeType&&resizeStyles[resizeType],styles.default,!disabled&&styles.defaultFocus,disabled&&styles.disabled,hasError&&styles.error,style],value:value,onChange:handleChange,placeholder:placeholder,"aria-disabled":disabled,readOnly:readOnly||disabled,autoComplete:autoComplete,name:name,autoFocus:autoFocus,rows:rows,spellCheck:spellCheck,wrap:wrap,minLength:minLength,maxLength:maxLength,"aria-required":!!required,onClick:disabled?undefined:onClick,onKeyDown:disabled?undefined:onKeyDown,onKeyUp:disabled?undefined:onKeyUp,onFocus:onFocus,onBlur:handleBlur,required:!!required,...otherProps,"aria-invalid":hasError})})});const VERTICAL_SPACING_PX=10;const styles=StyleSheet.create({textarea:{borderRadius:border.radius.radius_040,boxSizing:"border-box",padding:`${VERTICAL_SPACING_PX}px ${spacing.medium_16}px`,minHeight:`calc(${VERTICAL_SPACING_PX*2+2}px + ${font.lineHeight.medium})`},default:{background:semanticColor.input.default.background,border:`${border.width.thin} solid ${semanticColor.input.default.border}`,color:semanticColor.input.default.foreground,"::placeholder":{color:semanticColor.input.default.placeholder}},defaultFocus:{":focus-visible":{borderColor:semanticColor.focus.outer,outline:`${border.width.thin} solid ${semanticColor.focus.outer}`,outlineOffset:-2}},disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground,"::placeholder":{color:semanticColor.input.disabled.placeholder},cursor:"not-allowed",":focus-visible":{outline:`${border.width.medium} solid ${semanticColor.focus.outer}`,outlineOffset:-3}},error:{background:semanticColor.input.error.background,border:`${border.width.thin} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground,"::placeholder":{color:semanticColor.input.default.placeholder},":focus-visible":{outline:`${border.width.medium} solid ${semanticColor.focus.outer}`,borderColor:semanticColor.input.error.border}}});const resizeStyles=StyleSheet.create({both:{resize:"both"},none:{resize:"none"},horizontal:{resize:"horizontal"},vertical:{resize:"vertical"}});
46
+ const StyledTextarea=addStyle("textarea");const TextArea=React.forwardRef(function TextArea(props,ref){const{onChange,value,placeholder,disabled,id,testId,style,readOnly,autoComplete,name,className,autoFocus,rows,spellCheck,wrap,minLength,maxLength,onClick,onKeyDown,onKeyUp,onFocus,onBlur,validate,onValidate,required,resizeType,rootStyle,error,instantValidation=true,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,disabled,validate,onValidate,required,instantValidation});const hasError=error||!!errorMessage;const generatedUniqueId=useId();const uniqueId=id??generatedUniqueId;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsx(View,{style:[{width:"100%"},rootStyle],children:jsx(StyledTextarea,{id:uniqueId,"data-testid":testId,ref:ref,className:className,style:[styles.textarea,styles$7.BodyTextMediumMediumWeight,resizeType&&resizeStyles[resizeType],styles.default,disabled&&styles.disabled,hasError&&styles.error,readOnly&&styles.readOnly,style],value:value,onChange:handleChange,placeholder:placeholder,"aria-disabled":disabled,readOnly:readOnly||disabled,autoComplete:autoComplete,name:name,autoFocus:autoFocus,rows:rows,spellCheck:spellCheck,wrap:wrap,minLength:minLength,maxLength:maxLength,"aria-required":!!required,onClick:disabled?undefined:onClick,onKeyDown:disabled?undefined:onKeyDown,onKeyUp:disabled?undefined:onKeyUp,onFocus:onFocus,onBlur:handleBlur,required:!!required,...otherProps,"aria-invalid":hasError})})});const styles=StyleSheet.create({textarea:{borderRadius:theme.field.border.radius,boxSizing:"border-box",paddingInline:theme.field.layout.paddingInline,paddingBlock:theme.field.layout.paddingBlock,minHeight:theme.field.sizing.height},readOnly:{background:semanticColor.input.readOnly.background,color:semanticColor.input.readOnly.text},default:{background:semanticColor.input.default.background,border:`${border.width.thin} solid ${semanticColor.input.default.border}`,color:semanticColor.input.default.foreground,"::placeholder":{color:semanticColor.input.default.placeholder},...focusStyles.focus,[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:`0 0 0 ${theme.field.border.width.press} ${semanticColor.input.default.border}`}},disabled:{background:semanticColor.input.disabled.background,border:`${border.width.thin} solid ${semanticColor.input.disabled.border}`,color:semanticColor.input.disabled.foreground,"::placeholder":{color:semanticColor.input.disabled.placeholder},cursor:"not-allowed"},error:{background:semanticColor.input.error.background,border:`${theme.field.border.width.error} solid ${semanticColor.input.error.border}`,color:semanticColor.input.error.foreground,"::placeholder":{color:semanticColor.input.default.placeholder}}});const resizeStyles=StyleSheet.create({both:{resize:"both"},none:{resize:"none"},horizontal:{resize:"horizontal"},vertical:{resize:"vertical"}});
47
47
 
48
48
  export { Checkbox, CheckboxGroup, Choice, labeledTextField as LabeledTextField, RadioGroup, TextArea, TextField$1 as TextField };
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
38
  var checkIcon__default = /*#__PURE__*/_interopDefaultLegacy(checkIcon);
39
39
  var minusIcon__default = /*#__PURE__*/_interopDefaultLegacy(minusIcon);
40
40
 
41
- var themeDefault = {choice:{inputWrapper:{layout:{padding:wonderBlocksTokens.sizing.size_0,margin:wonderBlocksTokens.sizing.size_0}}}};
41
+ var themeDefault = {choice:{inputWrapper:{layout:{padding:wonderBlocksTokens.sizing.size_0,margin:wonderBlocksTokens.sizing.size_0}}},field:{border:{radius:wonderBlocksTokens.border.radius.radius_040,width:{error:wonderBlocksTokens.border.width.thin,press:wonderBlocksTokens.border.width.none}},sizing:{height:wonderBlocksTokens.sizing.size_400},layout:{paddingBlock:wonderBlocksTokens.sizing.size_100,paddingInline:wonderBlocksTokens.sizing.size_160}}};
42
42
 
43
43
  var theme = wonderBlocksTokens.mapValuesToCssVars(themeDefault,"--wb-c-form-");
44
44
 
@@ -64,13 +64,13 @@ const StyledFieldset=wonderBlocksCore.addStyle("fieldset");const StyledLegend=wo
64
64
 
65
65
  const defaultErrorMessage="This field is required.";const useFieldValidation=({value,disabled=false,validate,onValidate,required=false,instantValidation=true})=>{const[errorMessage,setErrorMessage]=React__namespace.useState(()=>validate&&value!==""&&!disabled&&validate(value)||null);const onChangeValidation=newValue=>{if(instantValidation){handleValidation(newValue);}else {setErrorMessage(null);if(onValidate){onValidate(null);}}};const onBlurValidation=newValue=>{if(!instantValidation){if(newValue||required){handleValidation(newValue);}}};const handleValidation=newValue=>{if(disabled){return}if(validate){const error=validate(newValue)||null;setErrorMessage(error);if(onValidate){onValidate(error);}}else if(required){const requiredString=typeof required==="string"?required:defaultErrorMessage;const error=newValue?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}};wonderBlocksCore.useOnMountEffect(()=>{if(value!==""){handleValidation(value);}});return {errorMessage,onBlurValidation,onChangeValidation}};
66
66
 
67
- const StyledInput=wonderBlocksCore.addStyle("input");const TextField=props=>{const{id,type="text",value,name,disabled=false,error,validate,onValidate,required,placeholder,style,testId,readOnly,autoFocus,autoComplete,forwardedRef,instantValidation=true,onKeyDown,onChange,onFocus,onBlur,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,required,disabled,instantValidation,validate,onValidate});const hasError=error||!!errorMessage;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleFocus=event=>{if(onFocus){onFocus(event);}};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueId=>jsxRuntime.jsx(StyledInput,{style:[styles$2.input,wonderBlocksTypography.styles.LabelMedium,styles$2.default,!disabled&&styles$2.defaultFocus,disabled&&styles$2.disabled,hasError&&styles$2.error,style],id:uniqueId,type:type,placeholder:placeholder,value:value,name:name,"aria-disabled":disabled,"aria-required":!!required,onChange:handleChange,onKeyDown:disabled?undefined:onKeyDown,onFocus:handleFocus,onBlur:handleBlur,"data-testid":testId,readOnly:readOnly||disabled,autoFocus:autoFocus,autoComplete:autoComplete,ref:forwardedRef,"aria-invalid":hasError,...otherProps})})};const styles$2=aphrodite.StyleSheet.create({input:{width:"100%",height:40,borderRadius:wonderBlocksTokens.border.radius.radius_040,boxSizing:"border-box",paddingLeft:wonderBlocksTokens.spacing.medium_16,margin:0},default:{background:wonderBlocksTokens.semanticColor.input.default.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.default.border}`,color:wonderBlocksTokens.semanticColor.input.default.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder}},defaultFocus:{":focus-visible":{borderColor:wonderBlocksTokens.semanticColor.focus.outer,outline:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-2}},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder},":focus-visible":{outlineColor:wonderBlocksTokens.semanticColor.focus.outer,outline:`${wonderBlocksTokens.border.width.medium} solid ${wonderBlocksTokens.semanticColor.focus.outer}`}},disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.disabled.placeholder},cursor:"not-allowed",":focus-visible":{outline:`${wonderBlocksTokens.border.width.medium} solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-3}}});var TextField$1 = React__namespace.forwardRef((props,ref)=>jsxRuntime.jsx(TextField,{...props,forwardedRef:ref}));
67
+ const StyledInput=wonderBlocksCore.addStyle("input");const TextField=props=>{const{id,type="text",value,name,disabled=false,error,validate,onValidate,required,placeholder,style,testId,readOnly,autoFocus,autoComplete,forwardedRef,instantValidation=true,onKeyDown,onChange,onFocus,onBlur,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,required,disabled,instantValidation,validate,onValidate});const hasError=error||!!errorMessage;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleFocus=event=>{if(onFocus){onFocus(event);}};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueId=>jsxRuntime.jsx(StyledInput,{style:[styles$2.input,wonderBlocksTypography.styles.BodyTextMediumMediumWeight,styles$2.default,disabled&&styles$2.disabled,hasError&&styles$2.error,readOnly&&styles$2.readOnly,style],id:uniqueId,type:type,placeholder:placeholder,value:value,name:name,"aria-disabled":disabled,"aria-required":!!required,onChange:handleChange,onKeyDown:disabled?undefined:onKeyDown,onFocus:handleFocus,onBlur:handleBlur,"data-testid":testId,readOnly:readOnly||disabled,autoFocus:autoFocus,autoComplete:autoComplete,ref:forwardedRef,"aria-invalid":hasError,...otherProps})})};const styles$2=aphrodite.StyleSheet.create({input:{width:"100%",height:theme.field.sizing.height,borderRadius:theme.field.border.radius,boxSizing:"border-box",paddingInline:theme.field.layout.paddingInline,paddingBlock:theme.field.layout.paddingBlock,margin:wonderBlocksTokens.sizing.size_0},readOnly:{background:wonderBlocksTokens.semanticColor.input.readOnly.background,color:wonderBlocksTokens.semanticColor.input.readOnly.text},default:{background:wonderBlocksTokens.semanticColor.input.default.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.default.border}`,color:wonderBlocksTokens.semanticColor.input.default.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder},...wonderBlocksStyles.focusStyles.focus,[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:`0 0 0 ${theme.field.border.width.press} ${wonderBlocksTokens.semanticColor.input.default.border}`}},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${theme.field.border.width.error} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder}},disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.disabled.placeholder},cursor:"not-allowed"}});var TextField$1 = React__namespace.forwardRef((props,ref)=>jsxRuntime.jsx(TextField,{...props,forwardedRef:ref}));
68
68
 
69
69
  const StyledSpan=wonderBlocksCore.addStyle("span");class FieldHeading extends React__namespace.Component{renderLabel(){const{label,id,required,testId}=this.props;const requiredIcon=jsxRuntime.jsxs(StyledSpan,{style:styles$1.required,"aria-hidden":true,children:[" ","*"]});return jsxRuntime.jsxs(React__namespace.Fragment,{children:[jsxRuntime.jsxs(wonderBlocksTypography.LabelMedium,{style:styles$1.label,tag:"label",htmlFor:id&&`${id}-field`,testId:testId&&`${testId}-label`,children:[label,required&&requiredIcon]}),jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.xxxSmall_4})]})}maybeRenderDescription(){const{description,testId}=this.props;if(!description){return null}return jsxRuntime.jsxs(React__namespace.Fragment,{children:[jsxRuntime.jsx(wonderBlocksTypography.LabelSmall,{style:styles$1.description,testId:testId&&`${testId}-description`,children:description}),jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.xxxSmall_4})]})}maybeRenderError(){const{error,id,testId}=this.props;if(!error){return null}return jsxRuntime.jsxs(React__namespace.Fragment,{children:[jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.small_12}),jsxRuntime.jsx(wonderBlocksTypography.LabelSmall,{style:styles$1.error,role:"alert",id:id&&`${id}-error`,testId:testId&&`${testId}-error`,children:error})]})}render(){const{field,style}=this.props;return jsxRuntime.jsxs(wonderBlocksCore.View,{style:style,children:[this.renderLabel(),this.maybeRenderDescription(),jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.xSmall_8}),field,this.maybeRenderError()]})}}const styles$1=aphrodite.StyleSheet.create({label:{color:wonderBlocksTokens.semanticColor.text.primary},description:{color:wonderBlocksTokens.semanticColor.text.secondary},error:{color:wonderBlocksTokens.semanticColor.status.critical.foreground},required:{color:wonderBlocksTokens.semanticColor.status.critical.foreground}});
70
70
 
71
71
  class LabeledTextField extends React__namespace.Component{render(){const{id,type,label,description,value,disabled,required,validate,onChange,onKeyDown,placeholder,style,testId,readOnly,autoComplete,forwardedRef,ariaDescribedby,name,onValidate,onFocus,onBlur,...otherProps}=this.props;return jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueId=>jsxRuntime.jsx(FieldHeading,{id:uniqueId,testId:testId,style:style,field:jsxRuntime.jsx(TextField$1,{id:`${uniqueId}-field`,"aria-describedby":ariaDescribedby?ariaDescribedby:`${uniqueId}-error`,"aria-required":required?"true":"false",required:required,testId:testId&&`${testId}-field`,type:type,value:value,placeholder:placeholder,disabled:disabled,validate:validate,onValidate:this.handleValidate,onChange:onChange,onKeyDown:onKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur,readOnly:readOnly,autoComplete:autoComplete,ref:forwardedRef,name:name,...otherProps}),label:label,description:description,required:!!required,error:!this.state.focused&&this.state.error||""})})}constructor(props){super(props),this.handleValidate=errorMessage=>{const{onValidate}=this.props;this.setState({error:errorMessage},()=>{if(onValidate){onValidate(errorMessage);}});},this.handleFocus=event=>{const{onFocus}=this.props;this.setState({focused:true},()=>{if(onFocus){onFocus(event);}});},this.handleBlur=event=>{const{onBlur}=this.props;this.setState({focused:false},()=>{if(onBlur){onBlur(event);}});};this.state={error:null,focused:false};}}LabeledTextField.defaultProps={type:"text",disabled:false};var labeledTextField = React__namespace.forwardRef((props,ref)=>jsxRuntime.jsx(LabeledTextField,{...props,forwardedRef:ref}));
72
72
 
73
- const StyledTextarea=wonderBlocksCore.addStyle("textarea");const TextArea=React__namespace.forwardRef(function TextArea(props,ref){const{onChange,value,placeholder,disabled,id,testId,style,readOnly,autoComplete,name,className,autoFocus,rows,spellCheck,wrap,minLength,maxLength,onClick,onKeyDown,onKeyUp,onFocus,onBlur,validate,onValidate,required,resizeType,rootStyle,error,instantValidation=true,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,disabled,validate,onValidate,required,instantValidation});const hasError=error||!!errorMessage;const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsxRuntime.jsx(wonderBlocksCore.View,{style:[{width:"100%"},rootStyle],children:jsxRuntime.jsx(StyledTextarea,{id:uniqueId,"data-testid":testId,ref:ref,className:className,style:[styles.textarea,wonderBlocksTypography.styles.LabelMedium,resizeType&&resizeStyles[resizeType],styles.default,!disabled&&styles.defaultFocus,disabled&&styles.disabled,hasError&&styles.error,style],value:value,onChange:handleChange,placeholder:placeholder,"aria-disabled":disabled,readOnly:readOnly||disabled,autoComplete:autoComplete,name:name,autoFocus:autoFocus,rows:rows,spellCheck:spellCheck,wrap:wrap,minLength:minLength,maxLength:maxLength,"aria-required":!!required,onClick:disabled?undefined:onClick,onKeyDown:disabled?undefined:onKeyDown,onKeyUp:disabled?undefined:onKeyUp,onFocus:onFocus,onBlur:handleBlur,required:!!required,...otherProps,"aria-invalid":hasError})})});const VERTICAL_SPACING_PX=10;const styles=aphrodite.StyleSheet.create({textarea:{borderRadius:wonderBlocksTokens.border.radius.radius_040,boxSizing:"border-box",padding:`${VERTICAL_SPACING_PX}px ${wonderBlocksTokens.spacing.medium_16}px`,minHeight:`calc(${VERTICAL_SPACING_PX*2+2}px + ${wonderBlocksTokens.font.lineHeight.medium})`},default:{background:wonderBlocksTokens.semanticColor.input.default.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.default.border}`,color:wonderBlocksTokens.semanticColor.input.default.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder}},defaultFocus:{":focus-visible":{borderColor:wonderBlocksTokens.semanticColor.focus.outer,outline:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-2}},disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.disabled.placeholder},cursor:"not-allowed",":focus-visible":{outline:`${wonderBlocksTokens.border.width.medium} solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-3}},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder},":focus-visible":{outline:`${wonderBlocksTokens.border.width.medium} solid ${wonderBlocksTokens.semanticColor.focus.outer}`,borderColor:wonderBlocksTokens.semanticColor.input.error.border}}});const resizeStyles=aphrodite.StyleSheet.create({both:{resize:"both"},none:{resize:"none"},horizontal:{resize:"horizontal"},vertical:{resize:"vertical"}});
73
+ const StyledTextarea=wonderBlocksCore.addStyle("textarea");const TextArea=React__namespace.forwardRef(function TextArea(props,ref){const{onChange,value,placeholder,disabled,id,testId,style,readOnly,autoComplete,name,className,autoFocus,rows,spellCheck,wrap,minLength,maxLength,onClick,onKeyDown,onKeyUp,onFocus,onBlur,validate,onValidate,required,resizeType,rootStyle,error,instantValidation=true,...otherProps}=props;const{errorMessage,onBlurValidation,onChangeValidation}=useFieldValidation({value,disabled,validate,onValidate,required,instantValidation});const hasError=error||!!errorMessage;const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const handleChange=event=>{const newValue=event.target.value;onChangeValidation(newValue);onChange(newValue);};const handleBlur=event=>{onBlurValidation(event.target.value);if(onBlur){onBlur(event);}};return jsxRuntime.jsx(wonderBlocksCore.View,{style:[{width:"100%"},rootStyle],children:jsxRuntime.jsx(StyledTextarea,{id:uniqueId,"data-testid":testId,ref:ref,className:className,style:[styles.textarea,wonderBlocksTypography.styles.BodyTextMediumMediumWeight,resizeType&&resizeStyles[resizeType],styles.default,disabled&&styles.disabled,hasError&&styles.error,readOnly&&styles.readOnly,style],value:value,onChange:handleChange,placeholder:placeholder,"aria-disabled":disabled,readOnly:readOnly||disabled,autoComplete:autoComplete,name:name,autoFocus:autoFocus,rows:rows,spellCheck:spellCheck,wrap:wrap,minLength:minLength,maxLength:maxLength,"aria-required":!!required,onClick:disabled?undefined:onClick,onKeyDown:disabled?undefined:onKeyDown,onKeyUp:disabled?undefined:onKeyUp,onFocus:onFocus,onBlur:handleBlur,required:!!required,...otherProps,"aria-invalid":hasError})})});const styles=aphrodite.StyleSheet.create({textarea:{borderRadius:theme.field.border.radius,boxSizing:"border-box",paddingInline:theme.field.layout.paddingInline,paddingBlock:theme.field.layout.paddingBlock,minHeight:theme.field.sizing.height},readOnly:{background:wonderBlocksTokens.semanticColor.input.readOnly.background,color:wonderBlocksTokens.semanticColor.input.readOnly.text},default:{background:wonderBlocksTokens.semanticColor.input.default.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.default.border}`,color:wonderBlocksTokens.semanticColor.input.default.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder},...wonderBlocksStyles.focusStyles.focus,[":active:not([aria-disabled='true']):not([readonly])"]:{boxShadow:`0 0 0 ${theme.field.border.width.press} ${wonderBlocksTokens.semanticColor.input.default.border}`}},disabled:{background:wonderBlocksTokens.semanticColor.input.disabled.background,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.input.disabled.border}`,color:wonderBlocksTokens.semanticColor.input.disabled.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.disabled.placeholder},cursor:"not-allowed"},error:{background:wonderBlocksTokens.semanticColor.input.error.background,border:`${theme.field.border.width.error} solid ${wonderBlocksTokens.semanticColor.input.error.border}`,color:wonderBlocksTokens.semanticColor.input.error.foreground,"::placeholder":{color:wonderBlocksTokens.semanticColor.input.default.placeholder}}});const resizeStyles=aphrodite.StyleSheet.create({both:{resize:"both"},none:{resize:"none"},horizontal:{resize:"horizontal"},vertical:{resize:"vertical"}});
74
74
 
75
75
  exports.Checkbox = Checkbox;
76
76
  exports.CheckboxGroup = CheckboxGroup;
@@ -7,5 +7,21 @@ declare const _default: {
7
7
  };
8
8
  };
9
9
  };
10
+ field: {
11
+ border: {
12
+ radius: string;
13
+ width: {
14
+ error: string;
15
+ press: string;
16
+ };
17
+ };
18
+ sizing: {
19
+ height: string;
20
+ };
21
+ layout: {
22
+ paddingBlock: string;
23
+ paddingInline: string;
24
+ };
25
+ };
10
26
  };
11
27
  export default _default;
@@ -7,5 +7,21 @@ declare const _default: {
7
7
  };
8
8
  };
9
9
  };
10
+ field: {
11
+ border: {
12
+ radius: string;
13
+ width: {
14
+ error: string;
15
+ press: string;
16
+ };
17
+ };
18
+ sizing: {
19
+ height: string;
20
+ };
21
+ layout: {
22
+ paddingBlock: string;
23
+ paddingInline: string;
24
+ };
25
+ };
10
26
  };
11
27
  export default _default;
@@ -7,5 +7,21 @@ declare const _default: {
7
7
  };
8
8
  };
9
9
  };
10
+ field: {
11
+ border: {
12
+ radius: string;
13
+ width: {
14
+ error: string;
15
+ press: string;
16
+ };
17
+ };
18
+ sizing: {
19
+ height: string;
20
+ };
21
+ layout: {
22
+ paddingBlock: string;
23
+ paddingInline: string;
24
+ };
25
+ };
10
26
  };
11
27
  export default _default;
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-form",
3
- "version": "7.2.0",
3
+ "version": "7.2.1",
4
4
  "design": "v1",
5
5
  "description": "Form components for Wonder Blocks.",
6
- "main": "dist/index.js",
7
- "module": "dist/es/index.js",
8
- "types": "dist/index.d.ts",
9
6
  "exports": {
10
7
  ".": {
11
8
  "import": "./dist/es/index.js",
@@ -14,18 +11,21 @@
14
11
  },
15
12
  "./styles.css": "./dist/css/vars.css"
16
13
  },
14
+ "main": "dist/index.js",
15
+ "module": "dist/es/index.js",
16
+ "types": "dist/index.d.ts",
17
17
  "author": "",
18
18
  "license": "MIT",
19
19
  "publishConfig": {
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@khanacademy/wonder-blocks-clickable": "7.1.13",
23
+ "@khanacademy/wonder-blocks-clickable": "7.1.14",
24
24
  "@khanacademy/wonder-blocks-core": "12.3.0",
25
- "@khanacademy/wonder-blocks-icon": "5.2.7",
26
- "@khanacademy/wonder-blocks-layout": "3.1.24",
27
- "@khanacademy/wonder-blocks-tokens": "11.2.2",
28
- "@khanacademy/wonder-blocks-typography": "4.2.9"
25
+ "@khanacademy/wonder-blocks-icon": "5.2.8",
26
+ "@khanacademy/wonder-blocks-layout": "3.1.25",
27
+ "@khanacademy/wonder-blocks-tokens": "11.3.0",
28
+ "@khanacademy/wonder-blocks-typography": "4.2.10"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@phosphor-icons/core": "^2.0.2",