playbook_ui 7.15.1 → 7.16.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/index.js +2 -2
  3. data/app/pb_kits/playbook/pb_avatar/_avatar.html.erb +4 -6
  4. data/app/pb_kits/playbook/pb_avatar/_avatar.jsx +6 -2
  5. data/app/pb_kits/playbook/pb_avatar/avatar.rb +4 -0
  6. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_no_image.html.erb +5 -0
  7. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_no_image.jsx +41 -0
  8. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_no_image.md +2 -0
  9. data/app/pb_kits/playbook/pb_avatar/docs/example.yml +2 -0
  10. data/app/pb_kits/playbook/pb_avatar/docs/index.js +1 -0
  11. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.jsx +1 -0
  12. data/app/pb_kits/playbook/pb_date_time/_date_time.jsx +2 -2
  13. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +2 -2
  14. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.jsx +5 -1
  15. data/app/pb_kits/playbook/pb_flex/_flex_item.jsx +4 -2
  16. data/app/pb_kits/playbook/pb_flex/_flex_item.scss +9 -0
  17. data/app/pb_kits/playbook/pb_flex/flex_item.rb +8 -1
  18. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_sizing.html.erb +4 -4
  19. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_sizing.jsx +12 -1
  20. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_sizing.md +2 -1
  21. data/app/pb_kits/playbook/pb_gauge/docs/example.yml +4 -5
  22. data/app/pb_kits/playbook/pb_image/_image.html.erb +3 -1
  23. data/app/pb_kits/playbook/pb_image/_image.jsx +4 -1
  24. data/app/pb_kits/playbook/pb_image/docs/_custom_error_image.html.erb +75 -0
  25. data/app/pb_kits/playbook/pb_image/docs/_custom_error_image.jsx +55 -0
  26. data/app/pb_kits/playbook/pb_image/docs/example.yml +2 -0
  27. data/app/pb_kits/playbook/pb_image/docs/index.js +1 -0
  28. data/app/pb_kits/playbook/pb_image/image.rb +2 -0
  29. data/app/pb_kits/playbook/pb_layout/_item.html.erb +6 -0
  30. data/app/pb_kits/playbook/pb_layout/_layout.jsx +19 -1
  31. data/app/pb_kits/playbook/pb_layout/_layout.scss +33 -1
  32. data/app/pb_kits/playbook/pb_layout/docs/_layout_collection_detail.jsx +1 -1
  33. data/app/pb_kits/playbook/pb_layout/docs/_layout_masonry.html.erb +48 -0
  34. data/app/pb_kits/playbook/pb_layout/docs/_layout_masonry.jsx +61 -0
  35. data/app/pb_kits/playbook/pb_layout/docs/example.yml +3 -0
  36. data/app/pb_kits/playbook/pb_layout/docs/index.js +1 -0
  37. data/app/pb_kits/playbook/pb_layout/item.rb +25 -0
  38. data/app/pb_kits/playbook/pb_layout/layout.rb +15 -15
  39. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.html.erb +1 -1
  40. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.jsx +9 -2
  41. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +20 -1
  42. data/app/pb_kits/playbook/pb_selectable_card/docs/_selectable_card_error.html.erb +36 -0
  43. data/app/pb_kits/playbook/pb_selectable_card/docs/_selectable_card_error.jsx +58 -0
  44. data/app/pb_kits/playbook/pb_selectable_card/docs/example.yml +2 -0
  45. data/app/pb_kits/playbook/pb_selectable_card/docs/index.js +1 -0
  46. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.rb +11 -0
  47. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.jsx +0 -1
  48. data/lib/playbook/version.rb +1 -1
  49. metadata +18 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 314da7ed0bc2cb7982bfaf10af7826efbb8822ad5ab5030433daf1bde9267398
