playbook_ui 13.33.1 → 13.34.0.pre.alpha.PBNTR358responsiveadvancedtablereact3366

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +5 -2
  3. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +25 -20
  4. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +17 -12
  5. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +55 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +5 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +30 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.jsx +82 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  11. data/app/pb_kits/playbook/pb_background/background.html.erb +2 -11
  12. data/app/pb_kits/playbook/pb_body/body.html.erb +1 -6
  13. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +1 -6
  14. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +1 -6
  15. data/app/pb_kits/playbook/pb_caption/caption.html.erb +1 -6
  16. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -7
  17. data/app/pb_kits/playbook/pb_collapsible/_collapsible.scss +1 -1
  18. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_color.jsx +2 -2
  19. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main.jsx +31 -32
  20. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_rails.html.erb +3 -2
  21. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_with_icon.jsx +33 -32
  22. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_with_icon_rails.html.erb +3 -7
  23. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_icons.jsx +1 -0
  24. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_state.jsx +9 -0
  25. data/app/pb_kits/playbook/pb_contact/_contact.tsx +25 -19
  26. data/app/pb_kits/playbook/pb_contact/contact.html.erb +6 -3
  27. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +71 -64
  28. data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
  29. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -6
  30. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +1 -6
  31. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +2 -5
  32. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +1 -6
  33. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +7 -3
  34. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +1 -1
  35. data/app/pb_kits/playbook/pb_dropdown/index.js +37 -31
  36. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  37. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +4 -0
  38. data/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx +11 -0
  39. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +52 -17
  40. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_icon.html.erb +5 -0
  41. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_icon.jsx +19 -0
  42. data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +2 -1
  43. data/app/pb_kits/playbook/pb_form_pill/docs/index.js +1 -1
  44. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +16 -9
  45. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +6 -1
  46. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  47. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  48. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  49. data/app/pb_kits/playbook/pb_icon/_icon.scss +17 -0
  50. data/app/pb_kits/playbook/pb_icon/_icon.tsx +3 -0
  51. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.html.erb +5 -0
  52. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.jsx +34 -0
  53. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.md +1 -0
  54. data/app/pb_kits/playbook/pb_icon/docs/example.yml +2 -0
  55. data/app/pb_kits/playbook/pb_icon/docs/index.js +1 -0
  56. data/app/pb_kits/playbook/pb_icon/icon.rb +9 -1
  57. data/app/pb_kits/playbook/pb_icon/icon.test.js +22 -9
  58. data/app/pb_kits/playbook/pb_star_rating/_star_rating.tsx +132 -201
  59. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_hide.jsx +28 -33
  60. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.jsx +14 -0
  61. data/app/pb_kits/playbook/pb_star_rating/docs/index.js +2 -0
  62. data/app/pb_kits/playbook/pb_star_rating/stars/utils.tsx +81 -0
  63. data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_display.tsx +56 -0
  64. data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_interactive.tsx +64 -0
  65. data/dist/playbook-rails.js +6 -6
  66. data/lib/playbook/version.rb +2 -2
  67. metadata +15 -5
@@ -8,9 +8,9 @@ const DOWN_ARROW_SELECTOR = "#dropdown_open_icon";
8
8
  const UP_ARROW_SELECTOR = "#dropdown_close_icon";
9
9
  const OPTION_SELECTOR = "[data-dropdown-option-label]";
10
10
  const CUSTOM_DISPLAY_SELECTOR = "[data-dropdown-custom-trigger]";
11
- const INPUT_FORM_VALIDATION = "#dropdown-form-validation";
12
11
  const DROPDOWN_TRIGGER_DISPLAY = "#dropdown_trigger_display";
13
12
  const DROPDOWN_PLACEHOLDER = "[data-dropdown-placeholder]";
13
+ const DROPDOWN_INPUT = "#dropdown-selected-option";
14
14
 
