playbook_ui 8.2.0.pre.alpha2 → 8.2.1.pre.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -18
  3. data/app/pb_kits/playbook/_playbook.scss +1 -0
  4. data/app/pb_kits/playbook/data/menu.yml +2 -1
  5. data/app/pb_kits/playbook/index.js +1 -0
  6. data/app/pb_kits/playbook/pb_avatar/_avatar.jsx +14 -2
  7. data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +1 -1
  8. data/app/pb_kits/playbook/pb_avatar/avatar.rb +5 -2
  9. data/app/pb_kits/playbook/pb_avatar/avatar.test.js +5 -2
  10. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_default.html.erb +5 -0
  11. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_default.jsx +5 -0
  12. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_status.html.erb +4 -0
  13. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_status.jsx +4 -0
  14. data/app/pb_kits/playbook/pb_avatar_action_button/_avatar_action_button.jsx +6 -0
  15. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.html.erb +2 -1
  16. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.rb +2 -0
  17. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_actions.html.erb +4 -0
  18. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_actions.jsx +4 -0
  19. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_default.html.erb +2 -0
  20. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_default.jsx +2 -0
  21. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_on_click.jsx +2 -0
  22. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_onclick.html.erb +2 -0
  23. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_placement.html.erb +8 -0
  24. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_placement.jsx +8 -0
  25. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_tooltip.html.erb +2 -0
  26. data/app/pb_kits/playbook/pb_avatar_action_button/pb_avatar_action_button.test.js +31 -0
  27. data/app/pb_kits/playbook/pb_badge/_badge.jsx +26 -1
  28. data/app/pb_kits/playbook/pb_caption/_caption.jsx +3 -2
  29. data/app/pb_kits/playbook/pb_caption/caption.rb +1 -1
  30. data/app/pb_kits/playbook/pb_card/_card.jsx +18 -3
  31. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
  32. data/app/pb_kits/playbook/pb_card/card.rb +3 -0
  33. data/app/pb_kits/playbook/pb_card/docs/_card_tag.html.erb +25 -0
  34. data/app/pb_kits/playbook/pb_card/docs/_card_tag.jsx +59 -0
  35. data/app/pb_kits/playbook/pb_card/docs/example.yml +2 -0
  36. data/app/pb_kits/playbook/pb_card/docs/index.js +1 -0
  37. data/app/pb_kits/playbook/pb_checkbox/_checkbox.jsx +31 -9
  38. data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +28 -19
  39. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +11 -3
  40. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +6 -1
  41. data/app/pb_kits/playbook/pb_checkbox/checkbox.test.js +94 -0
  42. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom.jsx +0 -1
  43. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +7 -0
  44. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.jsx +16 -0
  45. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +2 -0
  46. data/app/pb_kits/playbook/pb_checkbox/docs/index.js +1 -0
  47. data/app/pb_kits/playbook/pb_date_picker/_date_picker.jsx +6 -1
  48. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.js +3 -0
  49. data/app/pb_kits/playbook/pb_dialog/_close_icon.jsx +23 -0
  50. data/app/pb_kits/playbook/pb_dialog/_dialog.html.erb +10 -0
  51. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +142 -0
  52. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +133 -0
  53. data/app/pb_kits/playbook/pb_dialog/_dialog_context.jsx +3 -0
  54. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +21 -0
  55. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +36 -0
  56. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +68 -0
  57. data/app/pb_kits/playbook/pb_dialog/dialog.rb +47 -0
  58. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +23 -0
  59. data/app/pb_kits/playbook/pb_dialog/dialog_header.rb +31 -0
  60. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.jsx +53 -0
  61. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.md +2 -0
  62. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.jsx +27 -0
  63. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.jsx +27 -0
  64. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.md +2 -0
  65. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.jsx +119 -0
  66. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.md +2 -0
  67. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.jsx +28 -0
  68. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.md +2 -0
  69. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_sizes.jsx +93 -0
  70. data/app/pb_kits/playbook/pb_dialog/docs/example.yml +10 -0
  71. data/app/pb_kits/playbook/pb_dialog/docs/index.js +6 -0
  72. data/app/pb_kits/playbook/pb_flex/_flex.jsx +6 -3
  73. data/app/pb_kits/playbook/pb_form/form_builder.rb +4 -2
  74. data/app/pb_kits/playbook/pb_form/form_builder/action_area.rb +14 -7
  75. data/app/pb_kits/playbook/pb_form/simple_form.html.erb +2 -4
  76. data/app/pb_kits/playbook/pb_form/simple_form.rb +4 -0
  77. data/app/pb_kits/playbook/pb_online_status/_online_status.jsx +2 -0
  78. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +1 -1
  79. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.jsx +4 -3
  80. data/app/pb_kits/playbook/pb_text_input/_text_input.jsx +3 -0
  81. data/app/pb_kits/playbook/pb_textarea/_textarea.jsx +3 -0
  82. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +9 -1
  83. data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +9 -0
  84. data/app/pb_kits/playbook/pb_typeahead/components/Input.jsx +43 -0
  85. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx +21 -11
  86. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.jsx +1 -0
  87. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.jsx +8 -3
  88. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +4 -4
  89. data/app/pb_kits/playbook/pb_user_badge/_user_badge.jsx +1 -1
  90. data/app/pb_kits/playbook/react_rails_kits.js +4 -0
  91. data/lib/playbook/version.rb +2 -1
  92. metadata +55 -27
  93. data/app/pb_kits/playbook/pb_form/form_builder/action_area.html.erb +0 -3
