playbook_ui 13.33.1 → 13.34.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_background/background.html.erb +2 -11
  3. data/app/pb_kits/playbook/pb_body/body.html.erb +1 -6
  4. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +1 -6
  5. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +1 -6
  6. data/app/pb_kits/playbook/pb_caption/caption.html.erb +1 -6
  7. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -7
  8. data/app/pb_kits/playbook/pb_collapsible/_collapsible.scss +1 -1
  9. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_color.jsx +2 -2
  10. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main.jsx +31 -32
  11. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_rails.html.erb +3 -2
  12. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_with_icon.jsx +33 -32
  13. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_custom_main_with_icon_rails.html.erb +3 -7
  14. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_icons.jsx +1 -0
  15. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_state.jsx +9 -0
  16. data/app/pb_kits/playbook/pb_contact/_contact.tsx +25 -19
  17. data/app/pb_kits/playbook/pb_contact/contact.html.erb +6 -3
  18. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +71 -64
  19. data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
  20. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -6
  21. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +1 -6
  22. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +2 -5
  23. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +1 -6
  24. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +7 -3
  25. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +1 -1
  26. data/app/pb_kits/playbook/pb_dropdown/index.js +37 -31
  27. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  28. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +4 -0
  29. data/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx +11 -0
  30. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +52 -17
  31. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_icon.html.erb +5 -0
  32. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_icon.jsx +19 -0
  33. data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +2 -1
  34. data/app/pb_kits/playbook/pb_form_pill/docs/index.js +1 -1
  35. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +16 -9
  36. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +6 -1
  37. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  38. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  39. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  40. data/app/pb_kits/playbook/pb_icon/_icon.scss +17 -0
  41. data/app/pb_kits/playbook/pb_icon/_icon.tsx +3 -0
  42. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.html.erb +5 -0
  43. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.jsx +34 -0
  44. data/app/pb_kits/playbook/pb_icon/docs/_icon_color.md +1 -0
  45. data/app/pb_kits/playbook/pb_icon/docs/example.yml +2 -0
  46. data/app/pb_kits/playbook/pb_icon/docs/index.js +1 -0
  47. data/app/pb_kits/playbook/pb_icon/icon.rb +9 -1
  48. data/app/pb_kits/playbook/pb_icon/icon.test.js +22 -9
  49. data/app/pb_kits/playbook/pb_star_rating/_star_rating.tsx +132 -201
  50. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_hide.jsx +28 -33
  51. data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.jsx +14 -0
  52. data/app/pb_kits/playbook/pb_star_rating/docs/index.js +2 -0
  53. data/app/pb_kits/playbook/pb_star_rating/stars/utils.tsx +81 -0
  54. data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_display.tsx +56 -0
  55. data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_interactive.tsx +64 -0
  56. data/dist/playbook-rails.js +6 -6
  57. data/lib/playbook/version.rb +2 -2
  58. metadata +11 -2
@@ -10,16 +10,16 @@ import Caption from "../pb_caption/_caption";
10
10
  import Icon from "../pb_icon/_icon";
11
11
 
12
12
  type DateRangeInlineProps = {
13
- className?: string;
14
- id?: string;
15
- data?: string;
16
13
  align?: "left" | "center" | "vertical";
17
- size?: "sm" | "xs";
14
+ className?: string;
18
15
  dark?: boolean;
19
- htmlOptions?: {[key: string]: string | number | boolean | (() => any)};
16
+ data?: string;
17
+ endDate?: Date;
18
+ htmlOptions?: { [key: string]: string | number | boolean | (() => any) };
20
19
  icon?: boolean;
20
+ id?: string;
21
+ size?: "sm" | "xs";
21
22
  startDate?: Date;
22
- endDate?: Date;
23
23
  };
24
24
 
