playbook_ui 16.1.0.pre.alpha.play264213818 → 16.1.0.pre.alpha.play276813969

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_card/docs/_card_light.html.erb +3 -35
  3. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +8 -6
  4. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +6 -0
  5. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +83 -13
  6. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection_rails.md +3 -0
  7. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection_react.md +3 -0
  8. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.html.erb +52 -0
  9. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.jsx +72 -0
  10. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.md +5 -0
  11. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height.jsx +33 -0
  12. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_rails.html.erb +20 -0
  13. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_rails.md +8 -0
  14. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_react.md +8 -0
  15. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.html.erb +6 -3
  16. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +1 -0
  17. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.md +3 -1
  18. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.html.erb +9 -0
  19. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.jsx +33 -0
  20. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.md +3 -0
  21. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +6 -0
  22. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +4 -1
  23. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +11 -5
  24. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +15 -0
  25. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +94 -0
  26. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +5 -1
  27. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +7 -2
  28. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +4 -0
  29. data/app/pb_kits/playbook/pb_dropdown/index.js +184 -77
  30. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +3 -0
  31. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +18 -1
  32. data/app/pb_kits/playbook/pb_dropdown/utilities/clickOutsideHelper.tsx +6 -0
  33. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +1 -1
  34. data/app/pb_kits/playbook/pb_filter/docs/_filter_default.html.erb +2 -2
  35. data/app/pb_kits/playbook/pb_filter/docs/_filter_default.jsx +16 -9
  36. data/app/pb_kits/playbook/pb_filter/filter.rb +2 -2
  37. data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +1 -0
  38. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.html.erb +5 -5
  39. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.jsx +4 -4
  40. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +4 -0
  41. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -0
  42. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +638 -549
  43. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +3 -3
  44. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +4 -7
  45. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.md +3 -0
  46. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx +4 -4
  47. data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +20 -5
  48. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +1 -0
  49. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.html.erb +7 -0
  50. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.jsx +24 -0
  51. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.md +3 -0
  52. data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +2 -0
  53. data/app/pb_kits/playbook/pb_passphrase/docs/index.js +1 -0
  54. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +2 -0
  55. data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +30 -1
  56. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +3 -0
  57. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.html.erb +5 -0
  58. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.jsx +14 -0
  59. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.md +3 -0
  60. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +2 -0
  61. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
  62. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  63. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +34 -3
  64. data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +24 -1
  65. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +2 -1
  66. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +4 -1
  67. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.html.erb +1 -1
  68. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.jsx +1 -1
  69. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +4 -0
  70. data/dist/chunks/_typeahead-C4YsbA48.js +1 -0
  71. data/dist/chunks/vendor.js +2 -2
  72. data/dist/playbook-rails-react-bindings.js +1 -1
  73. data/dist/playbook-rails.js +1 -1
  74. data/dist/playbook.css +1 -1
  75. data/lib/playbook/forms/builder/phone_number_field.rb +9 -0
  76. data/lib/playbook/truncate.rb +1 -1
  77. data/lib/playbook/version.rb +1 -1
  78. metadata +22 -3
  79. data/dist/chunks/_typeahead-B9a6ZsEP.js +0 -1
@@ -1,6 +1,8 @@
1
1
  <%= pb_content_tag do %>
2
2
  <% if object.label.present? %>
3
- <%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
3
+ <label for="<%= object.select_id %>" data-dropdown="pb-dropdown-label">
4
+ <%= pb_rails("caption", props: { text: object.label, margin_bottom: "xs", classname: "pb_dropdown_kit_label", dark: object.dark }) %>
5
+ </label>
4
6
  <% end %>
5
7
  <div class="dropdown_wrapper<%= error_class %>" style="position: relative">
6
8
  <input
@@ -16,10 +18,12 @@
16
18
  <% end %>
17
19
  <% if content.present? %>
18
20
  <%= content.presence %>
19
- <%= pb_rails("body", props: { status: "negative", text: object.error }) %>
21
+ <% if object.error.present? %>
22
+ <%= pb_rails("body", props: { status: "negative", text: object.error, id: object.error_id, aria: { atomic: "true", live: "polite" }, html_options: { role: "alert" }, dark: object.dark }) %>
23
+ <% end %>
20
24
  <% else %>
21
- <%= pb_rails("dropdown/dropdown_trigger", props:{ autocomplete: object.autocomplete, multi_select:object.multi_select }) %>
22
- <%= pb_rails("dropdown/dropdown_container", props: { searchbar: object.searchbar }) do %>
25
+ <%= pb_rails("dropdown/dropdown_trigger", props: { autocomplete: object.autocomplete, multi_select: object.multi_select, placeholder: object.placeholder, select_id: object.select_id, label: object.label, error_id: object.error_id, error: object.error }) %>
26
+ <%= pb_rails("dropdown/dropdown_container", props: { searchbar: object.searchbar, constrain_height: object.constrain_height }) do %>
23
27
  <% if options_with_blank.present? %>
