playbook_ui 13.30.0.pre.alpha.PLAY1328fixtimelinekitglobalpropsreact3096 → 13.30.0.pre.alpha.play1367contenttagnoninputkits3159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +59 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.md +6 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +4 -4
- data/app/pb_kits/playbook/pb_background/background.html.erb +2 -11
- data/app/pb_kits/playbook/pb_body/body.html.erb +1 -6
- data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +1 -6
- data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +1 -6
- data/app/pb_kits/playbook/pb_caption/caption.html.erb +1 -6
- data/app/pb_kits/playbook/pb_card/_card.tsx +4 -3
- data/app/pb_kits/playbook/pb_card/card.html.erb +1 -7
- data/app/pb_kits/playbook/pb_collapsible/index.js +6 -1
- data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_default_swift.md +33 -0
- data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_props_swift.md +18 -0
- data/app/pb_kits/playbook/pb_date_time_stacked/docs/example.yml +6 -1
- data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
- data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +30 -35
- data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +2 -7
- data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +1 -5
- data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +1 -6
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +2 -4
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +70 -50
- data/app/pb_kits/playbook/pb_draggable/context/types.ts +26 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +2 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +1 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers.jsx +5 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.jsx +11 -4
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.md +4 -2
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.jsx +2 -2
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +7 -1
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.jsx +6 -4
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.md +7 -0
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +142 -15
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -5
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +18 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +228 -218
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +9 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +34 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +14 -12
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +7 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -2
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +9 -3
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.html.erb +32 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.jsx +48 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +16 -11
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.test.js +72 -0
- data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
- data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
- data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
- data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
- data/app/pb_kits/playbook/pb_icon/_icon.tsx +37 -6
- data/app/pb_kits/playbook/pb_icon/docs/_icon_default.html.erb +1 -1
- data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +2 -3
- data/app/pb_kits/playbook/pb_icon/icon.rb +21 -1
- data/app/pb_kits/playbook/pb_icon/icon_aliases.json +39 -0
- data/app/pb_kits/playbook/pb_list/_list.tsx +4 -4
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +7 -3
- data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.html.erb +1 -1
- data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.jsx +1 -0
- data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.md +3 -1
- data/app/pb_kits/playbook/pb_nav/item.html.erb +1 -1
- data/app/pb_kits/playbook/pb_nav/item.rb +1 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.html.erb +24 -0
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.md +4 -4
- data/app/pb_kits/playbook/pb_overlay/docs/_overlay_multi_directional.html.erb +11 -0
- data/app/pb_kits/playbook/pb_overlay/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +27 -0
- data/app/pb_kits/playbook/pb_overlay/overlay.rb +110 -0
- data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +7 -3
- data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +3 -3
- data/app/pb_kits/playbook/pb_table/table_header.html.erb +16 -2
- data/app/pb_kits/playbook/utilities/globalProps.ts +1 -0
- data/dist/menu.yml +2 -2
- data/dist/playbook-rails.js +7 -7
- data/lib/playbook/version.rb +1 -1
- metadata +18 -2
@@ -23,6 +23,7 @@ type FixedConfirmationToastProps = {
|
|
23
23
|
data?: string;
|
24
24
|
horizontal?: "right" | "left" | "center";
|
25
25
|
htmlOptions?: { [key: string]: string | number | boolean | (VoidCallback) };
|
26
|
+
icon?: string,
|
26
27
|
id?: string;
|
27
28
|
multiLine?: boolean;
|
28
29
|
onClose?: VoidCallback;
|
@@ -41,6 +42,7 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
|
|
41
42
|
closeable = false,
|
42
43
|
horizontal,
|
43
44
|
htmlOptions = {},
|
45
|
+
icon,
|
44
46
|
multiLine = false,
|
45
47
|
onClose = () => undefined,
|
46
48
|
open = true,
|
@@ -48,14 +50,18 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
|
|
48
50
|
text,
|
49
51
|
vertical,
|
50
52
|
} = props;
|
53
|
+
|
54
|
+
const returnedIcon = icon || iconMap[status]
|
55
|
+
const iconClass = icon ? "custom_icon" : ""
|
56
|
+
|
51
57
|
const css = classnames(
|
52
58
|
`pb_fixed_confirmation_toast_kit_${status}`,
|
53
59
|
{ _multi_line: multiLine },
|
54
60
|
{ [`positioned_toast ${vertical} ${horizontal}`]: vertical && horizontal },
|
61
|
+
`${iconClass}`,
|
55
62
|
globalProps(props),
|
56
63
|
className
|
57
64
|
);
|
58
|
-
const icon = iconMap[status];
|
59
65
|
|
60
66
|
const htmlProps = buildHtmlProps(htmlOptions);
|
61
67
|
|
@@ -86,11 +92,11 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
|
|
86
92
|
onClick={handleClick}
|
87
93
|
{...htmlProps}
|
88
94
|
>
|
89
|
-
{
|
95
|
+
{returnedIcon && (
|
90
96
|
<Icon
|
91
97
|
className="pb_icon"
|
92
98
|
fixedWidth
|
93
|
-
icon={
|
99
|
+
icon={returnedIcon}
|
94
100
|
/>
|
95
101
|
)}
|
96
102
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div>
|
2
|
+
<%= pb_rails("fixed_confirmation_toast", props: {
|
3
|
+
icon: "wrench",
|
4
|
+
text: "Fix before proceeding",
|
5
|
+
status: "error",
|
6
|
+
closeable: true,
|
7
|
+
margin_bottom: "md"
|
8
|
+
})%>
|
9
|
+
</div>
|
10
|
+
<div>
|
11
|
+
<%= pb_rails("fixed_confirmation_toast", props: {
|
12
|
+
icon: "star",
|
13
|
+
text: "Thank you for completing the form!",
|
14
|
+
status: "success",
|
15
|
+
margin_bottom: "md"
|
16
|
+
})%>
|
17
|
+
</div>
|
18
|
+
<div>
|
19
|
+
<%= pb_rails("fixed_confirmation_toast", props: {
|
20
|
+
icon: "file-pdf",
|
21
|
+
text: "Saved as PDF",
|
22
|
+
status: "neutral",
|
23
|
+
margin_bottom: "md"
|
24
|
+
})%>
|
25
|
+
</div>
|
26
|
+
<div>
|
27
|
+
<%= pb_rails("fixed_confirmation_toast", props: {
|
28
|
+
icon: "arrow-down",
|
29
|
+
text: "New Messages",
|
30
|
+
status: "tip"
|
31
|
+
})%>
|
32
|
+
</div>
|
data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.jsx
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import FixedConfirmationToast from '../_fixed_confirmation_toast'
|
4
|
+
|
5
|
+
const FixedConfirmationToastCustomIcon = (props) => {
|
6
|
+
return (
|
7
|
+
<div>
|
8
|
+
<div>
|
9
|
+
<FixedConfirmationToast
|
10
|
+
closeable
|
11
|
+
icon="wrench"
|
12
|
+
marginBottom="md"
|
13
|
+
status="error"
|
14
|
+
text="Fix before proceeding"
|
15
|
+
{...props}
|
16
|
+
/>
|
17
|
+
</div>
|
18
|
+
<div>
|
19
|
+
<FixedConfirmationToast
|
20
|
+
icon="star"
|
21
|
+
marginBottom="md"
|
22
|
+
status="success"
|
23
|
+
text="Thank you for completing the form!"
|
24
|
+
{...props}
|
25
|
+
/>
|
26
|
+
</div>
|
27
|
+
<div>
|
28
|
+
<FixedConfirmationToast
|
29
|
+
icon="file-pdf"
|
30
|
+
marginBottom="md"
|
31
|
+
status="neutral"
|
32
|
+
text="Saved as PDF"
|
33
|
+
{...props}
|
34
|
+
/>
|
35
|
+
</div>
|
36
|
+
<div>
|
37
|
+
<FixedConfirmationToast
|
38
|
+
icon="arrow-down"
|
39
|
+
status="tip"
|
40
|
+
text="New Messages"
|
41
|
+
{...props}
|
42
|
+
/>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
)
|
46
|
+
}
|
47
|
+
|
48
|
+
export default FixedConfirmationToastCustomIcon
|
@@ -6,6 +6,7 @@ examples:
|
|
6
6
|
- fixed_confirmation_toast_close: Click to Close
|
7
7
|
- fixed_confirmation_toast_positions: Click to Show Positions
|
8
8
|
- fixed_confirmation_toast_children: Children
|
9
|
+
- fixed_confirmation_toast_custom_icon: Custom Icon
|
9
10
|
|
10
11
|
react:
|
11
12
|
- fixed_confirmation_toast_default: Default
|
@@ -14,6 +15,7 @@ examples:
|
|
14
15
|
- fixed_confirmation_toast_positions: Click to Show Positions
|
15
16
|
- fixed_confirmation_toast_auto_close: Click to Show Auto Close
|
16
17
|
- fixed_confirmation_toast_children: Children
|
18
|
+
- fixed_confirmation_toast_custom_icon: Custom Icon
|
17
19
|
|
18
20
|
swift:
|
19
21
|
- fixed_confirmation_toast_default_swift: Default
|
@@ -4,3 +4,4 @@ export { default as FixedConfirmationToastClose } from './_fixed_confirmation_to
|
|
4
4
|
export { default as FixedConfirmationToastPositions } from './_fixed_confirmation_toast_positions.jsx'
|
5
5
|
export { default as FixedConfirmationToastAutoClose } from './_fixed_confirmation_toast_auto_close.jsx'
|
6
6
|
export { default as FixedConfirmationToastChildren } from './_fixed_confirmation_toast_children.jsx'
|
7
|
+
export { default as FixedConfirmationToastCustomIcon } from './_fixed_confirmation_toast_custom_icon.jsx'
|
@@ -20,6 +20,7 @@ module Playbook
|
|
20
20
|
values: [nil, "top", "bottom"],
|
21
21
|
default: nil
|
22
22
|
prop :auto_close, type: Playbook::Props::Number
|
23
|
+
prop :icon, type: Playbook::Props::String
|
23
24
|
|
24
25
|
def show_text?
|
25
26
|
text.present?
|
@@ -42,20 +43,24 @@ module Playbook
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def icon_value
|
45
|
-
case status
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
icon || case status
|
47
|
+
when "success"
|
48
|
+
"check"
|
49
|
+
when "error"
|
50
|
+
"exclamation-triangle"
|
51
|
+
when "neutral"
|
52
|
+
"info-circle"
|
53
|
+
when "tip"
|
54
|
+
"info-circle"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def icon_class
|
59
|
+
icon.present? ? " custom_icon" : ""
|
55
60
|
end
|
56
61
|
|
57
62
|
def classname
|
58
|
-
generate_classname("pb_fixed_confirmation_toast_kit", status, multi_line_class) + close_class + position_class + auto_close_class
|
63
|
+
generate_classname("pb_fixed_confirmation_toast_kit", status, multi_line_class) + close_class + position_class + auto_close_class + icon_class
|
59
64
|
end
|
60
65
|
end
|
61
66
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { render, waitFor } from '../utilities/test-utils'
|
3
|
+
|
4
|
+
import { FixedConfirmationToast } from '../'
|
5
|
+
|
6
|
+
beforeEach(() => {
|
7
|
+
// Silences error logs within the test suite.
|
8
|
+
jest.spyOn(console, 'error')
|
9
|
+
// eslint-disable-next-line
|
10
|
+
console.error.mockImplementation(() => {})
|
11
|
+
})
|
12
|
+
|
13
|
+
afterEach(() => {
|
14
|
+
// eslint-disable-next-line
|
15
|
+
console.error.mockRestore()
|
16
|
+
})
|
17
|
+
|
18
|
+
test('renders with default props', () => {
|
19
|
+
const { container } = render(<FixedConfirmationToast />);
|
20
|
+
expect(container.firstChild).toBeInTheDocument();
|
21
|
+
});
|
22
|
+
|
23
|
+
test('renders with text', () => {
|
24
|
+
const { getByText } = render(<FixedConfirmationToast text="Message Text" />);
|
25
|
+
expect(getByText('Message Text')).toBeInTheDocument();
|
26
|
+
});
|
27
|
+
|
28
|
+
test('does not render if open prop is false', () => {
|
29
|
+
const { container } = render(<FixedConfirmationToast open={false} />);
|
30
|
+
expect(container.firstChild).toBeNull();
|
31
|
+
});
|
32
|
+
|
33
|
+
test('closes after autoClose duration', async () => {
|
34
|
+
jest.useFakeTimers();
|
35
|
+
const onCloseMock = jest.fn();
|
36
|
+
render(
|
37
|
+
<FixedConfirmationToast
|
38
|
+
autoClose={1000}
|
39
|
+
onClose={onCloseMock}
|
40
|
+
open
|
41
|
+
/>
|
42
|
+
);
|
43
|
+
|
44
|
+
jest.advanceTimersByTime(1000);
|
45
|
+
await waitFor(() => expect(onCloseMock).toHaveBeenCalled());
|
46
|
+
});
|
47
|
+
|
48
|
+
test('renders success status with icon', () => {
|
49
|
+
const { container } = render(<FixedConfirmationToast status="success" />);
|
50
|
+
expect(container.querySelector('.pb_fixed_confirmation_toast_kit_success')).toBeInTheDocument();
|
51
|
+
expect(container.querySelector('.pb_icon')).toBeInTheDocument();
|
52
|
+
});
|
53
|
+
|
54
|
+
test('renders custom icon when provided', () => {
|
55
|
+
const { container } = render(<FixedConfirmationToast icon="wrench" />);
|
56
|
+
expect(container.querySelector('.custom_icon')).toBeInTheDocument();
|
57
|
+
});
|
58
|
+
|
59
|
+
test('renders correctly with multiLine prop', () => {
|
60
|
+
const { container } = render(<FixedConfirmationToast multiLine />);
|
61
|
+
expect(container.querySelector('._multi_line')).toBeInTheDocument();
|
62
|
+
});
|
63
|
+
|
64
|
+
test('renders position when provided', () => {
|
65
|
+
const { container } = render(
|
66
|
+
<FixedConfirmationToast
|
67
|
+
horizontal="right"
|
68
|
+
vertical="bottom"
|
69
|
+
/>
|
70
|
+
);
|
71
|
+
expect(container.querySelector('.positioned_toast')).toBeInTheDocument();
|
72
|
+
});
|
@@ -1,9 +1,4 @@
|
|
1
|
-
<%=
|
2
|
-
aria: object.aria,
|
3
|
-
class: object.classname,
|
4
|
-
data: object.data,
|
5
|
-
id: object.id,
|
6
|
-
**combined_html_options) do %>
|
1
|
+
<%= pb_content_tag(:span) do %>
|
7
2
|
<%= link_to object.url, target: object.link_option do %>
|
8
3
|
<%= pb_rails("badge", props: { dark: object.dark, variant: "primary", text: object.hashtag_text }) %>
|
9
4
|
<% end %>
|
@@ -1,8 +1,4 @@
|
|
1
|
-
<%=
|
2
|
-
id: object.id,
|
3
|
-
data: object.data,
|
4
|
-
class: object.classname,
|
5
|
-
**combined_html_options) do %>
|
1
|
+
<%= pb_content_tag do %>
|
6
2
|
<%= pb_rails("home_address_street/#{emphasis}_emphasis", props: object.send("#{emphasis}_emphasis_props")) %>
|
7
3
|
<% end %>
|
8
4
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
3
3
|
import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/props'
|
4
4
|
import { GlobalProps, globalProps } from '../utilities/globalProps'
|
5
5
|
import { isValidEmoji } from '../utilities/validEmojiChecker'
|
6
|
+
import aliasesJson from './icon_aliases.json'
|
6
7
|
|
7
8
|
export type IconSizes = "lg"
|
8
9
|
| "xs"
|
@@ -40,6 +41,19 @@ type IconProps = {
|
|
40
41
|
spin?: boolean,
|
41
42
|
} & GlobalProps
|
42
43
|
|
44
|
+
type AliasType = string | string[];
|
45
|
+
|
46
|
+
interface Aliases {
|
47
|
+
[key: string]: AliasType;
|
48
|
+
}
|
49
|
+
|
50
|
+
interface AliasesJson {
|
51
|
+
aliases: Aliases;
|
52
|
+
}
|
53
|
+
|
54
|
+
const aliases: AliasesJson = aliasesJson;
|
55
|
+
|
56
|
+
|
43
57
|
const flipMap = {
|
44
58
|
horizontal: 'fa-flip-horizontal',
|
45
59
|
vertical: 'fa-flip-vertical',
|
@@ -52,6 +66,22 @@ declare global {
|
|
52
66
|
var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
|
53
67
|
}
|
54
68
|
|
69
|
+
// Resolve alias function
|
70
|
+
const resolveAlias = (icon: string): string => {
|
71
|
+
const alias = aliases.aliases[icon];
|
72
|
+
|
73
|
+
if (alias) {
|
74
|
+
if (Array.isArray(alias)) {
|
75
|
+
return alias[0];
|
76
|
+
} else {
|
77
|
+
return alias;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
return icon;
|
82
|
+
};
|
83
|
+
|
84
|
+
|
55
85
|
const Icon = (props: IconProps) => {
|
56
86
|
const {
|
57
87
|
aria = {},
|
@@ -74,7 +104,8 @@ const Icon = (props: IconProps) => {
|
|
74
104
|
spin = false,
|
75
105
|
} = props
|
76
106
|
|
77
|
-
|
107
|
+
const resolvedIcon = resolveAlias(icon as string)
|
108
|
+
let iconElement: ReactSVGElement | null = typeof(resolvedIcon) === "object" ? resolvedIcon : null
|
78
109
|
|
79
110
|
const faClasses = {
|
80
111
|
'fa-border': border,
|
@@ -90,12 +121,12 @@ const Icon = (props: IconProps) => {
|
|
90
121
|
|
91
122
|
if (!customIcon && !iconElement) {
|
92
123
|
const PowerIcon: React.FunctionComponent<any> | undefined =
|
93
|
-
window.PB_ICONS ? window.PB_ICONS[
|
124
|
+
window.PB_ICONS ? window.PB_ICONS[resolvedIcon as string] : null
|
94
125
|
|
95
126
|
if (PowerIcon) {
|
96
127
|
iconElement = <PowerIcon /> as ReactSVGElement
|
97
128
|
} else {
|
98
|
-
faClasses[`fa-${
|
129
|
+
faClasses[`fa-${resolvedIcon}`] = resolvedIcon as string
|
99
130
|
}
|
100
131
|
}
|
101
132
|
|
@@ -115,7 +146,7 @@ const Icon = (props: IconProps) => {
|
|
115
146
|
className
|
116
147
|
)
|
117
148
|
|
118
|
-
aria.label ? null : aria.label = `${
|
149
|
+
aria.label ? null : aria.label = `${resolvedIcon} icon`
|
119
150
|
const ariaProps: {[key: string]: any} = buildAriaProps(aria)
|
120
151
|
const dataProps: {[key: string]: any} = buildDataProps(data)
|
121
152
|
const htmlProps = buildHtmlProps(htmlOptions)
|
@@ -137,7 +168,7 @@ const Icon = (props: IconProps) => {
|
|
137
168
|
}
|
138
169
|
</>
|
139
170
|
)
|
140
|
-
else if (isValidEmoji(
|
171
|
+
else if (isValidEmoji(resolvedIcon as string))
|
141
172
|
return (
|
142
173
|
<>
|
143
174
|
<span
|
@@ -146,7 +177,7 @@ const Icon = (props: IconProps) => {
|
|
146
177
|
className={classesEmoji}
|
147
178
|
id={id}
|
148
179
|
>
|
149
|
-
{
|
180
|
+
{resolvedIcon}
|
150
181
|
</span>
|
151
182
|
</>
|
152
183
|
)
|
@@ -1 +1 @@
|
|
1
|
-
<%= pb_rails("icon", props: { icon: "user", fixed_width: true }) %>
|
1
|
+
<%= pb_rails("icon", props: { icon: "user", fixed_width: true }) %>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# rubocop:disable Style/HashLikeCase
|
4
4
|
|
5
5
|
require "open-uri"
|
6
|
+
require "json"
|
6
7
|
|
7
8
|
module Playbook
|
8
9
|
module PbIcon
|
@@ -38,6 +39,8 @@ module Playbook
|
|
38
39
|
prop :spin, type: Playbook::Props::Boolean,
|
39
40
|
default: false
|
40
41
|
|
42
|
+
ALIASES = JSON.parse(File.read(Playbook::Engine.root.join("app/pb_kits/playbook/pb_icon/icon_aliases.json")))["aliases"].freeze
|
43
|
+
|
41
44
|
def valid_emoji?
|
42
45
|
emoji_regex = /\p{Emoji}/
|
43
46
|
emoji_regex.match?(icon)
|
@@ -83,7 +86,8 @@ module Playbook
|
|
83
86
|
return unless Rails.application.config.respond_to?(:icon_path)
|
84
87
|
|
85
88
|
base_path = Rails.application.config.icon_path
|
86
|
-
|
89
|
+
resolved_icon = resolve_alias(icon)
|
90
|
+
icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{resolved_icon}.svg")).first
|
87
91
|
icon_path if icon_path && File.exist?(icon_path)
|
88
92
|
end
|
89
93
|
|
@@ -106,6 +110,22 @@ module Playbook
|
|
106
110
|
|
107
111
|
private
|
108
112
|
|
113
|
+
def resolve_alias(icon)
|
114
|
+
aliases = ALIASES[icon]
|
115
|
+
return icon unless aliases
|
116
|
+
|
117
|
+
if aliases.is_a?(Array)
|
118
|
+
aliases.find { |alias_name| file_exists?(alias_name) } || icon
|
119
|
+
else
|
120
|
+
aliases
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def file_exists?(alias_name)
|
125
|
+
base_path = Rails.application.config.icon_path
|
126
|
+
File.exist?(Dir.glob(Rails.root.join(base_path, "**", "#{alias_name}.svg")).first)
|
127
|
+
end
|
128
|
+
|
109
129
|
def svg_size
|
110
130
|
size.nil? ? "1x" : size
|
111
131
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"aliases": {
|
3
|
+
"arrow-alt-circle-right": "circle-right",
|
4
|
+
"angles-down": "angle-double-down",
|
5
|
+
"arrow-alt-down": "down",
|
6
|
+
"arrow-alt-up": "up",
|
7
|
+
"arrow-right-long": "long-arrow-right",
|
8
|
+
"arrow-to-bottom": "arrow-down-to-line",
|
9
|
+
"arrows-h": "arrows-left-right",
|
10
|
+
"calendar-days": "calendar-alt",
|
11
|
+
"circle-arrow-right": "arrow-circle-right",
|
12
|
+
"clock-rotate-left": "history",
|
13
|
+
"close": [
|
14
|
+
"times",
|
15
|
+
"xmark"
|
16
|
+
],
|
17
|
+
"ellipsis-h": "ellipsis",
|
18
|
+
"exclamation-circle": "circle-exclamation",
|
19
|
+
"external-link": "arrow-up-right-from-square",
|
20
|
+
"file-lines": "file-alt",
|
21
|
+
"gear": "cog",
|
22
|
+
"home": "house",
|
23
|
+
"info-circle": "circle-info",
|
24
|
+
"map-o": "map",
|
25
|
+
"message": "comment-alt",
|
26
|
+
"minus-circle": "circle-minus",
|
27
|
+
"money": "money-bill",
|
28
|
+
"mouse-pointer": "arrow-pointer",
|
29
|
+
"nitro": "nitro-n",
|
30
|
+
"play-circle": "circle-play",
|
31
|
+
"plus-circle": "circle-plus",
|
32
|
+
"plus-square": "square-plus",
|
33
|
+
"powergon": "powergon-p",
|
34
|
+
"question-circle": "circle-question",
|
35
|
+
"roofing": "product-roofing",
|
36
|
+
"shelves": "inventory",
|
37
|
+
"th-list": "table-list"
|
38
|
+
}
|
39
|
+
}
|
@@ -10,7 +10,7 @@ type ListProps = {
|
|
10
10
|
className?: string;
|
11
11
|
children: React.ReactNode[] | React.ReactNode;
|
12
12
|
dark?: boolean;
|
13
|
-
|
13
|
+
enableDrag?: boolean;
|
14
14
|
data?: Record<string, unknown>;
|
15
15
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
16
16
|
id?: string;
|
@@ -32,7 +32,7 @@ const List = (props: ListProps) => {
|
|
32
32
|
className,
|
33
33
|
dark = false,
|
34
34
|
data = {},
|
35
|
-
|
35
|
+
enableDrag = false,
|
36
36
|
htmlOptions = {},
|
37
37
|
id,
|
38
38
|
layout = "",
|
@@ -54,7 +54,7 @@ const List = (props: ListProps) => {
|
|
54
54
|
const childrenWithProps = React.Children.map(
|
55
55
|
children,
|
56
56
|
(child: React.ReactElement) => {
|
57
|
-
return React.cloneElement(child, { text, variant,
|
57
|
+
return React.cloneElement(child, { text, variant, enableDrag });
|
58
58
|
}
|
59
59
|
);
|
60
60
|
const ariaProps = buildAriaProps(aria);
|
@@ -74,7 +74,7 @@ const List = (props: ListProps) => {
|
|
74
74
|
return (
|
75
75
|
<>
|
76
76
|
{
|
77
|
-
|
77
|
+
enableDrag ? (
|
78
78
|
<Draggable.Container>
|
79
79
|
<div className={classes}>
|
80
80
|
{ordered ? (
|
@@ -11,6 +11,7 @@ type ListItemProps = {
|
|
11
11
|
children: React.ReactNode[] | React.ReactNode,
|
12
12
|
className?: string,
|
13
13
|
data?: Record<string, unknown>,
|
14
|
+
dragId?: string,
|
14
15
|
dragHandle?: boolean,
|
15
16
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
16
17
|
id?: string,
|
@@ -23,7 +24,8 @@ const ListItem = (props: ListItemProps) => {
|
|
23
24
|
children,
|
24
25
|
className,
|
25
26
|
data = {},
|
26
|
-
|
27
|
+
enableDrag,
|
28
|
+
dragId,
|
27
29
|
dragHandle = true,
|
28
30
|
htmlOptions = {},
|
29
31
|
id,
|
@@ -42,8 +44,10 @@ const ListItem = (props: ListItemProps) => {
|
|
42
44
|
return (
|
43
45
|
<>
|
44
46
|
{
|
45
|
-
|
46
|
-
<Draggable.Item
|
47
|
+
enableDrag ? (
|
48
|
+
<Draggable.Item
|
49
|
+
dragId={dragId}
|
50
|
+
>
|
47
51
|
<li
|
48
52
|
{...ariaProps}
|
49
53
|
{...dataProps}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= pb_rails("nav", props: { variant: "bold" }) do %>
|
2
|
-
<%= pb_rails("nav/item", props: { text: "Overview", link: "#", collapsible: true, icon_left:"city" }) do %>
|
2
|
+
<%= pb_rails("nav/item", props: { text: "Overview", link: "#", collapsible: true, icon_left:"city", collapsed: false }) do %>
|
3
3
|
<%= pb_rails("nav", props: { variant: "bold" }) do %>
|
4
4
|
<%= pb_rails("nav/item", props: { text: "City", link: "#" }) %>
|
5
5
|
<%= pb_rails("nav/item", props: { text: "People", link: "#" }) %>
|
@@ -1 +1,3 @@
|
|
1
|
-
The `collapsible` prop allows users to create a nested, collapsible nav. Pass `collapsible` to any NavItem and pass that navItem any number of NavItems as children to create a collapsible nav.
|
1
|
+
The `collapsible` prop allows users to create a nested, collapsible nav. Pass `collapsible` to any NavItem and pass that navItem any number of NavItems as children to create a collapsible nav.
|
2
|
+
|
3
|
+
The optional `collapsed` prop can also be used to set the default state for the collapsed nav on first render of the page. `collapsed` takes a boolean value that is set to true (meaning nav is collapsed) by default. Set it to false as shown here to have the nav open on first render.
|
@@ -12,6 +12,7 @@ module Playbook
|
|
12
12
|
default: "regular"
|
13
13
|
prop :highlighted_border, type: Playbook::Props::Boolean, default: true
|
14
14
|
prop :collapsible, type: Playbook::Props::Boolean, default: false
|
15
|
+
prop :collapsed, type: Playbook::Props::Boolean, default: true
|
15
16
|
prop :link
|
16
17
|
prop :text
|
17
18
|
prop :collapsible_trail, type: Playbook::Props::Boolean, default: false
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= pb_rails("overlay") do %>
|
2
|
+
<%= pb_rails("table", props: { size: "sm" }) do %>
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th>Column 1</th>
|
6
|
+
<th>Column 2</th>
|
7
|
+
<th>Column 3</th>
|
8
|
+
<th>Column 4</th>
|
9
|
+
<th>Column 5</th>
|
10
|
+
</tr>
|
11
|
+
</thead>
|
12
|
+
<tbody>
|
13
|
+
<% 7.times do %>
|
14
|
+
<tr>
|
15
|
+
<td>Value 1</td>
|
16
|
+
<td>Value 2</td>
|
17
|
+
<td>Value 3</td>
|
18
|
+
<td>Value 4</td>
|
19
|
+
<td>Value 5</td>
|
20
|
+
</tr>
|
21
|
+
<% end %>
|
22
|
+
</tbody>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
Overlays
|
1
|
+
Overlays optionally accept a `color`, which sets the "start" (opaque) color of a gradient mask. Because this overlay is intended to reveal underlying content, the "end" color is fixed to transparent.
|
2
2
|
|
3
|
-
The optional `layout` prop accepts
|
3
|
+
The optional `layout` prop accepts the `position` and `size` of the overlay as a key:value pair.
|
4
4
|
|
5
|
-
The `position` key accepts `
|
5
|
+
The `position` key accepts `bottom` (default), `top`, `y` (for both top and bottom) `right`, `left`, or `x` (for both left and right), which sets the side(s) where the `color` overlay starts. The direction of the overlay is always toward the opposite side of the position. For example, the default position of `bottom` starts the overlay on the bottom edge of your container and extends it toward the opposite side: the top.
|
6
6
|
|
7
|
-
The `size` value accepts our [spacing tokens](https://playbook.powerapp.cloud/visual_guidelines/spacing) or a percentage value as a string, and literally translates to how much of the container is covered by the overlay
|
7
|
+
The `size` value is `full` (100%) by default, but accepts our [spacing tokens](https://playbook.powerapp.cloud/visual_guidelines/spacing) or a percentage value as a string, and literally translates to how much of the container is covered by the overlay(s).
|