playbook_ui 13.11.0 → 13.12.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_collapsible/collapsible_content.rb +3 -1
  3. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_external_controls.html.erb +22 -0
  4. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_external_controls.md +3 -0
  5. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_external_controls_multiple.html.erb +40 -0
  6. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_external_controls_multiple.md +1 -0
  7. data/app/pb_kits/playbook/pb_collapsible/docs/example.yml +2 -0
  8. data/app/pb_kits/playbook/pb_collapsible/index.js +4 -0
  9. data/app/pb_kits/playbook/pb_icon/docs/_icon_border_swift.md +7 -0
  10. data/app/pb_kits/playbook/pb_icon/docs/_icon_default_swift.md +7 -0
  11. data/app/pb_kits/playbook/pb_icon/docs/_icon_flip_swift.md +11 -0
  12. data/app/pb_kits/playbook/pb_icon/docs/_icon_props_swift.md +8 -0
  13. data/app/pb_kits/playbook/pb_icon/docs/_icon_rotate_swift.md +11 -0
  14. data/app/pb_kits/playbook/pb_icon/docs/_icon_sizes_swift.md +46 -0
  15. data/app/pb_kits/playbook/pb_icon/docs/example.yml +8 -0
  16. data/app/pb_kits/playbook/pb_image/docs/_image_props_swift.md +7 -0
  17. data/app/pb_kits/playbook/pb_image/docs/_rounded_image_swift.md +47 -0
  18. data/app/pb_kits/playbook/pb_image/docs/_size_image_swift.md +47 -0
  19. data/app/pb_kits/playbook/pb_image/docs/_size_none_image_swift.md +15 -0
  20. data/app/pb_kits/playbook/pb_image/docs/example.yml +5 -0
  21. data/app/pb_kits/playbook/pb_label_value/docs/_label_value_default_swift.md +11 -0
  22. data/app/pb_kits/playbook/pb_label_value/docs/_label_value_details_examples_swift.md +72 -0
  23. data/app/pb_kits/playbook/pb_label_value/docs/_label_value_details_swift.md +41 -0
  24. data/app/pb_kits/playbook/pb_label_value/docs/_label_value_props_swift.md +11 -0
  25. data/app/pb_kits/playbook/pb_label_value/docs/example.yml +6 -0
  26. data/app/pb_kits/playbook/pb_message/docs/_message_default_swift.md +57 -0
  27. data/app/pb_kits/playbook/pb_message/docs/_message_props_swift.md +12 -0
  28. data/app/pb_kits/playbook/pb_message/docs/example.yml +4 -0
  29. data/app/pb_kits/playbook/pb_table/docs/_table_header.html.erb +4 -4
  30. data/app/pb_kits/playbook/pb_table/styles/_hover.scss +26 -2
  31. data/app/pb_kits/playbook/pb_table/styles/_table-dark.scss +1 -17
  32. data/app/pb_kits/playbook/pb_table/table_header.html.erb +4 -3
  33. data/app/pb_kits/playbook/pb_table/table_header.rb +28 -5
  34. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +25 -9
  35. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default.html.erb +1 -1
  36. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default_react.jsx +0 -2
  37. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay.jsx +0 -1
  38. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_interaction.jsx +0 -1
  39. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_margin.jsx +0 -1
  40. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_selectors.html.erb +1 -1
  41. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_show_tooltip.html.erb +39 -0
  42. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_show_tooltip.md +5 -0
  43. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_show_tooltip_react.jsx +45 -0
  44. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_show_tooltip_react.md +3 -0
  45. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +3 -0
  46. data/app/pb_kits/playbook/pb_tooltip/docs/index.js +1 -0
  47. data/app/pb_kits/playbook/pb_tooltip/index.js +6 -0
  48. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +2 -1
  49. data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +34 -0
  50. data/app/pb_kits/playbook/playbook-doc.js +1 -1
  51. data/dist/playbook-rails.js +3 -3
  52. data/lib/playbook/pb_doc_helper.rb +2 -21
  53. data/lib/playbook/version.rb +2 -2
  54. metadata +26 -3
  55. data/app/pb_kits/playbook/pb_dawg/docs/example.yml +0 -9
@@ -1,6 +1,7 @@
1
1
  @import "../../tokens/opacity";
2
2
 
3
3
  $transition-speed: 0.2s;
4
+ $border_hover_color_dark: lighten($border_dark, 5%);
4
5
 
