playbook_ui 14.16.0 → 14.17.0.pre.alpha.PBNTR766tablenestedcollapsiblerowsborderdoubling7192

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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Utilities/types.ts +1 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +104 -2
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +168 -85
  5. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
  6. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +10 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +20 -7
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.jsx +90 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.md +3 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination.jsx +0 -1
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows.html.erb +39 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows.html.erb +33 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows_rails.md +1 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.md +6 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +4 -1
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  17. data/app/pb_kits/playbook/pb_advanced_table/index.js +1 -1
  18. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +4 -2
  19. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +19 -9
  20. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +38 -1
  21. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +49 -37
  22. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +39 -0
  23. data/app/pb_kits/playbook/pb_button/_button.scss +5 -5
  24. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +14 -7
  25. data/app/pb_kits/playbook/pb_contact/contact.test.js +7 -7
  26. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +34 -34
  27. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -2
  28. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +16 -0
  29. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +0 -11
  30. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.jsx +0 -7
  31. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_inline_styles.scss +28 -24
  32. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +2 -2
  33. data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.test.js +1 -1
  34. data/app/pb_kits/playbook/pb_draggable/_draggable.scss +43 -20
  35. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +58 -17
  36. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.jsx +102 -105
  37. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.md +3 -3
  38. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.jsx +50 -48
  39. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.md +1 -1
  40. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line.jsx +110 -0
  41. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line.md +5 -0
  42. data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_table_react.jsx → _draggable_with_table.jsx} +1 -1
  43. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.md +3 -1
  44. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +9 -6
  45. data/app/pb_kits/playbook/pb_draggable/docs/index.js +4 -1
  46. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +71 -3
  47. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +4 -3
  48. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +6 -6
  49. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +6 -6
  50. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +6 -6
  51. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +8 -8
  52. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +3 -3
  53. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +3 -4
  54. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +2 -3
  55. data/app/pb_kits/playbook/pb_form/pb_form_validation.js +1 -1
  56. data/app/pb_kits/playbook/pb_form_group/_form_group.scss +22 -0
  57. data/app/pb_kits/playbook/pb_icon/icon.test.js +9 -9
  58. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +1 -1
  59. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +1 -1
  60. data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +1 -1
  61. data/app/pb_kits/playbook/pb_label_value/label_value.test.js +1 -1
  62. data/app/pb_kits/playbook/pb_layout/_layout.scss +58 -0
  63. data/app/pb_kits/playbook/pb_layout/_layout.tsx +20 -7
  64. data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.jsx +190 -0
  65. data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.md +5 -0
  66. data/app/pb_kits/playbook/pb_layout/docs/example.yml +1 -0
  67. data/app/pb_kits/playbook/pb_layout/docs/index.js +1 -0
  68. data/app/pb_kits/playbook/pb_layout/layout.test.js +4 -0
  69. data/app/pb_kits/playbook/pb_layout/subcomponents/_game.tsx +90 -0
  70. data/app/pb_kits/playbook/pb_layout/subcomponents/_round.tsx +57 -0
  71. data/app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js +1 -1
  72. data/app/pb_kits/playbook/pb_link/link.test.jsx +2 -2
  73. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +2 -1
  74. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +5 -3
  75. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +29 -11
  76. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.html.erb +1 -1
  77. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +4 -4
  78. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +2 -0
  79. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_vertical.md +1 -0
  80. data/app/pb_kits/playbook/pb_stat_change/stat_change.test.js +8 -4
  81. data/app/pb_kits/playbook/pb_table/_table.tsx +4 -0
  82. data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless.jsx +50 -0
  83. data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless_react.md +1 -0
  84. data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating.jsx +59 -0
  85. data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating_react.md +1 -0
  86. data/app/pb_kits/playbook/pb_table/docs/example.yml +2 -0
  87. data/app/pb_kits/playbook/pb_table/docs/index.js +2 -0
  88. data/app/pb_kits/playbook/pb_table/styles/_collapsible.scss +24 -0
  89. data/app/pb_kits/playbook/pb_table/styles/_headers.scss +76 -0
  90. data/app/pb_kits/playbook/pb_table/styles/_striped.scss +3 -3
  91. data/app/pb_kits/playbook/pb_table/subcomponents/_table_head.tsx +11 -1
  92. data/app/pb_kits/playbook/pb_table/subcomponents/_table_header.tsx +11 -1
  93. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +5 -0
  94. data/app/pb_kits/playbook/pb_table/table.test.js +17 -0
  95. data/app/pb_kits/playbook/pb_tooltip/index.js +183 -56
  96. data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +2 -5
  97. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +4 -4
  98. data/app/pb_kits/playbook/pb_typeahead/index.ts +2 -2
  99. data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +2 -5
  100. data/app/pb_kits/playbook/pb_user/user.html.erb +1 -6
  101. data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +1 -6
  102. data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
  103. data/app/pb_kits/playbook/utilities/object.test.js +149 -1
  104. data/app/pb_kits/playbook/utilities/object.ts +124 -42
  105. data/dist/chunks/_typeahead-HqfDnjRe.js +22 -0
  106. data/dist/chunks/_weekday_stacked-DVQITtQ9.js +45 -0
  107. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  108. data/dist/chunks/lib-BGzBzFZX.js +29 -0
  109. data/dist/chunks/{pb_form_validation-DMajaRt3.js → pb_form_validation-BvNy9Bd6.js} +1 -1
  110. data/dist/chunks/vendor.js +1 -1
  111. data/dist/playbook-doc.js +1 -1
  112. data/dist/playbook-rails-react-bindings.js +1 -1
  113. data/dist/playbook-rails.js +1 -1
  114. data/dist/playbook.css +1 -1
  115. data/lib/playbook/kit_base.rb +4 -4
  116. data/lib/playbook/version.rb +2 -2
  117. metadata +38 -22
  118. data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +0 -282
  119. data/dist/chunks/_typeahead-BuTZG1Jn.js +0 -22
  120. data/dist/chunks/_weekday_stacked-oT22q75-.js +0 -45
  121. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
  122. data/dist/chunks/lib-Co5y3V4K.js +0 -29
  123. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows.md → _advanced_table_selectable_rows_no_subrows_react.md} +0 -0
  124. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows.md → _advanced_table_selectable_rows_react.md} +0 -0
  125. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_default_rails.html.erb → _draggable_default.html.erb} +0 -0
  126. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_default.md → _draggable_default_react.md} +0 -0
  127. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_multiple_containers_rails.html.erb → _draggable_multiple_containers.html.erb} +0 -0
  128. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_multiple_containers.md → _draggable_multiple_containers_react.md} +0 -0
  129. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_cards_rails.html.erb → _draggable_with_cards.html.erb} +0 -0
  130. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_cards.md → _draggable_with_cards_react.md} +0 -0
  131. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_list_rails.html.erb → _draggable_with_list.html.erb} +0 -0
  132. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_list.md → _draggable_with_list_react.md} +0 -0
  133. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_selectable_list_rails.html.erb → _draggable_with_selectable_list.html.erb} +0 -0
  134. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_selectable_list.md → _draggable_with_selectable_list_react.md} +0 -0
  135. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_with_table.md → _draggable_with_table_rails.md} +0 -0
