playbook_ui 13.30.0.pre.alpha.20240515remotebuildkitconversion3150 → 13.31.0.pre.alpha.PLAY882formpillprimaryandneutral3201

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) 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_date_year_stacked/docs/_date_year_stacked_default.jsx +4 -1
  9. data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
  10. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -6
  11. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +1 -6
  12. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +2 -5
  13. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +1 -6
  14. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +15 -1
  15. data/app/pb_kits/playbook/pb_draggable/context/types.ts +5 -0
  16. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +14 -19
  17. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +5 -3
  18. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.md +7 -3
  19. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +3 -5
  20. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.md +3 -5
  21. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -1
  22. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +2 -0
  23. data/app/pb_kits/playbook/pb_dropdown/index.js +33 -4
  24. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  25. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +9 -0
  26. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +108 -5
  27. data/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx +53 -0
  28. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +11 -2
  29. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  30. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +5 -1
  31. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  32. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  33. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  34. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.html.erb +1 -6
  35. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +3 -20
  36. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +8 -23
  37. data/dist/menu.yml +566 -472
  38. data/dist/playbook-rails.js +6 -6
  39. data/lib/playbook/version.rb +2 -2
  40. metadata +3 -3
  41. data/app/pb_kits/playbook/pb_icon/types.d.ts +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 566e8e55a2019e4b07f21aaf87d7c9cdec4882133ffff612eb28eea86a6e4ffa
4
- data.tar.gz: '0197bd9877b5b0ed9002660f011dbea1fe06b6cf258481cea72cb3be712b2c10'
3
+ metadata.gz: 58be8143dc1d3b0b8f64fddf26414a5486df02decbd590b04e78a2fd96b5a1a3
4
+ data.tar.gz: e109a14b818fc8ea6dc9e1c1c0fd7fd27325481d730c3c3f0a249e5b2334a1c5
5
5
  SHA512:
6
- metadata.gz: 85abde5d0af055ed6e080eeb6d767c38a93b495b9c4d6404b1a2f2e202131344089776a2d0f1b22de9ba2d48bb6940bab23237277b9e5f2031601c418e5ce24f
7
- data.tar.gz: bd1b40be0a0d261605f2835806562f91ec2c8248dbb39cbe4cb4591cb9d4a20fb25fb90d93f1e346cd7b71c23a66c71ad7dc09aa200dcc637ebeb27184551df9
6
+ metadata.gz: 517fb2d246a141e0490421f1d64a1b719650908e26a16320d9d647e73edde4a286df47c5fbeafc080d48063e744c4d7c1d45fd18e8ab25850d6ac5ec88eb1081
7
+ data.tar.gz: aa0c86a28ba3c93000bf2be8c4857332c19fe9137d00c5cfbe8c796068dc3e99f8f34feae53e989143fbb01e6d5286aafbc2abceeef7ce2b825f80150eb32703
@@ -1,23 +1,14 @@
1
1
  <% if object.image_url.present? %>
