playbook_ui 16.0.0.pre.alpha.PLAY2668multipleuserstooltiprails13556 → 16.0.0.pre.alpha.PLAY2684iconbuttonvariant13518

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1da81b6d114d52abee6e17253134d3b749f6f6d6f07f2840161e390841f5862
4
- data.tar.gz: 310a63b443f95e203b0df3a7e86e77df1f2c39747bc5d900cb5989585317ffa5
3
+ metadata.gz: c9d0f9943190ec65f7767c1f1131909858fe408507a1d372dc27035b69847e76
4
+ data.tar.gz: 692a5f395f2c164a70e82e763d565ba9165a618de92d36f2b251cec4be8d1a43
5
5
  SHA512:
6
- metadata.gz: 48f07c1c7681baae8d05db757a0633476cc891838cbd34d8a1befcbaa1b9740313611bfb4ac6a42e16508bbec0bc3b584e93c10f6500d4c305f1bb4dc16b2e4b
7
- data.tar.gz: 7bce0e9f5cb09ef11ef65d74dd3ccedb21b317ac4c62d34d364b0568dc1bdf1cb770f7d156caaf436858e76a988cb90207f6446cf9863a4308c5ec0b2f3d514e
6
+ metadata.gz: 23c40516ab6c6326addb1518871fd50284ab753a827eed90b552f1520fdf6cf1e675f7b7429b28ce5c8d88315a260cfd174c8a586e404d3a21f2aedcf6825340
7
+ data.tar.gz: 3fa52f22147c20d6c8bcae9c7cbfe258f5cb7fe76fc983b8ae8d4dcd1b804e2277aee4987ec06ce4d45bada533c11ca552eef8dd56b8792c56f6755b0dc4cb6d
@@ -112,4 +112,45 @@ $pb_button_sizes: (
112
112
  @include pb_button_disabled_dark;
113
113
  }
114
114
  }
115
+
116
+ // Icon-only button (icon prop set, no text) - square with equal padding
117
+ // Rails: uses .pb_button_icon_only class
118
+ // React: detects when pb_button_content has an empty text span
119
+ &.pb_button_icon_only,
120
+ &:has(.pb_button_content > span:empty) {
121
+ aspect-ratio: 1;
122
+ min-width: auto;
123
+ width: auto;
124
+ height: auto;
125
+ padding: $pb_button_v_padding !important;
126
+ min-height: ($pb_button_v_padding * 2) + $font_small;
127
+
128
+ &.pb_button_size_sm {
129
+ padding: $font_smaller !important;
130
+ min-height: ($font_smaller * 2) + $font_smaller;
131
+ }
132
+
133
+ &.pb_button_size_md {
134
+ padding: $font_small !important;
135
+ min-height: ($font_small * 2) + $font_small;
136
+ }
137
+
138
+ &.pb_button_size_lg {
139
+ padding: ($font_large - 2px) !important;
140
+ min-height: (($font_large - 2px) * 2) + ($font_large - 2px);
141
+ }
142
+
143
+ // Remove margins from icons
144
+ .button_with_icon,
145
+ .button_with_icon_right {
146
+ margin-right: 0;
147
+ margin-left: 0;
148
+ }
149
+
150
+ // Remove margins from Rails icon wrapper spans
151
+ > span {
152
+ margin-right: 0 !important;
153
+ margin-left: 0 !important;
154
+ }
155
+ }
115
156
  }
@@ -51,9 +51,13 @@ const buttonClassName = (props: ButtonPropTypes) => {
51
51
  type = 'inline',
52
52
  variant = 'primary',
53
53
  size = null,
54
+ text,
55
+ children,
54
56
  } = props
55
57
 
56
58
  const classNames = ['pb_button_kit']
59
+ // Icon-only: has icon, no text/children, and not a reaction button (reaction buttons have count)
60
+ const isIconOnly = icon && !text && !children && variant !== 'reaction'
57
61
 
58
62
  if (variant) classNames.push(`pb_button_${variant}`)
