playbook_ui 8.0.3 → 8.1.0.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/app/pb_kits/playbook/_playbook.scss +10 -7
  4. data/app/pb_kits/playbook/data/menu.yml +3 -1
  5. data/app/pb_kits/playbook/index.js +3 -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/card_header.rb +7 -7
  38. data/app/pb_kits/playbook/pb_card/docs/_card_tag.html.erb +25 -0
  39. data/app/pb_kits/playbook/pb_card/docs/_card_tag.jsx +59 -0
  40. data/app/pb_kits/playbook/pb_card/docs/example.yml +2 -0
  41. data/app/pb_kits/playbook/pb_card/docs/index.js +1 -0
  42. data/app/pb_kits/playbook/pb_circle_icon_button/circle_icon_button.test.js +17 -0
  43. data/app/pb_kits/playbook/pb_collapsible/_collapsible.jsx +84 -0
  44. data/app/pb_kits/playbook/pb_collapsible/_collapsible.scss +15 -0
  45. data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleContent.jsx +40 -0
  46. data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleMain.jsx +59 -0
  47. data/app/pb_kits/playbook/pb_collapsible/collapsible.html.erb +7 -0
  48. data/app/pb_kits/playbook/pb_collapsible/collapsible.rb +11 -0
  49. data/app/pb_kits/playbook/pb_collapsible/collapsible.test.js +50 -0
  50. data/app/pb_kits/playbook/pb_collapsible/collapsible_content.html.erb +7 -0
  51. data/app/pb_kits/playbook/pb_collapsible/collapsible_content.rb +17 -0
  52. data/app/pb_kits/playbook/pb_collapsible/collapsible_main.html.erb +16 -0
  53. data/app/pb_kits/playbook/pb_collapsible/collapsible_main.rb +15 -0
  54. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_default.html.erb +10 -0
  55. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_default.jsx +19 -0
  56. data/app/pb_kits/playbook/pb_collapsible/docs/example.yml +9 -0
  57. data/app/pb_kits/playbook/pb_collapsible/docs/index.js +1 -0
  58. data/app/pb_kits/playbook/pb_collapsible/index.js +79 -0
  59. data/app/pb_kits/playbook/pb_dashboard/commonSettings.js +2 -2
  60. data/app/pb_kits/playbook/pb_dashboard/pbChartsLightTheme.js +2 -2
  61. data/app/pb_kits/playbook/pb_date_time_stacked/_date_time_stacked.jsx +6 -2
  62. data/app/pb_kits/playbook/pb_date_time_stacked/date_time_stacked.html.erb +1 -1
  63. data/app/pb_kits/playbook/pb_dialog/_close_icon.jsx +23 -0
  64. data/app/pb_kits/playbook/pb_dialog/_dialog.html.erb +10 -0
  65. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +142 -0
  66. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +133 -0
  67. data/app/pb_kits/playbook/pb_dialog/_dialog_context.jsx +3 -0
  68. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +21 -0
  69. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +36 -0
  70. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +68 -0
  71. data/app/pb_kits/playbook/pb_dialog/dialog.rb +47 -0
  72. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +23 -0
  73. data/app/pb_kits/playbook/pb_dialog/dialog_header.rb +31 -0
  74. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.jsx +53 -0
  75. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.md +2 -0
  76. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.jsx +27 -0
  77. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.jsx +27 -0
  78. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_scrollable.md +2 -0
  79. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.jsx +119 -0
  80. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_separators.md +2 -0
  81. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.jsx +28 -0
  82. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_should_close_on_overlay.md +2 -0
  83. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_sizes.jsx +93 -0
  84. data/app/pb_kits/playbook/pb_dialog/docs/example.yml +10 -0
  85. data/app/pb_kits/playbook/pb_dialog/docs/index.js +6 -0
  86. data/app/pb_kits/playbook/pb_docs/kit_example.rb +1 -1
  87. data/app/pb_kits/playbook/pb_inline/_inline.jsx +83 -0
  88. data/app/pb_kits/playbook/pb_inline/_inline.scss +58 -0
  89. data/app/pb_kits/playbook/pb_inline/docs/_inline_default.jsx +36 -0
  90. data/app/pb_kits/playbook/pb_inline/docs/_inline_input_options.jsx +58 -0
  91. data/app/pb_kits/playbook/pb_inline/docs/_inline_text_options.jsx +99 -0
  92. data/app/pb_kits/playbook/pb_inline/docs/example.yml +5 -0
  93. data/app/pb_kits/playbook/pb_inline/docs/index.js +3 -0
  94. data/app/pb_kits/playbook/pb_inline/inline.test.jsx +21 -0
  95. data/app/pb_kits/playbook/pb_nav/_item.jsx +2 -0
  96. data/app/pb_kits/playbook/pb_nav/_nav.jsx +2 -2
  97. data/app/pb_kits/playbook/pb_nav/item.html.erb +2 -2
  98. data/app/pb_kits/playbook/pb_nav/nav.html.erb +1 -1
  99. data/app/pb_kits/playbook/pb_online_status/_online_status.jsx +2 -0
  100. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +1 -1
  101. data/app/pb_kits/playbook/pb_progress_simple/_progress_simple.jsx +1 -1
  102. data/app/pb_kits/playbook/pb_progress_simple/_progress_simple.scss +5 -0
  103. data/app/pb_kits/playbook/pb_progress_simple/docs/_progress_simple_variants.html.erb +5 -0
  104. data/app/pb_kits/playbook/pb_progress_simple/docs/_progress_simple_variants.jsx +7 -0
  105. data/app/pb_kits/playbook/pb_progress_simple/docs/_progress_simple_variants.md +1 -1
  106. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.rb +1 -1
  107. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.jsx +4 -3
  108. data/app/pb_kits/playbook/pb_text_input/_text_input.jsx +3 -0
  109. data/app/pb_kits/playbook/pb_textarea/_textarea.jsx +3 -0
  110. data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.jsx +43 -26
  111. data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.scss +18 -0
  112. data/app/pb_kits/playbook/pb_time_stacked/docs/_time_stacked_default.html.erb +18 -5
  113. data/app/pb_kits/playbook/pb_time_stacked/docs/_time_stacked_default.jsx +10 -5
  114. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.html.erb +7 -3
  115. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.rb +8 -30
  116. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.test.js +33 -0
  117. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +4 -3
  118. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +6 -1
  119. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.jsx +25 -2
  120. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.jsx +1 -0
  121. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.jsx +7 -3
  122. data/app/pb_kits/playbook/plugins/pb_chart.js +1 -1
  123. data/app/pb_kits/playbook/react_rails_kits.js +4 -0
  124. data/app/pb_kits/playbook/tokens/_border_radius.scss +0 -10
  125. data/app/pb_kits/playbook/tokens/_colors.scss +0 -25
  126. data/app/pb_kits/playbook/tokens/_line_height.scss +0 -9
  127. data/app/pb_kits/playbook/tokens/_opacity.scss +0 -9
  128. data/app/pb_kits/playbook/tokens/_positioning.scss +0 -9
  129. data/app/pb_kits/playbook/tokens/_screen_sizes.scss +0 -9
  130. data/app/pb_kits/playbook/tokens/_shadows.scss +0 -9
  131. data/app/pb_kits/playbook/tokens/_spacing.scss +0 -10
  132. data/app/pb_kits/playbook/tokens/_typography.scss +0 -25
  133. data/app/pb_kits/playbook/tokens/exports/_border_radius.scss +10 -0
  134. data/app/pb_kits/playbook/tokens/exports/_colors.scss +26 -0
  135. data/app/pb_kits/playbook/tokens/exports/_line_height.scss +10 -0
  136. data/app/pb_kits/playbook/tokens/exports/_opacity.scss +10 -0
  137. data/app/pb_kits/playbook/tokens/exports/_positioning.scss +10 -0
  138. data/app/pb_kits/playbook/tokens/exports/_screen_sizes.scss +10 -0
  139. data/app/pb_kits/playbook/tokens/exports/_shadows.scss +10 -0
  140. data/app/pb_kits/playbook/tokens/exports/_spacing.scss +10 -0
  141. data/app/pb_kits/playbook/tokens/exports/_typography.scss +24 -0
  142. data/app/pb_kits/playbook/utilities/test-utils.js +6 -0
  143. data/app/pb_kits/playbook/vendor.js +3 -0
  144. data/dist/reset.css +1 -0
  145. data/lib/playbook/props/base.rb +1 -1
  146. data/lib/playbook/version.rb +1 -1
  147. metadata +74 -11