2
- <%= content_tag(object.tag,
3
- aria: object.aria,
4
- data: object.data,
5
- id: object.id,
6
- class: object.classname,
2
+ <%= pb_content_tag(object.tag,
7
3
  style: "background-image: url('#{object.image_url}');
8
4
  background-repeat: #{object.background_repeat};
9
5
  background-size: #{object.background_size};
10
6
  background-position: #{object.background_position};",
11
- **combined_html_options
12
7
  ) do %>
13
8
  <%= content.presence %>
14
9
  <% end %>
15
10
  <% else %>
16
- <%= content_tag(object.tag,
17
- aria: object.aria,
18
- data: object.data,
19
- id: object.id,
20
- class: object.classname,
11
+ <%= pb_content_tag(object.tag,
21
12
  style: object.custom_background_color
22
13
  ) do %>
23
14
  <%= content.presence %>
@@ -1,8 +1,3 @@
1
- <%= content_tag(object.tag,
2
- aria: object.aria,
3
- id: object.id,
4
- data: object.data,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(object.tag) do %>
7
2
  <%= object.content %>
8
3
  <% end %>
@@ -1,9 +1,4 @@
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_tag(object.link ? 'a' : 'span', class: 'bread_crumb_item', href: object.link) do %>
8
3
  <%= content.presence %>
9
4
  <% end %>
@@ -1,8 +1,3 @@
1
- <%= content_tag(:nav,
2
- aria: object.aria,
3
- id: object.id,
4
- data: object.data,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:nav) do %>
7
2
  <%= content.presence %>
8
3
  <% end %>
@@ -1,8 +1,3 @@
1
- <%= content_tag(object.tag,
2
- aria: object.aria,
3
- id: object.id,
4
- data: object.data,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(object.tag) do %>
7
2
  <%= content.presence || object.text %>
8
3
  <% end %>
@@ -1,10 +1,4 @@
1
- <%= content_tag(object.tag,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- aria: object.aria,
6
- dark: object.dark,
7
- **combined_html_options) do %>
1
+ <%= pb_content_tag(object.tag) do %>
8
2
  <%= content.presence %>
9
3
  <% end %>
10
4
 
@@ -4,7 +4,10 @@ import { DateYearStacked } from '../../'
4
4
  const DateYearStackedDefault = (props) => {
5
5
  return (
6
6
  <div>
7
- <DateYearStacked date={new Date()} />
7
+ <DateYearStacked
8
+ date={new Date()}
9
+ {...props}
10
+ />
8
11
  <DateYearStacked
9
12
  align="center"
10
13
  date={new Date()}
@@ -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
 
@@ -51,7 +51,16 @@ export const DraggableContext = () => {
51
51
  return useContext(DragContext);
52
52
  };
53
53
 
54
- export const DraggableProvider = ({ children, initialItems, onReorder }: DraggableProviderType) => {
54
+ export const DraggableProvider = ({
55
+ children,
56
+ initialItems,
57
+ onReorder,
58
+ onDragStart,
59
+ onDragEnter,
60
+ onDragEnd,
61
+ onDrop,
62
+ onDragOver
63
+ }: DraggableProviderType) => {
55
64
  const [state, dispatch] = useReducer(reducer, initialState);
56
65
 
57
66
  useEffect(() => {
@@ -65,6 +74,7 @@ export const DraggableProvider = ({ children, initialItems, onReorder }: Draggab
65
74
  const handleDragStart = (id: string, container: string) => {
66
75
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container } });
67
76
  dispatch({ type: 'SET_IS_DRAGGING', payload: id });
77
+ if (onDragStart) onDragStart(id, container);
68
78
  };
69
79
 
70
80
  const handleDragEnter = (id: string, container: string) => {
@@ -72,11 +82,13 @@ export const DraggableProvider = ({ children, initialItems, onReorder }: Draggab
72
82
  dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
73
83
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: state.dragData.id, initialGroup: container } });
74
84
  }
85
+ if (onDragEnter) onDragEnter(id, container);
75
86
  };
76
87
 
77
88
  const handleDragEnd = () => {
78
89
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
79
90
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
91
+ if (onDragEnd) onDragEnd();
80
92
  };
81
93
 
82
94
  const changeCategory = (itemId: string, container: string) => {
@@ -87,11 +99,13 @@ export const DraggableProvider = ({ children, initialItems, onReorder }: Draggab
87
99
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
88
100
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
89
101
  changeCategory(state.dragData.id, container);
102
+ if (onDrop) onDrop(container);
90
103
  };
91
104
 
92
105
  const handleDragOver = (e: Event, container: string) => {
93
106
  e.preventDefault();
94
107
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
108
+ if (onDragOver) onDragOver(e, container);
95
109
  };
96
110
 
97
111
  const contextValue = useMemo(() => ({
@@ -23,4 +23,9 @@ export interface ItemType {
23
23
  children: React.ReactNode;
24
24
  initialItems: ItemType[];
25
25
  onReorder: (items: ItemType[]) => void;
26
+ onDragStart?: (id: string, container: string) => void;
27
+ onDragEnter?: (id: string, container: string) => void;
28
+ onDragEnd?: () => void;
29
+ onDrop?: (container: string) => void;
30
+ onDragOver?: (e: Event, container: string) => void;
26
31
  }
@@ -1,23 +1,19 @@
1
1
  import React, { useState } from "react";
2
- import { SelectableList, Draggable, DraggableProvider } from "../../";
2
+ import { Flex, Image, Draggable, DraggableProvider } from "../../";
3
3
 
4
4
  // Initial items to be dragged
5
5
  const data = [
6
6
  {
7
- id: "1",
8
- text: "Task 1",
7
+ id: "21",
8
+ url: "https://unsplash.it/500/400/?image=633",
9
9
  },
10
10
  {
11
- id: "2",
12
- text: "Task 2",
11
+ id: "22",
12
+ url: "https://unsplash.it/500/400/?image=634",
13
13
  },
14
14
  {
15
- id: "3",
16
- text: "Task 3",
17
- },
18
- {
19
- id: "4",
20
- text: "Task 4",
15
+ id: "23",
16
+ url: "https://unsplash.it/500/400/?image=637",
21
17
  },
22
18
  ];
23
19
 
@@ -30,20 +26,19 @@ const DraggableDefault = (props) => {
30
26
  onReorder={(items) => setInitialState(items)}
31
27
  >
32
28
  <Draggable.Container {...props}>
33
- <SelectableList variant="checkbox">
34
- {initialState.map(({ id, text }) => (
29
+ <Flex>
30
+ {initialState.map(({ id, url }) => (
35
31
  <Draggable.Item dragId={id}
36
32
  key={id}
37
33
  >
38
- <SelectableList.Item
39
- label={text}
40
- name={id}
41
- value={id}
42
- {...props}
34
+ <Image alt={id}
35
+ margin="xs"
36
+ size="md"
37
+ url={url}
43
38
  />
44
39
  </Draggable.Item>
45
40
  ))}
46
- </SelectableList>
41
+ </Flex>
47
42
  </Draggable.Container>
48
43
  </DraggableProvider>
49
44
  </>
@@ -1,4 +1,6 @@
1
- To use the Draggable kit, you must use the DraggableProvider and pass in `initialItems`. The `onReorder` is a function that returns the data as it changes as items are reordered. Use this to manage state as shown.
1
+ The Draggable kit gives you a full subcomponent structure that allows it to be used with almost any kits.
2
2
 
3
- The `Draggable.Container` specifies the container within which items can be dropped.
4
- The `Draggable.Item` specifies the items that can be dragged and dropped. `dragId` is a REQUIRED prop for Draggable.Item.
3
+ `DraggableProvider` = This provider manages all settings that allows drag and drop to function and must be used as the outermost wrapper. It has 2 REQUIRED props: `initialItems` (initial data) and `onReorder` (function that returns mutated data as items are reordered via drag and drop). Devs must manage state as shown.
4
+
5
+ `Draggable.Container` = This specifies the container within which items can be dropped.
6
+ `Draggable.Item` = This specifies the items that can be dragged and dropped. `dragId` is a REQUIRED prop for Draggable.Item.
@@ -1,5 +1,9 @@
1
- For a simplified version of the Draggable API for the Card kit, You can use the the Card kit as the Draggable Item by using the `draggableItem` prop. The dragHandle is added by default but this can be opted out of by setting `dragHandle` to false on the Card kit.
1
+ For a simplified version of the Draggable API for the Card kit, you can do the following:
2
+
3
+ Use `DraggableProvider` and manage state as shown.
4
+
5
+ `Draggable.Container` creates the container within which the cards can be dragged and dropped.
6
+
7
+ The Card kit is optimized to work with the draggable kit. To enable drag, use the `draggableItem` and `dragId` props on the Card kit as shown. An additional optional boolean prop (set to true by default) of `dragHandle` is also available to show the drag handle icon.
2
8
 
3
- In addition to the above `dragId` is a REQUIRED prop to be passedd to the Card kit when implementing dragging.
4
9
 
5
- The dev must manage state as shown.
@@ -1,7 +1,5 @@
1
- For a simplified version of the Draggable API for the List kit, use the DraggableProvider to wrap the List kit and use the `enableDrag` prop.
1
+ For a simplified version of the Draggable API for the List kit, you can do the following:
2
2
 
3
- In addition to the above `dragId` is a REQUIRED prop to be passed to the List kit when implementing dragging.
3
+ Use `DraggableProvider` and manage state as shown.
4
4
 
5
- The dev must manage state as shown.
6
-
7
- The dragHandle is added by default but this can be opted out of by setting `dragHandle` to false on the List kit.
5
+ The List kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on List kit AND `dragId` prop on ListItem. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on List kit to show the drag handle icon.
@@ -1,7 +1,5 @@
1
- For a simplified version of the Draggable API for the SelectableList kit, use the DraggableProvider to wrap the SelectableList kit and use the `enableDrag` prop.
1
+ For a simplified version of the Draggable API for the SelectableList kit, you can do the following:
2
2
 
3
- In addition to the above `dragId` is a REQUIRED prop to be passed to the SelectableList kit when implementing dragging.
3
+ Use `DraggableProvider` and manage state as shown.
4
4
 
5
- The dev must manage state as shown.
6
-
7
- The dragHandle is added by default but this can be opted out of by setting `dragHandle` to false on the SelectableList kit.
5
+ The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enableDrag` prop on SelectableList kit AND `dragId` prop on SelectableList.Item. An additional optional boolean prop (set to true by default) of `dragHandle` is also available on SelectableList kit to show the drag handle icon.
@@ -8,7 +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 type="hidden" name="<%= object.name %>" id="dropdown-selected-option" value=""/>
11
+ <input type="hidden" name="<%= object.name %>" id="dropdown-selected-option" value="" />
12
+ <input id="dropdown-form-validation" name="<%= object.name %>_form_validation" value="" style="display: none" <%= object.required ? "required" : ""%> />
13
+
12
14
  <% if content.present? %>
13
15
  <%= content.presence %>
14
16
  <%= pb_rails("body", props: { status: "negative", text: object.error }) %>
@@ -8,6 +8,8 @@ module Playbook
8
8
  prop :label, type: Playbook::Props::String
9
9
  prop :name, type: Playbook::Props::String
10
10
  prop :error, type: Playbook::Props::String
11
+ prop :required, type: Playbook::Props::Boolean,
12
+ default: false
11
13
 
12
14
  def data
13
15
  Hash(prop(:data)).merge(pb_dropdown: true)
@@ -8,16 +8,22 @@ 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
 
12
13
  export default class PbDropdown extends PbEnhancedElement {
13
14
  static get selector() {
14
15
  return DROPDOWN_SELECTOR;
15
16
  }
16
17
 
18
+ get target() {
19
+ return this.element.parentNode.querySelector(CONTAINER_SELECTOR);
20
+ }
21
+
17
22
  connect() {
18
23
  this.keyboardHandler = new PbDropdownKeyboard(this);
19
24
  this.bindEventListeners();
20
25
  this.updateArrowDisplay(false);
26
+ this.handleFormValidation();
21
27
  }
22
28
 
23
29
  bindEventListeners() {
@@ -38,9 +44,13 @@ export default class PbDropdown extends PbEnhancedElement {
38
44
  handleOptionClick(event) {
39
45
  const option = event.target.closest(OPTION_SELECTOR);
40
46
  const hiddenInput = this.element.querySelector("#dropdown-selected-option");
47
+ const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
48
+
41
49
  if (option) {
42
50
  const value = option.dataset.dropdownOptionLabel;
43
51
  hiddenInput.value = JSON.parse(value).id;
52
+ inputFormValidation.value = JSON.parse(value).id;
53
+ this.clearFormValidation(inputFormValidation);
44
54
  this.onOptionSelected(value, option);
45
55
  }
46
56
  }
@@ -103,10 +113,6 @@ export default class PbDropdown extends PbEnhancedElement {
103
113
  selectedOption.classList.add("pb_dropdown_option_selected");
104
114
  }
105
115
 
106
- get target() {
107
- return this.element.parentNode.querySelector(CONTAINER_SELECTOR);
108
- }
109
-
110
116
  showElement(elem) {
111
117
  elem.classList.remove("close");
112
118
  elem.classList.add("open");
@@ -150,4 +156,27 @@ export default class PbDropdown extends PbEnhancedElement {
150
156
  upArrow.style.display = isOpen ? "inline-block" : "none";
151
157
  }
152
158
  }
159
+
160
+ handleFormValidation() {
161
+ const inputFormValidation = this.element.querySelector(INPUT_FORM_VALIDATION);
162
+
163
+ inputFormValidation.addEventListener("invalid", function (event) {
164
+ if (inputFormValidation.hasAttribute("required") && inputFormValidation.value === "") {
165
+ event.preventDefault();
166
+ inputFormValidation.closest(".dropdown_wrapper").classList.add("error");
167
+ }
168
+ }, true);
169
+ }
170
+
171
+ clearFormValidation(input) {
172
+ if (input.checkValidity()) {
173
+ const dropdownWrapperElement = input.closest(".dropdown_wrapper");
174
+ dropdownWrapperElement.classList.remove("error");
175
+
176
+ const errorLabelElement = dropdownWrapperElement.querySelector(".pb_body_kit_negative");
177
+ if (errorLabelElement) {
178
+ errorLabelElement.remove();
179
+ }
180
+ }
181
+ }
153
182
  }
@@ -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 %>
@@ -13,6 +13,14 @@
13
13
  ]
14
14
  %>
15
15
 
16
+ <%
17
+ example_dropdown_options = [
18
+ { label: 'United States', value: 'United States', id: 'us' },
19
+ { label: 'Canada', value: 'Canada', id: 'ca' },
20
+ { label: 'Pakistan', value: 'Pakistan', id: 'pk' },
21
+ ]
22
+ %>
23
+
16
24
  <%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
17
25
  <%= form.text_field :example_text_field, props: { label: true, required: true } %>
18
26
  <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
@@ -22,6 +30,7 @@
22
30
  <%= form.password_field :example_password_field, props: { label: true, required: true } %>
23
31
  <%= form.url_field :example_url_field, props: { label: true, required: true } %>
24
32
  <%= form.text_area :example_text_area, props: { label: true, required: true } %>
33
+ <%= form.dropdown_field :example_dropdown, props: { label: true, options: example_dropdown_options, required: true } %>
25
34
  <%= form.select :example_select, [ ["Yes", 1], ["No", 2] ], props: { label: true, blank_selection: "Select One...", required: true } %>
26
35
  <%= form.collection_select :example_collection_select, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
27
36
  <%= form.check_box :example_checkbox, props: { text: "Example Checkbox", label: true, required: true } %>
@@ -8,6 +8,7 @@ $selector: ".pb_form_pill";
8
8
  $pb_form_pill_height: 37px;
9
9
  $form_pill_colors: (
10
10
  primary: map-get($status_color_text, "primary"),
11
+ neutral: map-get($status_color_text, "neutral"),
11
12
  );
12
13
 
13
14
 
@@ -23,34 +24,71 @@ $form_pill_colors: (
23
24
  cursor: pointer;
24
25
  @each $color_name, $color_value in $form_pill_colors {
25
26
  &[class*=_#{$color_name}] {
26
- background-color: rgba($color_value, $opacity-1);
27
+ background-color: mix($color_value, $card_light, 10%);
28
+ @if ($color_name == "neutral") {
29
+ background-color: $white;
30
+ border: 1px solid $border_light;
31
+ }
27
32
  transition: background-color 0.2s ease;
28
33
  box-shadow: none;
29
34
  @media (hover:hover) {
30
35
  &:hover {
31
- background-color: rgba($color_value, $opacity-2);
36
+ background-color: mix($color_value, $card_light, 20%);
37
+ @if ($color_name == "neutral") {
38
+ background-color: mix($neutral, $card_light, 20%);
39
+ border: 1px solid $border_light;
40
+ }
41
+ }
42
+ &:active {
43
+ background-color: mix($color_value, $card_light, 30%);
44
+ @if ($color_name == "neutral") {
45
+ background-color: mix($neutral, $card_light, 30%);
46
+ }
32
47
  }
33
48
  }
34
49
  #{$selector}_text {
35
50
  color: $color_value;
51
+ @if ($color_name == "neutral") {
52
+ color: $text_lt_default;
53
+ }
36
54
  padding-left: $space-sm;
37
- padding-right: $space-sm/4;
55
+ padding-right: $space-sm/2;
38
56
  }
39
57
  #{$selector}_close {
40
58
  color: $color_value;
41
- padding-left: $space-sm/2;
59
+ padding-left: $space-sm/4;
42
60
  padding-right: $space-sm/4;
43
61
  display: flex;
44
62
  align-items: center;
45
- height: 100%;
63
+ // I had to temporarily change height to 27px so new hover state darker background forms a circle not an oval
64
+ // before size change (ticket 2 of 4) - change back to 100% when $pb_form_pill_height changed to 27px from 37px
65
+ height: 27px;
66
+ border-radius: 70px;
46
67
  cursor: pointer;
68
+ &:hover {
69
+ background-color: mix($color_value, $card_light, 40%);
70
+ @if ($color_name == "neutral") {
71
+ background-color: mix($neutral, $card_light, 60%);
72
+ }
73
+ }
47
74
  }
48
75
  #{$selector}_tag {
49
76
  color: $color_value;
50
77
  padding-left: $space-sm;
78
+ @if ($color_name == "neutral") {
79
+ color: $text_lt_default;
80
+ }
51
81
  }
52
82
  }
53
83
  }
84
+ &:focus {
85
+ outline: $primary solid 2px;
86
+ outline-offset: -1px;
87
+ }
88
+ &:focus-visible {
89
+ outline: $primary solid 2px;
90
+ outline-offset: -1px;
91
+ }
54
92
  &.small {
55
93
  height: fit-content;
56
94
  height: -moz-fit-content;
@@ -70,6 +108,71 @@ $form_pill_colors: (
70
108
  &::before { line-height: 21px; }
71
109
  }
72
110
  }
111
+ &.dark {
112
+ @each $color_name, $color_value in $form_pill_colors {
113
+ // In dark mode, the base patterns below are needed for the next tickets for success, warning, error, info.
114
+ // Primary and Neutral are exceptions to the general rule in the handoff
115
+ &[class*=_#{$color_name}] {
116
+ // background-color: mix($color_value, $card_dark, 10%);
117
+ // .pb_form_pill_tag {
118
+ // color: $color_name;
119
+ // }
120
+ // .pb_form_pill_close {
121
+ // color: $color_name;
122
+ // &:hover {
123
+ // background-color: mix($color_value, $card_dark, 40%);
124
+ // }
125
+ // }
126
+ // &:hover {
127
+ // background-color: mix($color_value, $card_dark, 20%);
128
+ // }
129
+ // &:active {
130
+ // background-color: mix($color_value, $card_dark, 30%);
131
+ // }
132
+ @if ($color_name == "neutral") {
133
+ background-color: transparent;
134
+ border: 1px solid $border_dark;
135
+ .pb_form_pill_text, .pb_form_pill_tag {
136
+ color: $text_dk_default;
137
+ }
138
+ .pb_form_pill_close {
139
+ color: $text_dk_default;
140
+ &:hover {
141
+ background-color: mix($neutral, $card_dark, 40%);
142
+ }
143
+ }
144
+ &:hover {
145
+ background-color: mix($white, $card_dark, 10%);
146
+ }
147
+ &:active {
148
+ background-color: mix($white, $card_dark, 20%);
149
+ }
150
+ &:focus {
151
+ border: 1px solid $primary;
152
+ }
153
+ }
154
+ @if ($color_name == "primary") {
155
+ background-color: mix($active_dark, $card_dark, 10%);
156
+ .pb_form_pill_text, .pb_form_pill_tag {
157
+ color: $active_dark;
158
+ }
159
+ .pb_form_pill_close {
160
+ color: $active_dark;
161
+ &:hover {
162
+ background-color: mix($active_dark, $card_dark, 40%);
163
+ }
164
+ }
165
+ &:hover {
166
+ background-color: mix($active_dark, $card_dark, 20px);
167
+ }
168
+ &:active {
169
+ background-color: mix($active_dark, $card_dark, 30%);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+
73
176
  &[class*=lowercase] {
74
177
  text-transform: lowercase;
75
178
  }