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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/types.ts +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +0 -70
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +2 -83
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +7 -20
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -2
- data/app/pb_kits/playbook/pb_background/_background.scss +0 -26
- data/app/pb_kits/playbook/pb_background/_background.tsx +3 -6
- data/app/pb_kits/playbook/pb_background/background.test.js +0 -5
- data/app/pb_kits/playbook/pb_background/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_background/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +7 -14
- data/app/pb_kits/playbook/pb_contact/contact.test.js +7 -7
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +34 -34
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -2
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +0 -16
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +11 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.jsx +7 -0
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_inline_styles.scss +24 -28
- data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +2 -2
- data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.test.js +1 -1
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +17 -58
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +8 -8
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +3 -3
- data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +4 -3
- data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +3 -2
- data/app/pb_kits/playbook/pb_form/pb_form_validation.js +1 -1
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +0 -22
- data/app/pb_kits/playbook/pb_icon/icon.test.js +9 -9
- data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +1 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_label_value/label_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_layout/_layout.scss +0 -58
- data/app/pb_kits/playbook/pb_layout/_layout.tsx +7 -20
- data/app/pb_kits/playbook/pb_layout/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_layout/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_layout/layout.test.js +0 -4
- data/app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js +1 -1
- data/app/pb_kits/playbook/pb_link/link.test.jsx +2 -2
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +1 -2
- data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +3 -5
- data/app/pb_kits/playbook/pb_stat_change/stat_change.test.js +4 -8
- data/app/pb_kits/playbook/pb_table/styles/_striped.scss +3 -3
- data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +282 -0
- data/app/pb_kits/playbook/pb_tooltip/index.js +56 -183
- data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +5 -2
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +4 -4
- data/app/pb_kits/playbook/pb_typeahead/index.ts +2 -2
- data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +5 -2
- data/app/pb_kits/playbook/pb_user/user.html.erb +6 -1
- data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +6 -1
- data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
- data/app/pb_kits/playbook/utilities/object.test.js +1 -149
- data/app/pb_kits/playbook/utilities/object.ts +42 -124
- data/dist/chunks/{_typeahead-1gVtCLYL.js → _typeahead-N-EFroAX.js} +3 -3
- data/dist/chunks/_weekday_stacked-Db780bKR.js +45 -0
- data/dist/chunks/lib-Co5y3V4K.js +29 -0
- data/dist/chunks/{pb_form_validation-BvNy9Bd6.js → pb_form_validation-DMajaRt3.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/kit_base.rb +4 -4
- data/lib/playbook/version.rb +2 -2
- metadata +7 -15
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.jsx +0 -90
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.md +0 -3
- data/app/pb_kits/playbook/pb_background/docs/_background_overlay.jsx +0 -36
- data/app/pb_kits/playbook/pb_background/docs/_background_overlay.md +0 -1
- data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.jsx +0 -190
- data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.md +0 -5
- data/app/pb_kits/playbook/pb_layout/subcomponents/_game.tsx +0 -90
- data/app/pb_kits/playbook/pb_layout/subcomponents/_round.tsx +0 -57
- data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_vertical.md +0 -1
- data/dist/chunks/_weekday_stacked-Cl62R0Ef.js +0 -45
- 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("
|
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(`
|
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("
|
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("
|
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("
|
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("
|
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("
|
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(`
|
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("
|
152
|
+
expect(kit).toHaveClass("fa-user pb_icon_kit fa-fw fas")
|
153
153
|
})
|
154
154
|
|
155
155
|
test("renders with color prop", () => {
|
@@ -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"
|
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
|
-
|
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
|
-
|
154
|
+
layout == 'collection'
|
158
155
|
? ''
|
159
|
-
:
|
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
|
-
{
|
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
|
@@ -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 }) => {
|
@@ -73,7 +73,7 @@ test('adds icon', () => {
|
|
73
73
|
|
74
74
|
const kit = screen.getByTestId('icon-test')
|
75
75
|
|
76
|
-
const icon = kit.querySelector('.
|
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('.
|
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
|
-
|
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="
|
102
|
+
render(<NavDefault iconLeft="users-class" />)
|
104
103
|
const kit = screen.getByTestId(itemTestId)
|
105
|
-
|
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 =
|
28
|
-
|
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 =
|
43
|
-
|
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]
|
1
|
+
[class^=pb_table] {
|
2
2
|
&.striped {
|
3
3
|
tbody, .pb_table_tbody {
|
4
|
-
tr:nth-child(odd)
|
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)
|
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
|
+
}
|