playbook_ui 13.30.0 → 13.31.0.pre.alpha.play1262iconstyles3171

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +59 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.md +6 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -2
  5. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +4 -4
  6. data/app/pb_kits/playbook/pb_card/_card.tsx +4 -3
  7. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +1 -1
  8. data/app/pb_kits/playbook/pb_collapsible/index.js +6 -1
  9. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_default_swift.md +33 -0
  10. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_props_swift.md +18 -0
  11. data/app/pb_kits/playbook/pb_date_time_stacked/docs/example.yml +6 -1
  12. data/app/pb_kits/playbook/pb_draggable/_draggable.scss +2 -4
  13. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +70 -50
  14. data/app/pb_kits/playbook/pb_draggable/context/types.ts +26 -0
  15. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +2 -1
  16. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +1 -1
  17. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers.jsx +5 -1
  18. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.jsx +11 -4
  19. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.md +4 -2
  20. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.jsx +2 -2
  21. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +7 -1
  22. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.jsx +6 -4
  23. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.md +7 -0
  24. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +142 -15
  25. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -5
  26. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +18 -0
  27. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +228 -218
  28. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +9 -0
  29. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +34 -0
  30. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
  31. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
  32. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +14 -12
  33. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +7 -0
  34. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -2
  35. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +9 -3
  36. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.html.erb +32 -0
  37. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.jsx +48 -0
  38. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
  39. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +1 -0
  40. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +16 -11
  41. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.test.js +72 -0
  42. data/app/pb_kits/playbook/pb_icon/_icon.scss +223 -1
  43. data/app/pb_kits/playbook/pb_icon/_icon.tsx +136 -13
  44. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.html.erb +1 -1
  45. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +2 -3
  46. data/app/pb_kits/playbook/pb_icon/icon.rb +43 -17
  47. data/app/pb_kits/playbook/pb_icon/icon_aliases.json +39 -0
  48. data/app/pb_kits/playbook/pb_list/_list.tsx +4 -4
  49. data/app/pb_kits/playbook/pb_list/_list_item.tsx +7 -3
  50. data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +2 -2
  51. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.html.erb +1 -1
  52. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.jsx +1 -0
  53. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.md +3 -1
  54. data/app/pb_kits/playbook/pb_nav/item.html.erb +1 -1
  55. data/app/pb_kits/playbook/pb_nav/item.rb +1 -0
  56. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.html.erb +24 -0
  57. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_default.md +4 -4
  58. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_multi_directional.html.erb +11 -0
  59. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +4 -0
  60. data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +27 -0
  61. data/app/pb_kits/playbook/pb_overlay/overlay.rb +110 -0
  62. data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +7 -3
  63. data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +3 -3
  64. data/app/pb_kits/playbook/pb_table/table_header.html.erb +16 -2
  65. data/app/pb_kits/playbook/pb_timeline/_item.tsx +11 -10
  66. data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +8 -6
  67. data/app/pb_kits/playbook/utilities/globalProps.ts +1 -0
  68. data/dist/menu.yml +2 -2
  69. data/dist/playbook-rails.js +7 -7
  70. data/lib/playbook/version.rb +2 -2
  71. metadata +21 -5
@@ -3,6 +3,7 @@ import classnames from 'classnames'
3
3
  import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
  import { GlobalProps, globalProps } from '../utilities/globalProps'
5
5
  import { isValidEmoji } from '../utilities/validEmojiChecker'
6
+ import aliasesJson from './icon_aliases.json'
6
7
 
7
8
  export type IconSizes = "lg"
8
9
  | "xs"
@@ -40,11 +41,88 @@ type IconProps = {
40
41
  spin?: boolean,
41
42
  } & GlobalProps
42
43
 
