playbook_ui 4.14.0 → 4.15.0

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +2 -0
  3. data/app/pb_kits/playbook/data/menu.yml +2 -0
  4. data/app/pb_kits/playbook/index.js +4 -1
  5. data/app/pb_kits/playbook/packs/examples.js +2 -0
  6. data/app/pb_kits/playbook/packs/kits/pb_progress_step.js +2 -0
  7. data/app/pb_kits/playbook/pb_button/_button.jsx +9 -1
  8. data/app/pb_kits/playbook/pb_contact/_contact.jsx +1 -0
  9. data/app/pb_kits/playbook/pb_contact/contact.rb +2 -0
  10. data/app/pb_kits/playbook/pb_contact/docs/_contact_default.html.erb +5 -0
  11. data/app/pb_kits/playbook/pb_contact/docs/_contact_default.jsx +4 -0
  12. data/app/pb_kits/playbook/pb_contact/docs/_contact_with_detail.html.erb +6 -0
  13. data/app/pb_kits/playbook/pb_contact/docs/_contact_with_detail.jsx +5 -0
  14. data/app/pb_kits/playbook/pb_date_year_stacked/_date_year_stacked.jsx +2 -2
  15. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.jsx +56 -0
  16. data/app/pb_kits/playbook/pb_filter/Filter/FilterBackground.jsx +26 -0
  17. data/app/pb_kits/playbook/pb_filter/Filter/FilterDouble.jsx +58 -0
  18. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.jsx +46 -0
  19. data/app/pb_kits/playbook/pb_filter/Filter/FiltersPopover.jsx +37 -0
  20. data/app/pb_kits/playbook/pb_filter/Filter/ResultsCount.jsx +34 -0
  21. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.jsx +85 -0
  22. data/app/pb_kits/playbook/pb_filter/Filter/index.jsx +26 -0
  23. data/app/pb_kits/playbook/pb_filter/_filter.jsx +1 -222
  24. data/app/pb_kits/playbook/pb_filter/_filter.scss +16 -13
  25. data/app/pb_kits/playbook/pb_filter/docs/_filter_default.html.erb +34 -41
  26. data/app/pb_kits/playbook/pb_filter/docs/_filter_default.jsx +13 -9
  27. data/app/pb_kits/playbook/pb_filter/docs/_filter_no_background.html.erb +69 -74
  28. data/app/pb_kits/playbook/pb_filter/docs/_filter_no_background.jsx +12 -9
  29. data/app/pb_kits/playbook/pb_filter/docs/_filter_only.html.erb +28 -35
  30. data/app/pb_kits/playbook/pb_filter/docs/_filter_only.jsx +5 -6
  31. data/app/pb_kits/playbook/pb_filter/docs/_filter_single.html.erb +35 -41
  32. data/app/pb_kits/playbook/pb_filter/docs/_filter_single.jsx +12 -10
  33. data/app/pb_kits/playbook/pb_filter/docs/_sort_only.html.erb +12 -18
  34. data/app/pb_kits/playbook/pb_filter/docs/_sort_only.jsx +14 -44
  35. data/app/pb_kits/playbook/pb_filter/templates/_default.html.erb +1 -1
  36. data/app/pb_kits/playbook/pb_layout/_layout.jsx +66 -14
  37. data/app/pb_kits/playbook/pb_layout/docs/_layout_colors.jsx +63 -0
  38. data/app/pb_kits/playbook/pb_layout/docs/_layout_sizes.jsx +87 -0
  39. data/app/pb_kits/playbook/pb_layout/docs/_layout_sizes_dark.jsx +92 -0
  40. data/app/pb_kits/playbook/pb_layout/docs/_layout_transparent.jsx +24 -0
  41. data/app/pb_kits/playbook/pb_layout/docs/example.yml +4 -1
  42. data/app/pb_kits/playbook/pb_layout/docs/index.js +4 -1
  43. data/app/pb_kits/playbook/pb_online_status/_online_status.jsx +31 -14
  44. data/app/pb_kits/playbook/pb_online_status/docs/_online_status_default.jsx +19 -0
  45. data/app/pb_kits/playbook/pb_online_status/docs/example.yml +3 -3
  46. data/app/pb_kits/playbook/pb_online_status/docs/index.js +1 -0
  47. data/app/pb_kits/playbook/pb_popover/_popover.jsx +2 -2
  48. data/app/pb_kits/playbook/pb_popover/docs/example.yml +0 -2
  49. data/app/pb_kits/playbook/pb_popover/docs/index.js +0 -1
  50. data/app/pb_kits/playbook/pb_progress_step/_progress_step.html.erb +6 -0
  51. data/app/pb_kits/playbook/pb_progress_step/_progress_step.jsx +35 -0
  52. data/app/pb_kits/playbook/pb_progress_step/_progress_step.scss +388 -0
  53. data/app/pb_kits/playbook/pb_progress_step/_progress_step_item.html.erb +23 -0
  54. data/app/pb_kits/playbook/pb_progress_step/_progress_step_item.jsx +44 -0
  55. data/app/pb_kits/playbook/pb_progress_step/docs/_description.md +1 -0
  56. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_dark.html.erb +8 -0
  57. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_dark.jsx +18 -0
  58. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.html.erb +33 -0
  59. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_default.jsx +39 -0
  60. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_vertical.html.erb +33 -0
  61. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_vertical.jsx +40 -0
  62. data/app/pb_kits/playbook/pb_progress_step/docs/example.yml +12 -0
  63. data/app/pb_kits/playbook/pb_progress_step/docs/index.js +3 -0
  64. data/app/pb_kits/playbook/pb_progress_step/progress_step.rb +33 -0
  65. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.rb +19 -0
  66. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_default.html.erb +1 -1
  67. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_default.jsx +1 -1
  68. data/app/pb_kits/playbook/pb_stat_change/stat_change.rb +1 -1
  69. data/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +39 -14
  70. data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx +8 -0
  71. data/app/pb_kits/playbook/pb_timestamp/docs/example.yml +3 -3
  72. data/app/pb_kits/playbook/pb_timestamp/docs/index.js +1 -0
  73. data/app/pb_kits/playbook/pb_title_detail/_title_detail.jsx +47 -14
  74. data/app/pb_kits/playbook/pb_title_detail/docs/_title_detail_default.jsx +26 -0
  75. data/app/pb_kits/playbook/pb_title_detail/docs/example.yml +3 -3
  76. data/app/pb_kits/playbook/pb_title_detail/docs/index.js +1 -0
  77. data/app/pb_kits/playbook/pb_tooltip/_tooltip.html.erb +10 -0
  78. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +105 -0
  79. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default.html.erb +10 -0
  80. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_white.html.erb +9 -0
  81. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +5 -0
  82. data/app/pb_kits/playbook/pb_tooltip/index.js +80 -0
  83. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +34 -0
  84. data/app/pb_kits/playbook/tokens/_colors.scss +4 -0
  85. data/app/pb_kits/playbook/vendor.js +3 -0
  86. data/lib/playbook/version.rb +1 -1
  87. metadata +41 -6
  88. data/app/pb_kits/playbook/pb_layout/_body.jsx +0 -26
  89. data/app/pb_kits/playbook/pb_layout/_sidebar.jsx +0 -26
  90. data/app/pb_kits/playbook/pb_layout/docs/_layout_default.jsx +0 -14
  91. data/app/pb_kits/playbook/pb_popover/docs/_popover_with_button.html.erb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e529c840f659aace42862d67f6579c6fa9f1fc952960381374b8b005ff41b95
