@servicetitan/form 38.6.1 → 38.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,13 +6,13 @@ const cultures = {
6
6
  nanp: {
7
7
  PhoneFormat: {
8
8
  SimplePhoneMask: '(999) 999-9999?',
9
- SimplePhonePlaceholder: '(___) ___-____'
9
+ SampleSimplePhoneNumber: '(123) 456-7890'
10
10
  }
11
11
  },
12
12
  au: {
13
13
  PhoneFormat: {
14
14
  SimplePhoneMask: '99 9999 9999',
15
- SimplePhonePlaceholder: '__ ____ ____'
15
+ SampleSimplePhoneNumber: '04 1234 5678'
16
16
  }
17
17
  }
18
18
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/demo/phone-number-input-a2.tsx"],"sourcesContent":["import { ChangeEvent, FC, useState } from 'react';\n\nimport { observer } from 'mobx-react';\n\nimport { Culture } from '@servicetitan/culture';\n\nimport { PhoneNumberInputA2 } from '..';\n\ntype CultureKey = 'nanp' | 'au';\n\nconst cultures: Record<CultureKey, Culture> = {\n nanp: {\n PhoneFormat: {\n SimplePhoneMask: '(999) 999-9999?',\n SimplePhonePlaceholder: '(___) ___-____',\n },\n } as Culture,\n au: {\n PhoneFormat: {\n SimplePhoneMask: '99 9999 9999',\n SimplePhonePlaceholder: '__ ____ ____',\n },\n } as Culture,\n};\n\nexport const PhoneNumberInputA2Example: FC = observer(() => {\n const [value, setValue] = useState('');\n const [cultureKey, setCultureKey] = useState<CultureKey>('nanp');\n const [sip, setSip] = useState(false);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n };\n\n const handleCultureChange = (e: ChangeEvent<HTMLInputElement>) => {\n setCultureKey(e.target.value as CultureKey);\n setValue('');\n };\n\n return (\n <div>\n <fieldset>\n <legend>Region</legend>\n <label>\n <input\n type=\"radio\"\n name=\"culture\"\n value=\"nanp\"\n checked={cultureKey === 'nanp'}\n onChange={handleCultureChange}\n />\n US/Canada (NANP)\n </label>\n <label style={{ marginLeft: 16 }}>\n <input\n type=\"radio\"\n name=\"culture\"\n value=\"au\"\n checked={cultureKey === 'au'}\n onChange={handleCultureChange}\n />\n Australia\n </label>\n </fieldset>\n <br />\n <label>\n <input\n type=\"checkbox\"\n checked={sip}\n onChange={e => {\n setSip(e.target.checked);\n setValue('');\n }}\n />\n SIP\n </label>\n <br />\n <br />\n <PhoneNumberInputA2\n culture={cultures[cultureKey]}\n label=\"Phone\"\n value={value}\n onChange={handleChange}\n sip={sip}\n />\n <p>Returned value: {value}</p>\n </div>\n );\n});\n"],"names":["useState","observer","PhoneNumberInputA2","cultures","nanp","PhoneFormat","SimplePhoneMask","SimplePhonePlaceholder","au","PhoneNumberInputA2Example","value","setValue","cultureKey","setCultureKey","sip","setSip","handleChange","e","target","handleCultureChange","div","fieldset","legend","label","input","type","name","checked","onChange","style","marginLeft","br","culture","p"],"mappings":";AAAA,SAA0BA,QAAQ,QAAQ,QAAQ;AAElD,SAASC,QAAQ,QAAQ,aAAa;AAItC,SAASC,kBAAkB,QAAQ,KAAK;AAIxC,MAAMC,WAAwC;IAC1CC,MAAM;QACFC,aAAa;YACTC,iBAAiB;YACjBC,wBAAwB;QAC5B;IACJ;IACAC,IAAI;QACAH,aAAa;YACTC,iBAAiB;YACjBC,wBAAwB;QAC5B;IACJ;AACJ;AAEA,OAAO,MAAME,4BAAgCR,SAAS;IAClD,MAAM,CAACS,OAAOC,SAAS,GAAGX,SAAS;IACnC,MAAM,CAACY,YAAYC,cAAc,GAAGb,SAAqB;IACzD,MAAM,CAACc,KAAKC,OAAO,GAAGf,SAAS;IAE/B,MAAMgB,eAAe,CAACC;QAClBN,SAASM,EAAEC,MAAM,CAACR,KAAK;IAC3B;IAEA,MAAMS,sBAAsB,CAACF;QACzBJ,cAAcI,EAAEC,MAAM,CAACR,KAAK;QAC5BC,SAAS;IACb;IAEA,qBACI,MAACS;;0BACG,MAACC;;kCACG,KAACC;kCAAO;;kCACR,MAACC;;0CACG,KAACC;gCACGC,MAAK;gCACLC,MAAK;gCACLhB,OAAM;gCACNiB,SAASf,eAAe;gCACxBgB,UAAUT;;4BACZ;;;kCAGN,MAACI;wBAAMM,OAAO;4BAAEC,YAAY;wBAAG;;0CAC3B,KAACN;gCACGC,MAAK;gCACLC,MAAK;gCACLhB,OAAM;gCACNiB,SAASf,eAAe;gCACxBgB,UAAUT;;4BACZ;;;;;0BAIV,KAACY;0BACD,MAACR;;kCACG,KAACC;wBACGC,MAAK;wBACLE,SAASb;wBACTc,UAAUX,CAAAA;4BACNF,OAAOE,EAAEC,MAAM,CAACS,OAAO;4BACvBhB,SAAS;wBACb;;oBACF;;;0BAGN,KAACoB;0BACD,KAACA;0BACD,KAAC7B;gBACG8B,SAAS7B,QAAQ,CAACS,WAAW;gBAC7BW,OAAM;gBACNb,OAAOA;gBACPkB,UAAUZ;gBACVF,KAAKA;;0BAET,MAACmB;;oBAAE;oBAAiBvB;;;;;AAGhC,GAAG"}
1
+ {"version":3,"sources":["../../src/demo/phone-number-input-a2.tsx"],"sourcesContent":["import { ChangeEvent, FC, useState } from 'react';\n\nimport { observer } from 'mobx-react';\n\nimport { Culture } from '@servicetitan/culture';\n\nimport { PhoneNumberInputA2 } from '..';\n\ntype CultureKey = 'nanp' | 'au';\n\nconst cultures: Record<CultureKey, Culture> = {\n nanp: {\n PhoneFormat: {\n SimplePhoneMask: '(999) 999-9999?',\n SampleSimplePhoneNumber: '(123) 456-7890',\n },\n } as Culture,\n au: {\n PhoneFormat: {\n SimplePhoneMask: '99 9999 9999',\n SampleSimplePhoneNumber: '04 1234 5678',\n },\n } as Culture,\n};\n\nexport const PhoneNumberInputA2Example: FC = observer(() => {\n const [value, setValue] = useState('');\n const [cultureKey, setCultureKey] = useState<CultureKey>('nanp');\n const [sip, setSip] = useState(false);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n };\n\n const handleCultureChange = (e: ChangeEvent<HTMLInputElement>) => {\n setCultureKey(e.target.value as CultureKey);\n setValue('');\n };\n\n return (\n <div>\n <fieldset>\n <legend>Region</legend>\n <label>\n <input\n type=\"radio\"\n name=\"culture\"\n value=\"nanp\"\n checked={cultureKey === 'nanp'}\n onChange={handleCultureChange}\n />\n US/Canada (NANP)\n </label>\n <label style={{ marginLeft: 16 }}>\n <input\n type=\"radio\"\n name=\"culture\"\n value=\"au\"\n checked={cultureKey === 'au'}\n onChange={handleCultureChange}\n />\n Australia\n </label>\n </fieldset>\n <br />\n <label>\n <input\n type=\"checkbox\"\n checked={sip}\n onChange={e => {\n setSip(e.target.checked);\n setValue('');\n }}\n />\n SIP\n </label>\n <br />\n <br />\n <PhoneNumberInputA2\n culture={cultures[cultureKey]}\n label=\"Phone\"\n value={value}\n onChange={handleChange}\n sip={sip}\n />\n <p>Returned value: {value}</p>\n </div>\n );\n});\n"],"names":["useState","observer","PhoneNumberInputA2","cultures","nanp","PhoneFormat","SimplePhoneMask","SampleSimplePhoneNumber","au","PhoneNumberInputA2Example","value","setValue","cultureKey","setCultureKey","sip","setSip","handleChange","e","target","handleCultureChange","div","fieldset","legend","label","input","type","name","checked","onChange","style","marginLeft","br","culture","p"],"mappings":";AAAA,SAA0BA,QAAQ,QAAQ,QAAQ;AAElD,SAASC,QAAQ,QAAQ,aAAa;AAItC,SAASC,kBAAkB,QAAQ,KAAK;AAIxC,MAAMC,WAAwC;IAC1CC,MAAM;QACFC,aAAa;YACTC,iBAAiB;YACjBC,yBAAyB;QAC7B;IACJ;IACAC,IAAI;QACAH,aAAa;YACTC,iBAAiB;YACjBC,yBAAyB;QAC7B;IACJ;AACJ;AAEA,OAAO,MAAME,4BAAgCR,SAAS;IAClD,MAAM,CAACS,OAAOC,SAAS,GAAGX,SAAS;IACnC,MAAM,CAACY,YAAYC,cAAc,GAAGb,SAAqB;IACzD,MAAM,CAACc,KAAKC,OAAO,GAAGf,SAAS;IAE/B,MAAMgB,eAAe,CAACC;QAClBN,SAASM,EAAEC,MAAM,CAACR,KAAK;IAC3B;IAEA,MAAMS,sBAAsB,CAACF;QACzBJ,cAAcI,EAAEC,MAAM,CAACR,KAAK;QAC5BC,SAAS;IACb;IAEA,qBACI,MAACS;;0BACG,MAACC;;kCACG,KAACC;kCAAO;;kCACR,MAACC;;0CACG,KAACC;gCACGC,MAAK;gCACLC,MAAK;gCACLhB,OAAM;gCACNiB,SAASf,eAAe;gCACxBgB,UAAUT;;4BACZ;;;kCAGN,MAACI;wBAAMM,OAAO;4BAAEC,YAAY;wBAAG;;0CAC3B,KAACN;gCACGC,MAAK;gCACLC,MAAK;gCACLhB,OAAM;gCACNiB,SAASf,eAAe;gCACxBgB,UAAUT;;4BACZ;;;;;0BAIV,KAACY;0BACD,MAACR;;kCACG,KAACC;wBACGC,MAAK;wBACLE,SAASb;wBACTc,UAAUX,CAAAA;4BACNF,OAAOE,EAAEC,MAAM,CAACS,OAAO;4BACvBhB,SAAS;wBACb;;oBACF;;;0BAGN,KAACoB;0BACD,KAACA;0BACD,KAAC7B;gBACG8B,SAAS7B,QAAQ,CAACS,WAAW;gBAC7BW,OAAM;gBACNb,OAAOA;gBACPkB,UAAUZ;gBACVF,KAAKA;;0BAET,MAACmB;;oBAAE;oBAAiBvB;;;;;AAGhC,GAAG"}
@@ -9,9 +9,9 @@ export const PhoneNumberInputA2 = (props)=>{
9
9
  const { value, onChange, placeholder: propPlaceholder, culture: propCulture, sip, onFocus, onBlur, disabled, readOnly, ...restProps } = props;
10
10
  const [injectedCulture] = useOptionalDependencies(CULTURE_TOKEN);
11
11
  const culture = propCulture !== null && propCulture !== void 0 ? propCulture : injectedCulture;
12
- const { SimplePhoneMask = '?9999999999', SimplePhonePlaceholder = '' } = (_ref = culture === null || culture === void 0 ? void 0 : culture.PhoneFormat) !== null && _ref !== void 0 ? _ref : {};
12
+ const { SimplePhoneMask = '?9999999999', SampleSimplePhoneNumber = '' } = (_ref = culture === null || culture === void 0 ? void 0 : culture.PhoneFormat) !== null && _ref !== void 0 ? _ref : {};
13
13
  const mask = SimplePhoneMask.replace(/\?/g, '');
14
- const placeholder = propPlaceholder !== null && propPlaceholder !== void 0 ? propPlaceholder : SimplePhonePlaceholder;
14
+ const placeholder = propPlaceholder !== null && propPlaceholder !== void 0 ? propPlaceholder : SampleSimplePhoneNumber;
15
15
  const displayValue = String(value !== null && value !== void 0 ? value : '').replace(/\D/g, '');
16
16
  // Transform output value to digits-only (unmasked)
17
17
  const handleChange = useCallback((event)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/phone-number-input/phone-number-input-a2.tsx"],"sourcesContent":["import { ChangeEvent, FC, useCallback } from 'react';\nimport ReactInputMask from 'react-input-mask';\n\nimport { TextField, TextFieldProps } from '@servicetitan/anvil2';\nimport { Culture, CULTURE_TOKEN } from '@servicetitan/culture';\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\n\ntype PhoneNumberInputA2Props = TextFieldProps & {\n sip?: boolean;\n culture?: Culture;\n};\n\nexport const PhoneNumberInputA2: FC<PhoneNumberInputA2Props> = props => {\n const {\n value,\n onChange,\n placeholder: propPlaceholder,\n culture: propCulture,\n sip,\n onFocus,\n onBlur,\n disabled,\n readOnly,\n ...restProps\n } = props;\n\n const [injectedCulture] = useOptionalDependencies(CULTURE_TOKEN);\n const culture = propCulture ?? injectedCulture;\n const { SimplePhoneMask = '?9999999999', SimplePhonePlaceholder = '' } =\n culture?.PhoneFormat ?? {};\n\n const mask = SimplePhoneMask.replace(/\\?/g, '');\n const placeholder = propPlaceholder ?? SimplePhonePlaceholder;\n const displayValue = String(value ?? '').replace(/\\D/g, '');\n\n // Transform output value to digits-only (unmasked)\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n const digitsOnly = event.target.value.replace(/\\D/g, '');\n\n const unmaskedEvent = {\n ...event,\n target: { ...event.target, value: digitsOnly },\n currentTarget: { ...event.currentTarget, value: digitsOnly },\n } as ChangeEvent<HTMLInputElement>;\n\n onChange(unmaskedEvent);\n }\n },\n [onChange]\n );\n\n if (sip) {\n return (\n <TextField\n {...restProps}\n value={value}\n onChange={onChange}\n onFocus={onFocus}\n onBlur={onBlur}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n placeholder={propPlaceholder}\n />\n );\n }\n\n const renderTextField = (inputProps: Record<string, unknown>) => {\n // Exclude 'size' as it conflicts with TextField's size prop type\n const { size: UNUSED_SIZE, ...filteredProps } = inputProps;\n return <TextField {...filteredProps} {...restProps} type=\"tel\" placeholder={placeholder} />;\n };\n\n return (\n <ReactInputMask\n value={displayValue}\n onChange={handleChange}\n mask={mask}\n maskChar={null}\n onFocus={onFocus}\n onBlur={onBlur}\n disabled={disabled}\n readOnly={readOnly}\n >\n {renderTextField as any}\n </ReactInputMask>\n );\n};\n"],"names":["useCallback","ReactInputMask","TextField","CULTURE_TOKEN","useOptionalDependencies","PhoneNumberInputA2","props","value","onChange","placeholder","propPlaceholder","culture","propCulture","sip","onFocus","onBlur","disabled","readOnly","restProps","injectedCulture","SimplePhoneMask","SimplePhonePlaceholder","PhoneFormat","mask","replace","displayValue","String","handleChange","event","digitsOnly","target","unmaskedEvent","currentTarget","type","renderTextField","inputProps","size","UNUSED_SIZE","filteredProps","maskChar"],"mappings":";AAAA,SAA0BA,WAAW,QAAQ,QAAQ;AACrD,OAAOC,oBAAoB,mBAAmB;AAE9C,SAASC,SAAS,QAAwB,uBAAuB;AACjE,SAAkBC,aAAa,QAAQ,wBAAwB;AAC/D,SAASC,uBAAuB,QAAQ,0BAA0B;AAOlE,OAAO,MAAMC,qBAAkDC,CAAAA;;IAC3D,MAAM,EACFC,KAAK,EACLC,QAAQ,EACRC,aAAaC,eAAe,EAC5BC,SAASC,WAAW,EACpBC,GAAG,EACHC,OAAO,EACPC,MAAM,EACNC,QAAQ,EACRC,QAAQ,EACR,GAAGC,WACN,GAAGZ;IAEJ,MAAM,CAACa,gBAAgB,GAAGf,wBAAwBD;IAClD,MAAMQ,UAAUC,wBAAAA,yBAAAA,cAAeO;IAC/B,MAAM,EAAEC,kBAAkB,aAAa,EAAEC,yBAAyB,EAAE,EAAE,WAClEV,oBAAAA,8BAAAA,QAASW,WAAW,uCAAI,CAAC;IAE7B,MAAMC,OAAOH,gBAAgBI,OAAO,CAAC,OAAO;IAC5C,MAAMf,cAAcC,4BAAAA,6BAAAA,kBAAmBW;IACvC,MAAMI,eAAeC,OAAOnB,kBAAAA,mBAAAA,QAAS,IAAIiB,OAAO,CAAC,OAAO;IAExD,mDAAmD;IACnD,MAAMG,eAAe3B,YACjB,CAAC4B;QACG,IAAIpB,UAAU;YACV,MAAMqB,aAAaD,MAAME,MAAM,CAACvB,KAAK,CAACiB,OAAO,CAAC,OAAO;YAErD,MAAMO,gBAAgB;gBAClB,GAAGH,KAAK;gBACRE,QAAQ;oBAAE,GAAGF,MAAME,MAAM;oBAAEvB,OAAOsB;gBAAW;gBAC7CG,eAAe;oBAAE,GAAGJ,MAAMI,aAAa;oBAAEzB,OAAOsB;gBAAW;YAC/D;YAEArB,SAASuB;QACb;IACJ,GACA;QAACvB;KAAS;IAGd,IAAIK,KAAK;QACL,qBACI,KAACX;YACI,GAAGgB,SAAS;YACbX,OAAOA;YACPC,UAAUA;YACVM,SAASA;YACTC,QAAQA;YACRC,UAAUA;YACVC,UAAUA;YACVgB,MAAK;YACLxB,aAAaC;;IAGzB;IAEA,MAAMwB,kBAAkB,CAACC;QACrB,iEAAiE;QACjE,MAAM,EAAEC,MAAMC,WAAW,EAAE,GAAGC,eAAe,GAAGH;QAChD,qBAAO,KAACjC;YAAW,GAAGoC,aAAa;YAAG,GAAGpB,SAAS;YAAEe,MAAK;YAAMxB,aAAaA;;IAChF;IAEA,qBACI,KAACR;QACGM,OAAOkB;QACPjB,UAAUmB;QACVJ,MAAMA;QACNgB,UAAU;QACVzB,SAASA;QACTC,QAAQA;QACRC,UAAUA;QACVC,UAAUA;kBAETiB;;AAGb,EAAE"}
1
+ {"version":3,"sources":["../../src/phone-number-input/phone-number-input-a2.tsx"],"sourcesContent":["import { ChangeEvent, FC, useCallback } from 'react';\nimport ReactInputMask from 'react-input-mask';\n\nimport { TextField, TextFieldProps } from '@servicetitan/anvil2';\nimport { Culture, CULTURE_TOKEN } from '@servicetitan/culture';\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\n\ntype PhoneNumberInputA2Props = TextFieldProps & {\n sip?: boolean;\n culture?: Culture;\n};\n\nexport const PhoneNumberInputA2: FC<PhoneNumberInputA2Props> = props => {\n const {\n value,\n onChange,\n placeholder: propPlaceholder,\n culture: propCulture,\n sip,\n onFocus,\n onBlur,\n disabled,\n readOnly,\n ...restProps\n } = props;\n\n const [injectedCulture] = useOptionalDependencies(CULTURE_TOKEN);\n const culture = propCulture ?? injectedCulture;\n const { SimplePhoneMask = '?9999999999', SampleSimplePhoneNumber = '' } =\n culture?.PhoneFormat ?? {};\n\n const mask = SimplePhoneMask.replace(/\\?/g, '');\n const placeholder = propPlaceholder ?? SampleSimplePhoneNumber;\n const displayValue = String(value ?? '').replace(/\\D/g, '');\n\n // Transform output value to digits-only (unmasked)\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n const digitsOnly = event.target.value.replace(/\\D/g, '');\n\n const unmaskedEvent = {\n ...event,\n target: { ...event.target, value: digitsOnly },\n currentTarget: { ...event.currentTarget, value: digitsOnly },\n } as ChangeEvent<HTMLInputElement>;\n\n onChange(unmaskedEvent);\n }\n },\n [onChange]\n );\n\n if (sip) {\n return (\n <TextField\n {...restProps}\n value={value}\n onChange={onChange}\n onFocus={onFocus}\n onBlur={onBlur}\n disabled={disabled}\n readOnly={readOnly}\n type=\"text\"\n placeholder={propPlaceholder}\n />\n );\n }\n\n const renderTextField = (inputProps: Record<string, unknown>) => {\n // Exclude 'size' as it conflicts with TextField's size prop type\n const { size: UNUSED_SIZE, ...filteredProps } = inputProps;\n return <TextField {...filteredProps} {...restProps} type=\"tel\" placeholder={placeholder} />;\n };\n\n return (\n <ReactInputMask\n value={displayValue}\n onChange={handleChange}\n mask={mask}\n maskChar={null}\n onFocus={onFocus}\n onBlur={onBlur}\n disabled={disabled}\n readOnly={readOnly}\n >\n {renderTextField as any}\n </ReactInputMask>\n );\n};\n"],"names":["useCallback","ReactInputMask","TextField","CULTURE_TOKEN","useOptionalDependencies","PhoneNumberInputA2","props","value","onChange","placeholder","propPlaceholder","culture","propCulture","sip","onFocus","onBlur","disabled","readOnly","restProps","injectedCulture","SimplePhoneMask","SampleSimplePhoneNumber","PhoneFormat","mask","replace","displayValue","String","handleChange","event","digitsOnly","target","unmaskedEvent","currentTarget","type","renderTextField","inputProps","size","UNUSED_SIZE","filteredProps","maskChar"],"mappings":";AAAA,SAA0BA,WAAW,QAAQ,QAAQ;AACrD,OAAOC,oBAAoB,mBAAmB;AAE9C,SAASC,SAAS,QAAwB,uBAAuB;AACjE,SAAkBC,aAAa,QAAQ,wBAAwB;AAC/D,SAASC,uBAAuB,QAAQ,0BAA0B;AAOlE,OAAO,MAAMC,qBAAkDC,CAAAA;;IAC3D,MAAM,EACFC,KAAK,EACLC,QAAQ,EACRC,aAAaC,eAAe,EAC5BC,SAASC,WAAW,EACpBC,GAAG,EACHC,OAAO,EACPC,MAAM,EACNC,QAAQ,EACRC,QAAQ,EACR,GAAGC,WACN,GAAGZ;IAEJ,MAAM,CAACa,gBAAgB,GAAGf,wBAAwBD;IAClD,MAAMQ,UAAUC,wBAAAA,yBAAAA,cAAeO;IAC/B,MAAM,EAAEC,kBAAkB,aAAa,EAAEC,0BAA0B,EAAE,EAAE,WACnEV,oBAAAA,8BAAAA,QAASW,WAAW,uCAAI,CAAC;IAE7B,MAAMC,OAAOH,gBAAgBI,OAAO,CAAC,OAAO;IAC5C,MAAMf,cAAcC,4BAAAA,6BAAAA,kBAAmBW;IACvC,MAAMI,eAAeC,OAAOnB,kBAAAA,mBAAAA,QAAS,IAAIiB,OAAO,CAAC,OAAO;IAExD,mDAAmD;IACnD,MAAMG,eAAe3B,YACjB,CAAC4B;QACG,IAAIpB,UAAU;YACV,MAAMqB,aAAaD,MAAME,MAAM,CAACvB,KAAK,CAACiB,OAAO,CAAC,OAAO;YAErD,MAAMO,gBAAgB;gBAClB,GAAGH,KAAK;gBACRE,QAAQ;oBAAE,GAAGF,MAAME,MAAM;oBAAEvB,OAAOsB;gBAAW;gBAC7CG,eAAe;oBAAE,GAAGJ,MAAMI,aAAa;oBAAEzB,OAAOsB;gBAAW;YAC/D;YAEArB,SAASuB;QACb;IACJ,GACA;QAACvB;KAAS;IAGd,IAAIK,KAAK;QACL,qBACI,KAACX;YACI,GAAGgB,SAAS;YACbX,OAAOA;YACPC,UAAUA;YACVM,SAASA;YACTC,QAAQA;YACRC,UAAUA;YACVC,UAAUA;YACVgB,MAAK;YACLxB,aAAaC;;IAGzB;IAEA,MAAMwB,kBAAkB,CAACC;QACrB,iEAAiE;QACjE,MAAM,EAAEC,MAAMC,WAAW,EAAE,GAAGC,eAAe,GAAGH;QAChD,qBAAO,KAACjC;YAAW,GAAGoC,aAAa;YAAG,GAAGpB,SAAS;YAAEe,MAAK;YAAMxB,aAAaA;;IAChF;IAEA,qBACI,KAACR;QACGM,OAAOkB;QACPjB,UAAUmB;QACVJ,MAAMA;QACNgB,UAAU;QACVzB,SAASA;QACTC,QAAQA;QACRC,UAAUA;QACVC,UAAUA;kBAETiB;;AAGb,EAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/form",
3
- "version": "38.6.1",
3
+ "version": "38.7.0",
4
4
  "description": "",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/form",
6
6
  "repository": {
@@ -18,10 +18,10 @@
18
18
  "devDependencies": {
19
19
  "@progress/kendo-react-dateinputs": "~5.5.0",
20
20
  "@servicetitan/anvil2": "^2.0.1",
21
- "@servicetitan/confirm": "^38.6.1",
22
- "@servicetitan/culture": "^38.6.1",
21
+ "@servicetitan/confirm": "^38.7.0",
22
+ "@servicetitan/culture": "^38.7.0",
23
23
  "@servicetitan/design-system": "~14.5.1",
24
- "@servicetitan/form-state": "^38.6.1",
24
+ "@servicetitan/form-state": "^38.7.0",
25
25
  "@servicetitan/hash-browser-router": "^34.2.0",
26
26
  "@servicetitan/react-ioc": "^34.2.0",
27
27
  "@servicetitan/tokens": ">=12.2.1",
@@ -43,10 +43,10 @@
43
43
  "peerDependencies": {
44
44
  "@progress/kendo-react-dateinputs": "~5.5.0",
45
45
  "@servicetitan/anvil2": ">=1.42.0",
46
- "@servicetitan/confirm": "^38.6.1",
47
- "@servicetitan/culture": "^38.6.1",
46
+ "@servicetitan/confirm": "^38.7.0",
47
+ "@servicetitan/culture": "^38.7.0",
48
48
  "@servicetitan/design-system": ">=13.2.1",
49
- "@servicetitan/form-state": "^38.6.1",
49
+ "@servicetitan/form-state": "^38.7.0",
50
50
  "@servicetitan/react-ioc": ">21.0.0",
51
51
  "@servicetitan/tokens": ">=12.2.1",
52
52
  "accounting": "~0.4.1",
@@ -71,5 +71,5 @@
71
71
  "less": true,
72
72
  "webpack": false
73
73
  },
74
- "gitHead": "fcd96d8dd56219340083a3c8a181c10a81da48ae"
74
+ "gitHead": "294a6fa2cafd00b82d6a7e0f5f9bea6acab9b2b6"
75
75
  }
@@ -12,13 +12,13 @@ const cultures: Record<CultureKey, Culture> = {
12
12
  nanp: {
13
13
  PhoneFormat: {
14
14
  SimplePhoneMask: '(999) 999-9999?',
15
- SimplePhonePlaceholder: '(___) ___-____',
15
+ SampleSimplePhoneNumber: '(123) 456-7890',
16
16
  },
17
17
  } as Culture,
18
18
  au: {
19
19
  PhoneFormat: {
20
20
  SimplePhoneMask: '99 9999 9999',
21
- SimplePhonePlaceholder: '__ ____ ____',
21
+ SampleSimplePhoneNumber: '04 1234 5678',
22
22
  },
23
23
  } as Culture,
24
24
  };
@@ -48,7 +48,6 @@ jest.mock('react-input-mask', () => {
48
48
  return createElement('input', inputProps);
49
49
  },
50
50
  };
51
- // eslint-disable-next-line @typescript-eslint/naming-convention
52
51
  mod.__esModule = true;
53
52
  return mod;
54
53
  });
@@ -58,14 +57,14 @@ import { PhoneNumberInputA2 } from '../phone-number-input-a2';
58
57
  const nanpCulture = {
59
58
  PhoneFormat: {
60
59
  SimplePhoneMask: '(999) 999-9999?',
61
- SimplePhonePlaceholder: '(___) ___-____',
60
+ SampleSimplePhoneNumber: '(123) 456-7890',
62
61
  },
63
62
  } as Culture;
64
63
 
65
64
  const auCulture = {
66
65
  PhoneFormat: {
67
66
  SimplePhoneMask: '99 9999 9999',
68
- SimplePhonePlaceholder: '__ ____ ____',
67
+ SampleSimplePhoneNumber: '04 1234 5678',
69
68
  },
70
69
  } as Culture;
71
70
 
@@ -82,7 +81,7 @@ describe('PhoneNumberInputA2', () => {
82
81
  render(<PhoneNumberInputA2 culture={nanpCulture} value="" onChange={jest.fn()} />);
83
82
 
84
83
  const input = screen.getByRole('textbox');
85
- expect(input).toHaveAttribute('placeholder', '(___) ___-____');
84
+ expect(input).toHaveAttribute('placeholder', '(123) 456-7890');
86
85
  });
87
86
 
88
87
  it('uses DI culture when no culture prop is provided', () => {
@@ -91,7 +90,7 @@ describe('PhoneNumberInputA2', () => {
91
90
  render(<PhoneNumberInputA2 value="" onChange={jest.fn()} />);
92
91
 
93
92
  const input = screen.getByRole('textbox');
94
- expect(input).toHaveAttribute('placeholder', '__ ____ ____');
93
+ expect(input).toHaveAttribute('placeholder', '04 1234 5678');
95
94
  });
96
95
 
97
96
  it('uses fallback mask when no culture is available', () => {
@@ -106,7 +105,27 @@ describe('PhoneNumberInputA2', () => {
106
105
  });
107
106
 
108
107
  describe('placeholder', () => {
109
- it('uses explicit placeholder prop over culture placeholder', () => {
108
+ it('renders empty placeholder when SampleSimplePhoneNumber is empty', () => {
109
+ const cultureWithEmptySample = {
110
+ PhoneFormat: {
111
+ SimplePhoneMask: '(999) 999-9999?',
112
+ SampleSimplePhoneNumber: '',
113
+ },
114
+ } as Culture;
115
+
116
+ render(
117
+ <PhoneNumberInputA2
118
+ culture={cultureWithEmptySample}
119
+ value=""
120
+ onChange={jest.fn()}
121
+ />
122
+ );
123
+
124
+ const input = screen.getByRole('textbox');
125
+ expect(input).toHaveAttribute('placeholder', '');
126
+ });
127
+
128
+ it('uses explicit placeholder prop over culture sample phone number', () => {
110
129
  render(
111
130
  <PhoneNumberInputA2
112
131
  culture={nanpCulture}
@@ -159,7 +178,7 @@ describe('PhoneNumberInputA2', () => {
159
178
  render(<PhoneNumberInputA2 sip culture={nanpCulture} value="" onChange={jest.fn()} />);
160
179
 
161
180
  const input = screen.getByRole('textbox');
162
- expect(input).not.toHaveAttribute('placeholder', '(___) ___-____');
181
+ expect(input).not.toHaveAttribute('placeholder', '(123) 456-7890');
163
182
  });
164
183
 
165
184
  it('shows explicit placeholder even in SIP mode', () => {
@@ -224,7 +243,7 @@ describe('PhoneNumberInputA2', () => {
224
243
  const cultureWithOptional = {
225
244
  PhoneFormat: {
226
245
  SimplePhoneMask: '(999) 999-9999?',
227
- SimplePhonePlaceholder: '',
246
+ SampleSimplePhoneNumber: '',
228
247
  },
229
248
  } as Culture;
230
249
 
@@ -26,11 +26,11 @@ export const PhoneNumberInputA2: FC<PhoneNumberInputA2Props> = props => {
26
26
 
27
27
  const [injectedCulture] = useOptionalDependencies(CULTURE_TOKEN);
28
28
  const culture = propCulture ?? injectedCulture;
29
- const { SimplePhoneMask = '?9999999999', SimplePhonePlaceholder = '' } =
29
+ const { SimplePhoneMask = '?9999999999', SampleSimplePhoneNumber = '' } =
30
30
  culture?.PhoneFormat ?? {};
31
31
 
32
32
  const mask = SimplePhoneMask.replace(/\?/g, '');
33
- const placeholder = propPlaceholder ?? SimplePhonePlaceholder;
33
+ const placeholder = propPlaceholder ?? SampleSimplePhoneNumber;
34
34
  const displayValue = String(value ?? '').replace(/\D/g, '');
35
35
 
36
36
  // Transform output value to digits-only (unmasked)