@@ -0,0 +1,27 @@
1
+ import React, { useState } from 'react'
2
+ import { Button, Dialog } from '../../'
3
+
4
+ const DialogScrollable = () => {
5
+ const [isOpen, setIsOpen] = useState(false)
6
+ const close = () => setIsOpen(false)
7
+ const open = () => setIsOpen(true)
8
+
9
+ return (
10
+ <>
11
+ <Button onClick={open}>{'Open Dialog'}</Button>
12
+ <Dialog
13
+ cancelButton="Cancel"
14
+ confirmButton="Okay"
15
+ onCancel={close}
16
+ onClose={close}
17
+ onConfirm={close}
18
+ opened={isOpen}
19
+ size="md"
20
+ text="At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
21
+ title="Header Title is the Title Prop"
22
+ />
23
+ </>
24
+ )
25
+ }
26
+
27
+ export default DialogScrollable
@@ -0,0 +1,2 @@
1
+ The dialog will create a scroll container automatically when the text exceeds the height of the page.
2
+ No prop or configuration is needed.
@@ -0,0 +1,119 @@
1
+ /* @flow */
2
+
3
+ import React, { useState } from 'react'
4
+ import { Button, Dialog, Flex } from '../../'
5
+
6
+ const useDialog = (visible = false) => {
7
+ const [opened, setOpened] = useState(visible)
8
+ const toggle = () => setOpened(!opened)
9
+
10
+ return [opened, toggle]
11
+ }
12
+
13
+ const DialogSeparators = () => {
14
+ const [headerSeparatorDialogOpened, toggleHeaderSeparatorDialog] = useDialog()
15
+ const [footerSeparatorDialogOpened, toggleFooterSeparatorDialog] = useDialog()
16
+ const [bothSeparatorsDialogOpened, toggleBothSeparatorsDialog] = useDialog()
17
+ const [
18
+ neitherSeparatorsDialogOpened,
19
+ toggleNeitherSeparatorsDialog,
20
+ ] = useDialog()
21
+
22
+ /* eslint-disable react/jsx-handler-names */
23
+
24
+ const dialogs = [
25
+ {
26
+ size: 'md',
27
+ text: 'Header Separator',
28
+ title: 'Header Separator ',
29
+ toggle: toggleHeaderSeparatorDialog,
30
+ visible: headerSeparatorDialogOpened,
31
+ header: true,
32
+ footer: false,
33
+ },
34
+ {
35
+ size: 'md',
36
+ text: 'Footer Separator',
37
+ title: 'Footer Separator',
38
+ toggle: toggleFooterSeparatorDialog,
39
+ visible: footerSeparatorDialogOpened,
40
+ header: false,
41
+ footer: true,
42
+ },
43
+ {
44
+ size: 'md',
45
+ text: 'Both Separators',
46
+ title: 'Both Separators',
47
+ toggle: toggleBothSeparatorsDialog,
48
+ visible: bothSeparatorsDialogOpened,
49
+ header: true,
50
+ footer: true,
51
+ },
52
+ {
53
+ size: 'md',
54
+ text: 'No Separators',
55
+ title: 'No Separators',
56
+ toggle: toggleNeitherSeparatorsDialog,
57
+ visible: neitherSeparatorsDialogOpened,
58
+ header: false,
59
+ footer: false,
60
+ },
61
+ ]
62
+
63
+ return (
64
+ <div>
65
+ <Flex>
66
+ <Button
67
+ id="sm"
68
+ marginRight="xl"
69
+ onClick={toggleHeaderSeparatorDialog}
70
+ >
71
+ {'Default'}
72
+ </Button>
73
+ <Button
74
+ marginRight="xl"
75
+ onClick={toggleFooterSeparatorDialog}
76
+ >
77
+ {'Footer Separator'}
78
+ </Button>
79
+ <Button
80
+ marginRight="xl"
81
+ onClick={toggleBothSeparatorsDialog}
82
+ >
83
+ {'Both Separators'}
84
+ </Button>
85
+ <Button
86
+ marginRight="xl"
87
+ onClick={toggleNeitherSeparatorsDialog}
88
+ >
89
+ {'No Separators'}
90
+ </Button>
91
+ </Flex>
92
+ <Flex>
93
+ {dialogs.map((dialog) => (
94
+ <Dialog
95
+ key={dialog.size}
96
+ opened={dialog.visible}
97
+ size={dialog.size}
98
+ >
99
+ <Dialog.Header separator={dialog.header}>
100
+ {dialog.title}
101
+ </Dialog.Header>
102
+ <Dialog.Body>{dialog.text}</Dialog.Body>
103
+ <Dialog.Footer separator={dialog.footer}>
104
+ <Button onClick={dialog.toggle}>{'Okay'}</Button>
105
+ <Button
106
+ onClick={dialog.toggle}
107
+ variant="link"
108
+ >
109
+ {'Cancel'}
110
+ </Button>
111
+ </Dialog.Footer>
112
+ </Dialog>
113
+ ))}
114
+ </Flex>
115
+ </div>
116
+ )
117
+ }
118
+
119
+ export default DialogSeparators
@@ -0,0 +1,2 @@
1
+ By default, the Dialog.Header will load with `separator={true}` and the Dialog.Footer will load with `separator={false}`.
2
+ To control it yourself, toggle the boolean prop as you wish.
@@ -0,0 +1,28 @@
1
+ import React, { useState } from 'react'
2
+ import { Button, Dialog } from '../../'
3
+
4
+ const DialogShouldCloseOnOverlay = () => {
5
+ const [isOpen, setIsOpen] = useState(false)
6
+ const close = () => setIsOpen(false)
7
+ const open = () => setIsOpen(true)
8
+
9
+ return (
10
+ <>
11
+ <Button onClick={open}>{'Open Dialog'}</Button>
12
+ <Dialog
13
+ cancelButton="Cancel"
14
+ confirmButton="Okay"
15
+ onCancel={close}
16
+ onClose={close}
17
+ onConfirm={close}
18
+ opened={isOpen}
19
+ shouldCloseOnOverlayClick={false}
20
+ size="sm"
21
+ text="Click on the overlay all day. I will stay open."
22
+ title="Neat Header"
23
+ />
24
+ </>
25
+ )
26
+ }
27
+
28
+ export default DialogShouldCloseOnOverlay
@@ -0,0 +1,2 @@
1
+ When shouldCloseOnOverlayClick is explicitly set to `false`, click events on the overlay will not close the modal.
2
+ By default, shouldCloseOnOverlayClick is set to true.
@@ -0,0 +1,93 @@
1
+ /* @flow */
2
+
3
+ import React, { useState } from 'react'
4
+ import { Button, Dialog, Flex } from '../../'
5
+
6
+ const useDialog = (visible = false) => {
7
+ const [opened, setOpened] = useState(visible)
8
+ const toggle = () => setOpened(!opened)
9
+
10
+ return [opened, toggle]
11
+ }
12
+
13
+ const DialogSizes = () => {
14
+ const [smDialogOpened, toggleSmDialog] = useDialog()
15
+ const [mdDialogOpened, toggleMdDialog] = useDialog()
16
+ const [lgDialogOpened, toggleLgDialog] = useDialog()
17
+
18
+ /* eslint-disable react/jsx-handler-names */
19
+
20
+ const dialogs = [
21
+ {
22
+ size: 'sm',
23
+ text: 'Body on small dialog',
24
+ title: 'Header on small dialog',
25
+ toggle: toggleSmDialog,
26
+ visible: smDialogOpened,
27
+ },
28
+ {
29
+ size: 'md',
30
+ text: 'Body on medium dialog',
31
+ title: 'Header on medium dialog',
32
+ toggle: toggleMdDialog,
33
+ visible: mdDialogOpened,
34
+ },
35
+ {
36
+ size: 'lg',
37
+ text: 'Body on large dialog',
38
+ title: 'Header on large dialog',
39
+ toggle: toggleLgDialog,
40
+ visible: lgDialogOpened,
41
+ },
42
+ ]
43
+
44
+ return (
45
+ <div>
46
+ <Flex>
47
+ <Button
48
+ id="sm"
49
+ marginRight="xl"
50
+ onClick={toggleSmDialog}
51
+ >
52
+ {'Small Dialog'}
53
+ </Button>
54
+ <Button
55
+ marginRight="xl"
56
+ onClick={toggleMdDialog}
57
+ >
58
+ {'Medium Dialog'}
59
+ </Button>
60
+ <Button
61
+ marginRight="xl"
62
+ onClick={toggleLgDialog}
63
+ >
64
+ {'Large Dialog'}
65
+ </Button>
66
+ </Flex>
67
+ <Flex>
68
+ {dialogs.map((dialog) => (
69
+ <Dialog
70
+ key={dialog.size}
71
+ onClose={dialog.toggle}
72
+ opened={dialog.visible}
73
+ size={dialog.size}
74
+ >
75
+ <Dialog.Header>{dialog.title}</Dialog.Header>
76
+ <Dialog.Body>{dialog.text}</Dialog.Body>
77
+ <Dialog.Footer>
78
+ <Button onClick={dialog.toggle}>{'Okay'}</Button>
79
+ <Button
80
+ onClick={dialog.toggle}
81
+ variant="link"
82
+ >
83
+ {'Cancel'}
84
+ </Button>
85
+ </Dialog.Footer>
86
+ </Dialog>
87
+ ))}
88
+ </Flex>
89
+ </div>
90
+ )
91
+ }
92
+
93
+ export default DialogSizes
@@ -0,0 +1,10 @@
1
+ examples:
2
+
3
+ rails:
4
+
5
+ react:
6
+ - dialog_default: Simple
7
+ - dialog_compound_components: Complex
8
+ - dialog_sizes: Sizes
9
+ - dialog_scrollable: Scrollable
10
+ - dialog_should_close_on_overlay: Overlay Click
@@ -0,0 +1,6 @@
1
+ export { default as DialogDefault } from './_dialog_default.jsx'
2
+ export { default as DialogCompoundComponents } from './_dialog_compound_components.jsx'
3
+ export { default as DialogSizes } from './_dialog_sizes.jsx'
4
+ export { default as DialogScrollable } from './_dialog_scrollable.jsx'
5
+ export { default as DialogSeparators } from './_dialog_separators.jsx'
6
+ export { default as DialogShouldCloseOnOverlay } from './_dialog_should_close_on_overlay.jsx'
@@ -1,6 +1,6 @@
1
1
  /* @flow */