4
- data.tar.gz: 53c5c3676212e699d5c232fc6d4bc59ea3ab10a97335d08e7dc0e4e139a8859f
3
+ metadata.gz: 8d06b43573e33c771eb3617100802fa3e8ad15bf58f7037c233725df32d4e447
4
+ data.tar.gz: 005256edb667970f313898e57ede8d2f50cbe9222fd99007a318808e075f3e23
5
5
  SHA512:
6
- metadata.gz: 92e483f7ec5633610f6180f3d1cf8740f9fae2d128c9db1a17ae8ac55a352a19f358ad32104236f8dcbe9ccd370f40a57c3a63b2b7587a200c95f8d00500dc76
7
- data.tar.gz: 4707de050cf746dd9d82db1cc36cdc1bdf03a8a2653510e2785b324491ddbb1c462faea3053d4ba0d4e65c99f20bf609db0e76a16a3e851518ad58797af6c283
6
+ metadata.gz: 33b0a8f35f696aed191bae44c33aa4686864ba89ac73473b88cd749e30d6cc792a7d4fedff7b413857b7ddd3c22959b68df5b34884c0ffe92e6ec319b0af8c2d
7
+ data.tar.gz: 1070e81eb6faefd83fe85fa725534a8d5ad2ee16f17fb1b9b920433d045a75e09040a85ac64f33c3789d89de1b4dbb332355950f0289914a9acd65a6b8dc19e7
@@ -50,6 +50,7 @@
50
50
  @import 'pb_popover/popover';
