playbook_ui 14.19.0.pre.rc.2 → 14.20.0.pre.alpha.revert4453PBNTR933reactdraggablebugdragbtwnexamples7854
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 +4 -4
- data/app/pb_kits/playbook/_playbook.scss +0 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +11 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +175 -16
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +56 -25
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +23 -13
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/VisibilityTree.ts +47 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +6 -10
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +7 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +0 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.jsx +57 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.jsx +62 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.jsx +82 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.jsx +66 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows_rails.md +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows.jsx → _advanced_table_selectable_rows_no_subrows_react.jsx} +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.md +3 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +7 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +6 -2
- data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +106 -0
- data/app/pb_kits/playbook/pb_advanced_table/index.js +228 -11
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +9 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -3
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +1 -2
- data/app/pb_kits/playbook/pb_avatar/_avatar.scss +4 -0
- data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +3 -0
- data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +3 -3
- data/app/pb_kits/playbook/pb_avatar/avatar.rb +2 -0
- data/app/pb_kits/playbook/pb_avatar/avatar.test.js +18 -0
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.html.erb +5 -0
- data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.jsx +16 -0
- data/app/pb_kits/playbook/pb_avatar/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_avatar/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
- data/app/pb_kits/playbook/pb_card/card.rb +12 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_error.html.erb +2 -2
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +17 -58
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.html.erb +22 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line.html.erb +55 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line_rails.md +5 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_rails.md +5 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners.jsx +59 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners_react.md +1 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_draggable/draggable_container.rb +11 -1
- data/app/pb_kits/playbook/pb_draggable/draggable_item.rb +11 -1
- data/app/pb_kits/playbook/pb_draggable/index.js +4 -2
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +33 -5
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +6 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +82 -35
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +31 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.md +5 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +5 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +56 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +58 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +19 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +57 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +50 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +105 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +22 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +67 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +28 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +17 -64
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +58 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/{_dropdown_with_autocomplete_and_custom_display.jsx → _dropdown_with_autocomplete_with_subcomponents.jsx} +11 -25
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +11 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +33 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.md +3 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +61 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.md +2 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +52 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.md +2 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +18 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +7 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +20 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +45 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +10 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +3 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +37 -6
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +5 -1
- data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +0 -6
- data/app/pb_kits/playbook/pb_dropdown/index.js +380 -17
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +64 -11
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +3 -4
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +16 -12
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +83 -17
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/MultiSelectTriggerDisplay.tsx +58 -0
- data/app/pb_kits/playbook/pb_empty_state/_empty_state.scss +8 -1
- data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_alignment.html.erb +27 -0
- data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_default.html.erb +7 -0
- data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_orientation.html.erb +12 -0
- data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_size.html.erb +23 -0
- data/app/pb_kits/playbook/pb_empty_state/docs/example.yml +5 -1
- data/app/pb_kits/playbook/pb_empty_state/empty_state.html.erb +19 -0
- data/app/pb_kits/playbook/pb_empty_state/empty_state.rb +123 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +13 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +11 -1
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.jsx +41 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.rb +7 -1
- data/app/pb_kits/playbook/pb_file_upload/fileupload.test.js +18 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +2 -2
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +19 -12
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +13 -7
- data/app/pb_kits/playbook/pb_message/_message.tsx +3 -0
- data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.html.erb +9 -0
- data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.jsx +21 -0
- data/app/pb_kits/playbook/pb_message/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_message/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_message/message.html.erb +2 -1
- data/app/pb_kits/playbook/pb_message/message.rb +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +2 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_reset.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.md +2 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.md +3 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_form.html.erb +11 -11
- data/app/pb_kits/playbook/pb_overlay/_overlay.scss +2 -1
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.jsx +1 -1
- data/app/pb_kits/playbook/pb_overlay/subcomponents/_overlay_token.tsx +5 -4
- data/app/pb_kits/playbook/pb_person/_person.tsx +12 -2
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +9 -9
- data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +2 -2
- data/app/pb_kits/playbook/pb_select/_select.scss +10 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_error.html.erb +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.jsx +7 -7
- data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +5 -5
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +4 -2
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.html.erb +1 -1
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.html.erb +5 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +73 -3
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.html.erb +8 -1
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.jsx +23 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_user/_user.tsx +3 -0
- data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.html.erb +6 -0
- data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.jsx +16 -0
- data/app/pb_kits/playbook/pb_user/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_user/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_user/user.html.erb +2 -1
- data/app/pb_kits/playbook/pb_user/user.rb +1 -0
- data/dist/chunks/_typeahead-C-CI5Vgw.js +22 -0
- data/dist/chunks/_weekday_stacked-BCiM3zWM.js +45 -0
- data/dist/chunks/lib-D5R1BjUn.js +29 -0
- data/dist/chunks/{pb_form_validation-BWjy4bFn.js → pb_form_validation-BZ2AVAi_.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +6 -14
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/kit_base.rb +3 -3
- data/lib/playbook/version.rb +2 -2
- metadata +70 -22
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.html.erb +0 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +0 -79
- data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.scss +0 -3
- data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.tsx +0 -72
- data/app/pb_kits/playbook/pb_gantt_chart/docs/_gantt_chart_default.jsx +0 -53
- data/app/pb_kits/playbook/pb_gantt_chart/docs/example.yml +0 -7
- data/app/pb_kits/playbook/pb_gantt_chart/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_gantt_chart/gantt_chart.test.jsx +0 -19
- data/dist/chunks/_typeahead-D8CsVBZO.js +0 -22
- data/dist/chunks/_weekday_stacked-D3oLTSkH.js +0 -45
- data/dist/chunks/lib-BmTAc7Nc.js +0 -29
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_react.md → _advanced_table_selectable_rows.md} +0 -0
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows.html.erb → _advanced_table_selectable_rows_no_subrows_rails.html.erb} +0 -0
- /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows.html.erb → _advanced_table_selectable_rows_rails.html.erb} +0 -0
- /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_line.md → _draggable_drop_zones_line_react.md} +0 -0
- /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_event_listeners.md → _draggable_event_listeners_rails.md} +0 -0
| @@ -45,27 +45,31 @@ const DropdownOption = (props: DropdownOptionProps) => { | |
| 45 45 | 
             
                filterItem,
         | 
| 46 46 | 
             
                focusedOptionIndex,
         | 
| 47 47 | 
             
                handleOptionClick,
         | 
| 48 | 
            +
                multiSelect,
         | 
| 48 49 | 
             
                selected,
         | 
| 49 50 | 
             
              } = useContext(DropdownContext);
         | 