4
- data.tar.gz: 4ee326fa35a415359b0633ce7138526ce1c1346a0991ad079fb3307f350c432f
3
+ metadata.gz: ba7ca0e1a8dbb832e4553d4ca3c0c8c328ead105c57d691a0181ca169197b53a
4
+ data.tar.gz: a8c51729b2dfcfb7dc54d448abc6a305cb89fb367933b4a01893a8a455dd0fcb
5
5
  SHA512:
6
- metadata.gz: 25a9b84de3294b16d92378e48d5192ba6b444623a5161f3e64d0a68b52637cbef1949334d6cc72852dd4f85e414e827b413857afea83a0d1092c6331d79928ee
7
- data.tar.gz: c565fd03afa4505e9e0126a868d1acd67baa86fe293f9c84db4248ebd417b8da4c3ab8042092d6130ed9353343f79c87ef59066ce5a699807624dce1c129bd93
6
+ metadata.gz: e2ff1660024fbfc09a674433414caf39bc8b1c50220f51dc642c76d5de7d11f2b8056ae70ab924944c2828ee362f7b9986d1e5226672e9feda680606fc4ba7c2
7
+ data.tar.gz: 01b2ae4f1a7abed5972b1394f9a2b13ac31de8814050adef4f78ca81cab284c82fab7b966a88428b94c326f6319b72774443f00894c29e273773279d97388696
@@ -108,8 +108,8 @@ export dashboardValueSettings from './pb_dashboard_value/dashboardValueSettings'
108
108
  // Other JS/Plugins
109
109
  export pbChart from './plugins/pb_chart.js'
110
110
  export datePickerHelper from './pb_date_picker/date_picker_helper.js'
111
- export PbTypeahead from './pb_typeahead'
112
111
  export PbPopover from './pb_popover'
113
112
  export PbTable from './pb_table'
114
- export PbTooltip from './pb_tooltip'
115
113
  export PbTextarea from './pb_textarea'
114
+ export PbTooltip from './pb_tooltip'
115
+ export PbTypeahead from './pb_typeahead'
@@ -3,10 +3,8 @@
3
3
  data: object.data.merge(initials: object.initials),
4
4
  class: object.classname,
5
5
  aria: object.aria) do %>
6
- <%= content_tag(:div,
7
- data: { initials: object.initials },
8
- class: "avatar_wrapper") do %>
9
- <%= pb_rails("image", props: { url: object.image_url }) if object.image_url.present? %>
10
- <% end %>
11
- <%= pb_rails("online_status", props: object.online_status_props) if object.status %>
6
+ <%= content_tag(:div, data: { initials: object.initials }, class: "avatar_wrapper") do %>
7
+ <%= pb_rails("image", props: { url: object.image_url, on_error: object.handle_img_error }) if object.image_url.present? %>
8
+ <% end %>
9
+ <%= pb_rails("online_status", props: object.online_status_props) if object.status %>
12
10
  <% end %>
@@ -1,6 +1,6 @@
1
1
  /* @flow */
2
2
 
3
- import React from 'react'
3
+ import React, { useState } from 'react'
4
4
  import classnames from 'classnames'
5
5
  import { map } from 'lodash'
6
6
 