5
6
  [class^=pb_table] {
6
7
  &.table-sm,
@@ -15,9 +16,9 @@ $transition-speed: 0.2s;
15
16
  td {
16
17
  border-top-color: transparent;
17
18
  border-top-width: 0;
18
- transition: all $transition-speed ease;
19
+ transition: all $transition-speed ease;
19
20
  }
20
- @media (hover:hover) {
21
+ @media (hover:hover) {
21
22
  td {
22
23
  position: relative;
23
24
  &:after {
@@ -69,6 +70,29 @@ $transition-speed: 0.2s;
69
70
  }
70
71
  }
71
72
  }
73
+
74
+ &.dark {
75
+ tbody {
76
+ tr {
77
+ @media (hover:hover) {
78
+ &:hover {
79
+ box-shadow: 0 2px 10px 0 $shadow_dark;
80
+ td {
81
+ border-top-width: 0;
82
+ border-top-color: transparent;
83
+ border-color: $border_hover_color_dark !important;
84
+ &:after {
85
+ transition: background-color $transition-speed ease, height $transition-speed ease;
86
+ background-color: $border_hover_color_dark !important;
87
+ height: 1px;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+
72
96
  }
73
97
  }
74
98
  }
@@ -1,6 +1,6 @@
1
1
  @import "../../tokens/screen_sizes";
2
2
 
3
- $table-dark-card-bg: $bg_dark;
3
+ $table-dark-card-bg: $card_dark;
4
4
 
5
5
  [class^=pb_table] {
6
6
  &.table-sm,
@@ -24,7 +24,6 @@ $table-dark-card-bg: $bg_dark;
24
24
 
25
25
  td {
26
26
  border-color: $border_dark !important;
27
- border-bottom-width: 0 !important;
28
27
  color: $white;
29
28
 
30
29
  &:before {
@@ -39,21 +38,6 @@ $table-dark-card-bg: $bg_dark;
39
38
  }
40
39
  }
41
40
 
42
- &:not(.no-hover) {
43
- tbody {
44
- tr {
45
- @media (hover:hover) {
46
- &:hover {
47
- td {
48
- border-color: $border_dark !important;
49
- background: $bg_dark;
50
- }
51
- }
52
- }
53
- }
54
- }
55
- }
56
-
57
41
  &.table-card {
58
42
  background: $table-dark-card-bg !important;
59
43
  }
@@ -28,15 +28,16 @@
28
28
  position: object.placement ,
29
29
  padding: 'none'}) do %>
30
30
  <%= pb_rails("nav", props: {classname: "pb_table_header_dropdown"}) do %>
31
- <% object.sort_menu.each_with_index do |item, index| %>
31
+ <% object.sort_items.each do |sort_item| %>
32
+ <% item = active_or_first_item(sort_items_for(sort_item)) %>
32
33
  <%= pb_rails("nav/item", props: {
33
34
  text: item[:item],
34
- link: item[:link],
35
+ link: next_link(sort_item: sort_item),
35
36
  highlighted_border: false,
36
37
  padding: "xs",
37
38
  icon_right: sort_icon(item[:direction], item[:active]),
38
39
  active: item[:active],
39
- classname: "header_nav_item #{'header_first_item' if index == 0} #{'header_last_item' if index == object.sort_menu.size - 1}"
40
+ classname: "header_nav_item"
40
41
  }) %>
41
42
  <% end %>
42
43
  <% end %>
@@ -32,20 +32,43 @@ module Playbook
32
32
  align.present? ? "align_#{align}" : nil
33
33
  end
34
34
 
35
- def next_link
36
- return sort_menu[0][:link] if sort_menu.all? { |item| item[:active] == false }
35
+ def next_link(sort_item: "")
36
+ sort_menu_for = if sort_item.blank?
37
+ sort_menu
38
+ else
39
+ sort_items_for(sort_item)
40
+ end
41
+
42
+ return sort_menu_for[0][:link] if sort_menu_for.all? { |item| item[:active] == false }
37
43
 
38
44
  link = ""
39
45
 
40
- sort_menu.each_with_index do |item, index|
46
+ sort_menu_for.each_with_index do |item, index|
41
47
  if item[:active] == true
42
- next_index = (index + 1) % sort_menu.length
43
- link = sort_menu[next_index][:link]
48
+ next_index = (index + 1) % sort_menu_for.length
49
+ link = sort_menu_for[next_index][:link]
44
50
  end
45
51
  end
46
52
  link
47
53
  end
48
54
 
55
+ def sort_items
56
+ sort_menu.map { |hash| hash[:item] }.uniq
57
+ end
58
+
59
+ def sort_items_for(sort_item)
60
+ sort_menu.find_all { |hash| hash[:item] == sort_item }
61
+ end
62
+
63
+ def active_or_first_item(items)
64
+ active_item = items.find { |hash| hash[:active] == true }
65
+ if active_item.present?
66
+ active_item
67
+ else
68
+ items[0]
69
+ end
70
+ end
71
+
49
72
  def sorting_style?
50
73
  sort_menu != [{}]
51
74
  end
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState } from "react"
1
+ import React, { useRef, useState, forwardRef, ForwardedRef } from "react"
2
2
 
3
3
  import {
4
4
  arrow,
@@ -28,9 +28,10 @@ type TooltipProps = {
28
28
  placement?: Placement,
29
29
  position?: "absolute" | "fixed";
30
30
  text: string,
31
+ showTooltip?: boolean,
31
32
  } & GlobalProps
32
33
 
33
- const Tooltip = (props: TooltipProps): React.ReactElement => {
34
+ const Tooltip = forwardRef((props: TooltipProps, ref: ForwardedRef<unknown>): React.ReactElement => {
34
35
  const {
35
36
  aria = {},
36
37
  className,
@@ -42,6 +43,7 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
42
43
  placement: preferredPlacement = "top",
43
44
  position = "absolute",
44
45
  text,
46
+ showTooltip = true,
45
47
  zIndex,
46
48
  ...rest
47
49
  } = props
@@ -59,10 +61,9 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
59
61
 
60
62
  const {
61
63
  context,
62
- floating,
63
64
  middlewareData: { arrow: { x: arrowX, y: arrowY } = {}, },
64
65
  placement,
65
- reference,
66
+ refs,
66
67
  strategy,
67
68
  x,
68
69
  y,
@@ -82,12 +83,16 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
82
83
  ],
83
84
  open,
84
85
  onOpenChange(open) {
85
- setOpen(open)
86
+ if(!showTooltip) {
87
+ return
88
+ } else {
89
+ setOpen(open)
90
+ }
86
91
  },
87
92
  placement: preferredPlacement
88
93
  })
89
94
 
90
-
95
+
91
96
  const { getFloatingProps } = useInteractions([
92
97
  useHover(context, {
93
98
  delay,
@@ -108,7 +113,16 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
108
113
  <>
109
114
  <div
110
115
  className={`pb_tooltip_kit ${css}`}
111
- ref={reference}
116
+ ref={(element) => {
117
+ refs.setReference(element);
118
+ if (ref) {
119
+ if (typeof ref === "function") {
120
+ ref(element);
121
+ } else if (typeof ref === "object") {
122
+ ref.current = element;
123
+ }
124
+ }
125
+ }}
112
126
  role="tooltip_trigger"
113
127
  style={{ display: "inline-flex" }}
114
128
  {...ariaProps}
@@ -120,7 +134,7 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
120
134
  <div
121
135
  {...getFloatingProps({
122
136
  className: `tooltip_tooltip ${placement} visible`,
123
- ref: floating,
137
+ ref: refs.setFloating,
124
138
  role: "tooltip",
125
139
  style: {
126
140
  position: strategy,
@@ -153,6 +167,8 @@ const Tooltip = (props: TooltipProps): React.ReactElement => {
153
167
  )}
154
168
  </>
155
169
  )
156
- }
170
+ })
171
+
172
+ Tooltip.displayName = "Tooltip"
157
173
 
158
174
  export default Tooltip
@@ -1,4 +1,4 @@
1
- <%= pb_rails("flex", props: { gap: "md", justify: "center", wrap: true }) do %>
1
+ <%= pb_rails("flex", props: { gap: "md", wrap: true }) do %>
2
2
  <%= pb_rails("flex/flex_item") do %>
3
3
  <span id='regular-tooltip-1'>Hover here (Top)</span>
4
4
 
@@ -9,12 +9,10 @@ const TooltipDefaultReact = (props) => {
9
9
  <Flex
10
10
  flexDirection='row'
11
11
  gap='md'
12
- justifyContent='center'
13
12
  wrap
14
13
  >
15
14
  <FlexItem>
16
15
  <Tooltip
17
- className={"customClassNameHere"}
18
16
  placement='top'
19
17
  text="Whoa. I'm a Tooltip"
20
18
  zIndex={10}
@@ -9,7 +9,6 @@ const TooltipDelay = (props) => {
9
9
  <Flex
10
10
  flexDirection='row'
11
11
  gap='md'
12
- justifyContent='center'
13
12
  wrap
14
13
  >
15
14
  <FlexItem>
@@ -9,7 +9,6 @@ const TooltipInteraction = (props) => {
9
9
  <Flex
10
10
  flexDirection='row'
11
11
  gap='md'
12
- justifyContent='center'
13
12
  wrap
14
13
  >
15
14
  <FlexItem>
@@ -7,7 +7,6 @@ const TooltipMargin = (props) => {
7
7
  return (
8
8
  <Flex
9
9
  flexDirection='row'
10
- justifyContent='center'
11
10
  wrap
12
11
  >
13
12
  <Tooltip
@@ -1,4 +1,4 @@
1
- <%= pb_rails("flex", props: { horizontal: "center", orientation: "column" }) do %>
1
+ <%= pb_rails("flex", props: { orientation: "column" }) do %>
2
2
  <%= pb_rails("flex/flex_item", props: {margin_top: "md"}) do %>
3
3
  <%= pb_rails("button", props: {classname: "tooltip-example-trigger", text: "Example 1"}) %>
4
4
  <% end %>
@@ -0,0 +1,39 @@
1
+
2
+ <%= pb_rails("flex", props: { orientation: "column", gap: "md" }) do %>
3
+ <%= pb_rails("button", props: {text: "Toggle state", id: "toggle-tooltip-button"}) %>
4
+ <%= pb_rails("body") do %>
5
+ Tooltip is: <code id="show-tooltip-state">enabled</code>
6
+ <% end %>
7
+ <%= pb_rails("flex/flex_item") do %>
8
+ <span id="truncated-tooltip-1">Hover me</span>
9
+ <%= pb_rails("tooltip", props: {
10
+ trigger_element_selector: "#truncated-tooltip-1",
11
+ tooltip_id: "truncated-1",
12
+ position: "right",
13
+ }) do %>
14
+ Tooltip is enabled
15
+ <% end %>
16
+ <% end %>
17
+ <% end %>
18
+
19
+
20
+ <script>
21
+ const toggleTooltipButton = document.getElementById("toggle-tooltip-button");
22
+ const showTooltipStateText = document.getElementById("show-tooltip-state");
23
+
24
+ function hideTooltipIfNotTruncated(tooltipId) {
25
+ const tooltipElement = document.querySelector(
26
+ `[data-pb-tooltip-tooltip-id="${tooltipId}"]`
27
+ );
28
+
29
+ tooltipElement.dataset.pbTooltipShowTooltip =
30
+ tooltipElement.dataset.pbTooltipShowTooltip == "false" ? "true" : "false";
31
+
32
+ showTooltipStateText.innerText =
33
+ tooltipElement.dataset.pbTooltipShowTooltip == "false" ? "disabled" : "enabled";
34
+ }
35
+
36
+ toggleTooltipButton.addEventListener("click", () => {
37
+ hideTooltipIfNotTruncated("truncated-1");
38
+ });
39
+ </script>
@@ -0,0 +1,5 @@
1
+ You can build your own logic to control whether to show or hide the tooltip.
2
+
3
+ Click on the `Toggle state` button to change the state of the component and hover over the 'hover me' text to see it in action.
4
+
5
+ Each Tooltip has a `dataset` with the `pbTooltipShowTooltip` property set to true by default. To update it, access the `pbTooltipShowTooltip` in the dataset of your tooltip element: `yourTooltip.dataset.pbTooltipShowTooltip = 'false'`
@@ -0,0 +1,45 @@
1
+ // @flow
2
+
3
+ import React, { useState } from 'react'
4
+ import { Button, Body, Flex, FlexItem, Tooltip } from '../..'
5
+
6
+ const TooltipShowTooltipReact = (props) => {
7
+ const [showTooltip, setShowTooltip] = useState(true);
8
+
9
+ return (
10
+ <Flex
11
+ flexDirection='column'
12
+ gap='md'
13
+ wrap
14
+ >
15
+ <FlexItem>
16
+ <Button
17
+ onClick={()=> setShowTooltip(!showTooltip)}
18
+ text="Toggle state"
19
+ />
20
+ </FlexItem>
21
+ <FlexItem>
22
+ <Body >
23
+ <p>
24
+ {'Tooltip is: '}
25
+ <code>{showTooltip ? "enabled" : "disabled"}</code>
26
+ </p>
27
+ </Body>
28
+ </FlexItem>
29
+ <FlexItem>
30
+ <Tooltip
31
+ placement='right'
32
+ showTooltip={showTooltip}
33
+ text='Tooltip is enabled'
34
+ zIndex={10}
35
+ {...props}
36
+ >
37
+ {'Hover me.'}
38
+ </Tooltip>
39
+ </FlexItem>
40
+
41
+ </Flex>
42
+ )
43
+ }
44
+
45
+ export default TooltipShowTooltipReact
@@ -0,0 +1,3 @@
1
+ You can build your own logic to control whether to show the tooltip using the `showTooltip` prop. Its default value is `true`.
2
+
3
+ Click on the `Toggle state` button to change the state of the component and hover over the 'hover me' text to see it in action.
@@ -4,6 +4,7 @@ examples:
4
4
  - tooltip_default: Default
5
5
  - tooltip_selectors: Using Common Selectors
6
6
  - tooltip_with_icon_circle: Icon Circle Tooltip
7
+ - tooltip_show_tooltip: Show Tooltip
7
8
 
8
9
  react:
9
10
  - tooltip_default_react: Default
@@ -11,3 +12,5 @@ examples:
11
12
  - tooltip_margin: Margin
12
13
  - tooltip_icon: Tooltip with Icon
13
14
  - tooltip_delay: Delay
15
+ - tooltip_show_tooltip_react: Show Tooltip
16
+
@@ -3,3 +3,4 @@ export { default as TooltipInteraction } from './_tooltip_interaction'
3
3
  export { default as TooltipMargin } from './_tooltip_margin'
4
4
  export { default as TooltipIcon } from './_tooltip_icon'
5
5
  export { default as TooltipDelay } from './_tooltip_delay'
6
+ export { default as TooltipShowTooltipReact } from './_tooltip_show_tooltip_react'
@@ -54,6 +54,8 @@ export default class PbTooltip extends PbEnhancedElement {
54
54
  }
55
55
 
56
56
  showTooltip(trigger) {
57
+ if (this.shouldShowTooltip === "false") return
58
+
57
59
  this.popper = createPopper(trigger, this.tooltip, {
58
60
  placement: this.position,
59
61
  modifiers: [
@@ -127,4 +129,8 @@ export default class PbTooltip extends PbEnhancedElement {
127
129
  get triggerElementSelector() {
128
130
  return this.element.dataset.pbTooltipTriggerElementSelector
129
131
  }
132
+
133
+ get shouldShowTooltip() {
134
+ return this.element.dataset.pbTooltipShowTooltip
135
+ }
130
136
  }
@@ -20,7 +20,8 @@ module Playbook
20
20
  pb_tooltip_position: position,
21
21
  pb_tooltip_trigger_element_selector: trigger_element_selector,
22
22
  pb_tooltip_trigger_element_id: trigger_element_id,
23
- pb_tooltip_tooltip_id: tooltip_id
23
+ pb_tooltip_tooltip_id: tooltip_id,
24
+ pb_tooltip_show_tooltip: true
24
25
  )
25
26
  end
26
27
 
@@ -92,5 +92,39 @@ test("has position fixed", async () => {
92
92
  cleanup();
93
93
  })
94
94
 
95
+ cleanup();
96
+ });
97
+
98
+ test("display tooltip with showTooltip set to true", async () => {
99
+ render(
100
+ <Tooltip
101
+ data={{ testid: "fixed-position-test" }}
102
+ showTooltip
103
+ />
104
+ );
105
+
106
+ fireEvent.mouseEnter(screen.getByRole("tooltip_trigger"));
107
+ await waitFor(() => {
108
+ expect(screen.queryByRole("tooltip")).toBeInTheDocument();
109
+ cleanup();
110
+ })
111
+
112
+ cleanup();
113
+ });
114
+
115
+ test("doesn't display tooltip with showTooltip set to false", async () => {
116
+ render(
117
+ <Tooltip
118
+ data={{ testid: "fixed-position-test" }}
119
+ showTooltip={false}
120
+ />
121
+ );
122
+
123
+ fireEvent.mouseEnter(screen.getByRole("tooltip_trigger"));
124
+ await waitFor(() => {
125
+ expect(screen.queryByRole("tooltip")).not.toBeInTheDocument();
126
+ cleanup();
127
+ })
128
+
95
129
  cleanup();
96
130
  });
@@ -104,7 +104,7 @@ import * as UserBadge from 'pb_user_badge/docs'
104
104
  import * as Walkthrough from 'pb_walkthrough/docs'
105
105
  import * as WeekdayStacked from 'pb_weekday_stacked/docs'
106
106
 
107
- WebpackerReact.setup({
107
+ WebpackerReact.registerComponents({
108
108
  ...Avatar,
109
109
  ...AvatarActionButton,
110
110
  ...Background,