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

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.
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