playbook_ui 13.18.0.pre.alpha.play1141iconkitusinglibrary2210 → 13.18.0.pre.alpha.thor93bargraphoptions2211
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_bar_graph/_bar_graph.tsx +3 -1
- data/app/pb_kits/playbook/pb_icon/_icon.tsx +16 -28
- data/app/pb_kits/playbook/pb_icon/docs/_icon_custom.html.erb +11 -5
- data/app/pb_kits/playbook/pb_icon/docs/_icon_custom.jsx +18 -44
- data/app/pb_kits/playbook/pb_icon/docs/_icon_custom.md +8 -4
- data/app/pb_kits/playbook/pb_icon/icon.html.erb +4 -6
- data/app/pb_kits/playbook/pb_icon/icon.rb +10 -24
- data/dist/playbook-rails.js +2 -2
- data/lib/playbook/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ceb325111d4662aa6a0491153e357222b4f304d21c247fcc44a3db3aafda347a
|
4
|
+
data.tar.gz: 693e1c50633b9b8f309cd2c21ffaa457adbf54ed8a3bd3dfa965b9852c3f6ca6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64ae9216199a92f0559d7b524f6165f93698366b2d01e05669293b5a0fb974294148caf6415e97bcff6f8a09b1d2931cdc17cd28f2fc3b421be1532962061b97
|
7
|
+
data.tar.gz: 8134787717615c18836ec47718dae3518c79500d1786b9076618a71d8f0e5605706bc355aa9398c8dea710c3604828d93aeb680f0c7a17f4a19aab9510dc00c8
|
@@ -19,6 +19,7 @@ type BarGraphProps = {
|
|
19
19
|
yAxisMax: number;
|
20
20
|
chartData: { name: string; data: number[] }[];
|
21
21
|
className?: string;
|
22
|
+
customOptions?: Partial<Highcharts.Options>;
|
22
23
|
id: string;
|
23
24
|
pointStart: number;
|
24
25
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
@@ -48,6 +49,7 @@ const BarGraph = ({
|
|
48
49
|
className = "pb_bar_graph",
|
49
50
|
colors,
|
50
51
|
htmlOptions = {},
|
52
|
+
customOptions = {},
|
51
53
|
id,
|
52
54
|
pointStart,
|
53
55
|
subTitle,
|
@@ -128,7 +130,7 @@ const BarGraph = ({
|
|
128
130
|
const [options, setOptions] = useState({});
|
129
131
|
|
130
132
|
useEffect(() => {
|
131
|
-
setOptions({ ...staticOptions });
|
133
|
+
setOptions({ ...staticOptions, ...customOptions });
|
132
134
|
}, [chartData]);
|
133
135
|
|
134
136
|
return (
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React
|
1
|
+
import React from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
3
|
import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/props'
|
4
4
|
import { GlobalProps, globalProps } from '../utilities/globalProps'
|
@@ -27,7 +27,7 @@ type IconProps = {
|
|
27
27
|
data?: {[key: string]: string},
|
28
28
|
fixedWidth?: boolean,
|
29
29
|
flip?: "horizontal" | "vertical" | "both" | "none",
|
30
|
-
icon: string
|
30
|
+
icon: string,
|
31
31
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
32
32
|
id?: string,
|
33
33
|
inverse?: boolean,
|
@@ -47,11 +47,6 @@ const flipMap = {
|
|
47
47
|
none: ""
|
48
48
|
}
|
49
49
|
|
50
|
-
declare global {
|
51
|
-
// eslint-disable-next-line no-var
|
52
|
-
var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
|
53
|
-
}
|
54
|
-
|
55
50
|
const Icon = (props: IconProps) => {
|
56
51
|
const {
|
57
52
|
aria = {},
|
@@ -62,7 +57,7 @@ const Icon = (props: IconProps) => {
|
|
62
57
|
fixedWidth = true,
|
63
58
|
flip = "none",
|
64
59
|
htmlOptions = {},
|
65
|
-
icon
|
60
|
+
icon,
|
66
61
|
id,
|
67
62
|
inverse = false,
|
68
63
|
listItem = false,
|
@@ -74,8 +69,6 @@ const Icon = (props: IconProps) => {
|
|
74
69
|
spin = false,
|
75
70
|
} = props
|
76
71
|
|
77
|
-
let iconElement: ReactSVGElement | null = typeof(icon) === "object" ? icon : null
|
78
|
-
|
79
72
|
const faClasses = {
|
80
73
|
'fa-border': border,
|
81
74
|
'fa-fw': fixedWidth,
|
@@ -86,23 +79,19 @@ const Icon = (props: IconProps) => {
|
|
86
79
|
[`fa-${size}`]: size,
|
87
80
|
[`fa-pull-${pull}`]: pull,
|
88
81
|
[`fa-rotate-${rotation}`]: rotation,
|
89
|
-
}
|
90
|
-
|
91
|
-
if (!customIcon && !iconElement) {
|
92
|
-
const PowerIcon: React.FunctionComponent<any> | undefined =
|
93
|
-
window.PB_ICONS ? window.PB_ICONS[icon as string] : null
|
94
82
|
|
95
|
-
if (PowerIcon) {
|
96
|
-
iconElement = <PowerIcon /> as ReactSVGElement
|
97
|
-
} else {
|
98
|
-
faClasses[`fa-${icon}`] = icon as string
|
99
|
-
}
|
100
83
|
}
|
101
84
|
|
85
|
+
// Lets check and see if the icon prop is referring to a custom Power icon...
|
86
|
+
// If so, then set fa-icon to "custom"
|
87
|
+
// this ensures the JS will not do any further operations
|
88
|
+
// faClasses[`fa-${icon}`] = customIcon ? 'custom' : icon
|
89
|
+
if (!customIcon) faClasses[`fa-${icon}`] = icon
|
90
|
+
|
102
91
|
const classes = classnames(
|
103
92
|
flipMap[flip],
|
104
|
-
|
105
|
-
|
93
|
+
'pb_icon_kit',
|
94
|
+
customIcon ? '' : fontStyle,
|
106
95
|
faClasses,
|
107
96
|
globalProps(props),
|
108
97
|
className
|
@@ -121,22 +110,20 @@ const Icon = (props: IconProps) => {
|
|
121
110
|
|
122
111
|
// Add a conditional here to show only the SVG if custom
|
123
112
|
const displaySVG = (customIcon: any) => {
|
124
|
-
if (
|
113
|
+
if (customIcon)
|
125
114
|
return (
|
126
115
|
<>
|
127
116
|
{
|
128
|
-
React.cloneElement(
|
117
|
+
React.cloneElement(customIcon, {
|
129
118
|
...dataProps,
|
130
119
|
...htmlProps,
|
131
120
|
className: classes,
|
132
121
|
id,
|
133
|
-
width: 'auto',
|
134
|
-
height: 'auto',
|
135
122
|
})
|
136
123
|
}
|
137
124
|
</>
|
138
125
|
)
|
139
|
-
else if (isValidEmoji(icon
|
126
|
+
else if (isValidEmoji(icon))
|
140
127
|
return (
|
141
128
|
<>
|
142
129
|
<span
|
@@ -149,6 +136,7 @@ const Icon = (props: IconProps) => {
|
|
149
136
|
</span>
|
150
137
|
</>
|
151
138
|
)
|
139
|
+
|
152
140
|
else
|
153
141
|
return (
|
154
142
|
<>
|
@@ -173,4 +161,4 @@ const Icon = (props: IconProps) => {
|
|
173
161
|
)
|
174
162
|
}
|
175
163
|
|
176
|
-
export default Icon
|
164
|
+
export default Icon
|
@@ -2,9 +2,15 @@
|
|
2
2
|
<div class="icon-wrapper">
|
3
3
|
|
4
4
|
<% svg_url = "https://upload.wikimedia.org/wikipedia/commons/3/3b/Wrench_font_awesome.svg" %>
|
5
|
-
<p><%= pb_rails("icon", props: {
|
6
|
-
<p><%= pb_rails("icon", props: { rotation: 90,
|
7
|
-
<p><%= pb_rails("icon", props: { spin: true,
|
8
|
-
<p><%= pb_rails("icon", props: { size: "5x",
|
9
|
-
<p><%= pb_rails("icon", props: { flip: "horizontal", size: "5x",
|
5
|
+
<p><%= pb_rails("icon", props: { custom_icon: svg_url } ) %></p>
|
6
|
+
<p><%= pb_rails("icon", props: { rotation: 90, custom_icon: svg_url, size: "2x" } ) %></p>
|
7
|
+
<p><%= pb_rails("icon", props: { spin: true, custom_icon: svg_url, size: "3x" } ) %></p>
|
8
|
+
<p><%= pb_rails("icon", props: { size: "5x", custom_icon: svg_url } ) %></p>
|
9
|
+
<p><%= pb_rails("icon", props: { flip: "horizontal", size: "5x", custom_icon: svg_url } ) %></p>
|
10
|
+
|
11
|
+
<%= pb_rails("body", props: {
|
12
|
+
text: "Custom icons are compatible with other icon props (size, rotation,
|
13
|
+
spin, flip, etc). Their SVG fill colors will be inherited from
|
14
|
+
parent element's css color properties."
|
15
|
+
} ) %>
|
10
16
|
</div>
|
@@ -1,59 +1,33 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import { Icon } from '../../'
|
3
3
|
|
4
|
+
// import Icons as config from 'power-icons'
|
4
5
|
const config = {
|
5
|
-
|
6
|
-
<svg
|
6
|
+
moon: (
|
7
|
+
<svg
|
8
|
+
ariaHidden="true"
|
9
|
+
focusable="false"
|
10
|
+
role="img"
|
11
|
+
viewBox="0 0 512 512"
|
7
12
|
xmlns="http://www.w3.org/2000/svg"
|
8
13
|
>
|
9
|
-
<
|
10
|
-
|
11
|
-
|
14
|
+
<path
|
15
|
+
d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 7.1 5.8 12 12 12 2.4 0 4.9-.7 7.1-2.4L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zm16 352c0 8.8-7.2 16-16 16H288l-12.8 9.6L208 428v-60H64c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16h384c8.8 0 16 7.2 16 16v288zM336 184h-56v-56c0-8.8-7.2-16-16-16h-16c-8.8 0-16 7.2-16 16v56h-56c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h56v56c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16v-56h56c8.8 0 16-7.2 16-16v-16c0-8.8-7.2-16-16-16z"
|
16
|
+
fill="currentColor"
|
17
|
+
/>
|
12
18
|
</svg>
|
13
19
|
),
|
14
20
|
}
|
15
21
|
|
16
22
|
const IconCustom = (props) => {
|
17
23
|
return (
|
18
|
-
<
|
19
|
-
<
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
<p>
|
26
|
-
<Icon
|
27
|
-
icon={config.icon}
|
28
|
-
rotation={90}
|
29
|
-
size="2x"
|
30
|
-
{...props}
|
31
|
-
/>
|
32
|
-
</p>
|
33
|
-
<p>
|
34
|
-
<Icon
|
35
|
-
icon={config.icon}
|
36
|
-
size="3x"
|
37
|
-
spin
|
38
|
-
{...props}
|
39
|
-
/>
|
40
|
-
</p>
|
41
|
-
<p>
|
42
|
-
<Icon
|
43
|
-
icon={config.icon}
|
44
|
-
size="5x"
|
45
|
-
{...props}
|
46
|
-
/>
|
47
|
-
</p>
|
48
|
-
<p>
|
49
|
-
<Icon
|
50
|
-
flip="horizontal"
|
51
|
-
icon={config.icon}
|
52
|
-
size="5x"
|
53
|
-
{...props}
|
54
|
-
/>
|
55
|
-
</p>
|
56
|
-
</React.Fragment>
|
24
|
+
<div>
|
25
|
+
<Icon
|
26
|
+
customIcon={config.moon}
|
27
|
+
size="7x"
|
28
|
+
{...props}
|
29
|
+
/>
|
30
|
+
</div>
|
57
31
|
)
|
58
32
|
}
|
59
33
|
|
@@ -4,12 +4,16 @@ When using custom icons it is important to introduce a "clean" SVG. In order to
|
|
4
4
|
|
5
5
|
Attributes must be React compatible e.g. <code>xmlns:xlink</code> should be <code>xmlnsXlink</code> and so on. <strong>There should be no hyphenated attributes and no semi-colons!.</strong>
|
6
6
|
|
7
|
-
Fill colors with regards to <code>g</code> or <code>path</code> nodes, e.g. <code>fill="black"</code>, should be replaced with
|
7
|
+
Fill colors with regards to <code>g</code> or <code>path</code> nodes, e.g. <code>fill="black"</code>, should be replaced with <code>currentColor</code> ala <code>fill="currentColor"</code>. Your mileage may vary depending on the complexity of your SVG.
|
8
8
|
|
9
|
-
Pay attention to your custom icon's dimensions and `viewBox` attribute. It is best to use a `viewBox="0 0 512 512"` starting point
|
9
|
+
Pay attention to your custom icon's dimensions and `viewBox` attribute. It is best to use a `viewBox="0 0 512 512"` starting point __when designing instead of trying to retrofit the viewbox afterwards__!
|
10
10
|
|
11
|
-
You must source
|
11
|
+
You must source *your own SVG into component/view* you are working on. This can easily be done in programmatic and maintainable ways.
|
12
|
+
|
13
|
+
### React
|
14
|
+
|
15
|
+
So long as you have a valid React `<SVG>` node, you can send it as the `customIcon` prop and the kit will take care of the rest.
|
12
16
|
|
13
17
|
### Rails
|
14
18
|
|
15
|
-
|
19
|
+
Some Rails applications use only webpack(er) which means using `image_url` will be successful over `image_path` in most cases especially development where Webpack Dev Server is serving assets over HTTP. Rails applications still using Asset Pipeline may use `image_path` or `image_url`. Of course, YMMV depending on any custom configurations in your Rails application.
|
@@ -1,9 +1,7 @@
|
|
1
|
-
<% if object.
|
2
|
-
<%= object.render_svg %>
|
3
|
-
<% elsif object.valid_emoji
|
4
|
-
<span class="pb_icon_kit_emoji">
|
5
|
-
<%= object.icon.html_safe %>
|
6
|
-
</span>
|
1
|
+
<% if object.custom_icon %>
|
2
|
+
<%= object.render_svg(object.custom_icon) %>
|
3
|
+
<% elsif object.valid_emoji(object.icon) %>
|
4
|
+
<span class="pb_icon_kit_emoji"><%= object.icon.html_safe %></span>
|
7
5
|
<% else %>
|
8
6
|
<%= content_tag(:i, nil,
|
9
7
|
id: object.id,
|
@@ -38,7 +38,7 @@ module Playbook
|
|
38
38
|
prop :spin, type: Playbook::Props::Boolean,
|
39
39
|
default: false
|
40
40
|
|
41
|
-
def valid_emoji
|
41
|
+
def valid_emoji(icon)
|
42
42
|
emoji_regex = /\p{Emoji}/
|
43
43
|
emoji_regex.match?(icon)
|
44
44
|
end
|
@@ -79,33 +79,19 @@ module Playbook
|
|
79
79
|
)
|
80
80
|
end
|
81
81
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
svg = doc.at_css "svg"
|
92
|
-
svg["class"] = "pb_custom_icon " + object.custom_icon_classname
|
93
|
-
svg["height"] = "auto"
|
94
|
-
svg["width"] = "auto"
|
95
|
-
doc.at_css("path")["fill"] = "currentColor"
|
96
|
-
raw doc
|
97
|
-
end
|
98
|
-
|
99
|
-
def is_svg?
|
100
|
-
(icon || custom_icon.to_s).include?(".svg") || asset_path.present?
|
82
|
+
def render_svg(path)
|
83
|
+
if File.extname(path) == ".svg"
|
84
|
+
doc = Nokogiri::XML(URI.open(path)) # rubocop:disable Security/Open
|
85
|
+
svg = doc.at_css "svg"
|
86
|
+
svg["class"] = "pb_custom_icon " + object.custom_icon_classname
|
87
|
+
raw doc
|
88
|
+
else
|
89
|
+
raise("Custom icon must be an svg. Please check your path and file type.")
|
90
|
+
end
|
101
91
|
end
|
102
92
|
|
103
93
|
private
|
104
94
|
|
105
|
-
def svg_size
|
106
|
-
size.nil? ? "1x" : size
|
107
|
-
end
|
108
|
-
|
109
95
|
def border_class
|
110
96
|
border ? "fa-border" : nil
|
111
97
|
end
|