playbook_ui 14.17.0.pre.alpha.play1499backgroundkitoverlay7110 → 14.17.0.pre.rc.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 (83) 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 +0 -70
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +2 -83
  5. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +7 -20
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -2
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -2
  8. data/app/pb_kits/playbook/pb_background/_background.scss +0 -26
  9. data/app/pb_kits/playbook/pb_background/_background.tsx +3 -6
  10. data/app/pb_kits/playbook/pb_background/background.test.js +0 -5
  11. data/app/pb_kits/playbook/pb_background/docs/example.yml +0 -1
  12. data/app/pb_kits/playbook/pb_background/docs/index.js +0 -1
  13. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +7 -14
  14. data/app/pb_kits/playbook/pb_contact/contact.test.js +7 -7
  15. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +34 -34
  16. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -2
  17. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +0 -16
  18. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +11 -0
  19. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.jsx +7 -0
  20. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_inline_styles.scss +24 -28
  21. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +2 -2
  22. data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.test.js +1 -1
  23. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +17 -58
  24. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +3 -3
  25. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +6 -6
  26. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +6 -6
  27. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +6 -6
  28. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +8 -8
  29. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +3 -3
  30. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +4 -3
  31. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +3 -2
  32. data/app/pb_kits/playbook/pb_form/pb_form_validation.js +1 -1
  33. data/app/pb_kits/playbook/pb_form_group/_form_group.scss +0 -22
  34. data/app/pb_kits/playbook/pb_icon/icon.test.js +9 -9
  35. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +1 -1
  36. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +1 -1
  37. data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +1 -1
  38. data/app/pb_kits/playbook/pb_label_value/label_value.test.js +1 -1
  39. data/app/pb_kits/playbook/pb_layout/_layout.scss +0 -58
  40. data/app/pb_kits/playbook/pb_layout/_layout.tsx +7 -20
  41. data/app/pb_kits/playbook/pb_layout/docs/example.yml +0 -1
  42. data/app/pb_kits/playbook/pb_layout/docs/index.js +0 -1
  43. data/app/pb_kits/playbook/pb_layout/layout.test.js +0 -4
  44. data/app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js +1 -1
  45. data/app/pb_kits/playbook/pb_link/link.test.jsx +2 -2
  46. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +1 -2
  47. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +3 -5
  48. data/app/pb_kits/playbook/pb_stat_change/stat_change.test.js +4 -8
  49. data/app/pb_kits/playbook/pb_table/styles/_striped.scss +3 -3
  50. data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +282 -0
  51. data/app/pb_kits/playbook/pb_tooltip/index.js +56 -183
  52. data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +5 -2
  53. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +4 -4
  54. data/app/pb_kits/playbook/pb_typeahead/index.ts +2 -2
  55. data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +5 -2
  56. data/app/pb_kits/playbook/pb_user/user.html.erb +6 -1
  57. data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +6 -1
  58. data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
  59. data/app/pb_kits/playbook/utilities/object.test.js +1 -149
  60. data/app/pb_kits/playbook/utilities/object.ts +42 -124
  61. data/dist/chunks/{_typeahead-1gVtCLYL.js → _typeahead-N-EFroAX.js} +3 -3
  62. data/dist/chunks/_weekday_stacked-Db780bKR.js +45 -0
  63. data/dist/chunks/lib-Co5y3V4K.js +29 -0
  64. data/dist/chunks/{pb_form_validation-BvNy9Bd6.js → pb_form_validation-DMajaRt3.js} +1 -1
  65. data/dist/chunks/vendor.js +1 -1
  66. data/dist/playbook-doc.js +1 -1
  67. data/dist/playbook-rails-react-bindings.js +1 -1
  68. data/dist/playbook-rails.js +1 -1
  69. data/dist/playbook.css +1 -1
  70. data/lib/playbook/kit_base.rb +4 -4
  71. data/lib/playbook/version.rb +2 -2
  72. metadata +7 -15
  73. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.jsx +0 -90
  74. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.md +0 -3
  75. data/app/pb_kits/playbook/pb_background/docs/_background_overlay.jsx +0 -36
  76. data/app/pb_kits/playbook/pb_background/docs/_background_overlay.md +0 -1
  77. data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.jsx +0 -190
  78. data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.md +0 -5
  79. data/app/pb_kits/playbook/pb_layout/subcomponents/_game.tsx +0 -90
  80. data/app/pb_kits/playbook/pb_layout/subcomponents/_round.tsx +0 -57
  81. data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_vertical.md +0 -1
  82. data/dist/chunks/_weekday_stacked-Cl62R0Ef.js +0 -45
  83. data/dist/chunks/lib-BGzBzFZX.js +0 -29