| 50 51 |  | 
| 51 | 
            -
              const isItemMatchingFilter = (option: GenericObject) => {
         | 
| 52 | 
            -
                const label = typeof option | 
| 52 | 
            +
              const isItemMatchingFilter = (option: GenericObject | undefined) => {
         | 
| 53 | 
            +
                const label = typeof option?.label === 'string' ? option.label.toLowerCase() : option?.label;
         | 
| 53 54 | 
             
                return String(label).toLowerCase().includes(filterItem.toLowerCase());
         | 
| 54 55 | 
             
              }
         | 
| 55 56 |  | 
| 56 | 
            -
              if  | 
| 57 | 
            +
              // When multiSelect, then if an option is selected, remove from dropdown
         | 
| 58 | 
            +
              const isSelected = Array.isArray(selected)
         | 
| 59 | 
            +
               ? selected.some((item) => item.label === option?.label)
         | 
| 60 | 
            +
               : (selected as GenericObject)?.label === option?.label;
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              
         | 
| 63 | 
            +
              if (!isItemMatchingFilter(option) || (multiSelect && isSelected)) {
         | 
| 57 64 | 
             
                return null;
         | 
| 58 65 | 
             
              }
         | 
| 59 66 | 
             
              const isFocused =
         | 
| 60 67 | 
             
                focusedOptionIndex >= 0 &&
         | 
| 61 | 
            -
                filteredOptions[focusedOptionIndex].label === option | 
| 68 | 
            +
                filteredOptions[focusedOptionIndex].label === option?.label;
         | 
| 62 69 | 
             
              const focusedClass = isFocused && "focused";
         | 
| 63 70 |  | 
| 64 | 
            -
              const selectedClass =  | 
| 65 | 
            -
             | 
| 66 | 
            -
                  ? "selected"
         | 
| 67 | 
            -
                  : "list"
         | 
| 68 | 
            -
              }`;
         | 
| 71 | 
            +
              const selectedClass = isSelected ? "selected" : "list";
         | 
| 72 | 
            +
             | 
| 69 73 | 
             
              const ariaProps = buildAriaProps(aria);
         | 
| 70 74 | 
             
              const dataProps = buildDataProps(data);
         | 
| 71 75 | 
             
              const htmlProps = buildHtmlProps(htmlOptions);
         | 
| @@ -92,14 +96,14 @@ const DropdownOption = (props: DropdownOptionProps) => { | |
| 92 96 | 
             
                  <ListItem
         | 
| 93 97 | 
             
                      cursor="pointer"
         | 
| 94 98 | 
             
                      dark={dark}
         | 
| 95 | 
            -
                      data-name={option | 
| 96 | 
            -
                      key={option | 
| 99 | 
            +
                      data-name={option?.value}
         | 
| 100 | 
            +
                      key={option?.label}
         | 
| 97 101 | 
             
                      padding="none"
         | 
| 98 102 | 
             
                  >
         | 
| 99 103 | 
             
                      {children ? 
         | 
| 100 104 | 
             
                      <div className="dropdown_option_wrapper">{children}</div> :
         | 
| 101 105 | 
             
                          <Body dark={dark} 
         | 
| 102 | 
            -
                              text={option | 
| 106 | 
            +
                              text={option?.label} 
         | 
| 103 107 | 
             
                          />
         | 
| 104 108 | 
             
                      }
         | 
| 105 109 | 
             
                  </ListItem>
         | 
| @@ -10,6 +10,7 @@ import { globalProps } from "../../utilities/globalProps"; | |
| 10 10 | 
             
            import { useHandleOnKeyDown } from "../hooks/useHandleOnKeydown";
         | 
| 11 11 |  | 
| 12 12 | 
             
            import DropdownContext from "../context";
         | 
| 13 | 
            +
            import MultiSelectTriggerDisplay from "./MultiSelectTriggerDisplay";
         | 
| 13 14 |  | 
| 14 15 | 
             
            import Body from "../../pb_body/_body";
         | 
| 15 16 | 
             
            import Icon from "../../pb_icon/_icon";
         | 
| @@ -44,16 +45,17 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 44 45 | 
             
              const {
         | 
| 45 46 | 
             
                autocomplete,
         | 
| 46 47 | 
             
                filterItem,
         | 
| 48 | 
            +
                handleBackspace,
         | 
| 47 49 | 
             
                handleChange,
         | 
| 48 50 | 
             
                handleWrapperClick,
         | 
| 49 51 | 
             
                inputRef,
         | 
| 50 52 | 
             
                inputWrapperRef,
         | 
| 51 53 | 
             
                isDropDownClosed,
         | 
| 52 54 | 
             
                isInputFocused,
         | 
| 55 | 
            +
                multiSelect,
         | 
| 53 56 | 
             
                selected,
         | 
| 54 57 | 
             
                setIsInputFocused,
         | 
| 55 58 | 
             
                toggleDropdown,
         | 
| 56 | 
            -
                triggerRef,
         | 
| 57 59 | 
             
              } = useContext(DropdownContext);
         | 
| 58 60 |  | 
| 59 61 | 
             
              const handleKeyDown = useHandleOnKeyDown();
         | 
| @@ -70,11 +72,21 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 70 72 | 
             
              const triggerWrapperClasses = buildCss(
         | 
| 71 73 | 
             
                "dropdown_trigger_wrapper",
         | 
| 72 74 | 
             
                isInputFocused && "focus",
         | 
| 73 | 
            -
                !autocomplete && "select_only"
         | 
| 75 | 
            +
                !autocomplete && !multiSelect && "select_only"
         | 
| 74 76 | 
             
              );
         | 
| 75 77 |  | 
| 78 | 
            +
              const selectedArray = Array.isArray(selected)
         | 
| 79 | 
            +
                ? selected
         | 
| 80 | 
            +
                : selected && Object.keys(selected).length
         | 
| 81 | 
            +
                ? [selected]
         | 
| 82 | 
            +
                : [];
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              const joinedLabels = multiSelect
         | 
| 85 | 
            +
                ? ""
         | 
| 86 | 
            +
                : selectedArray.map((option) => option.label).join(", ");
         | 
| 87 | 
            +
             | 
| 76 88 | 
             
              const customDisplayPlaceholder = selected?.label ? (
         | 
| 77 | 
            -
                 | 
| 89 | 
            +
                ""
         | 
| 78 90 | 
             
              ) : autocomplete ? (
         | 
| 79 91 | 
             
                ""
         | 
| 80 92 | 
             
              ) : placeholder ? (
         | 
| @@ -83,8 +95,8 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 83 95 | 
             
                "Select..."
         | 
| 84 96 | 
             
              );
         | 
| 85 97 |  | 
| 86 | 
            -
              const defaultDisplayPlaceholder =  | 
| 87 | 
            -
                ?  | 
| 98 | 
            +
              const defaultDisplayPlaceholder = joinedLabels
         | 
| 99 | 
            +
                ? joinedLabels
         | 
| 88 100 | 
             
                : autocomplete
         | 
| 89 101 | 
             
                ? ""
         | 
| 90 102 | 
             
                : placeholder
         | 
| @@ -99,7 +111,6 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 99 111 | 
             
                    id={id}
         | 
| 100 112 | 
             
                >
         | 
| 101 113 | 
             
                  {
         | 
| 102 | 
            -
                    !triggerRef && (
         | 
| 103 114 | 
             
                      children ? (
         | 
| 104 115 | 
             
                        <div
         | 
| 105 116 | 
             
                            onClick={() => toggleDropdown()}
         | 
| @@ -127,31 +138,71 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 127 138 | 
             
                              paddingX="sm"
         | 
| 128 139 | 
             
                              paddingY="xs"
         | 
| 129 140 | 
             
                          >
         | 
| 130 | 
            -
                            <FlexItem>
         | 
| 131 | 
            -
                              <Flex align="center" | 
| 141 | 
            +
                            <FlexItem fixedSize={multiSelect ? "85%" : ""}>
         | 
| 142 | 
            +
                              <Flex align="center"
         | 
| 143 | 
            +
                                  wrap
         | 
| 144 | 
            +
                              >
         | 
| 132 145 | 
             
                                {customDisplay ? (
         | 
| 133 146 | 
             
                                  <Flex align="center">
         | 
| 134 147 | 
             
                                    {customDisplay}
         | 
| 135 148 | 
             
                                    <Body dark={dark} 
         | 
| 136 | 
            -
                                        paddingLeft={`${ | 
| 149 | 
            +
                                        paddingLeft={`${joinedLabels ? "xs" : "none"}`}
         | 
| 137 150 | 
             
                                    >
         | 
| 138 151 | 
             
                                      {customDisplayPlaceholder}
         | 
| 139 152 | 
             
                                    </Body>
         | 
| 140 153 | 
             
                                  </Flex>
         | 
| 141 154 | 
             
                                ) : (
         | 
| 142 | 
            -
                                   | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 155 | 
            +
                                  multiSelect ? (
         | 
| 156 | 
            +
                                    <>
         | 
| 157 | 
            +
                                    <MultiSelectTriggerDisplay
         | 
| 158 | 
            +
                                        autocomplete={autocomplete}
         | 
| 159 | 
            +
                                        dark={dark}
         | 
| 160 | 
            +
                                        placeholder={placeholder}
         | 
| 161 | 
            +
                                        selected={selectedArray}
         | 
| 162 | 
            +
                                    />
         | 
| 163 | 
            +
                                    {autocomplete && (
         | 
| 164 | 
            +
                                      <input
         | 
| 165 | 
            +
                                          className="dropdown_input"
         | 
| 166 | 
            +
                                          onChange={handleChange}
         | 
| 167 | 
            +
                                          onClick={(e) => {
         | 
| 168 | 
            +
                                            e.stopPropagation();// keep the wrapper’s handler from firing
         | 
| 169 | 
            +
                                            toggleDropdown();
         | 
| 170 | 
            +
                                          }}
         | 
| 171 | 
            +
                                          onFocus={() => setIsInputFocused(true)}
         | 
| 172 | 
            +
                                          onKeyDown={(e) => {
         | 
| 173 | 
            +
                                             handleKeyDown(e);
         | 
| 174 | 
            +
                                             e.stopPropagation(); //Fixes issue with keyboard accessibility
         | 
| 175 | 
            +
                                           }}
         | 
| 176 | 
            +
                                          placeholder={
         | 
| 177 | 
            +
                                            joinedLabels
         | 
| 178 | 
            +
                                              ? ""
         | 
| 179 | 
            +
                                              : placeholder
         | 
| 180 | 
            +
                                              ? placeholder
         | 
| 181 | 
            +
                                              : "Select..."
         | 
| 182 | 
            +
                                          }
         | 
| 183 | 
            +
                                          ref={inputRef}
         | 
| 184 | 
            +
                                          value={filterItem}
         | 
| 185 | 
            +
                                      />
         | 
| 186 | 
            +
                                    )}
         | 
| 187 | 
            +
                                    </>
         | 
| 188 | 
            +
                                  ) : (
         | 
| 189 | 
            +
                                    <Body dark={dark} 
         | 
| 190 | 
            +
                                        text={defaultDisplayPlaceholder} 
         | 
| 191 | 
            +
                                    />
         | 
| 192 | 
            +
                                  )
         | 
| 145 193 | 
             
                                )}
         | 
