playbook_ui 13.32.0 → 13.33.0.pre.alpha.PBNTR405dropdownformfixesrails3311

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.md +4 -0
  3. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +1 -1
  4. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +12 -7
  5. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.html.erb +10 -0
  6. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.jsx +31 -0
  7. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.html.erb +10 -0
  8. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.jsx +31 -0
  9. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +4 -0
  10. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -1
  11. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +9 -5
  12. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +11 -0
  13. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +1 -1
  14. data/app/pb_kits/playbook/pb_dropdown/index.js +74 -17
  15. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +108 -5
  16. data/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx +53 -0
  17. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +11 -2
  18. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_example.html.erb +5 -1
  19. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_example.jsx +1 -0
  20. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_size.html.erb +2 -0
  21. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_size.jsx +2 -0
  22. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_tag.html.erb +4 -1
  23. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_tag.jsx +3 -2
  24. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_user.html.erb +2 -0
  25. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_user.jsx +2 -0
  26. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  27. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +5 -1
  28. data/app/pb_kits/playbook/pb_icon/_icon.scss +210 -1
  29. data/app/pb_kits/playbook/pb_icon/_icon.tsx +100 -41
  30. data/app/pb_kits/playbook/pb_icon/icon.rb +33 -19
  31. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +2 -2
  32. data/app/pb_kits/playbook/pb_nav/docs/_tab_nav.html.erb +48 -0
  33. data/app/pb_kits/playbook/pb_nav/docs/_tab_nav.md +3 -0
  34. data/app/pb_kits/playbook/pb_nav/docs/example.yml +1 -0
  35. data/app/pb_kits/playbook/pb_nav/index.js +43 -0
  36. data/app/pb_kits/playbook/pb_nav/nav.rb +9 -0
  37. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +1 -1
  38. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +1 -1
  39. data/app/pb_kits/playbook/pb_star_rating/_star_rating.scss +11 -2
  40. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.html.erb +1 -0
  41. data/app/pb_kits/playbook/pb_star_rating/docs/example.yml +1 -1
  42. data/app/pb_kits/playbook/pb_star_rating/index.js +50 -0
  43. data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +25 -5
  44. data/app/pb_kits/playbook/pb_star_rating/star_rating.rb +6 -0
  45. data/app/pb_kits/playbook/pb_table/_table.tsx +1 -1
  46. data/app/pb_kits/playbook/pb_table/index.ts +4 -4
  47. data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +1 -1
  48. data/app/pb_kits/playbook/pb_table/subcomponents/_table_cell.tsx +1 -1
  49. data/app/pb_kits/playbook/pb_table/subcomponents/_table_head.tsx +1 -1
  50. data/app/pb_kits/playbook/pb_table/subcomponents/_table_header.tsx +1 -1
  51. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +1 -1
  52. data/app/pb_kits/playbook/pb_table/table.test.js +2 -0
  53. data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +1 -1
  54. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_default.jsx +1 -1
  55. data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +45 -27
  56. data/app/pb_kits/playbook/pb_textarea/index.tsx +3 -3
  57. data/app/pb_kits/playbook/pb_time/_time.tsx +3 -3
  58. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +1 -1
  59. data/app/pb_kits/playbook/pb_timeline/_item.tsx +1 -1
  60. data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +1 -1
  61. data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +10 -10
  62. data/app/pb_kits/playbook/pb_toggle/_toggle.tsx +1 -1
  63. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +2 -2
  64. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +1 -2
  65. data/app/pb_kits/playbook/pb_treemap_chart/treemapChart.test.js +2 -0
  66. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -3
  67. data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +4 -4
  68. data/app/pb_kits/playbook/pb_typeahead/components/Control.tsx +11 -7
  69. data/app/pb_kits/playbook/pb_typeahead/components/IndicatorsContainer.tsx +8 -3
  70. data/app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx +6 -1
  71. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +18 -19
  72. data/app/pb_kits/playbook/pb_typeahead/components/Option.tsx +6 -6
  73. data/app/pb_kits/playbook/pb_typeahead/components/Placeholder.tsx +6 -6
  74. data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +3 -3
  75. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_menu_list.jsx +2 -0
  76. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.html.erb +22 -57
  77. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.jsx +2 -2
  78. data/app/pb_kits/playbook/pb_typeahead/index.ts +31 -31
  79. data/app/pb_kits/playbook/pb_user/_user.tsx +1 -1
  80. data/app/pb_kits/playbook/pb_user_badge/_user_badge.tsx +6 -6
  81. data/app/pb_kits/playbook/pb_user_badge/badges/million-dollar.tsx +236 -235
  82. data/app/pb_kits/playbook/pb_user_badge/badges/veteran.tsx +1 -1
  83. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +68 -63
  84. data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +2 -2
  85. data/app/pb_kits/playbook/playbook-rails.js +6 -0
  86. data/dist/menu.yml +1 -1
  87. data/dist/playbook-rails.js +7 -7
  88. data/lib/playbook/forms/builder/star_rating_field.rb +14 -0
  89. data/lib/playbook/forms/builder.rb +1 -0
  90. data/lib/playbook/version.rb +2 -2
  91. metadata +16 -6
  92. data/app/pb_kits/playbook/pb_icon/icon_aliases.json +0 -39
