playbook_ui 12.28.0.pre.alpha.20230613implementbakesupport865 → 12.29.0.pre.alpha.play716popoverkitcloseonclickissue893
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/index.js +1 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +102 -95
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +18 -2
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +15 -4
- data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +84 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +15 -8
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_rails.html.erb +12 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_rails.md +3 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_range_limit.html.erb +12 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_range_limit.jsx +18 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_range_limit.md +1 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_react.jsx +17 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_react.md +1 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +3 -1
- data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +173 -0
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_calendar_input_icon.scss +3 -2
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +75 -0
- data/app/pb_kits/playbook/pb_map/_map.scss +16 -1
- data/app/pb_kits/playbook/pb_map/_map.tsx +9 -26
- data/app/pb_kits/playbook/pb_map/_map_controls.tsx +47 -0
- data/app/pb_kits/playbook/pb_map/_map_custom_button.tsx +18 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_with_custom_button.jsx +83 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_with_custom_button.md +1 -0
- data/app/pb_kits/playbook/pb_map/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_map/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_nav/_item.tsx +1 -1
- data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
- data/app/pb_kits/playbook/pb_popover/_popover.tsx +5 -3
- data/app/pb_kits/playbook/pb_popover/index.ts +5 -2
- data/dist/playbook-rails.js +279 -7
- data/lib/playbook/version.rb +2 -2
- metadata +15 -2
@@ -19,4 +19,6 @@ export { default as DatePickerWeek } from './_date_picker_week.jsx'
|
|
19
19
|
export { default as DatePickerPositions } from './_date_picker_positions.jsx'
|
20
20
|
export { default as DatePickerPositionsElement } from './_date_picker_positions_element.jsx'
|
21
21
|
export { default as DatePickerAllowInput } from './_date_picker_allow_input'
|
22
|
-
export { default as
|
22
|
+
export { default as DatePickerQuickPickReact } from './_date_picker_quick_pick_react'
|
23
|
+
export { default as DatePickerQuickPickRangeLimit } from './_date_picker_quick_pick_range_limit'
|
24
|
+
export { default as DatePickerOnClose } from './_date_picker_on_close.jsx'
|
@@ -0,0 +1,173 @@
|
|
1
|
+
import moment from 'moment'
|
2
|
+
|
3
|
+
type FpTypes = {
|
4
|
+
setDate: (arg0: any, arg1: boolean) => void,
|
5
|
+
config: { [key: string]: string },
|
6
|
+
clear: (arg0: boolean, arg1: boolean) => void,
|
7
|
+
close: () => void,
|
8
|
+
calendarContainer?: {
|
9
|
+
classList: { add: (arg0: string) => void };
|
10
|
+
prepend: (arg0: HTMLDivElement) => void;
|
11
|
+
append: (arg0: HTMLDivElement) => void;
|
12
|
+
},
|
13
|
+
loadedPlugins: string[],
|
14
|
+
};
|
15
|
+
|
16
|
+
type pluginDataType = {
|
17
|
+
ranges: { [key: string]: Date[] },
|
18
|
+
rangesNav: HTMLUListElement,
|
19
|
+
rangesButtons: [] | any,
|
20
|
+
}
|
21
|
+
|
22
|
+
let activeLabel = ""
|
23
|
+
|
24
|
+
const quickPickPlugin = (thisRangesEndToday: boolean) => {
|
25
|
+
return function (fp: FpTypes & any): any {
|
26
|
+
const thisWeekEndDate = thisRangesEndToday ? new Date() : moment().endOf('isoWeek').toDate()
|
27
|
+
const thisMonthEndDate = thisRangesEndToday ? new Date() : moment().endOf('month').toDate()
|
28
|
+
const thisQuarterEndDate = thisRangesEndToday ? new Date() : moment().endOf('quarter').toDate()
|
29
|
+
const thisYearEndDate = thisRangesEndToday ? new Date() : moment().endOf('year').toDate()
|
30
|
+
|
31
|
+
// variable that holds the ranges available
|
32
|
+
const ranges = {
|
33
|
+
'Today': [new Date(), new Date()],
|
34
|
+
'Yesterday': [moment().subtract(1, 'days').toDate(), moment().subtract(1, 'days').toDate()],
|
35
|
+
'This week': [moment().startOf('isoWeek').toDate(), thisWeekEndDate],
|
36
|
+
'This month': [moment().startOf('month').toDate(), thisMonthEndDate],
|
37
|
+
'This quarter': [moment().startOf('quarter').toDate(), thisQuarterEndDate],
|
38
|
+
'This year': [moment().startOf('year').toDate(), thisYearEndDate],
|
39
|
+
'Last week': [
|
40
|
+
moment().subtract(1, 'week').startOf('isoWeek').toDate(),
|
41
|
+
moment().subtract(1, 'week').endOf('isoWeek').toDate()
|
42
|
+
],
|
43
|
+
'Last month': [
|
44
|
+
moment().subtract(1, 'month').startOf('month').toDate(),
|
45
|
+
moment().subtract(1, 'month').endOf('month').toDate()
|
46
|
+
],
|
47
|
+
'Last quarter': [
|
48
|
+
moment().subtract(1, 'quarter').startOf('quarter').toDate(),
|
49
|
+
moment().subtract(1, 'quarter').endOf('quarter').toDate()
|
50
|
+
],
|
51
|
+
'Last year': [
|
52
|
+
moment().subtract(1, 'year').startOf('year').toDate(),
|
53
|
+
moment().subtract(1, 'year').endOf('year').toDate()
|
54
|
+
]
|
55
|
+
}
|
56
|
+
//creating the ul element for the nav dropdown and giving it classnames
|
57
|
+
const rangesNav = document.createElement('ul');
|
58
|
+
|
59
|
+
// creating the pluginData object that will hold the properties of this plugin
|
60
|
+
const pluginData: pluginDataType = {
|
61
|
+
ranges: ranges,
|
62
|
+
rangesNav: rangesNav,
|
63
|
+
rangesButtons: [],
|
64
|
+
};
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @param {string} label
|
68
|
+
* @returns HTML Element
|
69
|
+
*/
|
70
|
+
|
71
|
+
//function for creating the range buttons in the nav
|
72
|
+
const addRangeButton = (label: string) => {
|
73
|
+
|
74
|
+
// creating new elements to mimick selectable card component
|
75
|
+
const div2 = document.createElement('div');
|
76
|
+
div2.className = "nav-item-link"
|
77
|
+
div2.innerHTML = label;
|
78
|
+
|
79
|
+
pluginData.rangesButtons[label] = div2;
|
80
|
+
|
81
|
+
// create li elements inside the dropdown
|
82
|
+
const item = document.createElement('li');
|
83
|
+
item.className = "nav-item";
|
84
|
+
|
85
|
+
// append those nav items to the li items
|
86
|
+
item.appendChild(pluginData.rangesButtons[label]);
|
87
|
+
|
88
|
+
// append the li item to the ul rangeNav prop
|
89
|
+
pluginData.rangesNav.appendChild(item);
|
90
|
+
|
91
|
+
// return the ranges buton prop
|
92
|
+
return pluginData.rangesButtons[label];
|
93
|
+
};
|
94
|
+
|
95
|
+
const selectActiveRangeButton = (selectedDates: Array<Date>) => {
|
96
|
+
const current = pluginData.rangesNav.querySelector('.active');
|
97
|
+
|
98
|
+
if (current) {
|
99
|
+
current.classList.remove('active');
|
100
|
+
}
|
101
|
+
|
102
|
+
if (selectedDates.length > 0 && activeLabel) {
|
103
|
+
pluginData.rangesButtons[activeLabel].classList.add('active');
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
const isLabelMatchingSelectedDates = (selectedDates: Array<Date>) => {
|
108
|
+
return activeLabel && selectedDates[0].toDateString() === pluginData.ranges[activeLabel][0].toDateString() &&
|
109
|
+
selectedDates[1].toDateString() === pluginData.ranges[activeLabel][1].toDateString()
|
110
|
+
}
|
111
|
+
|
112
|
+
|
113
|
+
return {
|
114
|
+
// onReady is a hook from flatpickr that runs when calender is in a ready state
|
115
|
+
onReady(selectedDates: Array<Date>) {
|
116
|
+
// loop through the ranges and create an anchor tag for each range and add an event listener to set the date when user clicks on a date range
|
117
|
+
for (const [label, range] of Object.entries(pluginData.ranges)) {
|
118
|
+
addRangeButton(label).addEventListener('click', function () {
|
119
|
+
|
120
|
+
const start = moment(range[0]).toDate();
|
121
|
+
const end = moment(range[1]).toDate();
|
122
|
+
|
123
|
+
if (!start) {
|
124
|
+
fp.clear();
|
125
|
+
}
|
126
|
+
else {
|
127
|
+
activeLabel = label
|
128
|
+
fp.setDate([start, end], true);
|
129
|
+
fp.close();
|
130
|
+
}
|
131
|
+
});
|
132
|
+
}
|
133
|
+
// conditional to check if there is a dropdown to add it to the calendar container and get it the classes it needs
|
134
|
+
if (pluginData.rangesNav.children.length > 0) {
|
135
|
+
|
136
|
+
fp.calendarContainer.prepend(pluginData.rangesNav);
|
137
|
+
pluginData.rangesNav.classList.add('quick-pick-ul')
|
138
|
+
fp.calendarContainer.classList.add('quick-pick-drop-down');
|
139
|
+
|
140
|
+
/**
|
141
|
+
*
|
142
|
+
* @param {Array} selectedDates
|
143
|
+
*/
|
144
|
+
// function to give the active button the active class
|
145
|
+
selectActiveRangeButton(selectedDates);
|
146
|
+
}
|
147
|
+
},
|
148
|
+
onValueUpdate(selectedDates: Array<Date>) {
|
149
|
+
selectActiveRangeButton(selectedDates)
|
150
|
+
},
|
151
|
+
|
152
|
+
onClose(selectedDates: Array<Date>) {
|
153
|
+
// remove the active class from the button if the selected dates don't match the label
|
154
|
+
if (!isLabelMatchingSelectedDates(selectedDates)) {
|
155
|
+
pluginData.rangesButtons[activeLabel]?.classList.remove('active');
|
156
|
+
activeLabel = ""
|
157
|
+
}
|
158
|
+
|
159
|
+
// set the date to the first date in the array if the user types only one date
|
160
|
+
if (selectedDates.length === 1) {
|
161
|
+
fp.setDate([selectedDates[0], selectedDates[0]], true);
|
162
|
+
}
|
163
|
+
|
164
|
+
// set the input value to the selected dates when the dropdown is closed
|
165
|
+
if (selectedDates.length < 2 && selectedDates.length > 0) {
|
166
|
+
fp.input.placeholder = fp.formatDate(this.selectedDates[0], fp.config.dateFormat);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
};
|
170
|
+
};
|
171
|
+
}
|
172
|
+
|
173
|
+
export default quickPickPlugin;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
@import "../../tokens/colors";
|
1
2
|
// Calendar Icon Styles
|
2
3
|
.cal_icon_wrapper {
|
3
4
|
pointer-events: none;
|
@@ -13,8 +14,8 @@
|
|
13
14
|
padding-left: $space_sm - 1;
|
14
15
|
color: $text_lt_light;
|
15
16
|
@media (hover: hover) {
|
16
|
-
&:hover
|
17
|
-
|
17
|
+
&:hover{
|
18
|
+
background-color: rgba($focus_input_light,$opacity_5);
|
18
19
|
}
|
19
20
|
}
|
20
21
|
&.dark {
|
@@ -0,0 +1,75 @@
|
|
1
|
+
@import "../../tokens/animation-curves";
|
2
|
+
@import "../../tokens/colors";
|
3
|
+
@import "../../tokens/typography";
|
4
|
+
@import "../../tokens/titles";
|
5
|
+
@import "../../tokens/spacing";
|
6
|
+
|
7
|
+
$pb_card_border_width: 1px;
|
8
|
+
$pb_card_border_radius: $border_rad_heavier;
|
9
|
+
|
10
|
+
// used to display dropdown on the left of the calender
|
11
|
+
.quick-pick-drop-down {
|
12
|
+
width: auto;
|
13
|
+
display: grid;
|
14
|
+
}
|
15
|
+
|
16
|
+
.quick-pick-ul {
|
17
|
+
padding: $space_xs 0px;
|
18
|
+
margin: 0;
|
19
|
+
list-style: none;
|
20
|
+
}
|
21
|
+
|
22
|
+
.nav-item {
|
23
|
+
list-style: none;
|
24
|
+
border-radius: 6px;
|
25
|
+
border-bottom: 0;
|
26
|
+
margin: $space_xs $space_sm;
|
27
|
+
}
|
28
|
+
|
29
|
+
.nav-item-link {
|
30
|
+
text-decoration: none;
|
31
|
+
border-width: $pb_card_border_width;
|
32
|
+
border-style: solid;
|
33
|
+
border-color: $border_light;
|
34
|
+
border-radius: $pb_card_border_radius;
|
35
|
+
padding: $space_xs 14px;
|
36
|
+
transition-property: color, background-color;
|
37
|
+
transition-duration: 0.15s;
|
38
|
+
transition-timing-function: $bezier;
|
39
|
+
line-height: 1.4;
|
40
|
+
color: $charcoal;
|
41
|
+
font-size: $font_default;
|
42
|
+
font-weight: $regular;
|
43
|
+
&.active {
|
44
|
+
border-width: 2px;
|
45
|
+
border-color: $primary;
|
46
|
+
}
|
47
|
+
@media (hover:hover) {
|
48
|
+
&:hover {
|
49
|
+
cursor: pointer;
|
50
|
+
box-shadow: $shadow-deep;
|
51
|
+
border-color: $slate;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
// Hide the calendar
|
57
|
+
.quick-pick-drop-down > .flatpickr-months, .quick-pick-drop-down > .flatpickr-innerContainer {
|
58
|
+
display: none;
|
59
|
+
}
|
60
|
+
|
61
|
+
@media only screen and (max-width: 767px) {
|
62
|
+
.quick-pick-ul {
|
63
|
+
padding: $space_xs $space_xs;
|
64
|
+
display: grid;
|
65
|
+
grid-template-columns: 1fr 1fr;
|
66
|
+
}
|
67
|
+
|
68
|
+
.nav-item {
|
69
|
+
margin: $space_xxs $space_xs;
|
70
|
+
}
|
71
|
+
|
72
|
+
.nav-item-link {
|
73
|
+
padding: $space_xs $space_xxs;
|
74
|
+
}
|
75
|
+
}
|
@@ -5,6 +5,21 @@
|
|
5
5
|
@import "./_pb_map_button_mixin.scss";
|
6
6
|
|
7
7
|
[class*="pb_map"] {
|
8
|
+
.pb_map-custom-button {
|
9
|
+
@include pb_map_button;
|
10
|
+
position: relative;
|
11
|
+
margin-top: $space_xs;
|
12
|
+
box-shadow: $shadow_deep;
|
13
|
+
.pb_icon_kit {
|
14
|
+
width: $space_sm - 2;
|
15
|
+
height: $space_sm;
|
16
|
+
}
|
17
|
+
|
18
|
+
.pb_button_content {
|
19
|
+
height: $space_sm;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
8
23
|
.mapboxgl-map,
|
9
24
|
.maplibregl-map {
|
10
25
|
font-family: $font_family_base !important;
|
@@ -185,7 +200,7 @@
|
|
185
200
|
}
|
186
201
|
.map-zoom-in-button,
|
187
202
|
.map-zoom-out-button,
|
188
|
-
.map-flyto-button {
|
203
|
+
.map-flyto-button, .pb_map-custom-button {
|
189
204
|
@include pb_map_button_dark;
|
190
205
|
}
|
191
206
|
|
@@ -3,9 +3,7 @@ import classnames from 'classnames'
|
|
3
3
|
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
4
4
|
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
5
5
|
|
6
|
-
import
|
7
|
-
import Icon from '../pb_icon/_icon'
|
8
|
-
import Button from '../pb_button/_button'
|
6
|
+
import MapControls from './_map_controls';
|
9
7
|
|
10
8
|
type MapProps = {
|
11
9
|
aria?: { [key: string]: string },
|
@@ -47,29 +45,13 @@ const Map = (props: MapProps) => {
|
|
47
45
|
>
|
48
46
|
{
|
49
47
|
zoomBtns ? (
|
50
|
-
<
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
<Button className='map-zoom-out-button'
|
58
|
-
onClick={zoomOutClick}
|
59
|
-
>
|
60
|
-
<Icon icon="minus"/>
|
61
|
-
</Button>
|
62
|
-
</div>
|
63
|
-
{
|
64
|
-
flyTo ? (
|
65
|
-
<Button className='map-flyto-button'
|
66
|
-
onClick={flyToClick}
|
67
|
-
>
|
68
|
-
<Icon icon="eye"/>
|
69
|
-
</Button>
|
70
|
-
) : null
|
71
|
-
}
|
72
|
-
</Flex>
|
48
|
+
<Map.Controls
|
49
|
+
flyTo={flyTo}
|
50
|
+
flyToClick={flyToClick}
|
51
|
+
zoomBtns={zoomBtns}
|
52
|
+
zoomInClick={zoomInClick}
|
53
|
+
zoomOutClick={zoomOutClick}
|
54
|
+
/>
|
73
55
|
) : null
|
74
56
|
}
|
75
57
|
{children}
|
@@ -77,4 +59,5 @@ const Map = (props: MapProps) => {
|
|
77
59
|
)
|
78
60
|
}
|
79
61
|
|
62
|
+
Map.Controls = MapControls
|
80
63
|
export default Map
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import Button from "../pb_button/_button";
|
3
|
+
import Icon from "../pb_icon/_icon";
|
4
|
+
import Flex from "../pb_flex/_flex";
|
5
|
+
|
6
|
+
type MapControlTypes = {
|
7
|
+
zoomBtns?: boolean,
|
8
|
+
flyTo?: boolean,
|
9
|
+
zoomInClick?: () => {},
|
10
|
+
zoomOutClick?: () => {},
|
11
|
+
flyToClick?: () => {},
|
12
|
+
children?: React.ReactNode | React.ReactNode[]
|
13
|
+
}
|
14
|
+
|
15
|
+
const MapControls = ({
|
16
|
+
zoomBtns,
|
17
|
+
zoomInClick,
|
18
|
+
zoomOutClick,
|
19
|
+
flyTo,
|
20
|
+
flyToClick,
|
21
|
+
children,
|
22
|
+
}: MapControlTypes) => {
|
23
|
+
return (
|
24
|
+
<Flex className="custom-nav-control" orientation="column">
|
25
|
+
{zoomBtns ? (
|
26
|
+
<>
|
27
|
+
<div className="custom-nav-control-zoom">
|
28
|
+
<Button className="map-zoom-in-button" onClick={zoomInClick}>
|
29
|
+
<Icon icon="plus" />
|
30
|
+
</Button>
|
31
|
+
<Button className="map-zoom-out-button" onClick={zoomOutClick}>
|
32
|
+
<Icon icon="minus" />
|
33
|
+
</Button>
|
34
|
+
</div>
|
35
|
+
{flyTo ? (
|
36
|
+
<Button className="map-flyto-button" onClick={flyToClick}>
|
37
|
+
<Icon icon="eye" />
|
38
|
+
</Button>
|
39
|
+
) : null}
|
40
|
+
</>
|
41
|
+
) : null}
|
42
|
+
{children}
|
43
|
+
</Flex>
|
44
|
+
);
|
45
|
+
};
|
46
|
+
|
47
|
+
export default MapControls;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import Button from "../pb_button/_button";
|
3
|
+
import Icon from "../pb_icon/_icon";
|
4
|
+
|
5
|
+
type MapCustomButtonTypes = {
|
6
|
+
onClick?: () => {};
|
7
|
+
icon?: string;
|
8
|
+
};
|
9
|
+
|
10
|
+
const MapCustomButton = ({ onClick, icon }: MapCustomButtonTypes) => {
|
11
|
+
return (
|
12
|
+
<Button className="pb_map-custom-button" onClick={onClick}>
|
13
|
+
<Icon icon={icon} />
|
14
|
+
</Button>
|
15
|
+
);
|
16
|
+
};
|
17
|
+
|
18
|
+
export default MapCustomButton;
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import React, { useRef, useEffect, useState } from 'react'
|
2
|
+
import { Map, mapTheme, MapCustomButton } from '../..'
|
3
|
+
import maplibregl from 'maplibre-gl'
|
4
|
+
|
5
|
+
const MapWithCustomButton = (props) => {
|
6
|
+
|
7
|
+
//set Map instance to access from outside useEffect
|
8
|
+
const [mapInstance, setMapInstance] = useState(null)
|
9
|
+
const mapContainerRef = useRef(null)
|
10
|
+
|
11
|
+
//Set default position
|
12
|
+
const defaultPosition = [-75.379143, 39.831200]
|
13
|
+
|
14
|
+
// linking Maplibre methods to PB custom zoom in, zoom out, and fly to buttons
|
15
|
+
const handleZoomIn = (map) => {map.zoomIn({...mapTheme.zoomConfig})}
|
16
|
+
const handleZoomOut = (map) => {map.zoomOut({...mapTheme.zoomConfig})}
|
17
|
+
const handleFlyTo = (map) => {map.flyTo({
|
18
|
+
center: defaultPosition,
|
19
|
+
... mapTheme.flyToConfig
|
20
|
+
});}
|
21
|
+
|
22
|
+
//This function is called by the useEffect when map instance first loads
|
23
|
+
const loadMap = ( { target: map }) => {
|
24
|
+
//set marker/pin
|
25
|
+
new maplibregl.Marker({
|
26
|
+
color: mapTheme.marker,
|
27
|
+
}).setLngLat(defaultPosition)
|
28
|
+
.setPopup(new maplibregl.Popup({closeButton: false}).setHTML(`<h4 class="pb_title_kit_size_4">Hello World!</h4>`)) // add popup
|
29
|
+
.addTo(map);
|
30
|
+
|
31
|
+
// disable map zoom when using scroll
|
32
|
+
map.scrollZoom.disable();
|
33
|
+
|
34
|
+
//add attributioncontrols
|
35
|
+
map.addControl(new maplibregl.AttributionControl({
|
36
|
+
compact: true
|
37
|
+
}));
|
38
|
+
|
39
|
+
//set map instance
|
40
|
+
setMapInstance(map)
|
41
|
+
}
|
42
|
+
|
43
|
+
useEffect(() => {
|
44
|
+
new maplibregl.Map({
|
45
|
+
container: mapContainerRef.current,
|
46
|
+
center: defaultPosition,
|
47
|
+
...mapTheme.mapConfig
|
48
|
+
}).on('load', loadMap)
|
49
|
+
|
50
|
+
}, [])
|
51
|
+
|
52
|
+
return (
|
53
|
+
<Map
|
54
|
+
{...props}
|
55
|
+
>
|
56
|
+
<Map.Controls flyTo
|
57
|
+
flyToClick={()=> {handleFlyTo(mapInstance)}}
|
58
|
+
zoomBtns
|
59
|
+
zoomInClick={() => {handleZoomIn(mapInstance)}}
|
60
|
+
zoomOutClick={()=> {handleZoomOut(mapInstance)}}
|
61
|
+
>
|
62
|
+
<MapCustomButton icon="home"
|
63
|
+
onClick={() => alert("button clicked!")}
|
64
|
+
/>
|
65
|
+
<MapCustomButton icon="search"
|
66
|
+
onClick={() => alert("button clicked!")}
|
67
|
+
/>
|
68
|
+
</Map.Controls>
|
69
|
+
<div
|
70
|
+
ref={mapContainerRef}
|
71
|
+
style={{
|
72
|
+
position: 'absolute',
|
73
|
+
left: 0,
|
74
|
+
right: 0,
|
75
|
+
top: 0,
|
76
|
+
bottom: 0,
|
77
|
+
}}
|
78
|
+
/>
|
79
|
+
</Map>
|
80
|
+
)
|
81
|
+
}
|
82
|
+
|
83
|
+
export default MapWithCustomButton
|
@@ -0,0 +1 @@
|
|
1
|
+
If you want to add custom buttons to the Map, you can use the `MapCustomButton` component nested inside Map.Controls as shown in the code snippet below. Note that when Map.Controls is used in this way, the props for the rest of the buttons must also be passed to Map.Controls instead of the Map itself.
|
@@ -171,17 +171,19 @@ const PbReactPopover = (props: PbPopoverProps) => {
|
|
171
171
|
|
172
172
|
switch (closeOnClick) {
|
173
173
|
case "outside":
|
174
|
-
if (!targetIsPopover
|
174
|
+
if (!targetIsPopover && !targetIsReference) {
|
175
175
|
shouldClosePopover(true);
|
176
176
|
}
|
177
177
|
break;
|
178
178
|
case "inside":
|
179
|
-
if (targetIsPopover
|
179
|
+
if (targetIsPopover) {
|
180
180
|
shouldClosePopover(true);
|
181
181
|
}
|
182
182
|
break;
|
183
183
|
case "any":
|
184
|
-
|
184
|
+
if (targetIsPopover || !targetIsPopover && !targetIsReference) {
|
185
|
+
shouldClosePopover(true);
|
186
|
+
}
|
185
187
|
break;
|
186
188
|
}
|
187
189
|
},
|
@@ -49,13 +49,16 @@ export default class PbPopover extends PbEnhancedElement {
|
|
49
49
|
checkCloseTooltip() {
|
50
50
|
document.querySelector('body').addEventListener('click', ({ target } ) => {
|
51
51
|
const isTooltipElement = (target as HTMLElement).closest(`#${this.tooltipId}`) !== null
|
52
|
+
const isTriggerElement = (target as HTMLElement).closest(`#${this.triggerElementId}`) !== null
|
52
53
|
|
53
54
|
switch (this.closeOnClick) {
|
54
55
|
case 'any':
|
55
|
-
|
56
|
+
if (isTooltipElement || !isTooltipElement && !isTriggerElement) {
|
57
|
+
this.hideTooltip()
|
58
|
+
}
|
56
59
|
break
|
57
60
|
case 'outside':
|
58
|
-
if (!isTooltipElement) {
|
61
|
+
if (!isTooltipElement && !isTriggerElement) {
|
59
62
|
this.hideTooltip()
|
60
63
|
}
|
61
64
|
break
|