playbook_ui 12.24.0.pre.alpha.play833boldoptionfortitle2and3721 → 12.24.0.pre.alpha.play824733

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd4e3864286b541e0caf3e640c35a8f942dbcb6ab2d7baad716ac5a0e6d3e3ff
4
- data.tar.gz: 95157177f65e2b812bcf3cae77037188b8f1020c7662e6d6b1232d792feb7bc1
3
+ metadata.gz: 8231bb3fbf02190e76cf2763a3d70ee166e665ea67ab0456fb61e90aba95e933
4
+ data.tar.gz: 71ef01fbd0bb7e37c38958c8b0409d577a682283713c3c7a50aec203b6870423
5
5
  SHA512:
6
- metadata.gz: b0e07bf633784eb9262db46a90d2c334062e23f6dc30630cca188b3de480e1f28eea51841d0c1347712eda7826e947c3459f7d52b9a39599c4ef530b7eee8d3a
7
- data.tar.gz: db69cd005df2c3408d3f3cb72de4d3cb6c2c49ba40b426096cda9763dd157d51a56277d0d11a7ae69b993cceb52011ca9547ab7fe21c6f5be8aeff45592bf3d0
6
+ metadata.gz: 5ec035a7462706717a83e63a232d4e2cbf761eeb8e89b17466630e1921f01c1aeecd79b6e21f3b2d930a112edab0cf39cbd649ea9ddd3320a8ca9b942a4322ac
7
+ data.tar.gz: e1966ede2224963aa2c903d23765dae5cb24c0317d3d7bff6f0fd9d211ae1453f48d70ab94cffdf3d04d760274234a61b5fd2d2c1cf838d652bea6e635f059d8
@@ -1,12 +1,17 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React, { forwardRef, useEffect, useRef, useState } from 'react'
2
2
  import classnames from 'classnames'
3
- import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
4
- import { globalProps } from '../utilities/globalProps'
3
+
5
4
  import intlTelInput from 'intl-tel-input'
6
5
  import 'intl-tel-input/build/css/intlTelInput.css'
7
- import TextInput from '../pb_text_input/_text_input'
8
6
  import 'intl-tel-input/build/js/utils.js'
9
7
 
8
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
9
+ import { globalProps } from '../utilities/globalProps'
10
+
11
+ import TextInput from '../pb_text_input/_text_input'
12
+ import { Callback } from '../types'
13
+ import { isEmpty } from '../utilities/object'
14
+
10
15
  declare global {
11
16
  interface Window {
12
17
  intlTelInputGlobals: any
@@ -19,14 +24,17 @@ type PhoneNumberInputProps = {
19
24
  dark?: boolean,
20
25
  data?: { [key: string]: string },
21
26
  disabled?: boolean,
27
+ error?: string,
22
28
  id?: string,
23
29
  initialCountry?: string,
24
30
  isValid?: (valid: boolean) => void,
25
31
  label?: string,
26
32
  name?: string,
27
33
  onChange?: (e: React.FormEvent<HTMLInputElement>) => void,
34
+ onValidate?: Callback<boolean, void>,
28
35
  onlyCountries: string[],
29
36
  preferredCountries?: string[],
37
+ required?: boolean,
30
38
  value?: string,
31
39
  }
32
40
 
@@ -40,10 +48,10 @@ const formatToGlobalCountryName = (countryName: string) => {
40
48
  }
41
49
 
42
50
  const formatAllCountries = () => {
43
- let countryData = window.intlTelInputGlobals.getCountryData()
51
+ const countryData = window.intlTelInputGlobals.getCountryData()
44
52
 
45
53
  for (let i = 0; i < countryData.length; i++) {
46
- let country = countryData[i]
54
+ const country = countryData[i]
47
55
  country.name = formatToGlobalCountryName(country.name)
48
56
  }
49
57
  }
@@ -71,7 +79,9 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
71
79
  onChange = () => {
72
80
  void 0
73
81
  },
82
+ onValidate = () => null,
74
83
  onlyCountries = [],
84
+ required = false,
75
85
  preferredCountries = [],
76
86
  value = "",
77
87
  } = props
@@ -87,10 +97,18 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
87
97
  const inputRef = useRef<HTMLInputElement>()
88
98
  const [inputValue, setInputValue] = useState(value)
89
99
  const [itiInit, setItiInit] = useState<any>()
90
- const [error, setError] = useState('')
100
+ const [error, setError] = useState(props.error)
91
101
  const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
92
102
  const [selectedData, setSelectedData] = useState()
93
103
 
104
+ useEffect(() => {
105
+ if (error?.length > 0) {
106
+ onValidate(false)
107
+ } else {
108
+ onValidate(true)
109
+ }
110
+ }, [error, onValidate])
111
+
94
112
  const validateTooLongNumber = (itiInit: any) => {
95
113
  const error = itiInit.getValidationError()
96
114
 
@@ -137,9 +155,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
137
155
 
138
156
  // Separating Concerns as React Docs Recommend
139
157
  // This also Fixes things for our react_component rendering on the Rails Side
140
- useEffect(() => {
141
- formatAllCountries()
142
- }, [])
158
+ useEffect(formatAllCountries, [])
143
159
 
144
160
  useEffect(() => {
145
161
  const telInputInit = new intlTelInput(inputRef.current, {
@@ -148,14 +164,14 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
148
164
  allowDropdown: !disabled,
149
165
  initialCountry,
150
166
  onlyCountries,
151
- }
152
- )
167
+ })
153
168
 
154
169
  inputRef.current.addEventListener("countrychange", (evt: Event) => {
155
170
  validateTooLongNumber(telInputInit)
156
171
  const phoneNumberData = getCurrentSelectedData(telInputInit, (evt.target as HTMLInputElement).value)
157
172
  setSelectedData(phoneNumberData)
158
173
  onChange(phoneNumberData)
174
+ isValid(telInputInit.isValidNumber())
159
175
  })
160
176
 
161
177
  inputRef.current.addEventListener("open:countrydropdown", () => setDropDownIsOpen(true))
@@ -164,24 +180,34 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
164
180
  setItiInit(telInputInit)
165
181
  }, [])