51
51
  @import 'pb_progress_pills/progress_pills';
52
52
  @import 'pb_progress_simple/progress_simple';
53
+ @import 'pb_progress_step/progress_step';
53
54
  @import 'pb_radio/radio';
54
55
  @import 'pb_section_separator/section_separator';
55
56
  @import 'pb_select/select';
@@ -67,6 +68,7 @@
67
68
  @import 'pb_title_count/title_count';
68
69
  @import 'pb_title_detail/title_detail';
69
70
  @import 'pb_toggle/toggle';
71
+ @import 'pb_tooltip/tooltip';
70
72
  @import 'pb_typeahead/typeahead';
71
73
  @import 'pb_user/user';
72
74
  @import 'pb_user_badge/user_badge';
@@ -48,11 +48,13 @@ kits:
48
48
  - popover
49
49
  - progress_pills
50
50
  - progress_simple
51
+ - progress_step
51
52
  - section_separator
52
53
  - source
53
54
  - star_rating
54
55
  - stat_change
55
56
  - table
57
+ - tooltip
56
58
  - typography:
57
59
  - body
58
60
  - caption
@@ -52,6 +52,7 @@ export PersonContact from './pb_person_contact/_person_contact.jsx'
52
52
  export Pill from './pb_pill/_pill.jsx'
53
53
  export ProgressPills from './pb_progress_pills/_progress_pills.jsx'
54
54
  export ProgressSimple from './pb_progress_simple/_progress_simple.jsx'
55
+ export ProgressStep from './pb_progress_step/_progress_step.jsx'
55
56
  export Radio from './pb_radio/_radio.jsx'
56
57
  export SectionSeparator from './pb_section_separator/_section_separator.jsx'
57
58
  export Select from './pb_select/_select.jsx'
@@ -66,10 +67,11 @@ export Textarea from './pb_textarea/_textarea.jsx'
66
67
  export TextInput from './pb_text_input/_text_input.jsx'
67
68
  export Time from './pb_time/_time.jsx'
68
69
  export TimeStacked from './pb_time_stacked/_time_stacked.jsx'
69
- export TimeStamp from './pb_timestamp/_timestamp.jsx'
70
+ export Timestamp from './pb_timestamp/_timestamp.jsx'
70
71
  export TimeRangeInline from './pb_time_range_inline/_time_range_inline.jsx'
71
72
  export Title from './pb_title/_title.jsx'
72
73
  export TitleCount from './pb_title_count/_title_count.jsx'
74
+ export TitleDetail from './pb_title_detail/_title_detail.jsx'
73
75
  export Toggle from './pb_toggle/_toggle.jsx'
74
76
  export User from './pb_user/_user.jsx'
75
77
  export UserBadge from './pb_user_badge/_user_badge.jsx'
@@ -86,3 +88,4 @@ export pbChart from './plugins/pb_chart.js'
86
88
  export PbTypeahead from './pb_typeahead'
87
89
  export PbPopover from './pb_popover'
88
90
  export PbTable from './pb_table'
91
+ export PbTooltip from './pb_tooltip'
@@ -63,6 +63,7 @@ import * as PersonContact from 'pb_person_contact/docs'
63
63
  import * as Pill from 'pb_pill/docs'
