playbook_ui 13.30.0.pre.alpha.PBNTR353draggablev53136 → 13.30.0.pre.alpha.20240515remotebuildkitconversion3150

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) 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_collapsible/index.js +6 -1
  7. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_default_swift.md +33 -0
  8. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_date_time_stacked_props_swift.md +18 -0
  9. data/app/pb_kits/playbook/pb_date_time_stacked/docs/example.yml +6 -1
  10. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.md +2 -2
  11. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +1 -1
  12. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.md +1 -1
  13. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +18 -0
  14. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +228 -218
  15. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +9 -0
  16. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +34 -0
  17. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
  18. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
  19. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +14 -12
  20. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +7 -0
  21. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -2
  22. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +9 -3
  23. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.html.erb +32 -0
  24. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_custom_icon.jsx +48 -0
  25. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
  26. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +1 -0
  27. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +16 -11
  28. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.test.js +72 -0
  29. data/app/pb_kits/playbook/pb_icon/_icon.tsx +37 -6
  30. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.html.erb +6 -1
  31. data/app/pb_kits/playbook/pb_icon/docs/_icon_default.jsx +21 -5
  32. data/app/pb_kits/playbook/pb_icon/icon.rb +21 -1
  33. data/app/pb_kits/playbook/pb_icon/icon_aliases.json +39 -0
  34. data/app/pb_kits/playbook/pb_icon/types.d.ts +1 -0
  35. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.html.erb +1 -1
  36. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.jsx +1 -0
  37. data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav.md +3 -1
  38. data/app/pb_kits/playbook/pb_nav/item.html.erb +1 -1
  39. data/app/pb_kits/playbook/pb_nav/item.rb +1 -0
  40. data/app/pb_kits/playbook/pb_table/table_header.html.erb +16 -2
  41. data/dist/playbook-rails.js +7 -7
  42. data/lib/playbook/version.rb +1 -1
  43. metadata +13 -2
@@ -23,6 +23,7 @@ type FixedConfirmationToastProps = {
23
23
  data?: string;
24
24
  horizontal?: "right" | "left" | "center";
25
25
  htmlOptions?: { [key: string]: string | number | boolean | (VoidCallback) };
26
+ icon?: string,
26
27
  id?: string;
27
28
  multiLine?: boolean;
28
29
  onClose?: VoidCallback;
@@ -41,6 +42,7 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
41
42
  closeable = false,
42
43
  horizontal,
43
44
  htmlOptions = {},
45
+ icon,
44
46
  multiLine = false,
45
47
  onClose = () => undefined,
46
48
  open = true,
@@ -48,14 +50,18 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
48
50
  text,
49
51
  vertical,
50
52
  } = props;
53
+
54
+ const returnedIcon = icon || iconMap[status]
55
+ const iconClass = icon ? "custom_icon" : ""
56
+
51
57
  const css = classnames(
52
58
  `pb_fixed_confirmation_toast_kit_${status}`,
53
59
  { _multi_line: multiLine },
54
60
  { [`positioned_toast ${vertical} ${horizontal}`]: vertical && horizontal },
61
+ `${iconClass}`,
55
62
  globalProps(props),
56
63
  className
57
64
  );
58
- const icon = iconMap[status];
59
65
 
60
66
  const htmlProps = buildHtmlProps(htmlOptions);
61
67
 
@@ -86,11 +92,11 @@ const FixedConfirmationToast = (props: FixedConfirmationToastProps): React.React
86
92
  onClick={handleClick}
87
93
  {...htmlProps}
88
94
  >
