playbook_ui 14.7.0.pre.alpha.PBNTR667railstypeaheadformintegration4454 → 14.7.0.pre.alpha.spacingquickchange4482
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_card/docs/_card_light.md +1 -1
- data/app/pb_kits/playbook/pb_date/_date.scss +3 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default_rails.html.erb +26 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default_rails.md +7 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.html.erb +38 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +0 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.html.erb +19 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +6 -0
- data/app/pb_kits/playbook/pb_draggable/draggable.html.erb +3 -0
- data/app/pb_kits/playbook/pb_draggable/draggable.rb +18 -0
- data/app/pb_kits/playbook/pb_draggable/draggable_container.html.erb +3 -0
- data/app/pb_kits/playbook/pb_draggable/draggable_container.rb +15 -0
- data/app/pb_kits/playbook/pb_draggable/draggable_item.html.erb +7 -0
- data/app/pb_kits/playbook/pb_draggable/draggable_item.rb +18 -0
- data/app/pb_kits/playbook/pb_draggable/index.js +125 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +2 -2
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +12 -63
- data/app/pb_kits/playbook/pb_typeahead/index.ts +2 -36
- data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +2 -5
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +0 -4
- data/dist/chunks/{_typeahead-B-juiSkw.js → _typeahead-DhLic2Fe.js} +1 -1
- data/dist/chunks/{_weekday_stacked-DPqQHJ1l.js → _weekday_stacked-Mx8TYP5I.js} +1 -1
- data/dist/chunks/{lib-DpxYMiKe.js → lib-D-mTv-kp.js} +1 -1
- data/dist/chunks/{pb_form_validation-LqRlnmi6.js → pb_form_validation-BkWGwJsl.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/forms/builder/typeahead_field.rb +0 -13
- data/lib/playbook/version.rb +1 -1
- metadata +18 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb4670689518bf254b63ee24477971a5e2c1666b7f452199ad898551857bd62a
|
4
|
+
data.tar.gz: d334c3d12c391703d725f9a608c454087732ed3beda3cdca6e5b0bbb000dde49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '05496ee6555f50603e6fec1676da0f40c0fc2de7d90869409cd06b2de2d7e7a70896d6129480363fc6f908b22e6413406bbe29177a468480daca64af5f0fae5d'
|
7
|
+
data.tar.gz: bb61330ca3b6dc7340b0773eb0fcb3c7ad5312413c61d82f0ef6b070e7b8db8c044ec504c6ad67358135c8b16888c7615da8793114c715e4da8482879ccee752
|
@@ -1 +1 @@
|
|
1
|
-
Card can leverage the max-width property. Learn more in our <a href="https://playbook.powerapp.cloud/visual_guidelines" target="_blank">visual guidelines.</a>
|
1
|
+
Card can leverage the max-width property. Learn more in our <a href="https://playbook.powerapp.cloud/visual_guidelines" target="_blank">visual guidelines.</a>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% initial_items = [
|
2
|
+
{
|
3
|
+
id: "1",
|
4
|
+
url: "https://unsplash.it/500/400/?image=633",
|
5
|
+
},
|
6
|
+
{
|
7
|
+
id: "2",
|
8
|
+
url: "https://unsplash.it/500/400/?image=634",
|
9
|
+
},
|
10
|
+
{
|
11
|
+
id: "3",
|
12
|
+
url: "https://unsplash.it/500/400/?image=637",
|
13
|
+
},
|
14
|
+
] %>
|
15
|
+
|
16
|
+
<%= pb_rails("draggable", props: {initial_items: initial_items}) do %>
|
17
|
+
<%= pb_rails("draggable/draggable_container") do %>
|
18
|
+
<%= pb_rails("flex") do %>
|
19
|
+
<% initial_items.each do |item| %>
|
20
|
+
<%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id]}) do %>
|
21
|
+
<%= pb_rails("image", props: { alt: item[:id], size: "md", url: item[:url], margin: "xs" }) %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
The `draggable` kit gives you a full subcomponent structure that allows it to be used with almost any kit.
|
2
|
+
|
3
|
+
`initial_items` is a REQUIRED prop, which is the array of objects that contains data for the the draggable items.
|
4
|
+
|
5
|
+
`draggable/draggable_container` = This specifies the container within which items can be dropped.
|
6
|
+
|
7
|
+
`draggable/draggable_item` = This specifies the items that can be dragged and dropped. `drag_id` is a REQUIRED prop for draggable_item and must match the id on the items within `initial_items`.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<% initial_items = [
|
2
|
+
{ id: "21", name: "Joe Black" },
|
3
|
+
{ id: "22", name: "Nancy White" },
|
4
|
+
{ id: "23", name: "Bill Green" },
|
5
|
+
] %>
|
6
|
+
|
7
|
+
<%= pb_rails("draggable", props: {initial_items: initial_items}) do %>
|
8
|
+
<%= pb_rails("draggable/draggable_container") do %>
|
9
|
+
<% initial_items.each do |item| %>
|
10
|
+
<%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id]}) do %>
|
11
|
+
<%= pb_rails("card", props: {highlight: {position: "side", color:"primary"}, margin_bottom: "xs", padding: "xs"}) do %>
|
12
|
+
<%= pb_rails("flex", props:{align_items: "stretch", flex_direction:"column"}) do %>
|
13
|
+
<%= pb_rails("flex", props:{gap: "xs"}) do %>
|
14
|
+
<%= pb_rails("title", props: { text: item[:name], tag: "h4", size: 4 }) %>
|
15
|
+
<%= pb_rails("badge", props: {text:"35-12345" ,variant: "primary"}) %>
|
16
|
+
<% end %>
|
17
|
+
<%= pb_rails("caption", props: { size: "xs", text: "8:00A • Township Name • 90210" }) %>
|
18
|
+
<%= pb_rails("flex", props:{gap: "xxs", spacing:"between"}) do %>
|
19
|
+
<%= pb_rails("flex", props:{gap: "xxs"}) do %>
|
20
|
+
<%= pb_rails("caption", props: { size: "xs" , color: "error" }) do %>
|
21
|
+
<%= pb_rails("icon", props: { icon: "house-circle-exclamation", fixed_width: true }) %>
|
22
|
+
<% end %>
|
23
|
+
<%= pb_rails("caption", props: { size: "xs" , color: "success" }) do %>
|
24
|
+
<%= pb_rails("icon", props: { icon: "file-circle-check", fixed_width: true }) %>
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
27
|
+
<%= pb_rails("flex") do %>
|
28
|
+
<%= pb_rails("badge", props: {text:"Schedule QA" ,variant: "warning", rounded: true}) %>
|
29
|
+
<%= pb_rails("badge", props: {text:"Flex" ,variant: "primary", rounded: true}) %>
|
30
|
+
<%= pb_rails("badge", props: {text:"R99" ,variant: "primary", rounded: true}) %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
<% end %>
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<% initial_items = [
|
2
|
+
{ id: "31", name: "Philadelphia" },
|
3
|
+
{ id: "32", name: "New Jersey" },
|
4
|
+
{ id: "33", name: "Maryland" },
|
5
|
+
{ id: "34", name: "Connecticut" },
|
6
|
+
|
7
|
+
] %>
|
8
|
+
|
9
|
+
<%= pb_rails("draggable", props: {initial_items: initial_items}) do %>
|
10
|
+
<%= pb_rails("draggable/draggable_container") do %>
|
11
|
+
<%= pb_rails("list", props: {ordered: false}) do %>
|
12
|
+
<% initial_items.each do |item| %>
|
13
|
+
<%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id]}) do %>
|
14
|
+
<%= pb_rails("list/item") do %><%= item[:name] %><% end %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
@@ -8,4 +8,10 @@ examples:
|
|
8
8
|
- draggable_with_cards: Draggable with Cards
|
9
9
|
- draggable_multiple_containers: Dragging Across Multiple Containers
|
10
10
|
|
11
|
+
rails:
|
12
|
+
- draggable_default_rails: Default
|
13
|
+
- draggable_with_list_rails: Draggable with List Kit
|
14
|
+
- draggable_with_cards_rails: Draggable with Cards
|
15
|
+
|
16
|
+
|
11
17
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbDraggable
|
5
|
+
class Draggable < ::Playbook::KitBase
|
6
|
+
prop :initial_items, type: Playbook::Props::Array,
|
7
|
+
default: []
|
8
|
+
|
9
|
+
def data
|
10
|
+
Hash(prop(:data)).merge(pb_draggable: true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def classname
|
14
|
+
generate_classname("pb_draggable")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbDraggable
|
5
|
+
class DraggableContainer < ::Playbook::KitBase
|
6
|
+
def data
|
7
|
+
Hash(prop(:data)).merge(pb_draggable_container: true)
|
8
|
+
end
|
9
|
+
|
10
|
+
def classname
|
11
|
+
generate_classname("pb_draggable_container")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbDraggable
|
5
|
+
class DraggableItem < ::Playbook::KitBase
|
6
|
+
prop :drag_id, type: Playbook::Props::String,
|
7
|
+
default: ""
|
8
|
+
|
9
|
+
def data
|
10
|
+
Hash(prop(:data)).merge(pb_draggable_item: true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def classname
|
14
|
+
generate_classname("pb_draggable_item")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
import PbEnhancedElement from "../pb_enhanced_element";
|
2
|
+
|
3
|
+
const DRAGGABLE_SELECTOR = "[data-pb-draggable]";
|
4
|
+
const DRAGGABLE_CONTAINER = ".pb_draggable_container";
|
5
|
+
|
6
|
+
export default class PbDraggable extends PbEnhancedElement {
|
7
|
+
static get selector() {
|
8
|
+
return DRAGGABLE_SELECTOR;
|
9
|
+
}
|
10
|
+
|
11
|
+
connect() {
|
12
|
+
this.draggedItem = null;
|
13
|
+
this.draggedItemId = null;
|
14
|
+
document.addEventListener("DOMContentLoaded", () => this.bindEventListeners());
|
15
|
+
}
|
16
|
+
|
17
|
+
bindEventListeners() {
|
18
|
+
// Needed to prevent images within draggable items from being independently draggable
|
19
|
+
// Needed if using Image kit in draggable items
|
20
|
+
this.element.querySelectorAll(".pb_draggable_item img").forEach(img => {
|
21
|
+
img.setAttribute("draggable", "false");
|
22
|
+
});
|
23
|
+
|
24
|
+
this.element.querySelectorAll(".pb_draggable_item").forEach(item => {
|
25
|
+
item.addEventListener("dragstart", this.handleDragStart.bind(this));
|
26
|
+
item.addEventListener("dragend", this.handleDragEnd.bind(this));
|
27
|
+
item.addEventListener("dragenter", this.handleDragEnter.bind(this));
|
28
|
+
});
|
29
|
+
|
30
|
+
const container = this.element.querySelector(DRAGGABLE_CONTAINER);
|
31
|
+
if (container) {
|
32
|
+
container.addEventListener("dragover", this.handleDragOver.bind(this));
|
33
|
+
container.addEventListener("drop", this.handleDrop.bind(this));
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
handleDragStart(event) {
|
38
|
+
// Needed to prevent images within draggable items from being independently draggable
|
39
|
+
// Needed if using Image kit in draggable items
|
40
|
+
if (event.target.tagName.toLowerCase() === 'img') {
|
41
|
+
event.preventDefault();
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
|
45
|
+
this.draggedItem = event.target;
|
46
|
+
this.draggedItemId = event.target.id;
|
47
|
+
event.target.classList.add("is_dragging");
|
48
|
+
|
49
|
+
if (event.dataTransfer) {
|
50
|
+
event.dataTransfer.effectAllowed = 'move';
|
51
|
+
event.dataTransfer.setData('text/plain', this.draggedItemId);
|
52
|
+
}
|
53
|
+
|
54
|
+
setTimeout(() => {
|
55
|
+
event.target.style.opacity = '0.5';
|
56
|
+
}, 0);
|
57
|
+
}
|
58
|
+
|
59
|
+
handleDragEnter(event) {
|
60
|
+
if (!this.draggedItem || event.target === this.draggedItem) return;
|
61
|
+
|
62
|
+
const targetItem = event.target.closest('.pb_draggable_item');
|
63
|
+
if (!targetItem) return;
|
64
|
+
|
65
|
+
const container = targetItem.parentNode;
|
66
|
+
const items = Array.from(container.children);
|
67
|
+
const draggedIndex = items.indexOf(this.draggedItem);
|
68
|
+
const targetIndex = items.indexOf(targetItem);
|
69
|
+
|
70
|
+
if (draggedIndex > targetIndex) {
|
71
|
+
container.insertBefore(this.draggedItem, targetItem);
|
72
|
+
} else {
|
73
|
+
container.insertBefore(this.draggedItem, targetItem.nextSibling);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
handleDragOver(event) {
|
78
|
+
event.preventDefault();
|
79
|
+
const container = event.target.closest(DRAGGABLE_CONTAINER);
|
80
|
+
|
81
|
+
if (container) {
|
82
|
+
container.classList.add("active_container");
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
handleDrop(event) {
|
87
|
+
event.preventDefault();
|
88
|
+
const container = event.target.closest(DRAGGABLE_CONTAINER);
|
89
|
+
if (!container || !this.draggedItem) return;
|
90
|
+
|
91
|
+
container.classList.remove("active_container");
|
92
|
+
this.draggedItem.style.opacity = '1';
|
93
|
+
|
94
|
+
// Updated order of items as an array of item IDs
|
95
|
+
const reorderedItems = Array.from(container.children)
|
96
|
+
.filter(item => item.classList.contains("pb_draggable_item"))
|
97
|
+
.map(item => item.id.replace("item_", ""));
|
98
|
+
|
99
|
+
// Store reordered items in a data attribute on the container
|
100
|
+
container.setAttribute("data-reordered-items", JSON.stringify(reorderedItems));
|
101
|
+
|
102
|
+
const customEvent = new CustomEvent('pb-draggable-reorder', {
|
103
|
+
detail: {
|
104
|
+
reorderedItems,
|
105
|
+
containerId: container.id,
|
106
|
+
}
|
107
|
+
});
|
108
|
+
this.element.dispatchEvent(customEvent);
|
109
|
+
|
110
|
+
this.draggedItem = null;
|
111
|
+
this.draggedItemId = null;
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
handleDragEnd(event) {
|
116
|
+
event.target.classList.remove("is_dragging");
|
117
|
+
event.target.style.opacity = '1';
|
118
|
+
this.draggedItem = null;
|
119
|
+
this.draggedItemId = null;
|
120
|
+
|
121
|
+
this.element.querySelectorAll(DRAGGABLE_CONTAINER).forEach(container => {
|
122
|
+
container.classList.remove("active_container");
|
123
|
+
});
|
124
|
+
}
|
125
|
+
}
|
@@ -23,7 +23,7 @@
|
|
23
23
|
%>
|
24
24
|
|
25
25
|
<%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
|
26
|
-
<%= form.typeahead :
|
26
|
+
<%= form.typeahead :example_user, props: { data: { typeahead_example1: true, user: {} }, placeholder: "Search for a user" } %>
|
27
27
|
<%= form.text_field :example_text_field, props: { label: true } %>
|
28
28
|
<%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
|
29
29
|
<%= form.email_field :example_email_field, props: { label: true } %>
|
@@ -92,7 +92,7 @@
|
|
92
92
|
const selectedUserData = JSON.parse(selectedUserJSON)
|
93
93
|
|
94
94
|
// set the input field's value
|
95
|
-
event.target.querySelector('input[name=
|
95
|
+
event.target.querySelector('input[name=example_user]').value = selectedUserData.login
|
96
96
|
|
97
97
|
// log the selected option's dataset
|
98
98
|
console.log('The selected user data:')
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= pb_form_with(scope: :example, url: "", method: :get, loading: true) do |form| %>
|
2
|
-
<%= form.text_field :
|
2
|
+
<%= form.text_field :example_text_field, props: { label: true } %>
|
3
3
|
|
4
4
|
<%= form.actions do |action| %>
|
5
5
|
<%= action.submit %>
|
@@ -22,74 +22,23 @@
|
|
22
22
|
%>
|
23
23
|
|
24
24
|
<%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
|
25
|
-
<%= form.
|
26
|
-
<%= form.
|
27
|
-
<%= form.
|
28
|
-
<%= form.
|
29
|
-
<%= form.
|
30
|
-
<%= form.
|
31
|
-
<%= form.
|
32
|
-
<%= form.
|
33
|
-
<%= form.
|
34
|
-
<%= form.
|
35
|
-
<%= form.
|
36
|
-
<%= form.collection_select :example_collection_select_validation, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
|
25
|
+
<%= form.text_field :example_text_field, props: { label: true, required: true } %>
|
26
|
+
<%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
|
27
|
+
<%= form.email_field :example_email_field, props: { label: true, required: true } %>
|
28
|
+
<%= form.number_field :example_number_field, props: { label: true, required: true } %>
|
29
|
+
<%= form.search_field :example_project_number, props: { label: true, required: true, validation: { pattern: "[0-9]{2}-[0-9]{5}", message: "Please enter a valid project number (example: 33-12345)." } } %>
|
30
|
+
<%= form.password_field :example_password_field, props: { label: true, required: true } %>
|
31
|
+
<%= form.url_field :example_url_field, props: { label: true, required: true } %>
|
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 } %>
|
34
|
+
<%= form.select :example_select, [ ["Yes", 1], ["No", 2] ], props: { label: true, blank_selection: "Select One...", required: true } %>
|
35
|
+
<%= form.collection_select :example_collection_select, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
|
37
36
|
<%= form.check_box :example_checkbox, props: { text: "Example Checkbox", label: true, required: true } %>
|
38
37
|
<%= form.date_picker :example_date_picker_2, props: { label: true, required: true } %>
|
39
|
-
<%= form.star_rating_field :
|
38
|
+
<%= form.star_rating_field :example_star_rating, props: { variant: "interactive", label: true, required: true } %>
|
40
39
|
|
41
40
|
<%= form.actions do |action| %>
|
42
41
|
<%= action.submit %>
|
43
42
|
<%= action.button props: { type: "reset", text: "Cancel", variant: "secondary" } %>
|
44
43
|
<% end %>
|
45
44
|
<% end %>
|
46
|
-
|
47
|
-
<!-- form.typeahead user results example template -->
|
48
|
-
<template data-typeahead-example-result-option>
|
49
|
-
<%= pb_rails("user", props: {
|
50
|
-
name: tag(:slot, name: "name"),
|
51
|
-
orientation: "horizontal",
|
52
|
-
align: "left",
|
53
|
-
avatar_url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=",
|
54
|
-
avatar: true
|
55
|
-
}) %>
|
56
|
-
</template>
|
57
|
-
|
58
|
-
<!-- form.typeahead JS example implementation -->
|
59
|
-
<%= javascript_tag defer: "defer" do %>
|
60
|
-
document.addEventListener("pb-typeahead-kit-search", function(event) {
|
61
|
-
if (!event.target.dataset || !event.target.dataset.typeaheadExample2) return
|
62
|
-
|
63
|
-
fetch(`https://api.github.com/search/users?q=${encodeURIComponent(event.detail.searchingFor)}`)
|
64
|
-
.then(response => response.json())
|
65
|
-
.then((result) => {
|
66
|
-
const resultOptionTemplate = document.querySelector("[data-typeahead-example-result-option]")
|
67
|
-
|
68
|
-
event.detail.setResults((result.items || []).map((user) => {
|
69
|
-
const wrapper = resultOptionTemplate.content.cloneNode(true)
|
70
|
-
wrapper.children[0].dataset.user = JSON.stringify(user)
|
71
|
-
wrapper.querySelector('slot[name="name"]').replaceWith(user.login)
|
72
|
-
wrapper.querySelector('img').dataset.src = user.avatar_url
|
73
|
-
return wrapper
|
74
|
-
}))
|
75
|
-
})
|
76
|
-
})
|
77
|
-
|
78
|
-
|
79
|
-
document.addEventListener("pb-typeahead-kit-result-option-selected", function(event) {
|
80
|
-
if (!event.target.dataset.typeaheadExample2) return
|
81
|
-
|
82
|
-
const selectedUserJSON = event.detail.selected.firstElementChild.dataset.user
|
83
|
-
const selectedUserData = JSON.parse(selectedUserJSON)
|
84
|
-
|
85
|
-
// set the input field's value
|
86
|
-
event.target.querySelector('input[name=example_typeahead_validation]').value = selectedUserData.login
|
87
|
-
|
88
|
-
// log the selected option's dataset
|
89
|
-
console.log('The selected user data:')
|
90
|
-
console.dir(selectedUserData)
|
91
|
-
|
92
|
-
// do even more with the data later - TBD
|
93
|
-
event.target.dataset.user = selectedUserJSON
|
94
|
-
})
|
95
|
-
<% end %>
|
@@ -4,12 +4,11 @@ import { debounce } from 'lodash'
|
|
4
4
|
export default class PbTypeahead extends PbEnhancedElement {
|
5
5
|
_searchInput: HTMLInputElement
|
6
6
|
_resultsElement: HTMLElement
|
7
|
-
_debouncedSearch:
|
7
|
+
_debouncedSearch: Function
|
8
8
|
_resultsLoadingIndicator: HTMLElement
|
9
9
|
_resultOptionTemplate: HTMLElement
|
10
10
|
_resultsOptionCache: Map<string, Array<DocumentFragment>>
|
11
11
|
_searchContext: string
|
12
|
-
_validSelection: boolean
|
13
12
|
|
14
13
|
static get selector() {
|
15
14
|
return '[data-pb-typeahead-kit]'
|
@@ -20,7 +19,6 @@ export default class PbTypeahead extends PbEnhancedElement {
|
|
20
19
|
this.searchInput.addEventListener('focus', () => this.debouncedSearch())
|
21
20
|
this.searchInput.addEventListener('input', () => this.debouncedSearch())
|
22
21
|
this.resultsElement.addEventListener('click', (event: MouseEvent) => this.optionSelected(event))
|
23
|
-
this.element.closest('form')?.addEventListener('submit', (event) => this.handleFormSubmission(event))
|
24
22
|
}
|
25
23
|
|
26
24
|
handleKeydown(event: KeyboardEvent) {
|
@@ -88,9 +86,6 @@ export default class PbTypeahead extends PbEnhancedElement {
|
|
88
86
|
const resultOption = (event.target as Element).closest('[data-result-option-item]')
|
89
87
|
if (!resultOption) return
|
90
88
|
|
91
|
-
this._validSelection = true
|
92
|
-
this.removeValidationError()
|
93
|
-
|
94
89
|
this.resultsCacheClear()
|
95
90
|
this.searchInputClear()
|
96
91
|
this.clearResults()
|
@@ -98,35 +93,6 @@ export default class PbTypeahead extends PbEnhancedElement {
|
|
98
93
|
this.element.dispatchEvent(new CustomEvent('pb-typeahead-kit-result-option-selected', { bubbles: true, detail: { selected: resultOption, typeahead: this } }))
|
99
94
|
}
|
100
95
|
|
101
|
-
removeValidationError() {
|
102
|
-
const inputWrapper = this.searchInput.closest('.text_input_wrapper')
|
103
|
-
if (inputWrapper) {
|
104
|
-
const errorMessage = inputWrapper.querySelector('.pb_body_kit_negative') as HTMLElement
|
105
|
-
if (errorMessage) {
|
106
|
-
errorMessage.style.display = 'none'
|
107
|
-
}
|
108
|
-
this.searchInput.classList.remove('error')
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
showValidationError() {
|
113
|
-
const inputWrapper = this.searchInput.closest('.text_input_wrapper')
|
114
|
-
if (inputWrapper) {
|
115
|
-
const errorMessage = inputWrapper.querySelector('.pb_body_kit_negative') as HTMLElement
|
116
|
-
if (errorMessage) {
|
117
|
-
errorMessage.style.display = 'block'
|
118
|
-
}
|
119
|
-
this.searchInput.classList.add('error')
|
120
|
-
}
|
121
|
-
}
|
122
|
-
|
123
|
-
handleFormSubmission(event: Event) {
|
124
|
-
if (!this._validSelection) {
|
125
|
-
this.showValidationError()
|
126
|
-
event.preventDefault()
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
96
|
clearResults() {
|
131
97
|
this.resultsElement.innerHTML = ''
|
132
98
|
}
|
@@ -235,7 +201,7 @@ export default class PbTypeahead extends PbEnhancedElement {
|
|
235
201
|
}
|
236
202
|
|
237
203
|
toggleResultsLoadingIndicator(visible: boolean) {
|
238
|
-
|
204
|
+
var visibilityProperty = '0'
|
239
205
|
if (visible) visibilityProperty = '1'
|
240
206
|
this.resultsLoadingIndicator.style.opacity = visibilityProperty
|
241
207
|
}
|
@@ -17,14 +17,11 @@
|
|
17
17
|
<%= pb_rails("text_input", props: {
|
18
18
|
type: "search",
|
19
19
|
input_options: object.input_options,
|
20
|
+
label: object.label,
|
20
21
|
name: object.name,
|
21
22
|
value: object.value,
|
22
23
|
placeholder: object.placeholder,
|
23
24
|
margin_bottom: "none",
|
24
|
-
required: object.required,
|
25
|
-
validation: object.validation,
|
26
|
-
label: object.label,
|
27
|
-
id: object.input_options[:id],
|
28
25
|
}) %>
|
29
26
|
<%= pb_rails("list", props: { ordered: false, borderless: false, xpadding: true, role: "status", aria: { live: "polite" }, data: { pb_typeahead_kit_results: true } }) do %>
|
30
27
|
<% end %>
|
@@ -36,4 +33,4 @@
|
|
36
33
|
<% end %>
|
37
34
|
</template>
|
38
35
|
<% end %>
|
39
|
-
<% end %>
|
36
|
+
<% end %>
|
@@ -40,10 +40,6 @@ module Playbook
|
|
40
40
|
prop :pill_color, type: Playbook::Props::Enum,
|
41
41
|
values: %w[primary neutral success warning error info data_1 data_2 data_3 data_4 data_5 data_6 data_7 data_8 windows siding roofing doors gutters solar insulation accessories],
|
42
42
|
default: "primary"
|
43
|
-
prop :required, type: Playbook::Props::Boolean,
|
44
|
-
default: false
|
45
|
-
prop :validation, type: Playbook::Props::HashProp,
|
46
|
-
default: {}
|
47
43
|
|
48
44
|
def classname
|
49
45
|
default_margin_bottom = margin_bottom.present? ? "" : " mb_sm"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{jsx as jsx$1,Fragment,jsxs}from"react/jsx-runtime";import*as React from"react";import React__default,{createContext,useReducer,useEffect,useMemo,useContext,createElement,useState,useRef,forwardRef,useLayoutEffect,useCallback,useImperativeHandle,Component,Fragment as Fragment$1}from"react";import{q as getDefaultExportFromCjs,w as filter,x as omit,j as getAllIcons,y as get,n as commonjsGlobal,v as colors$1,s as highchartsTheme,z as merge,r as highchartsDarkTheme,A as useCollapsible,B as getAugmentedNamespace,C as createPopper,E as uniqueId,F as typography,G as cloneDeep,H as isString}from"./lib-
|
1
|
+
import{jsx as jsx$1,Fragment,jsxs}from"react/jsx-runtime";import*as React from"react";import React__default,{createContext,useReducer,useEffect,useMemo,useContext,createElement,useState,useRef,forwardRef,useLayoutEffect,useCallback,useImperativeHandle,Component,Fragment as Fragment$1}from"react";import{q as getDefaultExportFromCjs,w as filter,x as omit,j as getAllIcons,y as get,n as commonjsGlobal,v as colors$1,s as highchartsTheme,z as merge,r as highchartsDarkTheme,A as useCollapsible,B as getAugmentedNamespace,C as createPopper,E as uniqueId,F as typography,G as cloneDeep,H as isString}from"./lib-D-mTv-kp.js";import*as ReactDOM from"react-dom";import ReactDOM__default,{createPortal}from"react-dom";import{TrixEditor}from"react-trix";import Trix from"trix";import require$$0 from"react-is";const initialState={items:[],dragData:{id:"",initialGroup:""},isDragging:"",activeContainer:""};const reducer=(state,action)=>{switch(action.type){case"SET_ITEMS":return Object.assign(Object.assign({},state),{items:action.payload});case"SET_DRAG_DATA":return Object.assign(Object.assign({},state),{dragData:action.payload});case"SET_IS_DRAGGING":return Object.assign(Object.assign({},state),{isDragging:action.payload});case"SET_ACTIVE_CONTAINER":return Object.assign(Object.assign({},state),{activeContainer:action.payload});case"CHANGE_CATEGORY":return Object.assign(Object.assign({},state),{items:state.items.map((item=>item.id===action.payload.itemId?Object.assign(Object.assign({},item),{container:action.payload.container}):item))});case"REORDER_ITEMS":{const{dragId:dragId,targetId:targetId}=action.payload;const newItems=[...state.items];const draggedItem=newItems.find((item=>item.id===dragId));const draggedIndex=newItems.indexOf(draggedItem);const targetIndex=newItems.findIndex((item=>item.id===targetId));newItems.splice(draggedIndex,1);newItems.splice(targetIndex,0,draggedItem);return Object.assign(Object.assign({},state),{items:newItems})}default:return state}};const DragContext=createContext({});const DraggableContext=()=>useContext(DragContext);const DraggableProvider=({children:children,initialItems:initialItems,onReorder:onReorder,onDragStart:onDragStart,onDragEnter:onDragEnter,onDragEnd:onDragEnd,onDrop:onDrop,onDragOver:onDragOver})=>{const[state,dispatch]=useReducer(reducer,initialState);useEffect((()=>{dispatch({type:"SET_ITEMS",payload:initialItems})}),[initialItems]);useEffect((()=>{onReorder(state.items)}),[state.items]);const handleDragStart=(id,container)=>{dispatch({type:"SET_DRAG_DATA",payload:{id:id,initialGroup:container}});dispatch({type:"SET_IS_DRAGGING",payload:id});if(onDragStart)onDragStart(id,container)};const handleDragEnter=(id,container)=>{if(state.dragData.id!==id){dispatch({type:"REORDER_ITEMS",payload:{dragId:state.dragData.id,targetId:id}});dispatch({type:"SET_DRAG_DATA",payload:{id:state.dragData.id,initialGroup:container}})}if(onDragEnter)onDragEnter(id,container)};const handleDragEnd=()=>{dispatch({type:"SET_IS_DRAGGING",payload:""});dispatch({type:"SET_ACTIVE_CONTAINER",payload:""});if(onDragEnd)onDragEnd()};const changeCategory=(itemId,container)=>{dispatch({type:"CHANGE_CATEGORY",payload:{itemId:itemId,container:container}})};const handleDrop=container=>{dispatch({type:"SET_IS_DRAGGING",payload:""});dispatch({type:"SET_ACTIVE_CONTAINER",payload:""});changeCategory(state.dragData.id,container);if(onDrop)onDrop(container)};const handleDragOver=(e2,container)=>{e2.preventDefault();dispatch({type:"SET_ACTIVE_CONTAINER",payload:container});if(onDragOver)onDragOver(e2,container)};const contextValue=useMemo((()=>({items:state.items,dragData:state.dragData,isDragging:state.isDragging,activeContainer:state.activeContainer,handleDragStart:handleDragStart,handleDragEnter:handleDragEnter,handleDragEnd:handleDragEnd,handleDrop:handleDrop,handleDragOver:handleDragOver})),[state]);return jsx$1(DragContext.Provider,Object.assign({value:contextValue},{children:children}),void 0)};var classnames$1={exports:{}};
|
2
2
|
/*!
|
3
3
|
Copyright (c) 2018 Jed Watson.
|
4
4
|
Licensed under the MIT License (MIT), see
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{r as requireLazysizes}from"./lazysizes-B7xYodB-.js";import{jsx,Fragment,jsxs}from"react/jsx-runtime";import*as React from"react";import React__default,{useEffect,createContext,useContext,useState,useCallback,createElement,forwardRef,useRef,useImperativeHandle,Fragment as Fragment$1,useReducer,useMemo,useLayoutEffect,isValidElement}from"react";import{h as buildAriaProps,i as buildDataProps,j as buildHtmlProps,k as classnames,l as globalProps,m as buildCss,F as Flex,I as Icon,n as FlexItem,o as Body$1,p as Caption,A as Avatar,q as domSafeProps,r as Title,S as SectionSeparator,s as DialogContext,t as Modal,u as Draggable,v as TextInput,_ as __awaiter,w as __generator,x as __spread,y as PropTypes,z as Card,E as noop$3,H as PbReactPopover,J as CircleIconButton,K as Button,N as HighchartsReact,O as Badge,Q as joinPresent,U as titleize,V as IconCircle,W as Image,X as Checkbox,Y as Radio}from"./_typeahead-
|
1
|
+
import{r as requireLazysizes}from"./lazysizes-B7xYodB-.js";import{jsx,Fragment,jsxs}from"react/jsx-runtime";import*as React from"react";import React__default,{useEffect,createContext,useContext,useState,useCallback,createElement,forwardRef,useRef,useImperativeHandle,Fragment as Fragment$1,useReducer,useMemo,useLayoutEffect,isValidElement}from"react";import{h as buildAriaProps,i as buildDataProps,j as buildHtmlProps,k as classnames,l as globalProps,m as buildCss,F as Flex,I as Icon,n as FlexItem,o as Body$1,p as Caption,A as Avatar,q as domSafeProps,r as Title,S as SectionSeparator,s as DialogContext,t as Modal,u as Draggable,v as TextInput,_ as __awaiter,w as __generator,x as __spread,y as PropTypes,z as Card,E as noop$3,H as PbReactPopover,J as CircleIconButton,K as Button,N as HighchartsReact,O as Badge,Q as joinPresent,U as titleize,V as IconCircle,W as Image,X as Checkbox,Y as Radio}from"./_typeahead-DhLic2Fe.js";import{h as PbTable,j as getAllIcons,D as DateTime$1,a as datePickerHelper,u as useDropdown,o as omitBy,k as isEmpty,m as map,p as partial,l as find$1,n as commonjsGlobal,q as getDefaultExportFromCjs,r as highchartsDarkTheme,s as highchartsTheme,t as noop$4,v as colors,i as PbTextarea}from"./lib-D-mTv-kp.js";import*as ReactDOM from"react-dom";import ReactDOM__default,{createPortal}from"react-dom";var ls_attrchange={exports:{}};(function(module){(function(window2,factory){if(!window2){return}var globalInstall=function(){factory(window2.lazySizes);window2.removeEventListener("lazyunveilread",globalInstall,true)};factory=factory.bind(null,window2,window2.document);if(module.exports){factory(requireLazysizes())}else if(window2.lazySizes){globalInstall()}else{window2.addEventListener("lazyunveilread",globalInstall,true)}})(typeof window!="undefined"?window:0,(function(window2,document2,lazySizes){var addObserver=function(){var connect,disconnect,observer,connected;var lsCfg=lazySizes.cfg;var attributes={"data-bgset":1,"data-include":1,"data-poster":1,"data-bg":1,"data-script":1};var regClassTest="(\\s|^)("+lsCfg.loadedClass;var docElem=document2.documentElement;var setClass=function(target){lazySizes.rAF((function(){lazySizes.rC(target,lsCfg.loadedClass);if(lsCfg.unloadedClass){lazySizes.rC(target,lsCfg.unloadedClass)}lazySizes.aC(target,lsCfg.lazyClass);if(target.style.display=="none"||target.parentNode&&target.parentNode.style.display=="none"){setTimeout((function(){lazySizes.loader.unveil(target)}),0)}}))};var onMutation=function(mutations){var i,len,mutation,target;for(i=0,len=mutations.length;i<len;i++){mutation=mutations[i];target=mutation.target;if(!target.getAttribute(mutation.attributeName)){continue}if(target.localName=="source"&&target.parentNode){target=target.parentNode.querySelector("img")}if(target&®ClassTest.test(target.className)){setClass(target)}}};if(lsCfg.unloadedClass){regClassTest+="|"+lsCfg.unloadedClass}regClassTest+="|"+lsCfg.loadingClass+")(\\s|$)";regClassTest=new RegExp(regClassTest);attributes[lsCfg.srcAttr]=1;attributes[lsCfg.srcsetAttr]=1;if(window2.MutationObserver){observer=new MutationObserver(onMutation);connect=function(){if(!connected){connected=true;observer.observe(docElem,{subtree:true,attributes:true,attributeFilter:Object.keys(attributes)})}};disconnect=function(){if(connected){connected=false;observer.disconnect()}}}else{docElem.addEventListener("DOMAttrModified",function(){var runs;var modifications=[];var callMutations=function(){onMutation(modifications);modifications=[];runs=false};return function(e){if(connected&&attributes[e.attrName]&&e.newValue){modifications.push({target:e.target,attributeName:e.attrName});if(!runs){setTimeout(callMutations);runs=true}}}}(),true);connect=function(){connected=true};disconnect=function(){connected=false}}addEventListener("lazybeforeunveil",disconnect,true);addEventListener("lazybeforeunveil",connect);addEventListener("lazybeforesizes",disconnect,true);addEventListener("lazybeforesizes",connect);connect();removeEventListener("lazybeforeunveil",addObserver)};addEventListener("lazybeforeunveil",addObserver)}))})(ls_attrchange);
|
2
2
|
/**
|
3
3
|
* table-core
|
4
4
|
*
|