@@ -16,7 +16,7 @@ describe("Icon Kit", () => {
16
16
  )
17
17
 
18
18
  const kit = screen.getByTestId(testId)
19
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa svg_fw")
19
+ expect(kit).toHaveClass("fa-user pb_icon_kit fa-fw far")
20
20
  })
21
21
 
22
22
  test("renders rotate prop", () => {[
@@ -31,7 +31,7 @@ describe("Icon Kit", () => {
31
31
  )
32
32
 
33
33
  const kit = screen.getByTestId(testId)
34
- expect(kit).toHaveClass(`pb_custom_icon svg-inline--fa rotate_${rotateProp} svg_fw`)
34
+ expect(kit).toHaveClass(`fa-user pb_icon_kit fa-fw fa-rotate-${rotateProp} far`)
35
35
 
36
36
  cleanup()
37
37
  })
@@ -48,7 +48,7 @@ describe("Icon Kit", () => {
48
48
  )
49
49
 
50
50
  const kit = screen.getByTestId(testId)
51
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa flip_horizontal svg_fw")
51
+ expect(kit).toHaveClass("fa-user pb_icon_kit fa-fw fa-flip-horizontal far")
52
52
  })
53
53
 
54
54
 
@@ -63,7 +63,7 @@ describe("Icon Kit", () => {
63
63
  )
64
64
 
65
65
  const kit = screen.getByTestId(testId)
66
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa spin svg_fw")
66
+ expect(kit).toHaveClass("fa-spinner pb_icon_kit fa-fw fa-spin far")
67
67
  })
68
68
 
