playbook_ui 14.21.1 → 14.21.2

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +1 -3
  3. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +18 -1
  4. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom.html.erb +1 -0
  5. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom_rails.md +1 -0
  6. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.html.erb +22 -0
  7. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.md +5 -0
  8. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_options.html.erb +1 -0
  9. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +1 -0
  10. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +3 -12
  11. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +0 -2
  12. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -2
  13. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +10 -14
  14. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +15 -26
  15. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
  16. data/app/pb_kits/playbook/pb_section_separator/docs/_description.md +3 -1
  17. data/dist/chunks/{_weekday_stacked-LCNJiSQ3.js → _weekday_stacked-CzxoxxCR.js} +2 -2
  18. data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
  19. data/dist/chunks/vendor.js +1 -1
  20. data/dist/playbook-doc.js +1 -1
  21. data/dist/playbook-rails.js +1 -1
  22. data/dist/playbook.css +1 -1
  23. data/lib/playbook/version.rb +2 -2
  24. metadata +7 -6
  25. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.jsx +0 -42
  26. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.md +0 -1
  27. data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0737c92ce3c158f4a4d593ab763d9a708bf1ea647fdaea8476164b892b257b5
4
- data.tar.gz: b7eadcb56f9e3082b04d22e91e8da3576141e9e84651a5081399dde83de8eac5
3
+ metadata.gz: c56ad47c1f53eb40bac67e374299659f3ad5cdcd2cb61f4cb674830b10eb8bbc
4
+ data.tar.gz: 9dfb9ddd7c1d200d680757e083b9ce21bacc896c9ff5b14a8a7ba2490fc9c45d
5
5
  SHA512:
6
- metadata.gz: 51d6ccdd8b41cf5109dfe7b357c3c839889980d69116018901ae974629aaa96178f9622698e0f331310137b8437b2e3ad82936e1df193829ba613af6aeefeec6
7
- data.tar.gz: d03ea7ef7a82b1caa0f1eed79e107cfa287a9d4e47559c562f27958532ccde311c75158d7635f6163357937836185123cdcdaee68a093f9aad35d316d9dbeb5d
6
+ metadata.gz: f79b70fd74d0721049b8cde8a212f8f0df9030ac5506c4e2600269eb6cc9e8564e9159ee8874decc50bfbadd3fdfc5542381d9e54195d48fed0a9d6c7208b59d
7
+ data.tar.gz: 7a08df80bcc0f05516c60ebdc42e44a2a098a49d45bdd9d5e5ab9f3e7dd0f5936a2878761a17b14dc62c234ac37ad66bcb9c5e7704378717d4338fe8c9d67f86
@@ -39,7 +39,7 @@
39
39
  }
40
40
 
41
41
  -ms-overflow-style: none !important;
42
- scrollbar-width: thin !important;
42
+ scrollbar-width: thin;
43
43
  scrollbar-color: #00000033 transparent !important;
44
44
  }
45
45
 
@@ -410,7 +410,6 @@
410
410
 
411
411
  // Make sure all horizontal borders use the default border color
412
412
  tr, th, td {
413
- border-top-color: $border_light !important;
414
413
  border-bottom-color: $border_light !important;
415
414
  }
416
415
 
@@ -633,7 +632,6 @@
633
632
 
634
633
  // Make sure all horizontal borders use the default border color in dark mode
635
634
  tr, th, td {
636
- border-top-color: $border_dark !important;
637
635
  border-bottom-color: $border_dark !important;
638
636
  }
639
637
 
@@ -18,13 +18,30 @@ module Playbook
18
18
  default: false
19
19
  prop :form_spacing, type: Playbook::Props::Boolean,
20
20
  default: false
21
+ prop :hidden_input, type: Playbook::Props::Boolean,
22
+ default: false
23
+ prop :hidden_value
21
24
 
22
25
  def classname
23
26
  generate_classname("pb_checkbox_kit", checked_class) + error_class
24
27
  end
25
28
 
26
29
  def input
27
- check_box_tag(name, value, checked, input_options.merge(disabled: disabled))
30
+ inputs = []
31
+ effective_name = name || input_options[:name]
32
+ effective_value = value || input_options[:value] || "1"
33
+ is_checked = checked || input_options[:checked]
34
+
35
+ inputs << hidden_field_tag(effective_name, hidden_value || "0") if hidden_input && effective_name.present?
36
+
37
+ inputs << check_box_tag(
38
+ effective_name,
39
+ effective_value,
40
+ is_checked,
41
+ input_options.merge(disabled: disabled)
42
+ )
43
+
44
+ safe_join(inputs)
28
45
  end