59
63
  if (type) classNames.push(`pb_button_${type}`)
@@ -63,6 +67,7 @@ const buttonClassName = (props: ButtonPropTypes) => {
63
67
  if (size) classNames.push(`pb_button_size_${size}`)
64
68
  if (variant === 'reaction' && icon && !isValidEmoji(icon)) classNames.push('pb_button_reaction_default')
65
69
  if (variant === 'reaction' && highlight) classNames.push('pb_button_active')
70
+ if (isIconOnly) classNames.push('pb_button_icon_only')
66
71
 
67
72
  return classNames.join(' ')
68
73
  }
@@ -16,17 +16,21 @@
16
16
  <% end %>
17
17
  <% end %>
18
18
  <% else %>
19
- <% if object.icon && !object.icon_right %>
20
- <span>
21
- <%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_right: "xs", font_style: object.icon_font_family }) %>
22
- </span>
19
+ <% if !object.loading %>
20
+ <% if object.icon && !object.icon_right %>
21
+ <span>
22
+ <%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, font_style: object.icon_font_family }.merge((object.icon_only? && content.blank?) ? {} : { margin_right: "xs" })) %>
23
+ </span>
24
+ <% end %>
23
25
  <% end %>
24
26
  <%= pb_rails("icon", props: { custom_icon: Playbook::Engine::root.join(spinner_path), pulse: true, fixed_width: true, classname: "loading-icon" }) %>
25
27
  <span class="pb_button_content"><%= content.presence || object.text %></span>
26
- <% if object.icon && object.icon_right %>
27
- <span>
28
- <%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_left: "xs", font_style: object.icon_font_family }) %>
29
- </span>
28
+ <% if !object.loading %>
29
+ <% if object.icon && object.icon_right %>
30
+ <span>
31
+ <%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, font_style: object.icon_font_family }.merge((object.icon_only? && content.blank?) ? {} : { margin_left: "xs" })) %>
32
+ </span>
33
+ <% end %>
30
34
  <% end %>
31
35
  <% end %>
32
36
 
@@ -73,6 +73,10 @@ module Playbook
73
73
  emoji_regex.match?(icon)
74
74
  end
75
75
 
76
+ def icon_only?
77
+ icon.present? && text.blank? && variant != "reaction"
78
+ end
79
+
76
80
  def classname
77
81
  class_names = ["pb_button_kit"]
78
82
  class_names << "pb_button_#{variant}" if variant
@@ -82,6 +86,7 @@ module Playbook
82
86
  class_names << "pb_button_size_#{size}" if size
83
87
  class_names << "pb_button_reaction_default" if variant === "reaction" && icon && !valid_emoji(icon)
84
88
  class_names << "pb_button_active" if variant === "reaction" && highlight
89
+ class_names << "pb_button_icon_only" if icon_only?
85
90
 
86
91
  class_names.join(" ")
87
92
  generate_classname(class_names.compact.join(" "), separator: " ")