| 146 | 
            -
                                {autocomplete && (
         | 
| 194 | 
            +
                                {autocomplete && !multiSelect && (
         | 
| 147 195 | 
             
                                  <input
         | 
| 148 196 | 
             
                                      className="dropdown_input"
         | 
| 149 197 | 
             
                                      onChange={handleChange}
         | 
| 150 | 
            -
                                      onClick={() =>  | 
| 198 | 
            +
                                      onClick={(e) => {
         | 
| 199 | 
            +
                                        e.stopPropagation();// keep the wrapper’s handler from firing
         | 
| 200 | 
            +
                                        toggleDropdown();
         | 
| 201 | 
            +
                                      }}
         | 
| 151 202 | 
             
                                      onFocus={() => setIsInputFocused(true)}
         | 
| 152 203 | 
             
                                      onKeyDown={handleKeyDown}
         | 
| 153 204 | 
             
                                      placeholder={
         | 
| 154 | 
            -
                                         | 
| 205 | 
            +
                                        joinedLabels
         | 
| 155 206 | 
             
                                          ? ""
         | 
| 156 207 | 
             
                                          : placeholder
         | 
| 157 208 | 
             
                                          ? placeholder
         | 
| @@ -163,14 +214,29 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 163 214 | 
             
                                )}
         | 
| 164 215 | 
             
                              </Flex>
         | 
| 165 216 | 
             
                            </FlexItem>
         | 
| 217 | 
            +
                            <FlexItem>
         | 
| 166 218 | 
             
                              <Body
         | 
| 219 | 
            +
                                  alignItems="center"
         | 
| 167 220 | 
             
                                  dark={dark}
         | 
| 168 221 | 
             
                                  display="flex"
         | 
| 169 222 | 
             
                                  htmlOptions={{
         | 
| 170 223 | 
             
                                    onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
         | 
| 171 224 | 
             
                                  }}
         | 
| 172 225 | 
             
                                  key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
         | 
| 173 | 
            -
                              >
         | 
| 226 | 
            +
                              > 
         | 
| 227 | 
            +
                              {
         | 
| 228 | 
            +
                                selectedArray.length > 0 && (
         | 
| 229 | 
            +
                                  <div onClick={(e)=>{e.stopPropagation();handleBackspace()}}>
         | 
| 230 | 
            +
                                    <Icon
         | 
| 231 | 
            +
                                        cursor="pointer"
         | 
| 232 | 
            +
                                        dark={dark}
         | 
| 233 | 
            +
                                        icon="times"
         | 
| 234 | 
            +
                                        paddingRight="xs"
         | 
| 235 | 
            +
                                        size="sm"
         | 
| 236 | 
            +
                                    />
         | 
| 237 | 
            +
                                  </div>
         | 
| 238 | 
            +
                                )
         | 
| 239 | 
            +
                              }
         | 
| 174 240 | 
             
                                <Icon
         | 
| 175 241 | 
             
                                    cursor="pointer"
         | 
| 176 242 | 
             
                                    dark={dark}
         | 
| @@ -178,10 +244,10 @@ const DropdownTrigger = (props: DropdownTriggerProps) => { | |
| 178 244 | 
             
                                    size="sm"
         | 
| 179 245 | 
             
                                />
         | 
| 180 246 | 
             
                              </Body>
         | 
| 247 | 
            +
                            </FlexItem>
         | 
| 181 248 | 
             
                          </Flex>
         | 
| 182 249 | 
             
                        </>
         | 
| 183 250 | 
             
                      )
         | 
| 184 | 
            -
                    )
         | 
| 185 251 | 
             
                  }
         | 
| 186 252 | 
             
                </div>
         | 
| 187 253 | 
             
              );
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            import React, { useContext } from "react";
         | 
| 2 | 
            +
            import FormPill from "../../pb_form_pill/_form_pill";
         | 
| 3 | 
            +
            import Flex from "../../pb_flex/_flex";
         | 
| 4 | 
            +
            import Body from "../../pb_body/_body";
         | 
| 5 | 
            +
            import { GenericObject } from "../../types";
         | 
| 6 | 
            +
            import DropdownContext
         | 
| 7 | 
            +
             from "../context";
         | 
| 8 | 
            +
            type MultiSelectTriggerDisplayProps = {
         | 
| 9 | 
            +
              autocomplete?: boolean;
         | 
| 10 | 
            +
              selected: GenericObject[];
         | 
| 11 | 
            +
              placeholder?: string;
         | 
| 12 | 
            +
              dark?: boolean;
         | 
| 13 | 
            +
            };
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            const MultiSelectTriggerDisplay = ({
         | 
| 16 | 
            +
              autocomplete,
         | 
| 17 | 
            +
              selected,
         | 
| 18 | 
            +
              placeholder,
         | 
| 19 | 
            +
              dark = false,
         | 
| 20 | 
            +
            }: MultiSelectTriggerDisplayProps) => {
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              const { setSelected, onSelect, formPillProps } = useContext(DropdownContext);
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              if (selected.length === 0) {
         | 
| 25 | 
            +
                if (autocomplete) return null;
         | 
| 26 | 
            +
                return (
         | 
| 27 | 
            +
                <Body dark={dark} 
         | 
| 28 | 
            +
                    text={placeholder ? placeholder : "Select..."} 
         | 
| 29 | 
            +
                />
         | 
| 30 | 
            +
                )
         | 
| 31 | 
            +
              }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             const handleRemoveIconClick = (option: GenericObject) => {
         | 
| 34 | 
            +
              setSelected((prev: GenericObject[]) => {
         | 
| 35 | 
            +
                  const next = prev.filter((item) => item.label !== option.label);
         | 
| 36 | 
            +
                  onSelect && onSelect(next);
         | 
| 37 | 
            +
                  return next;
         | 
| 38 | 
            +
                });
         | 
| 39 | 
            +
             } 
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              return (
         | 
| 42 | 
            +
                <Flex wrap>
         | 
| 43 | 
            +
                  {selected.map((option, i) => (
         | 
| 44 | 
            +
                      <FormPill
         | 
| 45 | 
            +
                          dark={dark}
         | 
| 46 | 
            +
                          key={i}
         | 
| 47 | 
            +
                          marginRight="xs"
         | 
| 48 | 
            +
                          onClick={(e)=>{e.stopPropagation();handleRemoveIconClick(option)}}
         | 
| 49 | 
            +
                          tabIndex={0}
         | 
| 50 | 
            +
                          text={option.label}
         | 
| 51 | 
            +
                          {...formPillProps}
         | 
| 52 | 
            +
                      />
         | 
| 53 | 
            +
                  ))}
         | 
| 54 | 
            +
                </Flex>
         | 
| 55 | 
            +
              );
         | 
| 56 | 
            +
            };
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            export default MultiSelectTriggerDisplay;
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            .pb_empty_state_kit {
         | 
| 2 | 
            +
              max-width: 100%;
         | 
| 2 3 |  | 
| 3 4 | 
             
              .sm-state-vertical {
         | 
| 4 5 | 
             
                width: 150px;
         | 
| @@ -35,4 +36,10 @@ | |
| 35 36 | 
             
                }
         | 
| 36 37 | 
             
              }
         | 
| 37 38 |  | 
| 38 | 
            -
             | 
| 39 | 
            +
              &.dark {
         | 
| 40 | 
            +
                [class*="pb_title_kit"],
         | 
| 41 | 
            +
                [class*="pb_body_kit"],
         | 
| 42 | 
            +
                [class*="pb_detail_kit"],
         | 
| 43 | 
            +
                [class*="pb_button_kit_link"]:hover { color: $white; }
         | 
| 44 | 
            +
              }
         | 
| 45 | 
            +
            }
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            <%= pb_rails("flex", props: {align: "center", spacing: "evenly", wrap: true}) do %>
         | 