2
2
 
3
- import React from 'react'
3
+ import React, { forwardRef } from 'react'
4
4
  import classnames from 'classnames'
5
5
  import { buildCss } from '../utilities/props'
6
6
  import { globalProps } from '../utilities/globalProps.js'
@@ -22,11 +22,12 @@ type FlexProps = {
22
22
  wrap?: boolean,
23
23
  }
24
24
 
25
- const Flex = (props: FlexProps) => {
25
+ const Flex = (props: FlexProps, ref: React.ElementRef<"div">) => {
26
26
  const {
27
27
  align = 'none',
28
28
  children,
29
29
  className,
30
+ id,
30
31
  inline = false,
31
32
  horizontal = 'left',
32
33
  justify = 'none',
@@ -70,10 +71,12 @@ const Flex = (props: FlexProps) => {
70
71
  globalProps(props),
71
72
  className
72
73
  )}
74
+ id={id}
75
+ ref={ref}
73
76
  >
74
77
  {children}
75
78
  </div>
76
79
  )
77
80
  }
78
81
 
79
- export default Flex
82
+ export default forwardRef(Flex)
@@ -19,9 +19,11 @@ module Playbook
19
19
  prepend(CollectionSelectField)
20
20
  prepend(CheckboxField)
21
21
  prepend(DatePickerField)