69
69
  test("renders pull icon", () => {
@@ -77,7 +77,7 @@ describe("Icon Kit", () => {
77
77
  )
78
78
 
79
79
  const kit = screen.getByTestId(testId)
80
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa svg_fw pull_left")
80
+ expect(kit).toHaveClass("fa-arrow-left pb_icon_kit fa-fw fa-pull-left far")
81
81
  })
82
82
 
83
83
  test("renders pull icon", () => {
@@ -91,7 +91,7 @@ describe("Icon Kit", () => {
91
91
  )
92
92
 
93
93
  const kit = screen.getByTestId(testId)
94
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa svg_fw pull_left")
94
+ expect(kit).toHaveClass("fa-arrow-left pb_icon_kit fa-fw fa-pull-left far")
95
95
  })
96
96
 
97
97
  test("renders border around icon", () => {
@@ -105,7 +105,7 @@ describe("Icon Kit", () => {
105
105
  )
106
106
 
107
107
  const kit = screen.getByTestId(testId)
108
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa svg_border svg_fw")
108
+ expect(kit).toHaveClass("fa-user pb_icon_kit fa-border fa-fw far")
109
109
  })
110
110
 
111
111
  test("renders size prop", () => {
@@ -132,7 +132,7 @@ describe("Icon Kit", () => {
132
132
  )
133
133
 
134
134
  const kit = screen.getByTestId(testId)
135
- expect(kit).toHaveClass(`pb_custom_icon svg-inline--fa svg_${sizeProp} svg_fw`)
135
+ expect(kit).toHaveClass(`pb_icon_kit fa-user fa-fw fa-${sizeProp} far`)
136
136
 
137
137
  cleanup()
138
138
  })
@@ -149,7 +149,7 @@ describe("Icon Kit", () => {
149
149
  )
150
150
 
151
151
  const kit = screen.getByTestId(testId)
152
- expect(kit).toHaveClass("pb_custom_icon svg-inline--fa svg_fw")
152
+ expect(kit).toHaveClass("fa-user pb_icon_kit fa-fw fas")
153
153
  })
154
154
 
155
155
  test("renders with color prop", () => {
@@ -29,7 +29,7 @@ describe("IconCircle Kit", () => {
29
29
  )
30
30
 
31
31
  const kit = screen.getByTestId(testId)
32
- const icon = kit.querySelector('.pb_custom_icon')
32
+ const icon = kit.querySelector('.pb_icon_kit')
33
33
  expect(icon).toBeInTheDocument()
34
34
  })
35
35
 
@@ -33,7 +33,7 @@ describe("IconStatValue Kit", () => {
33
33
  )
34
34
 
35
35
  const kit = screen.getByTestId(testId)
36
- const icon = kit.querySelector(".pb_custom_icon")
36
+ const icon = kit.querySelector(".fa-lightbulb-on.pb_icon_kit.fa-fw")
37
37
  expect(icon).toBeInTheDocument()
38
38
  })
39
39
 
@@ -29,7 +29,7 @@ describe("IconValue Kit", () => {
29
29
  )
30
30
 
31
31
  const kit = screen.getByTestId(testId)
32
- const icon = kit.querySelector(".pb_custom_icon")
32
+ const icon = kit.querySelector(".fa-clipboard.pb_icon_kit.fa-fw")
33
33
  expect(icon).toBeInTheDocument()
34
34
  })
35
35
 
@@ -56,7 +56,7 @@ describe("LabelValue Kit", () => {
56
56
  />
57
57
  )
58
58
  const kit = screen.getByTestId(testId)
59
- const icon = kit.querySelector(".pb_custom_icon")
59
+ const icon = kit.querySelector(".fa-truck.pb_icon_kit.fa-fw")
60
60
  expect(icon).toBeInTheDocument()
61
61
  })
62
62
 
@@ -10,8 +10,6 @@ $list-header-height: $space_lg;
10
10
  $list-footer-height: $space_lg;
11
11
  $list-border-radius: $border_rad_lighter;
12
12
  $card-border-radius: $border_rad_lightest;
13
- $bracket-connector-width: 45px;
14
- $bracket-border-width: 4px;
15
13
 
16
14
 
17
15
  [class^=pb_layout_kit] {
@@ -170,62 +168,6 @@ $bracket-border-width: 4px;
170
168
  }
171
169
  }
172
170
 
173
- &[class*=_bracket]{
174
- display: flex;
175
- overflow-x: scroll;
176
-
177
- div.layout_round {
178
- display: flex;
179
- flex-direction: column;
180
- justify-content: space-around;
181
- flex-grow: 1;
182
- }
183
-
184
- .connector_container {
185
- display: flex;
186
- flex-direction: column;
187
- justify-content: space-around;
188
- }
189
- .right_connector {
190
- border-top: $bracket-border-width solid $border_light;
191
- width: $bracket-connector-width;
192
- margin-left: $bracket-connector-width;
193
- }
194
-
195
- .layout_round .layout_game {
196
- position: relative;
197
- }
198
-
199
- .half_box {
200
- content: '';
201
- position: absolute;
202
- top: calc(50% - $bracket-border-width / 2);
203
- height: calc(100% + $bracket-border-width);
204
- width: $bracket-connector-width;
205
- right: -$bracket-connector-width;
206
- border-top-right-radius: $border_radius_lg;
207
- border-bottom-right-radius: $border_radius_lg;
208
- border-top: $bracket-border-width solid $border_light;
209
- border-bottom: $bracket-border-width solid $border_light;
210
- border-right: $bracket-border-width solid $border_light;
211
- }
212
-
213
- .layout_round_label {
214
- display: none;
215
- }
216
-
217
- @media (max-width: $screen-md-max) {
218
- flex-direction: column;
219
- .layout_round_label {
220
- display: block;
221
- }
222
- .layout_round .layout_game::after,
223
- .connector_container,
224
- .half_box {
225
- display: none !important;
226
- }
227
- }
228
- }
229
171
 