24
28
  <% options_with_blank.each do |option| %>
25
29
  <%= pb_rails("dropdown/dropdown_option", props: {option: option}) %>
@@ -27,7 +31,9 @@
27
31
  <% end %>
28
32
  <% end %>
29
33
 
30
- <%= pb_rails("body", props: { status: "negative", text: object.error }) %>
34
+ <% if object.error.present? %>
35
+ <%= pb_rails("body", props: { status: "negative", text: object.error, id: object.error_id, aria: { atomic: "true", live: "polite" }, html_options: { role: "alert" }, dark: object.dark }) %>
36
+ <% end %>
31
37
  <% end %>
32
38
  </div>
33
39
  <% end %>
@@ -10,6 +10,7 @@ module Playbook
10
10
  prop :label, type: Playbook::Props::String
11
11
  prop :name, type: Playbook::Props::String
12
12
  prop :error, type: Playbook::Props::String
13
+ prop :id, type: Playbook::Props::String
13
14
  prop :required, type: Playbook::Props::Boolean,
14
15
  default: false
15
16
  prop :default_value
@@ -36,6 +37,8 @@ module Playbook
36
37
  default: ""
37
38
  prop :controls_start_id, type: Playbook::Props::String,
38
39
  default: ""
40
+ prop :clearable, type: Playbook::Props::Boolean,
41
+ default: true
39
42
  prop :start_date_id, type: Playbook::Props::String,
40
43
  default: "start_date_id"
41
44
  prop :start_date_name, type: Playbook::Props::String,
@@ -44,12 +47,16 @@ module Playbook
44
47
  default: "end_date_id"
45
48
  prop :end_date_name, type: Playbook::Props::String,
46
49
  default: "end_date_name"
50
+ prop :placeholder, type: Playbook::Props::String
51
+ prop :constrain_height, type: Playbook::Props::Boolean,
52
+ default: false
47
53
 
48
54
  def data
