playbook_ui 12.16.0.pre.alpha.lightboxcurrentphotoprop531 → 12.16.0.pre.alpha.tiptaptestingpart1528
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/pb_lightbox/Carousel/index.tsx +1 -0
- data/app/pb_kits/playbook/pb_lightbox/_lightbox.tsx +4 -7
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_compound_component.jsx +5 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_custom_header.jsx +5 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.jsx +5 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.md +1 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_multiple.jsx +5 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_lightbox/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_lightbox/lightbox.test.jsx +5 -1
- data/app/pb_kits/playbook/pb_nav/_item.tsx +6 -6
- data/app/pb_kits/playbook/pb_nav/_nav.tsx +2 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx +49 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorTypes.ts +9 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +62 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +128 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx +45 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx +59 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +23 -9
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +192 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +36 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +1 -0
- data/lib/playbook/version.rb +1 -1
- metadata +10 -4
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.jsx +0 -121
- data/app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.md +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4341c04235a54ee87163dc70611a3316292d39b9b1fdfbd18f2071918b5b52ba
|
4
|
+
data.tar.gz: 43730de1e579c36b56dd7d18683a22143170392ea4901b424d064333af087814
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3eefd540b9b47832aaaef279e5b6b30557d9bd3dcad56f0f0bba654d10916bfde828daa12a9b24ce41bfa9ff4678fc0bf6484491999b5997e98e98e0edbaa152
|
7
|
+
data.tar.gz: 0521a6ececeaf575787632b452b9b0ea8041d176be10dcb21c1e52868115fa1c7d8bc0e3f3137f958c73600aaef3bfc34ce932b7b80b408300ab51063079791f
|
@@ -12,11 +12,11 @@ type LightboxType = {
|
|
12
12
|
aria?: {[key: string]: string},
|
13
13
|
children: React.ReactNode[] | React.ReactNode | string,
|
14
14
|
className?: string,
|
15
|
-
currentPhotoIndex?: number,
|
16
15
|
data?: {[key: string]: string | number},
|
17
16
|
description?: string | any,
|
18
17
|
id?: string,
|
19
18
|
photos: [],
|
19
|
+
initialPhoto?: number,
|
20
20
|
onChange?: (index: number)=> {},
|
21
21
|
onClickRight?: () => void,
|
22
22
|
onClose?: () => void,
|
@@ -31,10 +31,10 @@ const Lightbox = (props: LightboxType): React.ReactNode => {
|
|
31
31
|
aria = {},
|
32
32
|
children,
|
33
33
|
className,
|
34
|
-
currentPhotoIndex,
|
35
34
|
data = {},
|
36
35
|
description,
|
37
36
|
id = '',
|
37
|
+
initialPhoto = 0,
|
38
38
|
photos,
|
39
39
|
onChange = ()=>{},
|
40
40
|
onClose,
|
@@ -44,15 +44,12 @@ const Lightbox = (props: LightboxType): React.ReactNode => {
|
|
44
44
|
title,
|
45
45
|
} = props
|
46
46
|
|
47
|
-
const [activePhoto, setActivePhoto] = useState(
|
47
|
+
const [activePhoto, setActivePhoto] = useState(initialPhoto)
|
48
|
+
|
48
49
|
useEffect(() => {
|
49
50
|
onChange(activePhoto)
|
50
51
|
},[activePhoto])
|
51
52
|
|
52
|
-
useEffect(() => {
|
53
|
-
setActivePhoto(currentPhotoIndex)
|
54
|
-
},[currentPhotoIndex])
|
55
|
-
|
56
53
|
const ariaProps = buildAriaProps(aria)
|
57
54
|
const dataProps = buildDataProps(data)
|
58
55
|
const classes = classnames(
|
@@ -10,14 +10,17 @@ const LightboxCompoundComponent = (props) => {
|
|
10
10
|
'https://images.unsplash.com/photo-1501045337096-542a73dafa4f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2052&q=80',
|
11
11
|
'https://images.unsplash.com/photo-1563693998336-93c10e5d8f91?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80,',
|
12
12
|
]
|
13
|
+
const [selectedPhoto, setSelectedPhoto] = useState(0)
|
13
14
|
const [showLightbox, toggleShowLightbox] = useState(false)
|
14
15
|
|
15
16
|
const handleCloseLightbox = () => {
|
16
17
|
toggleShowLightbox(!showLightbox)
|
18
|
+
setSelectedPhoto(null)
|
17
19
|
}
|
18
20
|
|
19
|
-
const onPhotoClick = () => {
|
21
|
+
const onPhotoClick = (photo) => {
|
20
22
|
toggleShowLightbox(!showLightbox)
|
23
|
+
setSelectedPhoto(photo)
|
21
24
|
}
|
22
25
|
|
23
26
|
const exampleStyles = {
|
@@ -31,6 +34,7 @@ const LightboxCompoundComponent = (props) => {
|
|
31
34
|
{showLightbox ? (
|
32
35
|
<Lightbox
|
33
36
|
description='Description Content Goes Here.'
|
37
|
+
initialPhoto={selectedPhoto}
|
34
38
|
onClose={handleCloseLightbox}
|
35
39
|
photos={photos}
|
36
40
|
title='Windows, Sidings, & Gutters'
|
@@ -10,14 +10,17 @@ const LightboxCustomHeader = (props) => {
|
|
10
10
|
"https://images.unsplash.com/photo-1501045337096-542a73dafa4f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2052&q=80",
|
11
11
|
"https://images.unsplash.com/photo-1563693998336-93c10e5d8f91?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80,",
|
12
12
|
];
|
13
|
+
const [selectedPhoto, setSelectedPhoto] = useState(0);
|
13
14
|
const [showLightbox, toggleShowLightbox] = useState(false);
|
14
15
|
|
15
16
|
const handleCloseLightbox = () => {
|
16
17
|
toggleShowLightbox(!showLightbox);
|
18
|
+
setSelectedPhoto(null);
|
17
19
|
};
|
18
20
|
|
19
|
-
const onPhotoClick = () => {
|
21
|
+
const onPhotoClick = (photo) => {
|
20
22
|
toggleShowLightbox(!showLightbox);
|
23
|
+
setSelectedPhoto(photo);
|
21
24
|
};
|
22
25
|
|
23
26
|
const exampleStyles = {
|
@@ -52,6 +55,7 @@ const LightboxCustomHeader = (props) => {
|
|
52
55
|
{showLightbox ? (
|
53
56
|
<Lightbox
|
54
57
|
description={customDescription}
|
58
|
+
initialPhoto={selectedPhoto}
|
55
59
|
navRight="All Photos"
|
56
60
|
onClickRight={()=> alert("Clicked!")}
|
57
61
|
onClose={handleCloseLightbox}
|
@@ -8,14 +8,17 @@ const LightboxDefault = (props) => {
|
|
8
8
|
const photos = [
|
9
9
|
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
10
10
|
]
|
11
|
+
const [selectedPhoto, setSelectedPhoto] = useState(0)
|
11
12
|
const [showLightbox, toggleShowLightbox] = useState(false)
|
12
13
|
|
13
14
|
const handleCloseLightbox = () => {
|
14
15
|
toggleShowLightbox(!showLightbox)
|
16
|
+
setSelectedPhoto(null)
|
15
17
|
}
|
16
18
|
|
17
|
-
const onPhotoClick = () => {
|
19
|
+
const onPhotoClick = (photoIndex) => {
|
18
20
|
toggleShowLightbox(!showLightbox)
|
21
|
+
setSelectedPhoto(photoIndex)
|
19
22
|
}
|
20
23
|
|
21
24
|
return (
|
@@ -24,6 +27,7 @@ const LightboxDefault = (props) => {
|
|
24
27
|
{showLightbox ? (
|
25
28
|
<Lightbox
|
26
29
|
icon="times"
|
30
|
+
initialPhoto={selectedPhoto}
|
27
31
|
onClose={handleCloseLightbox}
|
28
32
|
photos={photos}
|
29
33
|
{...props}
|
@@ -1 +1 @@
|
|
1
|
-
Lightbox contains several props: `photos` (an array of urls), `onClickLeft` (an optional callback function for top left close button), `title` and `description` (string or custom components), `icon` ( optional prop for the close button in the top left of the header), `navRight` (optional prop that renders clickable text in the top right section of the header), `onClickRight` (optional callback function of navRight) and `onChange` (optional event handler prop exposing index of current photo).
|
1
|
+
Lightbox contains several props: `photos` (an array of urls), `initialPhoto` (a number), `onClickLeft` (an optional callback function for top left close button), `title` and `description` (string or custom components), `icon` ( optional prop for the close button in the top left of the header), `navRight` (optional prop that renders clickable text in the top right section of the header), `onClickRight` (optional callback function of navRight) and `onChange` (optional event handler prop exposing index of current photo).
|
@@ -29,14 +29,17 @@ const LightboxMultiple = (props) => {
|
|
29
29
|
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
30
30
|
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
31
31
|
]
|
32
|
+
const [selectedPhoto, setSelectedPhoto] = useState(0)
|
32
33
|
const [light, toggleLight] = useState(false)
|
33
34
|
|
34
35
|
const handleCloseLightbox = () => {
|
35
36
|
toggleLight(!light)
|
37
|
+
setSelectedPhoto(null)
|
36
38
|
}
|
37
39
|
|
38
|
-
const onPhotoClick = () => {
|
40
|
+
const onPhotoClick = (photo) => {
|
39
41
|
toggleLight(!light)
|
42
|
+
setSelectedPhoto(photo)
|
40
43
|
}
|
41
44
|
|
42
45
|
const exampleStyles = {
|
@@ -49,6 +52,7 @@ const LightboxMultiple = (props) => {
|
|
49
52
|
{light ? (
|
50
53
|
<Lightbox
|
51
54
|
icon="times"
|
55
|
+
initialPhoto={selectedPhoto}
|
52
56
|
onChange={(index) => console.log(`current photo index: ${index}`)}
|
53
57
|
onClose={handleCloseLightbox}
|
54
58
|
photos={photos}
|
@@ -2,4 +2,3 @@ export { default as LightboxDefault } from './_lightbox_default.jsx'
|
|
2
2
|
export { default as LightboxMultiple } from './_lightbox_multiple.jsx'
|
3
3
|
export { default as LightboxCompoundComponent } from './_lightbox_compound_component.jsx'
|
4
4
|
export { default as LightboxCustomHeader } from './_lightbox_custom_header'
|
5
|
-
export { default as LightboxCurrentPhoto } from './_lightbox_current_photo'
|
@@ -18,6 +18,7 @@ test('Kit renders', () => {
|
|
18
18
|
data={{ testid: testId }}
|
19
19
|
icon="close"
|
20
20
|
id="test1"
|
21
|
+
initialPhoto={1}
|
21
22
|
onClose={() => {}}
|
22
23
|
photos={TEST_PHOTOS}
|
23
24
|
/>
|
@@ -34,6 +35,7 @@ test('Shows selected images', () => {
|
|
34
35
|
data={{ testid: testId }}
|
35
36
|
icon="close"
|
36
37
|
id="test1"
|
38
|
+
initialPhoto={1}
|
37
39
|
onClose={() => {}}
|
38
40
|
photos={TEST_PHOTOS}
|
39
41
|
/>
|
@@ -41,7 +43,7 @@ test('Shows selected images', () => {
|
|
41
43
|
const kit = screen.getByTestId(testId)
|
42
44
|
const slide = kit.getElementsByClassName('Slide')[0]
|
43
45
|
const image = slide.getElementsByTagName('img')[0]
|
44
|
-
expect(image).toHaveAttribute('src', TEST_PHOTOS[
|
46
|
+
expect(image).toHaveAttribute('src', TEST_PHOTOS[1])
|
45
47
|
|
46
48
|
const thumbnails = kit.getElementsByClassName('Thumbnail')
|
47
49
|
|
@@ -75,6 +77,7 @@ test('Closes on escape key', async () => {
|
|
75
77
|
data={{ testid: testId }}
|
76
78
|
icon="close"
|
77
79
|
id="test1"
|
80
|
+
initialPhoto={0}
|
78
81
|
onClose={mockClose}
|
79
82
|
photos={TEST_PHOTOS}
|
80
83
|
/>
|
@@ -103,6 +106,7 @@ test('Closes on close button', async () => {
|
|
103
106
|
data={{ testid: testId }}
|
104
107
|
icon="close"
|
105
108
|
id="test1"
|
109
|
+
initialPhoto={0}
|
106
110
|
onClose={mockClose}
|
107
111
|
photos={TEST_PHOTOS}
|
108
112
|
/>
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
2
2
|
import classnames from 'classnames'
|
3
3
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
5
|
-
import { globalProps } from '../utilities/globalProps'
|
5
|
+
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
6
6
|
|
7
7
|
import Icon from '../pb_icon/_icon'
|
8
8
|
import Image from '../pb_image/_image'
|
@@ -13,15 +13,15 @@ type NavItemProps = {
|
|
13
13
|
children?: React.ReactNode[] | React.ReactNode,
|
14
14
|
className?: string,
|
15
15
|
data?: object,
|
16
|
-
iconLeft
|
17
|
-
iconRight
|
16
|
+
iconLeft?: string,
|
17
|
+
iconRight?: string,
|
18
18
|
id?: string,
|
19
|
-
imageUrl
|
20
|
-
link
|
19
|
+
imageUrl?: string,
|
20
|
+
link?: string,
|
21
21
|
onClick?: React.MouseEventHandler<HTMLElement>,
|
22
22
|
target?: '_blank' | '_self' | '_parent' | '_top',
|
23
23
|
text: string,
|
24
|
-
}
|
24
|
+
} & GlobalProps
|
25
25
|
|
26
26
|
const NavItem = (props: NavItemProps) => {
|
27
27
|
const {
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import React from "react";
|
2
|
+
|
3
|
+
import Icon from "../../pb_icon/_icon";
|
4
|
+
import Flex from "../../pb_flex/_flex";
|
5
|
+
import Tooltip from "../../pb_tooltip/_tooltip";
|
6
|
+
|
7
|
+
|
8
|
+
type EditorButtonProps = {
|
9
|
+
classname?: string,
|
10
|
+
onclick?: () => {} | void,
|
11
|
+
icon?: string;
|
12
|
+
text?: string;
|
13
|
+
disable?: boolean
|
14
|
+
};
|
15
|
+
|
16
|
+
const EditorButton = ({
|
17
|
+
classname,
|
18
|
+
disable,
|
19
|
+
onclick,
|
20
|
+
icon,
|
21
|
+
text,
|
22
|
+
}: EditorButtonProps) => {
|
23
|
+
return (
|
24
|
+
<Tooltip
|
25
|
+
delay={{
|
26
|
+
open: 2000
|
27
|
+
}}
|
28
|
+
interaction
|
29
|
+
placement="top"
|
30
|
+
text={text}
|
31
|
+
>
|
32
|
+
<button
|
33
|
+
className={classname}
|
34
|
+
onClick={onclick}
|
35
|
+
disabled={disable}
|
36
|
+
>
|
37
|
+
<Flex
|
38
|
+
align="center"
|
39
|
+
className="toolbar_button_icon"
|
40
|
+
justify="center"
|
41
|
+
>
|
42
|
+
<Icon icon={icon} size="lg" />
|
43
|
+
</Flex>
|
44
|
+
</button>
|
45
|
+
</Tooltip>
|
46
|
+
);
|
47
|
+
};
|
48
|
+
|
49
|
+
export default EditorButton
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import Background from "../../pb_background/_background";
|
3
|
+
import Flex from "../../pb_flex/_flex";
|
4
|
+
import FlexItem from "../../pb_flex/_flex_item";
|
5
|
+
import SectionSeparator from "../../pb_section_separator/_section_separator";
|
6
|
+
|
7
|
+
import EditorButton from "./EditorButton";
|
8
|
+
import ToolbarDropdown from "./ToolbarDropdown";
|
9
|
+
import ToolbarNodes from "./ToolbarNodes";
|
10
|
+
import { ToolbarTypes } from "./EditorTypes";
|
11
|
+
import ToolbarHistoryItems from "./ToolbarHistory";
|
12
|
+
|
13
|
+
const EditorToolbar = ({ editor }:any) => {
|
14
|
+
const toolbaritems = [
|
15
|
+
{
|
16
|
+
icon: "bold",
|
17
|
+
text: "Bold",
|
18
|
+
classname:`toolbar_button ${editor.isActive('bold') ? 'is-active' : ''}`,
|
19
|
+
onclick:()=>editor.chain().focus().toggleBold().run(),
|
20
|
+
},
|
21
|
+
{
|
22
|
+
icon: "italic",
|
23
|
+
text: "Italic",
|
24
|
+
classname:`toolbar_button ${editor.isActive('italic') ? 'is-active' : ''}`,
|
25
|
+
onclick:() => editor.chain().focus().toggleItalic().run(),
|
26
|
+
},
|
27
|
+
{
|
28
|
+
icon: "strikethrough",
|
29
|
+
text: "Strikethrough",
|
30
|
+
classname:`toolbar_button ${editor.isActive('strike') ? 'is-active' : ''}`,
|
31
|
+
onclick:() => editor.chain().focus().toggleStrike().run(),
|
32
|
+
},
|
33
|
+
]
|
34
|
+
|
35
|
+
return (
|
36
|
+
<Background backgroundColor="white" className="toolbar">
|
37
|
+
<Flex flex="0" justify="between" paddingX="sm" paddingY="xxs">
|
38
|
+
<FlexItem className="toolbar_block" displayFlex>
|
39
|
+
<ToolbarDropdown editor={editor}/>
|
40
|
+
<SectionSeparator orientation="vertical" />
|
41
|
+
{toolbaritems && toolbaritems.map(
|
42
|
+
({ icon, text, classname, onclick}:ToolbarTypes, index:number) => (
|
43
|
+
<EditorButton
|
44
|
+
classname={classname}
|
45
|
+
icon={icon}
|
46
|
+
key={index}
|
47
|
+
text={text}
|
48
|
+
onclick={onclick}
|
49
|
+
/>
|
50
|
+
)
|
51
|
+
)}
|
52
|
+
<SectionSeparator orientation="vertical" />
|
53
|
+
<ToolbarNodes editor={editor} />
|
54
|
+
</FlexItem>
|
55
|
+
<ToolbarHistoryItems editor={editor} />
|
56
|
+
</Flex>
|
57
|
+
{/* <SectionSeparator /> */}
|
58
|
+
</Background>
|
59
|
+
);
|
60
|
+
};
|
61
|
+
|
62
|
+
export default EditorToolbar
|
@@ -0,0 +1,128 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
|
3
|
+
import Flex from '../../pb_flex/_flex'
|
4
|
+
import PbReactPopover from '../../pb_popover/_popover'
|
5
|
+
import Button from '../../pb_button/_button'
|
6
|
+
import Icon from '../../pb_icon/_icon'
|
7
|
+
import Nav from '../../pb_nav/_nav'
|
8
|
+
import NavItem from '../../pb_nav/_item'
|
9
|
+
|
10
|
+
import { ToolbarTypes } from './EditorTypes'
|
11
|
+
|
12
|
+
const ToolbarDropdown = ({editor}: any) => {
|
13
|
+
const [showPopover, setShowPopover] = useState(false)
|
14
|
+
const [activeItem, setActiveItem] = useState({text: "Paragraph", icon: "paragraph"})
|
15
|
+
|
16
|
+
const toolbarDropdownItems = [
|
17
|
+
{
|
18
|
+
node: "paragraph",
|
19
|
+
icon: "paragraph",
|
20
|
+
isActive: editor.isActive("paragraph"),
|
21
|
+
text: "Paragraph",
|
22
|
+
onclick: () => editor.chain().focus().setParagraph().run(),
|
23
|
+
},
|
24
|
+
{
|
25
|
+
node: "heading-1",
|
26
|
+
icon: "h1",
|
27
|
+
isActive: editor.isActive("heading", {level: 1}),
|
28
|
+
text: "Heading 1",
|
29
|
+
onclick: () => editor.chain().focus().toggleHeading({level:1}).run(),
|
30
|
+
},
|
31
|
+
{
|
32
|
+
node: "heading-2",
|
33
|
+
icon: "h2",
|
34
|
+
isActive: editor.isActive("heading", {level: 2}),
|
35
|
+
text: "Heading 2",
|
36
|
+
onclick: () => editor.chain().focus().toggleHeading({level:2}).run(),
|
37
|
+
},
|
38
|
+
{
|
39
|
+
node: "heading-3",
|
40
|
+
icon: "h3",
|
41
|
+
isActive: editor.isActive("heading", {level: 3}),
|
42
|
+
text: "Heading 3",
|
43
|
+
onclick: () => editor.chain().focus().toggleHeading({level:3}).run(),
|
44
|
+
},
|
45
|
+
{
|
46
|
+
node: "bulletList",
|
47
|
+
icon: "list",
|
48
|
+
isActive: editor.isActive("bulletList"),
|
49
|
+
text: "Bullet List",
|
50
|
+
onclick: () => editor.chain().focus().toggleBulletList().run(),
|
51
|
+
},
|
52
|
+
{
|
53
|
+
node: "orderedList",
|
54
|
+
icon: "list-ol",
|
55
|
+
isActive: editor.isActive("orderedList"),
|
56
|
+
text: "Ordered List",
|
57
|
+
onclick: () => editor.chain().focus().toggleOrderedList().run()
|
58
|
+
,
|
59
|
+
},
|
60
|
+
{
|
61
|
+
node: "blockquote",
|
62
|
+
icon: "block-quote",
|
63
|
+
isActive: editor.isActive("blockquote"),
|
64
|
+
text: "Block Quote",
|
65
|
+
onclick: () => editor.chain().focus().toggleBlockquote().run(),
|
66
|
+
},
|
67
|
+
]
|
68
|
+
|
69
|
+
|
70
|
+
const handleTogglePopover = () => {
|
71
|
+
setShowPopover(true)
|
72
|
+
}
|
73
|
+
|
74
|
+
const handlePopoverClose = (shouldClosePopover: boolean) => {
|
75
|
+
setShowPopover(!shouldClosePopover)
|
76
|
+
}
|
77
|
+
|
78
|
+
const popoverReference = (
|
79
|
+
<Button className="editor-dropdown-button"
|
80
|
+
onClick={handleTogglePopover}
|
81
|
+
variant="secondary"
|
82
|
+
>
|
83
|
+
<Flex align="center"
|
84
|
+
key={activeItem ? activeItem.icon : toolbarDropdownItems[0].icon}
|
85
|
+
gap="xs"
|
86
|
+
>
|
87
|
+
<Icon icon={activeItem ? activeItem.icon : toolbarDropdownItems[0].icon} size='lg'/>
|
88
|
+
{activeItem.text}
|
89
|
+
<Flex
|
90
|
+
className={showPopover ? "fa-flip-vertical" : ""}
|
91
|
+
display="inline_flex"
|
92
|
+
>
|
93
|
+
<Icon
|
94
|
+
fixedWidth
|
95
|
+
icon="angle-down"
|
96
|
+
margin-left="xs"
|
97
|
+
/>
|
98
|
+
</Flex>
|
99
|
+
</Flex>
|
100
|
+
</Button>
|
101
|
+
)
|
102
|
+
|
103
|
+
return (
|
104
|
+
<PbReactPopover
|
105
|
+
closeOnClick='outside'
|
106
|
+
padding='none'
|
107
|
+
placement="bottom"
|
108
|
+
reference={popoverReference}
|
109
|
+
shouldClosePopover={handlePopoverClose}
|
110
|
+
show={showPopover}
|
111
|
+
>
|
112
|
+
<Nav variant="subtle">
|
113
|
+
{toolbarDropdownItems.map(({ icon, text, onclick, isActive}:ToolbarTypes, index:number) => (
|
114
|
+
<NavItem
|
115
|
+
cursor="pointer"
|
116
|
+
className={`pb_tiptap_toolbar_dropdown_list_item ${isActive ? "active" : ""}`}
|
117
|
+
iconLeft={icon}
|
118
|
+
key={`${text}_${index}`}
|
119
|
+
onClick={()=> {onclick(); setShowPopover(false); setActiveItem({text:text, icon:icon})}}
|
120
|
+
text={text}
|
121
|
+
/>
|
122
|
+
))}
|
123
|
+
</Nav>
|
124
|
+
</PbReactPopover>
|
125
|
+
)
|
126
|
+
}
|
127
|
+
|
128
|
+
export default ToolbarDropdown
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import FlexItem from "../../pb_flex/_flex_item";
|
3
|
+
import EditorButton from "./EditorButton";
|
4
|
+
import { ToolbarTypes } from "./EditorTypes";
|
5
|
+
|
6
|
+
const ToolbarHistoryItems = ({editor}:any) => {
|
7
|
+
|
8
|
+
const toolbarHistoryItems = [
|
9
|
+
{
|
10
|
+
classname: `toolbar_button`,
|
11
|
+
icon: "undo",
|
12
|
+
text: "Undo",
|
13
|
+
onclick: () => editor.chain().focus().undo().run(),
|
14
|
+
disable: !editor.can().chain().focus().undo().run()
|
15
|
+
},
|
16
|
+
{
|
17
|
+
classname: `toolbar_button`,
|
18
|
+
icon: "redo",
|
19
|
+
text: "Redo",
|
20
|
+
onclick: () => editor.chain().focus().redo().run(),
|
21
|
+
disable: !editor.can().chain().focus().redo().run()
|
22
|
+
},
|
23
|
+
];
|
24
|
+
|
25
|
+
return (
|
26
|
+
<>
|
27
|
+
<FlexItem displayFlex>
|
28
|
+
{toolbarHistoryItems.map(
|
29
|
+
({ onclick, classname, disable, icon, text }:ToolbarTypes, index:number) => (
|
30
|
+
<EditorButton
|
31
|
+
classname={classname}
|
32
|
+
onclick={onclick}
|
33
|
+
disable={disable}
|
34
|
+
icon={icon}
|
35
|
+
key={index}
|
36
|
+
text={text}
|
37
|
+
/>
|
38
|
+
)
|
39
|
+
)}
|
40
|
+
</FlexItem>
|
41
|
+
</>
|
42
|
+
)
|
43
|
+
}
|
44
|
+
|
45
|
+
export default ToolbarHistoryItems
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import React, {useCallback} from "react";
|
2
|
+
import EditorButton from "./EditorButton";
|
3
|
+
import { ToolbarTypes } from "./EditorTypes";
|
4
|
+
|
5
|
+
const ToolbarNodes = ({editor}:any) => {
|
6
|
+
|
7
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
8
|
+
const setLink = useCallback(() => {
|
9
|
+
const previousUrl = editor.getAttributes("link").href;
|
10
|
+
const url = window.prompt("URL", previousUrl);
|
11
|
+
|
12
|
+
// cancelled
|
13
|
+
if (url === null) {
|
14
|
+
return;
|
15
|
+
}
|
16
|
+
|
17
|
+
// empty
|
18
|
+
if (url === "") {
|
19
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
20
|
+
|
21
|
+
return;
|
22
|
+
}
|
23
|
+
|
24
|
+
// update link
|
25
|
+
editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
26
|
+
}, [editor]);
|
27
|
+
|
28
|
+
const toolbarNodesItems = [
|
29
|
+
{
|
30
|
+
onclick: () => editor.chain().focus().toggleCodeBlock().run(),
|
31
|
+
icon: "code",
|
32
|
+
isActive: editor.isActive("codeBlock"),
|
33
|
+
text: "Codeblock",
|
34
|
+
},
|
35
|
+
{
|
36
|
+
onclick: setLink,
|
37
|
+
icon: "link",
|
38
|
+
isActive: editor.isActive("link"),
|
39
|
+
text: "Link",
|
40
|
+
},
|
41
|
+
];
|
42
|
+
|
43
|
+
return (
|
44
|
+
<>
|
45
|
+
{toolbarNodesItems.map(({ onclick, icon, text, isActive }:ToolbarTypes, index:number) => (
|
46
|
+
<EditorButton
|
47
|
+
classname={`toolbar_button ${isActive ? 'is-active' : ''}`}
|
48
|
+
onclick={onclick}
|
49
|
+
icon={icon}
|
50
|
+
key={index}
|
51
|
+
text={text}
|
52
|
+
/>
|
53
|
+
))}
|
54
|
+
</>
|
55
|
+
)
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
export default ToolbarNodes
|
@@ -14,6 +14,7 @@ try {
|
|
14
14
|
} catch (_e) { /* do nothing */ }
|
15
15
|
|
16
16
|
import { TrixEditor } from "react-trix"
|
17
|
+
import EditorToolbar from './TipTap/Toolbar'
|
17
18
|
|
18
19
|
type Editor = {
|
19
20
|
attributeIsActive?: Function,
|
@@ -27,7 +28,9 @@ type Editor = {
|
|
27
28
|
|
28
29
|
type RichTextEditorProps = {
|
29
30
|
aria?: { [key: string]: string },
|
31
|
+
advancedEditor?: any,
|
30
32
|
toolbarBottom?: Boolean,
|
33
|
+
children?: React.ReactNode | React.ReactNode[]
|
31
34
|
className?: string,
|
32
35
|
data?: { [key: string]: string },
|
33
36
|
focus?: boolean,
|
@@ -45,7 +48,9 @@ type RichTextEditorProps = {
|
|
45
48
|
const RichTextEditor = (props: RichTextEditorProps) => {
|
46
49
|
const {
|
47
50
|
aria = {},
|
51
|
+
advancedEditor,
|
48
52
|
toolbarBottom = false,
|
53
|
+
children,
|
49
54
|
className,
|
50
55
|
data = {},
|
51
56
|
focus = false,
|
@@ -152,15 +157,24 @@ const RichTextEditor = (props: RichTextEditorProps) => {
|
|
152
157
|
{...dataProps}
|
153
158
|
className={css}
|
154
159
|
>
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
160
|
+
{
|
161
|
+
advancedEditor ? (
|
162
|
+
<div>
|
163
|
+
<EditorToolbar editor={advancedEditor}/>
|
164
|
+
{ children }
|
165
|
+
</div>
|
166
|
+
) : (
|
167
|
+
<TrixEditor
|
168
|
+
className=""
|
169
|
+
fileParamName={name}
|
170
|
+
mergeTags={[]}
|
171
|
+
onChange={onChange}
|
172
|
+
onEditorReady={handleOnEditorReady}
|
173
|
+
placeholder={placeholder}
|
174
|
+
value={value}
|
175
|
+
/>
|
176
|
+
)
|
177
|
+
}
|
164
178
|
</div>
|
165
179
|
)
|
166
180
|
}
|
@@ -0,0 +1,192 @@
|
|
1
|
+
@import "../tokens/border_radius";
|
2
|
+
@import "../tokens/colors";
|
3
|
+
@import "../tokens/spacing";
|
4
|
+
@import "../tokens/titles";
|
5
|
+
@import "../tokens/line_height";
|
6
|
+
@import "../tokens/typography";
|
7
|
+
@import "../tokens/shadows";
|
8
|
+
@import "../tokens/transition";
|
9
|
+
|
10
|
+
[class^="pb_rich_text_editor_kit"] {
|
11
|
+
.toolbar_button {
|
12
|
+
display: flex;
|
13
|
+
align-items: center;
|
14
|
+
background: $transparent;
|
15
|
+
border: none;
|
16
|
+
border-radius: $border_rad_heaviest;
|
17
|
+
color: $text_lt_light;
|
18
|
+
cursor: pointer;
|
19
|
+
&_icon {
|
20
|
+
width: $space_xl + 2;
|
21
|
+
height: $space_xl + 2;
|
22
|
+
}
|
23
|
+
&.open {
|
24
|
+
color: $primary;
|
25
|
+
}
|
26
|
+
&.active,
|
27
|
+
&:active {
|
28
|
+
color: $primary;
|
29
|
+
background-color: $bg_light;
|
30
|
+
}
|
31
|
+
&:hover:not([disabled]) {
|
32
|
+
background-color: $neutral_subtle;
|
33
|
+
}
|
34
|
+
&:disabled {
|
35
|
+
.pb_icon_kit {
|
36
|
+
color: $border_light;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
&:focus-visible {
|
40
|
+
outline: none !important;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
.toolbar {
|
45
|
+
border-radius: $border_rad_heaviest $border_rad_heaviest 0 0;
|
46
|
+
border: 1px solid $border_light;
|
47
|
+
overflow-x: auto;
|
48
|
+
&_block {
|
49
|
+
gap: $space_xs;
|
50
|
+
}
|
51
|
+
.editor-dropdown-button {
|
52
|
+
background: transparent;
|
53
|
+
border: none;
|
54
|
+
color: $text_lt_light;
|
55
|
+
cursor: pointer;
|
56
|
+
font-weight: $light;
|
57
|
+
padding: ($space_xs - 1) 0px;
|
58
|
+
width: $space_xl * 3;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
.ProseMirror {
|
63
|
+
background: $white;
|
64
|
+
border: 1px solid $border_light;
|
65
|
+
border-top-color: transparent;
|
66
|
+
border-bottom-right-radius: $border_rad_heaviest;
|
67
|
+
border-bottom-left-radius: $border_rad_heaviest;
|
68
|
+
height: 100%;
|
69
|
+
padding: 1rem 1.5rem 1.5rem 1.5rem;
|
70
|
+
line-height: $lh_loose;
|
71
|
+
:first-child {
|
72
|
+
margin-top: 0;
|
73
|
+
}
|
74
|
+
|
75
|
+
h4,
|
76
|
+
h5,
|
77
|
+
h6,
|
78
|
+
ul,
|
79
|
+
ol,
|
80
|
+
blockquote,
|
81
|
+
p {
|
82
|
+
margin: 1rem 0 0 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
code {
|
86
|
+
font-family: monospace;
|
87
|
+
background: $bg_light;
|
88
|
+
padding: 0.1rem 0.3rem;
|
89
|
+
margin: 0 5px;
|
90
|
+
box-shadow: 0 2px 10px $shadow;
|
91
|
+
border-radius: 0.25rem;
|
92
|
+
overflow: hidden;
|
93
|
+
font-size: ($text_small - 1px);
|
94
|
+
}
|
95
|
+
|
96
|
+
pre {
|
97
|
+
background: $bg_dark;
|
98
|
+
padding: $space_sm;
|
99
|
+
border-radius: $border_rad_heaviest;
|
100
|
+
margin: 1.5rem 0 2rem 0;
|
101
|
+
code {
|
102
|
+
background: transparent;
|
103
|
+
box-shadow: none;
|
104
|
+
border: 0;
|
105
|
+
color: #faf6e4;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
a {
|
109
|
+
color: $primary;
|
110
|
+
border-bottom: 1px solid $primary;
|
111
|
+
&:hover {
|
112
|
+
color: $text_lt_default;
|
113
|
+
border-bottom: 1px solid $text_lt_default;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
blockquote {
|
117
|
+
font-size: $font_larger;
|
118
|
+
padding: $space_sm $space_md;
|
119
|
+
font-style: italic;
|
120
|
+
p {
|
121
|
+
margin: 0;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
&:focus-visible {
|
125
|
+
outline: unset;
|
126
|
+
border-color: $primary;
|
127
|
+
@include transition_default;
|
128
|
+
}
|
129
|
+
h1 {
|
130
|
+
font-size: $text_larger;
|
131
|
+
line-height: $text_larger;
|
132
|
+
font-weight: $bolder;
|
133
|
+
letter-spacing: $lspace_tight;
|
134
|
+
margin: 2.1rem 0 0 0;
|
135
|
+
}
|
136
|
+
h2 {
|
137
|
+
font-size: $text_larger;
|
138
|
+
line-height: $text_larger;
|
139
|
+
font-weight: $bolder;
|
140
|
+
letter-spacing: $lspace_tight;
|
141
|
+
margin: 1.9rem 0 0 0;
|
142
|
+
}
|
143
|
+
h3 {
|
144
|
+
font-size: $text_large;
|
145
|
+
line-height: $text_large;
|
146
|
+
font-weight: $bolder;
|
147
|
+
letter-spacing: $lspace_tight;
|
148
|
+
margin: 1.7rem 0 0 0;
|
149
|
+
}
|
150
|
+
h4,
|
151
|
+
h5,
|
152
|
+
h6 {
|
153
|
+
font-size: $text_base;
|
154
|
+
line-height: $text_base;
|
155
|
+
letter-spacing: $lspace_tight;
|
156
|
+
font-weight: $bolder;
|
157
|
+
}
|
158
|
+
hr {
|
159
|
+
margin: 2.2rem 0;
|
160
|
+
box-sizing: content-box;
|
161
|
+
overflow: hidden;
|
162
|
+
background: transparent;
|
163
|
+
border-bottom: 1px solid $transparent;
|
164
|
+
height: 1px;
|
165
|
+
padding: 0;
|
166
|
+
background-color: $border_light;
|
167
|
+
border: 0;
|
168
|
+
}
|
169
|
+
ol {
|
170
|
+
margin: 1rem 0 0 0;
|
171
|
+
padding-left: $space_md;
|
172
|
+
list-style: decimal;
|
173
|
+
li {
|
174
|
+
margin: 2px 0;
|
175
|
+
p {
|
176
|
+
margin: 0;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
ul {
|
181
|
+
list-style-position: disc;
|
182
|
+
margin: 1rem 0 0 0;
|
183
|
+
padding-left: $space_md;
|
184
|
+
li {
|
185
|
+
margin: 2px 0;
|
186
|
+
p {
|
187
|
+
margin: 0;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { RichTextEditor } from '../..'
|
3
|
+
import { useEditor, EditorContent } from "@tiptap/react"
|
4
|
+
import StarterKit from "@tiptap/starter-kit"
|
5
|
+
import Link from '@tiptap/extension-link'
|
6
|
+
|
7
|
+
|
8
|
+
const RichTextEditorAdvancedDefault = (props) => {
|
9
|
+
|
10
|
+
const editor = useEditor({
|
11
|
+
extensions: [
|
12
|
+
StarterKit,
|
13
|
+
Link
|
14
|
+
],
|
15
|
+
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
16
|
+
})
|
17
|
+
if (!editor) {
|
18
|
+
return null
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
return (
|
25
|
+
<div>
|
26
|
+
<RichTextEditor
|
27
|
+
advancedEditor={editor}
|
28
|
+
{...props}
|
29
|
+
>
|
30
|
+
<EditorContent editor={editor}/>
|
31
|
+
</RichTextEditor>
|
32
|
+
</div>
|
33
|
+
)
|
34
|
+
}
|
35
|
+
|
36
|
+
export default RichTextEditorAdvancedDefault
|
@@ -7,3 +7,4 @@ export { default as RichTextEditorTemplates } from './_rich_text_editor_template
|
|
7
7
|
export { default as RichTextEditorToolbarBottom } from './_rich_text_editor_toolbar_bottom.jsx'
|
8
8
|
export { default as RichTextEditorInline } from './_rich_text_editor_inline.jsx'
|
9
9
|
export { default as RichTextEditorPreview } from './_rich_text_editor_preview.jsx'
|
10
|
+
export { default as RichTextEditorAdvancedDefault } from './_rich_text_editor_advanced_default.jsx'
|
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: 12.16.0.pre.alpha.
|
4
|
+
version: 12.16.0.pre.alpha.tiptaptestingpart1528
|
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: 2023-04-
|
12
|
+
date: 2023-04-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -1332,8 +1332,6 @@ files:
|
|
1332
1332
|
- app/pb_kits/playbook/pb_lightbox/docs/_description.md
|
1333
1333
|
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_compound_component.jsx
|
1334
1334
|
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_compound_component.md
|
1335
|
-
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.jsx
|
1336
|
-
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_current_photo.md
|
1337
1335
|
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_custom_header.jsx
|
1338
1336
|
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_custom_header.md
|
1339
1337
|
- app/pb_kits/playbook/pb_lightbox/docs/_lightbox_default.jsx
|
@@ -1719,9 +1717,17 @@ files:
|
|
1719
1717
|
- app/pb_kits/playbook/pb_radio/radio.html.erb
|
1720
1718
|
- app/pb_kits/playbook/pb_radio/radio.rb
|
1721
1719
|
- app/pb_kits/playbook/pb_radio/radio.test.js
|
1720
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx
|
1721
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorTypes.ts
|
1722
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx
|
1723
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx
|
1724
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx
|
1725
|
+
- app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx
|
1722
1726
|
- app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss
|
1723
1727
|
- app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx
|
1728
|
+
- app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss
|
1724
1729
|
- app/pb_kits/playbook/pb_rich_text_editor/_trix_styles.scss
|
1730
|
+
- app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx
|
1725
1731
|
- app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.html.erb
|
1726
1732
|
- app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.jsx
|
1727
1733
|
- app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.html.erb
|
@@ -1,121 +0,0 @@
|
|
1
|
-
/* @flow */
|
2
|
-
/* eslint-disable jsx-control-statements/jsx-use-if-tag */
|
3
|
-
import React, { useState } from 'react'
|
4
|
-
import { Flex, Image, Button, Body, FlexItem } from '../../'
|
5
|
-
import Lightbox from '../_lightbox.tsx'
|
6
|
-
|
7
|
-
const LightboxCurrentPhoto = (props) => {
|
8
|
-
const photos = [
|
9
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
10
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
11
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
12
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
13
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
14
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
15
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
16
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
17
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
18
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
19
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
20
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
21
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
22
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
23
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
24
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
25
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
26
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
27
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
28
|
-
'https://images.unsplash.com/photo-1638727228877-d2a79ab75e68?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2668&q=80',
|
29
|
-
'https://images.unsplash.com/photo-1526657782461-9fe13402a841?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1984&q=80',
|
30
|
-
'https://images.unsplash.com/photo-1523057530100-383d7fbc77a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2669&q=80',
|
31
|
-
]
|
32
|
-
const [light, toggleLight] = useState(false)
|
33
|
-
//Setting state with the index of the current slide exposed by the onChange prop
|
34
|
-
const [active, setActive] = useState(0)
|
35
|
-
//Setting state for the current photo to pass to the kit
|
36
|
-
const [currentPhoto, setCurrentPhoto] = useState(active)
|
37
|
-
|
38
|
-
const handleCloseLightbox = () => {
|
39
|
-
toggleLight(!light)
|
40
|
-
}
|
41
|
-
|
42
|
-
const onPhotoClick = () => {
|
43
|
-
toggleLight(!light)
|
44
|
-
}
|
45
|
-
|
46
|
-
const exampleStyles = {
|
47
|
-
width: "100%",
|
48
|
-
overflow: "auto"
|
49
|
-
}
|
50
|
-
|
51
|
-
return (
|
52
|
-
<div className="lightbox_doc_example_custom">
|
53
|
-
{light ? (
|
54
|
-
<>
|
55
|
-
<Flex alignItems="center"
|
56
|
-
className='custom_lightbox_sidebar'
|
57
|
-
justifyContent="center"
|
58
|
-
>
|
59
|
-
<Flex margin='lg'
|
60
|
-
orientation='column'
|
61
|
-
>
|
62
|
-
<Body marginBottom='md'>
|
63
|
-
This UI is for demonstration purposes only to demonstrate how external buttons can be used to change the slides.
|
64
|
-
</Body>
|
65
|
-
<FlexItem alignSelf="center">
|
66
|
-
<Flex justifyContent="center">
|
67
|
-
<Button
|
68
|
-
onClick={()=> setCurrentPhoto(active > 0 ? active - 1 : 0)}
|
69
|
-
>
|
70
|
-
Back
|
71
|
-
</Button>
|
72
|
-
<Button marginLeft='sm'
|
73
|
-
onClick={() => setCurrentPhoto(active < photos.length - 1 ? active + 1 : photos.length - 1)}
|
74
|
-
>
|
75
|
-
Next
|
76
|
-
</Button>
|
77
|
-
</Flex>
|
78
|
-
</FlexItem>
|
79
|
-
</Flex>
|
80
|
-
</Flex>
|
81
|
-
<Lightbox
|
82
|
-
currentPhotoIndex={currentPhoto}
|
83
|
-
icon="times"
|
84
|
-
onChange={(index) => setActive(index)}
|
85
|
-
onClose={handleCloseLightbox}
|
86
|
-
photos={photos}
|
87
|
-
{...props}
|
88
|
-
/>
|
89
|
-
</>
|
90
|
-
) : (
|
91
|
-
<div
|
92
|
-
className="PhotoViewer"
|
93
|
-
style={exampleStyles}
|
94
|
-
>
|
95
|
-
<Flex>
|
96
|
-
{photos.map((photo, index) => {
|
97
|
-
return (
|
98
|
-
<div
|
99
|
-
key={index}
|
100
|
-
onClick={() => onPhotoClick(index)}
|
101
|
-
>
|
102
|
-
<Image
|
103
|
-
cursor="pointer"
|
104
|
-
marginRight="xl"
|
105
|
-
rounded
|
106
|
-
size="lg"
|
107
|
-
url={photo}
|
108
|
-
/>
|
109
|
-
|
110
|
-
<div className="overlay" />
|
111
|
-
</div>
|
112
|
-
)
|
113
|
-
})}
|
114
|
-
</Flex>
|
115
|
-
</div>
|
116
|
-
)}
|
117
|
-
</div>
|
118
|
-
)
|
119
|
-
}
|
120
|
-
|
121
|
-
export default LightboxCurrentPhoto
|
@@ -1 +0,0 @@
|
|
1
|
-
The `currentPhotoIndex` prop allows the user to pass a number to the lightbox that will set the current slide by index. This can be leveraged if the user wants to change slides using custom buttons. To do this, the user must also make use of the current slide's index that is exposed by the `onChange` prop.
|