230
172
  &[class*=_sidebar]{
231
173
  $layout_sizes: (
@@ -4,9 +4,6 @@ import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../uti
4
4
 
5
5
  import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
6
6
 
7
- import { Round, RoundLabel } from "./subcomponents/_round";
8
- import Game from "./subcomponents/_game";
9
-
10
7
  type LayoutPropTypes = {
11
8
  aria?: {[key: string]: string},
12
9
  children?: React.ReactChild[] | React.ReactChild,
@@ -21,7 +18,7 @@ type LayoutPropTypes = {
21
18
  size?: "xs" | "sm" | "md" | "base" | "lg" | "xl",
22
19
  variant?: "light" | "dark" | "gradient",
23
20
  transparent?: boolean,
24
- layout?: "sidebar" | "collection" | "kanban" | "content" | "masonry" | "bracket",
21
+ layout?: "sidebar" | "collection" | "kanban" | "content" | "masonry",
25
22
  } & GlobalProps
26
23
 
27
24
  type LayoutSideProps = {
@@ -143,7 +140,7 @@ const Layout = (props: LayoutPropTypes) => {
143
140
  const htmlProps = buildHtmlProps(htmlOptions)
144
141
 
145
142
  const layoutCss =
146
- (layout == 'collection' || layout == 'bracket')
143
+ layout == 'collection'
147
144
  ? `pb_layout_kit_${layout}`
148
145
  : layout == 'kanban'
149
146
  ? `pb_layout_kit_${layout}${responsiveClass}`
@@ -154,9 +151,11 @@ const Layout = (props: LayoutPropTypes) => {
154
151
  })
155
152
 
156
153
  const layoutCollapseCss =
157
- (layout == 'collection' || layout == 'kanban' || layout == 'bracket')
154
+ layout == 'collection'
158
155
  ? ''
159
- : buildCss('layout', position, 'collapse', collapse)
156
+ : layout == 'kanban'
157
+ ? ''
158
+ : buildCss('layout', position, 'collapse', collapse)
160
159
 
161
160
  const layoutChildren = React.Children.toArray(children)
162
161
 
@@ -176,15 +175,6 @@ const Layout = (props: LayoutPropTypes) => {
176
175
  (child: React.ReactElement & {type: {displayName: string}}) => child.type?.displayName !== 'Side'
177
176
  )
178
177
 
179
- const numberOfRounds = Array.isArray(nonSideChildren) ? React.Children.toArray(children).filter(
180
- (child) => {
181
- return (child as React.ReactElement).type === Layout.Round;
182
- }
183
- ).length : 0
184
- const bracketChildren = nonSideChildren.map(child =>
185
- React.isValidElement(child) ? React.cloneElement(child, { numberOfRounds }) : child
186
- )
187
-
188
178
  const filteredProps = {...props}
189
179
  delete filteredProps?.position
190
180
 
@@ -206,7 +196,7 @@ const Layout = (props: LayoutPropTypes) => {
206
196
  style={dynamicInlineProps}
207
197
  >
208
198
  {subComponentTags('Side')}
209
- {layout === 'bracket' ? bracketChildren : nonSideChildren}
199
+ {nonSideChildren}
210
200
  </div>
211
201
  )
212
202
  }
@@ -216,8 +206,5 @@ Layout.Body = Body
216
206
  Layout.Item = Item
217
207
  Layout.Header = Header
218
208
  Layout.Footer = Footer
219
- Layout.Round = Round
220
- Layout.Game = Game
221
- Layout.RoundLabel = RoundLabel
222
209
 
223
210
  export default Layout
@@ -18,5 +18,4 @@ examples:
18
18
  - layout_kanban: Kanban Layout
19
19
  - layout_content: Content Layout
20
20
  - layout_masonry: Masonry Layout
21
- - layout_bracket: Bracket Layout
22
21
 
@@ -7,5 +7,4 @@ 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'
11
10
 
@@ -82,10 +82,6 @@ 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
- },
89
85
  ]
90
86
 
91
87
  testValues.forEach(({ layout, expected }) => {
@@ -1,4 +1,4 @@
1
- import { debounce } from "../../utilities/object"
1
+ import { debounce } from 'lodash'
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_custom_icon')
76
+ const icon = kit.querySelector('.pb_icon_kit')
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_custom_icon')
90
+ const icon = kit.querySelector('.pb_icon_kit')
91
91
  expect(icon).toBeInTheDocument();
92
92
  })
93
93
 
@@ -7,12 +7,11 @@ import {
7
7
  buildDataProps,
8
8
  buildHtmlProps,
9
9
  } from "../utilities/props";
10
- import { cloneDeep } from "../utilities/object";
11
-
12
10
  import Icon from "../pb_icon/_icon";
13
11
  import FormPill from "../pb_form_pill/_form_pill";
14
12
  import Body from "../pb_body/_body";
15
13
  import Caption from "../pb_caption/_caption";
14
+ import { cloneDeep } from "lodash";
16
15
  import MultiLevelSelectOptions from "./multi_level_select_options";
17
16
  import MultiLevelSelectContext from "./context";
18
17
 
@@ -95,13 +95,11 @@ 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
- const icon = kit.querySelector(".pb_custom_icon.pb_nav_list_item_icon_right")
99
- expect(icon).toBeInTheDocument()
98
+ expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_right fa-fw fa-angle-down" />')
100
99
  })