| 2 | 
            +
              <%= pb_rails("empty_state", props: {
         | 
| 3 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 4 | 
            +
                header: "Title Explains",
         | 
| 5 | 
            +
                image: "default",
         | 
| 6 | 
            +
                primary_button: "Next Action",
         | 
| 7 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 8 | 
            +
                alignment: "left",
         | 
| 9 | 
            +
              }) %>
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              <%= pb_rails("empty_state", props: {
         | 
| 12 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 13 | 
            +
                header: "Title Explains",
         | 
| 14 | 
            +
                image: "default",
         | 
| 15 | 
            +
                primary_button: "Next Action",
         | 
| 16 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 17 | 
            +
              }) %>
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                <%= pb_rails("empty_state", props: {
         | 
| 20 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 21 | 
            +
                header: "Title Explains",
         | 
| 22 | 
            +
                image: "default",
         | 
| 23 | 
            +
                primary_button: "Next Action",
         | 
| 24 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 25 | 
            +
                alignment: "right",
         | 
| 26 | 
            +
              }) %>
         | 
| 27 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            <%= pb_rails("flex", props: {align: "center", justify: "center", wrap: true}) do %>
         | 
| 2 | 
            +
              <%= pb_rails("empty_state", props: {
         | 
| 3 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 4 | 
            +
                header: "Title Explains",
         | 
| 5 | 
            +
                image: "default",
         | 
| 6 | 
            +
                orientation:"horizontal",
         | 
| 7 | 
            +
                alignment: "left",
         | 
| 8 | 
            +
                size: "lg",
         | 
| 9 | 
            +
                primary_button: "Next Action",
         | 
| 10 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 11 | 
            +
              }) %>
         | 
