playbook_ui 13.30.0 → 13.31.0.pre.alpha.play1262iconstyles3172

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +59 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.md +6 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -2
  5. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +4 -4
  6. data/app/pb_kits/playbook/pb_card/_card.tsx +4 -3
  7. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +1 -1
  8. data/app/pb_kits/playbook/pb_collapsible/index.js +6 -1
  9. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_default_swift.md +33 -0
  10. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_props_swift.md +18 -0
  11. data/app/pb_kits/playbook/pb_date_time_stacked/docs/example.yml +6 -1
  12. data/app/pb_kits/playbook/pb_draggable/_draggable.scss +2 -4
  13. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +70 -50
  14. data/app/pb_kits/playbook/pb_draggable/context/types.ts +26 -0
  15. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +2 -1
  16. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +1 -1
  17. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers.jsx +5 -1
  18. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.jsx +11 -4
  19. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.md +4 -2
  20. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.jsx +2 -2
  21. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +7 -1
  22. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.jsx +6 -4
  23. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.md +7 -0
  24. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +142 -15
  25. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -5
  26. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +18 -0
  27. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +228 -218
  28. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +9 -0
  29. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +34 -0
  30. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
  31. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
  32. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +14 -12
  33. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +7 -0
  34. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -2
  35. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +9 -3
  36. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.html.erb +32 -0
  37. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.jsx +48 -0
  38. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
  39. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +1 -0
  40. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +16 -11
  41. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.test.js +72 -0
  42. data/app/pb_kits/playbook/pb_icon/_icon.scss +211 -1
  43. data/app/pb_kits/playbook/pb_icon/_icon.tsx +136 -13
  44. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.html.erb +1 -1
  45. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +2 -3
  46. data/app/pb_kits/playbook/pb_icon/icon.rb +43 -17
  47. data/app/pb_kits/playbook/pb_icon/icon_aliases.json +39 -0
  48. data/app/pb_kits/playbook/pb_list/_list.tsx +4 -4
  49. data/app/pb_kits/playbook/pb_list/_list_item.tsx +7 -3
  50. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +2 -2
  51. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.html.erb +1 -1
  52. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.jsx +1 -0
  53. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.md +3 -1
  54. data/app/pb_kits/playbook/pb_nav/item.html.erb +1 -1
  55. data/app/pb_kits/playbook/pb_nav/item.rb +1 -0
  56. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.html.erb +24 -0
  57. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.md +4 -4
  58. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_multi_directional.html.erb +11 -0
  59. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +4 -0
  60. data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +27 -0
  61. data/app/pb_kits/playbook/pb_overlay/overlay.rb +110 -0
  62. data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +7 -3
  63. data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +3 -3
  64. data/app/pb_kits/playbook/pb_table/table_header.html.erb +16 -2
  65. data/app/pb_kits/playbook/pb_timeline/_item.tsx +11 -10
  66. data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +8 -6
  67. data/app/pb_kits/playbook/utilities/globalProps.ts +1 -0
  68. data/dist/menu.yml +2 -2
  69. data/dist/playbook-rails.js +7 -7
  70. data/lib/playbook/version.rb +2 -2
  71. metadata +21 -5