25
25
  const dateTimestamp = (dateValue: Date, includeYear: boolean) => {
@@ -36,59 +36,36 @@ const dateTimeIso = (dateValue: Date) => {
36
36
 
37
37
  const DateRangeInline = (props: DateRangeInlineProps): React.ReactElement => {
38
38
  const {
39
- icon = false,
40
- dark = false,
41
- size = "sm",
42
39
  align = "left",
40
+ className,
41
+ dark = false,
43
42
  data = {},
43
+ endDate,
44
44
  htmlOptions = {},
45
+ icon = false,
46
+ size = "sm",
45
47
  startDate,
46
- endDate,
47
- className,
48
48
  } = props;
49
49
 
50
- const iconContent = () => {
51
- return (
52
- <>
53
- {icon && (
54
- <>
55
- <Body color="light"
56
- key={Math.random()}
57
- tag="span"
58
- >
59
- <Icon
60
- className="pb_date_range_inline_icon"
61
- dark={dark}
62
- fixedWidth
63
- icon="calendar-alt"
64
- size={size}
65
- tag="span"
66
- />
67
- </Body>
68
- </>
69
- )}
70
- </>
71
- );
72
- };
73
-
74
50
  const dateInCurrentYear = () => {
75
51
  const currentDate = new Date();
76
52
  return (
77
- startDate.getFullYear() == endDate.getFullYear() &&
78
- startDate.getFullYear() == currentDate.getFullYear()
53
+ startDate?.getFullYear() === endDate?.getFullYear() &&
54
+ startDate?.getFullYear() === currentDate.getFullYear()
79
55
  );
80
56
  };
81
57
 
82
58
  const dateRangeClasses = buildCss("pb_date_range_inline_kit", align);
83
- const dataProps = buildDataProps(data)
84
- const htmlProps = buildHtmlProps(htmlOptions)
59
+ const dataProps = buildDataProps(data);
60
+ const htmlProps = buildHtmlProps(htmlOptions);
61
+
85
62
  const renderTime = (date: Date) => {
86
63
  return (
87
64
  <time dateTime={dateTimeIso(date)}>
88
65
  {dateInCurrentYear() ? (
89
- <>{` ${dateTimestamp(date, false)} `}</>
66
+ ` ${dateTimestamp(date, false)} `
90
67
  ) : (
91
- <>{` ${dateTimestamp(date, true)} `}</>
68
+ ` ${dateTimestamp(date, true)} `
92
69
  )}
93
70
  </time>
94
71
  );
@@ -101,53 +78,83 @@ const DateRangeInline = (props: DateRangeInlineProps): React.ReactElement => {
101
78
  className={classnames(dateRangeClasses, globalProps(props), className)}
102
79
  >
103
80
  <div className="pb_date_range_inline_wrapper">
104
- {size == "xs" && (
81
+ {size === "xs" && (
105
82
  <>
106
- {iconContent()}
107
- <Caption dark={dark}
108
- tag="span"
109
- >
83
+ {icon && (
84
+ <Caption
85
+ dark={dark}
86
+ tag="span">
87
+ <Icon
88
+ className="pb_date_range_inline_icon"
89
+ dark={dark}
90
+ fixedWidth
91
+ icon="calendar-alt"
92
+ size={size}
93
+ tag="span"
94
+ />
95
+ </Caption>
96
+ )}
97
+ <Caption
98
+ dark={dark}
99
+ tag="span">
110
100
  {renderTime(startDate)}
111
101
  </Caption>
112
- <Caption dark={dark}
113
- tag="span"
114
- >
102
+ <Caption
103
+ dark={dark}
104
+ tag="span">
115
105
  <Icon
116
106
  className="pb_date_range_inline_arrow"
107
+ dark={dark}
117
108
  fixedWidth
118
109
  icon="long-arrow-right"
110
+ tag="span"
119
111
  />
120
112
  </Caption>
121
- <Caption dark={dark}
122
- tag="span"
123
- >
113
+ <Caption
114
+ dark={dark}
115
+ tag="span">
124
116
  {renderTime(endDate)}
125
117
  </Caption>
126
118
  </>
127
119
  )}
128
120
 
129
- {size == "sm" && (
121
+ {size === "sm" && (
130
122
  <>
131
- {iconContent()}
132
- <Body dark={dark}
133
- tag="span"
134
- >
123
+ {icon && (
124
+ <Body
125
+ color={"light"}
126
+ dark={dark}
127
+ tag="span">
128
+ <Icon
129
+ className="pb_date_range_inline_icon"
130
+ dark={dark}
131
+ fixedWidth
132
+ icon="calendar-alt"
133
+ size={size}
134
+ tag="span"
135
+ />
136
+ </Body>
137
+ )}
138
+ <Body
139
+ dark={dark}
140
+ tag="span">
135
141
  {renderTime(startDate)}
136
142
  </Body>
137
- <Body color="light"
138
- dark={dark}
139
- tag="span"
140
- >
143
+ <Body
144
+ color={"light"}
145
+ dark={dark}
146
+ tag="span">
141
147
  <Icon
142
148
  className="pb_date_range_inline_arrow"
143
149
  dark={dark}
144
150
  fixedWidth
145
151
  icon="long-arrow-right"
152
+ tag="span"
146
153
  />
147
154
  </Body>
148
- <Body dark={dark}
149
- tag="span"
150
- >
155
+ <Body
156
+ dark={dark}
157
+ tag="span">
151
158
  {renderTime(endDate)}
152
159
  </Body>
153
160
  </>
@@ -1,8 +1,3 @@
1
- <%= content_tag(object.tag,
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(object.tag) do %>
7
2
  <%= object.content %>
8
3
  <% end %>
@@ -1,10 +1,5 @@
1
1
  <div class="pb_dialog_wrapper_rails <%= object.full_height_style %>" data-overlay-click= <%= object.overlay_close %> >
2
- <%= content_tag(:dialog,
3
- aria: object.aria,
4
- data: object.data,
5
- id: object.id,
6
- class: object.classname,
7
- **combined_html_options) do %>
2
+ <%= pb_content_tag(:dialog) do %>
8
3
  <% if object.status === "" && object.title %>
9
4
  <%= pb_rails("dialog/dialog_header", props: { title: object.title, id: object.id }) %>
10
5
  <% end %>
@@ -1,8 +1,3 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- aria: object.aria,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <%= content.presence || object.text %>
8
3
  <% end %>
@@ -1,8 +1,5 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- aria: object.aria,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:div, class: "") do %>
2
+ <% 'excluded classname?' %>
6
3
  <% if object.confirm_button && object.cancel_button %>
7
4
  <div class="dialog-pseudo-footer"></div>
8
5
  <%= pb_rails("flex", props: { classname:object.classname, spacing:"between", padding_x:"sm", padding:"sm", padding_bottom:"sm" }) do %>
@@ -1,9 +1,4 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.sticky_header,
5
- aria: object.aria,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:div, class: object.sticky_header) do %>
7
2
  <%= pb_rails("flex", props: {classname:object.classname, spacing:"between", padding:"sm", align:"center"}) do %>
8
3
  <%= content.presence || object.title %>
9
4
 
@@ -8,9 +8,13 @@
8
8
  <%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
9
9
  <% end %>
10
10
  <div class="dropdown_wrapper<%= error_class %>" style="position: relative">
11
- <input type="hidden" name="<%= object.name %>" id="dropdown-selected-option" value="<%= input_default_value %>" />
12
- <input id="dropdown-form-validation" name="<%= object.name %>_form_validation" value="<%= input_default_value %>" style="display: none" <%= object.required ? "required" : ""%> />
13
-
11
+ <input
12
+ data-default-value="<%= input_default_value %>"
13
+ id="dropdown-selected-option"
14
+ name="<%= object.name %>"
15
+ style="display: none"
16
+ <%= object.required ? "required" : ""%>
17
+ />
14
18
  <% if content.present? %>
15
19
  <%= content.presence %>
16
20
  <%= pb_rails("body", props: { status: "negative", text: object.error }) %>
@@ -29,7 +29,7 @@ module Playbook
29
29
  end
30
30
 
31
31
  def input_default_value
32
- default_value.present? ? default_value.transform_keys(&:to_s) : ""
32
+ default_value.present? ? default_value.transform_keys(&:to_s)["id"] : ""
33
33
  end
34
34
 
35
35
  def options_with_blank
@@ -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 %>