166
182
 
183
+ let textInputProps: {[key: string]: any} = {
184
+ className: dropDownIsOpen ? 'dropdown_open' : '',
185
+ dark,
186
+ "data-phone-number": JSON.stringify(selectedData),
187
+ disabled,
188
+ error,
189
+ id,
190
+ label,
191
+ name,
192
+ onBlur: validateErrors,
193
+ onChange: handleOnChange,
194
+ value: inputValue
195
+ }
196
+
197
+ let wrapperProps: Record<string, unknown> = { className: classes }
198
+
199
+ if (!isEmpty(aria)) textInputProps = {...textInputProps, ...ariaProps}
200
+ if (!isEmpty(data)) wrapperProps = {...wrapperProps, ...dataProps}
201
+ if (required) textInputProps.required = true
202
+
167
203
  return (
168
- <div {...ariaProps} {...dataProps} className={classes}>
204
+ <div {...wrapperProps}>
169
205
  <TextInput
170
- className={dropDownIsOpen ? 'dropdown_open' : ''}
171
- dark={dark}
172
- data-phone-number={JSON.stringify(selectedData)}
173
- disabled={disabled}
174
- error={error}
175
- id={id}
176
- label={label}
177
- name={name}
178
- onBlur={() => validateErrors()}
179
- onChange={handleOnChange}
180
- ref={inputRef}
181
- value={inputValue}
206
+ ref={inputRef}
207
+ {...textInputProps}
182
208
  />
183
209
  </div>
184
210
  )
185
211
  }
186
212
 
