playbook_ui 11.4.0 → 11.5.0.pre.alpha.fontawesome

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/data/menu.yml +0 -13
  3. data/app/pb_kits/playbook/pb_badge/badge.test.js +80 -0
  4. data/app/pb_kits/playbook/pb_button/_button.tsx +7 -2
  5. data/app/pb_kits/playbook/pb_button/_button_mixins.scss +7 -0
  6. data/app/pb_kits/playbook/pb_button/button.html.erb +11 -0
  7. data/app/pb_kits/playbook/pb_button/button.rb +3 -0
  8. data/app/pb_kits/playbook/pb_button/button.test.js +6 -8
  9. data/app/pb_kits/playbook/pb_button/docs/_button_block_content.html.erb +1 -1
  10. data/app/pb_kits/playbook/pb_button/docs/_button_block_content.jsx +12 -9
  11. data/app/pb_kits/playbook/pb_button/docs/_button_block_content.md +1 -0
  12. data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.html.erb +2 -0
  13. data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.jsx +23 -0
  14. data/app/pb_kits/playbook/pb_button/docs/_button_icon_options.md +1 -0
  15. data/app/pb_kits/playbook/pb_button/docs/example.yml +2 -0
  16. data/app/pb_kits/playbook/pb_button/docs/index.js +1 -0
  17. data/app/pb_kits/playbook/pb_date/_date.tsx +1 -1
  18. data/app/pb_kits/playbook/pb_date_picker/_date_picker.jsx +13 -1
  19. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +24 -19
  20. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -1
  21. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +9 -0
  22. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.js +25 -3
  23. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.html.erb +44 -0
  24. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.jsx +60 -0
  25. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.md +9 -0
  26. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions_element.html.erb +33 -0
  27. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions_element.jsx +67 -0
  28. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +4 -0
  29. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -0
  30. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_overrides.scss +4 -4
  31. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +142 -0
  32. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +116 -0
  33. data/app/pb_kits/playbook/pb_date_range_inline/docs/_date_range_inline_default.jsx +1 -1
  34. data/app/pb_kits/playbook/pb_date_time/{_date_time.jsx → _date_time.tsx} +2 -5
  35. data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +110 -0
  36. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_align.jsx +1 -1
  37. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +1 -1
  38. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_size.jsx +1 -1
  39. data/app/pb_kits/playbook/pb_date_year_stacked/{_date_year_stacked.jsx → _date_year_stacked.tsx} +6 -6
  40. data/app/pb_kits/playbook/pb_date_year_stacked/date_year_stacked.test.js +67 -0
  41. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +32 -14
  42. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +5 -0
  43. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +2 -2
  44. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +22 -4
  45. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +3 -3
  46. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +79 -17
  47. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.jsx +55 -93
  48. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.jsx +79 -42
  49. data/app/pb_kits/playbook/pb_file_upload/{_file_upload.jsx → _file_upload.tsx} +6 -10
  50. data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.jsx +2 -0
  51. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.jsx +2 -0
  52. data/app/pb_kits/playbook/pb_filter/Filter/FiltersPopover.jsx +2 -2
  53. data/app/pb_kits/playbook/pb_filter/docs/_filter_min_width.html.erb +1 -0
  54. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.html.erb +34 -0
  55. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.jsx +66 -0
  56. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.md +4 -0
  57. data/app/pb_kits/playbook/pb_filter/docs/example.yml +2 -0
  58. data/app/pb_kits/playbook/pb_filter/docs/index.js +1 -0
  59. data/app/pb_kits/playbook/pb_filter/filter.html.erb +2 -2
  60. data/app/pb_kits/playbook/pb_filter/filter.rb +3 -0
  61. data/app/pb_kits/playbook/pb_filter/filter.test.js +76 -0
  62. data/app/pb_kits/playbook/pb_form_group/{_form_group.jsx → _form_group.tsx} +1 -4
  63. data/app/pb_kits/playbook/pb_form_group/form_group.test.js +17 -0
  64. data/app/pb_kits/playbook/pb_hashtag/_hashtag.tsx +10 -1
  65. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.html.erb +5 -0
  66. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.jsx +26 -0
  67. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.md +1 -0
  68. data/app/pb_kits/playbook/pb_hashtag/docs/example.yml +2 -0
  69. data/app/pb_kits/playbook/pb_hashtag/docs/index.js +1 -0
  70. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -1
  71. data/app/pb_kits/playbook/pb_hashtag/hashtag.rb +6 -0
  72. data/app/pb_kits/playbook/pb_hashtag/hashtag.test.js +54 -0
  73. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +129 -0
  74. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +2 -1
  75. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.rb +2 -0
  76. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.jsx +1 -1
  77. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_emphasis.jsx +2 -2
  78. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.html.erb +12 -0
  79. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.jsx +23 -0
  80. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.md +1 -0
  81. data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +3 -0
  82. data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +1 -0
  83. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +4 -0
  84. data/app/pb_kits/playbook/pb_home_address_street/home_adress_street.test.js +60 -0
  85. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +2 -1
  86. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.rb +4 -1
  87. data/app/pb_kits/playbook/pb_icon_stat_value/{_icon_stat_value.jsx → _icon_stat_value.tsx} +2 -4
  88. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +154 -0
  89. data/app/pb_kits/playbook/pb_icon_value/{_icon_value.jsx → _icon_value.tsx} +2 -4
  90. data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +77 -0
  91. data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +123 -0
  92. data/app/pb_kits/playbook/pb_label_value/label_value.test.js +109 -0
  93. data/app/pb_kits/playbook/pb_layout/{_layout.jsx → _layout.tsx} +13 -19
  94. data/app/pb_kits/playbook/pb_layout/layout.test.js +97 -0
  95. data/app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx +23 -15
  96. data/app/pb_kits/playbook/pb_popover/popover.rb +1 -1
  97. data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +0 -1
  98. data/app/pb_kits/playbook/pb_time/_time.tsx +2 -2
  99. data/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +5 -2
  100. data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb +9 -0
  101. data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx +10 -0
  102. data/app/pb_kits/playbook/pb_timestamp/timestamp.rb +4 -1
  103. data/app/pb_kits/playbook/pb_timestamp/timestamp.test.js +164 -0
  104. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -4
  105. data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +11 -8
  106. data/app/pb_kits/playbook/tokens/_colors.scss +74 -74
  107. data/app/pb_kits/playbook/tokens/_typography.scss +8 -8
  108. data/app/pb_kits/playbook/utilities/_flexbox.scss +11 -11
  109. data/app/pb_kits/playbook/utilities/{_align_content.scss → flexbox_global_props/_align_content.scss} +0 -0
  110. data/app/pb_kits/playbook/utilities/{_align_items.scss → flexbox_global_props/_align_items.scss} +0 -0
  111. data/app/pb_kits/playbook/utilities/{_align_self.scss → flexbox_global_props/_align_self.scss} +0 -0
  112. data/app/pb_kits/playbook/utilities/{_flex.scss → flexbox_global_props/_flex.scss} +0 -0
  113. data/app/pb_kits/playbook/utilities/{_flex_direction.scss → flexbox_global_props/_flex_direction.scss} +0 -0
  114. data/app/pb_kits/playbook/utilities/{_flex_grow.scss → flexbox_global_props/_flex_grow.scss} +0 -0
  115. data/app/pb_kits/playbook/utilities/{_flex_shrink.scss → flexbox_global_props/_flex_shrink.scss} +0 -0
  116. data/app/pb_kits/playbook/utilities/{_flex_wrap.scss → flexbox_global_props/_flex_wrap.scss} +0 -0
  117. data/app/pb_kits/playbook/utilities/{_justify_content.scss → flexbox_global_props/_justify_content.scss} +0 -0
  118. data/app/pb_kits/playbook/utilities/{_justify_self.scss → flexbox_global_props/_justify_self.scss} +0 -0
  119. data/app/pb_kits/playbook/utilities/{_order.scss → flexbox_global_props/_order.scss} +0 -0
  120. data/app/pb_kits/playbook/utilities/props.ts +1 -1
  121. data/app/pb_kits/playbook/utilities/test-utils.js +2 -3
  122. data/app/pb_kits/playbook/utilities/text.ts +1 -1
  123. data/fonts/fontawesome-min.js +3 -2
  124. data/fonts/regular-min.js +3 -2
  125. data/lib/playbook/version.rb +2 -2
  126. metadata +57 -26
  127. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.jsx +0 -155
  128. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.jsx +0 -124
  129. data/app/pb_kits/playbook/pb_label_value/_label_value.jsx +0 -155
