playbook_ui 16.3.0.pre.alpha.play284914770 → 16.3.0.pre.alpha.play285814889
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_button/_button_mixins.scss +6 -1
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +1 -1
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.jsx +6 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.html.erb +18 -9
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.jsx +24 -5
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height.jsx +6 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height_placement.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height_placement.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +3 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_closing_options_rails.html.erb +16 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_closing_options_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +1 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +5 -4
- data/app/pb_kits/playbook/pb_dropdown/index.js +27 -170
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +19 -14
- data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +1 -1
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +24 -15
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +35 -134
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_editor.tsx +51 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/_trix_editor.tsx +206 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.jsx +56 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +13 -21
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +0 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/inlineFocus.ts +5 -4
- data/app/pb_kits/playbook/pb_textarea/_textarea.scss +4 -1
- data/dist/chunks/{_pb_line_graph-BGY7jEks.js → _pb_line_graph-BI5wY8Wj.js} +1 -1
- data/dist/chunks/_typeahead-8CvXJGlb.js +1 -0
- data/dist/chunks/{globalProps-CK2YuA9O.js → globalProps-Bn1WUHLp.js} +1 -1
- data/dist/chunks/{lib-DspaUdlc.js → lib-qwWYiGtH.js} +1 -1
- data/dist/chunks/vendor.js +4 -4
- data/dist/menu.yml +1 -0
- 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 +11 -32
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_event_type.html.erb +0 -224
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_event_type.md +0 -7
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.html.erb +0 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.jsx +0 -15
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_focus.html.erb +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_focus.jsx +0 -17
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_inline.html.erb +0 -6
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_inline.jsx +0 -16
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_label.jsx +0 -28
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_label.md +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_preview.html.erb +0 -35
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_preview.jsx +0 -45
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.html.erb +0 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.jsx +0 -22
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.md +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_simple.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_simple.jsx +0 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_sticky.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_sticky.jsx +0 -15
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_templates.html.erb +0 -115
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_templates.jsx +0 -42
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_toolbar_bottom.html.erb +0 -4
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_toolbar_bottom.jsx +0 -14
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +0 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +0 -63
- data/dist/chunks/_typeahead-tG1K5JPP.js +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02d49483b3956da77f73aacb7718f16ebd2b6b8782c44e80815f22be2ffcde4e
|
|
4
|
+
data.tar.gz: 693802d5534038fe8a607937538cd3b9370627d0613a09353f9c14b4ed6bb721
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9878ce5bb1f4e16cd4dad4389e981eacc4ce7aab095d9c39fa0f3b9411768b0732ff6e96b12d35eaf67d0f34f0fdf85e71b5b063d406c3e44bd9f1d6d2389625
|
|
7
|
+
data.tar.gz: 4bc358a3ec5ede3933e21e49627d59353a776ed6ff602da16d0c2c509df8297486c56c7b10470504f37040d61e04ca8635e597181cab5eb9c9386635ebe3781b
|
|
@@ -57,7 +57,7 @@ $pb_button_border_width: 0px;
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
.loading-icon {
|
|
60
|
-
position:
|
|
60
|
+
position: static;
|
|
61
61
|
display: none;
|
|
62
62
|
}
|
|
63
63
|
.pb_button_content {
|
|
@@ -158,10 +158,15 @@ $pb_button_border_width: 0px;
|
|
|
158
158
|
// Loading =====================
|
|
159
159
|
@mixin pb_button_loading($loading: false) {
|
|
160
160
|
@if $loading == true {
|
|
161
|
+
display: inline-grid;
|
|
162
|
+
place-items: center;
|
|
163
|
+
|
|
161
164
|
.loading-icon {
|
|
165
|
+
grid-area: 1 / 1;
|
|
162
166
|
display: block;
|
|
163
167
|
}
|
|
164
168
|
.pb_button_content {
|
|
169
|
+
grid-area: 1 / 1;
|
|
165
170
|
visibility: hidden;
|
|
166
171
|
}
|
|
167
172
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<% end %>
|
|
29
29
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
30
30
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
31
|
-
<%= pb_rails("
|
|
31
|
+
<%= pb_rails("textarea", props: {id: "default"}) %>
|
|
32
32
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
33
33
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
34
34
|
<%= pb_rails("dropdown", props: {options: options, autocomplete: true}) %>
|
|
@@ -4,7 +4,7 @@ import Body from '../../pb_body/_body'
|
|
|
4
4
|
import Button from '../../pb_button/_button'
|
|
5
5
|
import Caption from '../../pb_caption/_caption'
|
|
6
6
|
import Dialog from '../../pb_dialog/_dialog'
|
|
7
|
-
import
|
|
7
|
+
import Textarea from '../../pb_textarea/_textarea'
|
|
8
8
|
import Typeahead from '../../pb_typeahead/_typeahead'
|
|
9
9
|
|
|
10
10
|
const DialogCompound = () => {
|
|
@@ -25,8 +25,11 @@ const DialogCompound = () => {
|
|
|
25
25
|
<Body>{'What do you need us to take care of?'}</Body>
|
|
26
26
|
</Dialog.Header>
|
|
27
27
|
<Dialog.Body>
|
|
28
|
-
<
|
|
29
|
-
|
|
28
|
+
<Textarea
|
|
29
|
+
id="default-example-1"
|
|
30
|
+
label="Description"
|
|
31
|
+
rows={4}
|
|
32
|
+
/>
|
|
30
33
|
<br />
|
|
31
34
|
<Caption>
|
|
32
35
|
{
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
<%= pb_rails("button", props: { text: "Open Dialog", data: {"open-dialog": "dialog-1"} }) %>
|
|
2
2
|
|
|
3
|
-
<%= pb_rails("dialog", props: {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}) %>
|
|
3
|
+
<%= pb_rails("dialog", props: {
|
|
4
|
+
id:"dialog-1",
|
|
5
|
+
size: "md",
|
|
6
|
+
title: "Header Title is the Title Prop"
|
|
7
|
+
}) do %>
|
|
8
|
+
<%= pb_rails("dialog/dialog_body") do %>
|
|
9
|
+
<%= pb_rails("button", props: { aria: { label: "Loading" }, loading: true, margin_right: "lg", text: "Button Primary" }) %>
|
|
10
|
+
<div style="height: 800px; background-color: lightgray;"></div>
|
|
11
|
+
<%= pb_rails("button", props: { loading: true, text: "Loading..." }) %>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<%= pb_rails("dialog/dialog_footer") do %>
|
|
15
|
+
<%= pb_rails("flex", props: { spacing: "between", padding_x: "md", padding_bottom: "md", padding: "sm" }) do %>
|
|
16
|
+
<%= pb_rails("button", props: { loading: true, text: "Send My Issue" }) %>
|
|
17
|
+
<%= pb_rails("button", props: { text: "Back", variant: "link", data: {"close-dialog": "dialog-1"} }) %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
@@ -12,16 +12,35 @@ const DialogDefault = () => {
|
|
|
12
12
|
<>
|
|
13
13
|
<Button onClick={open}>{'Open Dialog'}</Button>
|
|
14
14
|
<Dialog
|
|
15
|
-
cancelButton="Cancel Button"
|
|
16
|
-
confirmButton="Okay"
|
|
17
15
|
onCancel={close}
|
|
18
16
|
onClose={close}
|
|
19
17
|
onConfirm={close}
|
|
20
18
|
opened={isOpen}
|
|
21
|
-
size="
|
|
22
|
-
text="Hello Body Text, Nice to meet ya."
|
|
19
|
+
size="md"
|
|
23
20
|
title="Header Title is the Title Prop"
|
|
24
|
-
|
|
21
|
+
>
|
|
22
|
+
<Dialog.Body>
|
|
23
|
+
<Button
|
|
24
|
+
aria={{ label: 'Loading' }}
|
|
25
|
+
loading
|
|
26
|
+
text="Button Primary"
|
|
27
|
+
/>
|
|
28
|
+
<div style={{height: '800px', backgroundColor: 'lightgray'}} />
|
|
29
|
+
<Button
|
|
30
|
+
loading
|
|
31
|
+
text="Loading..."
|
|
32
|
+
/>
|
|
33
|
+
</Dialog.Body>
|
|
34
|
+
<Dialog.Footer>
|
|
35
|
+
<Button
|
|
36
|
+
loading
|
|
37
|
+
text="Send My Issue"
|
|
38
|
+
/>
|
|
39
|
+
<Button variant="link">
|
|
40
|
+
{"Back"}
|
|
41
|
+
</Button>
|
|
42
|
+
</Dialog.Footer>
|
|
43
|
+
</Dialog>
|
|
25
44
|
</>
|
|
26
45
|
)
|
|
27
46
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<% end %>
|
|
13
13
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
14
14
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
15
|
-
<%= pb_rails("
|
|
15
|
+
<%= pb_rails("textarea", props: {id: "default-7"}) %>
|
|
16
16
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
17
17
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<% end %>
|
|
32
32
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
33
33
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
34
|
-
<%= pb_rails("
|
|
34
|
+
<%= pb_rails("textarea", props: {id: "default-8"}) %>
|
|
35
35
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
36
36
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
37
37
|
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<% end %>
|
|
50
50
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
51
51
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
52
|
-
<%= pb_rails("
|
|
52
|
+
<%= pb_rails("textarea", props: {id: "default-9"}) %>
|
|
53
53
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
54
54
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
55
55
|
|
|
@@ -5,7 +5,7 @@ import Button from '../../pb_button/_button'
|
|
|
5
5
|
import Dialog from '../../pb_dialog/_dialog'
|
|
6
6
|
import Flex from '../../pb_flex/_flex'
|
|
7
7
|
import Caption from '../../pb_caption/_caption'
|
|
8
|
-
import
|
|
8
|
+
import Textarea from '../../pb_textarea/_textarea'
|
|
9
9
|
import Typeahead from '../../pb_typeahead/_typeahead'
|
|
10
10
|
|
|
11
11
|
const useDialog = (visible = false) => {
|
|
@@ -77,8 +77,11 @@ const DialogFullHeight = () => {
|
|
|
77
77
|
<Body>{title}</Body>
|
|
78
78
|
</Dialog.Header>
|
|
79
79
|
<Dialog.Body>
|
|
80
|
-
<
|
|
81
|
-
|
|
80
|
+
<Textarea
|
|
81
|
+
id="default-example-1"
|
|
82
|
+
label="Description"
|
|
83
|
+
rows={4}
|
|
84
|
+
/>
|
|
82
85
|
<br />
|
|
83
86
|
<Caption>
|
|
84
87
|
{
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<% end %>
|
|
14
14
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
15
15
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
16
|
-
<%= pb_rails("
|
|
16
|
+
<%= pb_rails("textarea", props: {id: "default-2"}) %>
|
|
17
17
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
18
18
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
19
19
|
<% end %>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<% end %>
|
|
33
33
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
34
34
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
35
|
-
<%= pb_rails("
|
|
35
|
+
<%= pb_rails("textarea", props: {id: "default-3"}) %>
|
|
36
36
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
37
37
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
38
38
|
<% end %>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<% end %>
|
|
51
51
|
<%= pb_rails("dialog/dialog_body") do %>
|
|
52
52
|
<%= pb_rails("caption", props: { text: "Description", margin_bottom: "xs" }) %>
|
|
53
|
-
<%= pb_rails("
|
|
53
|
+
<%= pb_rails("textarea", props: {id: "default-4"}) %>
|
|
54
54
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
55
55
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
56
56
|
<% end %>
|
|
@@ -5,7 +5,7 @@ import Button from '../../pb_button/_button'
|
|
|
5
5
|
import Dialog from '../../pb_dialog/_dialog'
|
|
6
6
|
import Flex from '../../pb_flex/_flex'
|
|
7
7
|
import Caption from '../../pb_caption/_caption'
|
|
8
|
-
import
|
|
8
|
+
import Textarea from "../../pb_textarea/_textarea";
|
|
9
9
|
import Typeahead from '../../pb_typeahead/_typeahead'
|
|
10
10
|
|
|
11
11
|
const useDialog = (visible = false) => {
|
|
@@ -76,8 +76,11 @@ const DialogFullHeightPlacement = () => {
|
|
|
76
76
|
<Body>{title}</Body>
|
|
77
77
|
</Dialog.Header>
|
|
78
78
|
<Dialog.Body>
|
|
79
|
-
<
|
|
80
|
-
|
|
79
|
+
<Textarea
|
|
80
|
+
id={`default-example-2-${index}`}
|
|
81
|
+
label="Description"
|
|
82
|
+
rows={4}
|
|
83
|
+
/>
|
|
81
84
|
<br />
|
|
82
85
|
<Caption>
|
|
83
86
|
{
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{ label: "United States", value: "unitedStates", id: "us" },
|
|
4
|
+
{ label: "Canada", value: "canada", id: "ca" },
|
|
5
|
+
{ label: "Pakistan", value: "pakistan", id: "pk" },
|
|
6
|
+
]
|
|
7
|
+
%>
|
|
8
|
+
|
|
9
|
+
<%= pb_rails("caption", props: { margin_bottom: "xs", text: "Any" }) %>
|
|
10
|
+
<%= pb_rails("dropdown", props: { options: options, close_on_click: "any", margin_bottom: "md" }) %>
|
|
11
|
+
|
|
12
|
+
<%= pb_rails("caption", props: { margin_bottom: "xs", text: "Outside" }) %>
|
|
13
|
+
<%= pb_rails("dropdown", props: { options: options, close_on_click: "outside", margin_bottom: "md" }) %>
|
|
14
|
+
|
|
15
|
+
<%= pb_rails("caption", props: { margin_bottom: "xs", text: "Inside" }) %>
|
|
16
|
+
<%= pb_rails("dropdown", props: { options: options, close_on_click: "inside" }) %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The `close_on_click` prop allows you to control when the Dropdown closes in response to click interactions. The value `any` reflects the default behavior, where the dropdown will close after any click. Set it to `outside` to ensure interactive elements as dropdown options are able to be interacted with or modified. Set it to `inside` for a dropdown that only closes when the input or dropdown menu is clicked.
|
|
@@ -25,6 +25,7 @@ examples:
|
|
|
25
25
|
- dropdown_separators_hidden: Separators Hidden
|
|
26
26
|
- dropdown_with_clearable: Clearable
|
|
27
27
|
- dropdown_with_constrain_height_rails: Constrain Height
|
|
28
|
+
- dropdown_closing_options_rails: Closing Options
|
|
28
29
|
- dropdown_quickpick_rails: Quick Pick Variant
|
|
29
30
|
- dropdown_quickpick_range_end_rails: Quick Pick Variant (Range Ends Today)
|
|
30
31
|
- dropdown_quickpick_default_dates: Quick Pick Variant (Default Dates)
|
|
@@ -32,7 +33,6 @@ examples:
|
|
|
32
33
|
- dropdown_quickpick_with_date_pickers_rails: Quick Pick with Date Pickers
|
|
33
34
|
- dropdown_quickpick_with_date_pickers_default_rails: Quick Pick with Date Pickers (Default Value)
|
|
34
35
|
- dropdown_required_indicator: Required Indicator
|
|
35
|
-
- dropdown_custom_event_type: Custom Event Type
|
|
36
36
|
|
|
37
37
|
react:
|
|
38
38
|
- dropdown_default: Default
|
|
@@ -39,6 +39,9 @@ module Playbook
|
|
|
39
39
|
default: ""
|
|
40
40
|
prop :clearable, type: Playbook::Props::Boolean,
|
|
41
41
|
default: true
|
|
42
|
+
prop :close_on_click, type: Playbook::Props::Enum,
|
|
43
|
+
values: %w[outside inside any],
|
|
44
|
+
default: "any"
|
|
42
45
|
prop :start_date_id, type: Playbook::Props::String,
|
|
43
46
|
default: "start_date_id"
|
|
44
47
|
prop :start_date_name, type: Playbook::Props::String,
|
|
@@ -52,8 +55,6 @@ module Playbook
|
|
|
52
55
|
default: false
|
|
53
56
|
prop :required_indicator, type: Playbook::Props::Boolean,
|
|
54
57
|
default: false
|
|
55
|
-
prop :custom_event_type, type: Playbook::Props::String,
|
|
56
|
-
default: ""
|
|
57
58
|
|
|
58
59
|
def data
|
|
59
60
|
Hash(prop(:data)).merge(
|
|
@@ -61,12 +62,12 @@ module Playbook
|
|
|
61
62
|
pb_dropdown_multi_select: multi_select,
|
|
62
63
|
pb_dropdown_variant: variant,
|
|
63
64
|
pb_dropdown_clearable: clearable,
|
|
65
|
+
pb_dropdown_close_on_click: close_on_click,
|
|
64
66
|
form_pill_props: form_pill_props.to_json,
|
|
65
67
|
start_date_id: variant == "quickpick" ? start_date_id : nil,
|
|
66
68
|
end_date_id: variant == "quickpick" ? end_date_id : nil,
|
|
67
69
|
controls_start_id: variant == "quickpick" && controls_start_id.present? ? controls_start_id : nil,
|
|
68
|
-
controls_end_id: variant == "quickpick" && controls_end_id.present? ? controls_end_id : nil
|
|
69
|
-
custom_event_type: custom_event_type.presence
|
|
70
|
+
controls_end_id: variant == "quickpick" && controls_end_id.present? ? controls_end_id : nil
|
|
70
71
|
).compact
|
|
71
72
|
end
|
|
72
73
|
|
|
@@ -68,6 +68,7 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
68
68
|
|
|
69
69
|
this.keyboardHandler = new PbDropdownKeyboard(this);
|
|
70
70
|
this.isMultiSelect = this.element.dataset.pbDropdownMultiSelect === "true";
|
|
71
|
+
this.closeOnClick = this.element.dataset.pbDropdownCloseOnClick || "any";
|
|
71
72
|
this.formPillProps = this.element.dataset.formPillProps
|
|
72
73
|
? JSON.parse(this.element.dataset.formPillProps)
|
|
73
74
|
: {};
|
|
@@ -94,25 +95,6 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
94
95
|
this.clearBtn.addEventListener("click", this.clearBtnHandler);
|
|
95
96
|
}
|
|
96
97
|
this.updateClearButton();
|
|
97
|
-
|
|
98
|
-
// Listen for clear and select events from external source
|
|
99
|
-
this.handleClearEventBound = this.handleClearEvent.bind(this);
|
|
100
|
-
document.addEventListener("pb:dropdown:clear", this.handleClearEventBound);
|
|
101
|
-
this.handleSelectEventBound = this.handleSelectEvent.bind(this);
|
|
102
|
-
document.addEventListener("pb:dropdown:select", this.handleSelectEventBound);
|
|
103
|
-
|
|
104
|
-
// Listen for custom_event_type to clear on custom events
|
|
105
|
-
const customEventTypeString = this.element.dataset.customEventType;
|
|
106
|
-
if (customEventTypeString) {
|
|
107
|
-
this.customClearEventTypes = customEventTypeString
|
|
108
|
-
.split(",")
|
|
109
|
-
.map((e) => e.trim())
|
|
110
|
-
.filter(Boolean);
|
|
111
|
-
this.handleCustomClearBound = this.handleCustomClearEvent.bind(this);
|
|
112
|
-
this.customClearEventTypes.forEach((eventType) => {
|
|
113
|
-
document.addEventListener(eventType, this.handleCustomClearBound);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
98
|
}
|
|
117
99
|
|
|
118
100
|
disconnect() {
|
|
@@ -164,19 +146,6 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
164
146
|
if (this.clearBtn && this.clearBtnHandler) {
|
|
165
147
|
this.clearBtn.removeEventListener('click', this.clearBtnHandler)
|
|
166
148
|
}
|
|
167
|
-
|
|
168
|
-
// Clean up external clear/select listeners
|
|
169
|
-
if (this.handleClearEventBound) {
|
|
170
|
-
document.removeEventListener("pb:dropdown:clear", this.handleClearEventBound)
|
|
171
|
-
}
|
|
172
|
-
if (this.handleSelectEventBound) {
|
|
173
|
-
document.removeEventListener("pb:dropdown:select", this.handleSelectEventBound)
|
|
174
|
-
}
|
|
175
|
-
if (this.customClearEventTypes && this.handleCustomClearBound) {
|
|
176
|
-
this.customClearEventTypes.forEach((eventType) => {
|
|
177
|
-
document.removeEventListener(eventType, this.handleCustomClearBound)
|
|
178
|
-
})
|
|
179
|
-
}
|
|
180
149
|
}
|
|
181
150
|
|
|
182
151
|
updateClearButton() {
|
|
@@ -204,6 +173,12 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
204
173
|
trigger.focus();
|
|
205
174
|
}
|
|
206
175
|
}
|
|
176
|
+
if (
|
|
177
|
+
this.closeOnClick === "outside" &&
|
|
178
|
+
this.target?.contains(e.target)
|
|
179
|
+
) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
207
182
|
this.toggleElement(this.target);
|
|
208
183
|
}
|
|
209
184
|
customTrigger.addEventListener("click", this.customTriggerClickHandler);
|
|
@@ -367,151 +342,29 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
367
342
|
|
|
368
343
|
handleDocumentClick(event) {
|
|
369
344
|
if (event.target.closest(SEARCH_BAR_SELECTOR)) return;
|
|
370
|
-
|
|
345
|
+
const shouldCloseOnOutsideClick =
|
|
346
|
+
this.closeOnClick === "outside" || this.closeOnClick === "any";
|
|
347
|
+
if (
|
|
348
|
+
shouldCloseOnOutsideClick &&
|
|
349
|
+
this.isClickOutside(event) &&
|
|
350
|
+
this.target.classList.contains("open")
|
|
351
|
+
) {
|
|
371
352
|
this.hideElement(this.target);
|
|
372
353
|
this.updateArrowDisplay(false);
|
|
373
354
|
}
|
|
374
355
|
}
|
|
375
356
|
|
|
376
|
-
// ----- External events handling section -----
|
|
377
|
-
// Handles pb:dropdown:clear - clear this dropdown when event.detail.dropdownId matches.
|
|
378
|
-
handleClearEvent(event) {
|
|
379
|
-
const targetId = event.detail?.dropdownId;
|
|
380
|
-
if (targetId && this.element.id === targetId) {
|
|
381
|
-
this.clearSelection();
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Handles custom_event_type events (e.g. turbo:submit-end) - clear when detail.dropdownId matches or is omitted.
|
|
386
|
-
handleCustomClearEvent(event) {
|
|
387
|
-
const targetId = event.detail?.dropdownId;
|
|
388
|
-
if (targetId == null || this.element.id === targetId) {
|
|
389
|
-
this.clearSelection();
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Handles pb:dropdown:select - set dropdown selection by option id(s).
|
|
394
|
-
// Single: detail: { dropdownId, optionId }. Multi: detail: { dropdownId, optionIds: ['id1', 'id2'] }.
|
|
395
|
-
handleSelectEvent(event) {
|
|
396
|
-
const targetId = event.detail?.dropdownId;
|
|
397
|
-
if (!targetId || this.element.id !== targetId) return;
|
|
398
|
-
|
|
399
|
-
const optionId = event.detail?.optionId;
|
|
400
|
-
const optionIds = event.detail?.optionIds;
|
|
401
|
-
if (optionId != null) {
|
|
402
|
-
this.setSelectionByOptionId(optionId);
|
|
403
|
-
} else if (Array.isArray(optionIds)) {
|
|
404
|
-
this.setSelectionByOptionIds(optionIds);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Set single-select dropdown to the option with the given id. No-op if id not found.
|
|
409
|
-
setSelectionByOptionId(optionId) {
|
|
410
|
-
if (this.isMultiSelect) return;
|
|
411
|
-
const hiddenInput = this.baseInput;
|
|
412
|
-
const optionEls = Array.from(this.element.querySelectorAll(OPTION_SELECTOR));
|
|
413
|
-
const selectedOption = optionEls.find((opt) => {
|
|
414
|
-
try {
|
|
415
|
-
return JSON.parse(opt.dataset.dropdownOptionLabel).id === optionId;
|
|
416
|
-
} catch {
|
|
417
|
-
return false;
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
if (!selectedOption) return;
|
|
421
|
-
|
|
422
|
-
optionEls.forEach((opt) => opt.classList.remove("pb_dropdown_option_selected"));
|
|
423
|
-
selectedOption.classList.add("pb_dropdown_option_selected");
|
|
424
|
-
hiddenInput.value = optionId;
|
|
425
|
-
const optionData = JSON.parse(selectedOption.dataset.dropdownOptionLabel);
|
|
426
|
-
const customDisplayElement = this.element.querySelector(
|
|
427
|
-
'[data-dropdown-trigger-custom-display]',
|
|
428
|
-
);
|
|
429
|
-
if (customDisplayElement) {
|
|
430
|
-
this.setTriggerElementText("");
|
|
431
|
-
customDisplayElement.style.display = "block";
|
|
432
|
-
customDisplayElement.style.paddingRight = "8px";
|
|
433
|
-
} else {
|
|
434
|
-
this.setTriggerElementText(optionData.label);
|
|
435
|
-
}
|
|
436
|
-
if (this.searchInput) {
|
|
437
|
-
this.searchInput.value = optionData.label;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
if (optionData.formatted_start_date && optionData.formatted_end_date) {
|
|
441
|
-
const startDateId = this.element.dataset.startDateId;
|
|
442
|
-
const endDateId = this.element.dataset.endDateId;
|
|
443
|
-
const controlsStartId = this.element.dataset.controlsStartId;
|
|
444
|
-
const controlsEndId = this.element.dataset.controlsEndId;
|
|
445
|
-
if (startDateId) {
|
|
446
|
-
const startDateInput = document.getElementById(startDateId);
|
|
447
|
-
if (startDateInput) startDateInput.value = optionData.formatted_start_date;
|
|
448
|
-
}
|
|
449
|
-
if (endDateId) {
|
|
450
|
-
const endDateInput = document.getElementById(endDateId);
|
|
451
|
-
if (endDateInput) endDateInput.value = optionData.formatted_end_date;
|
|
452
|
-
}
|
|
453
|
-
const syncDatePickers = () => {
|
|
454
|
-
if (controlsStartId) {
|
|
455
|
-
const startPicker = document.querySelector(`#${CSS.escape(controlsStartId)}`)?._flatpickr;
|
|
456
|
-
if (startPicker) startPicker.setDate(optionData.formatted_start_date, true, "m/d/Y");
|
|
457
|
-
}
|
|
458
|
-
if (controlsEndId) {
|
|
459
|
-
const endPicker = document.querySelector(`#${CSS.escape(controlsEndId)}`)?._flatpickr;
|
|
460
|
-
if (endPicker) endPicker.setDate(optionData.formatted_end_date, true, "m/d/Y");
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
syncDatePickers();
|
|
464
|
-
setTimeout(syncDatePickers, 100);
|
|
465
|
-
setTimeout(syncDatePickers, 300);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
this.updateClearButton();
|
|
469
|
-
this.emitSelectionChange();
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
// Set multi-select dropdown to the options with the given ids. Invalid ids are skipped.
|
|
473
|
-
setSelectionByOptionIds(optionIds) {
|
|
474
|
-
if (!this.isMultiSelect || !optionIds.length) return;
|
|
475
|
-
const optionEls = Array.from(this.element.querySelectorAll(OPTION_SELECTOR));
|
|
476
|
-
this.selectedOptions.clear();
|
|
477
|
-
optionEls.forEach((opt) => {
|
|
478
|
-
opt.classList.remove("pb_dropdown_option_selected");
|
|
479
|
-
opt.style.display = "";
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
optionIds.forEach((id) => {
|
|
483
|
-
const opt = optionEls.find((o) => {
|
|
484
|
-
try {
|
|
485
|
-
return JSON.parse(o.dataset.dropdownOptionLabel).id === id;
|
|
486
|
-
} catch {
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
if (opt) {
|
|
491
|
-
const raw = opt.dataset.dropdownOptionLabel;
|
|
492
|
-
this.selectedOptions.add(raw);
|
|
493
|
-
opt.style.display = "none";
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
this.updatePills();
|
|
498
|
-
this.updateClearButton();
|
|
499
|
-
this.adjustDropdownHeight();
|
|
500
|
-
this.syncHiddenInputs();
|
|
501
|
-
this.emitSelectionChange();
|
|
502
|
-
}
|
|
503
|
-
// ----- End External events handling section -----
|
|
504
|
-
|
|
505
357
|
isClickOutside(event) {
|
|
506
358
|
const label = event.target.closest(LABEL_SELECTOR);
|
|
507
359
|
if (label && this.element.contains(label)) return false;
|
|
508
360
|
const customTrigger = this.customTrigger;
|
|
509
361
|
if (customTrigger) {
|
|
510
|
-
|
|
362
|
+
const clickInTrigger = customTrigger.contains(event.target);
|
|
363
|
+
const clickInContainer = this.target?.contains(event.target);
|
|
364
|
+
return !clickInTrigger && !clickInContainer;
|
|
511
365
|
} else {
|
|
512
366
|
const triggerElement = this.trigger;
|
|
513
|
-
const containerElement =
|
|
514
|
-
this.element.parentNode.querySelector(CONTAINER_SELECTOR);
|
|
367
|
+
const containerElement = this.element.querySelector(CONTAINER_SELECTOR);
|
|
515
368
|
|
|
516
369
|
const isOutsideTrigger = triggerElement
|
|
517
370
|
? !triggerElement.contains(event.target)
|
|
@@ -650,11 +503,15 @@ export default class PbDropdown extends PbEnhancedElement {
|
|
|
650
503
|
}
|
|
651
504
|
|
|
652
505
|
const customTrigger = this.customTrigger;
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
506
|
+
const shouldCloseOnOptionSelect =
|
|
507
|
+
this.closeOnClick === "any" || this.closeOnClick === "inside";
|
|
508
|
+
if (
|
|
509
|
+
customTrigger &&
|
|
510
|
+
shouldCloseOnOptionSelect &&
|
|
511
|
+
this.target.classList.contains("open")
|
|
512
|
+
) {
|
|
513
|
+
this.hideElement(this.target);
|
|
514
|
+
this.updateArrowDisplay(false);
|
|
658
515
|
}
|
|
659
516
|
|
|
660
517
|
const options = this.element.querySelectorAll(OPTION_SELECTOR);
|
|
@@ -44,6 +44,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
|
44
44
|
|
|
45
45
|
const {
|
|
46
46
|
autocomplete,
|
|
47
|
+
blankSelection,
|
|
47
48
|
clearable,
|
|
48
49
|
error,
|
|
49
50
|
errorId,
|
|
@@ -57,6 +58,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
|
57
58
|
isInputFocused,
|
|
58
59
|
label: contextLabel,
|
|
59
60
|
multiSelect,
|
|
61
|
+
optionsWithBlankSelection,
|
|
60
62
|
selected,
|
|
61
63
|
selectId,
|
|
62
64
|
setIsInputFocused,
|
|
@@ -240,20 +242,22 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
|
240
242
|
onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
|
|
241
243
|
}}
|
|
242
244
|
key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
|
|
243
|
-
>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
245
|
+
>
|
|
246
|
+
{(!blankSelection || selected?.value !== optionsWithBlankSelection?.[0]?.value) && (
|
|
247
|
+
<>
|
|
248
|
+
{clearable !== false && selectedArray.length > 0 && (
|
|
249
|
+
<div onClick={(e)=>{e.stopPropagation();handleBackspace()}}>
|
|
250
|
+
<Icon
|
|
251
|
+
cursor="pointer"
|
|
252
|
+
dark={dark}
|
|
253
|
+
icon="times"
|
|
254
|
+
paddingRight="xs"
|
|
255
|
+
size="sm"
|
|
256
|
+
/>
|
|
257
|
+
</div>
|
|
258
|
+
)}
|
|
259
|
+
</>
|
|
260
|
+
)}
|
|
257
261
|
<Icon
|
|
258
262
|
cursor="pointer"
|
|
259
263
|
dark={dark}
|
|
@@ -261,6 +265,7 @@ const DropdownTrigger = (props: DropdownTriggerProps) => {
|
|
|
261
265
|
size="sm"
|
|
262
266
|
/>
|
|
263
267
|
</Body>
|
|
268
|
+
|
|
264
269
|
</FlexItem>
|
|
265
270
|
</Flex>
|
|
266
271
|
</>
|