| 12 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            <%= pb_rails("flex", props: {align: "center", spacing: "evenly", wrap: true}) do %>
         | 
| 2 | 
            +
              <%= pb_rails("empty_state", props: {
         | 
| 3 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 4 | 
            +
                header: "Title Explains",
         | 
| 5 | 
            +
                image: "default",
         | 
| 6 | 
            +
                primary_button: "Next Action",
         | 
| 7 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 8 | 
            +
                link_button: "Alt Action",
         | 
| 9 | 
            +
                link_button_url: "#link_button_url",
         | 
| 10 | 
            +
                size: "sm",
         | 
| 11 | 
            +
              }) %>
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              <%= pb_rails("empty_state", props: {
         | 
| 14 | 
            +
                description: "Body text goes into detail with possible steps for user to take",
         | 
| 15 | 
            +
                header: "Title Explains",
         | 
| 16 | 
            +
                image: "default",
         | 
| 17 | 
            +
                primary_button: "Next Action",
         | 
| 18 | 
            +
                primary_button_url: "#primary_button_url",
         | 
| 19 | 
            +
                link_button: "Alt Action",
         | 
| 20 | 
            +
                link_button_url: "#link_button_url",
         | 
| 21 | 
            +
                size: "lg",
         | 
| 22 | 
            +
              }) %>
         | 