@@ -0,0 +1,21 @@
1
+ <%= pb_rails("caption", props: { margin_y: "md", text: "Small Size (sm)" }) %>
2
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", margin_right: "lg" }) %>
3
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", variant: "secondary", margin_right: "lg" }) %>
4
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", variant: "link", margin_right: "lg" }) %>
5
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", variant: "danger", margin_right: "lg" }) %>
6
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", disabled: true, margin_right: "lg" }) %>
7
+ <%= pb_rails("button", props: { icon: "plus", size: "sm", loading: true, margin_right: "lg" }) %>
8
+ <%= pb_rails("caption", props: { margin_y: "md", text: "Medium Size (md)" }) %>
9
+ <%= pb_rails("button", props: { icon: "plus", size: "md", margin_right: "lg" }) %>
10
+ <%= pb_rails("button", props: { icon: "plus", size: "md", variant: "secondary", margin_right: "lg" }) %>
11
+ <%= pb_rails("button", props: { icon: "plus", size: "md", variant: "link", margin_right: "lg" }) %>
12
+ <%= pb_rails("button", props: { icon: "plus", size: "md", variant: "danger", margin_right: "lg" }) %>
13
+ <%= pb_rails("button", props: { icon: "plus", size: "md", disabled: true, margin_right: "lg" }) %>
14
+ <%= pb_rails("button", props: { icon: "plus", size: "md", loading: true, margin_right: "lg" }) %>
15
+ <%= pb_rails("caption", props: { margin_y: "md", text: "Large Size (lg)" }) %>
16
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", margin_right: "lg" }) %>
17
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", variant: "secondary", margin_right: "lg" }) %>
18
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", variant: "link", margin_right: "lg" }) %>
19
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", variant: "danger", margin_right: "lg" }) %>
20
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", disabled: true, margin_right: "lg" }) %>
21
+ <%= pb_rails("button", props: { icon: "plus", size: "lg", loading: true, margin_right: "lg" }) %>
@@ -0,0 +1,180 @@
1
+ import React from 'react'
2
+ import Button from "../../pb_button/_button"
3
+ import Caption from "../../pb_caption/_caption"
4
+
5
+ const ButtonIconVariant = (props) => (
6
+ <div>
7
+ <Caption
8
+ marginY="md"
9
+ text="Small Size (sm)"
10
+ />
11
+ <Button
12
+ icon="plus"
13
+ marginRight='lg'
14
+ size="sm"
15
+ tabIndex={0}
16
+ {...props}
17
+ />
18
+ {' '}
19
+ <Button
20
+ icon="plus"
21
+ marginRight='lg'
22
+ size="sm"
23
+ tabIndex={0}
24
+ variant="secondary"
25
+ {...props}
26
+ />
27
+ {' '}
28
+ <Button
29
+ icon="plus"
30
+ marginRight='lg'
31
+ size="sm"
32
+ tabIndex={0}
33
+ variant="link"
34
+ {...props}
35
+ />
36
+ {' '}
37
+ <Button
38
+ icon="plus"
39
+ marginRight='lg'
40
+ size="sm"
41
+ tabIndex={0}
42
+ variant="danger"
43
+ {...props}
44
+ />
45
+ {' '}
46
+ <Button
47
+ disabled
48
+ icon="plus"
49
+ marginRight='lg'
50
+ size="sm"
51
+ tabIndex={0}
52
+ {...props}
53
+ />
54
+ {' '}
55
+ <Button
56
+ icon="plus"
57
+ loading
58
+ marginRight='lg'
59
+ size="sm"
60
+ tabIndex={0}
61
+ {...props}
62
+ />
63
+ <br/>
64
+ <Caption
65
+ marginY="md"
66
+ text="Medium Size (md)"
67
+ />
68
+ <Button
69
+ icon="plus"
70
+ marginRight='lg'
71
+ size="md"
72
+ tabIndex={0}
73
+ {...props}
74
+ />
75
+ {' '}
76
+ <Button
77
+ icon="plus"
78
+ marginRight='lg'
79
+ size="md"
80
+ tabIndex={0}
81
+ variant="secondary"
82
+ {...props}
83
+ />
84
+ {' '}
85
+ <Button
86
+ icon="plus"
87
+ marginRight='lg'
88
+ size="md"
89
+ tabIndex={0}
90
+ variant="link"
91
+ {...props}
92
+ />
93
+ {' '}
94
+ <Button
95
+ icon="plus"
96
+ marginRight='lg'
97
+ size="md"
98
+ tabIndex={0}
99
+ variant="danger"
100
+ {...props}
101
+ />
102
+ {' '}
103
+ <Button
104
+ disabled
105
+ icon="plus"
106
+ marginRight='lg'
107
+ size="md"
108
+ tabIndex={0}
109
+ {...props}
110
+ />
111
+ {' '}
112
+ <Button
113
+ icon="plus"
114
+ loading
115
+ marginRight='lg'
116
+ size="md"
117
+ tabIndex={0}
118
+ {...props}
119
+ />
120
+ <br/>
121
+ <Caption
122
+ marginY="md"
123
+ text="Large Size (lg)"
124
+ />
125
+ <Button
126
+ icon="plus"
127
+ marginRight='lg'
128
+ size="lg"
129
+ tabIndex={0}
130
+ {...props}
131
+ />
132
+ {' '}
133
+ <Button
134
+ icon="plus"
135
+ marginRight='lg'
136
+ size="lg"
137
+ tabIndex={0}
138
+ variant="secondary"
139
+ {...props}
140
+ />
141
+ {' '}
142
+ <Button
143
+ icon="plus"
144
+ marginRight='lg'
145
+ size="lg"
146
+ tabIndex={0}
147
+ variant="link"
148
+ {...props}
149
+ />
150
+ {' '}
151
+ <Button
152
+ icon="plus"
153
+ marginRight='lg'
154
+ size="lg"
155
+ tabIndex={0}
156
+ variant="danger"
157
+ {...props}
158
+ />
159
+ {' '}
160
+ <Button
161
+ disabled
162
+ icon="plus"
163
+ marginRight='lg'
164
+ size="lg"
165
+ tabIndex={0}
166
+ {...props}
167
+ />
168
+ {' '}
169
+ <Button
170
+ icon="plus"
171
+ loading
172
+ marginRight='lg'
173
+ size="lg"
174
+ tabIndex={0}
175
+ {...props}
176
+ />
177
+ </div>
178
+ )
179
+
180
+ export default ButtonIconVariant
@@ -0,0 +1 @@
1
+ The icon button variant automatically renders when you provide an `icon` prop without a corresponding `text` prop. The button will only display an icon (no text) and will be wrapped with the icon button styling. This works with all button variants including "link", "primary", "secondary", etc. Simply use `<%= pb_rails("button", props: { icon: "plus", variant: "secondary" }) %>` to get an icon button.
@@ -0,0 +1 @@
1
+ The icon button variant automatically renders when you provide an `icon` prop without a corresponding `text` prop. The button will only display an icon (no text) and will be wrapped with the icon button styling. This works with all button variants including "link", "primary", "secondary", etc. Simply use `<Button icon="rocket" variant="primary" />` to get an icon button.
@@ -13,6 +13,7 @@ examples:
13
13
  - button_form: Button Form Attribute