44
+ type AliasType = string | string[];
45
+
46
+ interface Aliases {
47
+ [key: string]: AliasType;
48
+ }
49
+
50
+ interface AliasesJson {
51
+ aliases: Aliases;
52
+ }
53
+
54
+ const aliases: AliasesJson = aliasesJson;
55
+
56
+
43
57
  const flipMap = {
44
- horizontal: 'fa-flip-horizontal',
45
- vertical: 'fa-flip-vertical',
46
- both: 'fa-flip-horizontal fa-flip-vertical',
47
- none: ""
58
+ fa: {
59
+ horizontal: 'fa-flip-horizontal',
60
+ vertical: 'fa-flip-vertical',
61
+ both: 'fa-flip-horizontal fa-flip-vertical',
62
+ none: ''
63
+ },
64
+ svg: {
65
+ horizontal: 'flip_horizontal',
66
+ vertical: 'flip_vertical',
67
+ both: 'flip_horizontal flip_vertical',
68
+ none: ''
69
+ }
70
+ }
71
+ const pulseMap = {
72
+ fa: 'fa-pulse',
73
+ svg: 'pulse'
74
+ }
75
+ const spinMap = {
76
+ fa: 'fa-spin',
77
+ svg: 'spin'
78
+ }
79
+ const rotateMap = {
80
+ fa: {
81
+ 90: 'fa-rotate-90',
82
+ 180: 'fa-rotate-180',
83
+ 270: 'fa-rotate-270'
84
+ },
85
+ svg: {
86
+ 90: 'rotate_90',
87
+ 180: 'rotate_180',
88
+ 270: 'rotate_270'
89
+ }
90
+ }
91
+
92
+ const sizeMap = {
93
+ fa: {
94
+ "lg": "fa-lg",
95
+ "xs": "fa-xs",
96
+ "sm": "fa-sm",
97
+ "1x": "fa-1x",
98
+ "2x": "fa-2x",
99
+ "3x": "fa-3x",
100
+ "4x": "fa-4x",
101
+ "5x": "fa-5x",
102
+ "6x": "fa-6x",
103
+ "7x": "fa-7x",
104
+ "8x": "fa-8x",
105
+ "9x": "fa-9x",
106
+ "10x": "fa-10x",
107
+ "": ""
108
+ },
109
+ svg: {
110
+ "lg": "svg_lg",
111
+ "xs": "svg_xs",
112
+ "sm": "svg_sm",
113
+ "1x": "svg_1x",
114
+ "2x": "svg_2x",
115
+ "3x": "svg_3x",
116
+ "4x": "svg_4x",
117
+ "5x": "svg_5x",
118
+ "6x": "svg_6x",
119
+ "7x": "svg_7x",
120
+ "8x": "svg_8x",
121
+ "9x": "svg_9x",
122
+ "10x": "svg_10x",
123
+ "": ""
124
+ }
125
+
48
126
  }
49
127
 