| 23 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            <%= pb_content_tag do %>
         | 
| 2 | 
            +
              <%= pb_rails("flex", props: { align: flex_align, orientation: config[:flex_direction], padding_left: padding_size, padding_right: padding_size, vertical: "center", classname: config[:scss_class], max_width: "100%" }) do %>
         | 
| 3 | 
            +
                <%= pb_rails("image", props: { url: image == "default" ? default_image_data_uri : image, alt: "Empty State Image", html_options: { width: config[:image_width], height: "auto", alignment: "start" } }) %>
         | 
| 4 | 
            +
                <%= pb_rails("flex/flex_item") do %>
         | 
| 5 | 
            +
                  <%= pb_rails("title", props: { text: object.header, size: config[:title_size], padding_bottom: config[:title_padding], text_align: alignment }) %>
         | 
| 6 | 
            +
                  <% if size == "sm" %>
         | 
| 7 | 
            +
                    <%= pb_rails("detail", props: { text: object.description, padding_bottom: config[:description_pad], text_align: alignment }) %>
         | 
| 8 | 
            +
                  <% else %>
         | 
| 9 | 
            +
                    <%= pb_rails("body", props: { text: object.description, padding_bottom: config[:description_pad], text_align: alignment }) %>
         | 
| 10 | 
            +
                  <% end %>
         | 
| 11 | 
            +
                  <% if primary_button.present? %>
         | 
| 12 | 
            +
                    <%= pb_rails("button", props: { text: primary_button, variant: "primary", width: "100%", size: config[:button_size], link: primary_button_url,  margin_bottom: config[:button_margin] }) %>
         | 
| 13 | 
            +
                  <% end %>
         | 
| 14 | 
            +
                  <% if link_button.present? %>
         | 
| 15 | 
            +
                    <%= pb_rails("button", props: { text: link_button, variant: "link", size: config[:button_size], link: link_button_url, width: "100%" }) %>
         | 
| 16 | 
            +
                  <% end %>
         | 
| 17 | 
            +
                <% end %>
         | 
| 18 | 
            +
              <% end %>
         | 
| 19 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,123 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Playbook
         | 
| 4 | 
            +
              module PbEmptyState
         | 
| 5 | 
            +
                class EmptyState < Playbook::KitBase
         | 
| 6 | 
            +
                  prop :alignment, type: Playbook::Props::Enum,
         | 
| 7 | 
            +
                                   values: %w[center left right],
         | 
| 8 | 
            +
                                   default: "center"
         | 
| 9 | 
            +
                  prop :description
         | 
| 10 | 
            +
                  prop :header
         | 
| 11 | 
            +
                  prop :image
         | 
| 12 | 
            +
                  prop :link_button
         | 
| 13 | 
            +
                  prop :link_button_url
         | 
| 14 | 
            +
                  prop :orientation, type: Playbook::Props::Enum,
         | 
| 15 | 
            +
                                     values: %w[horizontal vertical],
         | 
| 16 | 
            +
                                     default: "vertical"
         | 
| 17 | 
            +
                  prop :primary_button
         | 
| 18 | 
            +
                  prop :primary_button_url
         | 
| 19 | 
            +
                  prop :size, type: Playbook::Props::Enum,
         | 
| 20 | 
            +
                              values: %w[sm md lg],
         | 