14
14
  - button_managed_disabled: Button Toggle Disabled State
15
15
  - button_managed_disabled_helper: Button Toggle Disabled State Helper
16
+ - button_icon_variant: Icon Button Variant
16
17
 
17
18
  react:
18
19
  - button_default: Button Variants
@@ -27,6 +28,7 @@ examples:
27
28
  - button_size: Button Size
28
29
  - button_form: Button Form Attribute
29
30
  - button_hover: Button Hover
31
+ - button_icon_variant: Icon Button Variant
30
32
 
31
33
  swift:
32
34
  - button_default_swift: Button Variants
@@ -4,6 +4,7 @@ export { default as ButtonLink } from './_button_link.jsx'
4
4
  export { default as ButtonLoading } from './_button_loading.jsx'
5
5
  export { default as ButtonBlockContent } from './_button_block_content.jsx'
6
6
  export { default as ButtonIconOptions } from './_button_icon_options.jsx'
7
+ export { default as ButtonIconVariant } from './_button_icon_variant.jsx'
7
8
  export { default as ButtonAccessibility } from './_button_accessibility.jsx'
8
9
  export { default as ButtonOptions } from './_button_options.jsx'
9
10
  export { default as ButtonSize } from './_button_size.jsx'
@@ -38,5 +38,5 @@ const MultipleUsersWithTooltip = (props) => {
38
38
  </div>
39
39
  )
40
40
  }
41
-
41
+ ``
42
42
  export default MultipleUsersWithTooltip