64
64
  import * as ProgressPills from 'pb_progress_pills/docs'
65
65
  import * as ProgressSimple from 'pb_progress_simple/docs'
66
+ import * as ProgressStep from 'pb_progress_step/docs'
66
67
  import * as Radio from 'pb_radio/docs'
67
68
  import * as SectionSeparator from 'pb_section_separator/docs'
68
69
  import * as Select from 'pb_select/docs'
@@ -137,6 +138,7 @@ WebpackerReact.setup({
137
138
  ...Pill,
138
139
  ...ProgressPills,
139
140
  ...ProgressSimple,
141
+ ...ProgressStep,
140
142
  ...Radio,
141
143
  ...SectionSeparator,
142
144
  ...Select,
@@ -0,0 +1,2 @@
1
+ import '../../pb_progress_step/_progress_step.jsx'
2
+
@@ -3,6 +3,8 @@
3
3
  import React from 'react'
4
4
  import classnames from 'classnames'
5
5
 
6
+ import Icon from '../pb_icon/_icon.jsx'
7
+
6
8
  type EventHandler = (SyntheticInputEvent<HTMLInputElement>) => void
7
9
  type ButtonPropTypes = {
8
10
  aria?: {
@@ -83,7 +85,13 @@ const Button = (props: ButtonPropTypes) => {
83
85
  const buttonAria = buttonAriaProps(props)
84
86
  const css = classnames(buttonClassName(props), className)
85
87
  const loadingIcon = (
86
- <i className="pb_icon_kit far fa-spinner fa-fw fa-pulse loading-icon" />
88
+ <div className="loading-icon">
89
+ <Icon
90
+ fixedWidth
91
+ icon="spinner"
92
+ pulse
93
+ />
94
+ </div>
87
95
  )
88
96
 
89
97
  const content = (
@@ -9,6 +9,7 @@ const contactTypeMap = {
9
9
  'cell': 'mobile',
10
10
  'home': 'phone',
11
11
  'work': 'phone-office',
12
+ 'work-cell': 'phone-laptop',
12
13
  'email': 'envelope',
13
14
  'wrong number': 'slash-phone',
14
15
  }
@@ -28,6 +28,8 @@ module Playbook
28
28
  "phone-office"
29
29
  when "email"
30
30
  "envelope"
31
+ when "work-cell"
32
+ "phone-laptop"
31
33
  when "wrong-phone"
32
34
  "phone-slash"
33
35
  else # "unknown" || "other"
@@ -16,3 +16,8 @@
16
16
  contact_type: "wrong number",
17
17
  contact_value: "3245627482",
18
18
  }) %>
19
+
20
+ <%= pb_rails("contact", props: {
21
+ contact_type: "work-cell",
22
+ contact_value: "349-185-9988",
23
+ }) %>
@@ -19,6 +19,10 @@ const ContactDefault = () => {
19
19
  contactType="work"
20
20
  contactValue="3245627482"
21
21
  />
22
+ <Contact
23
+ contactType="work-cell"
24
+ contactValue="3245627482"
25
+ />
22
26
  </div>
23
27
  )
24
28
  }
@@ -14,3 +14,9 @@
14
14
  contact_value: "3245627482",
15
15
  contact_detail: "Work",
16
16
  }) %>
17
+
18
+ <%= pb_rails("contact", props: {
19
+ contact_type: "work-cell",
20
+ contact_value: "3245627482",
21
+ contact_detail: "Work-Cell",
22
+ }) %>
@@ -18,6 +18,11 @@ const ContactDefault = () => {
18
18
  contactType="work"
19
19
  contactValue="3245627482"
20
20
  />
21
+ <Contact
22
+ contactDetail="Work-Cell"
23
+ contactType="work-cell"
24
+ contactValue="3245627482"
25
+ />
21
26
  </div>
22
27
  )
23
28
  }
@@ -12,7 +12,7 @@ import {
12
12
  } from '../'
13
13
 
