playbook_ui 14.14.0.pre.alpha.pbntr500currencykithandlingofnullvalues6311 → 14.14.0.pre.alpha.play1755pbcontenttag6460
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_currency/docs/_currency_null_display_rails.md +1 -0
- data/app/pb_kits/playbook/pb_currency/docs/_currency_null_display_react.md +1 -0
- data/app/pb_kits/playbook/pb_drawer/_drawer.scss +32 -8
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_behavior.html.erb +8 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.html.erb +33 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.html.erb +0 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.html.erb +20 -1
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.html.erb +24 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.html.erb +21 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.md +1 -0
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.html.erb +49 -0
- data/app/pb_kits/playbook/pb_drawer/docs/example.yml +5 -0
- data/app/pb_kits/playbook/pb_drawer/drawer.html.erb +20 -12
- data/app/pb_kits/playbook/pb_drawer/drawer.rb +49 -1
- data/app/pb_kits/playbook/pb_drawer/index.js +257 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
- data/app/pb_kits/playbook/pb_overlay/_overlay.scss +13 -0
- data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +7 -1
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.html.erb +11 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.jsx +37 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_rails.md +1 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_react.md +1 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.html.erb +11 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.md +1 -0
- data/app/pb_kits/playbook/pb_overlay/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_overlay/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_overlay/index.js +61 -0
- data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +5 -3
- data/app/pb_kits/playbook/pb_overlay/overlay.rb +16 -1
- data/app/pb_kits/playbook/pb_overlay/overlay.test.jsx +12 -0
- data/app/pb_kits/playbook/pb_select/index.js +38 -0
- data/app/pb_kits/playbook/pb_select/select.html.erb +1 -5
- data/app/pb_kits/playbook/pb_select/select.rb +8 -0
- data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
- data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
- data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +0 -3
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.html.erb +39 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.md +3 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_interaction.html.erb +26 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +282 -0
- data/app/pb_kits/playbook/pb_tooltip/index.js +1 -1
- data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +10 -2
- data/dist/chunks/{_typeahead-PqkcDf1H.js → _typeahead-BGTMEmj7.js} +2 -2
- data/dist/chunks/{_weekday_stacked-BrSrpj7J.js → _weekday_stacked-BBzZIYVP.js} +2 -2
- data/dist/chunks/{lib-D3us1bGD.js → lib-Fr78pbpF.js} +1 -1
- data/dist/chunks/{pb_form_validation-BpihMSOQ.js → pb_form_validation-CN51bfsD.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +2 -2
- 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/version.rb +1 -1
- metadata +28 -6
@@ -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
|
+
}
|
@@ -11,7 +11,7 @@ const TOOLTIP_TIMEOUT = 250
|
|
11
11
|
|
12
12
|
export default class PbTooltip extends PbEnhancedElement {
|
13
13
|
static get selector() {
|
14
|
-
return '[data-pb-tooltip-kit]'
|
14
|
+
return '[data-pb-tooltip-kit="true"][data-pb-tooltip-interaction="false"]:not([data-pb-tooltip-delay-open]):not([data-pb-tooltip-delay-close])'
|
15
15
|
}
|
16
16
|
|
17
17
|
connect() {
|
@@ -7,6 +7,10 @@ module Playbook
|
|
7
7
|
prop :trigger_element_selector
|
8
8
|
prop :trigger_element_id, deprecated: true
|
9
9
|
prop :tooltip_id
|
10
|
+
prop :interaction, type: Playbook::Props::Boolean,
|
11
|
+
default: false
|
12
|
+
prop :delay_open
|
13
|
+
prop :delay_close
|
10
14
|
prop :dark, type: Playbook::Props::Boolean,
|
11
15
|
default: false
|
12
16
|
prop :trigger_method, type: Playbook::Props::Enum,
|
@@ -18,15 +22,19 @@ module Playbook
|
|
18
22
|
end
|
19
23
|
|
20
24
|
def data
|
21
|
-
Hash(values[:data]).merge(
|
25
|
+
data = Hash(values[:data]).merge(
|
22
26
|
pb_tooltip_kit: true,
|
23
27
|
pb_tooltip_position: position,
|
24
28
|
pb_tooltip_trigger_element_selector: trigger_element_selector,
|
25
29
|
pb_tooltip_trigger_element_id: trigger_element_id,
|
26
30
|
pb_tooltip_tooltip_id: tooltip_id,
|
27
31
|
pb_tooltip_show_tooltip: true,
|
28
|
-
pb_tooltip_trigger_method: trigger_method
|
32
|
+
pb_tooltip_trigger_method: trigger_method,
|
33
|
+
pb_tooltip_interaction: interaction
|
29
34
|
)
|
35
|
+
data = data.merge(pb_tooltip_delay_open: delay_open) if delay_open
|
36
|
+
data = data.merge(pb_tooltip_delay_close: delay_close) if delay_close
|
37
|
+
data
|
30
38
|
end
|
31
39
|
|
32
40
|
private
|