@@ -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
- {icon && (
95
+ {returnedIcon && (
90
96
  <Icon
91
97
  className="pb_icon"
92
98
  fixedWidth
93
- icon={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>
@@ -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
- when "success"
47
- "check"
48
- when "error"
49
- "exclamation-triangle"
50
- when "neutral"
51
- "info-circle"
52
- when "tip"
53
- "info-circle"
54
- end
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,4 +1,3 @@
1
- // Rails custom icon styles
2
1
  svg.pb_custom_icon {
3
2
  width: 1em;
4
3
  fill: currentColor;
@@ -10,3 +9,214 @@ svg.pb_custom_icon {
10
9
  .pb_icon_kit_emoji {
11
10
  font-family: monospace;
12
11
  }
12
+
13
+ $rotate-list: (90, 180, 270);
14
+ $flip-list: (
15
+ "horizontal": (-1, 1),
16
+ "vertical": (1, -1),
17
+ "both": (-1, -1)
18
+ );
19
+
20
+ @keyframes pb_icon_spin {
21
+ 0% {
22
+ -webkit-transform: rotate(0);
23
+ transform: rotate(0);
24
+ }
25
+ 100% {
26
+ -webkit-transform: rotate(360deg);
27
+ transform: rotate(360deg);
28
+ }
29
+ };
30
+
31
+ svg {
32
+ &.pb_icon_kit,
33
+ &.pb_custom_icon{
34
+ @each $r in $rotate-list {
35
+ &.rotate_#{$r} {
36
+ transform: rotate(#{$r}deg);
37
+ }
38
+ }
39
+ @each $f, $v in $flip-list {
40
+ &.flip_#{$f} {
41
+ transform: scale($v);
42
+ }
43
+ }
44
+ &.svg-inline--fa {
45
+ height: 1em;
46
+ overflow: visible;
47
+ vertical-align: -.125em
48
+ }
49
+ &.svg_inverse {
50
+ color: #fff;
51
+ }
52
+ &.svg_border {
53
+ border-color: #eee;
54
+ border-radius: .1em;
55
+ border-style: solid;
56
+ border-width: .08em;
57
+ padding: .2em .25em .15em;
58
+ }
59
+ &.svg_fw {
60
+ text-align: center;
61
+ width: 1.25em
62
+ }
63
+ &.svg_li {
64
+ left: calc(2em * -1);
65
+ position: absolute;
66
+ text-align: center;
67
+ width: 2em;
68
+ line-height: inherit
69
+ }
70
+ &.pull_left {
71
+ float: left;
72
+ margin-right: .3em;
73
+ }
74
+
75
+ &.pull_right {
76
+ float: right;
77
+ margin-left: .3em;
78
+ }
79
+ &.pulse {
80
+ animation-name: pb_icon_spin;
81
+ animation-direction: normal;
82
+ animation-duration: 1s;
83
+ animation-iteration-count: infinite;
84
+ animation-timing-function: steps(8);
85
+ }
86
+ &.spin {
87
+ animation-name: pb_icon_spin;
88
+ animation-delay: 0s;
89
+ animation-direction: normal;
90
+ animation-duration: 2s;
91
+ animation-iteration-count: infinite;
92
+ animation-timing-function: linear;
93
+ }
94
+
95
+ &.svg_xs {
96
+ font-size: 0.75em
97
+ }
98
+
99
+ &.svg_sm {
100
+ font-size: 0.875em
101
+ }
102
+
103
+ &.svg_lg {
104
+ font-size: 1.25em
105
+ }
106
+
107
+ &.svg_1x {
108
+ font-size: 1em
109
+ }
110
+
111
+ &.svg_2x {
112
+ font-size: 2em
113
+ }
114
+
115
+ &.svg_3x {
116
+ font-size: 3em
117
+ }
118
+
119
+ &.svg_4x {
120
+ font-size: 4em
121
+ }
122
+
123
+ &.svg_5x {
124
+ font-size: 5em
125
+ }
126
+
127
+ &.svg_6x {
128
+ font-size: 6em
129
+ }
130
+
131
+ &.svg_7x {
132
+ font-size: 7em
133
+ }
134
+
135
+ &.svg_8x {
136
+ font-size: 8em
137
+ }
138
+
139
+ &.svg_9x {
140
+ font-size: 9em
141
+ }
142
+
143
+ &.svg_10x {
144
+ font-size: 10em
145
+ }
146
+ &.fa-xs {
147
+ font-size: .75em;
148
+ line-height: .0833333337em;
149
+ vertical-align: .125em
150
+ }
151
+ &.fa-sm {
152
+ font-size: .875em;
153
+ line-height: .0714285718em;
154
+ vertical-align: .0535714295em
155
+ }
156
+ &.fa-lg {
157
+ font-size: 1.25em;
158
+ line-height: .05em;
159
+ vertical-align: -.075em
160
+ }
161
+ &.fa-pull-left {
162
+ float: left;
163
+ margin-right: .3em;
164
+ }
165
+
166
+ &.fa-pull-right {
167
+ float: right;
168
+ margin-left: .3em;
169
+ }
170
+ &.fa-li {
171
+ left: calc(2em * -1);
172
+ position: absolute;
173
+ text-align: center;
174
+ width: 2em;
175
+ line-height: inherit
176
+ }
177
+ &.svg-inline--fa.fa-li {
178
+ width: 2em;
179
+ top: .25em
180
+ }
181
+ &.svg-inline--fa.fa-fw {
182
+ width: 1.25em;
183
+ }
184
+ &.fa-fw {
185
+ text-align: center;
186
+ width: 1.25em
187
+ }
188
+ &.fa-layers {
189
+ display: inline-block;
190
+ height: 1em;
191
+ position: relative;
192
+ text-align: center;
193
+ vertical-align: -.125em;
194
+ width: 1em
195
+ }
196
+ &.fa-2x {
197
+ font-size: 2em
198
+ }
199
+ &.fa-3x {
200
+ font-size: 3em
201
+ }
202
+ &.fa-flip {
203
+ animation-name: fa-flip;
204
+ animation-delay: 0s;
205
+ animation-direction: normal;
206
+ animation-duration: 1s;
207
+ animation-iteration-count: infinite;
208
+ animation-timing-function: ease-in-out;
209
+ }
210
+ &.fa-spin {
211
+ animation-name: fa-spin;
212
+ animation-delay: 0s;
213
+ animation-direction: normal;
214
+ animation-duration: 2s;
215
+ animation-iteration-count: infinite;
216
+ animation-timing-function: linear;
217
+ }
218
+ &.fa-pulse {
219
+ animation: fa-spin 1s infinite linear;
220
+ }
221
+ }
222
+ }
@@ -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,11 +41,88 @@ 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
- horizontal: 'fa-flip-horizontal',
45
- vertical: 'fa-flip-vertical',
46
- both: 'fa-flip-horizontal fa-flip-vertical',
47
- none: ""
58
+ fa: {
59
+ horizontal: 'fa-flip-horizontal',
60
+ vertical: 'fa-flip-vertical',
61
+ both: 'fa-flip-horizontal fa-flip-vertical',
62
+ none: ''
63
+ },
64
+ svg: {
65
+ horizontal: 'flip_horizontal',
66
+ vertical: 'flip_vertical',
67
+ both: 'flip_horizontal flip_vertical',
68
+ none: ''
69
+ }
70
+ }
71
+ const pulseMap = {
72
+ fa: 'fa-pulse',
73
+ svg: 'pulse'
74
+ }
75
+ const spinMap = {
76
+ fa: 'fa-spin',
77
+ svg: 'spin'
78
+ }
79
+ const rotateMap = {
80
+ fa: {
81
+ 90: 'fa-rotate-90',
82
+ 180: 'fa-rotate-180',
83
+ 270: 'fa-rotate-270'
84
+ },
85
+ svg: {
86
+ 90: 'rotate_90',
87
+ 180: 'rotate_180',
88
+ 270: 'rotate_270'
89
+ }
90
+ }
91
+
92
+ const sizeMap = {
93
+ fa: {
94
+ "lg": "fa-lg",
95
+ "xs": "fa-xs",
96
+ "sm": "fa-sm",
97
+ "1x": "fa-1x",
98
+ "2x": "fa-2x",
99
+ "3x": "fa-3x",
100
+ "4x": "fa-4x",
101
+ "5x": "fa-5x",
102
+ "6x": "fa-6x",
103
+ "7x": "fa-7x",
104
+ "8x": "fa-8x",
105
+ "9x": "fa-9x",
106
+ "10x": "fa-10x",
107
+ "": ""
108
+ },
109
+ svg: {
110
+ "lg": "svg_lg",
111
+ "xs": "svg_xs",
112
+ "sm": "svg_sm",
113
+ "1x": "svg_1x",
114
+ "2x": "svg_2x",
115
+ "3x": "svg_3x",
116
+ "4x": "svg_4x",
117
+ "5x": "svg_5x",
118
+ "6x": "svg_6x",
119
+ "7x": "svg_7x",
120
+ "8x": "svg_8x",
121
+ "9x": "svg_9x",
122
+ "10x": "svg_10x",
123
+ "": ""
124
+ }
125
+
48
126
  }
49
127
 
50
128
  declare global {
@@ -52,6 +130,22 @@ declare global {
52
130
  var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
53
131
  }
54
132
 
133
+ // Resolve alias function
134
+ const resolveAlias = (icon: string): string => {
135
+ const alias = aliases.aliases[icon];
136
+
137
+ if (alias) {
138
+ if (Array.isArray(alias)) {
139
+ return alias[0];
140
+ } else {
141
+ return alias;
142
+ }
143
+ }
144
+
145
+ return icon;
146
+ };
147
+
148
+
55
149
  const Icon = (props: IconProps) => {
56
150
  const {
57
151
  aria = {},
@@ -74,7 +168,8 @@ const Icon = (props: IconProps) => {
74
168
  spin = false,
75
169
  } = props
76
170
 
77
- let iconElement: ReactSVGElement | null = typeof(icon) === "object" ? icon : null
171
+ const resolvedIcon = resolveAlias(icon as string)
172
+ let iconElement: ReactSVGElement | null = typeof(resolvedIcon) === "object" ? resolvedIcon : null
78
173
 
79
174
  const faClasses = {
80
175
  'fa-border': border,
@@ -90,32 +185,60 @@ const Icon = (props: IconProps) => {
90
185
 
91
186
  if (!customIcon && !iconElement) {
92
187
  const PowerIcon: React.FunctionComponent<any> | undefined =
93
- window.PB_ICONS ? window.PB_ICONS[icon as string] : null
188
+ window.PB_ICONS ? window.PB_ICONS[resolvedIcon as string] : null
94
189
 
95
190
  if (PowerIcon) {
96
191
  iconElement = <PowerIcon /> as ReactSVGElement
97
192
  } else {
98
- faClasses[`fa-${icon}`] = icon as string
193
+ faClasses[`fa-${resolvedIcon}`] = resolvedIcon as string
99
194
  }
100
195
  }
101
196
 
102
- const classes = classnames(
103
- flipMap[flip],
197
+ const isFA = !iconElement && !customIcon
198
+
199
+ let classes = classnames(
104
200
  (!iconElement && !customIcon) ? 'pb_icon_kit' : '',
105
201
  (iconElement || customIcon) ? 'pb_custom_icon' : fontStyle,
106
202
  iconElement ? 'svg-inline--fa' : '',
107
- faClasses,
203
+ isFA? fontStyle : null,
108
204
  globalProps(props),
109
205
  className
110
206
  )
111
207
 
208
+ const transformClasses = classnames(
209
+ flip ? flipMap[isFA ? 'fa' : 'svg'][flip] : null,
210
+ pulse ? pulseMap[isFA ? 'fa' : 'svg'] : null,
211
+ rotation ? rotateMap[isFA ? 'fa' : 'svg'][rotation] : null,
212
+ spin ? spinMap[isFA ? 'fa' : 'svg'] : null,
213
+ size ? sizeMap[isFA ? 'fa' : 'svg'][size] : null,
214
+ border ? isFA ? 'fa-border' : 'svg_border' : null,
215
+ fixedWidth ? isFA ? 'fa-fw' : 'svg_fw' : null,
216
+ inverse ? isFA ? 'fa-inverse' : 'svg_inverse' : null,
217
+ listItem ? isFA ? 'fa-li' : 'svg_li' : null,
218
+ pull ? isFA ? `fa-pull-${pull}` : `pull_${pull}` : null,
219
+ )
220
+ classes += ` ${transformClasses}`
221
+
222
+ if (isFA) {
223
+ const faClassList = {
224
+ 'fa-border': border,
225
+ 'fa-fw': (iconElement) ? false : fixedWidth,
226
+ 'fa-inverse': inverse,
227
+ 'fa-li': listItem,
228
+ [`fa-${size}`]: size,
229
+ [`fa-pull-${pull}`]: pull,
230
+ }
231
+ faClassList[`fa-${icon}`] = icon as string
232
+ classes += ` ${classnames(faClassList)}`
233
+ }
234
+
112
235
  const classesEmoji = classnames(
113
236
  'pb_icon_kit_emoji',
114
237
  globalProps(props),
115
238
  className
116
239
  )
117
240
 
118
- aria.label ? null : aria.label = `${icon} icon`
241
+ aria.label ? null : aria.label = `${resolvedIcon} icon`
119
242
  const ariaProps: {[key: string]: any} = buildAriaProps(aria)
120
243
  const dataProps: {[key: string]: any} = buildDataProps(data)
121
244
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -137,7 +260,7 @@ const Icon = (props: IconProps) => {
137
260
  }
138
261
  </>
139
262
  )
140
- else if (isValidEmoji(icon as string))
263
+ else if (isValidEmoji(resolvedIcon as string))
141
264
  return (
142
265
  <>
143
266
  <span
@@ -146,7 +269,7 @@ const Icon = (props: IconProps) => {
146
269
  className={classesEmoji}
147
270
  id={id}
148
271
  >
149
- {icon}
272
+ {resolvedIcon}
150
273
  </span>
151
274
  </>
152
275
  )