101
100
 
102
101
  test('should have a left icon', () => {
103
- render(<NavDefault iconLeft="angle-up" />)
102
+ render(<NavDefault iconLeft="users-class" />)
104
103
  const kit = screen.getByTestId(itemTestId)
105
- const icon = kit.querySelector(".pb_custom_icon.pb_nav_list_item_icon_left")
106
- expect(icon).toBeInTheDocument()
104
+ expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_left fa-fw fa-users-class" />')
107
105
  })
@@ -19,27 +19,23 @@ test('it renders preset icon', () => {
19
19
  render(
20
20
  <StatChange
21
21
  change="increase"
22
- id="preset-icon"
23
22
  value="28.4"
24
23
  />
25
24
  )
26
25
 
27
- const kit = document.querySelector('#preset-icon')
28
- const icon = kit.querySelector(".pb_custom_icon")
29
- expect(icon).toBeInTheDocument()
26
+ const kit = screen.getByLabelText('arrow-up icon')
27
+ expect(kit).toBeTruthy
30
28
  })
31
29
 
32
30
  test('it renders custom icon', () => {
33
31
  render(
34
32
  <StatChange
35
33
  icon="chart-line-down"
36
- id="custom-icon"
37
34
  value={6.1}
38
35
  />
39
36
 
40
37
  )
41
38
 
42
- const kit = document.querySelector('#custom-icon')
43
- const icon = kit.querySelector(".pb_custom_icon")
44
- expect(icon).toBeInTheDocument()
39
+ const kit = screen.getByLabelText('chart-line-down icon')
40
+ expect(kit).toBeTruthy
45
41
  })
