playbook_ui 13.33.0.pre.alpha.PBNTR405dropdownformfixesrails3311 → 13.33.0.pre.alpha.PLAY1454formpillicons3309

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fbda811742441cdb16b2651544b02a6053acfca38e070ef814ff1f2fcb1c27c
4
- data.tar.gz: 159b81a126b1d13b8f64f2e16a53326dfbf21b1afd7118c469c95bf7e9524b5b
3
+ metadata.gz: e3efbce8e6bf0e2038cb58c547e077b7b44abba6abf56c59a4fc907fbfce2c5e
4
+ data.tar.gz: 7880d9315a8eaa5c0e9a3a265511ec50560452fe801cdbc4c0ccacd8dc788d83
5
5
  SHA512:
6
- metadata.gz: dc57caefdde9638b830c0ad6a010c8e0ada6cd7fd2d72b7b134271ed86de9e3bb7a45a351690afea6950b8c7e8733d3063fac7436e0d1bdc7cdc82074c219289
7
- data.tar.gz: ddce620575e43112f59837ad5a39d4efbda50072d4c48e3c171b37d8774605ee84770cdcd8c200ef0bb3018dee8b6e8fa10c1a30d58dbbccefa30e1e131158c2
6
+ metadata.gz: 0dbccb4ffc9f8ddf6aa98023dcfe77065eb705d3d2212ab6dff3d0c15e6797708f20789530ea9fcde6a1f2d687f4c6d2ff57e106f983171ed6d326b7f62ff99c
7
+ data.tar.gz: 8d4dc0b7828a8d9add30dd1c23416fbc4181a2ecb319e38792a80a717aef3b37e75a99790ef42d703be18dcd09c474faaaa5c4b6e6b612097bfb1044167128ed
@@ -8,13 +8,9 @@
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
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
- />
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
+
18
14
  <% if content.present? %>
19
15
  <%= content.presence %>
20
16
  <%= 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)["id"] : ""
32
+ default_value.present? ? default_value.transform_keys(&:to_s) : ""
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";
11
12
  const DROPDOWN_TRIGGER_DISPLAY = "#dropdown_trigger_display";
12
13
  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,13 +47,14 @@ 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_INPUT);
50
+ const hiddenInput = this.element.querySelector("#dropdown-selected-option");
51
+ const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
51
52
 
52
53
  if (option) {
53
54
  const value = option.dataset.dropdownOptionLabel;
54
55
  hiddenInput.value = JSON.parse(value).id;
55
- this.clearFormValidation(hiddenInput);
56
-
56
+ inputFormValidation.value = JSON.parse(value).id;
57
+ this.clearFormValidation(inputFormValidation);
57
58
  this.onOptionSelected(value, option);
58
59
  }
59
60
  }
@@ -159,18 +160,14 @@ export default class PbDropdown extends PbEnhancedElement {
159
160
  }
160
161
 
161
162
  handleFormValidation() {
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
- );
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);
174
171
  }
175
172
 
176
173
  clearFormValidation(input) {
@@ -178,9 +175,7 @@ export default class PbDropdown extends PbEnhancedElement {
178
175
  const dropdownWrapperElement = input.closest(".dropdown_wrapper");
179
176
  dropdownWrapperElement.classList.remove("error");
180
177
 
181
- const errorLabelElement = dropdownWrapperElement.querySelector(
182
- ".pb_body_kit_negative"
183
- );
178
+ const errorLabelElement = dropdownWrapperElement.querySelector(".pb_body_kit_negative");
184
179
  if (errorLabelElement) {
185
180
  errorLabelElement.remove();
186
181
  }
@@ -188,22 +183,23 @@ export default class PbDropdown extends PbEnhancedElement {
188
183
  }
189
184
 
190
185
  setDefaultValue() {
191
- const hiddenInput = this.element.querySelector(DROPDOWN_INPUT);
192
- const options = this.element.querySelectorAll(OPTION_SELECTOR);
186
+ const hiddenInput = this.element.querySelector("#dropdown-selected-option");
193
187
 
194
- const defaultValue = hiddenInput.dataset.defaultValue || "";
195
- hiddenInput.value = defaultValue;
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);
196
192
 
197
- if (defaultValue) {
198
- const selectedOption = Array.from(options).find((option) => {
199
- return (
200
- JSON.parse(option.dataset.dropdownOptionLabel).id === defaultValue
201
- );
193
+ options.forEach((option) => {
194
+ if (defaultValue.id === JSON.parse(option.dataset.dropdownOptionLabel).id) {
195
+ option.classList.add("pb_dropdown_option_selected");
196
+ }
202
197
  });
203
- selectedOption.classList.add("pb_dropdown_option_selected");
204
- this.setTriggerElementText(
205
- JSON.parse(selectedOption.dataset.dropdownOptionLabel).label
206
- );
198
+
199
+ this.setTriggerElementText(defaultValue.label);
200
+
201
+ hiddenInput.value = defaultValue.id;
202
+ inputFormValidation.value = defaultValue.id;
207
203
  }
208
204
  }
209
205
 
@@ -218,13 +214,11 @@ export default class PbDropdown extends PbEnhancedElement {
218
214
  }
219
215
 
220
216
  resetDropdownValue() {
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
- });
217
+ const hiddenInput = this.element.querySelector("#dropdown-selected-option");
218
+ const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
226
219
 
227
220
  hiddenInput.value = "";
221
+ inputFormValidation.value = "";
228
222
 
229
223
  const defaultPlaceholder = this.element.querySelector(DROPDOWN_PLACEHOLDER);
230
224
  this.setTriggerElementText(defaultPlaceholder.dataset.dropdownPlaceholder);
@@ -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