49
55
  Hash(prop(:data)).merge(
50
56
  pb_dropdown: true,
51
57
  pb_dropdown_multi_select: multi_select,
52
58
  pb_dropdown_variant: variant,
59
+ pb_dropdown_clearable: clearable,
53
60
  form_pill_props: form_pill_props.to_json,
54
61
  start_date_id: variant == "quickpick" ? start_date_id : nil,
55
62
  end_date_id: variant == "quickpick" ? end_date_id : nil,
@@ -62,6 +69,14 @@ module Playbook
62
69
  generate_classname("pb_dropdown", variant, separators_class)
63
70
  end
64
71
 
72
+ def select_id
73
+ id.presence || (label.present? ? label.downcase.gsub(/\s+/, "_").gsub(/[^a-z0-9_]/, "") : nil)
74
+ end
75
+
76
+ def error_id
77
+ error.present? ? "#{select_id || 'dropdown_trigger'}-error" : nil
78
+ end
79
+
65
80
  private
66
81
 
67
82
  def error_class
@@ -122,6 +122,80 @@ test('generated placeholder prop', () => {
122
122
 
123
123
  })
124
124
 
125
+ test('placeholder prop passed directly to Dropdown', () => {
126
+ render(
127
+ <Dropdown
128
+ data={{ testid: testId }}
129
+ options={options}
130
+ placeholder="Choose a country"
131
+ />
132
+ )
133
+
134
+ const kit = screen.getByTestId(testId)
135
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
136
+ expect(trigger).toHaveTextContent('Choose a country')
137
+ })
138
+
139
+ test('placeholder works with default variant', () => {
140
+ render(
141
+ <Dropdown
142
+ data={{ testid: testId }}
143
+ options={options}
144
+ placeholder="Select an option"
145
+ variant="default"
146
+ />
147
+ )
148
+
149
+ const kit = screen.getByTestId(testId)
150
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
151
+ expect(trigger).toHaveTextContent('Select an option')
152
+ })
153
+
154
+ test('placeholder works with subtle variant', () => {
155
+ render(
156
+ <Dropdown
157
+ data={{ testid: testId }}
158
+ options={options}
159
+ placeholder="Pick an option"
160
+ separators={false}
161
+ variant="subtle"
162
+ />
163
+ )
164
+
165
+ const kit = screen.getByTestId(testId)
166
+ expect(kit).toHaveClass('pb_dropdown_subtle_separators_hidden')
167
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
168
+ expect(trigger).toHaveTextContent('Pick an option')
169
+ })
170
+
171
+ test('placeholder works with quickpick variant', () => {
172
+ render(
173
+ <Dropdown
174
+ data={{ testid: testId }}
175
+ placeholder="Select a date range"
176
+ variant="quickpick"
177
+ />
178
+ )
179
+
180
+ const kit = screen.getByTestId(testId)
181
+ expect(kit).toHaveClass('pb_dropdown_quickpick')
182
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
183
+ expect(trigger).toHaveTextContent('Select a date range')
184
+ })
185
+
186
+ test('placeholder shows default "Select..." when not provided', () => {
187
+ render(
188
+ <Dropdown
189
+ data={{ testid: testId }}
190
+ options={options}
191
+ />
192
+ )
193
+
194
+ const kit = screen.getByTestId(testId)
195
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
196
+ expect(trigger).toHaveTextContent('Select...')
197
+ })
198
+
125
199
  test('generated label prop', () => {
126
200
  render (
127
201
  <Dropdown
@@ -466,7 +540,27 @@ test("quickpick clears selection when clicking X icon", () => {
466
540
  expect(trigger).toHaveTextContent("Select...")
467
541
  })
468
542
 
543
+ test("quickpick hides clear icon when clearable is false", () => {
544
+ render(
545
+ <Dropdown
546
+ clearable={false}
547
+ data={{ testid: testId }}
548
+ defaultValue="This Week"
549
+ variant="quickpick"
550
+ />
551
+ )
552
+
553
+ const kit = screen.getByTestId(testId)
554
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
555
+
556
+ expect(trigger).toHaveTextContent("This Week")
557
+
558
+ const clearIcon = kit.querySelector('[aria-label="times icon"]')
559
+ expect(clearIcon).not.toBeInTheDocument()
560
+ })
561
+
469
562
  test("quickpick returns date array values when option selected", () => {
563
+ // eslint-disable-next-line react/no-multi-comp
470
564
  const TestComponent = () => {
471
565
  const [selected, setSelected] = useState(null)
472
566
  return (
@@ -5,9 +5,13 @@ module Playbook
5
5
  class DropdownContainer < Playbook::KitBase
6
6
  prop :searchbar, type: Playbook::Props::Boolean,
7
7
  default: false
8
+ prop :constrain_height, type: Playbook::Props::Boolean,
9
+ default: false
8
10
 
9
11
  def classname
10
- generate_classname("pb_dropdown_container", "close", separator: " ")
12
+ classes = %w[pb_dropdown_container close]
13
+ classes << "constrain_height" if constrain_height
14
+ generate_classname(*classes, separator: " ")
11
15
  end
12
16
 
13
17
  def data
@@ -1,6 +1,10 @@
1
1
  <%= pb_content_tag do %>
2
2
  <% if content.present? %>
3
- <div style="display: inline-block" tabindex="0" data-dropdown-custom-trigger>
3
+ <div style="display: inline-block" tabindex="0" data-dropdown="pb-dropdown-trigger" data-dropdown-custom-trigger aria-invalid="<%= object.error.present? %>"
4
+ <% if object.label.present? %> aria-label="<%= [object.label, object.default_display_placeholder].join(', ') %>"<% end %>
5
+ <% if object.select_id.present? %> id="<%= object.select_id %>"<% end %>
6
+ <% if object.error_id.present? %> aria-describedby="<%= object.error_id %>"<% end %>
7
+ >
4
8
  <%= content.presence %>
5
9
  </div>
6
10
  <% else %>
@@ -9,10 +13,11 @@
9
13
  border_radius:"lg",
10
14
  classname: object.trigger_wrapper_classes,
11
15
  cursor: object.autocomplete ? "text" : "pointer",
16
+ id: object.select_id,
12
17
  justify: "between",
13
18
  padding_x:"sm",
14
19
  padding_y:"xs",
15
- html_options: {tabindex:"0"}
20
+ html_options: { tabindex: "0", "aria-label": object.label.present? ? [object.label, object.default_display_placeholder].join(", ") : nil, "aria-describedby": object.error_id, "aria-invalid": object.error.present?, "data-dropdown": "pb-dropdown-trigger" }
16
21
  }) do %>
17
22
  <%= pb_rails("flex/flex_item", props: { fixed_size: object.multi_select ? "85%" : "" }) do %>
18
23
  <%= pb_rails("flex", props: {align: "center"}) do %>
@@ -13,6 +13,10 @@ module Playbook
13
13
  default: false
14
14
  prop :multi_select, type: Playbook::Props::Boolean,
15
15
  default: false
16
+ prop :select_id, type: Playbook::Props::String
17
+ prop :label, type: Playbook::Props::String
18
+ prop :error_id, type: Playbook::Props::String
19
+ prop :error, type: Playbook::Props::String
16
20
 
17
21
  def data
18
22
  Hash(prop(:data)).merge(dropdown_trigger: true, dropdown_placeholder: default_display_placeholder)