29
46
 
30
47
  def checkbox_label_status
@@ -1,3 +1,4 @@
1
1
  <%= pb_rails("checkbox", props: {text: "Custom Checkbox"}) do%>
2
+ <input type="hidden" name="custom-name" value="0" />
2
3
  <input type="checkbox" name="custom-name" value="custom-value"/>
3
4
  <% end %>
@@ -0,0 +1 @@
1
+ When using a custom checkbox wrapped in the Checkbox kit, hidden inputs are not automatically included and cannot be prop enabled. Manually add a hidden input before the checkbox if necessary to submit a value when the checkbox is unchecked (as is standard in Rails forms).
@@ -0,0 +1,22 @@
1
+
2
+ <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
3
+ <%=pb_rails("flex", props: { gap: "sm", orientation: "column"}) do %>
4
+ <%= pb_rails("checkbox" , props: {
5
+ text: "1. pb_rails(\"checkbox\") Checkbox from kit",
6
+ value: "checkbox-value",
7
+ name: "checkbox-name",
8
+ hidden_input: true
9
+ }) %>
10
+ <%= form.check_box :example_checkbox,
11
+ data: { field1: "value1", field2: "value2" },
12
+ props: { text: "2. form.check_box Checkbox from Form Builder" },
13
+ unchecked_value: "no",
14
+ id: "checkbox-id",
15
+ name: "checkbox-name",
16
+ class: "checkbox-class"
17
+ %>
18
+ <%= form.actions do |action| %>
19
+ <%= action.button props: { type: "submit", text: "Submit", variant: "primary" } %>
20
+ <% end %>
21
+ <% end %>
22
+ <% end %>
@@ -0,0 +1,5 @@
1
+ The way to access hidden inputs for form submission depends on which version of the kit being used within the form context.
2
+
3
+ If using the Rails Checkbox version of the kit, set `hidden_input: true`. Inspect Checkbox #1 in the example above to see the hidden input in the DOM.
4
+
5
+ If using the Form Builder version of the kit (reference the [Form kit page](https://playbook.powerapp.cloud/kits/form) for more on these), the hidden input will appear if the input has a set `unchecked_value`. Inspect Checkbox #2 in the example above (and the two checkbox examples on the Form kit page) to see the hidden input in the DOM. See the [Rails check_box FormHelper docs](https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box) for more.
@@ -1,5 +1,6 @@
1
1
  <%= pb_rails("checkbox" , props: {
2
2
  text: "Checkbox with Options",
3
+ hidden_input: true,
3
4
  input_options: {
4
5
  id: "checkbox-id",
5
6
  name: "checkbox-name",
@@ -7,6 +7,7 @@ examples:
7
7
  - checkbox_options: Checkbox w/ Options
8
8
  - checkbox_indeterminate: Indeterminate Checkbox
9
9
  - checkbox_disabled: Disabled Checkbox
10
+ - checkbox_form: Form and Hidden Input
10
11
 
11
12
  react:
12
13
  - checkbox_default: Default
@@ -25,7 +25,6 @@ type DropdownProps = {
25
25
  blankSelection?: string;
26
26
  children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
27
27
  className?: string;
28
- closeOnSelection?: boolean;
29
28
  formPillProps?: GenericObject;
30
29
  dark?: boolean;
31
30
  data?: { [key: string]: string };
@@ -56,7 +55,6 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
56
55
  blankSelection = '',
57
56
  children,
58
57
  className,
59
- closeOnSelection = true,
60
58
  dark = false,
61
59
  data = {},
62
60
  defaultValue = {},
@@ -154,7 +152,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
154
152
  if (!multiSelect) return optionsWithBlankSelection;
155
153
  return optionsWithBlankSelection.filter((option: GenericObject) => !selectedArray.some((sel) => sel.label === option.label));
156
154
  }, [optionsWithBlankSelection, selectedArray, multiSelect]);
157
-
155
+
158
156
  const filteredOptions = useMemo(() => {
159
157
  return availableOptions.filter((opt: GenericObject) =>
160
158
  String(opt.label).toLowerCase().includes(filterItem.toLowerCase())
@@ -194,18 +192,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
194
192
  return next;
195
193
  });
196
194
  setFilterItem("");
197
- // Only close dropdown if closeOnSelection is true
198
- if (closeOnSelection) {
199
- setIsDropDownClosed(true);
200
- }
195
+ setIsDropDownClosed(true);
201
196
  } else {
202
197
  setSelected(clickedItem);
203
198
  setFilterItem("");
199
+ setIsDropDownClosed(true);
204
200
  onSelect && onSelect(clickedItem);
205
- // Only close dropdown if closeOnSelection is true
206
- if (closeOnSelection) {
207
- setIsDropDownClosed(true);
208
- }
209
201
  }
210
202
  };
211
203
 
@@ -260,7 +252,6 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
260
252
  <DropdownContext.Provider
261
253
  value={{
262
254
  autocomplete,
263
- closeOnSelection,
264
255
  dropdownContainerRef,
265
256
  filteredOptions,
266
257
  filterItem,
@@ -44,6 +44,4 @@ examples:
44
44
  - dropdown_clear_selection: Clear Selection
45
45
  - dropdown_separators_hidden: Separators Hidden
46
46
  - dropdown_with_external_control: useDropdown Hook
47
- - dropdown_close_on_select: Close On Selection
48
-
49
47
 
@@ -19,5 +19,4 @@ export { default as DropdownMultiSelect } from './_dropdown_multi_select.jsx'
19
19
  export { default as DropdownMultiSelectDisplay } from './_dropdown_multi_select_display.jsx'
20
20
  export { default as DropdownMultiSelectWithAutocomplete } from './_dropdown_multi_select_with_autocomplete.jsx'
21
21
  export { default as DropdownMultiSelectWithDefault } from './_dropdown_multi_select_with_default.jsx'
22
- export { default as DropdownMultiSelectWithCustomOptions } from './_dropdown_multi_select_with_custom_options.jsx'
23
- export { default as DropdownCloseOnSelect } from './_dropdown_close_on_select.jsx'
22
+ export { default as DropdownMultiSelectWithCustomOptions } from './_dropdown_multi_select_with_custom_options.jsx'
@@ -25,7 +25,7 @@ type DropdownOptionProps = {
25
25
  key?: string | number;
26
26
  option?: GenericObject;
27
27
  padding?: string;
28
- } & GlobalProps;
28
+ } & GlobalProps;
29
29
 
30
30
  const DropdownOption = (props: DropdownOptionProps) => {
31
31
  const {
@@ -56,17 +56,16 @@ const DropdownOption = (props: DropdownOptionProps) => {
56
56
 
57
57
  // When multiSelect, then if an option is selected, remove from dropdown
58
58
  const isSelected = Array.isArray(selected)
59
- ? selected.some((item) => item.label === option?.label)
60
- : (selected as GenericObject)?.label === option?.label;
59
+ ? selected.some((item) => item.label === option?.label)
60
+ : (selected as GenericObject)?.label === option?.label;
61
61
 
62
+
62
63
  if (!isItemMatchingFilter(option) || (multiSelect && isSelected)) {
63
64
  return null;
64
65
  }
65
-
66
66
  const isFocused =
67
67
  focusedOptionIndex >= 0 &&
68
68
  filteredOptions[focusedOptionIndex].label === option?.label;
69
-
70
69
  const focusedClass = isFocused && "focused";
71
70
 
72
71
  const selectedClass = isSelected ? "selected" : "list";
@@ -92,10 +91,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
92
91
  className={classes}
93
92
  id={id}
94
93
  key={key}
95
- onClick={(e) => {
96
- e.stopPropagation();
97
- handleOptionClick(option);
98
- }}
94
+ onClick= {() => handleOptionClick(option)}
99
95
  >
100
96
  <ListItem
101
97
  cursor="pointer"
@@ -104,12 +100,12 @@ const DropdownOption = (props: DropdownOptionProps) => {
104
100
  key={option?.label}
105
101
  padding="none"
106
102
  >
107
- {children ?
103
+ {children ?
108
104
  <div className="dropdown_option_wrapper">{children}</div> :
109
- <Body dark={dark}
110
- text={option?.label}
111
- />
112
- }
105
+ <Body dark={dark}
106
+ text={option?.label}
107
+ />
108
+ }
113
109
  </ListItem>
114
110
  </div>
115
111
  );
@@ -44,7 +44,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
44
44
 
45
45
  const {
46
46
  autocomplete,
47
- closeOnSelection,
48
47
  filterItem,
49
48
  handleBackspace,
50
49
  handleChange,
@@ -55,7 +54,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
55
54
  isInputFocused,
56
55
  multiSelect,
57
56
  selected,
58
- setIsDropDownClosed,
59
57
  setIsInputFocused,
60
58
  toggleDropdown,
61
59
  } = useContext(DropdownContext);
@@ -105,26 +103,11 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
105
103
  ? placeholder
106
104
  : "Select...";
107
105
 
108
- // Click handler that respects closeOnSelection
109
- const handleInputClick = (e: React.MouseEvent) => {
110
- e.stopPropagation(); // keep the wrapper's handler from firing
111
- if (isDropDownClosed) {
112
- // Always open if closed
113
- setIsDropDownClosed(false);
114
- } else if (!closeOnSelection) {
115
- // Keep open if closeOnSelection is false
116
- return;
117
- } else {
118
- // Default behavior - toggle
119
- toggleDropdown();
120
- }
121
- };
122
-
123
106
  return (
124
- <div {...ariaProps}
125
- {...dataProps}
107
+ <div {...ariaProps}
108
+ {...dataProps}
126
109
  {...htmlProps}
127
- className={classes}
110
+ className={classes}
128
111
  id={id}
129
112
  >
130
113
  {
@@ -162,7 +145,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
162
145
  {customDisplay ? (
163
146
  <Flex align="center">
164
147
  {customDisplay}
165
- <Body dark={dark}
148
+ <Body dark={dark}
166
149
  paddingLeft={`${joinedLabels ? "xs" : "none"}`}
167
150
  >
168
151
  {customDisplayPlaceholder}
@@ -181,7 +164,10 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
181
164
  <input
182
165
  className="dropdown_input"
183
166
  onChange={handleChange}
184
- onClick={handleInputClick}
167
+ onClick={(e) => {
168
+ e.stopPropagation();// keep the wrapper’s handler from firing
169
+ toggleDropdown();
170
+ }}
185
171
  onFocus={() => setIsInputFocused(true)}
186
172
  onKeyDown={(e) => {
187
173
  handleKeyDown(e);
@@ -200,8 +186,8 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
200
186
  )}
201
187
  </>
202
188
  ) : (
203
- <Body dark={dark}
204
- text={defaultDisplayPlaceholder}
189
+ <Body dark={dark}
190
+ text={defaultDisplayPlaceholder}
205
191
  />
206
192
  )
207
193
  )}
@@ -209,7 +195,10 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
209
195
  <input
210
196
  className="dropdown_input"
211
197
  onChange={handleChange}
212
- onClick={handleInputClick}
198
+ onClick={(e) => {
199
+ e.stopPropagation();// keep the wrapper’s handler from firing
200
+ toggleDropdown();
201
+ }}
213
202
  onFocus={() => setIsInputFocused(true)}
214
203
  onKeyDown={handleKeyDown}
215
204
  placeholder={
@@ -234,7 +223,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
234
223
  onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
235
224
  }}
236
225
  key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
237
- >
226
+ >
238
227
  {
239
228
  selectedArray.length > 0 && (
240
229
  <div onClick={(e)=>{e.stopPropagation();handleBackspace()}}>
@@ -101,7 +101,7 @@
101
101
  <%= form.dropdown_field :example_dropdown_validation_multi, props: { label: true, options: example_dropdown_options, multi_select: true, required: true } %>
102
102
  <%= form.select :example_select_validation, [ ["Yes", 1], ["No", 2] ], props: { label: true, blank_selection: "Select One...", required: true, validation_message: "Please, select an option." } %>
103
103
  <%= form.collection_select :example_collection_select_validation, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
104
- <%= form.check_box :example_checkbox, props: { text: "Example Checkbox", label: true, required: true } %>
104
+ <%= form.check_box :example_checkbox_validation, props: { text: "Example Checkbox Validation", label: true, required: true }, checked_value: "1", unchecked_value: "0" %>
105
105
  <%= form.date_picker :example_date_picker_2, props: { label: true, required: true, validation_message: "Please, select a date.", allow_input: true } %>
106
106
  <%= form.star_rating_field :example_star_rating_validation, props: { variant: "interactive", label: true, required: true } %>
107
107
  <%= form.time_zone_select_field :example_time_zone_select, ActiveSupport::TimeZone.us_zones, { default: "Eastern Time (US & Canada)" }, props: { label: true, blank_selection: "Select a Time Zone...", required: true } %>
@@ -1 +1,3 @@
1
- Section separator is a divider line that compartmentalizes content, typically used on cards or white backgrounds. This should only be used on light backgrounds (with our variable `$bg_light`).
1
+ Section separator is a divider line that compartmentalizes content, typically used on cards or white backgrounds.
2
+
3
+ To ensure that the section separator is properly rendered, please be sure to use our global `width` prop to set width to 100%. [See here](https://playbook.powerapp.cloud/visual_guidelines/width) for more information on the global width prop.