playbook_ui 8.2.0.pre.alpha1 → 8.2.1.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/app/pb_kits/playbook/_playbook.scss +2 -0
  4. data/app/pb_kits/playbook/data/menu.yml +3 -1
  5. data/app/pb_kits/playbook/index.js +2 -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_button/_button.jsx +6 -0
  29. data/app/pb_kits/playbook/pb_button/button.test.js +91 -0
  30. data/app/pb_kits/playbook/pb_button/docs/_button_default.jsx +0 -1
  31. data/app/pb_kits/playbook/pb_button_toolbar/button_toolbar.test.js +46 -0
  32. data/app/pb_kits/playbook/pb_caption/_caption.jsx +3 -2
  33. data/app/pb_kits/playbook/pb_caption/caption.rb +1 -1
  34. data/app/pb_kits/playbook/pb_card/_card.jsx +18 -3
  35. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
  36. data/app/pb_kits/playbook/pb_card/card.rb +3 -0
  37. data/app/pb_kits/playbook/pb_card/docs/_card_tag.html.erb +25 -0
  38. data/app/pb_kits/playbook/pb_card/docs/_card_tag.jsx +59 -0
  39. data/app/pb_kits/playbook/pb_card/docs/example.yml +2 -0
  40. data/app/pb_kits/playbook/pb_card/docs/index.js +1 -0
  41. data/app/pb_kits/playbook/pb_checkbox/_checkbox.jsx +31 -9
  42. data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +28 -19
  43. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +11 -3
  44. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +6 -1
  45. data/app/pb_kits/playbook/pb_checkbox/checkbox.test.js +94 -0
  46. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom.jsx +0 -1
  47. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +7 -0
  48. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.jsx +16 -0
  49. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +2 -0
  50. data/app/pb_kits/playbook/pb_checkbox/docs/index.js +1 -0
  51. data/app/pb_kits/playbook/pb_circle_icon_button/circle_icon_button.test.js +17 -0
  52. data/app/pb_kits/playbook/pb_date_picker/_date_picker.jsx +6 -0
  53. data/app/pb_kits/playbook/pb_dialog/_close_icon.jsx +23 -0
  54. data/app/pb_kits/playbook/pb_dialog/_dialog.html.erb +10 -0
  55. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +142 -0
  56. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +133 -0
  57. data/app/pb_kits/playbook/pb_dialog/_dialog_context.jsx +3 -0
  58. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +21 -0
  59. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +36 -0
  60. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +68 -0
  61. data/app/pb_kits/playbook/pb_dialog/dialog.rb +47 -0
  62. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +23 -0
  63. data/app/pb_kits/playbook/pb_dialog/dialog_header.rb +31 -0
  64. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.jsx +53 -0
  65. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.md +2 -0
  66. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.jsx +27 -0
  67. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.jsx +27 -0
  68. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.md +2 -0
  69. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.jsx +119 -0
  70. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.md +2 -0
  71. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.jsx +28 -0
  72. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.md +2 -0
  73. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_sizes.jsx +93 -0
  74. data/app/pb_kits/playbook/pb_dialog/docs/example.yml +10 -0
  75. data/app/pb_kits/playbook/pb_dialog/docs/index.js +6 -0
  76. data/app/pb_kits/playbook/pb_form/_form.scss +5 -1
  77. data/app/pb_kits/playbook/pb_form/form_builder.rb +4 -2
  78. data/app/pb_kits/playbook/pb_form/form_builder/action_area.rb +14 -7
  79. data/app/pb_kits/playbook/pb_form/simple_form.html.erb +2 -4
  80. data/app/pb_kits/playbook/pb_form/simple_form.rb +4 -0
  81. data/app/pb_kits/playbook/pb_inline/_inline.jsx +83 -0
  82. data/app/pb_kits/playbook/pb_inline/_inline.scss +58 -0
  83. data/app/pb_kits/playbook/pb_inline/docs/_inline_default.jsx +36 -0
  84. data/app/pb_kits/playbook/pb_inline/docs/_inline_input_options.jsx +58 -0
  85. data/app/pb_kits/playbook/pb_inline/docs/_inline_text_options.jsx +99 -0
  86. data/app/pb_kits/playbook/pb_inline/docs/example.yml +5 -0
  87. data/app/pb_kits/playbook/pb_inline/docs/index.js +3 -0
  88. data/app/pb_kits/playbook/pb_inline/inline.test.jsx +21 -0
  89. data/app/pb_kits/playbook/pb_online_status/_online_status.jsx +2 -0
  90. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +1 -1
  91. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.jsx +4 -3
  92. data/app/pb_kits/playbook/pb_text_input/_text_input.jsx +3 -0
  93. data/app/pb_kits/playbook/pb_textarea/_textarea.jsx +3 -0
  94. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +9 -1
  95. data/app/pb_kits/playbook/pb_typeahead/components/Input.jsx +24 -0
  96. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx +25 -2
  97. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.jsx +1 -0
  98. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.jsx +8 -3
  99. data/app/pb_kits/playbook/pb_user_badge/_user_badge.jsx +1 -1
  100. data/app/pb_kits/playbook/react_rails_kits.js +4 -0
  101. data/app/pb_kits/playbook/utilities/test-utils.js +6 -0
  102. data/lib/playbook/version.rb +2 -1
  103. metadata +75 -35
  104. data/app/pb_kits/playbook/pb_form/form_builder/action_area.html.erb +0 -3
