playbook_ui 14.11.1.pre.alpha.PBNTR769sticky5359 → 14.11.1.pre.alpha.PBNTR798datepickerturbo5537
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +0 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_control.md +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -2
- data/app/pb_kits/playbook/pb_button/button.html.erb +2 -3
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +1 -6
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +24 -16
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default_date.md +1 -1
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_turbo_frames.html.erb +13 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_turbo_frames_rails.md +3 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.html.erb +3 -9
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.md +5 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.html.erb +38 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.md +3 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.md +1 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +7 -12
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +9 -14
- data/app/pb_kits/playbook/pb_dropdown/dropdown_option.html.erb +6 -11
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +8 -14
- data/app/pb_kits/playbook/pb_list/item.html.erb +30 -8
- data/app/pb_kits/playbook/pb_list/item.rb +7 -0
- data/app/pb_kits/playbook/pb_list/list.html.erb +31 -11
- data/app/pb_kits/playbook/pb_list/list.rb +4 -0
- data/app/pb_kits/playbook/pb_loading_inline/_loading_inline.tsx +6 -1
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +30 -12
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.html.erb +15 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.jsx +24 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_format.md +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +3 -1
- data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +20 -1
- data/app/pb_kits/playbook/pb_radio/_radio.scss +12 -8
- data/app/pb_kits/playbook/pb_radio/docs/_radio_custom_children.jsx +8 -3
- data/app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb +17 -3
- data/app/pb_kits/playbook/pb_selectable_list/selectable_list.rb +3 -0
- data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb +11 -4
- data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.rb +3 -0
- data/app/pb_kits/playbook/pb_table/_table.tsx +2 -3
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns.html.erb +74 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns_rails.md +3 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns_rails.md +2 -2
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns.html.erb +74 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns_rails.md +3 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_table/index.ts +93 -34
- data/app/pb_kits/playbook/pb_table/styles/_scroll.scss +6 -5
- data/app/pb_kits/playbook/pb_table/table.html.erb +1 -1
- data/app/pb_kits/playbook/pb_table/table.rb +17 -2
- data/app/pb_kits/playbook/pb_table/utilities/addDataTitle.ts +22 -0
- data/app/pb_kits/playbook/pb_timeline/_timeline.scss +30 -30
- data/dist/chunks/{_typeahead-BNULwihE.js → _typeahead-TN5aDUj9.js} +2 -2
- data/dist/chunks/_weekday_stacked-BcnpLG66.js +45 -0
- data/dist/chunks/{lib-B7sgJtGS.js → lib-OFT985dg.js} +2 -2
- data/dist/chunks/{pb_form_validation-C5Cc0-1v.js → pb_form_validation-CrsXd1-Y.js} +1 -1
- data/dist/chunks/vendor.js +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/version.rb +1 -1
- metadata +33 -7
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_responsive.jsx +0 -52
- data/dist/chunks/_weekday_stacked-BKWemDAe.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9db2c07365905ebc29fe49d03e07ebffa52ad662459427fe22a5dfadf4b9131
|
4
|
+
data.tar.gz: 4397ab9e0058cebebc804b899f98eeeb84486b502380360135adbbc12e264559
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec13a85caeecebf850170e19c3eba654ad56ea06d6b186d8acfa9586dd4ed1ba0a97f4172cbc9fb60d675401acad7903f1f90f04a374613df457762bf1e51f9c
|
7
|
+
data.tar.gz: 9efa5d87d16f447ffe8011ebbcfbfa9133eb276758db161fc5097e698f53f55f4bf68a289b546902719f8adff35cf5f62ab211067027f72101b47df6dadabcb9
|
@@ -1,3 +1,3 @@
|
|
1
|
-
`sortControl` is an optional prop that can be used to gain greater control over the sort state of the Advanced Table. Tanstack handles sort itself, however it does provide for a way to handle the state manually if needed. Usecases for this include needing to store the sort state so it persists on page reload, set an initial sort state, etc.
|
1
|
+
`sortControl` is an optional prop that can be used to gain greater control over the sort state of the Advanced Table. Tanstack handles sort itself, however it does provide for a way to handle the state manually if needed. Usecases for this include needing to store the sort state so it persists on page reload, set an initial sort state, etc.
|
2
2
|
|
3
|
-
The sort state must be an object with a single key/value pair, with the key being "desc" and the value being a boolean. The default for sort
|
3
|
+
The sort state must be an object with a single key/value pair, with the key being "desc" and the value being a boolean. The default for sort direction is `desc: true`.
|
@@ -22,7 +22,6 @@ examples:
|
|
22
22
|
- advanced_table_table_props: Table Props
|
23
23
|
- advanced_table_inline_row_loading: Inline Row Loading
|
24
24
|
- advanced_table_responsive: Responsive Tables
|
25
|
-
- advanced_table_sticky_header_responsive: Sticky Header and Responsive
|
26
25
|
- advanced_table_custom_cell: Custom Components for Cells
|
27
26
|
- advanced_table_pagination: Pagination
|
28
27
|
- advanced_table_pagination_with_props: Pagination Props
|
@@ -13,5 +13,4 @@ export { default as AdvancedTableCustomCell } from './_advanced_table_custom_cel
|
|
13
13
|
export { default as AdvancedTablePagination } from './_advanced_table_pagination.jsx'
|
14
14
|
export { default as AdvancedTablePaginationWithProps } from './_advanced_table_pagination_with_props.jsx'
|
15
15
|
export { default as AdvancedTableColumnHeaders } from './_advanced_table_column_headers.jsx'
|
16
|
-
export { default as AdvancedTableColumnHeadersMultiple } from './_advanced_table_column_headers_multiple.jsx'
|
17
|
-
export { default as AdvancedTableStickyHeaderResponsive } from './_advanced_table_sticky_header_responsive.jsx'
|
16
|
+
export { default as AdvancedTableColumnHeadersMultiple } from './_advanced_table_column_headers_multiple.jsx'
|
@@ -1,6 +1,5 @@
|
|
1
|
-
<%=
|
2
|
-
object.tag == "button" ? object.options : object.link_options
|
3
|
-
**combined_html_options) do %>
|
1
|
+
<%= pb_content_tag(object.tag,
|
2
|
+
object.tag == "button" ? object.options : object.link_options) do %>
|
4
3
|
<% if object.variant === "reaction" %>
|
5
4
|
<% if icon && object.valid_emoji(object.icon) %>
|
6
5
|
<%= pb_rails("flex", props:{ align: "center" }) do %>
|
@@ -1,9 +1,4 @@
|
|
1
|
-
<%=
|
2
|
-
id: object.id,
|
3
|
-
data: object.data,
|
4
|
-
class: object.classname,
|
5
|
-
**combined_html_options
|
6
|
-
) do %>
|
1
|
+
<%= pb_content_tag(:label) do %>
|
7
2
|
<%= content.presence || object.input %>
|
8
3
|
<% if object.indeterminate %>
|
9
4
|
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_indeterminate">
|
@@ -1,9 +1,5 @@
|
|
1
|
-
<%=
|
2
|
-
|
3
|
-
class: object.classname + object.error_class,
|
4
|
-
data: object.data,
|
5
|
-
id: object.id,
|
6
|
-
**combined_html_options) do %>
|
1
|
+
<%= pb_content_tag(:div,
|
2
|
+
class: object.classname + object.error_class) do %>
|
7
3
|
<div class="input_wrapper">
|
8
4
|
<% if content.present? %>
|
9
5
|
<%= content %>
|
@@ -68,18 +64,30 @@
|
|
68
64
|
</div>
|
69
65
|
|
70
66
|
<%= javascript_tag do %>
|
71
|
-
|
72
|
-
|
67
|
+
(function() {
|
68
|
+
const loadDatePicker = () => {
|
69
|
+
datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
|
73
70
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
71
|
+
if (<%= object.selection_type == "quickpick" %>) {
|
72
|
+
document.getElementById("<%= object.picker_id %>").addEventListener("change", ({ target }) => {
|
73
|
+
const startDate = document.getElementById("<%= object.start_date_id %>")
|
74
|
+
const endDate = document.getElementById("<%= object.end_date_id %>")
|
75
|
+
const splittedValue = target.value.split(" to ")
|
76
|
+
startDate.value = splittedValue[0]
|
77
|
+
endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
|
78
|
+
})
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
window.addEventListener("DOMContentLoaded", () => {
|
83
|
+
loadDatePicker()
|
84
|
+
})
|
85
|
+
|
86
|
+
if (<%= !object.custom_event_type.empty? %>) {
|
87
|
+
window.addEventListener("<%= object.custom_event_type %>", () => {
|
88
|
+
loadDatePicker()
|
81
89
|
})
|
82
90
|
}
|
83
|
-
})
|
91
|
+
})()
|
84
92
|
<% end %>
|
85
93
|
<% end %>
|
@@ -73,6 +73,8 @@ module Playbook
|
|
73
73
|
default: false
|
74
74
|
prop :year_range, type: Playbook::Props::Array,
|
75
75
|
default: [1900, 2100]
|
76
|
+
prop :custom_event_type, type: Playbook::Props::String,
|
77
|
+
default: ""
|
76
78
|
|
77
79
|
def classname
|
78
80
|
default_margin_bottom = margin_bottom.present? ? "" : " mb_sm"
|
@@ -2,4 +2,4 @@ The `defaultDate`/`default_date` prop has a null or empty string value by defaul
|
|
2
2
|
|
3
3
|
If you use a Date object without UTC time standardization the Date Picker kit may misinterpret that date as yesterdays date (consequence of timezone differentials and the Javascript Date Object constructor). See [this GitHub issue for more information](https://github.com/powerhome/playbook/issues/1167) and the anti-pattern examples below.
|
4
4
|
|
5
|
-
|
5
|
+
You can leverage the `defaultDate`/`default_date` prop with custom logic in your filter or controller files where the determination of the default value changes based on user interaction. The page can load with an initial default date picker value or placeholder text, then after filter submission save the submitted values as the "new default" (via state or params).
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= pb_rails("date_picker", props: { picker_id: "date-picker-turbo-frames", custom_event_type: "datePickerLoader" }) %>
|
2
|
+
<%= pb_rails("button", props: { id: "date-picker-loader", text: "Click Event Simulation" }) %>
|
3
|
+
|
4
|
+
<script>
|
5
|
+
document.getElementById("date-picker-loader").addEventListener("click", () => {
|
6
|
+
window.document.dispatchEvent(
|
7
|
+
new CustomEvent("datePickerLoader", {
|
8
|
+
bubbles: true,
|
9
|
+
})
|
10
|
+
)
|
11
|
+
console.log("Event 'datePickerLoader' dispatched - in a real implementation, this event would trigger the date picker's reinitialization through the custom_event_type prop connection")
|
12
|
+
})
|
13
|
+
</script>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
The `custom_event_type` prop allows you to specify a custom event that will trigger the date picker's initialization, in addition to the default initialization on `DOMContentLoaded`. This is particularly useful in dynamic contexts like Turbo Frame updates where you need to reinitialize the date picker after new content loads. For Turbo integration, use `custom_event_type: "turbo:before-render"` to ensure the date picker properly reinitializes after Turbo navigation events.
|
2
|
+
|
3
|
+
In this example, we demonstrate the setup pattern by connecting a button to dispatch a "datePickerLoader" event - while the date picker's event listener is properly configured through the `custom_event_type` prop, this demo only logs the event dispatch to the console to illustrate the connection structure.
|
@@ -6,14 +6,8 @@
|
|
6
6
|
|
7
7
|
] %>
|
8
8
|
|
9
|
-
<%= pb_rails("
|
10
|
-
|
11
|
-
<%= pb_rails("list", props:
|
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 %>
|
9
|
+
<%= pb_rails("list", props: { enable_drag: true, items: initial_items }) do %>
|
10
|
+
<% initial_items.each do |item| %>
|
11
|
+
<%= pb_rails("list/item", props:{drag_id: item[:id]}) do %><%= item[:name] %><% end %>
|
18
12
|
<% end %>
|
19
13
|
<% end %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
For a simplified version of the Draggable API for the List kit, you can do the following:
|
2
|
+
|
3
|
+
The List kit is optimized to work with the draggable kit. To enable drag, use the `enable_drag` prop on List kit with an array of the included items AND `drag_id` prop on ListItems. You will also need to include the `items` prop containing your array of listed items for the Draggable API.
|
4
|
+
|
5
|
+
An additional optional boolean prop (set to true by default) of `drag_handle` is also available on ListItem kit to show the drag handle icon.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<%= pb_rails("selectable_list",
|
2
|
+
props: {
|
3
|
+
enable_drag: true,
|
4
|
+
variant: "radio",
|
5
|
+
items: [
|
6
|
+
{ drag_id: "41",
|
7
|
+
text: "Task 1",
|
8
|
+
input_options: {
|
9
|
+
value: "1",
|
10
|
+
name: "radio-name",
|
11
|
+
}
|
12
|
+
},
|
13
|
+
{ drag_id: "42",
|
14
|
+
text: "Task 2",
|
15
|
+
checked: true,
|
16
|
+
input_options: {
|
17
|
+
value: "2",
|
18
|
+
name: "radio-name",
|
19
|
+
}
|
20
|
+
},
|
21
|
+
{ drag_id: "43",
|
22
|
+
text: "Task 3",
|
23
|
+
input_options: {
|
24
|
+
value: "3",
|
25
|
+
name: "radio-name",
|
26
|
+
}
|
27
|
+
},
|
28
|
+
{ drag_id: "44",
|
29
|
+
text: "Task 4",
|
30
|
+
input_options: {
|
31
|
+
value: "4",
|
32
|
+
name: "radio-name",
|
33
|
+
}
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}
|
37
|
+
)
|
38
|
+
%>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
For a simplified version of the Draggable API for the SelectableList kit, you can do the following:
|
2
|
+
|
3
|
+
The SelectableList kit is optimized to work with the draggable kit. To enable drag, use the `enable_drag` prop on SelectableList kit AND `drag_id` prop within the SelectableList kit prop. An additional optional boolean prop (set to true by default) of `drag_handle` is also available on SelectableList kit to show the drag handle icon.
|
@@ -1 +1 @@
|
|
1
|
-
For the `subtle` variant, it is recommended that you set the `Separators` prop to `false` to remove the separator lines between the options for a
|
1
|
+
For the `subtle` variant, it is recommended that you set the `Separators` prop to `false` to remove the separator lines between the options for a cleaner look.
|
@@ -1,19 +1,14 @@
|
|
1
|
-
<%=
|
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 do %>
|
7
2
|
<% if object.label.present? %>
|
8
3
|
<%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
|
9
4
|
<% end %>
|
10
5
|
<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" : ""%>
|
6
|
+
<input
|
7
|
+
data-default-value="<%= input_default_value %>"
|
8
|
+
id="dropdown-selected-option"
|
9
|
+
name="<%= object.name %>"
|
10
|
+
style="display: none"
|
11
|
+
<%= object.required ? "required" : ""%>
|
17
12
|
/>
|
18
13
|
<% if content.present? %>
|
19
14
|
<%= content.presence %>
|
@@ -1,20 +1,15 @@
|
|
1
|
-
<%=
|
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 do %>
|
7
2
|
<%= pb_rails("list", props: {ordered: false, borderless: false}) do %>
|
8
|
-
<% if content.present? %>
|
3
|
+
<% if content.present? %>
|
9
4
|
<%= content.presence %>
|
10
|
-
<% else %>
|
5
|
+
<% else %>
|
11
6
|
<%= pb_rails("list/item", props: {
|
12
|
-
display: "flex",
|
13
|
-
justify_content: "center",
|
14
|
-
padding:"xs",
|
15
|
-
}) do %>
|
7
|
+
display: "flex",
|
8
|
+
justify_content: "center",
|
9
|
+
padding:"xs",
|
10
|
+
}) do %>
|
16
11
|
<%= pb_rails("body", props: {text: "No option"}) %>
|
17
12
|
<% end %>
|
18
13
|
<% end %>
|
19
|
-
<% end %>
|
20
|
-
<% end %>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
@@ -1,15 +1,10 @@
|
|
1
|
-
<%=
|
2
|
-
aria: object.aria,
|
3
|
-
class: object.classname,
|
4
|
-
data: object.data,
|
5
|
-
id: object.option[:id],
|
6
|
-
**combined_html_options) do %>
|
1
|
+
<%= pb_content_tag(:div, id: object.option[:id]) do %>
|
7
2
|
<%= pb_rails("list/item", props: {
|
8
|
-
display: "flex",
|
9
|
-
justify_content: "center",
|
10
|
-
padding:"none",
|
3
|
+
display: "flex",
|
4
|
+
justify_content: "center",
|
5
|
+
padding:"none",
|
11
6
|
cursor: "pointer"
|
12
|
-
}) do %>
|
7
|
+
}) do %>
|
13
8
|
<div class="dropdown_option_wrapper">
|
14
9
|
<% if content.present? %>
|
15
10
|
<%= content.presence %>
|
@@ -18,4 +13,4 @@
|
|
18
13
|
<% end %>
|
19
14
|
</div>
|
20
15
|
<% end %>
|
21
|
-
<% end %>
|
16
|
+
<% end %>
|
@@ -1,21 +1,16 @@
|
|
1
|
-
<%=
|
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 do %>
|
7
2
|
<% if content.present? %>
|
8
3
|
<div style="display: inline-block" tabindex="0" data-dropdown-custom-trigger>
|
9
4
|
<%= content.presence %>
|
10
5
|
</div>
|
11
6
|
<% else %>
|
12
7
|
<%= pb_rails("flex", props: {
|
13
|
-
align: "center",
|
14
|
-
border_radius:"lg",
|
15
|
-
classname: object.trigger_wrapper_classes,
|
16
|
-
cursor: "pointer",
|
17
|
-
justify: "between",
|
18
|
-
padding_x:"sm",
|
8
|
+
align: "center",
|
9
|
+
border_radius:"lg",
|
10
|
+
classname: object.trigger_wrapper_classes,
|
11
|
+
cursor: "pointer",
|
12
|
+
justify: "between",
|
13
|
+
padding_x:"sm",
|
19
14
|
padding_y:"xs",
|
20
15
|
html_options: {tabindex:"0"}
|
21
16
|
}) do %>
|
@@ -23,7 +18,7 @@
|
|
23
18
|
<%= pb_rails("flex", props: {align: "center"}) do %>
|
24
19
|
<% if object.custom_display.present? %>
|
25
20
|
<%= pb_rails("flex", props: {align: "center"}) do %>
|
26
|
-
<div id="dropdown_trigger_custom_display" style="display: none;">
|
21
|
+
<div id="dropdown_trigger_custom_display" style="display: none;">
|
27
22
|
<%= object.custom_display %>
|
28
23
|
</div>
|
29
24
|
<%= pb_rails("body", props: {text: object.default_display_placeholder, id: "dropdown_trigger_display"}) %>
|
@@ -40,4 +35,3 @@
|
|
40
35
|
<% end %>
|
41
36
|
<% end %>
|
42
37
|
<% end %>
|
43
|
-
|
@@ -1,10 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
<% if object.draggable? %>
|
2
|
+
<%= pb_rails("draggable/draggable_item", props:{drag_id: object.drag_id}) do %>
|
3
|
+
<%= content_tag(:li,
|
4
|
+
aria: object.aria,
|
5
|
+
class: object.classname,
|
6
|
+
data: object.data,
|
7
|
+
id: object.id,
|
8
|
+
tabindex: object.tabindex,
|
9
|
+
**combined_html_options
|
10
|
+
) do %>
|
11
|
+
<% if object.drag_handle %>
|
12
|
+
<span style="vertical-align: middle;">
|
13
|
+
<%= pb_rails("body") do %>
|
14
|
+
<svg width="auto" height="auto" viewBox="0 0 31 25" fill="none" xmlns="http://www.w3.org/2000/svg" color="currentColor" class="pb_custom_icon svg-inline--fa vertical_align_middle svg_fw"><path d="M12.904 6.355a1.48 1.48 0 01-1.5-1.5c0-.796.656-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5 0 .844-.703 1.5-1.5 1.5zm0 7.5a1.48 1.48 0 01-1.5-1.5c0-.796.656-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5 0 .844-.703 1.5-1.5 1.5zm1.5 6c0 .844-.703 1.5-1.5 1.5a1.48 1.48 0 01-1.5-1.5c0-.796.656-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5zm4.5-13.5a1.48 1.48 0 01-1.5-1.5c0-.796.657-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5 0 .844-.703 1.5-1.5 1.5zm1.5 6c0 .844-.703 1.5-1.5 1.5a1.48 1.48 0 01-1.5-1.5c0-.796.657-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5zm-1.5 9a1.48 1.48 0 01-1.5-1.5c0-.796.657-1.5 1.5-1.5.797 0 1.5.704 1.5 1.5 0 .844-.703 1.5-1.5 1.5z" fill="#242B42"></path></svg>
|
15
|
+
<% end %>
|
16
|
+
</span>
|
17
|
+
<% end %>
|
18
|
+
<%= content.presence %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<% else %>
|
22
|
+
<%= content_tag(:li,
|
23
|
+
aria: object.aria,
|
24
|
+
class: object.classname,
|
25
|
+
data: object.data,
|
26
|
+
id: object.id,
|
27
|
+
tabindex: object.tabindex,
|
28
|
+
**combined_html_options
|
29
|
+
) do %>
|
9
30
|
<%= content.presence %>
|
31
|
+
<% end %>
|
10
32
|
<% end %>
|
@@ -3,11 +3,18 @@
|
|
3
3
|
module Playbook
|
4
4
|
module PbList
|
5
5
|
class Item < Playbook::KitBase
|
6
|
+
prop :drag_handle, type: Playbook::Props::Boolean,
|
7
|
+
default: true
|
8
|
+
prop :drag_id, type: Playbook::Props::String
|
6
9
|
prop :tabindex
|
7
10
|
|
8
11
|
def classname
|
9
12
|
generate_classname("pb_item_kit")
|
10
13
|
end
|
14
|
+
|
15
|
+
def draggable?
|
16
|
+
drag_id.present?
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
@@ -1,13 +1,33 @@
|
|
1
|
-
|
2
|
-
<%=
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
<% if object.enable_drag %>
|
2
|
+
<%= pb_rails("draggable", props: {initial_items: object.items}) do %>
|
3
|
+
<%= pb_rails("draggable/draggable_container") do %>
|
4
|
+
<%= content_tag(:div, class: object.list_classname) do %>
|
5
|
+
<%= content_tag(:"#{object.ordered_class}",
|
6
|
+
aria: object.aria,
|
7
|
+
class: object.classname,
|
8
|
+
data: object.data,
|
9
|
+
id: object.id,
|
10
|
+
role: object.role,
|
11
|
+
tabindex: object.tabindex,
|
12
|
+
**combined_html_options
|
13
|
+
) do %>
|
14
|
+
<%= content.presence %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
<% else %>
|
20
|
+
<%= content_tag(:div, class: object.list_classname) do %>
|
21
|
+
<%= content_tag(:"#{object.ordered_class}",
|
22
|
+
aria: object.aria,
|
23
|
+
class: object.classname,
|
24
|
+
data: object.data,
|
25
|
+
id: object.id,
|
26
|
+
role: object.role,
|
27
|
+
tabindex: object.tabindex,
|
28
|
+
**combined_html_options
|
29
|
+
) do %>
|
30
|
+
<%= content.presence %>
|
31
|
+
<% end %>
|
12
32
|
<% end %>
|
13
33
|
<% end %>
|
@@ -7,6 +7,10 @@ module Playbook
|
|
7
7
|
default: false
|
8
8
|
prop :dark, type: Playbook::Props::Boolean,
|
9
9
|
default: false
|
10
|
+
prop :enable_drag, type: Playbook::Props::Boolean,
|
11
|
+
default: false
|
12
|
+
prop :items, type: Playbook::Props::Array,
|
13
|
+
default: []
|
10
14
|
prop :layout, type: Playbook::Props::Enum,
|
11
15
|
values: ["left", "right", ""],
|
12
16
|
default: ""
|
@@ -12,6 +12,7 @@ type LoadingInlineProps = {
|
|
12
12
|
aria?: { [key: string]: string },
|
13
13
|
className?: string,
|
14
14
|
data?: { [key: string]: string },
|
15
|
+
dark?: boolean,
|
15
16
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
16
17
|
id?: string,
|
17
18
|
text?: string,
|
@@ -23,6 +24,7 @@ const LoadingInline = (props: LoadingInlineProps) => {
|
|
23
24
|
aria = {},
|
24
25
|
className,
|
25
26
|
data = {},
|
27
|
+
dark = false,
|
26
28
|
htmlOptions = {},
|
27
29
|
id,
|
28
30
|
text = ' Loading',
|
@@ -45,7 +47,10 @@ const LoadingInline = (props: LoadingInlineProps) => {
|
|
45
47
|
className={classes}
|
46
48
|
id={id}
|
47
49
|
>
|
48
|
-
<Body
|
50
|
+
<Body
|
51
|
+
color="light"
|
52
|
+
dark={dark}
|
53
|
+
>
|
49
54
|
<Icon
|
50
55
|
aria={{ label: 'loading icon' }}
|
51
56
|
fixedWidth
|
@@ -35,6 +35,7 @@ type PhoneNumberInputProps = {
|
|
35
35
|
preferredCountries?: string[],
|
36
36
|
required?: boolean,
|
37
37
|
value?: string,
|
38
|
+
formatAsYouType?: boolean,
|
38
39
|
}
|
39
40
|
|
40
41
|
enum ValidationError {
|
@@ -87,6 +88,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
87
88
|
required = false,
|
88
89
|
preferredCountries = [],
|
89
90
|
value = "",
|
91
|
+
formatAsYouType = false,
|
90
92
|
} = props
|
91
93
|
|
92
94
|
const ariaProps = buildAriaProps(aria)
|
@@ -99,8 +101,8 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
99
101
|
)
|
100
102
|
|
101
103
|
const inputRef = useRef<HTMLInputElement>()
|
104
|
+
const itiRef = useRef<any>(null);
|
102
105
|
const [inputValue, setInputValue] = useState(value)
|
103
|
-
const [itiInit, setItiInit] = useState<any>()
|
104
106
|
const [error, setError] = useState(props.error)
|
105
107
|
const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
|
106
108
|
const [selectedData, setSelectedData] = useState()
|
@@ -130,8 +132,12 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
130
132
|
}
|
131
133
|
})
|
132
134
|
|
135
|
+
const unformatNumber = (formattedNumber: any) => {
|
136
|
+
return formattedNumber.replace(/\D/g, "")
|
137
|
+
}
|
138
|
+
|
133
139
|
const showFormattedError = (reason = '') => {
|
134
|
-
const countryName =
|
140
|
+
const countryName = itiRef.current.getSelectedCountryData().name
|
135
141
|
const reasonText = reason.length > 0 ? ` (${reason})` : ''
|
136
142
|
setError(`Invalid ${countryName} phone number${reasonText}`)
|
137
143
|
return true
|
@@ -189,12 +195,12 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
189
195
|
}
|
190
196
|
|
191
197
|
const validateErrors = () => {
|
192
|
-
if (
|
193
|
-
if (validateOnlyNumbers(
|
194
|
-
if (validateTooLongNumber(
|
195
|
-
if (validateTooShortNumber(
|
196
|
-
if (validateUnhandledError(
|
197
|
-
if (validateMissingAreaCode(
|
198
|
+
if (itiRef.current) isValid(itiRef.current.isValidNumber())
|
199
|
+
if (validateOnlyNumbers(itiRef.current)) return
|
200
|
+
if (validateTooLongNumber(itiRef.current)) return
|
201
|
+
if (validateTooShortNumber(itiRef.current)) return
|
202
|
+
if (validateUnhandledError(itiRef.current)) return
|
203
|
+
if (validateMissingAreaCode(itiRef.current)) return
|
198
204
|
}
|
199
205
|
|
200
206
|
const getCurrentSelectedData = (itiInit: any, inputValue: string) => {
|
@@ -203,10 +209,16 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
203
209
|
|
204
210
|
const handleOnChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
205
211
|
setInputValue(evt.target.value)
|
206
|
-
|
212
|
+
let phoneNumberData
|
213
|
+
if (formatAsYouType) {
|
214
|
+
const formattedPhoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
|
215
|
+
phoneNumberData = {...formattedPhoneNumberData, number: unformatNumber(formattedPhoneNumberData.number)}
|
216
|
+
} else {
|
217
|
+
phoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
|
218
|
+
}
|
207
219
|
setSelectedData(phoneNumberData)
|
208
220
|
onChange(phoneNumberData)
|
209
|
-
isValid(
|
221
|
+
isValid(itiRef.current.isValidNumber())
|
210
222
|
}
|
211
223
|
|
212
224
|
// Separating Concerns as React Docs Recommend
|
@@ -230,9 +242,11 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
230
242
|
onlyCountries,
|
231
243
|
countrySearch: false,
|
232
244
|
fixDropdownWidth: false,
|
233
|
-
formatAsYouType:
|
245
|
+
formatAsYouType: formatAsYouType,
|
234
246
|
})
|
235
247
|
|
248
|
+
itiRef.current = telInputInit;
|
249
|
+
|
236
250
|
inputRef.current.addEventListener("countrychange", (evt: Event) => {
|
237
251
|
const phoneNumberData = getCurrentSelectedData(telInputInit, (evt.target as HTMLInputElement).value)
|
238
252
|
setSelectedData(phoneNumberData)
|
@@ -243,7 +257,11 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.MutableRefOb
|
|
243
257
|
inputRef.current.addEventListener("open:countrydropdown", () => setDropDownIsOpen(true))
|
244
258
|
inputRef.current.addEventListener("close:countrydropdown", () => setDropDownIsOpen(false))
|
245
259
|
|
246
|
-
|
260
|
+
if (formatAsYouType) {
|
261
|
+
inputRef.current?.addEventListener("input", (evt) => {
|
262
|
+
handleOnChange(evt as unknown as React.ChangeEvent<HTMLInputElement>);
|
263
|
+
});
|
264
|
+
}
|
247
265
|
}, [])
|
248
266
|
|
249
267
|
let textInputProps: {[key: string]: any} = {
|