@pareto-engineering/design-system 2.0.0-alpha.32 → 2.0.0-alpha.35
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.
- package/dist/cjs/a/ContentTree/ContentTree.js +83 -0
- package/dist/cjs/a/ContentTree/common/Tree/Tree.js +116 -0
- package/dist/cjs/a/ContentTree/common/Tree/index.js +15 -0
- package/dist/cjs/a/ContentTree/common/index.js +31 -0
- package/dist/cjs/a/ContentTree/common/useContentTree.js +82 -0
- package/dist/cjs/a/ContentTree/common/useFirstVisibleNode.js +65 -0
- package/dist/cjs/a/ContentTree/index.js +15 -0
- package/dist/cjs/a/ContentTree/styles.scss +33 -0
- package/dist/cjs/a/index.js +9 -1
- package/dist/cjs/c/SocialMediaShareButton/SocialMediaShareButton.js +106 -0
- package/dist/cjs/c/SocialMediaShareButton/index.js +15 -0
- package/dist/cjs/c/SocialMediaShareButton/styles.scss +39 -0
- package/dist/cjs/c/index.js +9 -1
- package/dist/es/a/ContentTree/ContentTree.js +67 -0
- package/dist/es/a/ContentTree/common/Tree/Tree.js +98 -0
- package/dist/es/a/ContentTree/common/Tree/index.js +2 -0
- package/dist/es/a/ContentTree/common/index.js +3 -0
- package/dist/es/a/ContentTree/common/useContentTree.js +74 -0
- package/dist/es/a/ContentTree/common/useFirstVisibleNode.js +54 -0
- package/dist/es/a/ContentTree/index.js +2 -0
- package/dist/es/a/ContentTree/styles.scss +33 -0
- package/dist/es/a/index.js +2 -1
- package/dist/es/c/SocialMediaShareButton/SocialMediaShareButton.js +90 -0
- package/dist/es/c/SocialMediaShareButton/index.js +2 -0
- package/dist/es/c/SocialMediaShareButton/styles.scss +39 -0
- package/dist/es/c/index.js +2 -1
- package/package.json +3 -2
- package/src/__snapshots__/Storyshots.test.js.snap +196 -12
- package/src/local.scss +1 -0
- package/src/stories/StyleGuide/Sprites.stories.mdx +25 -0
- package/src/stories/StyleGuide/helpers.js +16 -0
- package/src/stories/a/ContentTree.stories.jsx +662 -0
- package/src/stories/c/SocialMediaShareButton.stories.jsx +25 -0
- package/src/ui/a/ContentTree/ContentTree.jsx +88 -0
- package/src/ui/a/ContentTree/common/Tree/Tree.jsx +138 -0
- package/src/ui/a/ContentTree/common/Tree/index.js +2 -0
- package/src/ui/a/ContentTree/common/index.js +3 -0
- package/src/ui/a/ContentTree/common/useContentTree.js +83 -0
- package/src/ui/a/ContentTree/common/useFirstVisibleNode.js +59 -0
- package/src/ui/a/ContentTree/index.js +2 -0
- package/src/ui/a/ContentTree/styles.scss +33 -0
- package/src/ui/a/index.js +1 -0
- package/src/ui/c/SocialMediaShareButton/SocialMediaShareButton.jsx +111 -0
- package/src/ui/c/SocialMediaShareButton/index.js +2 -0
- package/src/ui/c/SocialMediaShareButton/styles.scss +39 -0
- package/src/ui/c/index.js +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import { SocialMediaShareButton } from 'ui'
|
|
4
|
+
import Router from '../utils/Router'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title :'c/SocialMediaShareButton',
|
|
8
|
+
component :SocialMediaShareButton,
|
|
9
|
+
subcomponents:{
|
|
10
|
+
// Item:SocialMediaShareButton.Item
|
|
11
|
+
},
|
|
12
|
+
decorators:[
|
|
13
|
+
(storyfn) => <Router>{storyfn()}</Router>,
|
|
14
|
+
],
|
|
15
|
+
argTypes:{
|
|
16
|
+
backgroundColor:{ control: 'color' },
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const Base = () => (
|
|
21
|
+
<div>
|
|
22
|
+
<SocialMediaShareButton type="facebook" />
|
|
23
|
+
<SocialMediaShareButton type="twitter" />
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
import { useLayoutEffect } from 'react'
|
|
5
|
+
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
|
|
8
|
+
import styleNames from '@pareto-engineering/bem'
|
|
9
|
+
|
|
10
|
+
// Local Definitions
|
|
11
|
+
import { Tree, useContentTree } from './common'
|
|
12
|
+
|
|
13
|
+
const baseClassName = styleNames.base
|
|
14
|
+
|
|
15
|
+
const componentClassName = 'content-tree'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* This is the component description.
|
|
19
|
+
*/
|
|
20
|
+
const ContentTree = ({
|
|
21
|
+
id,
|
|
22
|
+
className:userClassName,
|
|
23
|
+
style,
|
|
24
|
+
target,
|
|
25
|
+
selectors,
|
|
26
|
+
// ...otherProps
|
|
27
|
+
}) => {
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
import('./styles.scss')
|
|
30
|
+
}, [])
|
|
31
|
+
|
|
32
|
+
const contentTree = useContentTree(target, selectors)
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div
|
|
36
|
+
id={id}
|
|
37
|
+
className={[
|
|
38
|
+
|
|
39
|
+
baseClassName,
|
|
40
|
+
|
|
41
|
+
componentClassName,
|
|
42
|
+
userClassName,
|
|
43
|
+
]
|
|
44
|
+
.filter((e) => e)
|
|
45
|
+
.join(' ')}
|
|
46
|
+
style={style}
|
|
47
|
+
// {...otherProps}
|
|
48
|
+
>
|
|
49
|
+
<Tree tree={contentTree} />
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ContentTree.propTypes = {
|
|
55
|
+
/**
|
|
56
|
+
* The HTML id for this element
|
|
57
|
+
*/
|
|
58
|
+
id:PropTypes.string,
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The HTML class names for this element
|
|
62
|
+
*/
|
|
63
|
+
className:PropTypes.string,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The React-written, css properties for this element.
|
|
67
|
+
*/
|
|
68
|
+
style:PropTypes.objectOf(PropTypes.string),
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The selectors to use to extract the navigation tree from the content.
|
|
72
|
+
*/
|
|
73
|
+
selectors:PropTypes.arrayOf(PropTypes.string),
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The reference to the parent element.
|
|
77
|
+
*/
|
|
78
|
+
target:PropTypes.oneOfType([
|
|
79
|
+
PropTypes.func,
|
|
80
|
+
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
|
81
|
+
]),
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
ContentTree.defaultProps = {
|
|
85
|
+
selectors:['h2', 'h3'],
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default ContentTree
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
import { useState, useEffect, useMemo } from 'react'
|
|
5
|
+
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
|
|
8
|
+
import styleNames from '@pareto-engineering/bem'
|
|
9
|
+
|
|
10
|
+
// Local Definitions
|
|
11
|
+
|
|
12
|
+
import useFirstVisibleNode from '../useFirstVisibleNode'
|
|
13
|
+
|
|
14
|
+
const baseClassName = styleNames.base
|
|
15
|
+
|
|
16
|
+
const componentClassName = 'tree'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is the component description.
|
|
20
|
+
*/
|
|
21
|
+
const Tree = ({
|
|
22
|
+
id,
|
|
23
|
+
className:userClassName,
|
|
24
|
+
style,
|
|
25
|
+
tree,
|
|
26
|
+
displayDepth,
|
|
27
|
+
// ...otherProps
|
|
28
|
+
}) => {
|
|
29
|
+
// The nodeIds to be used to get the first visible node
|
|
30
|
+
const [nodeIds, setNodeIds] = useState([])
|
|
31
|
+
|
|
32
|
+
// current visible nodeId
|
|
33
|
+
const visibleNodeId = useFirstVisibleNode(nodeIds)
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const node = document.getElementsByClassName(visibleNodeId)[0]
|
|
37
|
+
node?.classList.add(styleNames.modifierActive)
|
|
38
|
+
|
|
39
|
+
return () => {
|
|
40
|
+
node?.classList.remove(styleNames.modifierActive)
|
|
41
|
+
}
|
|
42
|
+
}, [visibleNodeId])
|
|
43
|
+
|
|
44
|
+
// Generate the tree structure from the content tree data depending on the display depth
|
|
45
|
+
const getNestedTree = (node, depth) => {
|
|
46
|
+
setNodeIds((prev) => [...prev, node.id])
|
|
47
|
+
if (depth <= 1) {
|
|
48
|
+
return (
|
|
49
|
+
<li key={node.id}>
|
|
50
|
+
<a
|
|
51
|
+
className={node.id}
|
|
52
|
+
href={node.id}
|
|
53
|
+
>
|
|
54
|
+
{node.text}
|
|
55
|
+
</a>
|
|
56
|
+
</li>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
return (
|
|
60
|
+
<li key={node.id}>
|
|
61
|
+
<p>
|
|
62
|
+
<a
|
|
63
|
+
href={node.id}
|
|
64
|
+
className={node.id}
|
|
65
|
+
>
|
|
66
|
+
{node.text}
|
|
67
|
+
</a>
|
|
68
|
+
</p>
|
|
69
|
+
{node.children.length > 0 && (
|
|
70
|
+
<ul>
|
|
71
|
+
{node.children.map((child) => getNestedTree(child, depth - 1))}
|
|
72
|
+
</ul>
|
|
73
|
+
)}
|
|
74
|
+
</li>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const ContentTree = useMemo(
|
|
79
|
+
() => tree.map((node) => getNestedTree(node, displayDepth)),
|
|
80
|
+
[tree],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<ul
|
|
85
|
+
id={id}
|
|
86
|
+
className={[
|
|
87
|
+
|
|
88
|
+
baseClassName,
|
|
89
|
+
|
|
90
|
+
componentClassName,
|
|
91
|
+
userClassName,
|
|
92
|
+
]
|
|
93
|
+
.filter((e) => e)
|
|
94
|
+
.join(' ')}
|
|
95
|
+
style={style}
|
|
96
|
+
>
|
|
97
|
+
{ContentTree}
|
|
98
|
+
</ul>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
Tree.propTypes = {
|
|
102
|
+
/**
|
|
103
|
+
* The HTML id for this element
|
|
104
|
+
*/
|
|
105
|
+
id:PropTypes.string,
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The HTML class names for this element
|
|
109
|
+
*/
|
|
110
|
+
className:PropTypes.string,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The React-written, css properties for this element.
|
|
114
|
+
*/
|
|
115
|
+
style:PropTypes.objectOf(PropTypes.string),
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The tree to render.
|
|
119
|
+
*/
|
|
120
|
+
tree:PropTypes.arrayOf(PropTypes.shape({
|
|
121
|
+
text :PropTypes.string,
|
|
122
|
+
id :PropTypes.string,
|
|
123
|
+
children:PropTypes.arrayOf(PropTypes.shape({
|
|
124
|
+
text:PropTypes.string, id:PropTypes.string,
|
|
125
|
+
})),
|
|
126
|
+
})),
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The levels of the tree to display.
|
|
130
|
+
*/
|
|
131
|
+
displayDepth:PropTypes.number,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
Tree.defaultProps = {
|
|
135
|
+
displayDepth:4,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default Tree
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
2
|
+
|
|
3
|
+
const useContentTree = (target, selectors) => {
|
|
4
|
+
const [contentTree, setContentTree] = useState([])
|
|
5
|
+
|
|
6
|
+
const getNodes = useCallback((parentTag) => {
|
|
7
|
+
const nodeList = parentTag.querySelectorAll(selectors.join(', '))
|
|
8
|
+
const nodes = []
|
|
9
|
+
|
|
10
|
+
nodeList.forEach((nodeNode) => {
|
|
11
|
+
const { id, innerText, tagName } = nodeNode
|
|
12
|
+
|
|
13
|
+
nodes.push({
|
|
14
|
+
id :`#${id}`,
|
|
15
|
+
text :innerText,
|
|
16
|
+
level:selectors.indexOf(tagName.toLowerCase()),
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
return nodes
|
|
21
|
+
}, [selectors])
|
|
22
|
+
|
|
23
|
+
const buildTree = useCallback((nodes) => {
|
|
24
|
+
// Track the nodes we've seen so far in the same level
|
|
25
|
+
const currentSameLevelNodes = []
|
|
26
|
+
// Track nodes of the next level which will be children of the current node
|
|
27
|
+
let nextLevelNodes = []
|
|
28
|
+
// Track the current node level
|
|
29
|
+
let lastLevel = -1
|
|
30
|
+
|
|
31
|
+
// If the nodes are empty, return an empty tree
|
|
32
|
+
if (nodes.length === 0) {
|
|
33
|
+
return []
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const buildSubTree = () => {
|
|
37
|
+
if (nextLevelNodes.length > 0) {
|
|
38
|
+
currentSameLevelNodes[currentSameLevelNodes.length - 1].children.push(
|
|
39
|
+
...buildTree(nextLevelNodes),
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
nodes.forEach((node) => {
|
|
45
|
+
// If the node is of a greater level, we need to build the sub tree
|
|
46
|
+
if (lastLevel !== -1 && lastLevel < node.level) {
|
|
47
|
+
nextLevelNodes.push(node)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// build a subtree
|
|
52
|
+
buildSubTree()
|
|
53
|
+
|
|
54
|
+
// reset the next level nodes
|
|
55
|
+
lastLevel = node.level
|
|
56
|
+
// add the current node to the current level nodes
|
|
57
|
+
currentSameLevelNodes.push({
|
|
58
|
+
id :node.id,
|
|
59
|
+
text :node.text,
|
|
60
|
+
children:[],
|
|
61
|
+
})
|
|
62
|
+
// reset the next level nodes after building the subtree
|
|
63
|
+
nextLevelNodes = []
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// build subtree
|
|
67
|
+
buildSubTree()
|
|
68
|
+
|
|
69
|
+
return currentSameLevelNodes
|
|
70
|
+
}, [])
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (target.current) {
|
|
74
|
+
const nodes = getNodes(target.current)
|
|
75
|
+
const tree = buildTree(nodes)
|
|
76
|
+
setContentTree(tree)
|
|
77
|
+
}
|
|
78
|
+
}, [target.current])
|
|
79
|
+
|
|
80
|
+
return contentTree
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default useContentTree
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useState, useEffect, useMemo, useCallback,
|
|
3
|
+
} from 'react'
|
|
4
|
+
import debounce from 'lodash/debounce'
|
|
5
|
+
|
|
6
|
+
const useFirstVisibleNode = (nodeIds, config) => {
|
|
7
|
+
const [visibleNodeId, setVisibleNodeId] = useState(null)
|
|
8
|
+
|
|
9
|
+
const { debounceMs = 25 } = config || {}
|
|
10
|
+
|
|
11
|
+
// get headlines nodes - Should only be recalculated when the ids change
|
|
12
|
+
const nodes = useMemo(() => {
|
|
13
|
+
if (nodeIds?.length > 0) {
|
|
14
|
+
return Array.from(document.querySelectorAll(nodeIds.join(',')))
|
|
15
|
+
}
|
|
16
|
+
return []
|
|
17
|
+
}, [nodeIds])
|
|
18
|
+
|
|
19
|
+
const getVisibleNodeId = useCallback(debounce(() => {
|
|
20
|
+
// Get the top postion of each headline node relative to the viewport
|
|
21
|
+
const topOffsets = nodes.map((node) => node.getBoundingClientRect().top)
|
|
22
|
+
|
|
23
|
+
// Get the node closer to zero (the top of the viewport)
|
|
24
|
+
// We have the default offset as Infinity so it's always greater that the first node Y position
|
|
25
|
+
const visibleNode = topOffsets.reduce(
|
|
26
|
+
(prev, currentOffset, currentIndex) => {
|
|
27
|
+
const node = Math.abs(currentOffset - 0) < Math.abs(prev.offset - 0)
|
|
28
|
+
? { node: nodes[currentIndex], offset: currentOffset }
|
|
29
|
+
: prev
|
|
30
|
+
|
|
31
|
+
return node
|
|
32
|
+
}, { node: nodes[0], offset: Infinity },
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
// Set the visible node id
|
|
36
|
+
setVisibleNodeId(`#${visibleNode?.node?.id}`)
|
|
37
|
+
}, debounceMs), [nodes])
|
|
38
|
+
|
|
39
|
+
// Recalculate the visible node id when the page is scrolled
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
window.addEventListener('scroll', getVisibleNodeId)
|
|
42
|
+
|
|
43
|
+
return () => {
|
|
44
|
+
window.removeEventListener('scroll', getVisibleNodeId)
|
|
45
|
+
}
|
|
46
|
+
}, [getVisibleNodeId])
|
|
47
|
+
|
|
48
|
+
// Recalculate the visible node id when the page is resized
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
window.addEventListener('resize', getVisibleNodeId)
|
|
51
|
+
return () => {
|
|
52
|
+
window.removeEventListener('resize', getVisibleNodeId)
|
|
53
|
+
}
|
|
54
|
+
}, [getVisibleNodeId])
|
|
55
|
+
|
|
56
|
+
return visibleNodeId
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default useFirstVisibleNode
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
@use "@pareto-engineering/bem";
|
|
3
|
+
|
|
4
|
+
$default-margin: 1em;
|
|
5
|
+
$default-padding: 1em;
|
|
6
|
+
|
|
7
|
+
.#{bem.$base}.content-tree{
|
|
8
|
+
|
|
9
|
+
ul {
|
|
10
|
+
list-style: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.#{bem.$base}.tree {
|
|
14
|
+
position: sticky;
|
|
15
|
+
top: 0;
|
|
16
|
+
padding: 0;
|
|
17
|
+
|
|
18
|
+
.#{bem.$modifier-active} {
|
|
19
|
+
color: var(--main2);
|
|
20
|
+
transition: color 0.2s;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
li:not(:last-child) {
|
|
24
|
+
margin-bottom: $default-margin;
|
|
25
|
+
ul {
|
|
26
|
+
padding-left: $default-padding;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
package/src/ui/a/index.js
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
import { useLayoutEffect } from 'react'
|
|
5
|
+
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
|
|
8
|
+
import styleNames from '@pareto-engineering/bem'
|
|
9
|
+
|
|
10
|
+
// Local Definitions
|
|
11
|
+
|
|
12
|
+
const baseClassName = styleNames.base
|
|
13
|
+
|
|
14
|
+
const componentClassName = 'social-media-share-button'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* This is the component description.
|
|
18
|
+
*/
|
|
19
|
+
const SocialMediaShareButton = ({
|
|
20
|
+
id,
|
|
21
|
+
className:userClassName,
|
|
22
|
+
style,
|
|
23
|
+
icon,
|
|
24
|
+
// children,
|
|
25
|
+
type,
|
|
26
|
+
color,
|
|
27
|
+
}) => {
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
import('./styles.scss')
|
|
30
|
+
}, [])
|
|
31
|
+
|
|
32
|
+
const { title } = document
|
|
33
|
+
const link = window.location.href
|
|
34
|
+
|
|
35
|
+
const defaultsMap = {
|
|
36
|
+
facebook:{
|
|
37
|
+
icon:'f',
|
|
38
|
+
link:`https://www.facebook.com/sharer/sharer.php?u=${link}"e=${title}`,
|
|
39
|
+
},
|
|
40
|
+
twitter:{
|
|
41
|
+
icon:'t',
|
|
42
|
+
link:`https://twitter.com/intent/tweet?text=${title}&url=${link}`,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<a
|
|
48
|
+
href={defaultsMap[type].link}
|
|
49
|
+
target="_blank"
|
|
50
|
+
rel="noreferrer"
|
|
51
|
+
id={id}
|
|
52
|
+
className={[
|
|
53
|
+
baseClassName,
|
|
54
|
+
componentClassName,
|
|
55
|
+
`x-${color || type}`,
|
|
56
|
+
userClassName,
|
|
57
|
+
]
|
|
58
|
+
.filter((e) => e)
|
|
59
|
+
.join(' ')}
|
|
60
|
+
style={style}
|
|
61
|
+
>
|
|
62
|
+
<button type="button">
|
|
63
|
+
{ icon || defaultsMap[type].icon }
|
|
64
|
+
</button>
|
|
65
|
+
</a>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
SocialMediaShareButton.propTypes = {
|
|
70
|
+
/**
|
|
71
|
+
* The HTML id for this element
|
|
72
|
+
*/
|
|
73
|
+
id:PropTypes.string,
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The HTML class names for this element
|
|
77
|
+
*/
|
|
78
|
+
className:PropTypes.string,
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The React-written, css properties for this element.
|
|
82
|
+
*/
|
|
83
|
+
style:PropTypes.objectOf(PropTypes.string),
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The children JSX
|
|
87
|
+
*/
|
|
88
|
+
// children:PropTypes.node,
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The Social Media to Target.
|
|
92
|
+
* If blank, you need to provide both an icon letter (from glyphter) and a link.
|
|
93
|
+
*/
|
|
94
|
+
type:PropTypes.oneOf(['twitter', 'facebook']),
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The icon of the social media
|
|
98
|
+
*/
|
|
99
|
+
icon:PropTypes.string,
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The button color
|
|
103
|
+
*/
|
|
104
|
+
color:PropTypes.string,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
SocialMediaShareButton.defaultProps = {
|
|
108
|
+
// someProp:false
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default SocialMediaShareButton
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
|
|
3
|
+
@use "@pareto-engineering/bem";
|
|
4
|
+
@use "@aztlan/stylebook/src/mixins";
|
|
5
|
+
@use "@aztlan/stylebook/src/globals" as *;
|
|
6
|
+
|
|
7
|
+
$default-dimensions: 2em;
|
|
8
|
+
$mobile-dimensions: 2.75em;
|
|
9
|
+
|
|
10
|
+
.#{bem.$base}.social-media-share-button{
|
|
11
|
+
|
|
12
|
+
> button {
|
|
13
|
+
appearance: none;
|
|
14
|
+
background: transparent;
|
|
15
|
+
border: 0;
|
|
16
|
+
border-radius: 3em;
|
|
17
|
+
color: var(--x);
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
font-family: "icons", sans-serif;
|
|
20
|
+
height: $default-dimensions;
|
|
21
|
+
transition: all .3s;
|
|
22
|
+
width: $default-dimensions;
|
|
23
|
+
|
|
24
|
+
@include mixins.media($to:$sm-md) {
|
|
25
|
+
height: $mobile-dimensions;
|
|
26
|
+
width: $mobile-dimensions;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&:hover {
|
|
30
|
+
background: var(--x);
|
|
31
|
+
color: var(--on-x);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&:focus, &:active {
|
|
35
|
+
background: var(--light-x);
|
|
36
|
+
color: var(--on-x);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/ui/c/index.js
CHANGED