@@ -1,4 +1,4 @@
1
- <%= content_tag(:div,
1
+ <%= content_tag(object.tag,
2
2
  id: object.id,
3
3
  data: object.data,
4
4
  class: object.classname,
@@ -9,6 +9,9 @@ module Playbook
9
9
  default: "none"
10
10
  prop :highlight, type: Playbook::Props::Hash,
11
11
  default: {}
12
+ prop :tag, type: Playbook::Props::Enum,
13
+ values: %w[div section footer header article aside main nav],
14
+ default: "div"
12
15
  prop :border_none, type: Playbook::Props::Boolean,
13
16
  default: false
14
17
  prop :border_radius, type: Playbook::Props::Enum,
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playbook
4
- module PbCard
5
- class CardHeader < Playbook::KitBase
6
- prop :header_color, type: Playbook::Props::String,
7
- default: "category_1"
4
+ module PbCard
5
+ class CardHeader < Playbook::KitBase
6
+ prop :header_color, type: Playbook::Props::String,
7
+ default: "category_1"
8
8
 
9
- def classname
10
- generate_classname("pb_card_header_kit", header_color)
11
- end
9
+ def classname
10
+ generate_classname("pb_card_header_kit", header_color)
12
11
  end
13
12
  end
14
13
  end
14
+ end
@@ -0,0 +1,25 @@
1
+ <%= pb_rails("card", props: { tag: "section" }) do %> section <% end %>
2
+
3
+ <br />
4
+
5
+ <%= pb_rails("card", props: { tag: "footer" }) do %> footer <% end %>
6
+
7
+ <br />
8
+
9
+ <%= pb_rails("card", props: { tag: "header" }) do %> header <% end %>
10
+
11
+ <br />
12
+
13
+ <%= pb_rails("card", props: { tag: "article" }) do %> article <% end %>
14
+
15
+ <br />
16
+
17
+ <%= pb_rails("card", props: { tag: "aside" }) do %> aside <% end %>
18
+
19
+ <br />
20
+
21
+ <%= pb_rails("card", props: { tag: "main" }) do %> main <% end %>
22
+
23
+ <br />
24
+
25
+ <%= pb_rails("card", props: { tag: "nav" }) do %> nav <% end %>
@@ -0,0 +1,59 @@
1
+ import React from 'react'
2
+ import { Card } from '../../'
3
+
4
+ const CardTag = (props) => {
5
+ return (
6
+ <div>
7
+ <Card
8
+ tag="section"
9
+ {...props}
10
+ >
11
+ {'section'}
12
+ </Card>
13
+ <br />
14
+ <Card
15
+ tag="footer"
16
+ {...props}
17
+ >
18
+ {'footer'}
19
+ </Card>
20
+ <br />
21
+ <Card
22
+ tag="header"
23
+ {...props}
24
+ >
25
+ {'header'}
26
+ </Card>
27
+ <br />
28
+ <Card
29
+ tag="article"
30
+ {...props}
31
+ >
32
+ {'article'}
33
+ </Card>
34
+ <br />
35
+ <Card
36
+ tag="aside"
37
+ {...props}
38
+ >
39
+ {'aside'}
40
+ </Card>
41
+ <br />
42
+ <Card
43
+ tag="main"
44
+ {...props}
45
+ >
46
+ {'main'}
47
+ </Card>
48
+ <br />
49
+ <Card
50
+ tag="nav"
51
+ {...props}
52
+ >
53
+ {'nav'}
54
+ </Card>
55
+ </div>
56
+ )
57
+ }
58
+
59
+ export default CardTag
@@ -4,6 +4,7 @@ examples:
4
4
  - card_highlight: Highlight Cards
5
5
  - card_header: Header Cards
6
6
  - card_selected: Selected
7
+ - card_tag: HTML Tag
7
8
  - card_padding: Padding Size
8
9
  - card_shadow: Shadow Size
9
10
  - card_content: Content Size
@@ -15,6 +16,7 @@ examples:
15
16
  - card_highlight: Highlight Cards
16
17
  - card_header: Header Cards
17
18
  - card_selected: Selected
19
+ - card_tag: HTML Tag
18
20
  - card_padding: Padding Size
19
21
  - card_shadow: Shadow Size
20
22
  - card_content: Content Size
@@ -2,6 +2,7 @@ export { default as CardLight } from './_card_light.jsx'
2
2
  export { default as CardHighlight } from './_card_highlight.jsx'
3
3
  export { default as CardHeader } from './_card_header.jsx'
4
4
  export { default as CardSelected } from './_card_selected.jsx'
5
+ export { default as CardTag } from './_card_tag.jsx'
5
6
  export { default as CardPadding } from './_card_padding.jsx'
6
7
  export { default as CardShadow } from './_card_shadow.jsx'
7
8
  export { default as CardContent } from './_card_content.jsx'
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import CircleIconButton from './_circle_icon_button'
5
+
6
+ test('default test', () => {
7
+ render(
8
+ <CircleIconButton
9
+ data={{ testid: 'default-test' }}
10
+ icon="plus"
11
+ />
12
+ )
13
+
14
+ const kit = screen.getByTestId('default-test')
15
+
16
+ expect(kit).toHaveClass('pb_circle_icon_button_kit')
17
+ })
@@ -0,0 +1,84 @@
1
+ /* @flow */
2
+
3
+ import classnames from 'classnames'
4
+ import React, { useState } from 'react'
5
+ import { globalProps } from '../utilities/globalProps.js'
6
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
7
+ import CollapsibleContent from './child_kits/CollapsibleContent'
8
+ import CollapsibleMain from './child_kits/CollapsibleMain'
9
+
10
+ export const CollapsibleContext = React.createContext({})
11
+
12
+ type CollapsibleProps = {
13
+ children: CollapsibleMain | CollapsibleContent | ReactNode,
14
+ aria?: object,
15
+ className?: string,
16
+ collapsed?: boolean,
17
+ data?: object,
18
+ id?: string,
19
+ padding?: string,
20
+ }
21
+
22
+ const useCollapsible = (initial = false) => {
23
+ const [collapsed, setCollapsed] = useState(initial)
24
+
25
+ return [
26
+ collapsed,
27
+ () => setCollapsed((t) => !t),
28
+ ]
29
+ }
30
+
31
+ const Collapsible = ({
32
+ aria = {},
33
+ className,
34
+ children = [],
35
+ collapsed = true,
36
+ data = {},
37
+ id,
38
+ padding = 'md',
39
+ ...props
40
+ }: CollapsibleProps) => {
41
+ const [isCollapsed, collapse] = useCollapsible(collapsed)
42
+ const CollapsibleParent = React.Children.toArray(children)
43
+
44
+ if (CollapsibleParent.length !== 2) {
45
+ throw new Error('Collapsible requires <CollapsibleMain> and <CollapsibleContent> to function properly.')
46
+ }
47
+
48
+ const Main = CollapsibleParent[0]
49
+ const Content = CollapsibleParent[1]
50
+
51
+ const { children: mainChildren, ...mainProps } = Main.props
52
+ const { children: contentChildren, ...contentProps } = Content.props
53
+ const ariaProps = buildAriaProps(aria)
54
+ const dataProps = buildDataProps(data)
55
+ const classes = classnames(
56
+ buildCss('pb_collapsible'),
57
+ className,
58
+ globalProps(props, { padding })
59
+ )
60
+
61
+ return (
62
+ <CollapsibleContext.Provider value={{ collapsed: isCollapsed, collapse }}>
63
+ <div
64
+ {...ariaProps}
65
+ {...dataProps}
66
+ className={classes}
67
+ id={id}
68
+ >
69
+ <CollapsibleMain {...mainProps}>
70
+ {mainChildren}
71
+ </CollapsibleMain>
72
+
73
+ <CollapsibleContent {...contentProps}>
74
+ {contentChildren}
75
+ </CollapsibleContent>
76
+ </div>
77
+ </CollapsibleContext.Provider>
78
+ )
79
+ }
80
+
81
+ Collapsible.Main = CollapsibleMain
82
+ Collapsible.Content = CollapsibleContent
83
+
84
+ export default Collapsible
@@ -0,0 +1,15 @@
1
+ [class^=pb_collapsible_kit] {
2
+ .toggle-content {
3
+ display: none;
4
+ height: 0;
5
+ padding-bottom: 0 !important;
6
+ padding-top: 0 !important;
7
+ overflow: hidden;
8
+ transition: height 300ms, padding 300ms ease-in-out;
9
+ }
10
+
11
+ .toggle-content.is-visible {
12
+ display: block;
13
+ height: auto;
14
+ }
15
+ }
@@ -0,0 +1,40 @@
1
+ /* @flow */
2
+
3
+ import classnames from 'classnames'
4
+ import React, { useContext } from 'react'
5
+ import AnimateHeight from 'react-animate-height'
6
+ import { buildCss } from '../../utilities/props'
7
+ import { globalProps } from '../../utilities/globalProps.js'
8
+
9
+ import { CollapsibleContext } from '../_collapsible.jsx'
10
+
11
+ type CollapsibleContentProps = {
12
+ children: array<React.ReactNode> | React.ReactNode | string,
13
+ className?: string,
14
+ padding?: string,
15
+ }
16
+
17
+ const CollapsibleContent = ({
18
+ children,
19
+ className,
20
+ padding = 'md',
21
+ ...props
22
+ }: CollapsibleContentProps) => {
23
+ const context = useContext(CollapsibleContext)
24
+ const contentCSS = buildCss('pb_collapsible_content_kit')
25
+ const contentSpacing = globalProps(props, { padding })
26
+
27
+ return (
28
+ <div className={classnames(contentCSS, className, contentSpacing)}>
29
+ <AnimateHeight
30
+ duration={300}
31
+ height={context.collapsed ? 0 : 'auto'}
32
+ id="bottom-section"
33
+ >
34
+ {children}
35
+ </AnimateHeight>
36
+ </div>
37
+ )
38
+ }
39
+
40
+ export default CollapsibleContent
@@ -0,0 +1,59 @@
1
+ /* @flow */
2
+
3
+ import classnames from 'classnames'
4
+ import { Flex, FlexItem } from '../../'
5
+ import React, { useContext } from 'react'
6
+ import { buildCss } from '../../utilities/props'
7
+ import { globalProps } from '../../utilities/globalProps.js'
8
+
9
+ import { CollapsibleContext } from '../_collapsible.jsx'
10
+
11
+ type CollapsibleMainProps = {
12
+ children: array<React.ReactNode> | React.ReactNode,
13
+ className?: string,
14
+ padding?: string,
15
+ }
16
+
17
+ type IconProps = {
18
+ collapsed: boolean
19
+ }
20
+
21
+ const Icon = ({ collapsed }: IconProps) => {
22
+ const direction = collapsed ? 'down' : 'up'
23
+
24
+ return (
25
+ <div
26
+ key={direction}
27
+ style={{ verticalAlign: 'middle' }}
28
+ >
29
+ <i className={`far fa-chevron-${direction} fa-fw`} />
30
+ </div>
31
+ )
32
+ }
33
+
34
+ const CollapsibleMain = ({
35
+ children,
36
+ className,
37
+ padding = 'md',
38
+ ...props
39
+ }: CollapsibleMainProps) => {
40
+ const context = useContext(CollapsibleContext)
41
+ const mainCSS = buildCss('pb_collapsible_main_kit')
42
+ const mainSpacing = globalProps(props, { padding })
43
+
44
+ return (
45
+ <div className={classnames(mainCSS, className, mainSpacing)}>
46
+ <div onClick={() => context.collapse()}>
47
+ <Flex
48
+ spacing="between"
49
+ vertical="center"
50
+ >
51
+ <FlexItem>{children}</FlexItem>
52
+ <FlexItem><Icon collapsed={context.collapsed} /></FlexItem>
53
+ </Flex>
54
+ </div>
55
+ </div>
56
+ )
57
+ }
58
+
59
+ export default CollapsibleMain
@@ -0,0 +1,7 @@
1
+ <%= content_tag(:div,
2
+ aria: object.aria,
3
+ class: object.classname,
4
+ data: object.data,
5
+ id: object.id) do %>
6
+ <%= content.presence %>
7
+ <% end %>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module PbCollapsible
5
+ class Collapsible < Playbook::KitBase
6
+ def classname
7
+ generate_classname("pb_collapsible_kit")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+
4
+ import Collapsible from './_collapsible'
5
+
6
+ beforeEach(() => {
7
+ // Silences error logs within the test suite.
8
+ jest.spyOn(console, 'error')
9
+ // eslint-disable-next-line
10
+ console.error.mockImplementation(() => {})
11
+ })
12
+
13
+ afterEach(() => {
14
+ // eslint-disable-next-line
15
+ console.error.mockRestore()
16
+ })
17
+
18
+ const testId = 'collapsible1',
19
+ kitClass = 'pb_collapsible'
20
+
21
+ test('throws error if incorrect # of children', () => {
22
+ expect(() => {
23
+ render(
24
+ <Collapsible />
25
+ )
26
+ }).toThrow()
27
+ })
28
+
29
+ test('returns namespaced additional_class class name', () => {
30
+ render(
31
+ <Collapsible
32
+ className="additional_class"
33
+ data={{ testid: testId }}
34
+ >
35
+ <Collapsible.Main>
36
+ <div>{'Main Section'}</div>
37
+ </Collapsible.Main>
38
+ <Collapsible.Content>
39
+ <div>
40
+ {
41
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In vel erat sed purus hendrerit viverra. Duis et vestibulum metus. Sed consequat ut ante non vehicula. Etiam nunc massa, pharetra vel quam id, posuere rhoncus quam. Quisque imperdiet arcu enim, nec aliquet justo auctor eget. Curabitur in metus nec nunc rhoncus faucibus vitae ac elit. Nulla facilisi. Vestibulum quis pretium nulla. Nulla ut accumsan velit. Duis varius urna sed sem tempor, sit amet fermentum nibh auctor. Praesent lorem arcu, egestas non ante quis, placerat pellentesque lectus.Vestibulum lacinia ipsum quis venenatis tristique. Vivamus suscipit, libero eu fringilla egestas, orci urna commodo arcu, vel gravida turpis ipsum molestie nibh. Donec cursus eu ante sagittis ultrices. Phasellus id sagittis risus. Mauris dapibus neque faucibus, tempor ligula vel, cursus ante. Donec faucibus gravida porta. Nullam egestas est quis aliquam feugiat. Sed eget metus diam. Cras eget placerat libero.'
42
+ }
43
+ </div>
44
+ </Collapsible.Content>
45
+ </Collapsible>
46
+ )
47
+
48
+ const kit = screen.getByTestId(testId)
49
+ expect(kit).toHaveClass(`${kitClass} additional_class`)
50
+ })