playbook_ui 13.33.1 → 13.34.0.pre.alpha.PBNTR358responsiveadvancedtablereact3368

Sign up to get free protection for your applications and to get access to all the features.
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
  })