@@ -1 +1,5 @@
1
- <%= pb_rails("form_pill", props: { text_transform: "lowercase" , text: "THIS IS A TAG" }) %>
1
+ <%= pb_rails("form_pill", props: {
2
+ text_transform: "lowercase" ,
3
+ text: "THIS IS A TAG",
4
+ tabindex: 0,
5
+ }) %>
@@ -6,6 +6,7 @@ const FormPillExample = (props) => {
6
6
  <div>
7
7
  <FormPill
8
8
  onClick={() => alert('Click!')}
9
+ tabIndex={0}
9
10
  text="THIS IS A TAG"
10
11
  textTransform="lowercase"
11
12
  {...props}
@@ -2,6 +2,7 @@
2
2
  name: "Anna Black",
3
3
  avatar_url: "https://randomuser.me/api/portraits/women/44.jpg",
4
4
  size: "small",
5
+ tabindex: 0,
5
6
  }) %>
6
7
 
7
8
  <br />
@@ -10,4 +11,5 @@
10
11
  <%= pb_rails("form_pill", props: {
11
12
  name: "Anna Black",
12
13
  size: "small",
14
+ tabindex: 0,
13
15
  }) %>
@@ -9,6 +9,7 @@ const FormPillSize = (props) => {
9
9
  avatarUrl="https://randomuser.me/api/portraits/women/44.jpg"
10
10
  name="Anna Black"
11
11
  size="small"
12
+ tabIndex={0}
12
13
  {...props}
13
14
  />
14
15
  <br />
@@ -16,6 +17,7 @@ const FormPillSize = (props) => {
16
17
  <FormPill
17
18
  name="Anna Black"
18
19
  size="small"
20
+ tabIndex={0}
19
21
  {...props}
20
22
  />
21
23
  </div>
@@ -1 +1,4 @@
1
- <%= pb_rails("form_pill", props: { text: "this is a tag" }) %>
1
+ <%= pb_rails("form_pill", props: {
2
+ text: "this is a tag",
3
+ tabindex: 0,
4
+ }) %>
@@ -6,8 +6,9 @@ const FormPillDefault = (props) => {
6
6
  <div>
7
7
  <FormPill
8
8
  onClick={() => {
9
- alert('Click!')
10
- }}
9
+ alert('Click!')
10
+ }}
11
+ tabIndex={0}
11
12
  text="this is a tag"
12
13
  {...props}
13
14
  />
@@ -1,6 +1,7 @@
1
1
  <%= pb_rails("form_pill", props: {
2
2
  name: "Anna Black",
3
3
  avatar_url: "https://randomuser.me/api/portraits/women/44.jpg",
4
+ tabindex: 0,
4
5
  }) %>
5
6
 
6
7
  <br />
@@ -8,4 +9,5 @@
8
9
 
9
10
  <%= pb_rails("form_pill", props: {
10
11
  name: "Anna Black",
12
+ tabindex: 0,
11
13
  }) %>
@@ -9,6 +9,7 @@ const FormPillDefault = (props) => {
9
9
  avatarUrl="https://randomuser.me/api/portraits/women/44.jpg"
10
10
  name="Anna Black"
11
11
  onClick={() => alert('Click!')}
12
+ tabIndex={0}
12
13
  {...props}
13
14
  />
14
15
  <br />
@@ -16,6 +17,7 @@ const FormPillDefault = (props) => {
16
17
  <FormPill
17
18
  name="Anna Black"
18
19
  onClick={() => alert('Click!')}
20
+ tabIndex={0}
19
21
  {...props}
20
22
  />
21
23
  </div>
@@ -1,4 +1,4 @@
1
- <%= content_tag(:div, id: object.id, data: object.data, class: object.classname + object.size_class, **combined_html_options) do %>
1
+ <%= content_tag(:div, id: object.id, data: object.data, class: object.classname + object.size_class, tabindex: object.tabindex, **combined_html_options) do %>
2
2
  <% if object.name.present? %>
3
3
  <%= pb_rails("avatar", props: { name: object.name, image_url: object.avatar_url, size: "xs" }) %>
4
4
  <%= pb_rails("title", props: { text: object.name, size: 4, classname: "pb_form_pill_text" }) %>
@@ -11,9 +11,13 @@ module Playbook
11
11
  prop :text_transform, type: Playbook::Props::Enum,
12
12
  values: %w[none lowercase],
13
13
  default: "none"
14
+ prop :color, type: Playbook::Props::Enum,
15
+ values: %w[primary neutral],
16
+ default: "primary"
17
+ prop :tabindex
14
18
 
15
19
  def classname
16
- generate_classname("pb_form_pill_kit", "primary", name, text, text_transform)
20
+ generate_classname("pb_form_pill_kit", color, name, text, text_transform)
17
21
  end
18
22
 
19
23
  def display_text
@@ -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,213 @@ 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
+
15
+ @keyframes pb_icon_spin {
16
+ 0% {
17
+ -webkit-transform: rotate(0);
18
+ transform: rotate(0);
19
+ }
20
+ 100% {
21
+ -webkit-transform: rotate(360deg);
22
+ transform: rotate(360deg);
23
+ }
24
+ };
25
+
26
+ svg {
27
+ &.pb_icon_kit,
28
+ &.pb_custom_icon{
29
+ @each $r in $rotate-list {
30
+ &.rotate_#{$r} {
31
+ transform: rotate(#{$r}deg);
32
+ }
33
+ }
34
+ &.flip_horizontal {
35
+ transform: scaleX(-1);
36
+ }
37
+ &.flip_vertical {
38
+ transform: scaleY(-1);
39
+ }
40
+ &.flip_horizontal.flip_vertical {
41
+ transform: scaleX(-1) scaleY(-1);
42
+ }
43
+ &.svg-inline--fa {
44
+ height: 1em;
45
+ overflow: visible;
46
+ vertical-align: -.125em
47
+ }
48
+ &.svg_inverse {
49
+ color: #fff;
50
+ }
51
+ &.svg_border {
52
+ border-color: #eee;
53
+ border-radius: .1em;
54
+ border-style: solid;
55
+ border-width: .08em;
56
+ padding: .2em .25em .15em;
57
+ }
58
+ &.svg_fw {
59
+ text-align: center;
60
+ width: 1.25em
61
+ }
62
+ &.svg_li {
63
+ left: calc(2em * -1);
64
+ position: absolute;
65
+ text-align: center;
66
+ width: 2em;
67
+ line-height: inherit
68
+ }
69
+ &.pull_left {
70
+ float: left;
71
+ margin-right: .3em;
72
+ }
73
+
74
+ &.pull_right {
75
+ float: right;
76
+ margin-left: .3em;
77
+ }
78
+ &.pulse {
79
+ animation-name: pb_icon_spin;
80
+ animation-direction: normal;
81
+ animation-duration: 1s;
82
+ animation-iteration-count: infinite;
83
+ animation-timing-function: steps(8);
84
+ }
85
+ &.spin {
86
+ animation-name: pb_icon_spin;
87
+ animation-delay: 0s;
88
+ animation-direction: normal;
89
+ animation-duration: 2s;
90
+ animation-iteration-count: infinite;
91
+ animation-timing-function: linear;
92
+ }
93
+
94
+ &.svg_xs {
95
+ font-size: 0.75em
96
+ }
97
+
98
+ &.svg_sm {
99
+ font-size: 0.875em
100
+ }
101
+
102
+ &.svg_lg {
103
+ font-size: 1.25em
104
+ }
105
+
106
+ &.svg_1x {
107
+ font-size: 1em
108
+ }
109
+
110
+ &.svg_2x {
111
+ font-size: 2em
112
+ }
113
+
114
+ &.svg_3x {
115
+ font-size: 3em
116
+ }
117
+
118
+ &.svg_4x {
119
+ font-size: 4em
120
+ }
121
+
122
+ &.svg_5x {
123
+ font-size: 5em
124
+ }
125
+
126
+ &.svg_6x {
127
+ font-size: 6em
128
+ }
129
+
130
+ &.svg_7x {
131
+ font-size: 7em
132
+ }
133
+
134
+ &.svg_8x {
135
+ font-size: 8em
136
+ }
137
+
138
+ &.svg_9x {
139
+ font-size: 9em
140
+ }
141
+
142
+ &.svg_10x {
143
+ font-size: 10em
144
+ }
145
+ &.fa-xs {
146
+ font-size: .75em;
147
+ line-height: .0833333337em;
148
+ vertical-align: .125em
149
+ }
150
+ &.fa-sm {
151
+ font-size: .875em;
152
+ line-height: .0714285718em;
153
+ vertical-align: .0535714295em
154
+ }
155
+ &.fa-lg {
156
+ font-size: 1.25em;
157
+ line-height: .05em;
158
+ vertical-align: -.075em
159
+ }
160
+ &.fa-pull-left {
161
+ float: left;
162
+ margin-right: .3em;
163
+ }
164
+
165
+ &.fa-pull-right {
166
+ float: right;
167
+ margin-left: .3em;
168
+ }
169
+ &.fa-li {
170
+ left: calc(2em * -1);
171
+ position: absolute;
172
+ text-align: center;
173
+ width: 2em;
174
+ line-height: inherit
175
+ }
176
+ &.svg-inline--fa.fa-li {
177
+ width: 2em;
178
+ top: .25em
179
+ }
180
+ &.svg-inline--fa.fa-fw {
181
+ width: 1.25em;
182
+ }
183
+ &.fa-fw {
184
+ text-align: center;
185
+ width: 1.25em
186
+ }
187
+ &.fa-layers {
188
+ display: inline-block;
189
+ height: 1em;
190
+ position: relative;
191
+ text-align: center;
192
+ vertical-align: -.125em;
193
+ width: 1em
194
+ }
195
+ &.fa-2x {
196
+ font-size: 2em
197
+ }
198
+ &.fa-3x {
199
+ font-size: 3em
200
+ }
201
+ &.fa-flip {
202
+ animation-name: fa-flip;
203
+ animation-delay: 0s;
204
+ animation-direction: normal;
205
+ animation-duration: 1s;
206
+ animation-iteration-count: infinite;
207
+ animation-timing-function: ease-in-out;
208
+ }
209
+ &.fa-spin {
210
+ animation-name: fa-spin;
211
+ animation-delay: 0s;
212
+ animation-direction: normal;
213
+ animation-duration: 2s;
214
+ animation-iteration-count: infinite;
215
+ animation-timing-function: linear;
216
+ }
217
+ &.fa-pulse {
218
+ animation: fa-spin 1s infinite linear;
219
+ }
220
+ }
221
+ }
@@ -3,7 +3,6 @@ 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'
7
6
 
8
7
  export type IconSizes = "lg"
9
8
  | "xs"
@@ -41,24 +40,75 @@ type IconProps = {
41
40
  spin?: boolean,
42
41
  } & GlobalProps
43
42
 
44
- type AliasType = string | string[];
45
-
46
- interface Aliases {
47
- [key: string]: AliasType;
43
+ const flipMap = {
44
+ fa: {
45
+ horizontal: 'fa-flip-horizontal',
46
+ vertical: 'fa-flip-vertical',
47
+ both: 'fa-flip-horizontal fa-flip-vertical',
48
+ none: ''
49
+ },
50
+ svg: {
51
+ horizontal: 'flip_horizontal',
52
+ vertical: 'flip_vertical',
53
+ both: 'flip_horizontal flip_vertical',
54
+ none: ''
55
+ }
48
56
  }
49
-
50
- interface AliasesJson {
51
- aliases: Aliases;
57
+ const pulseMap = {
58
+ fa: 'fa-pulse',
59
+ svg: 'pulse'
60
+ }
61
+ const spinMap = {
62
+ fa: 'fa-spin',
63
+ svg: 'spin'
64
+ }
65
+ const rotateMap = {
66
+ fa: {
67
+ 90: 'fa-rotate-90',
68
+ 180: 'fa-rotate-180',
69
+ 270: 'fa-rotate-270'
70
+ },
71
+ svg: {
72
+ 90: 'rotate_90',
73
+ 180: 'rotate_180',
74
+ 270: 'rotate_270'
75
+ }
52
76
  }
53
77
 
54
- const aliases: AliasesJson = aliasesJson;
55
-
78
+ const sizeMap = {
79
+ fa: {
80
+ "lg": "fa-lg",
81
+ "xs": "fa-xs",
82
+ "sm": "fa-sm",
83
+ "1x": "fa-1x",
84
+ "2x": "fa-2x",
85
+ "3x": "fa-3x",
86
+ "4x": "fa-4x",
87
+ "5x": "fa-5x",
88
+ "6x": "fa-6x",
89
+ "7x": "fa-7x",
90
+ "8x": "fa-8x",
91
+ "9x": "fa-9x",
92
+ "10x": "fa-10x",
93
+ "": ""
94
+ },
95
+ svg: {
96
+ "lg": "svg_lg",
97
+ "xs": "svg_xs",
98
+ "sm": "svg_sm",
99
+ "1x": "svg_1x",
100
+ "2x": "svg_2x",
101
+ "3x": "svg_3x",
102
+ "4x": "svg_4x",
103
+ "5x": "svg_5x",
104
+ "6x": "svg_6x",
105
+ "7x": "svg_7x",
106
+ "8x": "svg_8x",
107
+ "9x": "svg_9x",
108
+ "10x": "svg_10x",
109
+ "": ""
110
+ }
56
111
 
57
- const flipMap = {
58
- horizontal: 'fa-flip-horizontal',
59
- vertical: 'fa-flip-vertical',
60
- both: 'fa-flip-horizontal fa-flip-vertical',
61
- none: ""
62
112
  }
63
113
 
64
114
  declare global {
@@ -66,22 +116,6 @@ declare global {
66
116
  var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
67
117
  }
68
118
 
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
-
85
119
  const Icon = (props: IconProps) => {
86
120
  const {
87
121
  aria = {},
@@ -104,8 +138,7 @@ const Icon = (props: IconProps) => {
104
138
  spin = false,
105
139
  } = props
106
140
 
107
- const resolvedIcon = resolveAlias(icon as string)
108
- let iconElement: ReactSVGElement | null = typeof(resolvedIcon) === "object" ? resolvedIcon : null
141
+ let iconElement: ReactSVGElement | null = typeof(icon) === "object" ? icon : null
109
142
 
110
143
  const faClasses = {
111
144
  'fa-border': border,
@@ -121,32 +154,58 @@ const Icon = (props: IconProps) => {
121
154
 
122
155
  if (!customIcon && !iconElement) {
123
156
  const PowerIcon: React.FunctionComponent<any> | undefined =
124
- window.PB_ICONS ? window.PB_ICONS[resolvedIcon as string] : null
157
+ window.PB_ICONS ? window.PB_ICONS[icon as string] : null
125
158
 
126
159
  if (PowerIcon) {
127
160
  iconElement = <PowerIcon /> as ReactSVGElement
128
161
  } else {
129
- faClasses[`fa-${resolvedIcon}`] = resolvedIcon as string
162
+ faClasses[`fa-${icon}`] = icon as string
130
163
  }
131
164
  }
132
165
 
133
- const classes = classnames(
134
- flipMap[flip],
166
+ const isFA = !iconElement && !customIcon
167
+
168
+ let classes = classnames(
135
169
  (!iconElement && !customIcon) ? 'pb_icon_kit' : '',
136
170
  (iconElement || customIcon) ? 'pb_custom_icon' : fontStyle,
137
171
  iconElement ? 'svg-inline--fa' : '',
138
- faClasses,
139
172
  globalProps(props),
140
173
  className
141
174
  )
142
175
 
176
+ const transformClasses = classnames(
177
+ flip ? flipMap[isFA ? 'fa' : 'svg'][flip] : null,
178
+ pulse ? pulseMap[isFA ? 'fa' : 'svg'] : null,
179
+ rotation ? rotateMap[isFA ? 'fa' : 'svg'][rotation] : null,
180
+ spin ? spinMap[isFA ? 'fa' : 'svg'] : null,
181
+ size ? sizeMap[isFA ? 'fa' : 'svg'][size] : null,
182
+ border ? isFA ? 'fa-border' : 'svg_border' : null,
183
+ fixedWidth ? isFA ? 'fa-fw' : 'svg_fw' : null,
184
+ inverse ? isFA ? 'fa-inverse' : 'svg_inverse' : null,
185
+ listItem ? isFA ? 'fa-li' : 'svg_li' : null,
186
+ pull ? isFA ? `fa-pull-${pull}` : `pull_${pull}` : null,
187
+ )
188
+ classes += ` ${transformClasses}`
189
+
190
+ if (isFA) {
191
+ const faClassList = {
192
+ 'fa-border': border,
193
+ 'fa-inverse': inverse,
194
+ 'fa-li': listItem,
195
+ [`fa-${size}`]: size,
196
+ [`fa-pull-${pull}`]: pull,
197
+ }
198
+ faClassList[`fa-${icon}`] = icon as string
199
+ classes += ` ${classnames(faClassList)}`
200
+ }
201
+
143
202
  const classesEmoji = classnames(
144
203
  'pb_icon_kit_emoji',
145
204
  globalProps(props),
146
205
  className
147
206
  )
148
207
 
149
- aria.label ? null : aria.label = `${resolvedIcon} icon`
208
+ aria.label ? null : aria.label = `${icon} icon`
150
209
  const ariaProps: {[key: string]: any} = buildAriaProps(aria)
151
210
  const dataProps: {[key: string]: any} = buildDataProps(data)
152
211
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -168,7 +227,7 @@ const Icon = (props: IconProps) => {
168
227
  }
169
228
  </>
170
229
  )
171
- else if (isValidEmoji(resolvedIcon as string))
230
+ else if (isValidEmoji(icon as string))
172
231
  return (
173
232
  <>
174
233
  <span
@@ -177,7 +236,7 @@ const Icon = (props: IconProps) => {
177
236
  className={classesEmoji}
178
237
  id={id}
179
238
  >
180
- {resolvedIcon}
239
+ {icon}
181
240
  </span>
182
241
  </>
183
242
  )
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/HashLikeCase
4
-
5
3
  require "open-uri"
6
4
  require "json"
7
5
 
@@ -39,8 +37,6 @@ module Playbook
39
37
  prop :spin, type: Playbook::Props::Boolean,
40
38
  default: false
41
39
 
42
- ALIASES = JSON.parse(File.read(Playbook::Engine.root.join("app/pb_kits/playbook/pb_icon/icon_aliases.json")))["aliases"].freeze
43
-
44
40
  def valid_emoji?
45
41
  emoji_regex = /\p{Emoji}/
46
42
  emoji_regex.match?(icon)
@@ -82,6 +78,14 @@ module Playbook
82
78
  )
83
79
  end
84
80
 
81
+ def icon_alias_map
82
+ return unless Rails.application.config.respond_to?(:icon_alias_path)
83
+
84
+ base_path = Rails.application.config.icon_alias_path
85
+ json = File.read(Rails.root.join(base_path))
86
+ JSON.parse(json)["aliases"].freeze
87
+ end
88
+
85
89
  def asset_path
86
90
  return unless Rails.application.config.respond_to?(:icon_path)
87
91
 
@@ -111,7 +115,9 @@ module Playbook
111
115
  private
112
116
 
113
117
  def resolve_alias(icon)
114
- aliases = ALIASES[icon]
118
+ return icon unless icon_alias_map
119
+
120
+ aliases = icon_alias_map[icon]
115
121
  return icon unless aliases
116
122
 
117
123
  if aliases.is_a?(Array)
@@ -131,11 +137,13 @@ module Playbook
131
137
  end
132
138
 
133
139
  def border_class
134
- border ? "fa-border" : nil
140
+ prefix = is_svg? ? "svg_border" : "fa-border"
141
+ border ? prefix : nil
135
142
  end
136
143
 
137
144
  def fixed_width_class
138
- fixed_width ? "fa-fw" : nil
145
+ prefix = is_svg? ? "svg_fw" : "fa-fw"
146
+ fixed_width ? prefix : nil
139
147
  end
140
148
 
141
149
  def icon_class
@@ -143,38 +151,45 @@ module Playbook
143
151
  end
144
152
 
145
153
  def inverse_class
146
- inverse ? "fa-inverse" : nil
154
+ class_name = is_svg? ? "svg_inverse" : "fa-inverse"
155
+ inverse ? class_name : nil
147
156
  end
148
157
 
149
158
  def list_item_class
150
- list_item ? "fa-li" : nil
159
+ class_name = is_svg? ? "svg_li" : "fa-li"
160
+ list_item ? class_name : nil
151
161
  end
152
162
 
153
163
  def flip_class
164
+ prefix = is_svg? ? "flip_" : "fa-flip-"
154
165
  case flip
155
166
  when "horizontal"
156
- "fa-flip-horizontal"
167
+ "#{prefix}horizontal"
157
168
  when "vertical"
158
- "fa-flip-vertical"
169
+ "#{prefix}vertical"
159
170
  when "both"
160
- "fa-flip-horizontal fa-flip-vertical"
171
+ "#{prefix}horizontal #{prefix}vertical"
161
172
  end
162
173
  end
163
174
 
164
175
  def pull_class
165
- pull ? "fa-pull-#{pull}" : nil
176
+ class_name = is_svg? ? "pull_#{pull}" : "fa-pull-#{pull}"
177
+ pull ? class_name : nil
166
178
  end
167
179
 
168
180
  def pulse_class
169
- pulse ? "fa-pulse" : nil
181
+ class_name = is_svg? ? "pulse" : "fa-pulse"
182
+ pulse ? class_name : nil
170
183
  end
171
184
 
172
185
  def rotation_class
173
- rotation ? "fa-rotate-#{rotation}" : nil
186
+ class_name = is_svg? ? "rotate_#{rotation}" : "fa-rotate-#{rotation}"
187
+ rotation ? class_name : nil
174
188
  end
175
189
 
176
190
  def size_class
177
- size ? "fa-#{size}" : nil
191
+ class_name = is_svg? ? "svg_#{size}" : "fa-#{size}"
192
+ size ? class_name : nil
178
193
  end
179
194
 
180
195
  def font_style_class
@@ -182,10 +197,9 @@ module Playbook
182
197
  end
183
198
 
184
199
  def spin_class
185
- spin ? "fa-spin" : nil
200
+ class_name = is_svg? ? "spin" : "fa-spin"
201
+ spin ? class_name : nil
186
202
  end
187
203
  end
188
204
  end
189
205
  end
190
-
191
- # rubocop:enable Style/HashLikeCase
@@ -95,11 +95,11 @@ test('should not have a left border', () => {
95
95
  test('should have a right icon', () => {
96
96
  render(<NavDefault iconRight="angle-down" />)
97
97
  const kit = screen.getByTestId(itemTestId)
98
- expect(kit).toContainHTML('<i class="pb_icon_kit far fa-fw fa-angle-down pb_nav_list_item_icon_right" />')
98
+ expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_right fa-fw fa-angle-down" />')
99
99
  })
100
100
 
101
101
  test('should have a left icon', () => {
102
102
  render(<NavDefault iconLeft="users-class" />)
103
103
  const kit = screen.getByTestId(itemTestId)
104
- expect(kit).toContainHTML('<i class="pb_icon_kit far fa-fw fa-users-class pb_nav_list_item_icon_left" />')
104
+ expect(kit).toContainHTML('<i class="pb_icon_kit far pb_nav_list_item_icon_left fa-fw fa-users-class" />')
105
105
  })