50
128
  declare global {
@@ -52,6 +130,22 @@ declare global {
52
130
  var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
53
131
  }
54
132
 
133
+ // Resolve alias function
134
+ const resolveAlias = (icon: string): string => {
135
+ const alias = aliases.aliases[icon];
136
+
137
+ if (alias) {
138
+ if (Array.isArray(alias)) {
139
+ return alias[0];
140
+ } else {
141
+ return alias;
142
+ }
143
+ }
144
+
145
+ return icon;
146
+ };
147
+
148
+
55
149
  const Icon = (props: IconProps) => {
56
150
  const {
57
151
  aria = {},
@@ -74,7 +168,8 @@ const Icon = (props: IconProps) => {
74
168
  spin = false,
75
169
  } = props
76
170
 
77
- let iconElement: ReactSVGElement | null = typeof(icon) === "object" ? icon : null
171
+ const resolvedIcon = resolveAlias(icon as string)
172
+ let iconElement: ReactSVGElement | null = typeof(resolvedIcon) === "object" ? resolvedIcon : null
78
173
 
79
174
  const faClasses = {
80
175
  'fa-border': border,
@@ -90,32 +185,60 @@ const Icon = (props: IconProps) => {
90
185
 
91
186
  if (!customIcon && !iconElement) {
92
187
  const PowerIcon: React.FunctionComponent<any> | undefined =
93
- window.PB_ICONS ? window.PB_ICONS[icon as string] : null
188
+ window.PB_ICONS ? window.PB_ICONS[resolvedIcon as string] : null
94
189
 
95
190
  if (PowerIcon) {
96
191
  iconElement = <PowerIcon /> as ReactSVGElement
97
192
  } else {
98
- faClasses[`fa-${icon}`] = icon as string
193
+ faClasses[`fa-${resolvedIcon}`] = resolvedIcon as string
99
194
  }
100
195
  }
101
196
 
102
- const classes = classnames(
103
- flipMap[flip],
197
+ const isFA = !iconElement && !customIcon
198
+
199
+ let classes = classnames(
104
200
  (!iconElement && !customIcon) ? 'pb_icon_kit' : '',
105
201
  (iconElement || customIcon) ? 'pb_custom_icon' : fontStyle,
106
202
  iconElement ? 'svg-inline--fa' : '',
107
- faClasses,
203
+ isFA? fontStyle : null,
108
204
  globalProps(props),
109
205
  className
110
206
  )
111
207
 
208
+ const transformClasses = classnames(
209
+ flip ? flipMap[isFA ? 'fa' : 'svg'][flip] : null,
210
+ pulse ? pulseMap[isFA ? 'fa' : 'svg'] : null,
211
+ rotation ? rotateMap[isFA ? 'fa' : 'svg'][rotation] : null,
212
+ spin ? spinMap[isFA ? 'fa' : 'svg'] : null,
213
+ size ? sizeMap[isFA ? 'fa' : 'svg'][size] : null,
214
+ border ? isFA ? 'fa-border' : 'svg_border' : null,
215
+ fixedWidth ? isFA ? 'fa-fw' : 'svg_fw' : null,
216
+ inverse ? isFA ? 'fa-inverse' : 'svg_inverse' : null,
217
+ listItem ? isFA ? 'fa-li' : 'svg_li' : null,
218
+ pull ? isFA ? `fa-pull-${pull}` : `pull_${pull}` : null,
219
+ )
220
+ classes += ` ${transformClasses}`
221
+
222
+ if (isFA) {
223
+ const faClassList = {
224
+ 'fa-border': border,
225
+ 'fa-fw': (iconElement) ? false : fixedWidth,
226
+ 'fa-inverse': inverse,
227
+ 'fa-li': listItem,
228
+ [`fa-${size}`]: size,
229
+ [`fa-pull-${pull}`]: pull,
230
+ }
231
+ faClassList[`fa-${icon}`] = icon as string
232
+ classes += ` ${classnames(faClassList)}`
233
+ }
234
+
112
235
  const classesEmoji = classnames(
113
236
  'pb_icon_kit_emoji',
114
237
  globalProps(props),
115
238
  className
116
239
  )
117
240
 
118
- aria.label ? null : aria.label = `${icon} icon`
241
+ aria.label ? null : aria.label = `${resolvedIcon} icon`
119
242
  const ariaProps: {[key: string]: any} = buildAriaProps(aria)
120
243
  const dataProps: {[key: string]: any} = buildDataProps(data)
121
244
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -137,7 +260,7 @@ const Icon = (props: IconProps) => {
137
260
  }
138
261
  </>
139
262
  )
140
- else if (isValidEmoji(icon as string))
263
+ else if (isValidEmoji(resolvedIcon as string))
141
264
  return (
142
265
  <>
143
266
  <span
@@ -146,7 +269,7 @@ const Icon = (props: IconProps) => {
146
269
  className={classesEmoji}
147
270
  id={id}
148
271
  >
149
- {icon}
272
+ {resolvedIcon}
150
273
  </span>
151
274
  </>
152
275
  )
@@ -1 +1 @@
1
- <%= pb_rails("icon", props: { icon: "user", fixed_width: true }) %>
1
+ <%= pb_rails("icon", props: { icon: "user", fixed_width: true }) %>
@@ -1,6 +1,5 @@
1
- import React from 'react'
2
-
3
- import Icon from '../_icon'
1
+ import React from "react"
2
+ import Icon from "../_icon"
4
3
 
5
4
  const IconDefault = (props) => {
6
5
  return (
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/HashLikeCase
4
-
5
3
  require "open-uri"
4
+ require "json"
6
5
 
7
6
  module Playbook
8
7
  module PbIcon
@@ -38,6 +37,8 @@ module Playbook
38
37
  prop :spin, type: Playbook::Props::Boolean,
39
38
  default: false
40
39
 
40
+ ALIASES = JSON.parse(File.read(Playbook::Engine.root.join("app/pb_kits/playbook/pb_icon/icon_aliases.json")))["aliases"].freeze
41
+
41
42
  def valid_emoji?
42
43
  emoji_regex = /\p{Emoji}/
43
44
  emoji_regex.match?(icon)
@@ -83,7 +84,8 @@ module Playbook
83
84
  return unless Rails.application.config.respond_to?(:icon_path)
84
85
 
85
86
  base_path = Rails.application.config.icon_path
86
- icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{icon}.svg")).first
87
+ resolved_icon = resolve_alias(icon)
88
+ icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{resolved_icon}.svg")).first
87
89
  icon_path if icon_path && File.exist?(icon_path)
88
90
  end
89
91
 
@@ -106,16 +108,34 @@ module Playbook
106
108
 
107
109
  private
108
110
 
111
+ def resolve_alias(icon)
112
+ aliases = ALIASES[icon]
113
+ return icon unless aliases
114
+
115
+ if aliases.is_a?(Array)
116
+ aliases.find { |alias_name| file_exists?(alias_name) } || icon
117
+ else
118
+ aliases
119
+ end
120
+ end
121
+
122
+ def file_exists?(alias_name)
123
+ base_path = Rails.application.config.icon_path
124
+ File.exist?(Dir.glob(Rails.root.join(base_path, "**", "#{alias_name}.svg")).first)
125
+ end
126
+
109
127
  def svg_size
110
128
  size.nil? ? "1x" : size
111
129
  end
112
130
 
113
131
  def border_class
114
- border ? "fa-border" : nil
132
+ prefix = is_svg? ? "svg_border" : "fa-border"
133
+ border ? prefix : nil
115
134
  end
116
135
 
117
136
  def fixed_width_class
118
- fixed_width ? "fa-fw" : nil
137
+ prefix = is_svg? ? "svg_fw" : "fa-fw"
138
+ fixed_width ? prefix : nil
119
139
  end
120
140
 
121
141
  def icon_class
@@ -123,38 +143,45 @@ module Playbook
123
143
  end
124
144
 
125
145
  def inverse_class
126
- inverse ? "fa-inverse" : nil
146
+ class_name = is_svg? ? "svg_inverse" : "fa-inverse"
147
+ inverse ? class_name : nil
127
148
  end
128
149
 
129
150
  def list_item_class
130
- list_item ? "fa-li" : nil
151
+ class_name = is_svg? ? "svg_li" : "fa-li"
152
+ list_item ? class_name : nil
131
153
  end
132
154
 
133
155
  def flip_class
156
+ prefix = is_svg? ? "flip_" : "fa-flip-"
134
157
  case flip
135
158
  when "horizontal"
136
- "fa-flip-horizontal"
159
+ "#{prefix}horizontal"
137
160
  when "vertical"
138
- "fa-flip-vertical"
161
+ "#{prefix}vertical"
139
162
  when "both"
140
- "fa-flip-horizontal fa-flip-vertical"
163
+ "#{prefix}horizontal #{prefix}vertical"
141
164
  end
142
165
  end
143
166
 
144
167
  def pull_class
145
- pull ? "fa-pull-#{pull}" : nil
168
+ class_name = is_svg? ? "pull_#{pull}" : "fa-pull-#{pull}"
169
+ pull ? class_name : nil
146
170
  end
147
171
 
148
172
  def pulse_class
149
- pulse ? "fa-pulse" : nil
173
+ class_name = is_svg? ? "pulse" : "fa-pulse"
174
+ pulse ? class_name : nil
150
175
  end
151
176
 
152
177
  def rotation_class
153
- rotation ? "fa-rotate-#{rotation}" : nil
178
+ class_name = is_svg? ? "rotate_#{rotation}" : "fa-rotate-#{rotation}"
179
+ rotation ? class_name : nil
154
180
  end
155
181
 
156
182
  def size_class
157
- size ? "fa-#{size}" : nil
183
+ class_name = is_svg? ? "svg_#{size}" : "fa-#{size}"
184
+ size ? class_name : nil
158
185
  end
159
186
 
160
187
  def font_style_class
@@ -162,10 +189,9 @@ module Playbook
162
189
  end
163
190
 
164
191
  def spin_class
165
- spin ? "fa-spin" : nil
192
+ class_name = is_svg? ? "spin" : "fa-spin"
193
+ spin ? class_name : nil
166
194
  end
167
195
  end
168
196
  end
169
197
  end
170
-
171
- # rubocop:enable Style/HashLikeCase
@@ -0,0 +1,39 @@
1
+ {
2
+ "aliases": {
3
+ "arrow-alt-circle-right": "circle-right",
4
+ "angles-down": "angle-double-down",
5
+ "arrow-alt-down": "down",
6
+ "arrow-alt-up": "up",
7
+ "arrow-right-long": "long-arrow-right",
8
+ "arrow-to-bottom": "arrow-down-to-line",
9
+ "arrows-h": "arrows-left-right",
10
+ "calendar-days": "calendar-alt",
11
+ "circle-arrow-right": "arrow-circle-right",
12
+ "clock-rotate-left": "history",
13
+ "close": [
14
+ "times",
15
+ "xmark"
16
+ ],
17
+ "ellipsis-h": "ellipsis",
18
+ "exclamation-circle": "circle-exclamation",
19
+ "external-link": "arrow-up-right-from-square",
20
+ "file-lines": "file-alt",
21
+ "gear": "cog",
22
+ "home": "house",
23
+ "info-circle": "circle-info",
24
+ "map-o": "map",
25
+ "message": "comment-alt",
26
+ "minus-circle": "circle-minus",
27
+ "money": "money-bill",
28
+ "mouse-pointer": "arrow-pointer",
29
+ "nitro": "nitro-n",
30
+ "play-circle": "circle-play",
31
+ "plus-circle": "circle-plus",
32
+ "plus-square": "square-plus",
33
+ "powergon": "powergon-p",
34
+ "question-circle": "circle-question",
35
+ "roofing": "product-roofing",
36
+ "shelves": "inventory",
37
+ "th-list": "table-list"
38
+ }
39
+ }
@@ -10,7 +10,7 @@ type ListProps = {
10
10
  className?: string;
11
11
  children: React.ReactNode[] | React.ReactNode;
12
12
  dark?: boolean;
13
- draggable?: boolean;
13
+ enableDrag?: boolean;
14
14
  data?: Record<string, unknown>;
15
15
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
16
16
  id?: string;
@@ -32,7 +32,7 @@ const List = (props: ListProps) => {
32
32
  className,
33
33
  dark = false,
34
34
  data = {},
35
- draggable = false,
35
+ enableDrag = false,
36
36
  htmlOptions = {},
37
37
  id,
38
38
  layout = "",
@@ -54,7 +54,7 @@ const List = (props: ListProps) => {
54
54
  const childrenWithProps = React.Children.map(
55
55
  children,
56
56
  (child: React.ReactElement) => {
57
- return React.cloneElement(child, { text, variant, draggable });
57
+ return React.cloneElement(child, { text, variant, enableDrag });
58
58
  }
59
59
  );
60
60
  const ariaProps = buildAriaProps(aria);
@@ -74,7 +74,7 @@ const List = (props: ListProps) => {
74
74
  return (
75
75
  <>
76
76
  {
77
- draggable ? (
77
+ enableDrag ? (
78
78
  <Draggable.Container>
79
79
  <div className={classes}>
80
80
  {ordered ? (
@@ -11,6 +11,7 @@ type ListItemProps = {
11
11
  children: React.ReactNode[] | React.ReactNode,
12
12
  className?: string,
13
13
  data?: Record<string, unknown>,
14
+ dragId?: string,
14
15
  dragHandle?: boolean,
15
16
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
16
17
  id?: string,
@@ -23,7 +24,8 @@ const ListItem = (props: ListItemProps) => {
23
24
  children,
24
25
  className,
25
26
  data = {},
26
- draggable = false,
27
+ enableDrag,
28
+ dragId,
27
29
  dragHandle = true,
28
30
  htmlOptions = {},
29
31
  id,
@@ -42,8 +44,10 @@ const ListItem = (props: ListItemProps) => {
42
44
  return (
43
45
  <>
44
46
  {
45
- draggable ? (
46
- <Draggable.Item id={id}>
47
+ enableDrag ? (
48
+ <Draggable.Item
49
+ dragId={dragId}
50
+ >
47
51
  <li
48
52
  {...ariaProps}
49
53
  {...dataProps}
@@ -95,11 +95,11 @@ test('should not have a left border', () => {
95
95
  test('should have a right icon', () => {
96
96
  render(<NavDefault iconRight="angle-down" />)
97
97
  const kit = screen.getByTestId(itemTestId)
98
- expect(kit).toContainHTML('<i class="pb_icon_kit far fa-fw fa-angle-down pb_nav_list_item_icon_right" />')
98
+ expect(kit).toContainHTML('<i class="pb_icon_kit far far pb_nav_list_item_icon_right fa-fw fa-fw fa-angle-down" />')
99
99
  })
100
100
 
101
101
  test('should have a left icon', () => {
102
102
  render(<NavDefault iconLeft="users-class" />)
103
103
  const kit = screen.getByTestId(itemTestId)
104
- expect(kit).toContainHTML('<i class="pb_icon_kit far fa-fw fa-users-class pb_nav_list_item_icon_left" />')
104
+ expect(kit).toContainHTML('<i class="pb_icon_kit far far pb_nav_list_item_icon_left fa-fw fa-fw fa-users-class" />')
105
105
  })
@@ -1,5 +1,5 @@
1
1
  <%= pb_rails("nav", props: { variant: "bold" }) do %>
2
- <%= pb_rails("nav/item", props: { text: "Overview", link: "#", collapsible: true, icon_left:"city" }) do %>
2
+ <%= pb_rails("nav/item", props: { text: "Overview", link: "#", collapsible: true, icon_left:"city", collapsed: false }) do %>
3
3
  <%= pb_rails("nav", props: { variant: "bold" }) do %>
4
4
  <%= pb_rails("nav/item", props: { text: "City", link: "#" }) %>
5
5
  <%= pb_rails("nav/item", props: { text: "People", link: "#" }) %>
@@ -9,6 +9,7 @@ const CollapsibleNav = (props) => {
9
9
  >
10
10
  <NavItem
11
11
  active
12
+ collapsed={false}
12
13
  collapsible
13
14
  iconLeft="city"
14
15
  link="#"
@@ -1 +1,3 @@
1
- The `collapsible` prop allows users to create a nested, collapsible nav. Pass `collapsible` to any NavItem and pass that navItem any number of NavItems as children to create a collapsible nav.
1
+ The `collapsible` prop allows users to create a nested, collapsible nav. Pass `collapsible` to any NavItem and pass that navItem any number of NavItems as children to create a collapsible nav.
2
+
3
+ The optional `collapsed` prop can also be used to set the default state for the collapsed nav on first render of the page. `collapsed` takes a boolean value that is set to true (meaning nav is collapsed) by default. Set it to false as shown here to have the nav open on first render.
@@ -22,7 +22,7 @@
22
22
  </span>
23
23
  <% end %>
24
24
  <% end %>
25
- <%= pb_rails("collapsible/collapsible_content") do %>
25
+ <%= pb_rails("collapsible/collapsible_content", props: {collapsed: object.collapsed}) do %>
26
26
  <%= content.presence %>
27
27
  <% end %>
28
28
  <% end %>
@@ -12,6 +12,7 @@ module Playbook
12
12
  default: "regular"
13
13
  prop :highlighted_border, type: Playbook::Props::Boolean, default: true
14
14
  prop :collapsible, type: Playbook::Props::Boolean, default: false
15
+ prop :collapsed, type: Playbook::Props::Boolean, default: true
15
16
  prop :link
16
17
  prop :text
17
18
  prop :collapsible_trail, type: Playbook::Props::Boolean, default: false
@@ -0,0 +1,24 @@
1
+ <%= pb_rails("overlay") do %>
2
+ <%= pb_rails("table", props: { size: "sm" }) do %>
3
+ <thead>
4
+ <tr>
5
+ <th>Column 1</th>
6
+ <th>Column 2</th>
7
+ <th>Column 3</th>
8
+ <th>Column 4</th>
9
+ <th>Column 5</th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% 7.times do %>
14
+ <tr>
15
+ <td>Value 1</td>
16
+ <td>Value 2</td>
17
+ <td>Value 3</td>
18
+ <td>Value 4</td>
19
+ <td>Value 5</td>
20
+ </tr>
21
+ <% end %>
22
+ </tbody>
23
+ <% end %>
24
+ <% end %>
@@ -1,7 +1,7 @@
1
- Overlays require a `color`, which sets the "start" (opaque) color of a gradient mask. Because this overlay is intended to reveal underlying content, the "end" color is fixed to transparent.
1
+ Overlays optionally accept a `color`, which sets the "start" (opaque) color of a gradient mask. Because this overlay is intended to reveal underlying content, the "end" color is fixed to transparent.
2
2
 
3
- The optional `layout` prop accepts a `position` and a `size` as a key:value pair object.
3
+ The optional `layout` prop accepts the `position` and `size` of the overlay as a key:value pair.
4
4
 
5
- The `position` key accepts `top`, `bottom`, `y` (for both top and bottom) `right`, `left`, or `x` (for both left and right), which sets the side(s) where the `color` overlay starts. The direction of the overlay is always toward the opposite side of the position. For example, the default position of `bottom` starts the overlay on the bottom edge of your container and extends it toward the opposite side: the top.
5
+ The `position` key accepts `bottom` (default), `top`, `y` (for both top and bottom) `right`, `left`, or `x` (for both left and right), which sets the side(s) where the `color` overlay starts. The direction of the overlay is always toward the opposite side of the position. For example, the default position of `bottom` starts the overlay on the bottom edge of your container and extends it toward the opposite side: the top.
6
6
 
7
- The `size` value accepts our [spacing tokens](https://playbook.powerapp.cloud/visual_guidelines/spacing) or a percentage value as a string, and literally translates to how much of the container is covered by the overlay. By default, `size` is set to `full` (100%) so that your overlay covers the entire container with a smooth fade from `color` at its starting edge, fading to transparent and ending at the containers opposite edge.
7
+ The `size` value is `full` (100%) by default, but accepts our [spacing tokens](https://playbook.powerapp.cloud/visual_guidelines/spacing) or a percentage value as a string, and literally translates to how much of the container is covered by the overlay(s).
@@ -0,0 +1,11 @@
1
+ <%= pb_rails("overlay", props: { layout: { "x": "xl" }, color: "card_light" }) do %>
2
+ <%= pb_rails("flex", props: { column_gap: "lg", orientation: "row", overflow_x: "auto" }) do %>
3
+ <% 15.times do %>
4
+ <%= pb_rails("flex/flex_item") do %>
5
+ <%= pb_rails("card") do %>
6
+ Card content
7
+ <% end %>
8
+ <% end %>
9
+ <% end %>
10
+ <% end %>
11
+ <% end %>
@@ -2,3 +2,7 @@ examples:
2
2
  react:
3
3
  - overlay_default: Default
4
4
  - overlay_multi_directional: Multi-directional
5
+
6
+ rails:
7
+ - overlay_default: Default
8
+ - overlay_multi_directional: Multi-directional
@@ -0,0 +1,27 @@
1
+ <%= pb_content_tag(:div,
2
+ aria: object.aria,
3
+ class: object.classname,
4
+ data: object.data,
5
+ id: object.id,
6
+ **combined_html_options) do %>
7
+ <% if is_size_percentage %>
8
+ <div class="overlay_linear_gradient"
9
+ style="background: <%= previous_overlay %>"></div>
10
+
11
+ <%= content.presence %>
12
+
13
+ <% if has_subsequent_overlay %>
14
+ <div class="overlay_linear_gradient"
15
+ style="background: <%= subsequent_overlay %>"></div>
16
+ <% end %>
17
+
18
+ <% else %>
19
+ <div class="<%= previous_overlay_class_name %>"></div>
20
+
21
+ <%= content.presence %>
22
+
23
+ <% if has_subsequent_overlay %>
24
+ <div class="<%= subsequent_overlay_class_name %>"></div>
25
+ <% end %>
26
+ <% end %>
27
+ <% end %>