@@ -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,8 +1,12 @@
1
1
  .pb-form {
2
2
  .pb-form-actions {
3
3
  list-style: none;
4
- margin: 8px;
4
+ margin: 0;
5
5
  padding: 0;
6
+ display: flex;
7
+ justify-content: space-between;
8
+ align-items: flex-start;
9
+ flex-direction: row;
6
10
 
7
11
  > li {
8
12
  display: inline-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
@@ -0,0 +1,83 @@
1
+ /* @flow */
2
+
3
+ import React, { useEffect, useRef, useState } from 'react'
4
+ import classnames from 'classnames'
5
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
6
+ import { globalProps } from '../utilities/globalProps.js'
7
+ import './_inline.scss'
8
+
9
+ type InlineProps = {
10
+ aria?: object,
11
+ className?: string,
12
+ data?: object,
13
+ displayKit?: React.Node,
14
+ formInput?: React.Node,
15
+ id?: string,
16
+ }
17
+
18
+ const Inline = (props: InlineProps) => {
19
+ const {
20
+ aria = {},
21
+ className,
22
+ data = {},
23
+ displayKit,
24
+ id,
25
+ formInput,
26
+ } = props
27
+
28
+ const ariaProps = buildAriaProps(aria)
29
+ const dataProps = buildDataProps(data)
30
+ const classes = classnames(buildCss('pb_inline'), globalProps(props), className)
31
+
32
+ const [editing, setEditing] = useState(false)
33
+
34
+ const ToggleClickHandler = () => {
35
+ setEditing(!editing)
36
+ }
37
+
38
+ useEffect(() => {
39
+ if (editing) {
40
+ modifiedInput.ref.current.focus()
41
+
42
+ modifiedInput.ref.current.addEventListener('keydown', (e) => {
43
+ if (e.key === 'Escape' || e.key === 'Enter') {
44
+ setEditing(!editing)
45
+ }
46
+ })
47
+ }
48
+ }, [editing])
49
+
50
+ const { kitType, size } = displayKit.props
51
+ const textInputClassName = kitType ? (kitType.toLowerCase() + (size ? `_${size}` : '')) : ''
52
+
53
+ const modifiedInput = React.cloneElement(formInput, {
54
+ className: textInputClassName,
55
+ onBlur: () => setEditing(!editing),
56
+ ref: useRef(null),
57
+ })
58
+
59
+ return (
60
+ <div
61
+ {...ariaProps}
62
+ {...dataProps}
63
+ className={classes}
64
+ id={id}
65
+ >
66
+ <If condition={editing}>
67
+ {modifiedInput}
68
+ </If>
69
+ <If condition={!editing}>
70
+ <div
71
+ onClick={() => ToggleClickHandler()}
72
+ onFocus={() => ToggleClickHandler()}
73
+ tabIndex="0"
74
+ >
75
+ {displayKit}
76
+ </div>
77
+ </If>
78
+
79
+ </div>
80
+ )
81
+ }
82
+
83
+ export default Inline
@@ -0,0 +1,58 @@
1
+ @import "../pb_title/title_mixin";
2
+ @import "../pb_body/body_mixins";
3
+ @import "../pb_caption/caption_mixin";
4
+
5
+ .pb_inline {
6
+ .pb_text_input_kit {
7
+ &.title_1 {
8
+ .text_input_wrapper input {
9
+ @include pb_title_1;
10
+ }
11
+ &.dark .text_input_wrapper input {
12
+ @include pb_title_1;
13
+ @include pb_title_dark;
14
+ }
15
+ }
16
+ &.title_2 {
17
+ .text_input_wrapper input {
18
+ @include pb_title_2;
19
+ }
20
+ &.dark .text_input_wrapper input {
21
+ @include pb_title_2;
22
+ @include pb_title_dark;
23
+ }
24
+ }
25
+ &.title_3 {
26
+ .text_input_wrapper input {
27
+ @include pb_title_3;
28
+ }
29
+ &.dark .text_input_wrapper input {
30
+ @include pb_title_3;
31
+ @include pb_title_dark;
32
+ }
33
+ }
34
+ &.body {
35
+ .text_input_wrapper input {
36
+ @include pb_body;
37
+ }
38
+ &.dark .text_input_wrapper input {
39
+ @include pb_body_dark;
40
+ }
41
+ }
42
+ &.caption {
43
+ .text_input_wrapper input {
44
+ @include caption;
45
+ }
46
+ &.dark .text_input_wrapper input {
47
+ @include caption;
48
+ @include caption_dark;
49
+ }
50
+ }
51
+ .text_input_wrapper input {
52
+ padding: 8px 5px;
53
+ }
54
+ .text_input_wrapper, .pb_textarea_kit {
55
+ margin-bottom: 0;
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,36 @@
1
+ import React, { useState } from 'react'
2
+ import { Inline, TextInput, Title } from '../../'
3
+
4
+ const InlineDefault = (props) => {
5
+ const [formValue, setFormValue] = useState('Default Value')
6
+
7
+ const handleInputChange = (event) => {
8
+ setFormValue(event.target.value)
9
+ }
10
+
11
+ return (
12
+ <div>
13
+ <Inline
14
+ {...props}
15
+ displayKit={
16
+ <Title
17
+ {...props}
18
+ kitType="Title"
19
+ size={4}
20
+ tag="h4"
21
+ text={formValue}
22
+ />
23
+ }
24
+ formInput={
25
+ <TextInput
26
+ {...props}
27
+ onChange={handleInputChange}
28
+ value={formValue}
29
+ />
30
+ }
31
+ />
32
+ </div>
33
+ )
34
+ }
35
+
36
+ export default InlineDefault
@@ -0,0 +1,58 @@
1
+ import React, { useState } from 'react'
2
+ import { Body, Inline, Textarea, TextInput } from '../../'
3
+
4
+ const InlineInputOptions = (props) => {
5
+ const [formFields, setFormFields] = useState({
6
+ inputOne: 'Input One',
7
+ inputTwo: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
8
+ })
9
+
10
+ const handleChange = ({ target }) => {
11
+ const { name, value } = target
12
+ setFormFields({ ...formFields, [name]: value })
13
+ }
14
+
15
+ return (
16
+ <div>
17
+ <Inline
18
+ {...props}
19
+ displayKit={
20
+ <Body
21
+ {...props}
22
+ kitType="Body"
23
+ text={formFields.inputOne}
24
+ />
25
+ }
26
+ formInput={
27
+ <TextInput
28
+ {...props}
29
+ name="inputOne"
30
+ onChange={handleChange}
31
+ value={formFields.inputOne}
32
+ />
33
+ }
34
+ />
35
+ <Inline
36
+ {...props}
37
+ displayKit={
38
+ <Body
39
+ {...props}
40
+ kitType="Body"
41
+ text={formFields.inputTwo}
42
+ />
43
+ }
44
+ formInput={
45
+ <Textarea
46
+ {...props}
47
+ name="inputTwo"
48
+ onChange={handleChange}
49
+ resize="auto"
50
+ value={formFields.inputTwo}
51
+ />
52
+ }
53
+ />
54
+ </div>
55
+ )
56
+ }
57
+
58
+ export default InlineInputOptions