@@ -1,7 +1,7 @@
1
- [class^=pb_table]:not(:has(colgroup)) {
1
+ [class^=pb_table] {
2
2
  &.striped {
3
3
  tbody, .pb_table_tbody {
4
- tr:nth-child(odd):not(.pb_background_kit), .pb_table_tr:nth-child(odd):not(.pb_background_kit) {
4
+ tr:nth-child(odd), .pb_table_tr:nth-child(odd) {
5
5
  background-color: $bg_light;
6
6
  }
7
7
  }
@@ -10,7 +10,7 @@
10
10
  &.dark {
11
11
  &.striped {
12
12
  tbody, .pb_table_tbody {
13
- tr:nth-child(odd):not(.pb_background_kit), .pb_table_tr:nth-child(odd):not(.pb_background_kit) {
13
+ tr:nth-child(odd), .pb_table_tr:nth-child(odd) {
14
14
  background-color: $bg_dark;
15
15
  }
16
16
  }
@@ -0,0 +1,282 @@
1
+ import PbEnhancedElement from '../pb_enhanced_element'
2
+ import { computePosition, offset, flip, shift, arrow, autoUpdate } from '@floating-ui/dom'
3
+
4
+ const TOOLTIP_OFFSET = 20
5
+ const TOOLTIP_TIMEOUT = 250
6
+ const SAFE_ZONE_MARGIN = 1
7
+
8
+ export default class PbTooltipFloatingUi extends PbEnhancedElement {
9
+ static get selector() {
10
+ return '[data-pb-tooltip-kit="true"][data-pb-tooltip-delay-open], [data-pb-tooltip-kit="true"][data-pb-tooltip-delay-close], [data-pb-tooltip-kit="true"][data-pb-tooltip-interaction="true"]'
11
+ }
12
+
13
+ connect() {
14
+ if (this.tooltipInteraction) {
15
+ document.addEventListener('mousemove', (e) => {
16
+ this.lastMouseX = e.clientX
17
+ this.lastMouseY = e.clientY
18
+ })
19
+ }
20
+
21
+ this.triggerElements.forEach((trigger) => {
22
+ const method = this.triggerMethod
23
+ const interactionEnabled = this.tooltipInteraction
24
+
25
+ if (method === 'click') {
26
+ trigger.addEventListener('click', () => {
27
+ this.showTooltip(trigger)
28
+ })
29
+ } else {
30
+ trigger.addEventListener('mouseenter', () => {
31
+ clearSafeZoneListener(this)
32
+ clearTimeout(this.mouseleaveTimeout)
33
+ this.currentTrigger = trigger
34
+ const delayOpen = this.delayOpen ? parseInt(this.delayOpen) : TOOLTIP_TIMEOUT
35
+ this.mouseenterTimeout = setTimeout(() => {
36
+ this.showTooltip(trigger)
37
+ if (interactionEnabled) {
38
+ this.checkCloseTooltip(trigger)
39
+ }
40
+ }, delayOpen)
41
+ })
42
+
43
+ trigger.addEventListener('mouseleave', () => {
44
+ clearTimeout(this.mouseenterTimeout)
45
+ if (this.delayClose) {
46
+ const delayClose = parseInt(this.delayClose)
47
+ this.mouseleaveTimeout = setTimeout(() => {
48
+ if (interactionEnabled) {
49
+ this.attachSafeZoneListener()
50
+ } else {
51
+ this.hideTooltip()
52
+ }
53
+ }, delayClose)
54
+ } else {
55
+ if (interactionEnabled) {
56
+ this.attachSafeZoneListener()
57
+ } else {
58
+ this.hideTooltip()
59
+ }
60
+ }
61
+ })
62
+
63
+ if (interactionEnabled) {
64
+ this.tooltip.addEventListener('mouseenter', () => {
65
+ clearSafeZoneListener(this)
66
+ })
67
+
68
+ this.tooltip.addEventListener('mouseleave', () => {
69
+ this.attachSafeZoneListener()
70
+ })
71
+ }
72
+ }
73
+ })
74
+ }
75
+
76
+ attachSafeZoneListener() {
77
+ clearSafeZoneListener(this)
78
+ this.safeZoneHandler = (e) => {
79
+ if (!this.currentTrigger) return
80
+ const triggerRect = this.currentTrigger.getBoundingClientRect()
81
+ const tooltipRect = this.tooltip.getBoundingClientRect()
82
+ const safeRect = getSafeZone(triggerRect, tooltipRect, this.position, SAFE_ZONE_MARGIN)
83
+ if (!isPointInsideRect(e.clientX, e.clientY, safeRect)) {
84
+ this.hideTooltip()
85
+ clearSafeZoneListener(this)
86
+ }
87
+ }
88
+ document.addEventListener('mousemove', this.safeZoneHandler)
89
+ }
90
+
91
+ checkCloseTooltip(trigger) {
92
+ document.querySelector('body').addEventListener('click', ({ target }) => {
93
+ const isTooltip = target.closest(`#${this.tooltipId}`) === this.tooltip
94
+ const isTrigger = target.closest(this.triggerElementSelector) === trigger
95
+ if (isTrigger || isTooltip) {
96
+ this.checkCloseTooltip(trigger)
97
+ } else {
98
+ this.hideTooltip()
99
+ }
100
+ }, { once: true })
101
+ }
102
+
103
+ showTooltip(trigger) {
104
+ if (this.shouldShowTooltip === 'false') return
105
+
106
+ clearSafeZoneListener(this)
107
+
108
+ this.tooltip.style.opacity = '1'
109
+ this.tooltip.style.visibility = 'visible'
110
+ this.tooltip.style.pointerEvents = 'auto'
111
+
112
+ if (this.cleanup) {
113
+ this.cleanup()
114
+ }
115
+
116
+ const arrowElement = document.querySelector(`#${this.tooltipId}-arrow`)
117
+
118
+ this.cleanup = autoUpdate(trigger, this.tooltip, () => {
119
+ computePosition(trigger, this.tooltip, {
120
+ placement: this.position,
121
+ strategy: 'fixed',
122
+ middleware: [
123
+ offset({ mainAxis: TOOLTIP_OFFSET, crossAxis: 0 }),
124
+ flip(),
125
+ shift(),
126
+ arrow({ element: arrowElement })
127
+ ],
128
+ }).then(({ x, y, placement, middlewareData }) => {
129
+ Object.assign(this.tooltip.style, {
130
+ left: `${x}px`,
131
+ top: `${y}px`,
132
+ position: 'fixed'
133
+ })
134
+ this.tooltip.setAttribute('data-popper-placement', placement)
135
+ if (arrowElement && middlewareData.arrow) {
136
+ const { x: arrowX, y: arrowY } = middlewareData.arrow
137
+ Object.assign(arrowElement.style, {
138
+ left: arrowX != null ? `${arrowX}px` : '',
139
+ top: arrowY != null ? `${arrowY}px` : '',
140
+ position: 'absolute'
141
+ })
142
+ }
143
+ })
144
+ })
145
+
146
+ this.tooltip.classList.add('show')
147
+
148
+ if (this.triggerMethod === 'click') {
149
+ clearTimeout(this.autoHideTimeout)
150
+ this.autoHideTimeout = setTimeout(() => {
151
+ this.hideTooltip()
152
+ }, 1000)
153
+ }
154
+ }
155
+
156
+ hideTooltip() {
157
+ if (!this.tooltip) return
158
+
159
+ this.tooltip.classList.add('fade_out')
160
+ setTimeout(() => {
161
+ if (this.cleanup) {
162
+ this.cleanup()
163
+ this.cleanup = null
164
+ }
165
+ this.tooltip.classList.remove('show')
166
+ this.tooltip.classList.remove('fade_out')
167
+ this.tooltip.style.opacity = '0'
168
+ this.tooltip.style.visibility = 'hidden'
169
+ this.tooltip.style.pointerEvents = 'none'
170
+ this.tooltip.style.position = ''
171
+ this.tooltip.style.top = ''
172
+ this.tooltip.style.left = ''
173
+ this.tooltip.style.transform = ''
174
+ }, TOOLTIP_TIMEOUT)
175
+ }
176
+
177
+ get triggerElements() {
178
+ let triggerEl
179
+ if (this.triggerElementId) {
180
+ triggerEl = document.querySelector(`#${this.triggerElementId}`)
181
+ } else if (this.triggerElementSelector) {
182
+ const selectorIsId = this.triggerElementSelector.indexOf('#') > -1
183
+ triggerEl = selectorIsId
184
+ ? document.querySelector(this.triggerElementSelector)
185
+ : document.querySelectorAll(this.triggerElementSelector)
186
+ } else {
187
+ triggerEl = this.element
188
+ }
189
+ if (!triggerEl) {
190
+ console.error('Tooltip Kit: No valid trigger element found!')
191
+ return []
192
+ }
193
+ if (triggerEl.length === undefined) {
194
+ triggerEl = [triggerEl]
195
+ }
196
+ return triggerEl
197
+ }
198
+
199
+ get tooltip() {
200
+ return (this._tooltip = this._tooltip || this.element.querySelector(`#${this.tooltipId}`))
201
+ }
202
+
203
+ get position() {
204
+ return this.element.dataset.pbTooltipPosition
205
+ }
206
+
207
+ get triggerElementId() {
208
+ return this.element.dataset.pbTooltipTriggerElementId
209
+ }
210
+
211
+ get tooltipId() {
212
+ return this.element.dataset.pbTooltipTooltipId
213
+ }
214
+
215
+ get triggerElementSelector() {
216
+ return this.element.dataset.pbTooltipTriggerElementSelector
217
+ }
218
+
219
+ get shouldShowTooltip() {
220
+ return this.element.dataset.pbTooltipShowTooltip
221
+ }
222
+
223
+ get triggerMethod() {
224
+ return this.element.dataset.pbTooltipTriggerMethod || 'hover'
225
+ }
226
+
227
+ get tooltipInteraction() {
228
+ return this.element.dataset.pbTooltipInteraction === 'true'
229
+ }
230
+
231
+ get delayOpen() {
232
+ return this.element.dataset.pbTooltipDelayOpen
233
+ }
234
+
235
+ get delayClose() {
236
+ return this.element.dataset.pbTooltipDelayClose
237
+ }
238
+ }
239
+
240
+ function clearSafeZoneListener(context) {
241
+ if (context.safeZoneHandler) {
242
+ document.removeEventListener('mousemove', context.safeZoneHandler)
243
+ context.safeZoneHandler = null
244
+ }
245
+ }
246
+
247
+ function getSafeZone(triggerRect, tooltipRect, placement, margin) {
248
+ let safeRect = {}
249
+ if (placement.startsWith('top')) {
250
+ safeRect.left = triggerRect.left - margin
251
+ safeRect.right = triggerRect.right + margin
252
+ safeRect.top = tooltipRect.bottom - margin
253
+ safeRect.bottom = triggerRect.top + margin
254
+ } else if (placement.startsWith('bottom')) {
255
+ safeRect.left = triggerRect.left - margin
256
+ safeRect.right = triggerRect.right + margin
257
+ safeRect.top = triggerRect.bottom - margin
258
+ safeRect.bottom = tooltipRect.top + margin
259
+ } else if (placement.startsWith('left')) {
260
+ safeRect.top = triggerRect.top - margin
261
+ safeRect.bottom = triggerRect.bottom + margin
262
+ safeRect.left = tooltipRect.right - margin
263
+ safeRect.right = triggerRect.left + margin
264
+ } else if (placement.startsWith('right')) {
265
+ safeRect.top = triggerRect.top - margin
266
+ safeRect.bottom = triggerRect.bottom + margin
267
+ safeRect.left = triggerRect.right - margin
268
+ safeRect.right = tooltipRect.left + margin
269
+ } else {
270
+ safeRect = {
271
+ left: triggerRect.left - margin,
272
+ right: triggerRect.right + margin,
273
+ top: triggerRect.top - margin,
274
+ bottom: triggerRect.bottom + margin,
275
+ }
276
+ }
277
+ return safeRect
278
+ }
279
+
280
+ function isPointInsideRect(x, y, rect) {
281
+ return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
282
+ }