14
14
  type DateYearStackedProps = {
15
- align?: 'center' | 'right',
15
+ align?: 'left' | 'center' | 'right',
16
16
  className?: String | Array<String>,
17
17
  dark?: Boolean,
18
18
  data?: String,
@@ -21,7 +21,7 @@ type DateYearStackedProps = {
21
21
  }
22
22
 
23
23
  const DateYearStacked = ({
24
- align,
24
+ align = 'left',
25
25
  className,
26
26
  dark = false,
27
27
  date,
@@ -0,0 +1,56 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { isEmpty, map, omitBy } from 'lodash'
5
+ import { Caption, Title } from '../../'
6
+
7
+ export type FilterDescription = {
8
+ [key: string]: ?string | boolean,
9
+ }
10
+
11
+ export type CurrentFiltersProps = {
12
+ filters: FilterDescription,
13
+ }
14
+
15
+ const hiddenFilters = (value) => isEmpty(value) && value !== true
16
+
17
+ const CurrentFilters = ({ filters }: CurrentFiltersProps) => {
18
+ const displayableFilters = omitBy(filters, hiddenFilters)
19
+
20
+ return (
21
+ <div className="maskContainer">
22
+ <If condition={!isEmpty(filters)}>
23
+ <div className="filters">
24
+ <div className="left_gradient" />
25
+ {map(displayableFilters, (value, name) => (
26
+ <div
27
+ className="filter"
28
+ key={`filter-${name}`}
29
+ >
30
+ <Choose>
31
+ <When condition={value === true}>
32
+ <Title
33
+ size={4}
34
+ tag="h4"
35
+ text={name}
36
+ />
37
+ </When>
38
+ <Otherwise>
39
+ <Caption text={name} />
40
+ <Title
41
+ size={4}
42
+ tag="h4"
43
+ text={value}
44
+ />
45
+ </Otherwise>
46
+ </Choose>
47
+ </div>
48
+ ))}
49
+ <div className="right_gradient" />
50
+ </div>
51
+ </If>
52
+ </div>
53
+ )
54
+ }
55
+
56
+ export default CurrentFilters
@@ -0,0 +1,26 @@
1
+ /* @flow */
2
+
3
+ import React, { Node } from 'react'
4
+ import { Card } from '../../'
5
+
6
+ type FilterBackgroundProps = {
7
+ background: boolean,
8
+ className: string,
9
+ children: Node,
10
+ }
11
+ const FilterBackground = ({ background = true, className, children }: FilterBackgroundProps) => (
12
+ <div className={`pb_filter_kit ${className}`}>
13
+ <Choose>
14
+ <When condition={background}>
15
+ <Card padding="none">
16
+ {children}
17
+ </Card>
18
+ </When>
19
+ <Otherwise>
20
+ {children}
21
+ </Otherwise>
22
+ </Choose>
23
+ </div>
24
+ )
25
+
26
+ export default FilterBackground
@@ -0,0 +1,58 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { Caption, Flex, SectionSeparator } from '../../'
5
+
6
+ import CurrentFilters, { FilterDescription } from './CurrentFilters'
7
+ import FilterBackground, { FilterBackgroundProps } from './FilterBackground'
8
+ import FiltersPopover from './FiltersPopover'
9
+ import ResultsCount from './ResultsCount'
10
+ import SortMenu, { SortingChangeCallback, SortOptions, SortValue } from './SortMenu'
11
+
12
+ export type FilterDoubleProps = {
13
+ children: Node,
14
+ filters?: FilterDescription,
15
+ onSortChange: SortingChangeCallback,
16
+ results?: number,
17
+ sortOptions: SortOptions,
18
+ sortValue?: SortValue,
19
+ } & FilterBackgroundProps
20
+
21
+ const FilterDouble = ({ onSortChange, sortOptions, sortValue, filters, results, children, ...bgProps }: FilterDoubleProps) => (
22
+ <FilterBackground {...bgProps}>
23
+ <Flex
24
+ orientation="row"
25
+ vertical="center"
26
+ >
27
+ <FiltersPopover>
28
+ {children}
29
+ </FiltersPopover>
30
+ <CurrentFilters filters={filters} />
31
+ </Flex>
32
+ <SectionSeparator />
33
+ <Flex
34
+ className="filter-bottom"
35
+ orientation="row"
36
+ spacing="between"
37
+ vertical="center"
38
+ >
39
+ <ResultsCount
40
+ results={results}
41
+ title
42
+ />
43
+ <Flex
44
+ orientation="row"
45
+ vertical="center"
46
+ >
47
+ <Caption text="sort by:" />
48
+ <SortMenu
49
+ onChange={onSortChange}
50
+ options={sortOptions}
51
+ value={sortValue}
52
+ />
53
+ </Flex>
54
+ </Flex>
55
+ </FilterBackground>
56
+ )
57
+
58
+ export default FilterDouble
@@ -0,0 +1,46 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { isEmpty } from 'lodash'
5
+ import { Flex } from '../../'
6
+
7
+ import CurrentFilters, { FilterDescription } from './CurrentFilters'
8
+ import FilterBackground, { FilterBackgroundProps } from './FilterBackground'
9
+ import FiltersPopover from './FiltersPopover'
10
+ import ResultsCount from './ResultsCount'
11
+ import SortMenu, { SortingChangeCallback, SortOptions, SortValue } from './SortMenu'
12
+
13
+ export type FilterSingleProps = {
14
+ children?: Node,
15
+ filters?: FilterDescription,
16
+ onSortChange?: SortingChangeCallback,
17
+ results?: number,
18
+ sortOptions?: SortOptions,
19
+ sortValue?: SortValue,
20
+ } & FilterBackgroundProps
21
+
22
+ const FilterSingle = ({ onSortChange, sortOptions, sortValue, filters, results, children, ...bgProps }: FilterSingleProps) => (
23
+ <FilterBackground {...bgProps}>
24
+ <Flex
25
+ orientation="row"
26
+ vertical="center"
27
+ >
28
+ <If condition={children}>
29
+ <FiltersPopover>
30
+ {children}
31
+ </FiltersPopover>
32
+ <CurrentFilters filters={filters} />
33
+ </If>
34
+ <ResultsCount results={results} />
35
+ <If condition={!isEmpty(sortOptions)}>
36
+ <SortMenu
37
+ onChange={onSortChange}
38
+ options={sortOptions}
39
+ value={sortValue}
40
+ />
41
+ </If>
42
+ </Flex>
43
+ </FilterBackground>
44
+ )
45
+
46
+ export default FilterSingle
@@ -0,0 +1,37 @@
1
+ /* @flow */
2
+
3
+ import React, { Node, useState } from 'react'
4
+ import { CircleIconButton, PbReactPopover } from '../../'
5
+
6
+ const FiltersPopoverProps = { children: Node }
7
+ const FiltersPopover = ({ children }: FiltersPopoverProps) => {
8
+ const [hide, updateHide] = useState(true)
9
+ const toggle = () => updateHide(!hide)
10
+
11
+ const filterButton = (
12
+ <CircleIconButton
13
+ icon="filter"
14
+ id="filter"
15
+ onClick={toggle}
16
+ text="filter"
17
+ variant="secondary"
18
+ />
19
+ )
20
+
21
+ return (
22
+ <PbReactPopover
23
+ closeOnClick="outside"
24
+ offset
25
+ placement="bottom"
26
+ reference={filterButton}
27
+ shouldClosePopover={updateHide}
28
+ show={!hide}
29
+ >
30
+ <div className="pb-form">
31
+ {children}
32
+ </div>
33
+ </PbReactPopover>
34
+ )
35
+ }
36
+
37
+ export default FiltersPopover
@@ -0,0 +1,34 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import { Caption, TitleCount } from '../../'
5
+
6
+ const resultsText = (results: number): string => results == 1 ? 'Result' : 'Results'
7
+
8
+ type ResultsCountProps = {
9
+ results?: ?number,
10
+ title?: boolean,
11
+ }
12
+ const ResultsCount = ({ results, title }: ResultsCountProps) => (
13
+ <Choose>
14
+ <When condition={results && title}>
15
+ <TitleCount
16
+ align="center"
17
+ count={results}
18
+ title={`${resultsText(results)}:`}
19
+ />
20
+ </When>
21
+ <When condition={results}>
22
+ <Caption
23
+ className="filter-results"
24
+ size="xs"
25
+ text={`${results} ${resultsText(results)}`}
26
+ />
27
+ </When>
28
+ <Otherwise>
29
+ <div />
30
+ </Otherwise>
31
+ </Choose>
32
+ )
33
+
34
+ export default ResultsCount
@@ -0,0 +1,85 @@
1
+ /* @flow */
2
+
3
+ import React, { useState } from 'react'
4
+ import { find, map, partial } from 'lodash'
5
+ import { Button, Icon, List, ListItem, PbReactPopover } from '../../'
6
+
7
+ export type Direction = 'asc' | 'desc'
8
+ export type SortOptions = { [name: string]: string }
9
+ export type SortValue = { name: string, dir: Direction }
10
+ export type SortingChangeCallback = (SortValue[]) => void
11
+
12
+ const nextValue = (value: SortValue[], name: string): Direction => {
13
+ const current = find(value, { name })
14
+ return {
15
+ name,
16
+ dir: current && current.dir == 'asc' ? 'desc' : 'asc',
17
+ }
18
+ }
19
+
20
+ const directionIcon = (dir: Direction) => (
21
+ dir == 'asc' ? 'sort-amount-up' : 'sort-amount-down'
22
+ )
23
+
24
+ const renderOptions = (options: SortOptions, value: SortValue[], handleChange: (SortValue) => void) => (
25
+ map(options, (label, name) => {
26
+ const next = nextValue(value, name)
27
+ return (
28
+ <ListItem key={`option-${next.name}-${next.dir}`}>
29
+ <Button
30
+ icon={directionIcon(next.dir)}
31
+ onClick={partial(handleChange, next)}
32
+ text={` ${label}`}
33
+ variant="link"
34
+ />
35
+ </ListItem>
36
+ )
37
+ })
38
+ )
39
+
40
+ export type SortMenuProps = {
41
+ value?: SortValue[],
42
+ options: SortOptions,
43
+ onChange: SortingChangeCallback,
44
+ }
45
+ const SortMenu = ({ options, value, onChange }: SortMenuProps) => {
46
+ const [hide, updateHide] = useState(true)
47
+ const toggle = () => updateHide(!hide)
48
+ const handleChange = (value: SortValue) => {
49
+ updateHide(true)
50
+ onChange([value])
51
+ }
52
+
53
+ const sortButton = (
54
+ <Button
55
+ id="sort-button"
56
+ onClick={toggle}
57
+ variant="link"
58
+ >
59
+ {map(value, ({ dir, name }) => (
60
+ <span key={`current-sort-${name}-${dir}`}>
61
+ <Icon icon={directionIcon(dir)} />
62
+ {` ${options[name]}`}
63
+ </span>
64
+ ))}
65
+ </Button>
66
+ )
67
+
68
+ return (
69
+ <PbReactPopover
70
+ className="pb_filter_sort_menu"
71
+ closeOnClick="outside"
72
+ offset
73
+ placement="bottom"
74
+ reference={sortButton}
75
+ shouldClosePopover={updateHide}
76
+ show={!hide}
77
+ >
78
+ <List>
79
+ {renderOptions(options, value, handleChange)}
80
+ </List>
81
+ </PbReactPopover>
82
+ )
83
+ }
84
+
85
+ export default SortMenu
@@ -0,0 +1,26 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+
5
+ import FilterSingle, { FilterSingleProps } from './FilterSingle'
6
+ import FilterDouble, { FilterDoubleProps } from './FilterDouble'
7
+
8
+ type FilterProps = FilterSingleProps | FilterDoubleProps & {
9
+ double?: boolean,
10
+ }
11
+
12
+ const Filter = ({
13
+ double = false,
14
+ ...templateProps
15
+ }: FilterProps) => (
16
+ <Choose>
17
+ <When condition={double}>
18
+ <FilterDouble {...templateProps} />
19
+ </When>
20
+ <Otherwise>
21
+ <FilterSingle {...templateProps} />
22
+ </Otherwise>
23
+ </Choose>
24
+ )
25
+
26
+ export default Filter