@@ -12,57 +12,70 @@ const useDialog = (visible = false) => {
12
12
  }
13
13
 
14
14
  const DialogStatus = () => {
15
- const [infoAlertOpened, toggleInfoAlert] = useDialog()
15
+ const [defaultAlertOpened, toggleDefaultAlert] = useDialog()
16
16
  const [cautionAlertOpened, toggleCautionAlert] = useDialog()
17
+ const [deleteAlertOpened, toggleDeleteAlert] = useDialog()
18
+ const [infoAlertOpened, toggleInfoAlert] = useDialog()
17
19
  const [successAlertOpened, toggleSuccessAlert] = useDialog()
18
20
  const [errorAlertOpened, toggleErrorAlert] = useDialog()
19
- const [deleteAlertOpened, toggleDeleteAlert] = useDialog()
20
21
 
21
22
  const dialogs = [
22
23
  {
23
- status: "info",
24
+ size: "status_size",
25
+ status: "default",
24
26
  text: "Text explaining why there is an alert",
25
- title: "Are you Sure?",
26
- toggle: toggleInfoAlert,
27
- visible: infoAlertOpened,
28
- buttonOneText:"No, Cancel",
29
- buttonTwoText: "Yes, Action"
27
+ title: "Are you sure?",
28
+ toggle: toggleDefaultAlert,
29
+ visible: defaultAlertOpened,
30
+ buttonOneText:"Yes, Action",
31
+ buttonTwoText: "No, Cancel"
30
32
  },
31
33
  {
34
+ size: "status_size",
32
35
  status: "caution",
33
36
  text: "This is the action you will be taking",
34
- title: "Are you Sure?",
37
+ title: "Are you sure?",
35
38
  toggle: toggleCautionAlert,
36
39
  visible: cautionAlertOpened,
37
- buttonOneText:"No, Cancel",
38
- buttonTwoText: "Yes, Action"
40
+ buttonOneText:"Yes, Action",
41
+ buttonTwoText: "No, Cancel"
39
42
  },
40
43
  {
44
+ size: "status_size",
41
45
  status: "delete",
42
46
  text: "You are about to delete ...",
43
47
  title: "Delete",
44
48
  toggle: toggleDeleteAlert,
45
49
  visible: deleteAlertOpened,
46
- buttonOneText:"No, Cancel",
47
- buttonTwoText: "Yes, Delete"
50
+ buttonOneText:"Yes, Delete",
51
+ buttonTwoText: "No, Cancel"
48
52
  },
49
53
  {
50
- status: "error",
51
- text: "Text explaining the error",
52
- title: "Error Message",
53
- toggle: toggleErrorAlert,
54
- visible: errorAlertOpened,
55
- buttonOneText:"No, Cancel",
56
- buttonTwoText: "Ok, Thanks"
54
+ size: "sm",
55
+ status: "info",
56
+ text: "Text explaining why there is an alert",
57
+ title: "Information",
58
+ toggle: toggleInfoAlert,
59
+ visible: infoAlertOpened,
60
+ buttonOneText:"Ok, Thanks!",
57
61
  },
58
62
  {
63
+ size: "sm",
59
64
  status: "success",
60
65
  text: "Text explaining what is successful",
61
66
  title: "Success!",
62
67
  toggle: toggleSuccessAlert,
63
68
  visible: successAlertOpened,
64
- buttonOneText:"No, Cancel",
65
- buttonTwoText: "Ok, Thanks"
69
+ buttonOneText: "Great!",
70
+ },
71
+ {
72
+ size: "sm",
73
+ status: "error",
74
+ text: "Text explaining the error",
75
+ title: "Error Message",
76
+ toggle: toggleErrorAlert,
77
+ visible: errorAlertOpened,
78
+ buttonOneText:"Oh no!",
66
79
  },
67
80
  ]
68
81
 
@@ -71,9 +84,9 @@ const DialogStatus = () => {
71
84
  <Flex>
72
85
  <Button
73
86
  marginRight="md"
74
- onClick={toggleInfoAlert}
87
+ onClick={toggleDefaultAlert}
75
88
  >
76
- {"Information Status"}
89
+ {"Default Status"}
77
90
  </Button>
78
91
  <Button
79
92
  marginRight="md"
@@ -83,18 +96,27 @@ const DialogStatus = () => {
83
96
  </Button>
84
97
  <Button
85
98
  marginRight="md"
86
- onClick={toggleSuccessAlert}
99
+ onClick={toggleDeleteAlert}
87
100
  >
88
- {"Success Status"}
101
+ {"Delete Status"}
89
102
  </Button>
90
- <Button onClick={toggleErrorAlert}>
91
- {"Error Status"}
103
+ <Button
104
+ marginRight="md"
105
+ onClick={toggleInfoAlert}
106
+ >
107
+ {"Information Status"}
92
108
  </Button>
93
109
  <Button
94
110
  marginRight="md"
95
- onClick={toggleDeleteAlert}
111
+ onClick={toggleSuccessAlert}
96
112
  >
97
- {"Delete Status"}
113
+ {"Success Status"}
114
+ </Button>
115
+ <Button
116
+ marginRight="md"
117
+ onClick={toggleErrorAlert}
118
+ >
119
+ {"Error Status"}
98
120
  </Button>
99
121
  </Flex>
100
122
  <Flex>
@@ -103,22 +125,37 @@ const DialogStatus = () => {
103
125
  key={dialog.status}
104
126
  onClose={dialog.toggle}
105
127
  opened={dialog.visible}
128
+ size={dialog.size}
106
129
  status={dialog.status}
107
130
  text={dialog.text}
108
131
  title={dialog.title}
109
132
  >
110
- <Dialog.Footer>
111
- <Button
112
- onClick={dialog.toggle}
113
- variant="secondary"
114
- >
115
- {dialog.buttonOneText}
116
- </Button>
117
- <Button
118
- onClick={dialog.toggle}
119
- >
120
- {dialog.buttonTwoText}
121
- </Button>
133
+ <Dialog.Footer
134
+ paddingBottom="md"
135
+ paddingX="md"
136
+ >
137
+ <If condition={!dialog.buttonTwoText}>
138
+ <Button
139
+ fullWidth
140
+ onClick={dialog.toggle}
141
+ >
142
+ {dialog.buttonOneText}
143
+ </Button>
144
+ </If>
145
+ <If condition={dialog.buttonTwoText}>
146
+ <Button
147
+ onClick={dialog.toggle}
148
+ paddingRight="xl"
149
+ >
150
+ {dialog.buttonOneText}
151
+ </Button>
152
+ <Button
153
+ onClick={dialog.toggle}
154
+ variant="secondary"
155
+ >
156
+ {dialog.buttonTwoText}
157
+ </Button>
158
+ </If>
122
159
  </Dialog.Footer>
123
160
  </Dialog>
124
161
  ))}
@@ -1,5 +1,3 @@
1
- /* @flow */
2
-
3
1
  import React, { useCallback } from 'react'
4
2
  import { useDropzone } from 'react-dropzone'
5
3
  import classnames from 'classnames'
@@ -12,11 +10,11 @@ import Body from '../pb_body/_body'
12
10
  import Card from '../pb_card/_card'
13
11
 
14
12
  type FileUploadProps = {
15
- accept?: array<string>,
13
+ accept?: string[],
16
14
  className?: string,
17
15
  data?: object,
18
16
  acceptedFilesDescription?: string,
19
- onFilesAccepted: Callback,
17
+ onFilesAccepted: Callback<File, File>,
20
18
  }
21
19
 
22
20
  const FileUpload = (props: FileUploadProps) => {
@@ -27,10 +25,8 @@ const FileUpload = (props: FileUploadProps) => {
27
25
  data = {},
28
26
  onFilesAccepted = noop,
29
27
  } = props
30
- const onDrop = useCallback((files) => {
31
- onFilesAccepted(files)
32
- })
33
28
 
29
+ const onDrop = useCallback((files) => onFilesAccepted(files), []);
34
30
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
35
31
  accept,
36
32
  onDrop,
@@ -57,11 +53,11 @@ const FileUpload = (props: FileUploadProps) => {
57
53
  <Card>
58
54
  <input {...getInputProps()} />
59
55
  <Body color="light">
60
- <If condition={isDragActive}>
56
+ {isDragActive ?
61
57
  <p>{'Drop the files here ...'}</p>
62
- <Else />
58
+ :
63
59
  <p>{accept === null ? 'Choose a file or drag it here' : `Choose a file or drag it here. The accepted file types are: ${acceptedFilesDescription || acceptedFileTypes()}`}</p>
64
- </If>
60
+ }
65
61
  </Body>
66
62
  </Card>
67
63
  </div>
@@ -33,6 +33,7 @@ const FilterDouble = ({
33
33
  children,
34
34
  dark,
35
35
  minWidth,
36
+ placement,
36
37
  ...bgProps
37
38
  }: FilterDoubleProps) => (
38
39
  <FilterBackground
@@ -46,6 +47,7 @@ const FilterDouble = ({
46
47
  <FiltersPopover
47
48
  dark={dark}
48
49
  minWidth={minWidth}
50
+ placement={placement}
49
51
  >
50
52
  {children}
51
53
  </FiltersPopover>
@@ -33,6 +33,7 @@ const FilterSingle = ({
33
33
  children,
34
34
  dark,
35
35
  minWidth,
36
+ placement,
36
37
  ...bgProps
37
38
  }: FilterSingleProps) => {
38
39
  return (
@@ -49,6 +50,7 @@ const FilterSingle = ({
49
50
  <FiltersPopover
50
51
  dark={dark}
51
52
  minWidth={minWidth}
53
+ placement={placement}
52
54
  >
53
55
  {children}
54
56
  </FiltersPopover>
@@ -6,7 +6,7 @@ import CircleIconButton from '../../pb_circle_icon_button/_circle_icon_button'
6
6
  import PbReactPopover from '../../pb_popover/_popover'
7
7
 
8
8
  const FiltersPopoverProps = { children: Node }
9
- const FiltersPopover = ({ children, dark, minWidth }: FiltersPopoverProps) => {
9
+ const FiltersPopover = ({ children, dark, minWidth, placement = "bottom-start" }: FiltersPopoverProps) => {
10
10
  const [hide, updateHide] = useState(true)
11
11
  const toggle = () => updateHide(!hide)
12
12
 
@@ -25,7 +25,7 @@ const FiltersPopover = ({ children, dark, minWidth }: FiltersPopoverProps) => {
25
25
  <PbReactPopover
26
26
  closeOnClick="outside"
27
27
  minWidth={minWidth}
28
- placement="bottom"
28
+ placement={placement}
29
29
  reference={filterButton}
30
30
  shouldClosePopover={updateHide}
31
31
  show={!hide}
@@ -2,6 +2,7 @@
2
2
  pb_rails("filter", props: {
3
3
  min_width: "600px",
4
4
  id: "25",
5
+ position: "top",
5
6
  filters: [
6
7
  { name: "name", value: "John Wick" },
7
8
  { name: "city", value: "San Francisco"}
@@ -0,0 +1,34 @@
1
+ <%=
2
+ pb_rails("filter", props: {
3
+ id: "pla",
4
+ filters: [
5
+ { name: "name", value: "John Wick" }
6
+ ],
7
+ placement: "right",
8
+ template:"filter_only",
9
+ }) do
10
+ %>
11
+ <%
12
+ example_collection = [
13
+ OpenStruct.new(name: "Alabama", value: 1),
14
+ OpenStruct.new(name: "Alaska", value: 2),
15
+ OpenStruct.new(name: "Arizona", value: 3),
16
+ OpenStruct.new(name: "Arkansas", value: 4),
17
+ OpenStruct.new(name: "California", value: 5),
18
+ OpenStruct.new(name: "Colorado", value: 6),
19
+ OpenStruct.new(name: "Connecticut", value: 7),
20
+ OpenStruct.new(name: "Delaware", value: 8),
21
+ OpenStruct.new(name: "Florida", value: 9),
22
+ OpenStruct.new(name: "Georgia", value: 10),
23
+ ]
24
+ %>
25
+ <%= pb_rails("form", props: { form_system_options: { scope: :example, method: :get } }) do |form| %>
26
+ <%= form.text_field :example_text_field, props: { label: true } %>
27
+ <%= form.collection_select :example_collection_select, example_collection, :value, :name, props: { label: true } %>
28
+
29
+ <%= form.actions do |action| %>
30
+ <%= action.submit props: { text: "Apply", data: { disable_with: "<i class='far fa-spinner fa-spin mr-3'></i>Searching...".html_safe },}%>
31
+ <%= action.button props: { type: "reset", text: "Clear", variant: "secondary" } %>
32
+ <% end %>
33
+ <% end %>
34
+ <% end %>
@@ -0,0 +1,66 @@
1
+ import React from 'react'
2
+ import { Button, Filter, Flex, Select, TextInput } from '../..'
3
+
4
+ const SortingChangeCallback = (sortOptions) => {
5
+ alert(JSON.stringify(sortOptions[0]))
6
+ }
7
+
8
+ const FilterPlacement = (props) => {
9
+ const options = [
10
+ { value: 'USA' },
11
+ { value: 'Canada' },
12
+ { value: 'Brazil' },
13
+ { value: 'Philippines' },
14
+ { value: 'A Galaxy Far Far Away Like Really Far Away' },
15
+ ]
16
+ return (
17
+
18
+ <>
19
+ <Filter
20
+ double
21
+ onSortChange={SortingChangeCallback}
22
+ placement={"right"}
23
+ results={1}
24
+ sortOptions={{
25
+ popularity: 'Popularity',
26
+ // eslint-disable-next-line
27
+ manager_title: 'Manager\'s Title',
28
+ // eslint-disable-next-line
29
+ manager_name: 'Manager\'s Name',
30
+ }}
31
+ sortValue={[{ name: 'popularity', dir: 'desc' }]}
32
+ {...props}
33
+ >
34
+ <TextInput
35
+ label="Example Text Field"
36
+ placeholder="Enter Text"
37
+ {...props}
38
+ />
39
+
40
+ <Select
41
+ blankSelection="Select One..."
42
+ label="Example Collection Select"
43
+ name="Collection Select"
44
+ options={options}
45
+ {...props}
46
+ />
47
+ <Flex
48
+ spacing="between"
49
+ {...props}
50
+ >
51
+ <Button
52
+ text="Apply"
53
+ {...props}
54
+ />
55
+ <Button
56
+ text="Clear"
57
+ variant="secondary"
58
+ {...props}
59
+ />
60
+ </Flex>
61
+ </Filter>
62
+ </>
63
+ )
64
+ }
65
+
66
+ export default FilterPlacement
@@ -0,0 +1,4 @@
1
+ Click the filter buttom above to toggle the popover.
2
+
3
+ To change the filter's popover position, use the `placement` prop with one of the positions:
4
+ `"top" | "right" | "bottom" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"`
@@ -8,6 +8,7 @@ examples:
8
8
  - filter_only: Filter Only
9
9
  - sort_only: Sort Only
10
10
  - filter_min_width: Min Width for Popover Inside of Filter
11
+ - filter_placement: Filter Placement
11
12
 
12
13
  react:
13
14
  - filter_default: Default
@@ -18,3 +19,4 @@ examples:
18
19
  - sort_only: Sort Only
19
20
  - filter_min_width: Min Width for Popover Inside of Filter
20
21
  - filter_close_popover: Close Popover
22
+ - filter_placement: Filter Placement
@@ -6,3 +6,4 @@ export { default as FilterOnly } from './_filter_only.jsx'
6
6
  export { default as SortOnly } from './_sort_only.jsx'
7
7
  export { default as FilterMinWidth } from './_filter_min_width.jsx'
8
8
  export { default as FilterClosePopover } from './_filter_close_popover.jsx'
9
+ export { default as FilterPlacement } from './_filter_placement.jsx'
@@ -69,13 +69,13 @@
69
69
  <% end %>
70
70
 
71
71
  <% if object.template != "sort_only"%>
72
- <%= pb_rails("popover", props: {min_width: object.min_width, close_on_click: "outside", trigger_element_id: "filter#{object.id}", tooltip_id: "filter-form#{object.id}", position: 'bottom'}) do %>
72
+ <%= pb_rails("popover", props: {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 %>
73
73
  <%= content %>
74
74
  <% end %>
75
75
  <%end%>
76
76
 
77
77
  <% if object.template != "filter_only"%>
78
- <%= pb_rails("popover", props: {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: 'bottom', padding: 'none'}) do %>
78
+ <%= pb_rails("popover", props: {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 %>
79
79
  <%= pb_rails("list") do %>
80
80
  <% object.sort_menu.each do |item| %>
81
81
  <%= pb_rails("list/item") do%> <%= pb_rails("button", props: {variant: "link" ,classname: "p-0", text: item[:item], link: item[:link]}) %><% end %>
@@ -11,6 +11,9 @@ module Playbook
11
11
  default: "default"
12
12
  prop :background, type: Playbook::Props::Boolean, default: true
13
13
  prop :min_width, default: "auto"
14
+ prop :placement, type: Playbook::Props::Enum,
15
+ values: %w[top bottom left right top-start top-end bottom-start bottom-end right-start right-end left-start left-end],
16
+ default: "bottom-start"
14
17
 
15
18
  def classname
16
19
  generate_classname("pb_filter_kit")
@@ -0,0 +1,76 @@
1
+ import React from "react";
2
+ import {
3
+ render,
4
+ screen,
5
+ fireEvent,
6
+ } from "../utilities/test-utils";
7
+ import { Button, Filter, Flex, Select, TextInput } from "..";
8
+
9
+ function FilterTest(props) {
10
+ const SortingChangeCallback = (sortOptions) => {
11
+ alert(JSON.stringify(sortOptions[0]));
12
+ };
13
+
14
+ const options = [
15
+ { value: "USA" },
16
+ { value: "Canada" },
17
+ { value: "Brazil" },
18
+ { value: "Philippines" },
19
+ { value: "A Galaxy Far Far Away Like Really Far Away" },
20
+ ];
21
+ return (
22
+ <Filter
23
+ onSortChange={SortingChangeCallback}
24
+ results={1}
25
+ sortOptions={{
26
+ popularity: "Popularity",
27
+ // eslint-disable-next-line
28
+ manager_title: "Manager's Title",
29
+ // eslint-disable-next-line
30
+ manager_name: "Manager's Name",
31
+ }}
32
+ sortValue={[{ name: "popularity", dir: "desc" }]}
33
+ {...props}
34
+ >
35
+ <TextInput
36
+ label="Example Text Field"
37
+ placeholder="Enter Text"
38
+ {...props}
39
+ />
40
+
41
+ <Select
42
+ blankSelection="Select One..."
43
+ label="Example Collection Select"
44
+ name="Collection Select"
45
+ options={options}
46
+ {...props}
47
+ />
48
+ <Flex spacing="between"
49
+ {...props}>
50
+ <Button text="Apply"
51
+ {...props} />
52
+ <Button text="Clear"
53
+ variant="secondary"
54
+ {...props} />
55
+ </Flex>
56
+ </Filter>
57
+ );
58
+ }
59
+
60
+ test("triggers popover on filter button click", () => {
61
+ render(<FilterTest data={{ testid: "render-test" }}/>);
62
+
63
+ const btn = screen.getAllByRole("button")[0];
64
+
65
+ // checks if the sort menu rendered
66
+ expect(screen.getByLabelText("sort-amount-down icon")).toBeInTheDocument()
67
+ expect(screen.getByText('Popularity')).toBeInTheDocument() // check if filter/sort is rendered
68
+
69
+ // hits the filter button and triggers popover
70
+ fireEvent.click(btn);
71
+
72
+ // check if popover displays correctly by checking its tet
73
+ expect(screen.getByText("Example Text Field")).toBeInTheDocument()
74
+
75
+
76
+ });
@@ -1,12 +1,10 @@
1
- /* @flow */
2
-
3
1
  import React from 'react'
4
2
  import classnames from 'classnames'
5
3
  import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
6
4
  import { globalProps } from '../utilities/globalProps'
7
5
 
8
6
  type FormGroupProps = {
9
- aria?: object,
7
+ aria?: {[key: string]: string},
10
8
  children?: Node,
11
9
  className?: string,
12
10
  data?: object,
@@ -27,7 +25,6 @@ const FormGroup = (props: FormGroupProps) => {
27
25
  const ariaProps = buildAriaProps(aria)
28
26
  const dataProps = buildDataProps(data)
29
27
  const classes = classnames(buildCss('pb_form_group_kit', { full: fullWidth }), globalProps(props), className)
30
-
31
28
  return (
32
29
  <div
33
30
  {...ariaProps}
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import { render } from "../utilities/test-utils";
3
+
4
+ import { Button, FormGroup } from "..";
5
+
6
+ test("should render a div with a button child", () => {
7
+ const testId = "primary-test"
8
+ const { queryByTestId } = render(
9
+ <FormGroup>
10
+ <Button
11
+ data={{ testid: testId }}
12
+ text={"some text"} />
13
+ </FormGroup>
14
+ )
15
+
16
+ expect(queryByTestId("primary-test")).not.toBeNull;
17
+ })
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/jsx-no-target-blank */
1
2
  /* eslint-disable react/no-multi-comp, flowtype/space-before-type-colon */
2
3
 
3
4
  import React from 'react'
@@ -14,6 +15,8 @@ type HashtagProps = {
14
15
  dark?: boolean,
15
16
  data?: string,
16
17
  id?: string,
18
+ newWindow?: boolean,
19
+ rel?: string,
17
20
  text?: string,
18
21
  type: "default" | "home" | "project" | "appointment",
19
22
  url?: string,
@@ -33,6 +36,8 @@ const Hashtag = (props: HashtagProps) => {
33
36
  dark = false,
34
37
  data = {},
35
38
  id,
39
+ newWindow,
40
+ rel,
36
41
  text,
37
42
  type = 'default',
38
43
  url,
@@ -49,7 +54,11 @@ const Hashtag = (props: HashtagProps) => {
49
54
  className={classes}
50
55
  id={id}
51
56
  >
52
- <a href={url}>
57
+ <a
58
+ href={url}
59
+ rel={(newWindow ? "noreferrer" : rel)}
60
+ target={(newWindow ? '_blank' : '_self')}
61
+ >
53
62
  <Badge
54
63
  dark={dark}
55
64
  text={typeMap[type] + text}
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("hashtag", props: {text: "Open in the same Window", url: "https://google.com", type: "project"}) %>
2
+
3
+ <br/><br/>
4
+
5
+ <%= pb_rails("hashtag", props: {text: "Open in a new Window", url: "https://google.com", type: "project", new_window: true}) %>
@@ -0,0 +1,26 @@
1
+ import React from 'react'
2
+ import { Hashtag } from '../../'
3
+
4
+ const HashtagLink = (props) => {
5
+ return (
6
+ <div>
7
+ <Hashtag
8
+ text="Open in the same window"
9
+ type="project"
10
+ url="https://google.com"
11
+ {...props}
12
+ />
13
+ <br />
14
+ <br />
15
+ <Hashtag
16
+ newWindow
17
+ text="Open in a new window"
18
+ type="project"
19
+ url="https://google.com"
20
+ {...props}
21
+ />
22
+ </div>
23
+ )
24
+ }
25
+
26
+ export default HashtagLink
@@ -0,0 +1 @@
1
+ Use the newWindow/new_window prop to control whether the link opens on the same page or a new tab (same page is the default behavior)
@@ -2,6 +2,8 @@ examples:
2
2
 
3
3
  rails:
4
4
  - hashtag_default: Hashtag Types
5
+ - hashtag_link: Hashtag Links
5
6
 
6
7
  react:
7
8
  - hashtag_default: Hashtag Types
9
+ - hashtag_link: Hashtag Links
@@ -1 +1,2 @@
1
1
  export { default as HashtagDefault } from './_hashtag_default.jsx'
2
+ export { default as HashtagLink } from './_hashtag_link.jsx'
@@ -3,7 +3,7 @@
3
3
  class: object.classname,
4
4
  data: object.data,
5
5
  id: object.id) do %>
6
- <%= link_to object.url do %>
6
+ <%= link_to object.url, target: object.link_option do %>
7
7
  <%= pb_rails("badge", props: { dark: object.dark, variant: "primary", text: object.hashtag_text }) %>
8
8
  <% end %>
9
9
  <% end %>