playbook_ui 14.24.0.pre.rc.1 → 14.24.0.pre.rc.3
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/Components/CustomCell.tsx +7 -6
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +10 -10
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +53 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +9 -6
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +12 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +16 -0
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +7 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -2
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +17 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +6 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown_mixin.scss +36 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_active_style_options.jsx +90 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_active_style_options_react.md +4 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.jsx +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_react.md +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +24 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +11 -1
- data/app/pb_kits/playbook/pb_select/select.rb +4 -2
- data/dist/chunks/{_weekday_stacked-C16ua8Si.js → _weekday_stacked-DknbEzxo.js} +2 -2
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1b614d21917603d1c708b5fa2ae0a5979c59f8585775f530f5ad6d46466a137
|
4
|
+
data.tar.gz: bd3feccefc93d4eba14bafdadff62e3f4c8dfaf54838558baf848db18391570b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be0d1b4a2c260b6bf92c7a2f844a7f82bdd4386410a30431ebb0088a16fdd15db75b2e8ca76136795ddc346f9f928f5c383616545b50d388bc3d28b9b3646155
|
7
|
+
data.tar.gz: 41c468c85039f785d31d85bb9ae13acc223cf704769a47bfb079177df31b2ab96d8146f1b00373c2fe93e338d32edd24a2a7510746b0dad0424308059579ddac
|
@@ -20,7 +20,7 @@ interface CustomCellProps {
|
|
20
20
|
customRenderer?: (row: Row<GenericObject>, value: string | undefined) => React.ReactNode
|
21
21
|
selectableRows?: boolean
|
22
22
|
customStyle?: GenericObject
|
23
|
-
}
|
23
|
+
}
|
24
24
|
|
25
25
|
export const CustomCell = ({
|
26
26
|
getValue,
|
@@ -35,7 +35,7 @@ export const CustomCell = ({
|
|
35
35
|
|
36
36
|
const handleOnExpand = (row: Row<GenericObject>) => {
|
37
37
|
onRowToggleClick && onRowToggleClick(row);
|
38
|
-
|
38
|
+
|
39
39
|
if (!expandedControl) {
|
40
40
|
setExpanded({ ...expanded, [row.id]: !row.getIsExpanded() });
|
41
41
|
}
|
@@ -46,8 +46,8 @@ export const CustomCell = ({
|
|
46
46
|
|
47
47
|
return (
|
48
48
|
<div style={{ paddingLeft: `${row.depth * 1.25}em`}}>
|
49
|
-
<Flex
|
50
|
-
alignItems="center"
|
49
|
+
<Flex
|
50
|
+
alignItems="center"
|
51
51
|
columnGap="xs"
|
52
52
|
justify="start"
|
53
53
|
orientation="row"
|
@@ -71,11 +71,12 @@ export const CustomCell = ({
|
|
71
71
|
>
|
72
72
|
{row.getIsExpanded() ? (
|
73
73
|
<Icon cursor="pointer"
|
74
|
-
icon="circle-play
|
74
|
+
icon="circle-play"
|
75
|
+
rotation={90}
|
75
76
|
/>
|
76
77
|
) : (
|
77
78
|
<Icon cursor="pointer"
|
78
|
-
icon="circle-play"
|
79
|
+
icon="circle-play"
|
79
80
|
/>
|
80
81
|
)}
|
81
82
|
</button>
|
@@ -112,7 +112,7 @@ const TableActionBar: React.FC<TableActionBarProps> = ({
|
|
112
112
|
paddingBottom="xs"
|
113
113
|
text={node.label}
|
114
114
|
/>
|
115
|
-
<Flex flexDirection="column"
|
115
|
+
<Flex flexDirection="column"
|
116
116
|
paddingLeft="lg"
|
117
117
|
>
|
118
118
|
{node?.children?.map((child) =>
|
@@ -141,8 +141,8 @@ const TableActionBar: React.FC<TableActionBarProps> = ({
|
|
141
141
|
setShowPopover(!shouldClose)
|
142
142
|
|
143
143
|
const popoverReference = (
|
144
|
-
<Tooltip
|
145
|
-
placement="top"
|
144
|
+
<Tooltip
|
145
|
+
placement="top"
|
146
146
|
text="Column Configuration"
|
147
147
|
>
|
148
148
|
<div onClick={togglePopover}>
|
@@ -170,8 +170,8 @@ const TableActionBar: React.FC<TableActionBarProps> = ({
|
|
170
170
|
>
|
171
171
|
{type === "row-selection" ? (
|
172
172
|
<>
|
173
|
-
<Caption color="light"
|
174
|
-
paddingLeft="xs"
|
173
|
+
<Caption color="light"
|
174
|
+
paddingLeft="xs"
|
175
175
|
size="xs"
|
176
176
|
>
|
177
177
|
{selectedCount} Selected
|
@@ -188,15 +188,15 @@ const TableActionBar: React.FC<TableActionBarProps> = ({
|
|
188
188
|
zIndex={3}
|
189
189
|
>
|
190
190
|
<>
|
191
|
-
<Caption
|
192
|
-
paddingY="sm"
|
191
|
+
<Caption
|
192
|
+
paddingY="sm"
|
193
193
|
text="Columns Config"
|
194
|
-
textAlign="center"
|
194
|
+
textAlign="center"
|
195
195
|
/>
|
196
196
|
<SectionSeparator paddingBottom="xs" />
|
197
197
|
{tree.map((node: VisibilityNode) => (
|
198
|
-
<Flex cursor="pointer"
|
199
|
-
flexDirection="column"
|
198
|
+
<Flex cursor="pointer"
|
199
|
+
flexDirection="column"
|
200
200
|
key={node.id}
|
201
201
|
paddingX="xs"
|
202
202
|
>
|
@@ -124,13 +124,65 @@
|
|
124
124
|
-ms-overflow-style: none !important;
|
125
125
|
scrollbar-width: none !important;
|
126
126
|
}
|
127
|
-
|
127
|
+
|
128
|
+
// When action bar is hidden, ensure proper border radius for header corners
|
129
|
+
&.hidden-action-bar {
|
130
|
+
.pb_advanced_table_header {
|
131
|
+
> tr:first-child {
|
132
|
+
th:first-child {
|
133
|
+
border-top-left-radius: 4px !important;
|
134
|
+
}
|
135
|
+
th:last-child {
|
136
|
+
border-top-right-radius: 4px !important;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
// Also handle the case when there are multiple header rows
|
142
|
+
.pb_advanced_table_header {
|
143
|
+
> tr:first-child {
|
144
|
+
th:first-child,
|
145
|
+
.table-header-cells:first-child,
|
146
|
+
.table-header-cells-custom:first-child {
|
147
|
+
border-top-left-radius: 4px !important;
|
148
|
+
}
|
149
|
+
th:last-child,
|
150
|
+
.table-header-cells:last-child,
|
151
|
+
.table-header-cells-custom:last-child {
|
152
|
+
border-top-right-radius: 4px !important;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
// When action bar is shown, remove border radius from header
|
159
|
+
.row-selection-actions-card.is-visible ~ * .pb_advanced_table_header,
|
160
|
+
.row-selection-actions-card.show-action-card ~ * .pb_advanced_table_header {
|
161
|
+
> tr:first-child {
|
162
|
+
th:first-child,
|
163
|
+
th:last-child,
|
164
|
+
.table-header-cells:first-child,
|
165
|
+
.table-header-cells:last-child,
|
166
|
+
.table-header-cells-custom:first-child,
|
167
|
+
.table-header-cells-custom:last-child {
|
168
|
+
border-top-left-radius: 0 !important;
|
169
|
+
border-top-right-radius: 0 !important;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
128
174
|
|
129
175
|
.row-selection-actions-card {
|
130
176
|
border-bottom-right-radius: 0px !important;
|
131
177
|
border-bottom-left-radius: 0px !important;
|
132
178
|
border-bottom-color: transparent;
|
133
179
|
transition: height 300ms ease;
|
180
|
+
|
181
|
+
&.is-visible,
|
182
|
+
&.show-action-card {
|
183
|
+
border-top-left-radius: 4px !important;
|
184
|
+
border-top-right-radius: 4px !important;
|
185
|
+
}
|
134
186
|
}
|
135
187
|
.table-header-cells:first-child {
|
136
188
|
min-width: 180px;
|
@@ -218,10 +218,10 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
218
218
|
)
|
219
219
|
|
220
220
|
return (
|
221
|
-
<Card
|
221
|
+
<Card
|
222
222
|
borderNone
|
223
223
|
borderRadius="none"
|
224
|
-
className="advanced-table-fullscreen-header"
|
224
|
+
className="advanced-table-fullscreen-header"
|
225
225
|
{...props}
|
226
226
|
>
|
227
227
|
<Flex justify="end">
|
@@ -250,6 +250,10 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
250
250
|
const ariaProps = buildAriaProps(aria);
|
251
251
|
const dataProps = buildDataProps(data);
|
252
252
|
const htmlProps = buildHtmlProps(htmlOptions);
|
253
|
+
|
254
|
+
// Visibility flag for action bar
|
255
|
+
const isActionBarVisible = (selectableRows && showActionsBar && selectedRowsLength > 0) || columnVisibilityControl;
|
256
|
+
|
253
257
|
const classes = classnames(
|
254
258
|
buildCss("pb_advanced_table"),
|
255
259
|
`advanced-table-responsive-${responsive}`,
|
@@ -257,6 +261,8 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
257
261
|
{
|
258
262
|
'advanced-table-fullscreen': isFullscreen,
|
259
263
|
'advanced-table-allow-fullscreen': allowFullScreen,
|
264
|
+
// Add the hidden-action-bar class when action bar functionality exists but is not visible
|
265
|
+
'hidden-action-bar': (selectableRows || columnVisibilityControl) && !isActionBarVisible,
|
260
266
|
},
|
261
267
|
{'advanced-table-sticky-left-columns': stickyLeftColumn && stickyLeftColumn.length > 0},
|
262
268
|
columnGroupBorderColor ? `column-group-border-${columnGroupBorderColor}` : '',
|
@@ -270,9 +276,6 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
270
276
|
? getVirtualizedContainerStyles(maxHeight)
|
271
277
|
: {};
|
272
278
|
|
273
|
-
// Visibility flag for action bar
|
274
|
-
const isActionBarVisible = (selectableRows && showActionsBar && selectedRowsLength > 0) || columnVisibilityControl;
|
275
|
-
|
276
279
|
// The actual Main <Table /> element
|
277
280
|
const tableElement = (
|
278
281
|
<Table
|
@@ -288,7 +291,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
288
291
|
) : (
|
289
292
|
<>
|
290
293
|
<TableHeader />
|
291
|
-
<TableBody
|
294
|
+
<TableBody
|
292
295
|
isFetching={isFetching}
|
293
296
|
/>
|
294
297
|
</>
|
@@ -35,7 +35,12 @@ module Playbook
|
|
35
35
|
default: []
|
36
36
|
|
37
37
|
def classname
|
38
|
-
additional_classes = [
|
38
|
+
additional_classes = [
|
39
|
+
responsive_classname,
|
40
|
+
max_height_classname,
|
41
|
+
hide_scroll_bar_class,
|
42
|
+
hidden_action_bar_class,
|
43
|
+
]
|
39
44
|
additional_classes << "column-group-border-#{column_group_border_color}" if column_group_border_color != "none"
|
40
45
|
generate_classname("pb_advanced_table", *additional_classes, separator: " ")
|
41
46
|
end
|
@@ -49,7 +54,12 @@ module Playbook
|
|
49
54
|
end
|
50
55
|
|
51
56
|
def hide_scroll_bar_class
|
52
|
-
scroll_bar_none ? "advanced-table-hide-scrollbar
|
57
|
+
scroll_bar_none ? "advanced-table-hide-scrollbar" : ""
|
58
|
+
end
|
59
|
+
|
60
|
+
def hidden_action_bar_class
|
61
|
+
# Add hidden-action-bar class when action bar functionality is enabled but not currently visible
|
62
|
+
selectable_rows && !is_action_bar_visible ? "hidden-action-bar" : ""
|
53
63
|
end
|
54
64
|
|
55
65
|
def selected_rows
|
@@ -1,4 +1,7 @@
|
|
1
1
|
function showActionBar(actionBar, selectedCount) {
|
2
|
+
// Get container
|
3
|
+
const tableContainer = actionBar.closest('.pb_advanced_table');
|
4
|
+
|
2
5
|
// Show action bar directly
|
3
6
|
actionBar.style.height = "auto";
|
4
7
|
actionBar.style.overflow = "visible";
|
@@ -8,6 +11,11 @@ function showActionBar(actionBar, selectedCount) {
|
|
8
11
|
actionBar.classList.remove("p_none");
|
9
12
|
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
10
13
|
|
14
|
+
// Remove hidden-action-bar class when action bar is shown
|
15
|
+
if (tableContainer) {
|
16
|
+
tableContainer.classList.remove("hidden-action-bar");
|
17
|
+
}
|
18
|
+
|
11
19
|
// Update the count
|
12
20
|
const countElement = actionBar.querySelector(".selected-count");
|
13
21
|
if (countElement) {
|
@@ -16,12 +24,20 @@ function showActionBar(actionBar, selectedCount) {
|
|
16
24
|
}
|
17
25
|
|
18
26
|
function hideActionBar(actionBar) {
|
27
|
+
// Get container
|
28
|
+
const tableContainer = actionBar.closest('.pb_advanced_table');
|
29
|
+
|
19
30
|
// Hide action bar directly
|
20
31
|
actionBar.style.height = "0px";
|
21
32
|
actionBar.style.overflow = "hidden";
|
22
33
|
actionBar.style.opacity = "0";
|
23
34
|
actionBar.classList.add("p_none");
|
24
35
|
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
36
|
+
|
37
|
+
// Add hidden-action-bar class when action bar is hidden
|
38
|
+
if (tableContainer) {
|
39
|
+
tableContainer.classList.add("hidden-action-bar");
|
40
|
+
}
|
25
41
|
}
|
26
42
|
|
27
43
|
export function updateSelectionActionBar(table, selectedCount) {
|
@@ -79,8 +79,14 @@
|
|
79
79
|
left: 0;
|
80
80
|
border-radius: unset;
|
81
81
|
z-index: 5;
|
82
|
-
}
|
83
82
|
|
83
|
+
// Add proper border radius when action bar is visible
|
84
|
+
&.is-visible,
|
85
|
+
&.show-action-card {
|
86
|
+
border-top-left-radius: 4px !important;
|
87
|
+
border-top-right-radius: 4px !important;
|
88
|
+
}
|
89
|
+
}
|
84
90
|
.checkbox-cell {
|
85
91
|
display: table-cell !important;
|
86
92
|
}
|
@@ -39,11 +39,11 @@
|
|
39
39
|
style="color: <%= button_color %>"
|
40
40
|
>
|
41
41
|
<%= pb_rails("icon", props: { id: "advanced-table_open_icon", icon: "circle-play", cursor: "pointer" }) %>
|
42
|
-
<%= pb_rails("icon", props: { id: "advanced-table_close_icon", icon: "circle-play
|
42
|
+
<%= pb_rails("icon", props: { id: "advanced-table_close_icon", icon: "circle-play", cursor: "pointer", rotation: 90 }) %>
|
43
43
|
</button>
|
44
44
|
<% end %>
|
45
45
|
<% end %>
|
46
|
-
<%= pb_rails("flex/flex_item") do %>
|
46
|
+
<%= pb_rails("flex/flex_item") do %>
|
47
47
|
<% if column[:custom_renderer].present? %>
|
48
48
|
<%= raw(column[:custom_renderer].call(object.row, custom_renderer_value(column, index))) %>
|
49
49
|
<% elsif index.zero? %>
|
@@ -8,6 +8,7 @@
|
|
8
8
|
@import "../pb_textarea/textarea_mixin";
|
9
9
|
|
10
10
|
@import "./scss_partials/dropdown_animation";
|
11
|
+
@import "dropdown_mixin";
|
11
12
|
|
12
13
|
[class*="pb_dropdown"] {
|
13
14
|
.dropdown_wrapper {
|
@@ -98,9 +99,23 @@
|
|
98
99
|
[class^="pb_title_kit"], a {
|
99
100
|
color: $white !important;
|
100
101
|
}
|
102
|
+
border-bottom: 1px solid $border_light;
|
101
103
|
&:hover {
|
102
|
-
background-color: $product_1_background
|
104
|
+
background-color: $product_1_background;
|
105
|
+
}
|
106
|
+
|
107
|
+
// activeStyle font color map
|
108
|
+
@each $name, $color in $font-colors {
|
109
|
+
&.font-#{$name} {
|
110
|
+
@include apply-font-color($color);
|
111
|
+
}
|
103
112
|
}
|
113
|
+
// activeStyle background color map (no difference between selected and selected+hover custom colors)
|
114
|
+
@each $name, $bg in $background-colors {
|
115
|
+
&.bg-#{$name} {
|
116
|
+
background-color: $bg;
|
117
|
+
}
|
118
|
+
}
|
104
119
|
}
|
105
120
|
}
|
106
121
|
|
@@ -267,6 +282,7 @@
|
|
267
282
|
}
|
268
283
|
&[class*="selected"] {
|
269
284
|
background-color: $primary;
|
285
|
+
border-bottom: rgba($white, 0.15);
|
270
286
|
}
|
271
287
|
}
|
272
288
|
}
|
@@ -39,6 +39,10 @@ type DropdownProps = {
|
|
39
39
|
options: GenericObject;
|
40
40
|
separators?: boolean;
|
41
41
|
variant?: "default" | "subtle";
|
42
|
+
activeStyle?: {
|
43
|
+
backgroundColor?: string;
|
44
|
+
fontColor?: string;
|
45
|
+
};
|
42
46
|
};
|
43
47
|
|
44
48
|
interface DropdownComponent
|
@@ -69,6 +73,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
69
73
|
options,
|
70
74
|
separators = true,
|
71
75
|
variant = "default",
|
76
|
+
activeStyle,
|
72
77
|
} = props;
|
73
78
|
|
74
79
|
const ariaProps = buildAriaProps(aria);
|
@@ -251,6 +256,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
251
256
|
>
|
252
257
|
<DropdownContext.Provider
|
253
258
|
value={{
|
259
|
+
activeStyle,
|
254
260
|
autocomplete,
|
255
261
|
dropdownContainerRef,
|
256
262
|
filteredOptions,
|
@@ -0,0 +1,36 @@
|
|
1
|
+
@import "../tokens/colors";
|
2
|
+
|
3
|
+
// activeStyle fontColor sass map to go through text colors + set of custom colors
|
4
|
+
$custom-font-colors: (
|
5
|
+
primary: $primary
|
6
|
+
);
|
7
|
+
|
8
|
+
$merged-font-colors: map-merge($text_colors, $custom-font-colors);
|
9
|
+
|
10
|
+
$font-colors: ();
|
11
|
+
|
12
|
+
@each $key, $val in $merged-font-colors {
|
13
|
+
$font-colors: map-merge($font-colors, ($key: $val));
|
14
|
+
}
|
15
|
+
|
16
|
+
@mixin apply-font-color($color) {
|
17
|
+
color: $color;
|
18
|
+
|
19
|
+
[class^="pb_body"],
|
20
|
+
[class^="pb_title_kit"],
|
21
|
+
a {
|
22
|
+
color: $color !important;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
// activeStyle backgroundColor map (set of custom colors)
|
27
|
+
$custom-background-colors: (
|
28
|
+
"bg_light": $bg_light,
|
29
|
+
"white": $white,
|
30
|
+
);
|
31
|
+
|
32
|
+
$background-colors: ();
|
33
|
+
|
34
|
+
@each $key, $val in $custom-background-colors {
|
35
|
+
$background-colors: map-merge($background-colors, ($key: $val));
|
36
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Dropdown from '../_dropdown'
|
3
|
+
|
4
|
+
const DropdownCustomActiveStyleOptions = (props) => {
|
5
|
+
|
6
|
+
|
7
|
+
const options = [
|
8
|
+
{
|
9
|
+
label: "United States",
|
10
|
+
value: "unitedStates",
|
11
|
+
id: "us"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
label: "Canada",
|
15
|
+
value: "canada",
|
16
|
+
id: "ca"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
label: "Pakistan",
|
20
|
+
value: "pakistan",
|
21
|
+
id: "pk"
|
22
|
+
}
|
23
|
+
];
|
24
|
+
|
25
|
+
|
26
|
+
return (
|
27
|
+
<div>
|
28
|
+
<Dropdown
|
29
|
+
activeStyle={{
|
30
|
+
backgroundColor: "bg_light",
|
31
|
+
fontColor: "primary",
|
32
|
+
}}
|
33
|
+
label="Background Color: bg_light; Font Color: primary"
|
34
|
+
marginBottom="sm"
|
35
|
+
options={options}
|
36
|
+
{...props}
|
37
|
+
>
|
38
|
+
<Dropdown.Trigger/>
|
39
|
+
<Dropdown.Container>
|
40
|
+
{options.map((option) => (
|
41
|
+
<Dropdown.Option key={option.id}
|
42
|
+
option={option}
|
43
|
+
/>
|
44
|
+
))}
|
45
|
+
</Dropdown.Container>
|
46
|
+
</Dropdown>
|
47
|
+
<Dropdown
|
48
|
+
activeStyle={{
|
49
|
+
backgroundColor: "white",
|
50
|
+
fontColor: "primary",
|
51
|
+
}}
|
52
|
+
label="Background Color: white; Font Color: primary"
|
53
|
+
marginBottom="sm"
|
54
|
+
options={options}
|
55
|
+
{...props}
|
56
|
+
/>
|
57
|
+
<Dropdown
|
58
|
+
activeStyle={{
|
59
|
+
backgroundColor: "bg_light",
|
60
|
+
fontColor: "text_lt_default",
|
61
|
+
}}
|
62
|
+
autocomplete
|
63
|
+
label="Background Color: bg_light; Font Color: text_lt_default"
|
64
|
+
marginBottom="sm"
|
65
|
+
options={options}
|
66
|
+
{...props}
|
67
|
+
/>
|
68
|
+
<Dropdown
|
69
|
+
activeStyle={{
|
70
|
+
fontColor: "text_lt_lighter",
|
71
|
+
}}
|
72
|
+
label="Font Color: text_lt_lighter"
|
73
|
+
marginBottom="sm"
|
74
|
+
options={options}
|
75
|
+
{...props}
|
76
|
+
>
|
77
|
+
<Dropdown.Trigger/>
|
78
|
+
<Dropdown.Container>
|
79
|
+
{options.map((option) => (
|
80
|
+
<Dropdown.Option key={option.id}
|
81
|
+
option={option}
|
82
|
+
/>
|
83
|
+
))}
|
84
|
+
</Dropdown.Container>
|
85
|
+
</Dropdown>
|
86
|
+
</div>
|
87
|
+
)
|
88
|
+
}
|
89
|
+
|
90
|
+
export default DropdownCustomActiveStyleOptions
|
data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_active_style_options_react.md
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
The `activeStyle` prop can be used to customize the appearance of the dropdown selection indicator. It accepts an object with the following keys: `backgroundColor` sets the background color of the selected item (and its hover state); `fontColor` sets the font color of the selected item.
|
2
|
+
|
3
|
+
`backgroundColor` **Type**: String | **Values**: bg_light | white | **Default**: (no selection) is primary
|
4
|
+
`fontColor` **Type**: String | **Values**: primary | all [Playbook Text Colors](https://playbook.powerapp.cloud/visual_guidelines/colors) | **Default**: (no selection) is white
|
@@ -18,6 +18,7 @@ const DropdownCustomRadioOptions = (props) => {
|
|
18
18
|
return (
|
19
19
|
<div>
|
20
20
|
<Dropdown
|
21
|
+
activeStyle={{ backgroundColor: "bg_light", fontColor: "text_lt_default" }}
|
21
22
|
label="Select Item"
|
22
23
|
onSelect={(selectedItem) => setSelectedValue(selectedItem?.value)}
|
23
24
|
options={options}
|
@@ -1 +1 @@
|
|
1
|
-
Radio inputs can be used inside `Dropdown.Option` for a custom layout that mimics form-like selection within a dropdown.
|
1
|
+
Radio inputs can be used inside `Dropdown.Option` for a custom layout that mimics form-like selection within a dropdown. Use the [activeStyle](https://playbook.powerapp.cloud/kits/dropdown/react#custom-active-style-options) `backgroundColor` and `fontColor` props to create contrast between the Radio selection indicator and the Dropdown selection background indicator.
|
@@ -16,7 +16,7 @@ examples:
|
|
16
16
|
- dropdown_with_search_rails: Custom Trigger Dropdown with Search
|
17
17
|
- dropdown_with_custom_padding: Custom Option Padding
|
18
18
|
- dropdown_with_custom_icon_options: Custom Icon Options
|
19
|
-
# - dropdown_with_custom_radio_options: Custom Radio Options # TODO: Update and publish doc ex in [PLAY-2146](https://runway.powerhrg.com/backlog_items/PLAY-2146) (remove this comment afterwards)
|
19
|
+
# - dropdown_with_custom_radio_options: Custom Radio Options # TODO: Update and publish doc ex in the Rails follow up to [PLAY-2146](https://runway.powerhrg.com/backlog_items/PLAY-2146) (remove this comment afterwards)
|
20
20
|
- dropdown_error: Dropdown with Error
|
21
21
|
- dropdown_default_value: Default Value
|
22
22
|
- dropdown_multi_select_with_default: Multi Select Default Value
|
@@ -39,8 +39,9 @@ examples:
|
|
39
39
|
- dropdown_with_custom_trigger: Custom Trigger
|
40
40
|
- dropdown_with_search: Custom Trigger Dropdown with Search
|
41
41
|
- dropdown_with_custom_padding: Custom Option Padding
|
42
|
+
- dropdown_with_custom_active_style_options: Custom Active Style Options
|
42
43
|
- dropdown_with_custom_icon_options: Custom Icon Options
|
43
|
-
|
44
|
+
- dropdown_with_custom_radio_options: Custom Radio Options
|
44
45
|
- dropdown_error: Dropdown with Error
|
45
46
|
- dropdown_default_value: Default Value
|
46
47
|
- dropdown_multi_select_with_default: Multi Select Default Value
|
@@ -21,4 +21,5 @@ export { default as DropdownMultiSelectWithAutocomplete } from './_dropdown_mult
|
|
21
21
|
export { default as DropdownMultiSelectWithDefault } from './_dropdown_multi_select_with_default.jsx'
|
22
22
|
export { default as DropdownMultiSelectWithCustomOptions } from './_dropdown_multi_select_with_custom_options.jsx'
|
23
23
|
export {default as DropdownWithCustomIconOptions} from './_dropdown_with_custom_icon_options.jsx'
|
24
|
-
export {default as DropdownWithCustomRadioOptions} from './_dropdown_with_custom_radio_options.jsx'
|
24
|
+
export {default as DropdownWithCustomRadioOptions} from './_dropdown_with_custom_radio_options.jsx'
|
25
|
+
export {default as DropdownWithCustomActiveStyleOptions} from './_dropdown_with_custom_active_style_options.jsx'
|
@@ -369,4 +369,28 @@ test("defaultValue works with multiSelect", () => {
|
|
369
369
|
const option2 = Array.from(kit.querySelectorAll(".pb_dropdown_option_list"));
|
370
370
|
const firstOpt = options[0].label
|
371
371
|
expect(option2[0]).not.toHaveTextContent(firstOpt)
|
372
|
+
})
|
373
|
+
|
374
|
+
test("applies activeStyle backgroundColor and fontColor when selected", () => {
|
375
|
+
render(
|
376
|
+
<Dropdown
|
377
|
+
activeStyle={{
|
378
|
+
backgroundColor: "bg_light",
|
379
|
+
fontColor: "primary",
|
380
|
+
}}
|
381
|
+
data={{ testid: testId }}
|
382
|
+
options={options}
|
383
|
+
/>
|
384
|
+
)
|
385
|
+
|
386
|
+
const kit = screen.getByTestId(testId)
|
387
|
+
const option = kit.querySelectorAll(".pb_dropdown_option_list")[1]
|
388
|
+
|
389
|
+
fireEvent.click(option)
|
390
|
+
|
391
|
+
const selected = kit.querySelector(".pb_dropdown_option_selected")
|
392
|
+
|
393
|
+
expect(selected).toBeInTheDocument()
|
394
|
+
expect(selected).toHaveClass("bg-bg_light")
|
395
|
+
expect(selected).toHaveClass("font-primary")
|
372
396
|
})
|
@@ -41,6 +41,7 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
41
41
|
} = props;
|
42
42
|
|
43
43
|
const {
|
44
|
+
activeStyle,
|
44
45
|
filteredOptions,
|
45
46
|
filterItem,
|
46
47
|
focusedOptionIndex,
|
@@ -59,7 +60,6 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
59
60
|
? selected.some((item) => item.label === option?.label)
|
60
61
|
: (selected as GenericObject)?.label === option?.label;
|
61
62
|
|
62
|
-
|
63
63
|
if (!isItemMatchingFilter(option) || (multiSelect && isSelected)) {
|
64
64
|
return null;
|
65
65
|
}
|
@@ -70,6 +70,14 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
70
70
|
|
71
71
|
const selectedClass = isSelected ? "selected" : "list";
|
72
72
|
|
73
|
+
|
74
|
+
const bgTokenClass = activeStyle?.backgroundColor
|
75
|
+
? `bg-${activeStyle.backgroundColor}`
|
76
|
+
: "";
|
77
|
+
const fontTokenClass = activeStyle?.fontColor
|
78
|
+
? `font-${activeStyle.fontColor}`
|
79
|
+
: "";
|
80
|
+
|
73
81
|
const ariaProps = buildAriaProps(aria);
|
74
82
|
const dataProps = buildDataProps(data);
|
75
83
|
const htmlProps = buildHtmlProps(htmlOptions);
|
@@ -79,6 +87,8 @@ const DropdownOption = (props: DropdownOptionProps) => {
|
|
79
87
|
selectedClass,
|
80
88
|
focusedClass,
|
81
89
|
),
|
90
|
+
bgTokenClass,
|
91
|
+
fontTokenClass,
|
82
92
|
globalProps(props),
|
83
93
|
className
|
84
94
|
);
|
@@ -24,7 +24,9 @@ module Playbook
|
|
24
24
|
prop :validation_message, type: Playbook::Props::String, default: ""
|
25
25
|
|
26
26
|
def classnames
|
27
|
-
classname + inline_class
|
27
|
+
([classname] + [inline_class, compact_class, show_arrow_class])
|
28
|
+
.reject(&:empty?)
|
29
|
+
.join(" ")
|
28
30
|
end
|
29
31
|
|
30
32
|
def all_attributes
|
@@ -44,7 +46,7 @@ module Playbook
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def inline_class
|
47
|
-
inline ? "
|
49
|
+
inline ? "inline" : ""
|
48
50
|
end
|
49
51
|
|
50
52
|
def compact_class
|