playbook_ui 14.5.0.pre.alpha.PLAY1485selectablecardoverflowoutlinebug4097 → 14.5.0.pre.alpha.PLAY1485selectablecardoverflowoutlinebug4216

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +25 -7
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_custom_cell.jsx +72 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_custom_cell.md +5 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -0
  7. data/app/pb_kits/playbook/pb_card/_card.tsx +5 -1
  8. data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +5 -1
  9. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb +30 -7
  10. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md +0 -2
  11. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +84 -3
  12. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +28 -5
  13. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_clear_selection.jsx +45 -0
  14. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_clear_selection.md +1 -0
  15. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.html.erb +9 -0
  16. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.jsx +33 -0
  17. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.html.erb +10 -0
  18. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.jsx +34 -0
  19. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.md +1 -0
  20. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +5 -0
  21. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -0
  22. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +10 -1
  23. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +1 -1
  24. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +2 -2
  25. data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.tsx +2 -0
  26. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +2 -0
  27. data/app/pb_kits/playbook/pb_filter/Filter/FiltersPopover.tsx +4 -1
  28. data/app/pb_kits/playbook/pb_filter/docs/_filter_popover_props.html.erb +41 -0
  29. data/app/pb_kits/playbook/pb_filter/docs/_filter_popover_props.jsx +71 -0
  30. data/app/pb_kits/playbook/pb_filter/docs/_filter_popover_props_rails.md +1 -0
  31. data/app/pb_kits/playbook/pb_filter/docs/_filter_popover_props_react.md +1 -0
  32. data/app/pb_kits/playbook/pb_filter/docs/example.yml +3 -0
  33. data/app/pb_kits/playbook/pb_filter/docs/index.js +1 -0
  34. data/app/pb_kits/playbook/pb_filter/filter.html.erb +2 -2
  35. data/app/pb_kits/playbook/pb_filter/filter.rb +2 -0
  36. data/app/pb_kits/playbook/pb_flex/_flex.tsx +3 -1
  37. data/app/pb_kits/playbook/pb_flex/_flex_item.tsx +8 -2
  38. data/app/pb_kits/playbook/pb_flex/flex_item.html.erb +3 -6
  39. data/app/pb_kits/playbook/pb_flex/flex_item.rb +7 -2
  40. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb +39 -0
  41. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.md +1 -0
  42. data/app/pb_kits/playbook/pb_form/docs/example.yml +1 -0
  43. data/app/pb_kits/playbook/pb_form/form.rb +2 -0
  44. data/app/pb_kits/playbook/pb_form/formHelper.js +27 -0
  45. data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.scss +169 -65
  46. data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.test.js +5 -5
  47. data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.tsx +15 -9
  48. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/_multiple_users_stacked_size.html.erb +336 -0
  49. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/_multiple_users_stacked_size.jsx +97 -0
  50. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/example.yml +2 -0
  51. data/app/pb_kits/playbook/pb_multiple_users_stacked/docs/index.js +1 -0
  52. data/app/pb_kits/playbook/pb_multiple_users_stacked/multiple_users_stacked.html.erb +28 -6
  53. data/app/pb_kits/playbook/pb_multiple_users_stacked/multiple_users_stacked.rb +31 -1
  54. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +86 -18
  55. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +15 -6
  56. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_preferred_countries.md +1 -1
  57. data/app/pb_kits/playbook/pb_phone_number_input/intlTelInput.scss +849 -931
  58. data/app/pb_kits/playbook/pb_phone_number_input/types.d.ts +4 -1
  59. data/app/pb_kits/playbook/pb_popover/_popover.tsx +6 -2
  60. data/app/pb_kits/playbook/pb_popover/docs/_popover_default.html.erb +1 -1
  61. data/app/pb_kits/playbook/pb_popover/popover.rb +3 -1
  62. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +66 -2
  63. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.tsx +1 -0
  64. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -1
  65. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.rb +5 -1
  66. data/app/pb_kits/playbook/utilities/globalPropNames.mjs +3 -0
  67. data/app/pb_kits/playbook/utilities/globalProps.ts +39 -2
  68. data/dist/chunks/_typeahead-BhHnXJjy.js +22 -0
  69. data/dist/chunks/_weekday_stacked-B9Sy5PN8.js +45 -0
  70. data/dist/chunks/{lib-CEpcaI8y.js → lib-D-mTv-kp.js} +1 -1
  71. data/dist/chunks/{pb_form_validation-D9zkwt2b.js → pb_form_validation-BkWGwJsl.js} +1 -1
  72. data/dist/chunks/vendor.js +1 -1
  73. data/dist/playbook-doc.js +1 -1
  74. data/dist/playbook-rails-react-bindings.js +1 -1
  75. data/dist/playbook-rails.js +1 -1
  76. data/dist/playbook.css +1 -1
  77. data/lib/playbook/kit_base.rb +21 -1
  78. data/lib/playbook/pb_forms_helper.rb +3 -1
  79. data/lib/playbook/version.rb +1 -1
  80. metadata +24 -6
  81. data/dist/chunks/_typeahead-C9g4qCcE.js +0 -22
  82. data/dist/chunks/_weekday_stacked-B0Zid7Rv.js +0 -45