@@ -0,0 +1,190 @@
1
+ import React from 'react'
2
+
3
+ import Layout from '../../pb_layout/_layout'
4
+ import Flex from '../../pb_flex/_flex'
5
+ import Body from '../../pb_body/_body'
6
+ import Caption from '../../pb_caption/_caption'
7
+ import SectionSeparator from '../../pb_section_separator/_section_separator'
8
+
9
+ const LayoutBracket = () => {
10
+ return (
11
+ <div>
12
+ <Layout
13
+ layout="bracket"
14
+ >
15
+ <Layout.RoundLabel>
16
+ <Caption>Wild Card</Caption>
17
+ <SectionSeparator marginY="sm"/>
18
+ </Layout.RoundLabel>
19
+ <Layout.Round marginBottom={{ xs: "md", sm: "md" }}>
20
+ <Layout.Game>
21
+ <Flex justify="between">
22
+ <Body>Packers</Body>
23
+ <Body>10</Body>
24
+ </Flex>
25
+ <Flex justify="between">
26
+ <Body><strong>Eagles</strong></Body>
27
+ <Body>22</Body>
28
+ </Flex>
29
+ </Layout.Game>
30
+ <Layout.Game>
31
+ <Flex justify="between">
32
+ <Body>Vikings</Body>
33
+ <Body>9</Body>
34
+ </Flex>
35
+ <Flex justify="between">
36
+ <Body><strong>Rams</strong></Body>
37
+ <Body>27</Body>
38
+ </Flex>
39
+ </Layout.Game>
40
+ <Layout.Game>
41
+ <Flex justify="between">
42
+ <Body><strong>Lions</strong></Body>
43
+ </Flex>
44
+ <Flex justify="between">
45
+ <Body>BYE</Body>
46
+ </Flex>
47
+ </Layout.Game>
48
+ <Layout.Game>
49
+ <Flex justify="between">
50
+ <Body><strong>Commanders</strong></Body>
51
+ <Body>23</Body>
52
+ </Flex>
53
+ <Flex justify="between">
54
+ <Body>Buccaneers</Body>
55
+ <Body>20</Body>
56
+ </Flex>
57
+ </Layout.Game>
58
+ <Layout.Game>
59
+ <Flex justify="between">
60
+ <Body><strong>Chiefs</strong></Body>
61
+ </Flex>
62
+ <Flex justify="between">
63
+ <Body>BYE</Body>
64
+ </Flex>
65
+ </Layout.Game>
66
+ <Layout.Game>
67
+ <Flex justify="between">
68
+ <Body>Chargers</Body>
69
+ <Body>12</Body>
70
+ </Flex>
71
+ <Flex justify="between">
72
+ <Body><strong>Texans</strong></Body>
73
+ <Body>32</Body>
74
+ </Flex>
75
+ </Layout.Game>
76
+ <Layout.Game>
77
+ <Flex justify="between">
78
+ <Body>Broncos</Body>
79
+ <Body>7</Body>
80
+ </Flex>
81
+ <Flex justify="between">
82
+ <Body><strong>Bills</strong></Body>
83
+ <Body>31</Body>
84
+ </Flex>
85
+ </Layout.Game>
86
+ <Layout.Game>
87
+ <Flex justify="between">
88
+ <Body>Steelers</Body>
89
+ <Body>14</Body>
90
+ </Flex>
91
+ <Flex justify="between">
92
+ <Body><strong>Ravens</strong></Body>
93
+ <Body>28</Body>
94
+ </Flex>
95
+ </Layout.Game>
96
+ </Layout.Round>
97
+ <Layout.RoundLabel>
98
+ <Caption>Divisional</Caption>
99
+ <SectionSeparator marginY="sm"/>
100
+ </Layout.RoundLabel>
101
+ <Layout.Round marginBottom={{ xs: "md", sm: "md" }}>
102
+ <Layout.Game>
103
+ <Flex justify="between">
104
+ <Body>Rams</Body>
105
+ <Body>22</Body>
106
+ </Flex>
107
+ <Flex justify="between">
108
+ <Body><strong>Eagles</strong></Body>
109
+ <Body>28</Body>
110
+ </Flex>
111
+ </Layout.Game>
112
+ <Layout.Game>
113
+ <Flex justify="between">
114
+ <Body><strong>Commanders</strong></Body>
115
+ <Body>45</Body>
116
+ </Flex>
117
+ <Flex justify="between">
118
+ <Body>Lions</Body>
119
+ <Body>31</Body>
120
+ </Flex>
121
+ </Layout.Game>
122
+ <Layout.Game>
123
+ <Flex justify="between">
124
+ <Body>Texans</Body>
125
+ <Body>14</Body>
126
+ </Flex>
127
+ <Flex justify="between">
128
+ <Body><strong>Chiefs</strong></Body>
129
+ <Body>23</Body>
130
+ </Flex>
131
+ </Layout.Game>
132
+ <Layout.Game>
133
+ <Flex justify="between">
134
+ <Body>Ravens</Body>
135
+ <Body>25</Body>
136
+ </Flex>
137
+ <Flex justify="between">
138
+ <Body><strong>Bills</strong></Body>
139
+ <Body>27</Body>
140
+ </Flex>
141
+ </Layout.Game>
142
+ </Layout.Round>
143
+ <Layout.RoundLabel>
144
+ <Caption>Conference</Caption>
145
+ <SectionSeparator marginY="sm"/>
146
+ </Layout.RoundLabel>
147
+ <Layout.Round marginBottom={{ xs: "md", sm: "md" }}>
148
+ <Layout.Game>
149
+ <Flex justify="between">
150
+ <Body>Commanders</Body>
151
+ <Body>23</Body>
152
+ </Flex>
153
+ <Flex justify="between">
154
+ <Body><strong>Eagles</strong></Body>
155
+ <Body>55</Body>
156
+ </Flex>
157
+ </Layout.Game>
158
+ <Layout.Game>
159
+ <Flex justify="between">
160
+ <Body>Bills</Body>
161
+ <Body>29</Body>
162
+ </Flex>
163
+ <Flex justify="between">
164
+ <Body><strong>Chiefs</strong></Body>
165
+ <Body>32</Body>
166
+ </Flex>
167
+ </Layout.Game>
168
+ </Layout.Round>
169
+ <Layout.RoundLabel>
170
+ <Caption>Super Bowl</Caption>
171
+ <SectionSeparator marginY="sm"/>
172
+ </Layout.RoundLabel>
173
+ <Layout.Round>
174
+ <Layout.Game>
175
+ <Flex justify="between">
176
+ <Body>Chiefs</Body>
177
+ <Body>22</Body>
178
+ </Flex>
179
+ <Flex justify="between">
180
+ <Body><strong>Eagles</strong></Body>
181
+ <Body>40</Body>
182
+ </Flex>
183
+ </Layout.Game>
184
+ </Layout.Round>
185
+ </Layout>
186
+ </div>
187
+ )
188
+ }
189
+
190
+ export default LayoutBracket
@@ -0,0 +1,5 @@
1
+ Use `<Layout.RoundLabel>`, `<Layout.Round>`, and `<Layout.Game>` to make a bracket layout.
2
+
3
+ On mobile devices, `<Layout.RoundLabel>` will display (on desktop these components are hidden) and the bracket will be in one column.
4
+
5
+ Ensure that each `<Layout.Game>` maintains a consistent height for the bracket lines to lay out properly.
@@ -18,4 +18,5 @@ examples:
18
18
  - layout_kanban: Kanban Layout