187
- export default PhoneNumberInput
213
+ export default forwardRef(PhoneNumberInput)
@@ -0,0 +1,14 @@
1
+ <form id="example-form-validation" action="" method="get">
2
+ <%= pb_rails("phone_number_input", props: { error: "Missing phone number.", id: "validation", initial_country: "af", value: "", required: true }) %>
3
+ <%= pb_rails("button", props: {html_type: "submit", text: "Save Phone Number"}) %>
4
+ </form>
5
+
6
+ <% content_for(:pb_js) do %>
7
+ <%= javascript_tag do %>
8
+ document.addEventListener('DOMContentLoaded', function () {
9
+ document.querySelector('#example-form-validation').addEventListener('submit', function (e) {
10
+ if (e.target.querySelectorAll('[error]:not([error=""])').length > 0) e.preventDefault();
11
+ })
12
+ })
13
+ <% end %>
14
+ <% end %>
@@ -0,0 +1,61 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Button, FixedConfirmationToast, PhoneNumberInput } from "../../";
3
+
4
+ const PhoneNumberInputValidation = (props) => {
5
+ const [formErrors, setFormErrors] = useState("");
6
+ const [showFormErrors, setShowFormErrors] = useState(false);
7
+ const [phoneNumber, setPhoneNumber] = useState("");
8
+ const [countryCode, setCountryCode] = useState("af");
9
+
10
+ const handleOnValidate = (valid) => {
11
+ setFormErrors(
12
+ valid ? "" : "Please correct the fields below and try again."
13
+ );
14
+ };
15
+
16
+ const handleOnChange = ({ iso2, number }) => {
17
+ setCountryCode(iso2);
18
+ setPhoneNumber(number);
19
+ };
20
+
21
+ const handleOnSubmit = (e) => {
22
+ if (showFormErrors) e.preventDefault()
23
+ }
24
+
25
+ useEffect(() => {
26
+ setShowFormErrors(formErrors.length > 0);
27
+ }, [formErrors]);
28
+
29
+ return (
30
+ <form
31
+ action=""
32
+ method="get"
33
+ onSubmit={handleOnSubmit}
34
+ >
35
+ {showFormErrors && (
36
+ <FixedConfirmationToast
37
+ closeable
38
+ marginBottom="md"
39
+ status="error"
40
+ text={formErrors}
41
+ />
42
+ )}
43
+ <PhoneNumberInput
44
+ error="Missing phone number."
45
+ id="validation"
46
+ initialCountry={countryCode}
47
+ onChange={handleOnChange}
48
+ onValidate={handleOnValidate}
49
+ required
50
+ value={phoneNumber}
51
+ {...props}
52
+ />
53
+ <Button
54
+ htmlType="submit"
55
+ text="Save Phone Number"
56
+ />
57
+ </form>
58
+ );
59
+ };
60
+
61
+ export default PhoneNumberInputValidation;
@@ -5,9 +5,11 @@ examples:
5
5
  - phone_number_input_preferred_countries: Preferred Countries
6
6
  - phone_number_input_initial_country: Initial Country
7
7
  - phone_number_input_only_countries: Limited Countries
8
+ - phone_number_input_validation: Form Validation
8
9
 
9
10
  rails:
10
11
  - phone_number_input_default: Default
11
12
  - phone_number_input_preferred_countries: Preferred Countries
12
13
  - phone_number_input_initial_country: Initial Country
13
- - phone_number_input_only_countries: Limited Countries
14
+ - phone_number_input_only_countries: Limited Countries
15
+ - phone_number_input_validation: Form Validation
@@ -2,3 +2,4 @@ export { default as PhoneNumberInputDefault } from './_phone_number_input_defaul
2
2
  export { default as PhoneNumberInputPreferredCountries } from './_phone_number_input_preferred_countries'
3
3
  export { default as PhoneNumberInputInitialCountry } from './_phone_number_input_initial_country'
4
4
  export { default as PhoneNumberInputOnlyCountries } from './_phone_number_input_only_countries'
5
+ export { default as PhoneNumberInputValidation } from './_phone_number_input_validation'
@@ -5,6 +5,8 @@ module Playbook
5
5
  class PhoneNumberInput < Playbook::KitBase
6
6
  prop :disabled, type: Playbook::Props::Boolean,
7
7
  default: false
8
+ prop :required, type: Playbook::Props::Boolean,
9
+ default: false
8
10
  prop :initial_country, type: Playbook::Props::String,
9
11
  default: ""
10
12
  prop :label, type: Playbook::Props::String,
@@ -15,6 +17,7 @@ module Playbook
15
17
  default: []
16
18
  prop :preferred_countries, type: Playbook::Props::Array,
17
19
  default: []
20
+ prop :error, type: Playbook::Props::String
18
21
  prop :value, type: Playbook::Props::String,
19
22
  default: ""
20
23
 
@@ -27,11 +30,13 @@ module Playbook
27
30
  id: id,
28
31
  dark: dark,
29
32
  disabled: disabled,
33
+ error: error,
30
34
  initialCountry: initial_country,