@@ -13,13 +13,18 @@ module Playbook
13
13
  prop :default_value
14
14
  prop :blank_selection, type: Playbook::Props::String,
15
15
  default: ""
16
+ prop :variant, type: Playbook::Props::Enum,
17
+ values: %w[default subtle],
18
+ default: "default"
19
+ prop :separators, type: Playbook::Props::Boolean,
20
+ default: true
16
21
 
17
22
  def data
18
23
  Hash(prop(:data)).merge(pb_dropdown: true)
19
24
  end
20
25
 
21
26
  def classname
22
- generate_classname("pb_dropdown")
27
+ generate_classname("pb_dropdown", variant, separators_class, separator: " ")
23
28
  end
24
29
 
25
30
  private
@@ -32,6 +37,10 @@ module Playbook
32
37
  default_value.present? ? default_value.transform_keys(&:to_s)["id"] : ""
33
38
  end
34
39
 
40
+ def separators_class
41
+ separators ? "" : "separators_hidden"
42
+ end
43
+
35
44
  def options_with_blank
36
45
  blank_selection.present? ? [{ id: "", value: "", label: blank_selection }] + options : options
37
46
  end
@@ -62,7 +62,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
62
62
  const focusedClass = isFocused && "focused";
63
63
 
64
64
  const selectedClass = `${
65
- selected.label === option.label
65
+ selected?.label === option.label
66
66
  ? "selected"
67
67
  : "list"
68
68
  }`;
@@ -73,7 +73,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
73
73
  !autocomplete && "select_only"
74
74
  );
75
75
 