| 21 | 
            +
                              default: "md"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  SIZE_CONFIGS = {
         | 
| 24 | 
            +
                    sm: {
         | 
| 25 | 
            +
                      vertical: {
         | 
| 26 | 
            +
                        image_width: "100px",
         | 
| 27 | 
            +
                        title_size: 4,
         | 
| 28 | 
            +
                        title_padding: "xxs",
         | 
| 29 | 
            +
                        description_pad: "sm",
         | 
| 30 | 
            +
                        button_size: "sm",
         | 
| 31 | 
            +
                        button_margin: "xs",
         | 
| 32 | 
            +
                        scss_class: "sm-state-vertical",
         | 
| 33 | 
            +
                        flex_direction: "column",
         | 
| 34 | 
            +
                      },
         | 
| 35 | 
            +
                      horizontal: {
         | 
| 36 | 
            +
                        image_width: "100px",
         | 
| 37 | 
            +
                        title_size: 4,
         | 
| 38 | 
            +
                        title_padding: "xxs",
         | 
| 39 | 
            +
                        description_pad: "sm",
         | 
| 40 | 
            +
                        button_size: "sm",
         | 
| 41 | 
            +
                        button_margin: "xs",
         | 
| 42 | 
            +
                        scss_class: "sm-state-horizontal",
         | 
| 43 | 
            +
                        flex_direction: "row",
         | 
| 44 | 
            +
                      },
         | 
| 45 | 
            +
                    },
         | 
| 46 | 
            +
                    md: {
         | 
| 47 | 
            +
                      vertical: {
         | 
| 48 | 
            +
                        image_width: "140px",
         | 
| 49 | 
            +
                        title_size: 3,
         | 
| 50 | 
            +
                        title_padding: "xs",
         | 
| 51 | 
            +
                        description_pad: "md",
         | 
| 52 | 
            +
                        button_size: "md",
         | 
| 53 | 
            +
                        button_margin: "sm",
         | 
| 54 | 
            +
                        scss_class: "md-state-vertical",
         | 
| 55 | 
            +
                        flex_direction: "column",
         | 
| 56 | 
            +
                      },
         | 
| 57 | 
            +
                      horizontal: {
         | 
| 58 | 
            +
                        image_width: "140px",
         | 
| 59 | 
            +
                        title_size: 3,
         | 
| 60 | 
            +
                        title_padding: "xs",
         | 
| 61 | 
            +
                        description_pad: "md",
         | 
| 62 | 
            +
                        button_size: "md",
         | 
| 63 | 
            +
                        button_margin: "sm",
         | 
| 64 | 
            +
                        scss_class: "md-state-horizontal",
         | 
| 65 | 
            +
                        flex_direction: "row",
         | 
| 66 | 
            +
                      },
         | 
| 67 | 
            +
                    },
         | 
| 68 | 
            +
                    lg: {
         | 
| 69 | 
            +
                      vertical: {
         | 
| 70 | 
            +
                        image_width: "100%",
         | 
| 71 | 
            +
                        title_size: 1,
         | 
| 72 | 
            +
                        title_padding: "sm",
         | 
| 73 | 
            +
                        description_pad: "lg",
         | 
| 74 | 
            +
                        button_size: "md",
         | 
| 75 | 
            +
                        button_margin: "md",
         | 
| 76 | 
            +
                        scss_class: "lg-state-vertical",
         | 
| 77 | 
            +
                        flex_direction: "column",
         | 
| 78 | 
            +
                      },
         | 
| 79 | 
            +
                      horizontal: {
         | 
| 80 | 
            +
                        image_width: "100%",
         | 
| 81 | 
            +
                        title_size: 2,
         | 
| 82 | 
            +
                        title_padding: "sm",
         | 
| 83 | 
            +
                        description_pad: "lg",
         | 
| 84 | 
            +
                        button_size: "md",
         | 
| 85 | 
            +
                        button_margin: "md",
         | 
| 86 | 
            +
                        scss_class: "lg-state-horizontal",
         | 
| 87 | 
            +
                        flex_direction: "row",
         | 
| 88 | 
            +
                      },
         | 
| 89 | 
            +
                    },
         | 
| 90 | 
            +
                  }.freeze
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  def classname
         | 
| 93 | 
            +
                    generate_classname("pb_empty_state_kit")
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  def config
         | 
| 97 | 
            +
                    SIZE_CONFIGS[size.to_sym][orientation.to_sym]
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  def default_image_data_uri
         | 
| 101 | 
            +
                    svg_path = __dir__.then { |d| File.join(d, "docs", "default_image", "computer_fly_no_branding.svg") }
         | 
| 102 | 
            +
                    svg      = File.read(svg_path)
         | 
| 103 | 
            +
                    encoded  = ERB::Util.url_encode(svg)
         | 
| 104 | 
            +
                    "data:image/svg+xml,#{encoded}"
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  def padding_size
         | 
| 108 | 
            +
                    size == "sm" ? "xs" : "xl"
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  def flex_align
         | 
| 112 | 
            +
                    case alignment
         | 
| 113 | 
            +
                    when "left"
         | 
| 114 | 
            +
                      "start"
         | 
| 115 | 
            +
                    when "right"
         | 
| 116 | 
            +
                      "end"
         | 
| 117 | 
            +
                    else
         | 
| 118 | 
            +
                      "center"
         | 
| 119 | 
            +
                    end
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
            end
         | 
| @@ -9,10 +9,23 @@ | |
| 9 9 | 
             
                border: none;
         | 
| 10 10 | 
             
                width: 0;
         | 
| 11 11 | 
             
              }
         | 
| 12 | 
            +
              &.error {
         | 
| 13 | 
            +
                [class^='pb_card_kit'] {
         | 
| 14 | 
            +
                  border-color: $error;
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
                [class^='pb_body_kit'][status="negative"] {
         | 
| 17 | 
            +
                  margin-top: $space_xs;
         | 
| 18 | 
            +
                }
         | 
| 19 | 
            +
              }
         | 
| 12 20 | 
             
            }
         | 
| 13 21 |  | 
| 14 22 | 
             
            .dark [class*='pb_file_upload_kit'] {
         | 
| 15 23 | 
             
              [class*='pb_card_kit'] {
         | 
| 16 24 | 
             
                border: 1px $text_dk_lighter dashed;
         | 
| 17 25 | 
             
              }
         | 
| 26 | 
            +
              &.error {
         | 
| 27 | 
            +
                [class^='pb_card_kit'] {
         | 
| 28 | 
            +
                  border-color: $error_dark;
         | 
| 29 | 
            +
                }
         | 
| 30 | 
            +
              }
         | 
| 18 31 | 
             
            }
         | 