31
35
  label: label,
32
36
  name: name,
33
37
  onlyCountries: only_countries,
34
38
  preferredCountries: preferred_countries,
39
+ required: required,
35
40
  value: value,
36
41
  }
37
42
  end
@@ -1,74 +1,122 @@
1
- import React from 'react'
2
- import { render, screen } from '../utilities/test-utils'
3
- import PhoneNumberInput from './_phone_number_input'
1
+ import React from "react";
2
+ import { render, screen } from "../utilities/test-utils";
3
+ import PhoneNumberInput from "./_phone_number_input";
4
4
 
5
- const testId = "phoneNumberInput"
5
+ const testId = "phoneNumberInput";
6
6
 
7
- test('should be disabled', () => {
8
- const props = {
9
- disabled: true,
10
- id: testId,
11
- }
7
+ test("should be disabled", () => {
8
+ const props = {
9
+ disabled: true,
10
+ id: testId,
11
+ };
12
12
 
13
- render(<PhoneNumberInput {...props} />)
14
- const kit = screen.getByRole("textbox")
15
- expect(kit).toBeDisabled()
16
- })
13
+ render(<PhoneNumberInput {...props} />);
14
+ const kit = screen.getByRole("textbox");
15
+ expect(kit).toBeDisabled();
16
+ });
17
17
 
18
- test('should be enabled by default', () => {
19
- const props = {
20
- id: testId,
21
- }
18
+ test("should be enabled by default", () => {
19
+ const props = {
20
+ id: testId,
21
+ };
22
22
 
23
- render(<PhoneNumberInput {...props} />)
24
- const kit = screen.getByRole("textbox")
25
- expect(kit).not.toBeDisabled()
26
- })
23
+ render(<PhoneNumberInput {...props} />);
24
+ const kit = screen.getByRole("textbox");
25
+ expect(kit).not.toBeDisabled();
26
+ });
27
27
 
28
- test('should have label', () => {
29
- const label = 'Phone Number'
30
- const props = {
31
- id: testId,
32
- label,
33
- }
28
+ test("should have label", () => {
29
+ const label = "Phone Number";
30
+ const props = {
31
+ id: testId,
32
+ label,
33
+ };
34
34
 
35
- render(<PhoneNumberInput {...props} />)
36
- const kit = screen.getByText(label)
37
- expect(kit).toBeInTheDocument()
38
- })
35
+ render(<PhoneNumberInput {...props} />);
36
+ const kit = screen.getByText(label);
37
+ expect(kit).toBeInTheDocument();
38
+ });
39
39
 
40
- test('should pass data prop', () => {
41
- const props = {
42
- data: { testid: testId },
43
- id: testId,
44
- }
40
+ test("should pass data prop", () => {
41
+ const props = {
42
+ data: { testid: testId },
43
+ id: testId,
44
+ };
45
+
46
+ render(<PhoneNumberInput {...props} />);
47
+ const kit = screen.getByTestId(testId);
48
+ expect(kit).toBeInTheDocument();
49
+ });
50
+
51
+ test("should pass className prop", () => {
52
+ const className = "custom-class-name";
53
+ const props = {
54
+ className,
55
+ data: { testid: testId },
56
+ id: testId,
57
+ };
58
+
59
+ render(<PhoneNumberInput {...props} />);
60
+ const kit = screen.getByTestId(testId);
61
+ expect(kit).toHaveClass(className);
62
+ });
63
+
64
+ test("should pass value prop", () => {
65
+ const value = "1234567890";
66
+ const props = {
67
+ id: testId,
68
+ value,
69
+ };
45
70
 
46
- render(<PhoneNumberInput {...props} />)
47
- const kit = screen.getByTestId(testId)
48
- expect(kit).toBeInTheDocument()
49
- })
71
+ render(<PhoneNumberInput {...props} />);
72
+ const kit = screen.getByRole("textbox");
73
+ expect(kit).toHaveDisplayValue(value);
74
+ });
50
75
 
