playbook_ui 14.15.0.pre.rc.4 → 14.15.0
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/RegularTableView.tsx +127 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +55 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TablePagination.tsx +33 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +275 -0
- data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +143 -3
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +66 -0
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +195 -0
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +45 -99
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +73 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +52 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/TableContainerStyles.ts +80 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +123 -7
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +153 -299
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_infinite_scroll.jsx +50 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_mock_data_infinite_scroll.json +152002 -0
- data/app/pb_kits/playbook/pb_card/_card.tsx +2 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +4 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -0
- data/app/pb_kits/playbook/pb_date_picker/index.ts +38 -0
- data/app/pb_kits/playbook/pb_drawer/_drawer.scss +19 -3
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.jsx +3 -3
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.jsx +20 -37
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.jsx +6 -6
- data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.jsx +1 -0
- data/app/pb_kits/playbook/pb_drawer/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +5 -4
- data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +2 -2
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +9 -2
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +4 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.html.erb +40 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.jsx +50 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.md +3 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_form_pill/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +7 -1
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +13 -3
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +72 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +91 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +2 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +6 -0
- data/app/pb_kits/playbook/pb_popover/_popover.tsx +1 -1
- data/app/pb_kits/playbook/pb_radio/_radio.tsx +85 -74
- data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.jsx +60 -0
- data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.md +1 -0
- data/app/pb_kits/playbook/pb_radio/docs/example.yml +2 -1
- data/app/pb_kits/playbook/pb_radio/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_radio/radio.test.js +16 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.jsx +58 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.md +1 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_select/select.html.erb +3 -5
- data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
- data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
- data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
- data/app/pb_kits/playbook/pb_timeline/_timeline.scss +2 -2
- data/app/pb_kits/playbook/pb_title/_title.scss +32 -0
- data/app/pb_kits/playbook/pb_title/_title.tsx +10 -1
- data/app/pb_kits/playbook/pb_title/docs/_title_default.html.erb +1 -2
- data/app/pb_kits/playbook/pb_title/docs/_title_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_title/docs/_title_display_size.html.erb +7 -0
- data/app/pb_kits/playbook/pb_title/docs/_title_display_size.jsx +54 -0
- data/app/pb_kits/playbook/pb_title/docs/_title_display_size.md +1 -0
- data/app/pb_kits/playbook/pb_title/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_title/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_title/title.rb +10 -1
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +25 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.jsx +69 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.md +3 -0
- data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +1 -1
- data/app/pb_kits/playbook/pb_tooltip/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +2 -1
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +5 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +4 -1
- data/app/pb_kits/playbook/utilities/object.test.js +99 -0
- data/app/pb_kits/playbook/utilities/object.ts +29 -1
- data/dist/chunks/_typeahead-BhfaW1J9.js +36 -0
- data/dist/chunks/_weekday_stacked-CKRIELiF.js +45 -0
- data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
- data/dist/chunks/{lib-Dmay5Z6U.js → lib-5OzNgeeu.js} +2 -2
- data/dist/chunks/{pb_form_validation-DdP7BnVX.js → pb_form_validation-DGhKbZtO.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +34 -7
- data/dist/chunks/_typeahead-NXKDTf__.js +0 -36
- data/dist/chunks/_weekday_stacked-DtCYkCXM.js +0 -45
- data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
@@ -243,7 +243,7 @@ $gap_lg: $height_from_top + $space_lg;
|
|
243
243
|
}
|
244
244
|
[class=pb_timeline_item_left_block] {
|
245
245
|
margin-bottom: $space_lg;
|
246
|
-
width: $space_lg;
|
246
|
+
min-width: $space_lg;
|
247
247
|
}
|
248
248
|
[class=pb_timeline_item_right_block] {
|
249
249
|
@include flex_wrapper(column);
|
@@ -263,7 +263,7 @@ $gap_lg: $height_from_top + $space_lg;
|
|
263
263
|
}
|
264
264
|
[class=pb_timeline_item_left_block] {
|
265
265
|
margin-bottom: $space_lg;
|
266
|
-
width: $space_lg;
|
266
|
+
min-width: $space_lg;
|
267
267
|
}
|
268
268
|
[class=pb_timeline_item_right_block] {
|
269
269
|
@include flex_wrapper(column);
|
@@ -31,6 +31,38 @@
|
|
31
31
|
@include pb_title_thin;
|
32
32
|
}
|
33
33
|
|
34
|
+
&[class*=_display] {
|
35
|
+
font-size: clamp(24px, calc(1.25vw + 5.3vw), 128px);
|
36
|
+
}
|
37
|
+
|
38
|
+
&[class*=_dynamic] {
|
39
|
+
&[class*=_xs] {
|
40
|
+
font-size: min(2vw, 80vw / 16);
|
41
|
+
}
|
42
|
+
|
43
|
+
&[class*=_sm] {
|
44
|
+
font-size: min(2.5vw, 96vw / 16);
|
45
|
+
}
|
46
|
+
|
47
|
+
&[class*=_md] {
|
48
|
+
font-size: min(4vw, 160vw / 16);
|
49
|
+
}
|
50
|
+
|
51
|
+
&[class*=_lg] {
|
52
|
+
font-size: min(5vw, 192vw / 16);
|
53
|
+
}
|
54
|
+
|
55
|
+
&[class*=_xl] {
|
56
|
+
font-size: min(6vw, 224vw / 16);
|
57
|
+
}
|
58
|
+
|
59
|
+
&[class*=_xxl] {
|
60
|
+
font-size: min(8vw, 256vw / 16);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
|
34
66
|
@each $size, $size_value in $breakpoints_grid {
|
35
67
|
@for $title_size_value from 1 through 4 {
|
36
68
|
$min_size: map-get($size_value, "min");
|
@@ -3,7 +3,7 @@ import classnames from 'classnames'
|
|
3
3
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
4
4
|
import { deprecatedProps, GlobalProps, globalProps } from '../utilities/globalProps'
|
5
5
|
|
6
|
-
type SizeType = 1 | 2 | 3 | 4 | "1" | "2" | "3" | "4"
|
6
|
+
type SizeType = 1 | 2 | 3 | 4 | "1" | "2" | "3" | "4" | "display"
|
7
7
|
type SizeResponsiveType = {[key: string]: SizeType}
|
8
8
|
|
9
9
|
type TitleProps = {
|
@@ -16,6 +16,7 @@ type TitleProps = {
|
|
16
16
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
17
17
|
id?: string,
|
18
18
|
size?: SizeType | SizeResponsiveType,
|
19
|
+
displaySize?: null | "xs" | "sm" | "md" | "lg" | "xl" | "xxl",
|
19
20
|
tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div" | "span",
|
20
21
|
text?: string,
|
21
22
|
variant?: null | "link",
|
@@ -32,6 +33,7 @@ const Title = (props: TitleProps): React.ReactElement => {
|
|
32
33
|
htmlOptions = {},
|
33
34
|
id,
|
34
35
|
size = 3,
|
36
|
+
displaySize = null,
|
35
37
|
bold = true,
|
36
38
|
tag = 'h3',
|
37
39
|
text,
|
@@ -56,9 +58,16 @@ const Title = (props: TitleProps): React.ReactElement => {
|
|
56
58
|
return css.trim()
|
57
59
|
}
|
58
60
|
|
61
|
+
const buildDisplaySize = () => {
|
62
|
+
if (displaySize) {
|
63
|
+
return `pb_title_kit_dynamic_${displaySize}`
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
59
67
|
const classes = classnames(
|
60
68
|
buildCss('pb_title_kit', isSizeNumberOrString ? `size_${size}` : "", variant, color, getBold),
|
61
69
|
globalProps(props),
|
70
|
+
buildDisplaySize(),
|
62
71
|
buildResponsiveSizeCss(),
|
63
72
|
className
|
64
73
|
)
|
@@ -1,10 +1,9 @@
|
|
1
1
|
<%= pb_rails("title", props: {
|
2
|
+
margin_bottom: "md"
|
2
3
|
}) do %>
|
3
4
|
Default Title
|
4
5
|
<% end %>
|
5
6
|
|
6
|
-
<br/>
|
7
|
-
|
8
7
|
<%= pb_rails("title", props: { text: "Title 1", tag: "h1", size: 1 }) %>
|
9
8
|
<%= pb_rails("title", props: { text: "Title 2", tag: "h2", size: 2 }) %>
|
10
9
|
<%= pb_rails("title", props: { text: "Title 3", tag: "h3", size: 3 }) %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= pb_rails("title", props: { text: "Display Size xs", tag: "h1", display_size: "xs" }) %>
|
2
|
+
<%= pb_rails("title", props: { text: "Display Size sm", tag: "h1", display_size: "sm" }) %>
|
3
|
+
<%= pb_rails("title", props: { text: "Display Size md", tag: "h1", display_size: "md" }) %>
|
4
|
+
<%= pb_rails("title", props: { text: "Display Size lg", tag: "h1", display_size: "lg" }) %>
|
5
|
+
<%= pb_rails("title", props: { text: "Display Size xl", tag: "h1", display_size: "xl" }) %>
|
6
|
+
<%= pb_rails("title", props: { text: "Display Size xxl", tag: "h1", display_size: "xxl" }) %>
|
7
|
+
<%= pb_rails("title", props: { text: "This is a size of display", tag: "h1", size: "display"}) %>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import Title from '../_title'
|
4
|
+
|
5
|
+
const TitleDisplaySize = (props) => {
|
6
|
+
return (
|
7
|
+
<div>
|
8
|
+
<Title
|
9
|
+
displaySize="xs"
|
10
|
+
tag="h1"
|
11
|
+
text="Display Size xs"
|
12
|
+
{...props}
|
13
|
+
/>
|
14
|
+
<Title
|
15
|
+
displaySize="sm"
|
16
|
+
tag="h1"
|
17
|
+
text="Display Size sm"
|
18
|
+
{...props}
|
19
|
+
/>
|
20
|
+
<Title
|
21
|
+
displaySize="md"
|
22
|
+
tag="h1"
|
23
|
+
text="Display Size md"
|
24
|
+
{...props}
|
25
|
+
/>
|
26
|
+
<Title
|
27
|
+
displaySize="lg"
|
28
|
+
tag="h1"
|
29
|
+
text="Display Size lg"
|
30
|
+
{...props}
|
31
|
+
/>
|
32
|
+
<Title
|
33
|
+
displaySize="xl"
|
34
|
+
tag="h1"
|
35
|
+
text="Display Size xl"
|
36
|
+
{...props}
|
37
|
+
/>
|
38
|
+
<Title
|
39
|
+
displaySize="xxl"
|
40
|
+
tag="h1"
|
41
|
+
text="Display Size xxl"
|
42
|
+
{...props}
|
43
|
+
/>
|
44
|
+
<Title
|
45
|
+
size="display"
|
46
|
+
tag="h1"
|
47
|
+
text="This is a size of display"
|
48
|
+
{...props}
|
49
|
+
/>
|
50
|
+
</div>
|
51
|
+
)
|
52
|
+
}
|
53
|
+
|
54
|
+
export default TitleDisplaySize
|
@@ -0,0 +1 @@
|
|
1
|
+
Responsive sizes for large screens and tablets, perfect for digital signage.
|
@@ -5,6 +5,7 @@ examples:
|
|
5
5
|
- title_colors: Colors
|
6
6
|
- title_responsive: Responsive
|
7
7
|
- title_truncate: Truncate
|
8
|
+
- title_display_size: Display Size
|
8
9
|
|
9
10
|
react:
|
10
11
|
- title_default: Default UI
|
@@ -12,3 +13,4 @@ examples:
|
|
12
13
|
- title_colors: Colors
|
13
14
|
- title_responsive: Responsive
|
14
15
|
- title_truncate: Truncate
|
16
|
+
- title_display_size: Display Size
|
@@ -3,3 +3,4 @@ export { default as TitleLightWeight } from './_title_light_weight.jsx'
|
|
3
3
|
export { default as TitleColors } from './_title_colors.jsx'
|
4
4
|
export { default as TitleResponsive } from './_title_responsive.jsx'
|
5
5
|
export { default as TitleTruncate } from './_title_truncate.jsx'
|
6
|
+
export { default as TitleDisplaySize } from './_title_display_size.jsx'
|
@@ -16,12 +16,15 @@ module Playbook
|
|
16
16
|
default: nil,
|
17
17
|
deprecated: true
|
18
18
|
prop :bold, type: Playbook::Props::Boolean, default: true
|
19
|
+
prop :display_size, type: Playbook::Props::Enum,
|
20
|
+
values: [nil, "xs", "sm", "md", "lg", "xl", "xxl"],
|
21
|
+
default: nil
|
19
22
|
|
20
23
|
def classname
|
21
24
|
if is_size_responsive
|
22
25
|
generate_classname("pb_title_kit", variant, color, is_bold) + generate_responsive_size_classname
|
23
26
|
else
|
24
|
-
generate_classname("pb_title_kit", size, variant, color, is_bold)
|
27
|
+
generate_classname("pb_title_kit", size, variant, color, is_bold) + generate_display_size
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -29,6 +32,12 @@ module Playbook
|
|
29
32
|
bold ? nil : "thin"
|
30
33
|
end
|
31
34
|
|
35
|
+
def generate_display_size
|
36
|
+
return "" if display_size.nil?
|
37
|
+
|
38
|
+
" pb_title_kit_dynamic_#{display_size}"
|
39
|
+
end
|
40
|
+
|
32
41
|
def is_size_responsive
|
33
42
|
try(:size).is_a?(::Hash)
|
34
43
|
end
|
@@ -25,12 +25,18 @@ type TooltipProps = {
|
|
25
25
|
children: JSX.Element,
|
26
26
|
data?: { [key: string]: string },
|
27
27
|
delay?: number | Partial<{open: number; close: number}>,
|
28
|
+
height?: string,
|
28
29
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
29
30
|
icon?: string,
|
30
31
|
interaction?: boolean,
|
32
|
+
maxHeight?: string,
|
33
|
+
maxWidth?: string,
|
34
|
+
minHeight?: string,
|
35
|
+
minWidth?: string,
|
31
36
|
placement?: Placement,
|
32
37
|
position?: "absolute" | "fixed";
|
33
38
|
text: string,
|
39
|
+
width: string,
|
34
40
|
showTooltip?: boolean,
|
35
41
|
forceOpenTooltip?: boolean,
|
36
42
|
} & GlobalProps
|
@@ -42,13 +48,19 @@ const Tooltip = forwardRef((props: TooltipProps, ref: ForwardedRef<unknown>): Re
|
|
42
48
|
children,
|
43
49
|
data = {},
|
44
50
|
delay = 0,
|
51
|
+
height,
|
45
52
|
htmlOptions = {},
|
46
53
|
icon = null,
|
47
54
|
interaction = false,
|
55
|
+
maxHeight,
|
56
|
+
maxWidth,
|
57
|
+
minHeight,
|
58
|
+
minWidth,
|
48
59
|
placement: preferredPlacement = "top",
|
49
60
|
position = "absolute",
|
50
61
|
text,
|
51
62
|
showTooltip = true,
|
63
|
+
width,
|
52
64
|
zIndex,
|
53
65
|
forceOpenTooltip = false,
|
54
66
|
...rest
|
@@ -115,6 +127,18 @@ const Tooltip = forwardRef((props: TooltipProps, ref: ForwardedRef<unknown>): Re
|
|
115
127
|
top: "bottom",
|
116
128
|
}[placement.split("-")[0]]
|
117
129
|
|
130
|
+
const tooltipSizing = () => {
|
131
|
+
return Object.assign(
|
132
|
+
{},
|
133
|
+
height ? { height: height } : {},
|
134
|
+
maxHeight ? { maxHeight: maxHeight } : {},
|
135
|
+
maxWidth ? { maxWidth: maxWidth } : {},
|
136
|
+
minHeight ? { minHeight: minHeight } : {},
|
137
|
+
minWidth ? { minWidth: minWidth } : {},
|
138
|
+
width ? { width: width } : {}
|
139
|
+
);
|
140
|
+
};
|
141
|
+
|
118
142
|
return (
|
119
143
|
<>
|
120
144
|
<div
|
@@ -144,6 +168,7 @@ const Tooltip = forwardRef((props: TooltipProps, ref: ForwardedRef<unknown>): Re
|
|
144
168
|
ref: refs.setFloating,
|
145
169
|
role: "tooltip",
|
146
170
|
style: {
|
171
|
+
...tooltipSizing(),
|
147
172
|
position: strategy,
|
148
173
|
top: y ?? 0,
|
149
174
|
left: x ?? 0,
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { Button, Tooltip, Flex, FlexItem } from 'playbook-ui';
|
3
|
+
|
4
|
+
const TooltipSizing = (props) => {
|
5
|
+
|
6
|
+
return (
|
7
|
+
<Flex
|
8
|
+
flexDirection='row'
|
9
|
+
gap='md'
|
10
|
+
wrap
|
11
|
+
>
|
12
|
+
<FlexItem>
|
13
|
+
<Tooltip
|
14
|
+
height='150px'
|
15
|
+
placement='top'
|
16
|
+
text="I'm 150px high and 100px wide!"
|
17
|
+
width='100px'
|
18
|
+
{...props}
|
19
|
+
>
|
20
|
+
<Button text="Height and Width"/>
|
21
|
+
</Tooltip>
|
22
|
+
</FlexItem>
|
23
|
+
<FlexItem>
|
24
|
+
<Tooltip
|
25
|
+
maxHeight='100px'
|
26
|
+
placement='top'
|
27
|
+
text="I have a maxHeight of 100px! Lorem ipsum dolor sit amet consectetur adipisicing elit."
|
28
|
+
width='250px'
|
29
|
+
{...props}
|
30
|
+
>
|
31
|
+
<Button text="maxHeight"/>
|
32
|
+
</Tooltip>
|
33
|
+
</FlexItem>
|
34
|
+
<FlexItem>
|
35
|
+
<Tooltip
|
36
|
+
maxWidth='150px'
|
37
|
+
placement='top'
|
38
|
+
text="I have a maxWidth of 150px! Lorem ipsum dolor sit amet consectetur adipisicing elit."
|
39
|
+
{...props}
|
40
|
+
>
|
41
|
+
<Button text="maxWidth"/>
|
42
|
+
</Tooltip>
|
43
|
+
</FlexItem>
|
44
|
+
<FlexItem>
|
45
|
+
<Tooltip
|
46
|
+
minWidth='300px'
|
47
|
+
placement='top'
|
48
|
+
text="I have a minWidth of 300px!"
|
49
|
+
{...props}
|
50
|
+
>
|
51
|
+
<Button text="minWidth"/>
|
52
|
+
</Tooltip>
|
53
|
+
</FlexItem>
|
54
|
+
<FlexItem>
|
55
|
+
<Tooltip
|
56
|
+
maxWidth='150px'
|
57
|
+
minHeight='300px'
|
58
|
+
placement='top'
|
59
|
+
text="I have a minHeight of 300px!"
|
60
|
+
{...props}
|
61
|
+
>
|
62
|
+
<Button text="minHeight"/>
|
63
|
+
</Tooltip>
|
64
|
+
</FlexItem>
|
65
|
+
</Flex>
|
66
|
+
)
|
67
|
+
}
|
68
|
+
|
69
|
+
export default TooltipSizing
|
@@ -12,7 +12,7 @@ examples:
|
|
12
12
|
- tooltip_default_react: Default
|
13
13
|
- tooltip_interaction: Content Interaction
|
14
14
|
- tooltip_margin: Margin
|
15
|
+
- tooltip_sizing: Tooltip Sizing
|
15
16
|
- tooltip_icon: Tooltip with Icon
|
16
17
|
- tooltip_delay: Delay
|
17
18
|
- tooltip_show_tooltip_react: Show Tooltip
|
18
|
-
|
@@ -1,6 +1,7 @@
|
|
1
1
|
export { default as TooltipDefaultReact } from './_tooltip_default_react'
|
2
2
|
export { default as TooltipInteraction } from './_tooltip_interaction'
|
3
3
|
export { default as TooltipMargin } from './_tooltip_margin'
|
4
|
+
export { default as TooltipSizing } from './_tooltip_sizing'
|
4
5
|
export { default as TooltipIcon } from './_tooltip_icon'
|
5
6
|
export { default as TooltipDelay } from './_tooltip_delay'
|
6
7
|
export { default as TooltipShowTooltipReact } from './_tooltip_show_tooltip_react'
|
@@ -3,7 +3,8 @@ import Select from 'react-select'
|
|
3
3
|
import AsyncSelect from 'react-select/async'
|
4
4
|
import CreateableSelect from 'react-select/creatable'
|
5
5
|
import AsyncCreateableSelect from 'react-select/async-creatable'
|
6
|
-
import { get, isString, uniqueId } from '
|
6
|
+
import { get, isString, uniqueId } from '../utilities/object'
|
7
|
+
|
7
8
|
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
8
9
|
import classnames from 'classnames'
|
9
10
|
|
@@ -8,15 +8,17 @@ import { SelectValueType } from '../_typeahead'
|
|
8
8
|
type Props = {
|
9
9
|
data: SelectValueType,
|
10
10
|
multiValueTemplate: any,
|
11
|
+
wrapped?: boolean,
|
11
12
|
pillColor?: "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",
|
12
13
|
removeProps: any,
|
13
14
|
selectProps: any,
|
14
15
|
}
|
15
16
|
|
17
|
+
|
16
18
|
const MultiValue = (props: Props) => {
|
17
19
|
const { removeProps } = props
|
18
20
|
const { imageUrl, label } = props.data
|
19
|
-
const { dark, multiKit, pillColor, truncate } = props.selectProps
|
21
|
+
const { dark, multiKit, pillColor, truncate, wrapped } = props.selectProps
|
20
22
|
|
21
23
|
const formPillProps = {
|
22
24
|
marginRight: 'xs',
|
@@ -52,6 +54,7 @@ const MultiValue = (props: Props) => {
|
|
52
54
|
size={multiKit === 'smallPill' ? 'small' : ''}
|
53
55
|
text=''
|
54
56
|
truncate={truncate}
|
57
|
+
wrapped={wrapped}
|
55
58
|
{...props}
|
56
59
|
/>
|
57
60
|
}
|
@@ -66,6 +69,7 @@ const MultiValue = (props: Props) => {
|
|
66
69
|
size={multiKit === 'smallPill' ? 'small' : ''}
|
67
70
|
text={label}
|
68
71
|
truncate={truncate}
|
72
|
+
wrapped={wrapped}
|
69
73
|
{...props}
|
70
74
|
/>
|
71
75
|
}
|
@@ -44,6 +44,8 @@ module Playbook
|
|
44
44
|
default: false
|
45
45
|
prop :validation, type: Playbook::Props::HashProp,
|
46
46
|
default: {}
|
47
|
+
prop :wrapped, type: Playbook::Props::Boolean,
|
48
|
+
default: false
|
47
49
|
prop :clear_on_context_change, type: Playbook::Props::Boolean,
|
48
50
|
default: true
|
49
51
|
prop :options_by_context, type: Playbook::Props::HashProp,
|
@@ -72,7 +74,7 @@ module Playbook
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def is_react?
|
75
|
-
pills || !is_multi
|
77
|
+
pills || !is_multi || wrapped
|
76
78
|
end
|
77
79
|
|
78
80
|
def typeahead_react_options
|
@@ -94,6 +96,7 @@ module Playbook
|
|
94
96
|
placeholder: placeholder,
|
95
97
|
plusIcon: plus_icon,
|
96
98
|
truncate: truncate,
|
99
|
+
wrapped: wrapped,
|
97
100
|
searchContextSelector: search_context_selector,
|
98
101
|
optionsByContext: options_by_context,
|
99
102
|
clearOnContextChange: clear_on_context_change,
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import { isEmpty, get, isString, uniqueId, omitBy } from './object';
|
2
|
+
|
3
|
+
describe('Lodash functions', () => {
|
4
|
+
describe('isEmpty', () => {
|
5
|
+
test('returns true for empty objects', () => {
|
6
|
+
expect(isEmpty({})).toBe(true);
|
7
|
+
});
|
8
|
+
test('returns true for empty arrays', () => {
|
9
|
+
expect(isEmpty([])).toBe(true);
|
10
|
+
});
|
11
|
+
test('returns false for non-empty objects', () => {
|
12
|
+
expect(isEmpty({ a: 1 })).toBe(false);
|
13
|
+
});
|
14
|
+
test('returns false for non-empty arrays', () => {
|
15
|
+
expect(isEmpty([1])).toBe(false);
|
16
|
+
});
|
17
|
+
test('returns true for null and undefined', () => {
|
18
|
+
expect(isEmpty(null)).toBe(true);
|
19
|
+
expect(isEmpty(undefined)).toBe(true);
|
20
|
+
});
|
21
|
+
test('returns false for non-object, non-array values', () => {
|
22
|
+
expect(isEmpty("hello")).toBe(false);
|
23
|
+
expect(isEmpty(123)).toBe(false);
|
24
|
+
});
|
25
|
+
});
|
26
|
+
|
27
|
+
describe('get', () => {
|
28
|
+
const obj = { a: { b: { c: 42 } }, arr: [{ x: 1 }, { y: 2 }] };
|
29
|
+
|
30
|
+
test('retrieves nested properties by dot path', () => {
|
31
|
+
expect(get(obj, 'a.b.c')).toBe(42);
|
32
|
+
});
|
33
|
+
test('returns default value if path does not exist', () => {
|
34
|
+
expect(get(obj, 'a.b.d', 'default')).toBe('default');
|
35
|
+
});
|
36
|
+
test('retrieves array values using bracket notation', () => {
|
37
|
+
expect(get(obj, 'arr[1].y')).toBe(2);
|
38
|
+
});
|
39
|
+
test('returns default for non-existent paths', () => {
|
40
|
+
expect(get(obj, 'non.existent.path', null)).toBe(null);
|
41
|
+
});
|
42
|
+
});
|
43
|
+
|
44
|
+
describe('isString', () => {
|
45
|
+
test('returns true for string literal', () => {
|
46
|
+
expect(isString('test')).toBe(true);
|
47
|
+
});
|
48
|
+
test('returns true for String object', () => {
|
49
|
+
expect(isString(new String('test'))).toBe(true);
|
50
|
+
});
|
51
|
+
test('returns false for non-string values', () => {
|
52
|
+
expect(isString(123)).toBe(false);
|
53
|
+
expect(isString(null)).toBe(false);
|
54
|
+
expect(isString({ a: 1 })).toBe(false);
|
55
|
+
expect(isString([ 'a','b','c' ])).toBe(false);
|
56
|
+
});
|
57
|
+
});
|
58
|
+
|
59
|
+
describe('uniqueId', () => {
|
60
|
+
test('generates unique ids without prefix', () => {
|
61
|
+
const id1 = uniqueId();
|
62
|
+
const id2 = uniqueId();
|
63
|
+
expect(id1).not.toBe(id2);
|
64
|
+
expect(Number(id1)).toBeLessThan(Number(id2));
|
65
|
+
});
|
66
|
+
test('generates unique ids with prefix', () => {
|
67
|
+
const id1 = uniqueId('id_');
|
68
|
+
const id2 = uniqueId('id_');
|
69
|
+
const id3 = uniqueId('id_');
|
70
|
+
expect(id1).not.toBe(id2);
|
71
|
+
expect(id1).not.toBe(id3);
|
72
|
+
expect(id2).not.toBe(id3);
|
73
|
+
expect(id1.startsWith('id_')).toBe(true);
|
74
|
+
expect(id2.startsWith('id_')).toBe(true);
|
75
|
+
expect(id3.startsWith('id_')).toBe(true);
|
76
|
+
});
|
77
|
+
});
|
78
|
+
|
79
|
+
describe('omitBy', () => {
|
80
|
+
test('omits keys for which predicate returns true', () => {
|
81
|
+
const obj = { a: 1, b: 2, c: 3 };
|
82
|
+
const isEven = value => value % 2 === 0;
|
83
|
+
const noEvenValues = omitBy(obj, isEven);
|
84
|
+
expect(noEvenValues).toEqual({ a: 1, c: 3 });
|
85
|
+
});
|
86
|
+
test('returns empty object for null input', () => {
|
87
|
+
expect(omitBy(null, () => true)).toEqual({});
|
88
|
+
});
|
89
|
+
test('returns empty object for non-object input', () => {
|
90
|
+
expect(omitBy("string", () => true)).toEqual({});
|
91
|
+
});
|
92
|
+
test('returns original object if predicate returns false for all keys', () => {
|
93
|
+
const obj = { a: 1, b: 2 };
|
94
|
+
const isBiggerThanFive = value => value >= 4;
|
95
|
+
const objWithSmallValues = omitBy(obj, isBiggerThanFive);
|
96
|
+
expect(objWithSmallValues).toEqual(obj);
|
97
|
+
});
|
98
|
+
});
|
99
|
+
});
|
@@ -1,3 +1,31 @@
|
|
1
1
|
/* 🛠️ Any commonly used lodash functions can be added here. 🤙 */
|
2
2
|
|
3
|
-
export const isEmpty = (obj:
|
3
|
+
export const isEmpty = (obj: any) => [Object, Array].includes((obj || {}).constructor) && !Object.entries((obj || {})).length;
|
4
|
+
|
5
|
+
export const get = <T, R = any>(obj: T, path: string, defaultValue?: R): R | any => {
|
6
|
+
const travel = (regexp: RegExp): any =>
|
7
|
+
String.prototype.split
|
8
|
+
.call(path, regexp)
|
9
|
+
.filter(Boolean)
|
10
|
+
.reduce((res: any, key: string) => (res !== null && res !== undefined ? res[key] : res), obj)
|
11
|
+
const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/)
|
12
|
+
return result === undefined || result === obj ? defaultValue : result
|
13
|
+
}
|
14
|
+
|
15
|
+
export const isString = (str: unknown): str is string =>
|
16
|
+
str != null && typeof (str as any).valueOf() === "string"
|
17
|
+
|
18
|
+
export const uniqueId: (prefix?: string) => string = (() => {
|
19
|
+
let counter = 0
|
20
|
+
return (prefix = '') => `${prefix}${++counter}`
|
21
|
+
})()
|
22
|
+
|
23
|
+
export const omitBy = (obj: Record<string, any>, predicate: (value: any, key: string) => boolean) => {
|
24
|
+
if (obj === null || typeof obj !== 'object') return {}
|
25
|
+
return Object.keys(obj).reduce((result: Record<string, any>, key: string) => {
|
26
|
+
if (!predicate(obj[key], key)) {
|
27
|
+
result[key] = obj[key];
|
28
|
+
}
|
29
|
+
return result;
|
30
|
+
}, {})
|
31
|
+
}
|