@@ -1 +1 @@
1
- Use the `withTooltip` / `with_tooltip` boolean prop to enable setting user-specific tooltip content via the `tooltip` property in the users array.
1
+ Use the `withTooltip` boolean prop to enable setting user-specific tooltip content via the `tooltip` property in the users array.
@@ -4,7 +4,6 @@ examples:
4
4
  - multiple_users_default: Default
5
5
  - multiple_users_reverse: Reverse
6
6
  - multiple_users_size: Size
7
- - multiple_users_with_tooltip: With Tooltip
8
7
 
9
8
 
10
9
  react:
@@ -1,55 +1,11 @@
1
1
  <%= pb_content_tag do %>
2
- <% if object.with_tooltip %>
3
- <% object.users.take(object.display_count).each_with_index do |user, index| %>
4
- <% user_id = "multiple-users-#{object.object_id}-user-#{index}" %>
5
- <div id="<%= user_id %>" class="pb_multiple_users_item">
6
- <%= pb_rails("avatar", props: user.except(:tooltip).merge({size: object.size, dark: object.dark})) %>
7
- </div>
8
- <% end %>
9
-
10
- <% if object.more_than_four %>
11
- <% badge_id = "multiple-users-#{object.object_id}-badge" %>
12
- <div id="<%= badge_id %>" class="pb_multiple_users_item multiple_users_badge_<%= object.size %><%= object.dark ? " dark" : "" %>">
13
- <%= "+#{object.users.count - object.display_count}" %>
14
- </div>
15
- <% end %>
16
-
17
- <% object.users.take(object.display_count).each_with_index do |user, index| %>
18
- <% if user[:tooltip].present? %>
19
- <% user_id = "multiple-users-#{object.object_id}-user-#{index}" %>
20
- <%= pb_rails("tooltip", props: {
21
- trigger_element_selector: "##{user_id}",
22
- tooltip_id: "#{user_id}-tooltip",
23
- position: "top",
24
- z_index: "10"
25
- }) do %>
26
- <%= user[:tooltip] %>
27
- <% end %>
28
- <% end %>
29
- <% end %>
30
-
31
- <% if object.more_than_four %>
32
- <% badge_id = "multiple-users-#{object.object_id}-badge" %>
33
- <%= pb_rails("tooltip", props: {
34
- trigger_element_selector: "##{badge_id}",
35
- tooltip_id: "#{badge_id}-tooltip",
36
- position: "top",
37
- z_index: "10"
38
- }) do %>
39
- <% object.users.drop(object.display_count).each do |user| %>
40
- <div><%= user[:tooltip] || user[:name] %></div>
41
- <% end %>
42
- <% end %>
43
- <% end %>
44
- <% else %>
45
- <% object.users.take(object.display_count).each do |user| %>
46
- <%= pb_rails("avatar", props: user.merge({size: object.size, classname: "pb_multiple_users_item", dark: object.dark})) %>
47
- <% end %>
2
+ <% object.users.take(object.display_count).each do |user| %>
3
+ <%= pb_rails("avatar", props: user.merge({size: object.size, classname: "pb_multiple_users_item", dark: object.dark}) ) %>
4
+ <% end %>
48
5
 
49
- <% if object.more_than_four %>
50
- <div class="pb_multiple_users_item multiple_users_badge_<%= object.size %><%= object.dark ? " dark" : "" %>">
51
- <%= "+#{object.users.count - object.display_count}" %>
52
- </div>
53
- <% end %>
6
+ <% if object.more_than_four %>
7
+ <div class="pb_multiple_users_item multiple_users_badge_<%= object.size %><%= object.dark ? " dark" : "" %>">
8
+ <%= "+#{object.users.count - object.display_count}" %>
9
+ </div>
54
10
  <% end %>
55
11
  <% end %>
@@ -8,7 +8,6 @@ module Playbook
8
8
  values: %w[xxs xs],
9
9
  default: "xs"
10
10
  prop :users, type: Playbook::Props::HashArray, required: true
11
- prop :with_tooltip, type: Playbook::Props::Boolean, default: false
12
11
 
13
12
  def more_than_four
14
13
  users.count > 4