playbook_ui 10.19.0.pre.lightbox → 10.19.0.pre.popover.alpha1
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/_playbook.scss +0 -1
- data/app/pb_kits/playbook/data/menu.yml +0 -1
- data/app/pb_kits/playbook/index.js +1 -2
- data/app/pb_kits/playbook/pb_button/_button.jsx +3 -3
- data/app/pb_kits/playbook/pb_button/_button.scss +17 -0
- data/app/pb_kits/playbook/pb_button/button.rb +6 -3
- data/app/pb_kits/playbook/pb_button/button.test.js +13 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_size.html.erb +3 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_size.jsx +26 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_size.md +1 -0
- data/app/pb_kits/playbook/pb_button/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_button/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_popover/_popover.jsx +2 -4
- data/app/pb_kits/playbook/pb_popover/docs/_popover_close.html.erb +7 -7
- data/app/pb_kits/playbook/pb_popover/index.js +4 -9
- data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +3 -3
- data/app/pb_kits/playbook/pb_title/title.html.erb +3 -2
- data/app/pb_kits/playbook/playbook-doc.js +0 -2
- data/lib/playbook/version.rb +1 -1
- metadata +5 -21
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Slide.jsx +0 -53
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Slides.jsx +0 -54
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnail.jsx +0 -39
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnails.jsx +0 -82
- data/app/pb_kits/playbook/pb_lightbox/Carousel/index.jsx +0 -54
- data/app/pb_kits/playbook/pb_lightbox/Carousel/styles.scss +0 -110
- data/app/pb_kits/playbook/pb_lightbox/Carousel/useSlides.js +0 -66
- data/app/pb_kits/playbook/pb_lightbox/Carousel/useUnscrollableBody.js +0 -11
- data/app/pb_kits/playbook/pb_lightbox/_lightbox.jsx +0 -81
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.jsx +0 -65
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.md +0 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_multiple.jsx +0 -65
- data/app/pb_kits/playbook/pb_lightbox/docs/example.yml +0 -6
- data/app/pb_kits/playbook/pb_lightbox/docs/index.js +0 -2
- data/app/pb_kits/playbook/pb_lightbox/hooks/useToggler.js +0 -10
- data/app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js +0 -21
- data/app/pb_kits/playbook/pb_lightbox/hooks/useWindowSize.js +0 -25
- data/app/pb_kits/playbook/pb_lightbox/lightbox.scss +0 -92
- data/app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '090e97cafaabff3f06f58cca0ce4a1416d09f6baea9f828e51c93059f279f292'
|
4
|
+
data.tar.gz: 580359a862a8567240f9759e2ab80b708688d528ddc054789e6f658352cc21e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85c349d66339b000e6d7cb9077621b9e8d40852538d6e9eb7111947fabd0df9e11b3d2448a67609727c9fb915393ddf903140f43375be0947d5d749ffb6fb85a
|
7
|
+
data.tar.gz: b3774dfcbf0315c3b2fde5e145e7e0e33c3ceb23e5371aa01120ccca6f7294e7883e1f19c89dc73cdc3af2664d7b3484f0d9de5835119e862424902ee153bbc9
|
@@ -4,6 +4,7 @@ import 'lazysizes/plugins/attrchange/ls.attrchange'
|
|
4
4
|
import 'lazysizes'
|
5
5
|
|
6
6
|
// vvv React Component JSX Imports from the React Kits vvv
|
7
|
+
export { default as Walkthrough } from './pb_walkthrough/_walkthrough'
|
7
8
|
export { default as Avatar } from './pb_avatar/_avatar'
|
8
9
|
export { default as AvatarActionButton } from './pb_avatar_action_button/_avatar_action_button'
|
9
10
|
export { default as Background } from './pb_background/_background'
|
@@ -54,7 +55,6 @@ export { default as Layout } from './pb_layout/_layout'
|
|
54
55
|
export { default as Legend } from './pb_legend/_legend'
|
55
56
|
export { default as LineGraph } from './pb_line_graph/_line_graph'
|
56
57
|
export { default as List } from './pb_list/_list'
|
57
|
-
export { default as Lightbox } from './pb_lightbox/_lightbox'
|
58
58
|
export { default as ListItem } from './pb_list/_list_item'
|
59
59
|
export { default as LoadingInline } from './pb_loading_inline/_loading_inline'
|
60
60
|
export { default as Message } from './pb_message/_message'
|
@@ -101,7 +101,6 @@ export { default as Toggle } from './pb_toggle/_toggle'
|
|
101
101
|
export { default as Typeahead } from './pb_typeahead/_typeahead'
|
102
102
|
export { default as User } from './pb_user/_user'
|
103
103
|
export { default as UserBadge } from './pb_user_badge/_user_badge'
|
104
|
-
export { default as Walkthrough } from './pb_walkthrough/_walkthrough'
|
105
104
|
export { default as WeekdayStacked } from './pb_weekday_stacked/_weekday_stacked'
|
106
105
|
// ^^^ React Component JSX Imports from the React Kits ^^^
|
107
106
|
|
@@ -22,7 +22,7 @@ type ButtonPropTypes = {
|
|
22
22
|
loading?: boolean,
|
23
23
|
newWindow?: boolean,
|
24
24
|
onClick?: EventHandler,
|
25
|
-
size
|
25
|
+
size?: 'sm' | 'md' | 'lg',
|
26
26
|
text?: string,
|
27
27
|
type: 'inline' | null,
|
28
28
|
htmlType: string | 'button',
|
@@ -36,16 +36,16 @@ const buttonClassName = (props: ButtonPropTypes) => {
|
|
36
36
|
disabled = false,
|
37
37
|
fullWidth = false,
|
38
38
|
loading = false,
|
39
|
-
size = null,
|
40
39
|
type = 'inline',
|
41
40
|
variant = 'primary',
|
41
|
+
size = null,
|
42
42
|
} = props
|
43
43
|
|
44
44
|
let className = 'pb_button_kit'
|
45
45
|
|
46
|
+
className += `${size !== null ? `_${size}` : ''}`
|
46
47
|
className += `${variant !== null ? `_${variant}` : ''}`
|
47
48
|
className += `${type !== null ? `_${type}` : ''}`
|
48
|
-
className += `${size !== null ? `_${size}` : ''}`
|
49
49
|
className += `${fullWidth ? '_block' : ''}`
|
50
50
|
className += disabled ? '_disabled' : '_enabled'
|
51
51
|
className += loading ? '_loading' : ''
|
@@ -1,7 +1,24 @@
|
|
1
1
|
@import "./button_mixins";
|
2
2
|
|
3
|
+
$pb_button_sizes: (
|
4
|
+
"sm": 0.75rem,
|
5
|
+
"md": 0.875rem,
|
6
|
+
"lg": 1.125rem,
|
7
|
+
);
|
8
|
+
|
3
9
|
[class^=pb_button_kit]{
|
4
10
|
@include pb_button;
|
11
|
+
// Size =================
|
12
|
+
@each $name, $size in $pb_button_sizes {
|
13
|
+
&[class*=_#{$name}] {
|
14
|
+
font-size: $size;
|
15
|
+
padding: calc(#{$size} / 2) calc(#{$size} * 2.42) !important;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
&[class*=_sm] {
|
19
|
+
min-height: 0;
|
20
|
+
}
|
21
|
+
|
5
22
|
// Variants =================
|
6
23
|
&[class*=_primary] {
|
7
24
|
@include pb_button_primary;
|
@@ -18,6 +18,9 @@ module Playbook
|
|
18
18
|
prop :text
|
19
19
|
prop :type
|
20
20
|
prop :value
|
21
|
+
prop :size, type: Playbook::Props::Enum,
|
22
|
+
values: ["sm", "md", "lg", nil],
|
23
|
+
default: nil
|
21
24
|
|
22
25
|
def options
|
23
26
|
{
|
@@ -44,12 +47,12 @@ module Playbook
|
|
44
47
|
link ? "a" : "button"
|
45
48
|
end
|
46
49
|
|
47
|
-
private
|
48
|
-
|
49
50
|
def classname
|
50
|
-
generate_classname("pb_button_kit", variant, full_width_class, disabled_class, loading_class)
|
51
|
+
generate_classname("pb_button_kit", size, variant, full_width_class, disabled_class, loading_class)
|
51
52
|
end
|
52
53
|
|
54
|
+
private
|
55
|
+
|
53
56
|
def disabled_class
|
54
57
|
disabled ? "disabled" : "enabled"
|
55
58
|
end
|
@@ -89,3 +89,16 @@ test('click event', async () => {
|
|
89
89
|
|
90
90
|
expect(screen.getByText('clicked button!')).toBeInTheDocument()
|
91
91
|
})
|
92
|
+
|
93
|
+
test('size prop', () => {
|
94
|
+
render(
|
95
|
+
<Button
|
96
|
+
data={{ testid: 'size-test' }}
|
97
|
+
size="sm"
|
98
|
+
/>
|
99
|
+
)
|
100
|
+
|
101
|
+
const kit = screen.getByTestId('size-test')
|
102
|
+
|
103
|
+
expect(kit).toHaveClass('pb_button_kit_sm_primary_inline_enabled')
|
104
|
+
})
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { Button } from '../../'
|
3
|
+
|
4
|
+
const ButtonSize = (props) => (
|
5
|
+
<div>
|
6
|
+
<Button
|
7
|
+
size="sm"
|
8
|
+
text="Button sm size"
|
9
|
+
{...props}
|
10
|
+
/>
|
11
|
+
{' '}
|
12
|
+
<Button
|
13
|
+
size="md"
|
14
|
+
text="Button md size"
|
15
|
+
{...props}
|
16
|
+
/>
|
17
|
+
{' '}
|
18
|
+
<Button
|
19
|
+
size="lg"
|
20
|
+
text="Button lg size"
|
21
|
+
{...props}
|
22
|
+
/>
|
23
|
+
</div>
|
24
|
+
)
|
25
|
+
|
26
|
+
export default ButtonSize
|
@@ -0,0 +1 @@
|
|
1
|
+
By default button has the `md` size style, even if you don't explicitly pass a size prop.
|
@@ -7,6 +7,7 @@ examples:
|
|
7
7
|
- button_block_content: Button Block Content
|
8
8
|
- button_accessibility: Button Accessibility Options
|
9
9
|
- button_options: Button Additional Options
|
10
|
+
- button_size: Button Size
|
10
11
|
react:
|
11
12
|
- button_default: Button Variants
|
12
13
|
- button_full_width: Button Full Width
|
@@ -15,3 +16,4 @@ examples:
|
|
15
16
|
- button_block_content: Button Block Content
|
16
17
|
- button_accessibility: Button Accessibility Options
|
17
18
|
- button_options: Button Additional Options (onClick)
|
19
|
+
- button_size: Button Size
|
@@ -5,3 +5,4 @@ export { default as ButtonLoading } from './_button_loading.jsx'
|
|
5
5
|
export { default as ButtonBlockContent } from './_button_block_content.jsx'
|
6
6
|
export { default as ButtonAccessibility } from './_button_accessibility.jsx'
|
7
7
|
export { default as ButtonOptions } from './_button_options.jsx'
|
8
|
+
export { default as ButtonSize } from './_button_size.jsx'
|
@@ -150,16 +150,14 @@ export default class PbReactPopover extends React.Component<PbPopoverProps> {
|
|
150
150
|
const targetIsReference =
|
151
151
|
target.closest('.pb_popover_reference_wrapper') !== null
|
152
152
|
|
153
|
-
if (targetIsReference) return
|
154
|
-
|
155
153
|
switch (closeOnClick) {
|
156
154
|
case 'outside':
|
157
|
-
if (!targetIsPopover) {
|
155
|
+
if (!targetIsPopover || targetIsReference) {
|
158
156
|
shouldClosePopover(true)
|
159
157
|
}
|
160
158
|
break
|
161
159
|
case 'inside':
|
162
|
-
if (targetIsPopover) {
|
160
|
+
if (targetIsPopover || targetIsReference) {
|
163
161
|
shouldClosePopover(true)
|
164
162
|
}
|
165
163
|
break
|
@@ -1,23 +1,23 @@
|
|
1
1
|
<%= pb_rails("flex", props: {classname: "flex-container", spacing: "between"}) do %>
|
2
2
|
<span>
|
3
|
-
<%= pb_rails("button", props: { text: "Click Inside", variant: "secondary", id:
|
3
|
+
<%= pb_rails("button", props: { text: "Click Inside", variant: "secondary", id: "inside-popover-1" }) %>
|
4
4
|
<%= pb_rails("popover", props: {
|
5
5
|
close_on_click: "inside",
|
6
6
|
trigger_element_id: "inside-popover-1",
|
7
7
|
tooltip_id: "inside-tooltip-1",
|
8
|
-
position:
|
8
|
+
position: "bottom",
|
9
9
|
offset: true
|
10
10
|
}) do %>
|
11
11
|
Click on me!
|
12
12
|
<% end %>
|
13
13
|
</span>
|
14
14
|
<span>
|
15
|
-
<%= pb_rails("button", props: { text: "Click Outside", variant: "secondary", id:
|
15
|
+
<%= pb_rails("button", props: { text: "Click Outside", variant: "secondary", id: "outside-popover-1" }) %>
|
16
16
|
<%= pb_rails("popover", props: {
|
17
17
|
close_on_click: "outside",
|
18
18
|
trigger_element_id: "outside-popover-1",
|
19
19
|
tooltip_id: "outside-tooltip-1",
|
20
|
-
position:
|
20
|
+
position: "left",
|
21
21
|
offset: true
|
22
22
|
}) do %>
|
23
23
|
Click anywhere but me!
|
@@ -27,16 +27,16 @@
|
|
27
27
|
<%= pb_rails("button", props: {
|
28
28
|
text: "Click Anywhere",
|
29
29
|
variant: "secondary",
|
30
|
-
id:
|
30
|
+
id: "any-popover-1"
|
31
31
|
}) %>
|
32
32
|
<%= pb_rails("popover", props: {
|
33
33
|
close_on_click: "any",
|
34
34
|
trigger_element_id: "any-popover-1",
|
35
35
|
tooltip_id: "any-tooltip-1",
|
36
|
-
position:
|
36
|
+
position: "top",
|
37
37
|
offset: true
|
38
38
|
}) do %>
|
39
39
|
Click anything!
|
40
40
|
<% end %>
|
41
41
|
</span>
|
42
|
-
<% end %>
|
42
|
+
<% end %>
|
@@ -36,15 +36,14 @@ export default class PbPopover extends PbEnhancedElement {
|
|
36
36
|
}
|
37
37
|
|
38
38
|
setTimeout(() => {
|
39
|
-
this.popper.update()
|
40
39
|
this.toggleTooltip()
|
40
|
+
this.popper.update()
|
41
41
|
}, 0)
|
42
42
|
})
|
43
43
|
}
|
44
44
|
|
45
45
|
checkCloseTooltip() {
|
46
46
|
document.querySelector('body').addEventListener('click', ({ target }) => {
|
47
|
-
const isTriggerElement = target.closest(`#${this.triggerElementId}`) !== null
|
48
47
|
const isTooltipElement = target.closest(`#${this.tooltipId}`) !== null
|
49
48
|
|
50
49
|
switch (this.closeOnClick) {
|
@@ -52,21 +51,17 @@ export default class PbPopover extends PbEnhancedElement {
|
|
52
51
|
this.hideTooltip()
|
53
52
|
break
|
54
53
|
case 'outside':
|
55
|
-
if (isTooltipElement) {
|
56
|
-
this.checkCloseTooltip()
|
57
|
-
} else {
|
54
|
+
if (!isTooltipElement) {
|
58
55
|
this.hideTooltip()
|
59
56
|
}
|
60
57
|
break
|
61
58
|
case 'inside':
|
62
|
-
if (isTooltipElement
|
59
|
+
if (isTooltipElement) {
|
63
60
|
this.hideTooltip()
|
64
|
-
} else {
|
65
|
-
this.checkCloseTooltip()
|
66
61
|
}
|
67
62
|
break
|
68
63
|
}
|
69
|
-
}, { once: true })
|
64
|
+
}, { once: true, capture: true })
|
70
65
|
}
|
71
66
|
|
72
67
|
hideTooltip() {
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class: object.classname,
|
4
4
|
data: object.data,
|
5
5
|
id: object.id) do %>
|
6
|
-
<div class="pb_popover_tooltip" id="<%= object.tooltip_id %>" role="tooltip" style="<%= object.z_index_helper %>">
|
6
|
+
<div class="pb_popover_tooltip hide" id="<%= object.tooltip_id %>" role="tooltip" style="<%= object.z_index_helper %>">
|
7
7
|
<div class="pb_popover_body <%= object.width_height_class_helper %> <%= object.popover_spacing_helper %>" style="<%= object.width_height_helper %>">
|
8
8
|
<%= content.presence %>
|
9
9
|
</div>
|
@@ -92,13 +92,13 @@
|
|
92
92
|
.add-on {
|
93
93
|
&-right {
|
94
94
|
.add-on-card {
|
95
|
-
border: 1px solid
|
95
|
+
border: 1px solid red;
|
96
96
|
border-left: 0;
|
97
97
|
}
|
98
98
|
}
|
99
99
|
&-left {
|
100
100
|
.add-on-card {
|
101
|
-
border: 1px solid
|
101
|
+
border: 1px solid red;
|
102
102
|
border-right: 0;
|
103
103
|
}
|
104
104
|
}
|
@@ -169,7 +169,7 @@
|
|
169
169
|
&-card {
|
170
170
|
height: 45px;
|
171
171
|
margin: 0;
|
172
|
-
padding: 0
|
172
|
+
padding: 0;
|
173
173
|
align-items: center;
|
174
174
|
justify-content: center;
|
175
175
|
width: 45px;
|
@@ -51,7 +51,6 @@ import * as LabelPill from 'pb_label_pill/docs'
|
|
51
51
|
import * as LabelValue from 'pb_label_value/docs'
|
52
52
|
import * as Layout from 'pb_layout/docs'
|
53
53
|
import * as LegendDocs from 'pb_legend/docs'
|
54
|
-
import * as Lightbox from 'pb_lightbox/docs'
|
55
54
|
import * as LineGraphDocs from 'pb_line_graph/docs'
|
56
55
|
import * as List from 'pb_list/docs'
|
57
56
|
import * as LoadingInline from 'pb_loading_inline/docs'
|
@@ -146,7 +145,6 @@ WebpackerReact.setup({
|
|
146
145
|
...LabelValue,
|
147
146
|
...Layout,
|
148
147
|
...LegendDocs,
|
149
|
-
...Lightbox,
|
150
148
|
...LineGraphDocs,
|
151
149
|
...List,
|
152
150
|
...LoadingInline,
|
data/lib/playbook/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playbook_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.19.0.pre.
|
4
|
+
version: 10.19.0.pre.popover.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Power UX
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-01-
|
12
|
+
date: 2022-01-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -426,6 +426,9 @@ files:
|
|
426
426
|
- app/pb_kits/playbook/pb_button/docs/_button_loading.md
|
427
427
|
- app/pb_kits/playbook/pb_button/docs/_button_options.html.erb
|
428
428
|
- app/pb_kits/playbook/pb_button/docs/_button_options.jsx
|
429
|
+
- app/pb_kits/playbook/pb_button/docs/_button_size.html.erb
|
430
|
+
- app/pb_kits/playbook/pb_button/docs/_button_size.jsx
|
431
|
+
- app/pb_kits/playbook/pb_button/docs/_button_size.md
|
429
432
|
- app/pb_kits/playbook/pb_button/docs/_footer.md
|
430
433
|
- app/pb_kits/playbook/pb_button/docs/example.yml
|
431
434
|
- app/pb_kits/playbook/pb_button/docs/index.js
|
@@ -1168,25 +1171,6 @@ files:
|
|
1168
1171
|
- app/pb_kits/playbook/pb_legend/docs/index.js
|
1169
1172
|
- app/pb_kits/playbook/pb_legend/legend.html.erb
|
1170
1173
|
- app/pb_kits/playbook/pb_legend/legend.rb
|
1171
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/Slide.jsx
|
1172
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/Slides.jsx
|
1173
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnail.jsx
|
1174
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnails.jsx
|
1175
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/index.jsx
|
1176
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/styles.scss
|
1177
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/useSlides.js
|
1178
|
-
- app/pb_kits/playbook/pb_lightbox/Carousel/useUnscrollableBody.js
|
1179
|
-
- app/pb_kits/playbook/pb_lightbox/_lightbox.jsx
|
1180
|
-
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.jsx
|
1181
|
-
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.md
|
1182
|
-
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_multiple.jsx
|
1183
|
-
- app/pb_kits/playbook/pb_lightbox/docs/example.yml
|
1184
|
-
- app/pb_kits/playbook/pb_lightbox/docs/index.js
|
1185
|
-
- app/pb_kits/playbook/pb_lightbox/hooks/useToggler.js
|
1186
|
-
- app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js
|
1187
|
-
- app/pb_kits/playbook/pb_lightbox/hooks/useWindowSize.js
|
1188
|
-
- app/pb_kits/playbook/pb_lightbox/lightbox.scss
|
1189
|
-
- app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx
|
1190
1174
|
- app/pb_kits/playbook/pb_line_graph/_line_graph.jsx
|
1191
1175
|
- app/pb_kits/playbook/pb_line_graph/_line_graph.scss
|
1192
1176
|
- app/pb_kits/playbook/pb_line_graph/docs/_description.md
|
@@ -1,53 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
|
-
import React from 'react'
|
4
|
-
import { noop } from 'lodash'
|
5
|
-
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch'
|
6
|
-
|
7
|
-
import styles from './styles.scss'
|
8
|
-
|
9
|
-
type SlideType = {
|
10
|
-
alt: string,
|
11
|
-
current: number,
|
12
|
-
onClick: () => void,
|
13
|
-
onChange: (index: number) => void,
|
14
|
-
onZoom: (zoom: number) => void,
|
15
|
-
zooming: boolean,
|
16
|
-
url: string,
|
17
|
-
}
|
18
|
-
|
19
|
-
export default function Slide({
|
20
|
-
alt,
|
21
|
-
onClick = noop,
|
22
|
-
onZoom = noop,
|
23
|
-
url,
|
24
|
-
zooming = false,
|
25
|
-
}: SlideType) {
|
26
|
-
const handlePinchingStop = (e) => {
|
27
|
-
const isZooming = e.state.scale > 1
|
28
|
-
onZoom(isZooming)
|
29
|
-
}
|
30
|
-
|
31
|
-
return (
|
32
|
-
<TransformWrapper
|
33
|
-
doubleClick={{ mode: 'reset' }}
|
34
|
-
initialScale={1}
|
35
|
-
onPinchingStop={handlePinchingStop}
|
36
|
-
panning={{ disabled: !zooming }}
|
37
|
-
>
|
38
|
-
<button
|
39
|
-
className={styles.Slide}
|
40
|
-
onClick={onClick}
|
41
|
-
onDoubleClick={() => onZoom(false)}
|
42
|
-
tabIndex={-1}
|
43
|
-
>
|
44
|
-
<TransformComponent className={styles.TransformComponent}>
|
45
|
-
<img
|
46
|
-
alt={alt}
|
47
|
-
src={url}
|
48
|
-
/>
|
49
|
-
</TransformComponent>
|
50
|
-
</button>
|
51
|
-
</TransformWrapper>
|
52
|
-
)
|
53
|
-
}
|
@@ -1,54 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
|
-
import { noop } from 'lodash'
|
4
|
-
import { motion } from 'framer-motion/dist/framer-motion'
|
5
|
-
import React, { useState } from 'react'
|
6
|
-
|
7
|
-
import Slide from './Slide'
|
8
|
-
import styles from './styles.scss'
|
9
|
-
import useSlides from './useSlides'
|
10
|
-
|
11
|
-
type SlidesType = {
|
12
|
-
urls: Array<string>,
|
13
|
-
current: number,
|
14
|
-
onChange: (index: number) => void,
|
15
|
-
onClick: (index: number) => void,
|
16
|
-
}
|
17
|
-
|
18
|
-
export default function Slides({
|
19
|
-
urls = [],
|
20
|
-
current = 0,
|
21
|
-
onClick = noop,
|
22
|
-
onChange = noop,
|
23
|
-
}: SlidesType) {
|
24
|
-
const [zooming, setZooming] = useState(false)
|
25
|
-
const { controls, dragConstraints, handleDragEnd } = useSlides({
|
26
|
-
current,
|
27
|
-
pagesCount: urls.length,
|
28
|
-
onChange,
|
29
|
-
})
|
30
|
-
|
31
|
-
const handleZoom = (isZooming) => setZooming(isZooming)
|
32
|
-
|
33
|
-
return (
|
34
|
-
<motion.div
|
35
|
-
animate={controls}
|
36
|
-
className={styles.Slides}
|
37
|
-
drag={!zooming && 'x'}
|
38
|
-
dragConstraints={dragConstraints}
|
39
|
-
dragElastic={0.05}
|
40
|
-
onDragEnd={handleDragEnd}
|
41
|
-
transition={{ type: 'spring', bounce: 0 }}
|
42
|
-
>
|
43
|
-
{urls.map((url, i) => (
|
44
|
-
<Slide
|
45
|
-
key={i}
|
46
|
-
onClick={() => onClick(i)}
|
47
|
-
onZoom={handleZoom}
|
48
|
-
url={url}
|
49
|
-
zooming={zooming}
|
50
|
-
/>
|
51
|
-
))}
|
52
|
-
</motion.div>
|
53
|
-
)
|
54
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
|
-
import React from 'react'
|
4
|
-
import { noop } from 'lodash'
|
5
|
-
import classnames from 'classnames'
|
6
|
-
import Image from '../../pb_image/_image'
|
7
|
-
|
8
|
-
import styles from './styles.scss'
|
9
|
-
|
10
|
-
type ThumbnailType = {
|
11
|
-
active?: boolean,
|
12
|
-
alt?: string,
|
13
|
-
onClick: () => void,
|
14
|
-
url: string,
|
15
|
-
width?: string,
|
16
|
-
}
|
17
|
-
|
18
|
-
export default function Thumbnail({
|
19
|
-
active = false,
|
20
|
-
alt,
|
21
|
-
width,
|
22
|
-
url,
|
23
|
-
onClick = noop,
|
24
|
-
}: ThumbnailType) {
|
25
|
-
return (
|
26
|
-
<button
|
27
|
-
className={classnames(styles.Thumbnail, { [styles.active]: active })}
|
28
|
-
onClick={onClick}
|
29
|
-
style={{ width }}
|
30
|
-
type="button"
|
31
|
-
>
|
32
|
-
<Image
|
33
|
-
alt={alt}
|
34
|
-
size="sm"
|
35
|
-
url={url}
|
36
|
-
/>
|
37
|
-
</button>
|
38
|
-
)
|
39
|
-
}
|
@@ -1,82 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
|
3
|
-
import { noop } from 'lodash'
|
4
|
-
import classnames from 'classnames'
|
5
|
-
import React, { useEffect } from 'react'
|
6
|
-
import { motion, useAnimation } from 'framer-motion/dist/framer-motion'
|
7
|
-
import { useWindowSize } from '../hooks/useWindowSize'
|
8
|
-
|
9
|
-
import Thumbnail from './Thumbnail'
|
10
|
-
|
11
|
-
import styles from './styles.scss'
|
12
|
-
|
13
|
-
export const indexWithinBounds = (
|
14
|
-
current: number,
|
15
|
-
min: number,
|
16
|
-
max: number
|
17
|
-
): number => {
|
18
|
-
if (current < min) return 0
|
19
|
-
if (current > max) return max
|
20
|
-
return current
|
21
|
-
}
|
22
|
-
|
23
|
-
type ThumbnailsType = {
|
24
|
-
current: number,
|
25
|
-
onChange: () => null,
|
26
|
-
urls: [],
|
27
|
-
}
|
28
|
-
|
29
|
-
export default function Thumbnails({
|
30
|
-
current = 0,
|
31
|
-
onChange = noop,
|
32
|
-
urls = [],
|
33
|
-
}: ThumbnailsType) {
|
34
|
-
const controls = useAnimation()
|
35
|
-
const viewportSize = useWindowSize()
|
36
|
-
const thumbnailWidth = viewportSize.width / 8
|
37
|
-
const draggable = thumbnailWidth * urls.length > viewportSize.width
|
38
|
-
const css = classnames(styles.Thumbnails, {
|
39
|
-
[styles.draggable]: draggable,
|
40
|
-
})
|
41
|
-
const dragConstraints = {
|
42
|
-
left: -1 * (thumbnailWidth * urls.length - viewportSize.width),
|
43
|
-
right: 0,
|
44
|
-
}
|
45
|
-
|
46
|
-
const modifyTarget = (target) => {
|
47
|
-
const nextIndex = Math.round(Math.abs(target) / thumbnailWidth)
|
48
|
-
const snapTargetIndex = indexWithinBounds(nextIndex, 0, urls.length)
|
49
|
-
const snapTarget = snapTargetIndex * thumbnailWidth
|
50
|
-
const direction = Math.sign(target)
|
51
|
-
return direction * snapTarget
|
52
|
-
}
|
53
|
-
|
54
|
-
useEffect(() => {
|
55
|
-
if (draggable) {
|
56
|
-
const x = Math.max(-current * thumbnailWidth, dragConstraints.left)
|
57
|
-
controls.start({ x })
|
58
|
-
}
|
59
|
-
}, [controls, current, draggable, dragConstraints.left, thumbnailWidth])
|
60
|
-
|
61
|
-
return (
|
62
|
-
<motion.div
|
63
|
-
animate={controls}
|
64
|
-
className={css}
|
65
|
-
drag={draggable && 'x'}
|
66
|
-
dragConstraints={dragConstraints}
|
67
|
-
dragElastic={0.05}
|
68
|
-
dragTransition={{ modifyTarget }}
|
69
|
-
transition={{ type: 'spring', bounce: 0 }}
|
70
|
-
>
|
71
|
-
{urls.map((url, i) => (
|
72
|
-
<Thumbnail
|
73
|
-
active={i === current}
|
74
|
-
alt={i}
|
75
|
-
key={i}
|
76
|
-
onClick={() => onChange(i)}
|
77
|
-
url={url}
|
78
|
-
/>
|
79
|
-
))}
|
80
|
-
</motion.div>
|
81
|
-
)
|
82
|
-
}
|