@@ -39,6 +39,9 @@ const Avatar = (props: AvatarProps) => {
39
39
  const initials = name && firstTwoInitials(name)
40
40
  dataProps['data-initials'] = initials
41
41
 
42
+ const [error, setError] = useState(false)
43
+ const handleError = () => setError(true)
44
+
42
45
  return (
43
46
  <div
44
47
  {...ariaProps}
@@ -50,9 +53,10 @@ const Avatar = (props: AvatarProps) => {
50
53
  className="avatar_wrapper"
51
54
  data-initials={initials}
52
55
  >
53
- <If condition={imageUrl}>
56
+ <If condition={imageUrl && !error}>
54
57
  <Image
55
58
  alt={name}
59
+ onError={handleError}
56
60
  url={imageUrl}
57
61
  />
58
62
  </If>
@@ -25,6 +25,10 @@ module Playbook
25
25
  def online_status_props
26
26
  { status: status, classname: "size_#{size}" }
27
27
  end
28
+
29
+ def handle_img_error
30
+ "this.style.display = 'none'"
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("avatar", props: { image_url: true, name: "Terry Johnson", size: "xs" }) %>
2
+ <%= pb_rails("avatar", props: { image_url: 4, name: "Terry Johnson", size: "sm" }) %>
3
+ <%= pb_rails("avatar", props: { image_url: "https://google.com", name: "Terry Johnson", size: "md" }) %>
4
+ <%= pb_rails("avatar", props: { image_url: "", name: "Terry Johnson", size: "lg" }) %>
5
+ <%= pb_rails("avatar", props: { image_url: "https://randomuser.me/api/portraits/men/notapicture.jpg", name: "Terry Johnson", size: "xl" }) %>
@@ -0,0 +1,41 @@
1
+ import React from 'react'
2
+ import { Avatar } from '../../'
3
+
4
+ const AvatarNoImage = (props) => {
5
+ return (
6
+ <div>
7
+ <Avatar
8
+ imageUrl="Just some text here"
9
+ name="Terry Johnson"
10
+ size="xs"
11
+ {...props}
12
+ />
13
+ <Avatar
14
+ imageUrl={4}
15
+ name="Terry Johnson"
16
+ size="sm"
17
+ {...props}
18
+ />
19
+ <Avatar
20
+ imageUrl="https://google.com"
21
+ name="Terry Johnson"
22
+ size="md"
23
+ {...props}
24
+ />
25
+ <Avatar
26
+ imageUrl=""
27
+ name="Terry Johnson"
28
+ size="lg"
29
+ {...props}
30
+ />
31
+ <Avatar
32
+ imageUrl="https://randomuser.me/api/portraits/men/notapicture.jpg"
33
+ name="Terry Johnson"
34
+ size="xl"
35
+ {...props}
36
+ />
37
+ </div>
38
+ )
39
+ }
40
+
41
+ export default AvatarNoImage
@@ -0,0 +1,2 @@
1
+
2
+ A monagram is used as a fallback when an invalid or missing image url is provided.
@@ -2,8 +2,10 @@ examples:
2
2
  rails:
3
3
  - avatar_default: Default
4
4
  - avatar_monogram: Monogram
5
+ - avatar_no_image: "Bad Image Link"
5
6
  - avatar_status: Status
6
7
  react:
7
8
  - avatar_default: Default
8
9
  - avatar_monogram: Monogram
10
+ - avatar_no_image: "Bad Image Link"
9
11
  - avatar_status: Status
@@ -1,3 +1,4 @@
1
1
  export { default as AvatarDefault } from './_avatar_default.jsx'
2
2
  export { default as AvatarMonogram } from './_avatar_monogram.jsx'
3
3
  export { default as AvatarStatus } from './_avatar_status.jsx'
4
+ export { default as AvatarNoImage } from './_avatar_no_image.jsx'
@@ -49,6 +49,7 @@ const DateRangeInline = (props: DateRangeInlineProps) => {
49
49
  <If condition={icon}>
50
50
  <Body
51
51
  color="light"
52
+ key={Math.random()}
52
53
  tag="span"
53
54
  >
54
55
  <Icon
@@ -53,13 +53,13 @@ const DateTime = (props: DateTimeProps) => {
53
53
  vertical="baseline"
54
54
  >
55
55
  <FormattedDate
56
- datetime={datetime}
57
56
  showDayOfWeek={showDayOfWeek}
58
57
  size={size}
59
58
  timeZone={timeZone}
59
+ value={datetime}
60
60
  />
61
61
  <Time
62
- date={new Date()}
62
+ date={datetime}
63
63
  marginLeft="sm"
64
64
  showIcon={showIcon}
65
65
  size={size}
@@ -4,7 +4,7 @@ import DateTime from '../_date_time.jsx'
4
4
  const DateTimeDefault = (props) => (
5
5
  <div>
6
6
  <DateTime
7
- datetime={new Date()}
7
+ datetime={new Date('2020-12-31 14:24:09')}
8
8
  showDayOfWeek
9
9
  showIcon
10
10
  {...props}
@@ -29,7 +29,7 @@ const DateTimeDefault = (props) => (
29
29
  <br />
30
30
 
31
31
  <DateTime
32
- datetime={new Date()}
32
+ datetime={new Date('2020-12-31 14:24:09 -0500')}
33
33
  {...props}
34
34
  />
35
35
  </div>
@@ -31,11 +31,15 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps) => {
31
31
  )
32
32
  const icon = iconMap[status]
33
33
 
34
+ const handleClick = () => {
35
+ toggleToast(!closeable)
36
+ }
37
+
34
38
  return (
35
39
  <If condition={showToast}>
36
40
  <div
37
41
  className={css}
38
- onClick={closeable && (() => toggleToast(false))}
42
+ onClick={handleClick}
39
43
  >
40
44
  <If condition={icon}>
41
45
  <Icon
@@ -10,19 +10,21 @@ type FlexItemPropTypes = {
10
10
  shrink: boolean,
11
11
  flex: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 'none',
12
12
  className: string,
13
+ overflow?: "auto" | "hidden" | "initial" | "inherit" | "scroll" | "visible",
13
14
  }
14
15
 
15
16
  const FlexItem = (props: FlexItemPropTypes) => {
16
- const { children, className, fixedSize, grow, shrink, flex } = props
17
+ const { children, className, fixedSize, grow, overflow = null, shrink, flex } = props
17
18
  const growClass = grow === true ? 'grow' : ''
18
19
  const flexClass = flex !== 'none' ? `flex_${flex}` : ''
20
+ const overflowClass = overflow ? `overflow_${overflow}` : ''
19
21
  const shrinkClass = shrink === true ? 'shrink' : ''
20
22
  const fixedStyle =
21
23
  fixedSize !== undefined ? { flexBasis: `${fixedSize}` } : null
22
24
 
23
25
  return (
24
26
  <div
25
- className={classnames(buildCss('pb_flex_item_kit', growClass, shrinkClass, flexClass), globalProps(props), className)}
27
+ className={classnames(buildCss('pb_flex_item_kit', growClass, shrinkClass, flexClass), overflowClass, globalProps(props), className)}
26
28
  style={fixedStyle}
27
29
  >
28
30
  {children}
@@ -12,6 +12,15 @@
12
12
  flex-shrink: 1;
13
13
  }
14
14
 
15
+
16
+ $overflow_values: auto, hidden, inherit, initial, scroll, visible;
17
+
18
+ @each $value in $overflow_values {
19
+ &.overflow_#{$value} {
20
+ overflow: #{$value}
21
+ }
22
+ }
23
+
15
24
  @for $i from 0 through 12 {
16
25
  &[class*=_flex_#{$i}]{
17
26
  flex: $i;
@@ -15,9 +15,12 @@ module Playbook
15
15
  prop :flex, type: Playbook::Props::Enum,
16
16
  values: %w[0 1 2 3 4 5 6 7 8 9 10 11 12 none],
17
17
  default: "none"
18
+ prop :overflow, type: Playbook::Props::Enum,
19
+ values: %w[auto hidden inherit initial scroll visible] + [nil],
20
+ default: nil
18
21
 
19
22
  def classname
20
- generate_classname("pb_flex_item_kit", fixed_size_class, grow_class, shrink_class, flex_class)
23
+ generate_classname("pb_flex_item_kit", fixed_size_class, grow_class, shrink_class, flex_class) + overflow_class
21
24
  end
22
25
 
23
26
  def style_value
@@ -34,6 +37,10 @@ module Playbook
34
37
  grow ? "grow" : nil
35
38
  end
36
39
 
40
+ def overflow_class
41
+ overflow ? " overflow_#{overflow}" : ""
42
+ end
43
+
37
44
  def shrink_class
38
45
  shrink ? "shrink" : nil
39
46
  end
@@ -1,23 +1,23 @@
1
1
  <%= pb_rails("flex", props: {wrap: true}) do %>
2
- <%= pb_rails("flex/flex_item", props: {fixed_size: "400px"}) do %>
2
+ <%= pb_rails("flex/flex_item", props: {fixed_size: "400px", overflow: "hidden", shrink: true }) do %>
3
3
  <%= pb_rails("gauge", props: {
4
4
  id: "gauge-sizing4",
5
5
  chart_data: [{ name: "Point 1", value: 100 }],
6
6
  }) %>
7
7
  <% end %>
8
- <%= pb_rails("flex/flex_item", props: {fixed_size: "300px"}) do %>
8
+ <%= pb_rails("flex/flex_item", props: {fixed_size: "300px", overflow: "hidden", shrink: true }) do %>
9
9
  <%= pb_rails("gauge", props: {
10
10
  id: "gauge-sizing3",
11
11
  chart_data: [{ name: "Point 2", value: 75 }],
12
12
  }) %>
13
13
  <% end %>
14
- <%= pb_rails("flex/flex_item", props: {fixed_size: "200px"}) do %>
14
+ <%= pb_rails("flex/flex_item", props: {fixed_size: "200px", overflow: "hidden", shrink: true }) do %>
15
15
  <%= pb_rails("gauge", props: {
16
16
  id: "gauge-sizing2",
17
17
  chart_data: [{ name: "Point 3", value: 50 }],
18
18
  }) %>
19
19
  <% end %>
20
- <%= pb_rails("flex/flex_item", props: {fixed_size: "125px"}) do %>
20
+ <%= pb_rails("flex/flex_item", props: {fixed_size: "125px", overflow: "hidden", shrink: true }) do %>
21
21
  <%= pb_rails("gauge", props: {
22
22
  id: "gauge-sizing1",
23
23
  chart_data: [{ name: "Point 4", value: 25 }],
@@ -9,6 +9,8 @@ const GaugeSizing = (props) => (
9
9
  >
10
10
  <FlexItem
11
11
  fixedSize="400px"
12
+ overflow="hidden"
13
+ shrink
12
14
  {...props}
13
15
  >
14
16
  <Gauge
@@ -19,6 +21,8 @@ const GaugeSizing = (props) => (
19
21
  </FlexItem>
20
22
  <FlexItem
21
23
  fixedSize="300px"
24
+ overflow="hidden"
25
+ shrink
22
26
  {...props}
23
27
  >
24
28
  <Gauge
@@ -29,6 +33,8 @@ const GaugeSizing = (props) => (
29
33
  </FlexItem>
30
34
  <FlexItem
31
35
  fixedSize="200px"
36
+ overflow="hidden"
37
+ shrink
32
38
  {...props}
33
39
  >
34
40
  <Gauge
@@ -37,7 +43,12 @@ const GaugeSizing = (props) => (
37
43
  {...props}
38
44
  />
39
45
  </FlexItem>
40
- <FlexItem fixedSize="125px">
46
+ <FlexItem
47
+ fixedSize="125px"
48
+ overflow="hidden"
49
+ shrink
50
+ {...props}
51
+ >
41
52
  <Gauge
42
53
  chartData={[ { name: 'Point 4', value: 25 } ]}
43
54
  id="gauge-sizing1"
@@ -1 +1,2 @@
1
- ### Gauge resizes dynamically to fit whatever element it's placed within.
1
+ ### Gauge resizes dynamically to fit whatever element it's placed within.
2
+ #### Note: set `overflow` to hidden on the parent element when nesting gauges inside of a flex items to best respond to shrinking screens.
@@ -1,5 +1,5 @@
1
1
  examples:
2
-
2
+
3
3
  rails:
4
4
  - gauge_default: Default
5
5
  - gauge_disable_animation: Disable Animation
@@ -9,16 +9,15 @@ examples:
9
9
  - gauge_min_max: Min Max Labels
10
10
  - gauge_sizing: Sizing
11
11
  - gauge_height: Height
12
-
13
-
12
+
13
+
14
14
  react:
15
15
  - gauge_default: Default
16
16
  - gauge_disable_animation: Disable Animation
17
- - gauge_title: Title
17
+ - gauge_title: Title
18
18
  - gauge_units: Units
19
19
  - gauge_full_circle: Full Circle
20
20
  - gauge_min_max: Min Max Labels
21
21
  - gauge_sizing: Sizing
22
22
  - gauge_height: Height
23
23
  - gauge_live_data: Live Data
24
-
@@ -4,5 +4,7 @@
4
4
  class: object.classname,
5
5
  aria: object.aria,
6
6
  src: object.url,
7
- alt: object.alt)
7
+ alt: object.alt,
8
+ onerror: object.on_error,
9
+ )
8
10
  %>
@@ -11,6 +11,7 @@ type ImageProps = {
11
11
  className?: string,
12
12
  data?: object,
13
13
  id?: string,
14
+ onError?: () => {},
14
15
  size: "xs" | "sm" | "md" | "lg" | "xl",
15
16
  rounded?: boolean,
16
17
  url: string,
@@ -23,6 +24,7 @@ const Image = (props: ImageProps) => {
23
24
  className,
24
25
  data = {},
25
26
  id,
27
+ onError = null,
26
28
  rounded = false,
27
29
  size = '',
28
30
  url = '',
@@ -46,7 +48,8 @@ const Image = (props: ImageProps) => {
46
48
  className={classes}
47
49
  data-src={url}
48
50
  id={id}
49
- rounded={rounded}
51
+ onError={onError}
52
+ rounded={+rounded}
50
53
  src={url}
51
54
  />
52
55
  </div>
@@ -0,0 +1,75 @@
1
+ <style>
2
+ .image-error:before {
3
+ content: "Sorry, the image below seems to be broken.";
4
+ display: block;
5
+ margin-bottom: 10px;
6
+ }
7
+ .image-error {
8
+ margin: 5px;
9
+ padding: 5px;
10
+ outline: 1px solid red;
11
+ }
12
+ </style>
13
+
14
+ <%= pb_rails("body",
15
+ props: {
16
+ text: "Handle when an image fails to load or a broken link is passed. This is not neccessary most of the time."
17
+ }
18
+ ) %>
19
+
20
+ <br>
21
+ <br>
22
+
23
+ <%= pb_rails("body",
24
+ props: {
25
+ text: "Alter the display when the image fails to load:"
26
+ }
27
+ ) %>
28
+
29
+ <%= pb_rails("image",
30
+ props: {
31
+ alt: "This is the alt text!",
32
+ on_error: "this.style.color = 'red'",
33
+ rounded: true,
34
+ size: "xs",
35
+ url: "not_a_picture"
36
+ }
37
+ ) %>
38
+
39
+ <br>
40
+ <br>
41
+
42
+ <%= pb_rails("body",
43
+ props: {
44
+ text: "Give it an error class:"
45
+ }
46
+ ) %>
47
+
48
+ <%= pb_rails("image",
49
+ props: {
50
+ alt: "This is the alt text!",
51
+ on_error: "this.classList.add('image-error')",
52
+ rounded: true,
53
+ size: "xs",
54
+ url: "not_a_picture"
55
+ }
56
+ ) %>
57
+
58
+ <br>
59
+ <br>
60
+
61
+ <%= pb_rails("body",
62
+ props: {
63
+ text: "Or hide it completely:"
64
+ }
65
+ ) %>
66
+
67
+ <%= pb_rails("image",
68
+ props: {
69
+ alt: "This is the alt text!",
70
+ on_error: "this.style.display = 'none'",
71
+ rounded: true,
72
+ size: "xs",
73
+ url: "not_a_picture",
74
+ }
75
+ ) %>