| @@ -22,6 +22,7 @@ type FileUploadProps = { | |
| 22 22 | 
             
              maxSize?: number,
         | 
| 23 23 | 
             
              onFilesAccepted: Callback<File, File>,
         | 
| 24 24 | 
             
              onFilesRejected: (error: string, files: readonly FileRejection[]) => void,
         | 
| 25 | 
            +
              error?: string,
         | 
| 25 26 | 
             
            }
         | 
| 26 27 |  | 
| 27 28 | 
             
            const getFormattedFileSize = (fileSize: number): string => {
         | 
| @@ -36,6 +37,7 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => { | |
| 36 37 | 
             
                customMessage,
         | 
| 37 38 | 
             
                dark = false,
         | 
| 38 39 | 
             
                data = {},
         | 
| 40 | 
            +
                error,
         | 
| 39 41 | 
             
                htmlOptions = {},
         | 
| 40 42 | 
             
                maxSize,
         | 
| 41 43 | 
             
                onFilesAccepted = noop,
         | 
| @@ -100,7 +102,7 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => { | |
| 100 102 |  | 
| 101 103 | 
             
              return (
         | 
| 102 104 | 
             
                <div
         | 
| 103 | 
            -
                    className={classnames(buildCss('pb_file_upload_kit'), globalProps(props), className)}
         | 
| 105 | 
            +
                    className={classnames(buildCss('pb_file_upload_kit'), { 'error': error }, globalProps(props), className)}
         | 
| 104 106 | 
             
                    {...dataProps}
         | 
| 105 107 | 
             
                    {...htmlProps}
         | 
| 106 108 | 
             
                    {...getRootProps()}
         | 
| @@ -118,6 +120,14 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => { | |
| 118 120 | 
             
                      }
         | 
| 119 121 | 
             
                    </Body>
         | 
| 120 122 | 
             
                  </Card>
         | 
| 123 | 
            +
                  {error && (
         | 
| 124 | 
            +
                    <Body
         | 
| 125 | 
            +
                        dark={dark}
         | 
| 126 | 
            +
                        marginTop="xxs"
         | 
| 127 | 
            +
                        status="negative"
         | 
| 128 | 
            +
                        text={error}
         | 
| 129 | 
            +
                    />
         | 
| 130 | 
            +
                  )}
         | 
| 121 131 | 
             
                </div>
         | 
| 122 132 | 
             
              )
         | 
| 123 133 | 
             
            }
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= pb_rails("file_upload", props: {id: "error",  error: raw(pb_rails("icon", props: { icon: "warning" }) + " Please upload a valid file")}) %>
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            import React, { useState } from 'react'
         | 
| 2 | 
            +
            import FileUpload from '../_file_upload'
         | 
| 3 | 
            +
            import List from '../../pb_list/_list'
         | 
| 4 | 
            +
            import ListItem from '../../pb_list/_list_item'
         | 
| 5 | 
            +
            import Icon from '../../pb_icon/_icon'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            const AcceptedFilesList = ({ files }) => (
         | 
| 8 | 
            +
              <List>
         | 
| 9 | 
            +
                {files.map((file) => (
         | 
| 10 | 
            +
                  <ListItem key={file.name}>{file.name}</ListItem>
         | 
| 11 | 
            +
                ))}
         | 
| 12 | 
            +
              </List>
         | 
| 13 | 
            +
            )
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            const FileUploadError = (props) => {
         | 
| 16 | 
            +
              const [filesToUpload, setFilesToUpload] = useState([])
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              const handleOnFilesAccepted = (files) => {
         | 
| 19 | 
            +
                setFilesToUpload([...filesToUpload, ...files])
         | 
| 20 | 
            +
              }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              const error = (<>
         | 
| 23 | 
            +
                <Icon icon="warning" /> Please upload a valid file
         | 
| 24 | 
            +
              </>)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              return (
         | 
| 27 | 
            +
                <div>
         | 
| 28 | 
            +
                  <AcceptedFilesList
         | 
| 29 | 
            +
                      files={filesToUpload}
         | 
| 30 | 
            +
                      {...props}
         | 
| 31 | 
            +
                  />
         | 
| 32 | 
            +
                  <FileUpload
         | 
| 33 | 
            +
                      error={error}
         | 
| 34 | 
            +
                      onFilesAccepted={handleOnFilesAccepted}
         | 
| 35 | 
            +
                      {...props}
         | 
| 36 | 
            +
                  />
         | 
| 37 | 
            +
                </div>
         | 
| 38 | 
            +
              )
         | 
| 39 | 
            +
            }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            export default FileUploadError
         | 
| @@ -3,6 +3,7 @@ examples: | |
| 3 3 | 
             
              rails:
         | 
| 4 4 | 
             
              - file_upload_default: File Upload
         | 
| 5 5 | 
             
              - file_upload_custom: Custom
         | 
| 6 | 
            +
              - file_upload_error: Error
         | 
| 6 7 |  | 
| 7 8 | 
             
              react:
         | 
| 8 9 | 
             
              - file_upload_default: Default List of files to upload
         | 
| @@ -10,3 +11,4 @@ examples: | |
| 10 11 | 
             
              - file_upload_custom_message: Add a custom message
         | 
| 11 12 | 
             
              - file_upload_custom_description: Add your one accepted files description
         | 
| 12 13 | 
             
              - file_upload_max_size: Set a file size limit
         | 
| 14 | 
            +
              - file_upload_error: Error
         |