22
+ end
22
23
 
23
- def actions(&block)
24
- @template.render_component ActionArea.new(submit_default_value: submit_default_value, children: block)
24
+ def actions
25
+ @template.send(:view_context).content_tag :ol, class: "pb-form-actions" do
26
+ yield ActionArea.new(@template, submit_default_value)
25
27
  end
26
28
  end
27
29
  end
@@ -3,22 +3,29 @@
3
3
  module Playbook
4
4
  module PbForm
5
5
  module FormBuilder
6
- class ActionArea < Playbook::KitBase
7
- prop :submit_default_value, type: Playbook::Props::String
6
+ class ActionArea
7
+ def initialize(view_context, submit_default_value)
8
+ self.view_context = view_context
9
+ self.submit_default_value = submit_default_value
10
+ end
8
11
 
9
12
  def submit(value = nil, props: {})
10
13
  props[:type] ||= "submit"
14
+ props[:text] ||= value || submit_default_value
15
+
11
16
  button(value, props: props)
12
17
  end
13
18
 
14
19
  def button(value = nil, props:)
15
- props[:text] ||= value || submit_default_value
16
-
17
- content_tag(:li) do
18
- pb_rails("button", props: props)
20
+ view_context.content_tag(:li) do
21
+ view_context.pb_rails("button", props: props)
19
22
  end