15
15
  export default class PbDropdown extends PbEnhancedElement {
16
16
  static get selector() {
@@ -47,14 +47,13 @@ export default class PbDropdown extends PbEnhancedElement {
47
47
 
48
48
  handleOptionClick(event) {
49
49
  const option = event.target.closest(OPTION_SELECTOR);
50
- const hiddenInput = this.element.querySelector("#dropdown-selected-option");
51
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
50
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
52
51
 
53
52
  if (option) {
54
53
  const value = option.dataset.dropdownOptionLabel;
55
54
  hiddenInput.value = JSON.parse(value).id;
56
- inputFormValidation.value = JSON.parse(value).id;
57
- this.clearFormValidation(inputFormValidation);
55
+ this.clearFormValidation(hiddenInput);
56
+
58
57
  this.onOptionSelected(value, option);
59
58
  }
60
59
  }
@@ -160,14 +159,18 @@ export default class PbDropdown extends PbEnhancedElement {
160
159
  }
161
160
 
162
161
  handleFormValidation() {
163
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
164
-
165
- inputFormValidation.addEventListener("invalid", function (event) {
166
- if (inputFormValidation.hasAttribute("required") && inputFormValidation.value === "") {
167
- event.preventDefault();
168
- inputFormValidation.closest(".dropdown_wrapper").classList.add("error");
169
- }
170
- }, true);
162
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
163
+
164
+ hiddenInput.addEventListener(
165
+ "invalid",
166
+ function (event) {
167
+ if (hiddenInput.hasAttribute("required") && hiddenInput.value === "") {
168
+ event.preventDefault();
169
+ hiddenInput.closest(".dropdown_wrapper").classList.add("error");
170
+ }
171
+ },
172
+ true
173
+ );
171
174
  }
172
175
 
173
176
  clearFormValidation(input) {
@@ -175,7 +178,9 @@ export default class PbDropdown extends PbEnhancedElement {
175
178
  const dropdownWrapperElement = input.closest(".dropdown_wrapper");
176
179
  dropdownWrapperElement.classList.remove("error");
177
180
 
178
- const errorLabelElement = dropdownWrapperElement.querySelector(".pb_body_kit_negative");
181
+ const errorLabelElement = dropdownWrapperElement.querySelector(
182
+ ".pb_body_kit_negative"
183
+ );
179
184
  if (errorLabelElement) {
180
185
  errorLabelElement.remove();
181
186
  }
@@ -183,23 +188,22 @@ export default class PbDropdown extends PbEnhancedElement {
183
188
  }
184
189
 
185
190
  setDefaultValue() {
186
- const hiddenInput = this.element.querySelector("#dropdown-selected-option");
191
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
192
+ const options = this.element.querySelectorAll(OPTION_SELECTOR);
187
193
 
188
- if (hiddenInput.value) {
189
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
190
- const defaultValue = JSON.parse(hiddenInput.value.replaceAll("=>", ":"));
191
- const options = this.element.querySelectorAll(OPTION_SELECTOR);
194
+ const defaultValue = hiddenInput.dataset.defaultValue || "";
195
+ hiddenInput.value = defaultValue;
192
196
 
193
- options.forEach((option) => {
194
- if (defaultValue.id === JSON.parse(option.dataset.dropdownOptionLabel).id) {
195
- option.classList.add("pb_dropdown_option_selected");
196
- }
197
+ if (defaultValue) {
198
+ const selectedOption = Array.from(options).find((option) => {
199
+ return (
200
+ JSON.parse(option.dataset.dropdownOptionLabel).id === defaultValue
201
+ );
197
202
  });
198
-
199
- this.setTriggerElementText(defaultValue.label);
200
-
201
- hiddenInput.value = defaultValue.id;
202
- inputFormValidation.value = defaultValue.id;
203
+ selectedOption.classList.add("pb_dropdown_option_selected");
204
+ this.setTriggerElementText(
205
+ JSON.parse(selectedOption.dataset.dropdownOptionLabel).label
206
+ );
203
207
  }
204
208
  }
205
209
 
@@ -214,11 +218,13 @@ export default class PbDropdown extends PbEnhancedElement {
214
218
  }
215
219
 
216
220
  resetDropdownValue() {
217
- const hiddenInput = this.element.querySelector("#dropdown-selected-option");
218
- const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
221
+ const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
222
+ const options = this.element.querySelectorAll(OPTION_SELECTOR);
223
+ options.forEach((option) => {
224
+ option.classList.remove("pb_dropdown_option_selected");
225
+ });
219
226
 
220
227
  hiddenInput.value = "";
221
- inputFormValidation.value = "";
222
228
 
223
229
  const defaultPlaceholder = this.element.querySelector(DROPDOWN_PLACEHOLDER);
224
230
  this.setTriggerElementText(defaultPlaceholder.dataset.dropdownPlaceholder);
@@ -1,7 +1,3 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
6
2
  <%= content.presence %>
7
3
  <% end %>
@@ -89,6 +89,10 @@ $form_pill_colors: (
89
89
  outline: $primary solid 2px;
90
90
  outline-offset: -1px;
91
91
  }
92
+ .pb_form_pill_icon {
93
+ height: 12px !important;
94
+ width: 12px !important;
95
+ }
92
96
  &.small {
93
97
  height: fit-content;
94
98
  height: -moz-fit-content;
@@ -50,4 +50,15 @@ test('displays size variant', () => {
50
50
  )
51
51
  const kit = screen.getByTestId('formpill')
52
52
  expect(kit).toHaveClass(`pb_form_pill_kit_primary small none`)
53
+ });
54
+
55
+ test('displays icon', () => {
56
+ render(
57
+ <FormPill
58
+ data={{ testid: testId }}
59
+ icon={"test"}
60
+ />
61
+ )
62
+ const kit = screen.getByTestId('formpill')
63
+ expect(kit).toHaveClass(`pb_form_pill_kit_primary_icon none`)
53
64
  });
@@ -21,6 +21,7 @@ type FormPillProps = {
21
21
  color?: "primary" | "neutral",
22
22
  data?: {[key: string]: string},
23
23
  tabIndex?: number,
24
+ icon?: string,
24
25
  closeProps?: {
25
26
  onClick?: React.MouseEventHandler<HTMLSpanElement>,
26
27
  onMouseDown?: React.MouseEventHandler<HTMLSpanElement>,
@@ -42,9 +43,12 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
42
43
  color = "primary",
43
44
  data = {},
44
45
  tabIndex,
46
+ icon = "",
45
47
  } = props
48
+
49
+ const iconClass = icon ? "_icon" : ""
46
50
  const css = classnames(
47
- `pb_form_pill_kit_${color}`,
51
+ `pb_form_pill_kit_${color}${iconClass}`,
48
52
  globalProps(props),
49
53
  className,
50
54
  size === 'small' ? 'small' : null,
@@ -61,29 +65,60 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
61
65
  {...dataProps}
62
66
  {...htmlProps}
63
67
  >
64
- {name &&
68
+ {((name && !icon && !text) || (name && !icon && text)) && (
65
69
  <>
66
- <Avatar
67
- imageUrl={avatarUrl}
68
- name={name}
69
- size="xs"
70
- status={null}
71
- />
72
- <Title
73
- className="pb_form_pill_text"
74
- size={4}
75
- text={name}
76
- />
70
+ <Avatar
71
+ imageUrl={avatarUrl}
72
+ name={name}
73
+ size="xs"
74
+ status={null}
75
+ />
76
+ <Title
77
+ className="pb_form_pill_text"
78
+ size={4}
79
+ text={name}
80
+ />
77
81
  </>
78
- }
79
-
80
- {text &&
82
+ )}
83
+ {((name && icon && !text) || (name && icon && text)) && (
84
+ <>
85
+ <Avatar
86
+ imageUrl={avatarUrl}
87
+ name={name}
88
+ size="xs"
89
+ status={null}
90
+ />
91
+ <Title
92
+ className="pb_form_pill_text"
93
+ size={4}
94
+ text={name}
95
+ />
96
+ <Icon
97
+ className="pb_form_pill_icon"
98
+ icon={icon}
99
+ />
100
+ </>
101
+ )}
102
+ {(!name && icon && text) && (
103
+ <>
104
+ <Icon
105
+ className="pb_form_pill_icon"
106
+ icon={icon}
107
+ />
108
+ <Title
109
+ className="pb_form_pill_tag"
110
+ size={4}
111
+ text={text}
112
+ />
113
+ </>
114
+ )}
115
+ {(!name && !icon && text) && (
81
116
  <Title
82
117
  className="pb_form_pill_tag"
83
118
  size={4}
84
119
  text={text}
85
120
  />
86
- }
121
+ )}
87
122
  <div
88
123
  className="pb_form_pill_close"
89
124
  onClick={onClick}
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("form_pill", props: {
2
+ icon: "badge-check",
3
+ text: "icon and tag",
4
+ tabindex: 0,
5
+ }) %>
@@ -0,0 +1,19 @@
1
+ import React from 'react'
2
+ import FormPill from '../_form_pill'
3
+
4
+ const FormPillIcon = (props) => {
5
+ return (
6
+ <div>
7
+ <FormPill
8
+ icon="badge-check"
9
+ onClick={() => {
10
+ alert('Click!')
11
+ }}
12
+ tabIndex={0}
13
+ text="icon and tag"
14
+ {...props}
15
+ />
16
+ </div>
17
+ )
18
+ }
19
+ export default FormPillIcon
@@ -5,10 +5,11 @@ examples:
5
5
  - form_pill_size: Form Pill Size
6
6
  - form_pill_tag: Form Pill Tag
7
7
  - form_pill_example: Example
8
-
8
+ # - form_pill_icon: Form Pill Icon
9
9
 
10
10
  react:
11
11
  - form_pill_user: Form Pill User
12
12
  - form_pill_size: Form Pill Size
13
13
  - form_pill_tag: Form Pill Tag
14
14
  - form_pill_example: Example
15
+ # - form_pill_icon: Form Pill Icon
@@ -2,4 +2,4 @@ export { default as FormPillUser } from './_form_pill_user.jsx'
2
2
  export { default as FormPillSize } from './_form_pill_size.jsx'
3
3
  export { default as FormPillTag } from './_form_pill_tag.jsx'
4
4
  export { default as FormPillExample } from './_form_pill_example.jsx'
5
-
5
+ export { default as FormPillIcon } from './_form_pill_icon.jsx'
@@ -1,12 +1,19 @@
1
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
- <%= pb_rails("title", props: { text: object.name, size: 4, classname: "pb_form_pill_text" }) %>
5
- <% elsif object.text.present? %>
6
- <%= pb_rails("title", props: { text: object.text, size: 4, classname: "pb_form_pill_tag" }) %>
7
- <% end %>
8
-
9
- <%= pb_rails("body", props: { classname: "pb_form_pill_close" }) do %>
10
- <%= pb_rails("icon", props: { icon: 'times' , fixed_width: true }) %>
11
- <% end %>
12
- <% end %>
4
+ <%= pb_rails("title", props: { text: object.name, size: 4, classname: "pb_form_pill_text" }) %>
5
+ <% if object.icon.present? %>
6
+ <%= pb_rails("icon", props: { classname: "pb_form_pill_icon", icon: object.icon }) %>
7
+ <% end %>
8
+ <% elsif object.text.present? %>
9
+ <% if object.icon.present? %>
10
+ <%= pb_rails("icon", props: { classname: "pb_form_pill_icon", icon: object.icon }) %>
11
+ <% end %>
12
+ <% if object.text.present? %>
13
+ <%= pb_rails("title", props: { text: object.text, size: 4, classname: "pb_form_pill_tag" }) %>
14
+ <% end %>
15
+ <% end %>
16
+ <%= pb_rails("body", props: { classname: "pb_form_pill_close" }) do %>
17
+ <%= pb_rails("icon", props: { icon: 'times' , fixed_width: true }) %>
18
+ <% end %>
19
+ <% end %>
@@ -15,9 +15,10 @@ module Playbook
15
15
  values: %w[primary neutral],
16
16
  default: "primary"
17
17
  prop :tabindex
18
+ prop :icon
18
19
 
19
20
  def classname
20
- generate_classname("pb_form_pill_kit", color, name, text, text_transform)
21
+ generate_classname("pb_form_pill_kit", color, icon_class, name, text, text_transform)
21
22
  end
22
23
 
23
24
  def display_text
@@ -27,6 +28,10 @@ module Playbook
27
28
  def size_class
28
29
  size == "small" ? " small" : ""
29
30
  end
31
+
32
+ def icon_class
33
+ icon ? "icon" : nil
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -1,9 +1,4 @@
1
- <%= content_tag(:span,
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
- <%= content_tag(:span,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:span) do %>
6
2
  <mark>
7
3
  <%= content.presence || object.text %>
8
4
  </mark>
@@ -1,8 +1,4 @@
1
- <%= content_tag(:div,
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
 
@@ -1,3 +1,20 @@
1
+ @import "../tokens/colors";
2
+
3
+ // All the merges below create $icon_colors, a map of all color tokens in colors.scss
4
+ $merge_kits1: map-merge($status_colors, $category_colors);
5
+ $merge_kits2: map-merge($merge_kits1, $product_colors);
6
+ $merge_kits3: map-merge($merge_kits2, $text_colors);
7
+ $icon_colors: map-merge($merge_kits3, $data_colors);
8
+
9
+ .pb_custom_icon, .pb_icon_kit {
10
+ @each $color_name, $color_value in $icon_colors {
11
+ &[class*="#{$color_name}"] {
12
+ color: $color_value;
13
+ }
14
+ }
15
+ }
16
+
17
+ // Rails custom icon styles
1
18
  svg.pb_custom_icon {
2
19
  width: 1em;
3
20
  fill: currentColor;
@@ -23,6 +23,7 @@ type IconProps = {
23
23
  aria?: {[key: string]: string},
24
24
  border?: string,
25
25
  className?: string,
26
+ color?: string,
26
27
  customIcon?: {[key: string] :SVGElement},
27
28
  data?: {[key: string]: string},
28
29
  fixedWidth?: boolean,
@@ -121,6 +122,7 @@ const Icon = (props: IconProps) => {
121
122
  aria = {},
122
123
  border = false,
123
124
  className,
125
+ color,
124
126
  customIcon,
125
127
  data = {},
126
128
  fixedWidth = true,
@@ -169,6 +171,7 @@ const Icon = (props: IconProps) => {
169
171
  (!iconElement && !customIcon) ? 'pb_icon_kit' : '',
170
172
  (iconElement || customIcon) ? 'pb_custom_icon' : fontStyle,
171
173
  iconElement ? 'svg-inline--fa' : '',
174
+ color ? `color_${color}` : '',
172
175
  globalProps(props),
173
176
  className
174
177
  )
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("flex", props: {orientation: "column"}) do %>
2
+ <%= pb_rails("icon", props: { icon: "user", fixed_width: true, color: "primary", padding_bottom: "sm", size: "2x" }) %>
3
+ <%= pb_rails("icon", props: { icon: "recycle", fixed_width: true, color: "data_4", padding_bottom: "sm", size: "2x" }) %>
4
+ <%= pb_rails("icon", props: { icon: "roofing", fixed_width: true, color: "product_5_background", size: "2x" }) %>
5
+ <% end %>
@@ -0,0 +1,34 @@
1
+ import React from "react"
2
+ import Icon from "../_icon"
3
+
4
+ const IconDefault = (props) => {
5
+ return (
6
+ <div style={{ display: "flex", flexDirection: "column"}}>
7
+ <Icon
8
+ color="primary"
9
+ fixedWidth
10
+ icon="user"
11
+ paddingBottom="sm"
12
+ size="2x"
13
+ {...props}
14
+ />
15
+ <Icon
16
+ color="data_4"
17
+ fixedWidth
18
+ icon="recycle"
19
+ paddingBottom="sm"
20
+ size="2x"
21
+ {...props}
22
+ />
23
+ <Icon
24
+ color="product_5_background"
25
+ fixedWidth
26
+ icon="product-roofing"
27
+ size="2x"
28
+ {...props}
29
+ />
30
+ </div>
31
+ )
32
+ }
33
+
34
+ export default IconDefault
@@ -0,0 +1 @@
1
+ Pass any text, status, data, product, or category Playbook <a href="https://playbook.powerapp.cloud/visual_guidelines/colors" target="_blank">color token</a> to the `color` prop to change any icon's color.
@@ -9,6 +9,7 @@ examples:
9
9
  - icon_sizes: Icon Sizes
10
10
  - icon_custom: Icon Custom
11
11
  - icon_fa_kit: Icon with FontAwesome Kit
12
+ - icon_color: Icon Color
12
13
 
13
14
  react:
14
15
  - icon_default: Icon Default
@@ -20,6 +21,7 @@ examples:
20
21
  - icon_sizes: Icon Sizes
21
22
  - icon_custom: Icon Custom
22
23
  - icon_fa_kit: Icon with FontAwesome Kit
24
+ - icon_color: Icon Color
23
25
 
24
26
  swift:
25
27
  - icon_default_swift: Icon Default
@@ -7,3 +7,4 @@ export { default as IconBorder } from './_icon_border.jsx'
7
7
  export { default as IconSizes } from './_icon_sizes.jsx'
8
8
  export { default as IconCustom } from './_icon_custom.jsx'
9
9
  export { default as IconFaKit} from './_icon_fa_kit.jsx'
10
+ export { default as IconColor } from './_icon_color.jsx'
@@ -36,6 +36,7 @@ module Playbook
36
36
  default: "far"
37
37
  prop :spin, type: Playbook::Props::Boolean,
38
38
  default: false
39
+ prop :color, type: Playbook::Props::String
39
40
 
40
41
  def valid_emoji?
41
42
  emoji_regex = /\p{Emoji}/
@@ -45,6 +46,7 @@ module Playbook
45
46
  def classname
46
47
  generate_classname(
47
48
  "pb_icon_kit",
49
+ color_class,
48
50
  font_style_class,
49
51
  icon_class,
50
52
  border_class,
@@ -65,6 +67,7 @@ module Playbook
65
67
  generate_classname(
66
68
  "pb_icon_kit",
67
69
  border_class,
70
+ color_class,
68
71
  fixed_width_class,
69
72
  flip_class,
70
73
  inverse_class,
@@ -104,7 +107,8 @@ module Playbook
104
107
  svg["aria"] = object.aria
105
108
  svg["height"] = "auto"
106
109
  svg["width"] = "auto"
107
- doc.at_css("path")["fill"] = "currentColor"
110
+ fill_color = object.color || "currentColor"
111
+ doc.at_css("path")["fill"] = fill_color
108
112
  raw doc
109
113
  end
110
114
 
@@ -200,6 +204,10 @@ module Playbook
200
204
  class_name = is_svg? ? "spin" : "fa-spin"
201
205
  spin ? class_name : nil
202
206
  end
207
+
208
+ def color_class
209
+ color ? "color_#{color}" : nil
210
+ end
203
211
  end
204
212
  end
205
213
  end
@@ -12,7 +12,7 @@ describe("Icon Kit", () => {
12
12
  data={{ testid: testId }}
13
13
  fixedWidth
14
14
  icon="user"
15
- />
15
+ />
16
16
  )
17
17
 
18
18
  const kit = screen.getByTestId(testId)
@@ -27,7 +27,7 @@ describe("Icon Kit", () => {
27
27
  fixedWidth
28
28
  icon="user"
29
29
  rotation={rotateProp}
30
- />
30
+ />
31
31
  )
32
32
 
33
33
  const kit = screen.getByTestId(testId)
@@ -44,7 +44,7 @@ describe("Icon Kit", () => {
44
44
  fixedWidth
45
45
  flip="horizontal"
46
46
  icon="user"
47
- />
47
+ />
48
48
  )
49
49
 
50
50
  const kit = screen.getByTestId(testId)
@@ -59,7 +59,7 @@ describe("Icon Kit", () => {
59
59
  fixedWidth
60
60
  icon="spinner"
61
61
  spin
62
- />
62
+ />
63
63
  )
64
64
 
65
65
  const kit = screen.getByTestId(testId)
@@ -73,7 +73,7 @@ describe("Icon Kit", () => {
73
73
  fixedWidth
74
74
  icon="arrow-left"
75
75
  pull="left"
76
- />
76
+ />
77
77
  )
78
78
 
79
79
  const kit = screen.getByTestId(testId)
@@ -87,7 +87,7 @@ describe("Icon Kit", () => {
87
87
  fixedWidth
88
88
  icon="arrow-left"
89
89
  pull="left"
90
- />
90
+ />
91
91
  )
92
92
 
93
93
  const kit = screen.getByTestId(testId)
@@ -101,7 +101,7 @@ describe("Icon Kit", () => {
101
101
  data={{ testid: testId }}
102
102
  fixedWidth
103
103
  icon="user"
104
- />
104
+ />
105
105
  )
106
106
 
107
107
  const kit = screen.getByTestId(testId)
@@ -128,7 +128,7 @@ describe("Icon Kit", () => {
128
128
  data={{ testid: testId }}
129
129
  icon="user"
130
130
  size={sizeProp}
131
- />
131
+ />
132
132
  )
133
133
 
134
134
  const kit = screen.getByTestId(testId)
@@ -145,11 +145,24 @@ describe("Icon Kit", () => {
145
145
  fixedWidth
146
146
  fontStyle="fas"
147
147
  icon="user"
148
- />
148
+ />
149
149
  )
150
150
 
151
151
  const kit = screen.getByTestId(testId)
152
152
  expect(kit).toHaveClass("fa-user pb_icon_kit fa-fw fas")
153
153
  })
154
154
 
155
+ test("renders with color prop", () => {
156
+ render(
157
+ <Icon
158
+ color="primary"
159
+ data={{ testid: testId }}
160
+ icon="user"
161
+ />
162
+ )
163
+
164
+ const kit = screen.getByTestId(testId)
165
+ expect(kit).toHaveClass("color_primary")
166
+ })
167
+
155
168
  })