51
- test('should pass className prop', () => {
52
- const className = 'custom-class-name'
76
+ //TODO: test required field presence
77
+ test("should pass required prop", () => {
78
+ const props = {
79
+ id: testId,
80
+ };
81
+
82
+ render(
83
+ <PhoneNumberInput
84
+ required
85
+ {...props}
86
+ />
87
+ );
88
+ const kit = screen.getByRole("textbox");
89
+ expect(kit).toHaveAttribute("required");
90
+ });
91
+
92
+ test("should have error attribute when invalid", () => {
53
93
  const props = {
54
- className,
55
- data: { testid: testId },
56
- id: testId,
57
- }
58
-
59
- render(<PhoneNumberInput {...props} />)
60
- const kit = screen.getByTestId(testId)
61
- expect(kit).toHaveClass(className)
62
- })
63
-
64
- test('should pass value prop', () => {
65
- const value = '1234567890'
94
+ id: testId,
95
+ error: "Something isn't right here."
96
+ };
97
+
98
+ render(
99
+ <PhoneNumberInput
100
+ {...props}
101
+ />
102
+ );
103
+ const kit = screen.getByRole("textbox");
104
+ expect(kit).toHaveAttribute("error");
105
+ });
106
+
107
+ test("should trigger callback", () => {
108
+ const handleOnValidate = jest.fn((valid) => valid)
109
+
66
110
  const props = {
67
- id: testId,
68
- value,
69
- }
70
-
71
- render(<PhoneNumberInput {...props} />)
72
- const kit = screen.getByRole("textbox")
73
- expect(kit).toHaveDisplayValue(value)
74
- })
111
+ id: testId,
112
+ onValidate: handleOnValidate
113
+ };
114
+
115
+ render(
116
+ <PhoneNumberInput
117
+ {...props}
118
+ />
119
+ );
120
+
121
+ expect(handleOnValidate).toBeCalledWith(true)
122
+ });
@@ -18,7 +18,6 @@
18
18
  &[class*=_3] {
19
19
  @include pb_title_3;
20
20
  @include title_colors;
21
- @include pb_title_bold;
22
21
  }
23
22
 
24
23
  &[class*=_4] {
@@ -30,7 +29,7 @@
30
29
  @include pb_title_dark;
31
30
  }
32
31
 
33
- &[class*=thin] {
32
+ &[class*=_thin] {
34
33
  @include pb_title_thin;
35
34
  }
36
35
  }