20
23
  end
24
+
25
+ private
26
+
27
+ attr_accessor :view_context, :submit_default_value
21
28
  end
22
29
  end
23
30
  end
24
- end
31
+ end
@@ -1,6 +1,4 @@
1
- <%= simple_form_for model, options do |form| %>
2
- <% instance_exec form, &children %>
3
- <% end %>
1
+ <%= simple_form_for model, options, &method(:render_form) %>
4
2
 
5
3
  <% if validate %>
6
4
  <% content_for :pb_js do %>
@@ -10,4 +8,4 @@
10
8
  })
11
9
  <% end %>
12
10
  <% end %>
13
- <% end %>
11
+ <% end %>
@@ -48,6 +48,10 @@ module Playbook
48
48
  prop(:options).fetch(:html, {})
49
49
  end
50
50
 
51
+ def render_form(builder)
52
+ view_context.capture(builder, &children)
53
+ end
54
+
51
55
  def render_in(view_context, &_block)
52
56
  super(view_context, &nil)
53
57
  end
@@ -23,6 +23,8 @@ const OnlineStatus = (props: OnlineStatusProps) => {
23
23
  status = 'offline',
24
24
  } = props
25
25
 
26
+ aria.label = status
27
+
26
28
  const ariaProps = buildAriaProps(aria)
27
29
  const dataProps = buildDataProps(data)
28
30
  const classes = classnames(buildCss('pb_online_status_kit', status), globalProps(props), className)
@@ -1,5 +1,5 @@
1
1
  <%= content_tag(:div,
2
- aria: object.aria,
2
+ aria: object.aria.merge!(label: object.status),
3
3
  class: object.classname,
4
4
  data: object.data,
5
5
  id: object.id) do %>
@@ -1,6 +1,6 @@
1
1
  /* @flow */
2
2
 
3
- import React, { useEffect, useRef } from 'react'
3
+ import React, { forwardRef, useEffect, useRef } from 'react'
4
4
  import classnames from 'classnames'
5
5
  import useFocus from './useFocus.js'
6
6
  import Trix from 'trix'
@@ -22,7 +22,7 @@ type RichTextEditorProps = {
22
22
  value?: string,
23
23
  }
24
24
 
25
- const RichTextEditor = (props: RichTextEditorProps) => {
25
+ const RichTextEditor = (props: RichTextEditorProps, ref: React.ElementRef<"input">) => {
26
26
  const {
27
27
  aria = {},
28
28
  className,
@@ -120,6 +120,7 @@ const RichTextEditor = (props: RichTextEditorProps) => {
120
120
  <input
121
121
  id={id}
122
122
  name={name}
123
+ ref={ref}
123
124
  type="hidden"
124
125
  value={value}
125
126
  />
@@ -133,4 +134,4 @@ const RichTextEditor = (props: RichTextEditorProps) => {
133
134
  )
134
135
  }
135
136
 
136
- export default RichTextEditor
137
+ export default forwardRef(RichTextEditor)