playbook_ui 11.4.0 → 11.5.0.pre.alpha.datepicker1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) 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/_flatpickr_styles.scss +0 -3
  31. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_overrides.scss +4 -4
  32. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +142 -0
  33. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +116 -0
  34. data/app/pb_kits/playbook/pb_date_range_inline/docs/_date_range_inline_default.jsx +1 -1
  35. data/app/pb_kits/playbook/pb_date_time/{_date_time.jsx → _date_time.tsx} +2 -5
  36. data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +110 -0
  37. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_align.jsx +1 -1
  38. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +1 -1
  39. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_size.jsx +1 -1
  40. data/app/pb_kits/playbook/pb_date_year_stacked/{_date_year_stacked.jsx → _date_year_stacked.tsx} +6 -6
  41. data/app/pb_kits/playbook/pb_date_year_stacked/date_year_stacked.test.js +67 -0
  42. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +32 -14
  43. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +5 -0
  44. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +2 -2
  45. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +22 -4
  46. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +3 -3
  47. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +79 -17
  48. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.jsx +55 -93
  49. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.jsx +79 -42
  50. data/app/pb_kits/playbook/pb_file_upload/{_file_upload.jsx → _file_upload.tsx} +6 -10
  51. data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.jsx +2 -0
  52. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.jsx +2 -0
  53. data/app/pb_kits/playbook/pb_filter/Filter/FiltersPopover.jsx +2 -2
  54. data/app/pb_kits/playbook/pb_filter/docs/_filter_min_width.html.erb +1 -0
  55. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.html.erb +34 -0
  56. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.jsx +66 -0
  57. data/app/pb_kits/playbook/pb_filter/docs/_filter_placement.md +4 -0
  58. data/app/pb_kits/playbook/pb_filter/docs/example.yml +2 -0
  59. data/app/pb_kits/playbook/pb_filter/docs/index.js +1 -0
  60. data/app/pb_kits/playbook/pb_filter/filter.html.erb +2 -2
  61. data/app/pb_kits/playbook/pb_filter/filter.rb +3 -0
  62. data/app/pb_kits/playbook/pb_filter/filter.test.js +76 -0
  63. data/app/pb_kits/playbook/pb_form_group/{_form_group.jsx → _form_group.tsx} +1 -4
  64. data/app/pb_kits/playbook/pb_form_group/form_group.test.js +17 -0
  65. data/app/pb_kits/playbook/pb_hashtag/_hashtag.tsx +10 -1
  66. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.html.erb +5 -0
  67. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.jsx +26 -0
  68. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.md +1 -0
  69. data/app/pb_kits/playbook/pb_hashtag/docs/example.yml +2 -0
  70. data/app/pb_kits/playbook/pb_hashtag/docs/index.js +1 -0
  71. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -1
  72. data/app/pb_kits/playbook/pb_hashtag/hashtag.rb +6 -0
  73. data/app/pb_kits/playbook/pb_hashtag/hashtag.test.js +54 -0
  74. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +129 -0
  75. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +2 -1
  76. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.rb +2 -0
  77. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.jsx +1 -1
  78. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_emphasis.jsx +2 -2
  79. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.html.erb +12 -0
  80. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.jsx +23 -0
  81. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.md +1 -0
  82. data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +3 -0
  83. data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +1 -0
  84. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +4 -0
  85. data/app/pb_kits/playbook/pb_home_address_street/home_adress_street.test.js +60 -0
  86. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +2 -1
  87. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.rb +4 -1
  88. data/app/pb_kits/playbook/pb_icon_stat_value/{_icon_stat_value.jsx → _icon_stat_value.tsx} +2 -4
  89. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +154 -0
  90. data/app/pb_kits/playbook/pb_icon_value/{_icon_value.jsx → _icon_value.tsx} +2 -4
  91. data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +77 -0
  92. data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +123 -0
  93. data/app/pb_kits/playbook/pb_label_value/label_value.test.js +109 -0
  94. data/app/pb_kits/playbook/pb_layout/{_layout.jsx → _layout.tsx} +13 -19
  95. data/app/pb_kits/playbook/pb_layout/layout.test.js +97 -0
  96. data/app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx +23 -15
  97. data/app/pb_kits/playbook/pb_popover/popover.rb +1 -1
  98. data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +0 -1
  99. data/app/pb_kits/playbook/pb_time/_time.tsx +2 -2
  100. data/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +5 -2
  101. data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb +9 -0
  102. data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx +10 -0
  103. data/app/pb_kits/playbook/pb_timestamp/timestamp.rb +4 -1
  104. data/app/pb_kits/playbook/pb_timestamp/timestamp.test.js +164 -0
  105. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -4
  106. data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +11 -8
  107. data/app/pb_kits/playbook/tokens/_colors.scss +74 -74
  108. data/app/pb_kits/playbook/tokens/_typography.scss +8 -8
  109. data/app/pb_kits/playbook/utilities/_flexbox.scss +11 -11
  110. data/app/pb_kits/playbook/utilities/{_align_content.scss → flexbox_global_props/_align_content.scss} +0 -0
  111. data/app/pb_kits/playbook/utilities/{_align_items.scss → flexbox_global_props/_align_items.scss} +0 -0
  112. data/app/pb_kits/playbook/utilities/{_align_self.scss → flexbox_global_props/_align_self.scss} +0 -0
  113. data/app/pb_kits/playbook/utilities/{_flex.scss → flexbox_global_props/_flex.scss} +0 -0
  114. data/app/pb_kits/playbook/utilities/{_flex_direction.scss → flexbox_global_props/_flex_direction.scss} +0 -0
  115. data/app/pb_kits/playbook/utilities/{_flex_grow.scss → flexbox_global_props/_flex_grow.scss} +0 -0
  116. data/app/pb_kits/playbook/utilities/{_flex_shrink.scss → flexbox_global_props/_flex_shrink.scss} +0 -0
  117. data/app/pb_kits/playbook/utilities/{_flex_wrap.scss → flexbox_global_props/_flex_wrap.scss} +0 -0
  118. data/app/pb_kits/playbook/utilities/{_justify_content.scss → flexbox_global_props/_justify_content.scss} +0 -0
  119. data/app/pb_kits/playbook/utilities/{_justify_self.scss → flexbox_global_props/_justify_self.scss} +0 -0
  120. data/app/pb_kits/playbook/utilities/{_order.scss → flexbox_global_props/_order.scss} +0 -0
  121. data/app/pb_kits/playbook/utilities/props.ts +1 -1
  122. data/app/pb_kits/playbook/utilities/test-utils.js +2 -3
  123. data/app/pb_kits/playbook/utilities/text.ts +1 -1
  124. data/lib/playbook/version.rb +2 -2
  125. metadata +56 -25
  126. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.jsx +0 -155
  127. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.jsx +0 -124
  128. 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 %>