playbook_ui 14.7.0.pre.alpha.revert3916revert3893PBNTR667railstypeaheadformintegration4523 → 14.7.0.pre.alpha.spacingquickchange4482
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_date_picker/date_picker_helper.ts +1 -1
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +0 -2
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +1 -17
- data/app/pb_kits/playbook/pb_drawer/_drawer.scss +175 -88
- data/app/pb_kits/playbook/pb_drawer/_drawer.tsx +47 -79
- data/app/pb_kits/playbook/pb_drawer/drawer.test.jsx +16 -20
- 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_timeline/_timeline.scss +1 -43
- data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +2 -6
- data/app/pb_kits/playbook/pb_timeline/docs/example.yml +3 -5
- data/app/pb_kits/playbook/pb_timeline/docs/index.js +0 -2
- data/app/pb_kits/playbook/pb_timeline/timeline.rb +1 -11
- data/app/pb_kits/playbook/pb_timeline/timeline.test.js +4 -4
- 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/app/pb_kits/playbook/utilities/_hover.scss +27 -40
- data/app/pb_kits/playbook/utilities/globalProps.ts +3 -5
- data/dist/chunks/_typeahead-DhLic2Fe.js +22 -0
- data/dist/chunks/_weekday_stacked-Mx8TYP5I.js +45 -0
- data/dist/chunks/{lib-GRGYd9YR.js → lib-D-mTv-kp.js} +1 -1
- data/dist/chunks/{pb_form_validation-CS6rgdtE.js → pb_form_validation-BkWGwJsl.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/forms/builder/typeahead_field.rb +0 -13
- data/lib/playbook/hover.rb +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +6 -13
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_default_date.html.erb +0 -42
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_default_date.jsx +0 -44
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_default_date.md +0 -1
- data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_gap.html.erb +0 -94
- data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_gap.jsx +0 -180
- data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_gap.md +0 -1
- data/app/pb_kits/playbook/utilities/test/globalProps/hover.test.js +0 -79
- data/dist/chunks/_typeahead-CA5rhmXa.js +0 -22
- data/dist/chunks/_weekday_stacked-9SqFhGPG.js +0 -45
@@ -1,7 +1,6 @@
|
|
1
1
|
import React, { useState } from 'react';
|
2
|
-
import { render, fireEvent, screen } from '../utilities/test-utils';
|
2
|
+
import { render, cleanup, fireEvent, screen } from '../utilities/test-utils';
|
3
3
|
import { Drawer, Button } from 'playbook-ui';
|
4
|
-
import { waitFor } from '@testing-library/react';
|
5
4
|
|
6
5
|
const size = 'sm';
|
7
6
|
|
@@ -12,10 +11,9 @@ function DrawerTest({ props }) {
|
|
12
11
|
|
13
12
|
return (
|
14
13
|
<>
|
15
|
-
|
14
|
+
<Button onClick={open}>{'Open Drawer'}</Button>
|
16
15
|
<Drawer
|
17
16
|
className="wrapper"
|
18
|
-
id="drawer-id"
|
19
17
|
onClose={close}
|
20
18
|
opened={isOpen}
|
21
19
|
placement="left"
|
@@ -29,17 +27,24 @@ function DrawerTest({ props }) {
|
|
29
27
|
);
|
30
28
|
}
|
31
29
|
|
30
|
+
afterEach(cleanup);
|
31
|
+
|
32
32
|
test('renders with the right border class when border prop is right', async () => {
|
33
33
|
render(<DrawerTest props={{ border: 'right' }} />);
|
34
34
|
|
35
35
|
fireEvent.click(screen.getByText('Open Drawer'));
|
36
36
|
|
37
|
-
|
37
|
+
const drawer = await screen.findByRole('dialog');
|
38
|
+
expect(drawer).toHaveClass('drawer_border_right');
|
39
|
+
});
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
test('renders with the left border class when border prop is left', async () => {
|
42
|
+
render(<DrawerTest props={{ border: 'left' }} />);
|
41
43
|
|
42
|
-
|
44
|
+
fireEvent.click(screen.getByText('Open Drawer'));
|
45
|
+
|
46
|
+
const drawer = await screen.findByRole('dialog');
|
47
|
+
expect(drawer).toHaveClass('drawer_border_left');
|
43
48
|
});
|
44
49
|
|
45
50
|
test('renders with the full border class when border prop is full', async () => {
|
@@ -47,10 +52,7 @@ test('renders with the full border class when border prop is full', async () =>
|
|
47
52
|
|
48
53
|
fireEvent.click(screen.getByText('Open Drawer'));
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
const container = document.getElementById('drawer-id');
|
53
|
-
const drawer = container.querySelector('#drawer-id .pb_drawer');
|
55
|
+
const drawer = await screen.findByRole('dialog');
|
54
56
|
expect(drawer).toHaveClass('drawer_border_full');
|
55
57
|
});
|
56
58
|
|
@@ -59,10 +61,7 @@ test('does not have a border class when border prop is none', async () => {
|
|
59
61
|
|
60
62
|
fireEvent.click(screen.getByText('Open Drawer'));
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
const container = document.getElementById('drawer-id');
|
65
|
-
const drawer = container.querySelector('#drawer-id .pb_drawer');
|
64
|
+
const drawer = await screen.findByRole('dialog');
|
66
65
|
expect(drawer).not.toHaveClass('drawer_border_right');
|
67
66
|
expect(drawer).not.toHaveClass('drawer_border_left');
|
68
67
|
expect(drawer).not.toHaveClass('drawer_border_full');
|
@@ -73,9 +72,6 @@ test('renders the correct size class for a large drawer', async () => {
|
|
73
72
|
|
74
73
|
fireEvent.click(screen.getByText('Open Drawer'));
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
const container = document.getElementById('drawer-id');
|
79
|
-
const drawer = container.querySelector('#drawer-id .pb_drawer');
|
75
|
+
const drawer = await screen.findByRole('dialog');
|
80
76
|
expect(drawer).toHaveClass('pb_drawer pb_drawer_lg_left');
|
81
77
|
});
|
@@ -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 %>
|
@@ -8,12 +8,6 @@ $icon_margin: $space_xs/2;
|
|
8
8
|
$icon_height: 28px;
|
9
9
|
$height_from_top: $icon_height/2 - $connector_width/2;
|
10
10
|
|
11
|
-
// Add gap variables
|
12
|
-
$gap_xs: $height_from_top + $space_xs;
|
13
|
-
$gap_sm: $height_from_top + $space_sm;
|
14
|
-
$gap_md: $height_from_top + $space_md;
|
15
|
-
$gap_lg: $height_from_top + $space_lg;
|
16
|
-
|
17
11
|
@mixin pb_timeline_line_solid($width, $height, $margin) {
|
18
12
|
width: $width;
|
19
13
|
height: $height;
|
@@ -162,7 +156,7 @@ $gap_lg: $height_from_top + $space_lg;
|
|
162
156
|
}
|
163
157
|
}
|
164
158
|
}
|
165
|
-
}
|
159
|
+
}
|
166
160
|
}
|
167
161
|
}
|
168
162
|
&[class*=_vertical] {
|
@@ -272,41 +266,5 @@ $gap_lg: $height_from_top + $space_lg;
|
|
272
266
|
}
|
273
267
|
}
|
274
268
|
}
|
275
|
-
&[class*=_gap_xs] {
|
276
|
-
[class*=pb_timeline_item_kit] {
|
277
|
-
[class=pb_timeline_item_step] {
|
278
|
-
[class=pb_timeline_item_connector] {
|
279
|
-
height: $gap_xs !important;
|
280
|
-
}
|
281
|
-
}
|
282
|
-
}
|
283
|
-
}
|
284
|
-
&[class*=_gap_sm] {
|
285
|
-
[class*=pb_timeline_item_kit] {
|
286
|
-
[class=pb_timeline_item_step] {
|
287
|
-
[class=pb_timeline_item_connector] {
|
288
|
-
height: $gap_sm !important;
|
289
|
-
}
|
290
|
-
}
|
291
|
-
}
|
292
|
-
}
|
293
|
-
&[class*=_gap_md] {
|
294
|
-
[class*=pb_timeline_item_kit] {
|
295
|
-
[class=pb_timeline_item_step] {
|
296
|
-
[class=pb_timeline_item_connector] {
|
297
|
-
height: $gap_md !important;
|
298
|
-
}
|
299
|
-
}
|
300
|
-
}
|
301
|
-
}
|
302
|
-
&[class*=_gap_lg] {
|
303
|
-
[class*=pb_timeline_item_kit] {
|
304
|
-
[class=pb_timeline_item_step] {
|
305
|
-
[class=pb_timeline_item_connector] {
|
306
|
-
height: $gap_lg !important;
|
307
|
-
}
|
308
|
-
}
|
309
|
-
}
|
310
|
-
}
|
311
269
|
}
|
312
270
|
}
|
@@ -20,7 +20,6 @@ type TimelineProps = {
|
|
20
20
|
id?: string,
|
21
21
|
orientation?: string,
|
22
22
|
showDate?: boolean,
|
23
|
-
gap?: 'xs' | 'sm' | 'md' | 'lg' | 'none',
|
24
23
|
} & GlobalProps
|
25
24
|
|
26
25
|
const Timeline = ({
|
@@ -32,16 +31,13 @@ const Timeline = ({
|
|
32
31
|
id,
|
33
32
|
orientation = 'horizontal',
|
34
33
|
showDate = false,
|
35
|
-
gap = 'none',
|
36
34
|
...props
|
37
35
|
}: TimelineProps): React.ReactElement => {
|
38
36
|
const ariaProps = buildAriaProps(aria)
|
39
37
|
const dataProps = buildDataProps(data)
|
40
38
|
const htmlProps = buildHtmlProps(htmlOptions)
|
41
39
|
const dateStyle = showDate === true ? '_with_date' : ''
|
42
|
-
const
|
43
|
-
const timelineCss = buildCss('pb_timeline_kit', `${orientation}`, dateStyle, gapStyle)
|
44
|
-
|
40
|
+
const timelineCss = buildCss('pb_timeline_kit', `_${orientation}`, dateStyle)
|
45
41
|
return (
|
46
42
|
<div
|
47
43
|
{...ariaProps}
|
@@ -60,4 +56,4 @@ Timeline.Step = TimelineStep
|
|
60
56
|
Timeline.Label = TimelineLabel
|
61
57
|
Timeline.Detail = TimelineDetail
|
62
58
|
|
63
|
-
export default Timeline
|
59
|
+
export default Timeline
|
@@ -1,16 +1,14 @@
|
|
1
1
|
examples:
|
2
|
-
|
2
|
+
|
3
3
|
rails:
|
4
4
|
- timeline_default: Default
|
5
5
|
- timeline_vertical: Vertical
|
6
6
|
- timeline_with_date: With Date
|
7
7
|
- timeline_with_children: With Children
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
|
11
10
|
react:
|
12
11
|
- timeline_default: Default
|
13
12
|
- timeline_vertical: Vertical
|
14
13
|
- timeline_with_date: With Date
|
15
14
|
- timeline_with_children: With Children
|
16
|
-
- timeline_with_gap: With Gap
|
@@ -2,5 +2,3 @@ export { default as TimelineDefault } from './_timeline_default.jsx'
|
|
2
2
|
export { default as TimelineVertical } from './_timeline_vertical.jsx'
|
3
3
|
export { default as TimelineWithDate } from './_timeline_with_date.jsx'
|
4
4
|
export { default as TimelineWithChildren } from './_timeline_with_children.jsx'
|
5
|
-
export { default as TimelineWithGap } from './_timeline_with_gap.jsx'
|
6
|
-
|
@@ -8,15 +8,9 @@ module Playbook
|
|
8
8
|
default: "horizontal"
|
9
9
|
prop :show_date, type: Playbook::Props::Boolean,
|
10
10
|
default: false
|
11
|
-
prop :gap, type: Playbook::Props::Enum,
|
12
|
-
values: %w[xs sm md lg none],
|
13
|
-
default: "none"
|
14
11
|
|
15
12
|
def classname
|
16
|
-
generate_classname("pb_timeline_kit",
|
17
|
-
orientation,
|
18
|
-
date_class,
|
19
|
-
gap_class)
|
13
|
+
generate_classname("pb_timeline_kit", orientation, date_class)
|
20
14
|
end
|
21
15
|
|
22
16
|
private
|
@@ -24,10 +18,6 @@ module Playbook
|
|
24
18
|
def date_class
|
25
19
|
show_date ? "with_date" : nil
|
26
20
|
end
|
27
|
-
|
28
|
-
def gap_class
|
29
|
-
gap == "none" ? nil : "gap_#{gap}"
|
30
|
-
end
|
31
21
|
end
|
32
22
|
end
|
33
23
|
end
|
@@ -147,26 +147,26 @@ test('should pass id prop', () => {
|
|
147
147
|
test('should have horizontal orientation by default', () => {
|
148
148
|
render(<TimelineDefault />)
|
149
149
|
const kit = screen.getByTestId(testId)
|
150
|
-
expect(kit).toHaveClass('
|
150
|
+
expect(kit).toHaveClass('pb_timeline_kit__horizontal')
|
151
151
|
})
|
152
152
|
|
153
153
|
test('should pass vertical orientation', () => {
|
154
154
|
const props = { orientation: 'vertical' }
|
155
155
|
render(<TimelineDefault {...props} />)
|
156
156
|
const kit = screen.getByTestId(testId)
|
157
|
-
expect(kit).toHaveClass('
|
157
|
+
expect(kit).toHaveClass('pb_timeline_kit__vertical')
|
158
158
|
})
|
159
159
|
|
160
160
|
test('should pass showDate prop', () => {
|
161
161
|
const props = { showDate: true }
|
162
162
|
render(<TimelineDefault {...props} />)
|
163
163
|
const kit = screen.getByTestId(testId)
|
164
|
-
expect(kit).toHaveClass('
|
164
|
+
expect(kit).toHaveClass('pb_timeline_kit__horizontal__with_date')
|
165
165
|
})
|
166
166
|
|
167
167
|
test('should pass showDate prop with Children', () => {
|
168
168
|
const props = { showDate: true }
|
169
169
|
render(<TimelineWithChildren {...props} />)
|
170
170
|
const kit = screen.getByTestId(testId)
|
171
|
-
expect(kit).toHaveClass('
|
171
|
+
expect(kit).toHaveClass('pb_timeline_kit__horizontal__with_date')
|
172
172
|
})
|
@@ -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"
|
@@ -21,47 +21,34 @@
|
|
21
21
|
}
|
22
22
|
|
23
23
|
@mixin hover-color-classes($colors-list) {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
@each $name, $color in $colors-list {
|
25
|
+
.hover_background_#{"" + $name}:hover,
|
26
|
+
.group_hover:hover .group_hover.hover_background_#{"" + $name} {
|
27
|
+
background-color: $color !important;
|
28
|
+
transition: background-color $transition-speed ease;
|
29
|
+
}
|
30
|
+
.hover_color_#{"" + $name}:hover,
|
31
|
+
.group_hover:hover .group_hover.hover_color_#{"" + $name} {
|
32
|
+
color: $color !important;
|
33
|
+
transition: color $transition-speed ease;
|
33
34
|
}
|
34
|
-
}
|
35
|
-
|
36
|
-
@include hover-scale-classes($scales);
|
37
|
-
@include hover-shadow-classes($box_shadows);
|
38
|
-
@include hover-color-classes($product_colors);
|
39
|
-
@include hover-color-classes($status_colors);
|
40
|
-
@include hover-color-classes($data_colors);
|
41
|
-
@include hover-color-classes($shadow_colors);
|
42
|
-
@include hover-color-classes($colors);
|
43
|
-
@include hover-color-classes($interface_colors);
|
44
|
-
@include hover-color-classes($main_colors);
|
45
|
-
@include hover-color-classes($background_colors);
|
46
|
-
@include hover-color-classes($card_colors);
|
47
|
-
@include hover-color-classes($active_colors);
|
48
|
-
@include hover-color-classes($action_colors);
|
49
|
-
@include hover-color-classes($hover_colors);
|
50
|
-
@include hover-color-classes($border_colors);
|
51
|
-
@include hover-color-classes($text_colors);
|
52
|
-
@include hover-color-classes($category_colors);
|
53
|
-
|
54
|
-
.hover_visibility {
|
55
|
-
opacity: 0;
|
56
|
-
transition: opacity $transition-speed ease;
|
57
|
-
|
58
|
-
&:hover {
|
59
|
-
opacity: 1;
|
60
35
|
}
|
61
36
|
}
|
62
37
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
38
|
+
@include hover-scale-classes($scales);
|
39
|
+
@include hover-shadow-classes($box_shadows);
|
40
|
+
@include hover-color-classes($product_colors);
|
41
|
+
@include hover-color-classes($status_colors);
|
42
|
+
@include hover-color-classes($data_colors);
|
43
|
+
@include hover-color-classes($shadow_colors);
|
44
|
+
@include hover-color-classes($colors);
|
45
|
+
@include hover-color-classes($interface_colors);
|
46
|
+
@include hover-color-classes($main_colors);
|
47
|
+
@include hover-color-classes($background_colors);
|
48
|
+
@include hover-color-classes($card_colors);
|
49
|
+
@include hover-color-classes($active_colors);
|
50
|
+
@include hover-color-classes($action_colors);
|
51
|
+
@include hover-color-classes($hover_colors);
|
52
|
+
@include hover-color-classes($border_colors);
|
53
|
+
@include hover-color-classes($text_colors);
|
54
|
+
@include hover-color-classes($category_colors);
|
@@ -63,8 +63,7 @@ type FlexWrap = {
|
|
63
63
|
type Hover = Shadow & {
|
64
64
|
background?: string,
|
65
65
|
color?: string,
|
66
|
-
scale?: "sm" | "md" | "lg"
|
67
|
-
visibility?: boolean,
|
66
|
+
scale?: "sm" | "md" | "lg"
|
68
67
|
}
|
69
68
|
|
70
69
|
type GroupHover = {
|
@@ -231,10 +230,9 @@ const PROP_CATEGORIES: {[key:string]: (props: {[key: string]: any}) => string} =
|
|
231
230
|
let css = '';
|
232
231
|
if (!hover) return css;
|
233
232
|
css += hover.shadow ? `hover_shadow_${hover.shadow} ` : '';
|
234
|
-
css += hover.background ? `
|
233
|
+
css += hover.background ? `hover_background_${hover.background } ` : '';
|
235
234
|
css += hover.scale ? `hover_scale_${hover.scale} ` : '';
|
236
|
-
css += hover.color ? `
|
237
|
-
css += hover.visibility ? `hover_visibility` : '';
|
235
|
+
css += hover.color ? `hover_color_${hover.color } ` : '';
|
238
236
|
return css;
|
239
237
|
},
|
240
238
|
|