playbook_ui 18.3.0.pre.rc.1 → 18.3.0.pre.rc.2
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_advanced_table/table_header.rb +1 -1
- data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +3 -1
- data/app/pb_kits/playbook/pb_avatar/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_contact/_contact.tsx +4 -1
- data/app/pb_kits/playbook/pb_contact/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date/_date.tsx +3 -1
- data/app/pb_kits/playbook/pb_date/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +3 -1
- data/app/pb_kits/playbook/pb_date_range_inline/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_range_stacked/_date_range_stacked.tsx +3 -1
- data/app/pb_kits/playbook/pb_date_range_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_stacked/_date_stacked.tsx +4 -1
- data/app/pb_kits/playbook/pb_date_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_time/_date_time.tsx +3 -1
- data/app/pb_kits/playbook/pb_date_time/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_time_stacked/_date_time_stacked.tsx +2 -1
- data/app/pb_kits/playbook/pb_date_time_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_date_year_stacked/_date_year_stacked.tsx +3 -1
- data/app/pb_kits/playbook/pb_date_year_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_draggable/utilities/touchDrag.ts +10 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +112 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +11 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_draggable_pills.html.erb +51 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_draggable_pills.jsx +62 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_draggable_pills_rails.md +9 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_draggable_pills_react.md +9 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_playground.json +16 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_playground.overrides.json +7 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +10 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +194 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown_index.test.js +254 -0
- data/app/pb_kits/playbook/pb_dropdown/index.js +166 -7
- data/app/pb_kits/playbook/pb_dropdown/kit.schema.json +24 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/MultiSelectTriggerDisplay.tsx +336 -31
- data/app/pb_kits/playbook/pb_dropdown/utilities/pillReorder.js +281 -0
- data/app/pb_kits/playbook/pb_dropdown/utilities/usePillDropIndicator.ts +144 -0
- data/app/pb_kits/playbook/pb_form/pb_form_validation.js +1 -0
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +1 -4
- data/app/pb_kits/playbook/pb_image/_image.tsx +3 -1
- data/app/pb_kits/playbook/pb_image/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +6 -3
- data/app/pb_kits/playbook/pb_map/docs/_map_default.md +22 -3
- data/app/pb_kits/playbook/pb_person/_person.tsx +3 -1
- data/app/pb_kits/playbook/pb_person/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +3 -4
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_extensions.md +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_markdown_support.md +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +0 -6
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +26 -21
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.test.js +85 -1
- data/app/pb_kits/playbook/pb_selectable_card_icon/_selectable_card_icon.scss +0 -9
- data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_selectable_card_icon_custom.jsx +1 -1
- data/app/pb_kits/playbook/pb_selectable_icon/_selectable_icon.scss +0 -7
- data/app/pb_kits/playbook/pb_source/source.rb +1 -1
- data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +3 -1
- data/app/pb_kits/playbook/pb_time_range_inline/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.tsx +3 -1
- data/app/pb_kits/playbook/pb_time_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_timestamp/_timestamp.tsx +3 -1
- data/app/pb_kits/playbook/pb_timestamp/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +127 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +15 -10
- data/app/pb_kits/playbook/pb_user/_user.tsx +3 -1
- data/app/pb_kits/playbook/pb_user/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_user_badge/_user_badge.tsx +3 -1
- data/app/pb_kits/playbook/pb_user_badge/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +3 -1
- data/app/pb_kits/playbook/pb_weekday_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/utilities/test/globalProps/onClick.test.js +186 -0
- data/dist/ai/all-schemas.json +56 -2
- data/dist/ai/external-dependencies.json +1 -1
- data/dist/ai/forms.json +2 -2
- data/dist/ai/index.json +3 -3
- data/dist/ai/kits/avatar.schema.json +1 -0
- data/dist/ai/kits/contact.schema.json +1 -0
- data/dist/ai/kits/date.schema.json +1 -0
- data/dist/ai/kits/date_range_inline.schema.json +1 -0
- data/dist/ai/kits/date_range_stacked.schema.json +1 -0
- data/dist/ai/kits/date_stacked.schema.json +1 -0
- data/dist/ai/kits/date_time.schema.json +1 -0
- data/dist/ai/kits/date_time_stacked.schema.json +1 -0
- data/dist/ai/kits/date_year_stacked.schema.json +1 -0
- data/dist/ai/kits/dropdown.schema.json +38 -1
- data/dist/ai/kits/image.schema.json +1 -0
- data/dist/ai/kits/person.schema.json +1 -0
- data/dist/ai/kits/rich_text_editor.schema.json +1 -1
- data/dist/ai/kits/time_range_inline.schema.json +1 -0
- data/dist/ai/kits/time_stacked.schema.json +1 -0
- data/dist/ai/kits/timestamp.schema.json +1 -0
- data/dist/ai/kits/user.schema.json +1 -0
- data/dist/ai/kits/user_badge.schema.json +1 -0
- data/dist/ai/kits/weekday_stacked.schema.json +1 -0
- data/dist/ai/playgrounds/dropdown.json +1 -1
- data/dist/ai/playgrounds/rich_text_editor.json +1 -1
- data/dist/chunks/{_pagination-D0hcdUl3.js → _pagination-CARbC_IN.js} +1 -1
- data/dist/chunks/{_tooltip-DfZEKsnv.js → _tooltip-UkcgcThO.js} +1 -1
- data/dist/chunks/{_typeahead-CmJ8Ggzz.js → _typeahead-NYVJDWmJ.js} +1 -1
- data/dist/chunks/index-4jrZjexD.js +1 -0
- data/dist/chunks/index-BAy61y8S.js +1 -0
- data/dist/chunks/index-Cb_SDipk.js +1 -0
- data/dist/chunks/index-D3RdsDp7.js +1 -0
- data/dist/chunks/index-D8PZIesy.js +1 -0
- data/dist/chunks/index-DIoc-aua.js +1 -0
- data/dist/chunks/index-qex65UMn.js +1 -0
- data/dist/chunks/vendor.js +2 -2
- data/dist/menu.yml +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 +37 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8582fa63726a34ad01ae22c73948ace36979ee0b5d3a2f6a362309826689f963
|
|
4
|
+
data.tar.gz: 657c7f4fcc9819b0dec67daaab5cca1c11bc3cd8948374bc462ea287d72fe57e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2598b3eea96f74b461e103e443895c80e9372ebf6dde222dca8efd6d1d9b7900f7ad3b69a48e4c80e98fb8036e1105cd344e619f2131e877477b52b929a1f4ed
|
|
7
|
+
data.tar.gz: 1cdd22957b2083b97d80ab7591d5441e18d43eb42a734ea33b06edd4365117d42d1b9fc1a112d33aea8cca06de775d95eaa9fa59dd5518b66f2c392c66ff99b4
|
|
@@ -157,7 +157,7 @@ module Playbook
|
|
|
157
157
|
|
|
158
158
|
# Determines if the toggle-all button should be shown in the header based on inline row loading and persist toggle expansion button props
|
|
159
159
|
def show_toggle_all_button?
|
|
160
|
-
return false unless
|
|
160
|
+
return false unless %w[header all].include?(enable_toggle_expansion)
|
|
161
161
|
|
|
162
162
|
has_any_sub_rows? || (inline_row_loading && persist_toggle_expansion_button)
|
|
163
163
|
end
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
|
3
3
|
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
import { getPlacementProps } from './Utilities/GetPlacementPropsHelper'
|
|
7
8
|
|
|
8
9
|
import Image from "../pb_image/_image";
|
|
@@ -33,7 +34,7 @@ export type AvatarProps = {
|
|
|
33
34
|
name?: string,
|
|
34
35
|
size?: "md" | "lg" | "sm" | "xl" | "xs" | "xxs",
|
|
35
36
|
status?: "away" | "offline" | "online",
|
|
36
|
-
} & GlobalProps
|
|
37
|
+
} & GlobalProps & GlobalEventProps
|
|
37
38
|
|
|
38
39
|
const firstTwoInitials = (name: string) =>
|
|
39
40
|
name.split(/\s/).map((name) => name[0])
|
|
@@ -94,6 +95,7 @@ const Avatar = (props: AvatarProps): React.ReactElement => {
|
|
|
94
95
|
{...ariaProps}
|
|
95
96
|
{...dataProps}
|
|
96
97
|
{...htmlProps}
|
|
98
|
+
{...globalEventProps(props)}
|
|
97
99
|
className={classes}
|
|
98
100
|
id={id}
|
|
99
101
|
>
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
|
3
3
|
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
|
|
7
8
|
import Body from '../pb_body/_body'
|
|
8
9
|
import Caption from '../pb_caption/_caption'
|
|
@@ -64,7 +65,7 @@ type ContactProps = {
|
|
|
64
65
|
iconEnabled?: boolean
|
|
65
66
|
id?: string
|
|
66
67
|
unstyled?: boolean
|
|
67
|
-
}
|
|
68
|
+
} & GlobalEventProps
|
|
68
69
|
|
|
69
70
|
const Contact = (props: ContactProps): React.ReactElement => {
|
|
70
71
|
const {
|
|
@@ -125,6 +126,7 @@ const Contact = (props: ContactProps): React.ReactElement => {
|
|
|
125
126
|
{...ariaProps}
|
|
126
127
|
{...dataProps}
|
|
127
128
|
{...htmlProps}
|
|
129
|
+
{...globalEventProps(props)}
|
|
128
130
|
className={classes}
|
|
129
131
|
id={id}
|
|
130
132
|
>
|
|
@@ -139,6 +141,7 @@ const Contact = (props: ContactProps): React.ReactElement => {
|
|
|
139
141
|
{...ariaProps}
|
|
140
142
|
{...dataProps}
|
|
141
143
|
{...htmlProps}
|
|
144
|
+
{...globalEventProps(props)}
|
|
142
145
|
className={classes}
|
|
143
146
|
id={id}
|
|
144
147
|
>
|
|
@@ -3,6 +3,7 @@ import classnames from "classnames";
|
|
|
3
3
|
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
|
5
5
|
import { globalProps } from "../utilities/globalProps";
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from "../utilities/globalEventProps";
|
|
6
7
|
import DateTime from '../pb_kit/dateTime';
|
|
7
8
|
|
|
8
9
|
import Body from "../pb_body/_body";
|
|
@@ -24,7 +25,7 @@ type PbDateProps = {
|
|
|
24
25
|
size?: "sm" | "md" | "lg";
|
|
25
26
|
unstyled?: boolean;
|
|
26
27
|
value: Date;
|
|
27
|
-
};
|
|
28
|
+
} & GlobalEventProps;
|
|
28
29
|
|
|
29
30
|
const PbDate = (props: PbDateProps): React.ReactElement => {
|
|
30
31
|
const {
|
|
@@ -64,6 +65,7 @@ const PbDate = (props: PbDateProps): React.ReactElement => {
|
|
|
64
65
|
{...ariaProps}
|
|
65
66
|
{...dataProps}
|
|
66
67
|
{...htmlProps}
|
|
68
|
+
{...globalEventProps(props)}
|
|
67
69
|
className={classes}
|
|
68
70
|
id={id}
|
|
69
71
|
>
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import classnames from "classnames";
|
|
3
3
|
|
|
4
4
|
import { globalProps } from "../utilities/globalProps";
|
|
5
|
+
import { GlobalEventProps, globalEventProps } from "../utilities/globalEventProps";
|
|
5
6
|
import { buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
|
6
7
|
import DateTime from '../pb_kit/dateTime';
|
|
7
8
|
|
|
@@ -21,7 +22,7 @@ type DateRangeInlineProps = {
|
|
|
21
22
|
size?: "sm" | "xs";
|
|
22
23
|
showCurrentYear?: boolean;
|
|
23
24
|
startDate?: Date;
|
|
24
|
-
};
|
|
25
|
+
} & GlobalEventProps;
|
|
25
26
|
|
|
26
27
|
const dateTimestamp = (dateValue: Date, includeYear: boolean) => {
|
|
27
28
|
if (includeYear) {
|
|
@@ -74,6 +75,7 @@ const DateRangeInline = (props: DateRangeInlineProps): React.ReactElement => {
|
|
|
74
75
|
<div
|
|
75
76
|
{...dataProps}
|
|
76
77
|
{...htmlProps}
|
|
78
|
+
{...globalEventProps(props)}
|
|
77
79
|
className={classnames(dateRangeClasses, globalProps(props), className)}
|
|
78
80
|
>
|
|
79
81
|
<div className="pb_date_range_inline_wrapper">
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
|
3
3
|
|
|
4
4
|
import { buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
|
|
7
8
|
import Body from '../pb_body/_body'
|
|
8
9
|
import Flex from '../pb_flex/_flex'
|
|
@@ -18,7 +19,7 @@ type DateRangeStackedProps = {
|
|
|
18
19
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
|
19
20
|
id?: string,
|
|
20
21
|
startDate: Date,
|
|
21
|
-
}
|
|
22
|
+
} & GlobalEventProps
|
|
22
23
|
|
|
23
24
|
const DateRangeStacked = (props: DateRangeStackedProps): React.ReactElement => {
|
|
24
25
|
const {
|
|
@@ -41,6 +42,7 @@ const DateRangeStacked = (props: DateRangeStackedProps): React.ReactElement => {
|
|
|
41
42
|
<div
|
|
42
43
|
{...dataProps}
|
|
43
44
|
{...htmlProps}
|
|
45
|
+
{...globalEventProps(props)}
|
|
44
46
|
className={css}
|
|
45
47
|
>
|
|
46
48
|
<Flex vertical="center">
|
|
@@ -3,6 +3,7 @@ import React from "react";
|
|
|
3
3
|
import classnames from "classnames";
|
|
4
4
|
import { buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
|
5
5
|
import { globalProps } from "../utilities/globalProps";
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from "../utilities/globalEventProps";
|
|
6
7
|
import DateTime from '../pb_kit/dateTime';
|
|
7
8
|
|
|
8
9
|
import Caption from "../pb_caption/_caption";
|
|
@@ -20,7 +21,7 @@ type DateStackedProps = {
|
|
|
20
21
|
id?: string;
|
|
21
22
|
reverse?: boolean;
|
|
22
23
|
showCurrentYear?: boolean;
|
|
23
|
-
};
|
|
24
|
+
} & GlobalEventProps;
|
|
24
25
|
|
|
25
26
|
const sizes: {sm: 4, md: 3} = {
|
|
26
27
|
sm: 4,
|
|
@@ -60,6 +61,7 @@ const DateStacked = (props: DateStackedProps): React.ReactElement => {
|
|
|
60
61
|
<div
|
|
61
62
|
{...dataProps}
|
|
62
63
|
{...htmlProps}
|
|
64
|
+
{...globalEventProps(props)}
|
|
63
65
|
className={classes}
|
|
64
66
|
>
|
|
65
67
|
<div className="pb_date_stacked_day_month">
|
|
@@ -76,6 +78,7 @@ const DateStacked = (props: DateStackedProps): React.ReactElement => {
|
|
|
76
78
|
<div
|
|
77
79
|
{...dataProps}
|
|
78
80
|
{...htmlProps}
|
|
81
|
+
{...globalEventProps(props)}
|
|
79
82
|
className={classes}
|
|
80
83
|
>
|
|
81
84
|
<div className="pb_date_stacked_day_month">
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
|
3
3
|
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
|
|
7
8
|
import Flex from '../pb_flex/_flex'
|
|
8
9
|
import Time from '../pb_time/_time'
|
|
@@ -21,7 +22,7 @@ type DateTimeProps = {
|
|
|
21
22
|
showDayOfWeek: boolean,
|
|
22
23
|
showIcon?: boolean,
|
|
23
24
|
timeZone?: string
|
|
24
|
-
}
|
|
25
|
+
} & GlobalEventProps
|
|
25
26
|
|
|
26
27
|
const DateTime = (props: DateTimeProps): React.ReactElement => {
|
|
27
28
|
const {
|
|
@@ -53,6 +54,7 @@ const DateTime = (props: DateTimeProps): React.ReactElement => {
|
|
|
53
54
|
{...ariaProps}
|
|
54
55
|
{...dataProps}
|
|
55
56
|
{...htmlProps}
|
|
57
|
+
{...globalEventProps(props)}
|
|
56
58
|
className={classes}
|
|
57
59
|
id={id}
|
|
58
60
|
>
|
|
@@ -4,6 +4,7 @@ import classnames from 'classnames'
|
|
|
4
4
|
|
|
5
5
|
import { buildCss, buildHtmlProps } from '../utilities/props'
|
|
6
6
|
import { deprecatedProps, globalProps } from '../utilities/globalProps'
|
|
7
|
+
import { GlobalEventProps } from '../utilities/globalEventProps'
|
|
7
8
|
|
|
8
9
|
import Flex from '../pb_flex/_flex'
|
|
9
10
|
import FlexItem from '../pb_flex/_flex_item'
|
|
@@ -20,7 +21,7 @@ type DateTimeStackedProps = {
|
|
|
20
21
|
dark: boolean,
|
|
21
22
|
timeZone?: string,
|
|
22
23
|
showCurrentYear?: boolean,
|
|
23
|
-
}
|
|
24
|
+
} & GlobalEventProps
|
|
24
25
|
|
|
25
26
|
const DateTimeStacked = (props: DateTimeStackedProps): React.ReactElement => {
|
|
26
27
|
if (props.date) deprecatedProps()
|
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
|
3
3
|
|
|
4
4
|
import { buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
import DateTime from '../pb_kit/dateTime';
|
|
7
8
|
|
|
8
9
|
import Body from '../pb_body/_body'
|
|
@@ -16,7 +17,7 @@ type DateYearStackedProps = {
|
|
|
16
17
|
date: Date,
|
|
17
18
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
|
18
19
|
id?: string,
|
|
19
|
-
}
|
|
20
|
+
} & GlobalEventProps
|
|
20
21
|
|
|
21
22
|
const DateYearStacked = (props: DateYearStackedProps): React.ReactElement => {
|
|
22
23
|
const {
|
|
@@ -39,6 +40,7 @@ const DateYearStacked = (props: DateYearStackedProps): React.ReactElement => {
|
|
|
39
40
|
<div
|
|
40
41
|
{...dataProps}
|
|
41
42
|
{...htmlProps}
|
|
43
|
+
{...globalEventProps(props)}
|
|
42
44
|
className={css}
|
|
43
45
|
>
|
|
44
46
|
<Title
|
|
@@ -370,6 +370,16 @@ export const bindMousePointerDrag = ({
|
|
|
370
370
|
event.preventDefault();
|
|
371
371
|
event.stopPropagation();
|
|
372
372
|
|
|
373
|
+
// Dropdown: restore pill focus after preventDefault so ArrowLeft/Right work.
|
|
374
|
+
// Typeahead: leave focus on the search input — focusing the pill blurs it and
|
|
375
|
+
// react-select closes the menu / clears the query.
|
|
376
|
+
const pill = itemElement.querySelector<HTMLElement>(
|
|
377
|
+
'.pb_form_pill_kit, .pb_form_pill_kit_icon',
|
|
378
|
+
);
|
|
379
|
+
if (pill && !itemElement.closest('.pb_typeahead_kit')) {
|
|
380
|
+
pill.focus({ preventScroll: true });
|
|
381
|
+
}
|
|
382
|
+
|
|
373
383
|
state.active = true;
|
|
374
384
|
state.startX = event.clientX;
|
|
375
385
|
state.startY = event.clientY;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
@import "../tokens/border_radius";
|
|
5
5
|
@import "../tokens/shadows";
|
|
6
6
|
@import "../tokens/positioning";
|
|
7
|
+
@import "../tokens/opacity";
|
|
7
8
|
@import "../pb_body/body_mixins";
|
|
8
9
|
@import "../pb_textarea/textarea_mixin";
|
|
9
10
|
|
|
@@ -536,3 +537,114 @@
|
|
|
536
537
|
padding: 0;
|
|
537
538
|
pointer-events: auto;
|
|
538
539
|
}
|
|
540
|
+
|
|
541
|
+
.pb_dropdown_draggable_pills {
|
|
542
|
+
display: inline-flex;
|
|
543
|
+
flex-wrap: wrap;
|
|
544
|
+
align-items: center;
|
|
545
|
+
gap: 0;
|
|
546
|
+
|
|
547
|
+
.pb_draggable_item {
|
|
548
|
+
position: relative;
|
|
549
|
+
display: inline-flex;
|
|
550
|
+
align-items: center;
|
|
551
|
+
user-select: none;
|
|
552
|
+
-webkit-user-select: none;
|
|
553
|
+
|
|
554
|
+
&.pb_dropdown_drop_before::before,
|
|
555
|
+
&.pb_dropdown_drop_after::after {
|
|
556
|
+
content: "";
|
|
557
|
+
position: absolute;
|
|
558
|
+
inset-block: 2px;
|
|
559
|
+
width: 2px;
|
|
560
|
+
background-color: $primary;
|
|
561
|
+
border-radius: $border_radius_rounded;
|
|
562
|
+
pointer-events: none;
|
|
563
|
+
}
|
|
564
|
+
&.pb_dropdown_drop_before::before {
|
|
565
|
+
inset-inline-start: -5px;
|
|
566
|
+
}
|
|
567
|
+
&.pb_dropdown_drop_after::after {
|
|
568
|
+
inset-inline-end: 3px;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
&:hover {
|
|
572
|
+
cursor: grab;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
&.is_dragging {
|
|
576
|
+
cursor: grabbing;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.pb_form_pill_kit_icon,
|
|
580
|
+
.pb_form_pill_kit_icon * {
|
|
581
|
+
cursor: grab;
|
|
582
|
+
}
|
|
583
|
+
.pb_form_pill_close,
|
|
584
|
+
.pb_form_pill_close * {
|
|
585
|
+
cursor: pointer;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
&.active .pb_draggable_item > * {
|
|
590
|
+
pointer-events: none;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.pb_dropdown_pill_with_handle {
|
|
595
|
+
display: inline-flex;
|
|
596
|
+
align-items: center;
|
|
597
|
+
gap: $space_xxs;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.pb_dropdown_external_drag_handle {
|
|
601
|
+
display: inline-flex;
|
|
602
|
+
align-items: center;
|
|
603
|
+
flex-shrink: 0;
|
|
604
|
+
cursor: grab;
|
|
605
|
+
user-select: none;
|
|
606
|
+
color: $text_lighter;
|
|
607
|
+
|
|
608
|
+
&:active {
|
|
609
|
+
cursor: grabbing;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.pb_dropdown_pill_grip_icon {
|
|
613
|
+
color: $text_lighter !important;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.pb_dropdown_draggable_pills,
|
|
618
|
+
.pb_dropdown_pill_drag_preview {
|
|
619
|
+
.pb_form_pill_kit_icon .pb_form_pill_icon,
|
|
620
|
+
.pb_form_pill_kit_icon .pb_dropdown_pill_grip_icon {
|
|
621
|
+
order: -1;
|
|
622
|
+
color: $text_lighter !important;
|
|
623
|
+
margin-left: -$space_xs;
|
|
624
|
+
padding-right: $space_xxs;
|
|
625
|
+
scale: 0.9;
|
|
626
|
+
}
|
|
627
|
+
.pb_form_pill_kit_icon.dark .pb_form_pill_icon,
|
|
628
|
+
.pb_form_pill_kit_icon.dark .pb_dropdown_pill_grip_icon {
|
|
629
|
+
color: $text_lighter_dark !important;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.pb_dropdown_pill_drag_preview {
|
|
634
|
+
position: fixed;
|
|
635
|
+
z-index: $z_max;
|
|
636
|
+
display: inline-flex;
|
|
637
|
+
align-items: center;
|
|
638
|
+
opacity: $opacity_5;
|
|
639
|
+
pointer-events: none;
|
|
640
|
+
|
|
641
|
+
.pb_form_pill_kit,
|
|
642
|
+
.pb_form_pill_kit_icon {
|
|
643
|
+
box-shadow: $shadow_deep;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
body:has(.pb_dropdown_pill_drag_preview),
|
|
648
|
+
body:has(.pb_dropdown_pill_drag_preview) * {
|
|
649
|
+
cursor: grabbing !important;
|
|
650
|
+
}
|
|
@@ -126,6 +126,8 @@ type DropdownProps = {
|
|
|
126
126
|
defaultValue?: GenericObject;
|
|
127
127
|
error?: string;
|
|
128
128
|
enableFormSupport?: boolean;
|
|
129
|
+
enablePillReorder?: boolean;
|
|
130
|
+
externalDragHandle?: boolean;
|
|
129
131
|
htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
|
|
130
132
|
id?: string;
|
|
131
133
|
isClosed?: boolean;
|
|
@@ -138,6 +140,7 @@ type DropdownProps = {
|
|
|
138
140
|
options?: GenericObject;
|
|
139
141
|
placeholder?: string;
|
|
140
142
|
separators?: boolean;
|
|
143
|
+
showPillIndex?: boolean;
|
|
141
144
|
variant?: "default" | "subtle" | "quickpick";
|
|
142
145
|
rangeEndsToday?: boolean;
|
|
143
146
|
controlsStartId?: string;
|
|
@@ -184,6 +187,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
184
187
|
disabled = false,
|
|
185
188
|
error: errorProp,
|
|
186
189
|
enableFormSupport = false,
|
|
190
|
+
enablePillReorder = false,
|
|
191
|
+
externalDragHandle = false,
|
|
187
192
|
htmlOptions = {},
|
|
188
193
|
id,
|
|
189
194
|
isClosed = true,
|
|
@@ -196,6 +201,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
196
201
|
onSelect,
|
|
197
202
|
options,
|
|
198
203
|
placeholder,
|
|
204
|
+
showPillIndex = false,
|
|
199
205
|
rangeEndsToday = false,
|
|
200
206
|
controlsStartId,
|
|
201
207
|
controlsEndId,
|
|
@@ -207,6 +213,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
207
213
|
validationMessage = "Please fill out this field."
|
|
208
214
|
} = props;
|
|
209
215
|
|
|
216
|
+
const isPillReorderEnabled = Boolean(enablePillReorder && multiSelect);
|
|
217
|
+
|
|
210
218
|
const creationEnabled = allowOptionCreation && variant !== "quickpick";
|
|
211
219
|
const autocomplete = autocompleteProp || creationEnabled;
|
|
212
220
|
|
|
@@ -837,6 +845,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
837
845
|
disabled,
|
|
838
846
|
error,
|
|
839
847
|
errorId,
|
|
848
|
+
enablePillReorder: isPillReorderEnabled,
|
|
849
|
+
externalDragHandle,
|
|
840
850
|
filterItem,
|
|
841
851
|
filteredOptions,
|
|
842
852
|
focusedOptionIndex,
|
|
@@ -865,6 +875,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
865
875
|
setIsDropDownClosed,
|
|
866
876
|
setIsInputFocused,
|
|
867
877
|
setSelected,
|
|
878
|
+
showPillIndex,
|
|
868
879
|
toggleDropdown
|
|
869
880
|
}}
|
|
870
881
|
>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{ label: 'Year', value: 'year', id: 'year' },
|
|
4
|
+
{ label: 'Territory', value: 'territory', id: 'territory' },
|
|
5
|
+
{ label: 'Branch', value: 'branch', id: 'branch' },
|
|
6
|
+
{ label: 'Product', value: 'product', id: 'product' },
|
|
7
|
+
]
|
|
8
|
+
%>
|
|
9
|
+
|
|
10
|
+
<%= pb_rails("body", props: { text: "Select services, then drag the pills to reorder them.", margin_bottom: "xs" }) %>
|
|
11
|
+
|
|
12
|
+
<%= pb_rails("dropdown", props: {
|
|
13
|
+
id: "dropdown-draggable-pills-example",
|
|
14
|
+
default_value: [options[0], options[1], options[2]],
|
|
15
|
+
enable_pill_reorder: true,
|
|
16
|
+
show_pill_index: true,
|
|
17
|
+
multi_select: true,
|
|
18
|
+
label: "Services",
|
|
19
|
+
name: :services,
|
|
20
|
+
options: options,
|
|
21
|
+
placeholder: "Add services...",
|
|
22
|
+
}) %>
|
|
23
|
+
|
|
24
|
+
<%= pb_rails("body", props: {
|
|
25
|
+
id: "dropdown-draggable-order",
|
|
26
|
+
color: "lighter",
|
|
27
|
+
margin_top: "xs",
|
|
28
|
+
text: "Current order: Year -> Territory -> Branch",
|
|
29
|
+
}) %>
|
|
30
|
+
|
|
31
|
+
<script>
|
|
32
|
+
(() => {
|
|
33
|
+
const dropdownId = "dropdown-draggable-pills-example";
|
|
34
|
+
const orderElement = document.getElementById("dropdown-draggable-order");
|
|
35
|
+
|
|
36
|
+
const updateOrderText = (detail) => {
|
|
37
|
+
if (!orderElement || !Array.isArray(detail)) return;
|
|
38
|
+
orderElement.textContent = `Current order: ${detail.map((item) => item.label).join(" -> ")}`;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
document.addEventListener("pb:dropdown:reordered", (event) => {
|
|
42
|
+
if (event.target.id !== dropdownId) return;
|
|
43
|
+
updateOrderText(event.detail);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
document.addEventListener("pb:dropdown:selected", (event) => {
|
|
47
|
+
if (event.target.id !== dropdownId) return;
|
|
48
|
+
updateOrderText(event.detail);
|
|
49
|
+
});
|
|
50
|
+
})();
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { Body, Button, Dropdown, Flex } from 'playbook-ui'
|
|
3
|
+
|
|
4
|
+
const options = [
|
|
5
|
+
{ label: 'Year', value: 'year', id: 'year' },
|
|
6
|
+
{ label: 'Territory', value: 'territory', id: 'territory' },
|
|
7
|
+
{ label: 'Branch', value: 'branch', id: 'branch' },
|
|
8
|
+
{ label: 'Product', value: 'product', id: 'product' },
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
const DropdownDraggablePills = (props) => {
|
|
12
|
+
const [value, setValue] = useState([
|
|
13
|
+
options[0],
|
|
14
|
+
options[1],
|
|
15
|
+
options[2],
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
const currentOrder = value.map((item) => item.label).join(' -> ')
|
|
19
|
+
|
|
20
|
+
const handleReset = () => {
|
|
21
|
+
setValue([options[0], options[1], options[2]])
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Flex
|
|
26
|
+
align="stretch"
|
|
27
|
+
gap="sm"
|
|
28
|
+
orientation="column"
|
|
29
|
+
>
|
|
30
|
+
<Flex
|
|
31
|
+
align="center"
|
|
32
|
+
justify="between"
|
|
33
|
+
>
|
|
34
|
+
<Body text="Select services, then drag the pills to reorder them." />
|
|
35
|
+
<Button
|
|
36
|
+
onClick={handleReset}
|
|
37
|
+
text="Reset"
|
|
38
|
+
variant="secondary"
|
|
39
|
+
/>
|
|
40
|
+
</Flex>
|
|
41
|
+
|
|
42
|
+
<Dropdown
|
|
43
|
+
enablePillReorder
|
|
44
|
+
label="Services"
|
|
45
|
+
multiSelect
|
|
46
|
+
onChange={({ target }) => setValue(target.value || [])}
|
|
47
|
+
options={options}
|
|
48
|
+
placeholder="Add services..."
|
|
49
|
+
showPillIndex
|
|
50
|
+
value={value}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
<Body
|
|
55
|
+
color="lighter"
|
|
56
|
+
text={`Current order: ${currentOrder}`}
|
|
57
|
+
/>
|
|
58
|
+
</Flex>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default DropdownDraggablePills
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Use `enable_pill_reorder: true` with `show_pill_index: true` to let users drag selected multi-select pills into a new order. By default, each pill shows a grip icon and can be dragged from anywhere on the pill. Set `external_drag_handle: true` to use an external grip handle instead (drag only from the handle).
|
|
2
|
+
|
|
3
|
+
While dragging, pills stay in place, a ghost follows the pointer, and a blue line marks where the pill will land. Order is committed on drop.
|
|
4
|
+
|
|
5
|
+
The `pb:dropdown:reordered` custom event receives the reordered value array. Submitted form values (hidden inputs) preserve the new order. `pb:dropdown:selected` also fires with the updated order.
|
|
6
|
+
|
|
7
|
+
Keyboard reorder: focus a pill, then press ArrowLeft or ArrowRight to move it one position.
|
|
8
|
+
|
|
9
|
+
Works with Multi-Select and Multi-Select + Autocomplete Dropdown variants only, and is disabled by default.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Use `enablePillReorder` to let users drag selected multi-select pills into a new order. Pair with `showPillIndex` to display numbered prefixes that update automatically after reorder or removal.
|
|
2
|
+
|
|
3
|
+
By default, each pill shows a grip icon and can be dragged from anywhere on the pill. Set `externalDragHandle` to `true` to use an external grip handle instead (drag only from the handle).
|
|
4
|
+
|
|
5
|
+
While dragging, pills stay in place, a ghost follows the pointer, and a blue line marks where the pill will land. Order is committed on drop. The `onChange` callback receives the reordered value array.
|
|
6
|
+
|
|
7
|
+
Keyboard reorder: focus a pill, then press ArrowLeft or ArrowRight to move it one position.
|
|
8
|
+
|
|
9
|
+
Works with Multi-Select and Multi-Select + Autocomplete. Dropdown variants only, and is disabled by default.
|