76
- const customDisplayPlaceholder = selected.label ? (
76
+ const customDisplayPlaceholder = selected?.label ? (
77
77
  <b>{selected.label}</b>
78
78
  ) : autocomplete ? (
79
79
  ""
@@ -83,7 +83,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
83
83
  "Select..."
84
84
  );
85
85
 
86
- const defaultDisplayPlaceholder = selected.label
86
+ const defaultDisplayPlaceholder = selected?.label
87
87
  ? selected.label
88
88
  : autocomplete
89
89
  ? ""
@@ -34,6 +34,7 @@ const FilterDouble = ({
34
34
  maxHeight,
35
35
  minWidth,
36
36
  placement,
37
+ popoverProps,
37
38
  ...bgProps
38
39
  }: FilterDoubleProps): React.ReactElement => (
39
40
  <FilterBackground
@@ -49,6 +50,7 @@ const FilterDouble = ({
49
50
  maxHeight={maxHeight}
50
51
  minWidth={minWidth}
51
52
  placement={placement}
53
+ popoverProps={popoverProps}
52
54
  >
53
55
  {children}
54
56
  </FiltersPopover>
@@ -33,6 +33,7 @@ const FilterSingle = ({
33
33
  maxHeight,
34
34
  minWidth,
35
35
  placement,
36
+ popoverProps,
36
37
  ...bgProps
37
38
  }: FilterSingleProps): React.ReactElement => {
38
39
  return (
@@ -52,6 +53,7 @@ const FilterSingle = ({
52
53
  maxHeight={maxHeight}
53
54
  minWidth={minWidth}
54
55
  placement={placement}
56
+ popoverProps={popoverProps}
55
57
  >
56
58
  {children}
57
59
  </FiltersPopover>
@@ -2,6 +2,7 @@ import React, { ReactNode, useState } from 'react'
2
2
 
3
3
  import CircleIconButton from '../../pb_circle_icon_button/_circle_icon_button'
4
4
  import PbReactPopover from '../../pb_popover/_popover'
5
+ import { GenericObject } from '../../types'
5
6
 
6
7
  type FiltersPopoverProps = {
7
8
  children?: React.ReactChild[] | React.ReactChild | (({closePopover}: {closePopover: () => void}) => ReactNode),
@@ -9,8 +10,9 @@ type FiltersPopoverProps = {
9
10
  maxHeight?: string,
10
11
  minWidth?: string,
11
12
  placement?: "top" | "right" | "bottom" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end",
13
+ popoverProps?: GenericObject,
12
14
  }
13
- const FiltersPopover = ({ children, dark, maxHeight, minWidth, placement = "bottom-start" }: FiltersPopoverProps): React.ReactElement => {
15
+ const FiltersPopover = ({ children, dark, maxHeight, minWidth, placement = "bottom-start", popoverProps }: FiltersPopoverProps): React.ReactElement => {
14
16
  const [hide, updateHide] = useState(true)
15
17
  const toggle = () => updateHide(!hide)
16
18
 
@@ -33,6 +35,7 @@ const FiltersPopover = ({ children, dark, maxHeight, minWidth, placement = "bott
33
35
  reference={filterButton}
34
36
  shouldClosePopover={updateHide}
35
37
  show={!hide}
38
+ {...popoverProps}
36
39
  >
37
40
  <div className="pb-form">
38
41
  {typeof children === 'function'
@@ -0,0 +1,41 @@
1
+ <%=
2
+ pb_rails("filter", props: {
3
+ id: "filter_popover_props",
4
+ position: "top",
5
+ filters: [
6
+ { name: "name", value: "John Wick" },
7
+ { name: "city", value: "San Francisco"}
8
+ ],
9
+ sort_menu: [
10
+ { item: "Popularity", link: "?q[sorts]=managers_popularity+asc", active: true, direction: "desc" },
11
+ { item: "Mananger's Title", link: "?q[sorts]=managers_title+asc", active: false },
12
+ { item: "Manager's Name", link: "?q[sorts]=managers_name+asc", active: false },
13
+ ],
14
+ template: "default",
15
+ results: 1,
16
+ popover_props: { width: "250px" },
17
+ }) do
18
+ %>
19
+ <%
20
+ example_collection = [
21
+ OpenStruct.new(name: "USA", value: 1),
22
+ OpenStruct.new(name: "Canada", value: 2),
23
+ OpenStruct.new(name: "Brazil", value: 3),
24
+ OpenStruct.new(name: "Philippines", value: 4),
25
+ OpenStruct.new(name: "A galaxy far far away, like really far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far away...", value: 5)
26
+ ]
27
+ %>
28
+ <%= pb_rails("form", props: { form_system_options: { scope: :example, method: :get } }) do |form| %>
29
+ <%= form.text_field :example_text_field, props: { label: true } %>
30
+ <%= form.collection_select :example_collection_select, example_collection, :value, :name, props: {max_width: "sm", label: true } %>
31
+
32
+ <%= form.actions do |action| %>
33
+ <%= action.submit props: {
34
+ text: "Apply",
35
+ data: {
36
+ disable_with: "pb_rails('icon', props: { icon: 'spinner', spin: true, fixed_width: true })Searching...".html_safe
37
+ },}%>
38
+ <%= action.button props: { type: "reset", text: "Clear", variant: "secondary" } %>
39
+ <% end %>
40
+ <% end %>
41
+ <% end %>
@@ -0,0 +1,71 @@
1
+ import React from 'react'
2
+ import { Button, Filter, Flex, Select, TextInput } from 'playbook-ui'
3
+
4
+ const FilterPopoverProps = (props) => {
5
+ const options = [
6
+ { value: 'USA' },
7
+ { value: 'Canada' },
8
+ { value: 'Brazil' },
9
+ { value: 'Philippines' },
10
+ { value: 'A galaxy far far away, like really far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far far away...' },
11
+ ]
12
+
13
+ const popoverProps = {
14
+ width: "250px"
15
+ }
16
+
17
+ return (
18
+ <Filter
19
+ {...props}
20
+ double
21
+ filters={{
22
+ 'Full Name': 'John Wick',
23
+ 'City': 'San Francisco',
24
+ }}
25
+ popoverProps={popoverProps}
26
+ results={1}
27
+ sortOptions={{
28
+ popularity: 'Popularity',
29
+ // eslint-disable-next-line
30
+ manager_title: 'Manager\'s Title',
31
+ // eslint-disable-next-line
32
+ manager_name: 'Manager\'s Name',
33
+ }}
34
+ sortValue={[{ name: 'popularity', dir: 'desc' }]}
35
+ >
36
+ {({ closePopover }) => (
37
+ <form>
38
+ <TextInput
39
+ label="Example Text Field"
40
+ placeholder="Enter Text"
41
+ {...props}
42
+ />
43
+ <Select
44
+ blankSelection="Select One..."
45
+ label="Example Collection Select"
46
+ name="Collection Select"
47
+ options={options}
48
+ {...props}
49
+ />
50
+ <Flex
51
+ spacing="between"
52
+ {...props}
53
+ >
54
+ <Button
55
+ onClick={closePopover}
56
+ text="Apply"
57
+ {...props}
58
+ />
59
+ <Button
60
+ text="Clear"
61
+ variant="secondary"
62
+ {...props}
63
+ />
64
+ </Flex>
65
+ </form>
66
+ )}
67
+ </Filter>
68
+ )
69
+ }
70
+
71
+ export default FilterPopoverProps
@@ -0,0 +1 @@
1
+ This kit uses the [Popover kit](https://playbook.powerapp.cloud/kits/popover) under the hood for the Filter Popover which comes with its own set of props. If you want to apply certain Popover props to that underlying kit, you can do so by using the optional `popover_props` prop. This prop must be an object that contains valid Popover props. For a full list of Popover props, see [here](https://playbook.powerapp.cloud/kits/popover).
@@ -0,0 +1 @@
1
+ This kit uses the [Popover kit](https://playbook.powerapp.cloud/kits/popover/react) under the hood for the Filter Popover which comes with its own set of props. If you want to apply certain Popover props to that underlying kit, you can do so by using the optional `popoverProps` prop. This prop must be an object that contains valid Popover props. For a full list of Popover props, see [here](https://playbook.powerapp.cloud/kits/popover/react).
@@ -10,6 +10,7 @@ examples:
10
10
  - filter_max_width: Max Width for Popover Inside of Filter
11
11
  - filter_max_height: Max Height for Popover Inside of Filter
12
12
  - filter_placement: Filter Placement
13
+ - filter_popover_props: Popover Props
13
14
 
14
15
  react:
15
16
  - filter_default: Default
@@ -21,3 +22,5 @@ examples:
21
22
  - filter_max_width: Max Width for Popover Inside of Filter
22
23
  - filter_max_height: Max Height for Popover Inside of Filter
23
24
  - filter_placement: Filter Placement
25
+ - filter_popover_props: Popover Props
26
+
@@ -7,3 +7,4 @@ export { default as SortOnly } from './_sort_only.jsx'
7
7
  export { default as FilterMaxWidth } from './_filter_max_width.jsx'
8
8
  export { default as FilterMaxHeight } from './_filter_max_height.jsx'
9
9
  export { default as FilterPlacement } from './_filter_placement.jsx'
10
+ export { default as FilterPopoverProps } from './_filter_popover_props.jsx'
@@ -71,13 +71,13 @@
71
71
  <% end %>
72
72
 
73
73
  <% if object.template != "sort_only"%>
74
- <%= pb_rails("popover", props: {max_height: object.max_height, min_width: object.min_width, close_on_click: "outside", trigger_element_id: "filter#{object.id}", tooltip_id: "filter-form#{object.id}", position: object.placement }) do %>
74
+ <%= pb_rails("popover", props: {max_height: object.max_height, min_width: object.min_width, close_on_click: "outside", trigger_element_id: "filter#{object.id}", tooltip_id: "filter-form#{object.id}", position: object.placement }.merge(object.popover_props)) do %>
75
75
  <%= content %>
76
76
  <% end %>
77
77
  <%end%>
78
78
 
79
79
  <% if object.template != "filter_only"%>
80
- <%= pb_rails("popover", props: {max_height: object.max_height, classname: "pb_filter_sort_menu", close_on_click: "outside", trigger_element_id: "sort-button#{object.id}", tooltip_id: "sort-filter-btn-tooltip#{object.id}", position: object.placement , padding: 'none'}) do %>
80
+ <%= pb_rails("popover", props: {max_height: object.max_height, classname: "pb_filter_sort_menu", close_on_click: "outside", trigger_element_id: "sort-button#{object.id}", tooltip_id: "sort-filter-btn-tooltip#{object.id}", position: object.placement , padding: 'none'}.merge(object.popover_props)) do %>
81
81
  <%= pb_rails("list") do %>
82
82
  <% object.sort_menu.each do |item| %>
83
83
  <%= pb_rails("list/item") do%> <%= pb_rails("button", props: {variant: "link" ,classname: "p-0", text: item[:item], link: item[:link]}) %><% end %>
@@ -15,6 +15,8 @@ module Playbook
15
15
  prop :placement, type: Playbook::Props::Enum,
16
16
  values: %w[top bottom left right top-start top-end bottom-start bottom-end right-start right-end left-start left-end],
17
17
  default: "bottom-start"
18
+ prop :popover_props, type: Playbook::Props::HashProp,
19
+ default: {}
18
20
 
19
21
  def classname
20
22
  generate_classname("pb_filter_kit").rstrip
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
- import { GlobalProps, globalProps } from '../utilities/globalProps'
4
+ import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
5
5
  import { GenericObject, Sizes } from '../types'
6
6
 
7
7
  type FlexProps = {
@@ -61,6 +61,7 @@ const Flex = (props: FlexProps): React.ReactElement => {
61
61
  const alignSelfClass = alignSelf !== 'none' ? `align_self_${alignSelf}` : ''
62
62
  const dataProps = buildDataProps(data)
63
63
  const htmlProps = buildHtmlProps(htmlOptions)
64
+ const dynamicInlineProps = globalInlineProps(props)
64
65
 
65
66
 
66
67
  return (
@@ -83,6 +84,7 @@ const Flex = (props: FlexProps): React.ReactElement => {
83
84
  globalProps(props),
84
85
  className
85
86
  )}
87
+ style={dynamicInlineProps}
86
88
  {...dataProps}
87
89
  {...htmlProps}
88
90
  >
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildCss, buildHtmlProps } from '../utilities/props'
4
- import { globalProps, GlobalProps } from '../utilities/globalProps'
4
+ import { globalProps, GlobalProps, globalInlineProps} from '../utilities/globalProps'
5
5
  type FlexItemPropTypes = {
6
6
  children: React.ReactNode[] | React.ReactNode,
7
7
  fixedSize?: string,
@@ -35,14 +35,20 @@ const FlexItem = (props: FlexItemPropTypes): React.ReactElement => {
35
35
  const fixedStyle =
36
36
  fixedSize !== undefined ? { flexBasis: `${fixedSize}` } : null
37
37
  const orderClass = order !== 'none' ? `order_${order}` : null
38
+ const dynamicInlineProps = globalInlineProps(props)
39
+ const combinedStyles = {
40
+ ...fixedStyle,
41
+ ...dynamicInlineProps
42
+ }
38
43
 
39
44
  const htmlProps = buildHtmlProps(htmlOptions)
40
45
 
46
+
41
47
  return (
42
48
  <div
43
49
  {...htmlProps}
44
50
  className={classnames(buildCss('pb_flex_item_kit', growClass, shrinkClass, flexClass, displayFlexClass), orderClass, alignSelfClass, globalProps(props), className)}
45
- style={fixedStyle}
51
+ style={combinedStyles}
46
52
  >
47
53
  {children}
48
54
  </div>
@@ -1,8 +1,5 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- style: object.style_value,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:div,
2
+ style: object.inline_styles
3
+ ) do %>
7
4
  <%= content.presence %>
8
5
  <% end %>
@@ -20,8 +20,13 @@ module Playbook
20
20
  generate_classname("pb_flex_item_kit", fixed_size_class, grow_class, shrink_class, display_flex_class) + align_self_class
21
21
  end
22
22
 
23
- def style_value
24
- "flex-basis: #{fixed_size};" if fixed_size.present?
23
+ def inline_styles
24
+ styles = []
25
+ styles << "flex-basis: #{fixed_size};" if fixed_size.present?
26
+ styles << "height: #{height};" if height.present?
27
+ styles << "min-height: #{min_height};" if min_height.present?
28
+ styles << "max-height: #{max_height};" if max_height.present?
29
+ styles.join(" ")
25
30
  end
26
31
 
27
32
  private
@@ -0,0 +1,39 @@
1
+ <%= pb_form_with(scope: :example, url: "", method: :get, loading: true) do |form| %>
2
+ <%= form.text_field :example_text_field, props: { label: true } %>
3
+
4
+ <%= form.actions do |action| %>
5
+ <%= action.submit %>
6
+ <%= action.button props: { type: "reset", text: "Cancel", variant: "secondary" } %>
7
+ <% end %>
8
+ <% end %>
9
+
10
+ <script>
11
+ const loadingForm = document.querySelector(".pb_form_loading")
12
+ if (loadingForm) {
13
+ loadingForm.addEventListener("submit", function(event) {
14
+ event.preventDefault();
15
+
16
+ const submitButton = event['submitter'];
17
+ const cancelButton = event['target'].querySelector('button[type="reset"]');
18
+
19
+ if (submitButton) {
20
+ let currentClass = submitButton.className;
21
+ let newClass = currentClass.replace("_disabled_loading", "_enabled");
22
+
23
+ let cancelClass = cancelButton ? cancelButton.className : "";
24
+ let newCancelClass = cancelClass.replace("_disabled", "_enabled");
25
+
26
+ setTimeout(function() {
27
+ submitButton.disabled = false;
28
+ submitButton.className = currentClass;
29
+
30
+ if (cancelButton) {
31
+ cancelButton.disabled = false;
32
+ cancelButton.className = cancelClass;
33
+ }
34
+ }, 5000);
35
+ }
36
+ });
37
+ }
38
+ </script>
39
+
@@ -0,0 +1 @@
1
+ Pressing Submit will trigger a loading state where the button content is replaced by a spinner icon and the submit button will be disabled.
@@ -3,3 +3,4 @@ examples:
3
3
  rails:
4
4
  - form_form_with: Default
5
5
  - form_form_with_validate: Default + Validation
6
+ - form_form_with_loading: Default + Loading
@@ -7,6 +7,7 @@ module Playbook
7
7
  type: Playbook::Props::Base
8
8
  prop :form_system_options, deprecated: "Use options instead",
9
9
  type: Playbook::Props::Base
10
+ prop :loading, type: Playbook::Props::Boolean, default: false
10
11
  prop :options, type: Playbook::Props::Base
11
12
  prop :validate, type: Playbook::Props::Boolean, default: false
12
13
 
@@ -22,6 +23,7 @@ module Playbook
22
23
  aria: aria,
23
24
  class: classname,
24
25
  data: data,
26
+ loading: loading,
25
27
  validate: validate,
26
28
  }.merge(prop(:options) || prop(:form_system_options) || {})
27
29
  end
@@ -0,0 +1,27 @@
1
+ const formHelper = () => {
2
+ const loadingForm = document.querySelector(".pb_form_loading")
3
+ if (loadingForm) {
4
+ loadingForm.addEventListener("submit", function(event) {
5
+ const submitButton = event['submitter'];
6
+ const cancelButton = event['target'].querySelector('button[type="reset"]');
7
+
8
+ if (submitButton) {
9
+ let currentClass = submitButton.className;
10
+ let newClass = currentClass.replace("_enabled", "_disabled_loading");
11
+
12
+ let cancelClass = cancelButton ? cancelButton.className : "";
13
+ let newCancelClass = cancelClass.replace("_enabled", "_disabled");
14
+
15
+ submitButton.disabled = true;
16
+ submitButton.className = newClass;
17
+
18
+ if (cancelButton) {
19
+ cancelButton.disabled = true;
20
+ cancelButton.className = newCancelClass;
21
+ }
22
+ }
23
+ });
24
+ }
25
+ };
26
+
27
+ export default formHelper;