@@ -21,13 +21,13 @@ const Title = (props: TitleProps): React.ReactElement => {
21
21
  if (props.variant) deprecatedProps('Title', ['variant']) //variant prop is deprecated, use color instead
22
22
  const {
23
23
  aria = {},
24
+ bold = true,
24
25
  children,
25
26
  className,
26
27
  color,
27
28
  data = {},
28
29
  id,
29
30
  size = 3,
30
- bold = size === 3 ? false : true,
31
31
  tag = 'h3',
32
32
  text,
33
33
  variant = null,
@@ -35,10 +35,9 @@ const Title = (props: TitleProps): React.ReactElement => {
35
35
 
36
36
  const ariaProps: {[key: string]: string | number} = buildAriaProps(aria)
37
37
  const dataProps: {[key: string]: string | number} = buildDataProps(data)
38
-
39
38
  const getBold = bold ? '' : 'thin'
40
39
  const classes = classnames(
41
- buildCss("pb_title_kit", `size_${size}`, variant, color) + ` ${getBold}`,
40
+ buildCss('pb_title_kit', `size_${size}`, variant, color, getBold),
42
41
  globalProps(props),
43
42
  className
44
43
  )
@@ -17,21 +17,14 @@ module Playbook
17
17
  values: [nil, "link"],
18
18
  default: nil,
19
19
  deprecated: true
20
-
21
- def initialize(props)
22
- props[:bold] = [1, 2, 4].include?(props[:size]) unless props.key?(:bold)
23
- props[:bold] = false if props[:size].nil? && !props.key?(:bold)
24
- super(props)
25
- end
26
-
27
- prop :bold, type: Playbook::Props::Boolean
20
+ prop :bold, type: Playbook::Props::Boolean, default: true
28
21
 
29
22
  def classname
30
- generate_classname("pb_title_kit", size, variant, color) + is_bold
23
+ generate_classname("pb_title_kit", size, variant, color, is_bold)
31
24
  end
32
25
 
33
26
  def is_bold
34
- bold ? "" : " thin"
27
+ bold ? nil : "thin"
35
28
  end
36
29
  end
37
30
  end
@@ -12,7 +12,7 @@ test('returns namespaced class name', () => {
12
12
  )
13
13
 
14
14
  const kit = screen.getByTestId('primary-test')
15
- expect(kit).toHaveClass('pb_title_kit_size_3 thin')
15
+ expect(kit).toHaveClass('pb_title_kit_size_3')
16
16
  })
17
17
 
18
18
  test('with thin font weight', () => {
@@ -25,7 +25,7 @@ test('with thin font weight', () => {
25
25
  )
26
26
 
27
27
  const kit = screen.getByTestId('primary-test')
28
- expect(kit).toHaveClass('pb_title_kit_size_3 thin')
28
+ expect(kit).toHaveClass('pb_title_kit_size_3_thin')
29
29
  })
30
30
 
31
31
  test('with colors', () => {
@@ -38,5 +38,5 @@ test('with colors', () => {
38
38
  )
39
39
 
40
40
  const kit = screen.getByTestId('primary-test')
41
- expect(kit).toHaveClass('pb_title_kit_size_3_success thin')
41
+ expect(kit).toHaveClass('pb_title_kit_size_3_success')
42
42
  })
@@ -0,0 +1,3 @@
1
+ /* 🛠️ Any commonly used lodash functions can be added here. 🤙 */
2
+
3
+ export const isEmpty = (obj: Record<string, unknown>): boolean => Object.keys(obj).length < 1
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Forms
5
+ class Builder
6
+ def intl_telephone(name, props: {})
7
+ props[:name] = name
8
+ @template.pb_rails("phone_number_input", props: props)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -10,6 +10,7 @@ module Playbook
10
10
  require_relative "builder/form_field_builder"
11
11
  require_relative "builder/select_field"
12
12
  require_relative "builder/typeahead_field"
13
+ require_relative "builder/intl_telephone_field"
13
14
 
14
15
  prepend(FormFieldBuilder.new(:email_field, kit_name: "text_input"))
15
16
  prepend(FormFieldBuilder.new(:number_field, kit_name: "text_input"))
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Playbook
4
4
  PREVIOUS_VERSION = "12.24.0"
5
- VERSION = "12.24.0.pre.alpha.play833boldoptionfortitle2and3721"
5
+ VERSION = "12.24.0.pre.alpha.play824733"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.24.0.pre.alpha.play833boldoptionfortitle2and3721
4
+ version: 12.24.0.pre.alpha.play824733
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-06-01 00:00:00.000000000 Z
12
+ date: 2023-06-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -1607,6 +1607,8 @@ files:
1607
1607
  - app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_preferred_countries.html.erb
1608
1608
  - app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_preferred_countries.jsx
1609
1609
  - app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_preferred_countries.md
1610
+ - app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.html.erb
1611
+ - app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx
1610
1612
  - app/pb_kits/playbook/pb_phone_number_input/docs/example.yml
1611
1613
  - app/pb_kits/playbook/pb_phone_number_input/docs/index.js
1612
1614
  - app/pb_kits/playbook/pb_phone_number_input/phone_number_input.html.erb
@@ -2415,6 +2417,7 @@ files:
2415
2417
  - app/pb_kits/playbook/utilities/flexbox_global_props/_justify_self.scss
2416
2418
  - app/pb_kits/playbook/utilities/flexbox_global_props/_order.scss
2417
2419
  - app/pb_kits/playbook/utilities/globalProps.ts
2420
+ - app/pb_kits/playbook/utilities/object.ts
2418
2421
  - app/pb_kits/playbook/utilities/props.ts
2419
2422
  - app/pb_kits/playbook/utilities/test-utils.js
2420
2423
  - app/pb_kits/playbook/utilities/test/globalProps/alignContent.test.js
@@ -2452,6 +2455,7 @@ files:
2452
2455
  - lib/playbook/forms/builder/collection_select_field.rb
2453
2456
  - lib/playbook/forms/builder/date_picker_field.rb
2454
2457
  - lib/playbook/forms/builder/form_field_builder.rb
2458
+ - lib/playbook/forms/builder/intl_telephone_field.rb
2455
2459
  - lib/playbook/forms/builder/select_field.rb
2456
2460
  - lib/playbook/forms/builder/typeahead_field.rb
2457
2461
  - lib/playbook/justify_content.rb