19
19
  - layout_content: Content Layout
20
20
  - layout_masonry: Masonry Layout
21
+ - layout_bracket: Bracket Layout
21
22
 
@@ -7,4 +7,5 @@ export { default as LayoutKanbanResponsive } from './_layout_kanban_responsive.j
7
7
  export { default as LayoutCollectionDetail } from './_layout_collection_detail.jsx'
8
8
  export { default as LayoutContent } from './_layout_content.jsx'
9
9
  export { default as LayoutMasonry } from './_layout_masonry.jsx'
10
+ export { default as LayoutBracket } from './_layout_bracket.jsx'
10
11
 
@@ -82,6 +82,10 @@ test("render all layout variants", () => {
82
82
  layout: "masonry",
83
83
  expected: "pb_layout_kit_masonry_size_md_left_light",
84
84
  },
85
+ {
86
+ layout: "bracket",
87
+ expected: "pb_layout_kit_bracket",
88
+ },
85
89
  ]
86
90
 
87
91
  testValues.forEach(({ layout, expected }) => {
@@ -0,0 +1,90 @@
1
+ import React from 'react'
2
+ import classnames from 'classnames'
3
+
4
+ import { GlobalProps, globalProps, globalInlineProps } from '../../utilities/globalProps'
5
+
6
+ import Card from '../../pb_card/_card'
7
+ import SectionSeparator from '../../pb_section_separator/_section_separator'
8
+
9
+ type LayoutGameProps = {
10
+ children: React.ReactNode[] | React.ReactNode,
11
+ className?: string,
12
+ numberOfRounds: number,
13
+ numberOfGames: number,
14
+ isOdd: boolean,
15
+ } & GlobalProps
16
+
17
+ // Game component (modeled after Item)
18
+ const Game = (props: LayoutGameProps) => {
19
+ const { children, className, numberOfRounds, numberOfGames, isOdd } = props
20
+ const dynamicInlineProps = globalInlineProps(props)
21
+
22
+ const numberOfChildren = Array.isArray(children) ? children.length : 0
23
+
24
+ const isMultiple = Array.isArray(children)
25
+
26
+ let ratio = 0
27
+ let exponent
28
+ if (numberOfGames > 1) {
29
+ exponent = (numberOfRounds) - Math.log2(numberOfGames) - 1
30
+ ratio = 2 ** exponent
31
+ }
32
+
33
+ if (numberOfChildren === 2) {
34
+ const [firstChild, secondChild] = React.Children.toArray(children)
35
+
36
+ if (React.isValidElement(firstChild) && React.isValidElement(secondChild)) {
37
+ return (
38
+ <div
39
+ className={classnames('layout_game', globalProps(props), className)}
40
+ style={dynamicInlineProps}
41
+ >
42
+ <Card
43
+ marginY="xs"
44
+ padding="none"
45
+ shadow="deep"
46
+ >
47
+ <Card.Body padding="xs">{firstChild}</Card.Body>
48
+ <SectionSeparator />
49
+ <Card.Body padding="xs">{secondChild}</Card.Body>
50
+ </Card>
51
+ {isOdd && numberOfGames > 1 &&
52
+ <div
53
+ className="half_box"
54
+ style={{ height: `calc(${ratio} * 100% + 4px)` }}
55
+ />
56
+ }
57
+ </div>
58
+ )
59
+ }
60
+ }
61
+
62
+ return (
63
+ <div
64
+ className={classnames('layout_game', globalProps(props), className)}
65
+ style={dynamicInlineProps}
66
+ >
67
+ {((!isMultiple && children) || numberOfChildren >= 1 )? (
68
+ children
69
+ ) : (
70
+ <Card
71
+ marginY="xs"
72
+ padding="none"
73
+ shadow="deep"
74
+ >
75
+ <Card.Body padding="xs">To be determined...</Card.Body>
76
+ <SectionSeparator />
77
+ <Card.Body padding="xs">To be determined...</Card.Body>
78
+ </Card>
79
+ )}
80
+ {isOdd && numberOfGames > 1 &&
81
+ <div
82
+ className="half_box"
83
+ style={{ height: `calc(${ratio} * 100% + 4px)` }}
84
+ />
85
+ }
86
+ </div>
87
+ )
88
+ }
89
+
90
+ export default Game
@@ -0,0 +1,57 @@
1
+ import React from 'react'
2
+ import classnames from 'classnames'
3
+
4
+ import { GlobalProps, globalProps, globalInlineProps } from '../../utilities/globalProps'
5
+
6
+ type LayoutRoundLabelProps = {
7
+ children: React.ReactNode[] | React.ReactNode,
8
+ className?: string,
9
+ } & GlobalProps
10
+
11
+ export const RoundLabel = (props: LayoutRoundLabelProps) => {
12
+ const { children, className } = props
13
+ const dynamicInlineProps = globalInlineProps(props)
14
+ return (
15
+ <div
16
+ className={classnames('layout_round_label', className)}
17
+ style={dynamicInlineProps}
18
+ >
19
+ {children}
20
+ </div>
21
+ )
22
+ }
23
+
24
+ type LayoutRoundProps = {
25
+ children: React.ReactNode[] | React.ReactNode,
26
+ className?: string,
27
+ numberOfRounds: number,
28
+ } & GlobalProps
29
+
30
+ export const Round = (props: LayoutRoundProps) => {
31
+ const { children, className, numberOfRounds } = props
32
+ const dynamicInlineProps = globalInlineProps(props)
33
+ const numberOfChildren = Array.isArray(children) ? children.length : 0
34
+
35
+ const childrenWithProps = Array.isArray(children) ? children.map((child, index) =>
36
+ React.isValidElement(child) ? React.cloneElement(child, { numberOfRounds, numberOfGames: numberOfChildren, isOdd: index % 2 === 0, key: `child_${index}` }) : child
37
+ ) : children
38
+
39
+ const rightConnectors = Array.from({ length: numberOfChildren / 2 }, (_, index) => (
40
+ <div
41
+ className="right_connector"
42
+ key={`right_connector_${index}`}
43
+ />
44
+ ))
45
+
46
+ return (
47
+ <>
48
+ <div
49
+ className={classnames('layout_round', globalProps(props), className)}
50
+ style={dynamicInlineProps}
51
+ >
52
+ {childrenWithProps}
53
+ </div>
54
+ <div className="connector_container">{rightConnectors}</div>
55
+ </>
56
+ )
57
+ }
@@ -1,4 +1,4 @@
1
- import { debounce } from 'lodash'
1
+ import { debounce } from "../../utilities/object"
2
2
  import { useCallback, useMemo, useState } from 'react'
3
3
 
4
4
  export default function useVisibility(initialState = false) {
@@ -73,7 +73,7 @@ test('adds icon', () => {
73
73
 
74
74
  const kit = screen.getByTestId('icon-test')
75
75
 
76
- const icon = kit.querySelector('.pb_icon_kit')
76
+ const icon = kit.querySelector('.pb_custom_icon')
77
77
  expect(icon).toBeInTheDocument();
78
78
  })
79
79
 
@@ -87,7 +87,7 @@ test('adds icon right', () => {
87
87
 
88
88
  const kit = screen.getByTestId('icon-right-test')
89
89
 
90
- const icon = kit.querySelector('.pb_icon_kit')
90
+ const icon = kit.querySelector('.pb_custom_icon')
91
91
  expect(icon).toBeInTheDocument();
92
92
  })
93
93
 
@@ -7,11 +7,12 @@ import {
7
7
  buildDataProps,
8
8
  buildHtmlProps,
9
9
  } from "../utilities/props";
10
+ import { cloneDeep } from "../utilities/object";
11
+
10
12
  import Icon from "../pb_icon/_icon";
11
13
  import FormPill from "../pb_form_pill/_form_pill";
12
14
  import Body from "../pb_body/_body";
13
15
  import Caption from "../pb_caption/_caption";
14
- import { cloneDeep } from "lodash";
15
16
  import MultiLevelSelectOptions from "./multi_level_select_options";
16
17
  import MultiLevelSelectContext from "./context";
17
18
 
@@ -95,11 +95,13 @@ test('should not have a left border', () => {
95
95
  test('should have a right icon', () => {
96
96
  render(<NavDefault iconRight="angle-down" />)
97
97
  const kit = screen.getByTestId(itemTestId)
98
- expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_right fa-fw fa-angle-down" />')
98
+ const icon = kit.querySelector(".pb_custom_icon.pb_nav_list_item_icon_right")
99
+ expect(icon).toBeInTheDocument()
99
100
  })
100
101
 
101
102
  test('should have a left icon', () => {
102
- render(<NavDefault iconLeft="users-class" />)
103
+ render(<NavDefault iconLeft="angle-up" />)
103
104
  const kit = screen.getByTestId(itemTestId)
104
- expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_left fa-fw fa-users-class" />')
105
+ const icon = kit.querySelector(".pb_custom_icon.pb_nav_list_item_icon_left")
106
+ expect(icon).toBeInTheDocument()
105
107
  })
@@ -32,11 +32,12 @@ type RichTextEditorProps = {
32
32
  advancedEditor?: any,
33
33
  advancedEditorToolbar?: boolean,
34
34
  toolbarBottom?: boolean,
35
- children?: React.ReactNode | React.ReactNode[]
35
+ children?: React.ReactNode | React.ReactNode[],
36
36
  className?: string,
37
37
  data?: { [key: string]: string },
38
38
  focus?: boolean,
39
- htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
39
+ htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
40
+ inputOptions?: { [key: string]: string | number | boolean | (() => void) },
40
41
  id?: string,
41
42
  inline?: boolean,
42
43
  extensions?: { [key: string]: string }[],
@@ -61,6 +62,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
61
62
  data = {},
62
63
  focus = false,
63
64
  htmlOptions = {},
65
+ inputOptions = {},
64
66
  inline = false,
65
67
  extensions,
66
68
  name,
@@ -70,7 +72,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
70
72
  sticky = false,
71
73
  template = '',
72
74
  value = '',
73
- maxWidth="md"
75
+ maxWidth = "md"
74
76
  } = props
75
77
 
76
78
  const ariaProps = buildAriaProps(aria),
@@ -79,12 +81,28 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
79
81
 
80
82
  const htmlProps = buildHtmlProps(htmlOptions)
81
83
 
82
- const handleOnEditorReady = (editorInstance: Editor) => setEditor(editorInstance),
83
- element = editor?.element
84
+ const handleOnEditorReady = (editorInstance: Editor) => {
85
+ setEditor(editorInstance)
86
+ setTimeout(() => {
87
+ const oldId = editorInstance.element.getAttribute('input')
88
+ if (oldId) {
89
+ const hiddenInput = document.getElementById(oldId)
90
+ if (hiddenInput) {
91
+ const newId = (inputOptions.id as string) || oldId
92
+ hiddenInput.id = newId
93
+ editorInstance.element.setAttribute('input', newId)
94
+
95
+ if (inputOptions.name) {
96
+ hiddenInput.setAttribute('name', inputOptions.name as string)
97
+ }
98
+ }
99
+ }
100
+ })
101
+ }
84
102
 
85
103
  // DOM manipulation must wait for editor to be ready
86
- if (editor) {
87
- const toolbarElement = element.parentElement.querySelector('trix-toolbar') as HTMLElement,
104
+ if (editor && editor.element) {
105
+ const toolbarElement = editor.element.parentElement.querySelector('trix-toolbar') as HTMLElement,
88
106
  blockCodeButton = toolbarElement.querySelector('[data-trix-attribute=code]') as HTMLElement
89
107
 
90
108
  // replace default trix "block code" button with "inline code" button
@@ -118,8 +136,8 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
118
136
  }, [editor, template])
119
137
 
120
138
  useEffect(() => {
121
- if (!element) return
122
- element.addEventListener('click', ({ target }: Event) => {
139
+ if (!editor?.element) return
140
+ editor.element.addEventListener('click', ({ target }: Event) => {
123
141
  const trixEditorContainer = (target as Element).closest('.pb_rich_text_editor_kit')
124
142
  if (!trixEditorContainer) return
125
143
 
@@ -128,7 +146,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
128
146
 
129
147
  if (anchorElement.hasAttribute('href')) window.open(anchorElement.href)
130
148
  })
131
- }, [element])
149
+ }, [editor])
132
150
 
133
151
  const richTextEditorClass = 'pb_rich_text_editor_kit',
134
152
  simpleClass = simple ? 'simple' : '',
@@ -137,7 +155,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
137
155
  inlineClass = inline ? 'inline' : '',
138
156
  toolbarBottomClass = toolbarBottom ? 'toolbar-bottom' : ''
139
157
 
140
- let css = classnames(globalProps(props, {maxWidth}), className)
158
+ let css = classnames(globalProps(props, { maxWidth }), className)
141
159
  css = classnames(
142
160
  richTextEditorClass,
143
161
  simpleClass,
@@ -1 +1 @@
1
- <%= pb_rails("rich_text_editor", props: {id: "default", value: "Add your text here. You can format your text, add links, quotes, and bullets."}) %>
1
+ <%= pb_rails("rich_text_editor", props: {input_options: { id: 'hidden_input_id', name: "hidden_input_name" }, value: "Add your text here. You can format your text, add links, quotes, and bullets."}) %>
@@ -1,5 +1,5 @@
1
1
  <%= react_component('RichTextEditor',
2
- object.rich_text_options,
3
- aria: object.aria,
4
- data: object.data
5
- ) %>
2
+ object.rich_text_options,
3
+ aria: object.aria,
4
+ data: object.data
5
+ ) %>
@@ -20,6 +20,7 @@ module Playbook
20
20
  prop :value
21
21
  prop :template
22
22
  prop :placeholder
23
+ prop :input_options
23
24
 
24
25
  def classname
25
26
  generate_classname("pb_rich_text_editor_kit", simple_class, focus_class, sticky_class, separator: " ")
@@ -49,6 +50,7 @@ module Playbook
49
50
  value: value,
50
51
  template: template,
51
52
  placeholder: placeholder,
53
+ inputOptions: input_options,
52
54
  }
53
55
  end
54
56
  end
@@ -0,0 +1 @@
1
+ To guarantee the vertical section separator displays properly, please add the `vertical: "stretch"`/`vertical="stretch"` property to the parent container (which is commonly a Flex container). This will stretch the container’s child elements vertically and ensure the section separator appears as expected.
@@ -19,23 +19,27 @@ test('it renders preset icon', () => {
19
19
  render(
20
20
  <StatChange
21
21
  change="increase"
22
+ id="preset-icon"
22
23
  value="28.4"
23
24
  />
24
25
  )
25
26
 
26
- const kit = screen.getByLabelText('arrow-up icon')
27
- expect(kit).toBeTruthy
27
+ const kit = document.querySelector('#preset-icon')
28
+ const icon = kit.querySelector(".pb_custom_icon")
29
+ expect(icon).toBeInTheDocument()
28
30
  })
29
31
 
30
32
  test('it renders custom icon', () => {
31
33
  render(
32
34
  <StatChange
33
35
  icon="chart-line-down"
36
+ id="custom-icon"
34
37
  value={6.1}
35
38
  />
36
39
 
37
40
  )
38
41
 
39
- const kit = screen.getByLabelText('chart-line-down icon')
40
- expect(kit).toBeTruthy
42
+ const kit = document.querySelector('#custom-icon')
43
+ const icon = kit.querySelector(".pb_custom_icon")
44
+ expect(icon).toBeInTheDocument()
41
45
  })
@@ -21,6 +21,7 @@ type TableProps = {
21
21
  data?: { [key: string]: string },
22
22
  dataTable: boolean,
23
23
  disableHover?: boolean,
24
+ headerStyle?: "default" | "borderless" | "floating"
24
25
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
25
26
  id?: string,
26
27
  outerPadding?: "none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl",
@@ -46,6 +47,7 @@ const Table = (props: TableProps): React.ReactElement => {
46
47
  data = {},
47
48
  dataTable = false,
48
49
  disableHover = false,
50
+ headerStyle = "default",
49
51
  htmlOptions = {},
50
52
  id,
51
53
  outerPadding = '',
@@ -85,6 +87,8 @@ const Table = (props: TableProps): React.ReactElement => {
85
87
  'sticky-left-column': stickyLeftColumn,
86
88
  'sticky-right-column': stickyRightColumn,
87
89
  'striped': striped,
90
+ 'header-borderless': headerStyle === 'borderless',
91
+ 'header-floating': headerStyle === 'floating',
88
92
  [outerPaddingCss]: outerPadding !== '',
89
93
  },
90
94
  globalProps(props),
@@ -0,0 +1,50 @@
1
+ import React from 'react'
2
+
3
+ import Table from '../../pb_table/_table'
4
+
5
+ const TableWithHeaderStyleBorderless = (props) => {
6
+ return (
7
+ <>
8
+ <Table
9
+ headerStyle="borderless"
10
+ size="sm"
11
+ {...props}
12
+ >
13
+ <thead>
14
+ <tr>
15
+ <th>{'Column 1'}</th>
16
+ <th>{'Column 2'}</th>
17
+ <th>{'Column 3'}</th>
18
+ <th>{'Column 4'}</th>
19
+ <th>{'Column 5'}</th>
20
+ </tr>
21
+ </thead>
22
+ <tbody>
23
+ <tr>
24
+ <td>{'Value 1'}</td>
25
+ <td>{'Value 2'}</td>
26
+ <td>{'Value 3'}</td>
27
+ <td>{'Value 4'}</td>
28
+ <td>{'Value 5'}</td>
29
+ </tr>
30
+ <tr>
31
+ <td>{'Value 1'}</td>
32
+ <td>{'Value 2'}</td>
33
+ <td>{'Value 3'}</td>
34
+ <td>{'Value 4'}</td>
35
+ <td>{'Value 5'}</td>
36
+ </tr>
37
+ <tr>
38
+ <td>{'Value 1'}</td>
39
+ <td>{'Value 2'}</td>
40
+ <td>{'Value 3'}</td>
41
+ <td>{'Value 4'}</td>
42
+ <td>{'Value 5'}</td>
43
+ </tr>
44
+ </tbody>
45
+ </Table>
46
+ </>
47
+ )
48
+ }
49
+
50
+ export default TableWithHeaderStyleBorderless
@@ -0,0 +1 @@
1
+ Customize your header by removing the header borders with the `headerStyle="borderless"` prop.