89
- {icon && (
95
+ {returnedIcon && (
90
96
  <Icon
91
97
  className="pb_icon"
92
98
  fixedWidth
93
- icon={icon}
99
+ icon={returnedIcon}
94
100
  />
95
101
  )}
96
102
 
@@ -0,0 +1,32 @@
1
+ <div>
2
+ <%= pb_rails("fixed_confirmation_toast", props: {
3
+ icon: "wrench",
4
+ text: "Fix before proceeding",
5
+ status: "error",
6
+ closeable: true,
7
+ margin_bottom: "md"
8
+ })%>
9
+ </div>
10
+ <div>
11
+ <%= pb_rails("fixed_confirmation_toast", props: {
12
+ icon: "star",
13
+ text: "Thank you for completing the form!",
14
+ status: "success",
15
+ margin_bottom: "md"
16
+ })%>
17
+ </div>
18
+ <div>
19
+ <%= pb_rails("fixed_confirmation_toast", props: {
20
+ icon: "file-pdf",
21
+ text: "Saved as PDF",
22
+ status: "neutral",
23
+ margin_bottom: "md"
24
+ })%>
25
+ </div>
26
+ <div>
27
+ <%= pb_rails("fixed_confirmation_toast", props: {
28
+ icon: "arrow-down",
29
+ text: "New Messages",
30
+ status: "tip"
31
+ })%>
32
+ </div>
@@ -0,0 +1,48 @@
1
+ import React from 'react'
2
+
3
+ import FixedConfirmationToast from '../_fixed_confirmation_toast'
4
+
5
+ const FixedConfirmationToastCustomIcon = (props) => {
6
+ return (
7
+ <div>
8
+ <div>
9
+ <FixedConfirmationToast
10
+ closeable
11
+ icon="wrench"
12
+ marginBottom="md"
13
+ status="error"
14
+ text="Fix before proceeding"
15
+ {...props}
16
+ />
17
+ </div>
18
+ <div>
19
+ <FixedConfirmationToast
20
+ icon="star"
21
+ marginBottom="md"
22
+ status="success"
23
+ text="Thank you for completing the form!"
24
+ {...props}
25
+ />
26
+ </div>
27
+ <div>
28
+ <FixedConfirmationToast
29
+ icon="file-pdf"
30
+ marginBottom="md"
31
+ status="neutral"
32
+ text="Saved as PDF"
33
+ {...props}
34
+ />
35
+ </div>
36
+ <div>
37
+ <FixedConfirmationToast
38
+ icon="arrow-down"
39
+ status="tip"
40
+ text="New Messages"
41
+ {...props}
42
+ />
43
+ </div>
44
+ </div>
45
+ )
46
+ }
47
+
48
+ export default FixedConfirmationToastCustomIcon
@@ -6,6 +6,7 @@ examples:
6
6
  - fixed_confirmation_toast_close: Click to Close
7
7
  - fixed_confirmation_toast_positions: Click to Show Positions
8
8
  - fixed_confirmation_toast_children: Children
9
+ - fixed_confirmation_toast_custom_icon: Custom Icon
9
10
 
10
11
  react:
11
12
  - fixed_confirmation_toast_default: Default
@@ -14,6 +15,7 @@ examples:
14
15
  - fixed_confirmation_toast_positions: Click to Show Positions
15
16
  - fixed_confirmation_toast_auto_close: Click to Show Auto Close
16
17
  - fixed_confirmation_toast_children: Children
18
+ - fixed_confirmation_toast_custom_icon: Custom Icon
17
19
 
18
20
  swift:
19
21
  - fixed_confirmation_toast_default_swift: Default
@@ -4,3 +4,4 @@ export { default as FixedConfirmationToastClose } from './_fixed_confirmation_to
4
4
  export { default as FixedConfirmationToastPositions } from './_fixed_confirmation_toast_positions.jsx'
5
5
  export { default as FixedConfirmationToastAutoClose } from './_fixed_confirmation_toast_auto_close.jsx'
6
6
  export { default as FixedConfirmationToastChildren } from './_fixed_confirmation_toast_children.jsx'
7
+ export { default as FixedConfirmationToastCustomIcon } from './_fixed_confirmation_toast_custom_icon.jsx'
@@ -20,6 +20,7 @@ module Playbook
20
20
  values: [nil, "top", "bottom"],
21
21
  default: nil
22
22
  prop :auto_close, type: Playbook::Props::Number
23
+ prop :icon, type: Playbook::Props::String
23
24
 
24
25
  def show_text?
25
26
  text.present?
@@ -42,20 +43,24 @@ module Playbook
42
43
  end
43
44
 
44
45
  def icon_value
45
- case status
46
- when "success"
47
- "check"
48
- when "error"
49
- "exclamation-triangle"
50
- when "neutral"
51
- "info-circle"
52
- when "tip"
53
- "info-circle"
54
- end
46
+ icon || case status
47
+ when "success"
48
+ "check"
49
+ when "error"
50
+ "exclamation-triangle"
51
+ when "neutral"
52
+ "info-circle"
53
+ when "tip"
54
+ "info-circle"
55
+ end
56
+ end
57
+
58
+ def icon_class
59
+ icon.present? ? " custom_icon" : ""
55
60
  end
56
61
 
57
62
  def classname
58
- generate_classname("pb_fixed_confirmation_toast_kit", status, multi_line_class) + close_class + position_class + auto_close_class
63
+ generate_classname("pb_fixed_confirmation_toast_kit", status, multi_line_class) + close_class + position_class + auto_close_class + icon_class
59
64
  end
60
65
  end
61
66
  end
@@ -0,0 +1,72 @@
1
+ import React from 'react'
2
+ import { render, waitFor } from '../utilities/test-utils'
3
+
4
+ import { FixedConfirmationToast } from '../'
5
+
6
+ beforeEach(() => {
7
+ // Silences error logs within the test suite.
8
+ jest.spyOn(console, 'error')
9
+ // eslint-disable-next-line
10
+ console.error.mockImplementation(() => {})
11
+ })
12
+
13
+ afterEach(() => {
14
+ // eslint-disable-next-line
15
+ console.error.mockRestore()
16
+ })
17
+
18
+ test('renders with default props', () => {
19
+ const { container } = render(<FixedConfirmationToast />);
20
+ expect(container.firstChild).toBeInTheDocument();
21
+ });
22
+
23
+ test('renders with text', () => {
24
+ const { getByText } = render(<FixedConfirmationToast text="Message Text" />);
25
+ expect(getByText('Message Text')).toBeInTheDocument();
26
+ });
27
+
28
+ test('does not render if open prop is false', () => {
29
+ const { container } = render(<FixedConfirmationToast open={false} />);
30
+ expect(container.firstChild).toBeNull();
31
+ });
32
+
33
+ test('closes after autoClose duration', async () => {
34
+ jest.useFakeTimers();
35
+ const onCloseMock = jest.fn();
36
+ render(
37
+ <FixedConfirmationToast
38
+ autoClose={1000}
39
+ onClose={onCloseMock}
40
+ open
41
+ />
42
+ );
43
+
44
+ jest.advanceTimersByTime(1000);
45
+ await waitFor(() => expect(onCloseMock).toHaveBeenCalled());
46
+ });
47
+
48
+ test('renders success status with icon', () => {
49
+ const { container } = render(<FixedConfirmationToast status="success" />);
50
+ expect(container.querySelector('.pb_fixed_confirmation_toast_kit_success')).toBeInTheDocument();
51
+ expect(container.querySelector('.pb_icon')).toBeInTheDocument();
52
+ });
53
+
54
+ test('renders custom icon when provided', () => {
55
+ const { container } = render(<FixedConfirmationToast icon="wrench" />);
56
+ expect(container.querySelector('.custom_icon')).toBeInTheDocument();
57
+ });
58
+
59
+ test('renders correctly with multiLine prop', () => {
60
+ const { container } = render(<FixedConfirmationToast multiLine />);
61
+ expect(container.querySelector('._multi_line')).toBeInTheDocument();
62
+ });
63
+
64
+ test('renders position when provided', () => {
65
+ const { container } = render(
66
+ <FixedConfirmationToast
67
+ horizontal="right"
68
+ vertical="bottom"
69
+ />
70
+ );
71
+ expect(container.querySelector('.positioned_toast')).toBeInTheDocument();
72
+ });
@@ -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,6 +41,19 @@ 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
58
  horizontal: 'fa-flip-horizontal',
45
59
  vertical: 'fa-flip-vertical',
@@ -52,6 +66,22 @@ declare global {
52
66
  var PB_ICONS: {[key: string]: React.FunctionComponent<any>}
53
67
  }
54
68
 
69
+ // Resolve alias function
70
+ const resolveAlias = (icon: string): string => {
71
+ const alias = aliases.aliases[icon];
72
+
73
+ if (alias) {
74
+ if (Array.isArray(alias)) {
75
+ return alias[0];
76
+ } else {
77
+ return alias;
78
+ }
79
+ }
80
+
81
+ return icon;
82
+ };
83
+
84
+
55
85
  const Icon = (props: IconProps) => {
56
86
  const {
57
87
  aria = {},
@@ -74,7 +104,8 @@ const Icon = (props: IconProps) => {
74
104
  spin = false,
75
105
  } = props
76
106
 
77
- let iconElement: ReactSVGElement | null = typeof(icon) === "object" ? icon : null
107
+ const resolvedIcon = resolveAlias(icon as string)
108
+ let iconElement: ReactSVGElement | null = typeof(resolvedIcon) === "object" ? resolvedIcon : null
78
109
 
79
110
  const faClasses = {
80
111
  'fa-border': border,
@@ -90,12 +121,12 @@ const Icon = (props: IconProps) => {
90
121
 
91
122
  if (!customIcon && !iconElement) {
92
123
  const PowerIcon: React.FunctionComponent<any> | undefined =
93
- window.PB_ICONS ? window.PB_ICONS[icon as string] : null
124
+ window.PB_ICONS ? window.PB_ICONS[resolvedIcon as string] : null
94
125
 
95
126
  if (PowerIcon) {
96
127
  iconElement = <PowerIcon /> as ReactSVGElement
97
128
  } else {
98
- faClasses[`fa-${icon}`] = icon as string
129
+ faClasses[`fa-${resolvedIcon}`] = resolvedIcon as string
99
130
  }
100
131
  }
101
132
 
@@ -115,7 +146,7 @@ const Icon = (props: IconProps) => {
115
146
  className
116
147
  )
117
148
 
118
- aria.label ? null : aria.label = `${icon} icon`
149
+ aria.label ? null : aria.label = `${resolvedIcon} icon`
119
150
  const ariaProps: {[key: string]: any} = buildAriaProps(aria)
120
151
  const dataProps: {[key: string]: any} = buildDataProps(data)
121
152
  const htmlProps = buildHtmlProps(htmlOptions)
@@ -137,7 +168,7 @@ const Icon = (props: IconProps) => {
137
168
  }
138
169
  </>
139
170
  )
140
- else if (isValidEmoji(icon as string))
171
+ else if (isValidEmoji(resolvedIcon as string))
141
172
  return (
142
173
  <>
143
174
  <span
@@ -146,7 +177,7 @@ const Icon = (props: IconProps) => {
146
177
  className={classesEmoji}
147
178
  id={id}
148
179
  >
149
- {icon}
180
+ {resolvedIcon}
150
181
  </span>
151
182
  </>
152
183
  )
@@ -1 +1,6 @@
1
- <%= pb_rails("icon", props: { icon: "user", fixed_width: true }) %>
1
+ <%= pb_rails("icon", props: { icon: "angles-down", fixed_width: true }) %>
2
+ <%= pb_rails("icon", props: { icon: "circle-arrow-right", fixed_width: true }) %>
3
+ <%= pb_rails("icon", props: { icon: "arrow-circle-right", fixed_width: true }) %>
4
+
5
+ <%= pb_rails("caption", props: { text: "Font Awesome (no alias & not in our Playbook-icons lib)", margin_y: "md" }) %>
6
+ <%= pb_rails("icon", props: { icon: "elephant", fixed_width: true }) %>
@@ -1,13 +1,29 @@
1
- import React from 'react'
1
+ import React from "react"
2
2
 
3
- import Icon from '../_icon'
3
+ import Icon from "../_icon"
4
+ import {Caption} from "../.."
4
5
 
5
6
  const IconDefault = (props) => {
6
7
  return (
7
8
  <div>
8
- <Icon
9
- fixedWidth
10
- icon="user"
9
+ <Icon fixedWidth
10
+ icon='angles-down'
11
+ {...props}
12
+ />
13
+ <Icon fixedWidth
14
+ icon='circle-arrow-right'
15
+ {...props}
16
+ />
17
+ <Icon fixedWidth
18
+ icon='arrow-circle-right'
19
+ {...props}
20
+ />
21
+ <Caption
22
+ marginY='md'
23
+ text='Font Awesome (no alias & not in our Playbook-icons lib)'
24
+ />
25
+ <Icon fixedWidth
26
+ icon='elephant'
11
27
  {...props}
12
28
  />
13
29
  </div>
@@ -3,6 +3,7 @@
3
3
  # rubocop:disable Style/HashLikeCase
4
4
 
5
5
  require "open-uri"
6
+ require "json"
6
7
 
7
8
  module Playbook
8
9
  module PbIcon
@@ -38,6 +39,8 @@ module Playbook
38
39
  prop :spin, type: Playbook::Props::Boolean,
39
40
  default: false
40
41
 
42
+ ALIASES = JSON.parse(File.read(Playbook::Engine.root.join("app/pb_kits/playbook/pb_icon/icon_aliases.json")))["aliases"].freeze
43
+
41
44
  def valid_emoji?
42
45
  emoji_regex = /\p{Emoji}/
43
46
  emoji_regex.match?(icon)
@@ -83,7 +86,8 @@ module Playbook
83
86
  return unless Rails.application.config.respond_to?(:icon_path)
84
87
 
85
88
  base_path = Rails.application.config.icon_path
86
- icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{icon}.svg")).first
89
+ resolved_icon = resolve_alias(icon)
90
+ icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{resolved_icon}.svg")).first
87
91
  icon_path if icon_path && File.exist?(icon_path)
88
92
  end
89
93
 
@@ -106,6 +110,22 @@ module Playbook
106
110
 
107
111
  private
108
112
 
113
+ def resolve_alias(icon)
114
+ aliases = ALIASES[icon]
115
+ return icon unless aliases
116
+
117
+ if aliases.is_a?(Array)
118
+ aliases.find { |alias_name| file_exists?(alias_name) } || icon
119
+ else
120
+ aliases
121
+ end
122
+ end
123
+
124
+ def file_exists?(alias_name)
125
+ base_path = Rails.application.config.icon_path
126
+ File.exist?(Dir.glob(Rails.root.join(base_path, "**", "#{alias_name}.svg")).first)
127
+ end
128
+
109
129
  def svg_size
110
130
  size.nil? ? "1x" : size
111
131
  end
@@ -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
+ }
@@ -0,0 +1 @@
1
+ declare module 'js-yaml'
@@ -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
@@ -52,6 +52,20 @@
52
52
  data: object.data,
53
53
  id: object.id,
54
54
  **combined_html_options) do %>
55
- <%= content.presence || object.text %>
55
+ <% unless sorting_style? %>
56
+ <%= content.presence || object.text %>
57
+ <% else %>
58
+ <%= link_to next_link, style: link_style do %>
59
+ <%= pb_rails("flex", props:{ align: object.align_content, justify: object.justify_sort_icon, classname: "pb_th_link" }) do %>
60
+ <%= content.presence || object.text %>
61
+ <% if sorting_style? %>
62
+ <%= pb_rails("icon", props: { icon: object.sort_icon(active_item[:direction], active_item[:active]),
63
+ fixed_width: true,
64
+ classname: active_item.any? ? "pb_th_active" : "",
65
+ padding_left: "xs" }) %>
66
+ <% end %>
67
+ <% end %>
68
+ <% end %>
69
+ <% end %>
70
+ <% end %>
56
71
  <% end %>
57
- <% end %>