playbook_ui 16.1.0.pre.alpha.PLAY277014019 → 16.1.0.pre.alpha.ghostcrewfileuploadtext14338
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 +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +33 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_custom.jsx +71 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_background_custom.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_button/_button.scss +41 -0
- data/app/pb_kits/playbook/pb_button/_button.tsx +5 -0
- data/app/pb_kits/playbook/pb_button/button.html.erb +12 -8
- data/app/pb_kits/playbook/pb_button/button.rb +5 -0
- data/app/pb_kits/playbook/pb_button/button.test.js +105 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_variant.html.erb +21 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_variant.jsx +180 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_variant_rails.md +1 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_icon_variant_react.md +1 -0
- data/app/pb_kits/playbook/pb_button/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_button/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +1 -1
- data/app/pb_kits/playbook/pb_checkbox/_checkbox.tsx +17 -0
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +10 -1
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +2 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_required_indicator.html.erb +6 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_required_indicator.jsx +17 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +12 -4
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +25 -16
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +3 -0
- data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +36 -1
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_required_indicator.html.erb +5 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_required_indicator.jsx +13 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_required_indicator.md +1 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +60 -12
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_required_indicator.html.erb +14 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_required_indicator.jsx +42 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.html.erb +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.md +3 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +17 -5
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +11 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +24 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +15 -10
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +4 -0
- data/app/pb_kits/playbook/pb_dropdown/index.js +132 -79
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +16 -0
- data/app/pb_kits/playbook/pb_dropdown/utilities/clickOutsideHelper.tsx +6 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +157 -3
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_button.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_button.jsx +1 -0
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_date_picker.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_date_picker.jsx +1 -0
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_default.html.erb +3 -3
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_default.jsx +4 -1
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_full_width.html.erb +4 -4
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_full_width.jsx +4 -1
- data/app/pb_kits/playbook/pb_form_group/docs/_form_group_typeahead.jsx +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -0
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +648 -549
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +3 -3
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +4 -7
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.md +3 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_required_indicator.html.erb +72 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_required_indicator.jsx +87 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +18 -17
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +3 -0
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx +55 -25
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select_options.tsx +4 -4
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +8 -3
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +71 -67
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_max_displayed_users.jsx +71 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +2 -1
- data/app/pb_kits/playbook/pb_multiple_users/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_nav/_item.tsx +5 -3
- data/app/pb_kits/playbook/pb_nav/_nav.scss +82 -3
- data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav_disabled_item.html.erb +24 -0
- data/app/pb_kits/playbook/pb_nav/docs/_collapsible_nav_disabled_item.jsx +87 -0
- data/app/pb_kits/playbook/pb_nav/docs/example.yml +2 -6
- data/app/pb_kits/playbook/pb_nav/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_nav/item.html.erb +1 -1
- data/app/pb_kits/playbook/pb_nav/item.rb +1 -1
- data/app/pb_kits/playbook/pb_nav/navTypes.ts +1 -0
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +20 -2
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +9 -0
- data/app/pb_kits/playbook/pb_select/_select.tsx +26 -18
- data/app/pb_kits/playbook/pb_select/docs/_select_required_indicator.html.erb +24 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_required_indicator.jsx +33 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_select/select.html.erb +7 -1
- data/app/pb_kits/playbook/pb_select/select.rb +3 -0
- data/app/pb_kits/playbook/pb_star_rating/_star_rating.tsx +3 -0
- data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.html.erb +1 -1
- data/app/pb_kits/playbook/pb_star_rating/docs/_star_rating_interactive.jsx +1 -0
- data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +2 -2
- data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_interactive.tsx +55 -39
- data/app/pb_kits/playbook/pb_table/index.ts +29 -27
- data/app/pb_kits/playbook/pb_text_input/text_input.html.erb +10 -10
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +29 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +411 -323
- data/app/pb_kits/playbook/pb_typeahead/components/Control.tsx +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_required_indicator.html.erb +16 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_required_indicator.jsx +23 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +22 -21
- data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +3 -2
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +3 -1
- data/app/pb_kits/playbook/tokens/_colors.scss +3 -0
- data/app/pb_kits/playbook/tokens/_colors_accessible.scss +250 -0
- data/app/pb_kits/playbook/tokens/exports/_colors.module.scss +10 -0
- data/dist/chunks/{_pb_line_graph-BgKF_zz1.js → _pb_line_graph-CC2Ywwix.js} +1 -1
- data/dist/chunks/_typeahead-DtzfGPUT.js +1 -0
- data/dist/chunks/{globalProps-BhVYCqRf.js → globalProps-DYr2qrIf.js} +1 -1
- data/dist/chunks/lib-DgqmX9CF.js +29 -0
- data/dist/chunks/vendor.js +3 -3
- data/dist/menu.yml +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +2 -2
- data/dist/reset.css +1 -1
- data/lib/playbook/forms/builder/collection_select_field.rb +7 -1
- data/lib/playbook/forms/builder/date_picker_field.rb +8 -2
- data/lib/playbook/forms/builder/dropdown_field.rb +7 -1
- data/lib/playbook/forms/builder/form_field_builder.rb +1 -1
- data/lib/playbook/forms/builder/multi_level_select_field.rb +8 -0
- data/lib/playbook/forms/builder/select_field.rb +7 -1
- data/lib/playbook/forms/builder/time_zone_select_field.rb +7 -1
- data/lib/playbook/forms/builder/typeahead_field.rb +15 -1
- data/lib/playbook/forms/builder.rb +2 -2
- data/lib/playbook/tokens/colors.json +99 -0
- data/lib/playbook/tokens.rb +99 -0
- data/lib/playbook/version.rb +1 -1
- data/lib/playbook.rb +1 -0
- metadata +37 -6
- data/dist/chunks/_typeahead-Do4yr_4Z.js +0 -1
- data/dist/chunks/lib-DD34ZrWL.js +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e77463bcd2917e10f224e72546b98f389c106c928b9377cf0ab0bc2e9c6e1226
|
|
4
|
+
data.tar.gz: 5d44603ac547c6944a0b47e7614ac49b2ea79d5c17bf684962ce481b5a5209e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eefd223b13bfbe1e0d0338c8e18230865956ee33b37afe29bbc93681fd88759f480df9ffe9e1cc2dd197669ec60b3fe9f9c2d70e50964b58e87432bdd1ec15e6
|
|
7
|
+
data.tar.gz: 23cf3b5b1a6000d46dc2666eb99f4e682d1d09e8fb2ddfbd9a649c26a7fc9eaf2d5e75e1128401c9ce12e609fba0e7f42e270a0314e86f8f3330a440bf3a91ec
|
|
@@ -66,8 +66,18 @@ const TableCellRenderer = ({
|
|
|
66
66
|
// Find the "owning" colDefinition by accessor. Needed for multi column logic
|
|
67
67
|
const colDef = findColumnDefByAccessor(columnDefinitions ?? [], column.id)
|
|
68
68
|
const cellAlignment = colDef?.columnStyling?.cellAlignment ?? "right"
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
|
|
70
|
+
// Support function-based styling for conditional rendering
|
|
71
|
+
const cellFontColorValue = colDef?.columnStyling?.fontColor
|
|
72
|
+
const cellFontColor = typeof cellFontColorValue === 'function'
|
|
73
|
+
? cellFontColorValue(row)
|
|
74
|
+
: cellFontColorValue
|
|
75
|
+
|
|
76
|
+
const cellBackgroundColorValue = colDef?.columnStyling?.cellBackgroundColor
|
|
77
|
+
const cellBackgroundColor = typeof cellBackgroundColorValue === 'function'
|
|
78
|
+
? cellBackgroundColorValue(row)
|
|
79
|
+
: cellBackgroundColorValue
|
|
80
|
+
|
|
71
81
|
const paddingValue = colDef?.columnStyling?.cellPadding ?? customRowStyle?.cellPadding
|
|
72
82
|
const paddingClass = paddingValue ? `p_${paddingValue}` : undefined
|
|
73
83
|
|
|
@@ -920,6 +920,39 @@ test("columnStyling.backgroundColor works as excpected", () => {
|
|
|
920
920
|
expect(firstEnrollmentCell).toHaveStyle({ backgroundColor: colors.error_subtle });
|
|
921
921
|
});
|
|
922
922
|
|
|
923
|
+
test("columnStyling.cellBackgroundColor works as expected with function", () => {
|
|
924
|
+
const styledColumnDefs = [
|
|
925
|
+
{
|
|
926
|
+
accessor: "year",
|
|
927
|
+
label: "Year",
|
|
928
|
+
cellAccessors: ["quarter", "month", "day"],
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
accessor: "newEnrollments",
|
|
932
|
+
label: "New Enrollments",
|
|
933
|
+
columnStyling:{
|
|
934
|
+
cellBackgroundColor: (row) => row.original.newEnrollments > 15 ? colors.success_subtle : colors.error_subtle,
|
|
935
|
+
fontColor: (row) => row.original.newEnrollments > 15 ? colors.success : colors.error,
|
|
936
|
+
},
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
accessor: "scheduledMeetings",
|
|
940
|
+
label: "Scheduled Meetings",
|
|
941
|
+
},
|
|
942
|
+
];
|
|
943
|
+
|
|
944
|
+
render(
|
|
945
|
+
<AdvancedTable
|
|
946
|
+
columnDefinitions={styledColumnDefs}
|
|
947
|
+
data={{ testid: testId }}
|
|
948
|
+
tableData={MOCK_DATA}
|
|
949
|
+
/>
|
|
950
|
+
);
|
|
951
|
+
|
|
952
|
+
const firstEnrollmentCell = screen.getAllByText("20")[0].closest("td");
|
|
953
|
+
expect(firstEnrollmentCell).toHaveStyle({ backgroundColor: colors.success_subtle, color: colors.success });
|
|
954
|
+
});
|
|
955
|
+
|
|
923
956
|
test("columnStyling.headerBackgroundColor works as excpected", () => {
|
|
924
957
|
const styledColumnDefs = [
|
|
925
958
|
{
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import AdvancedTable from '../_advanced_table'
|
|
3
|
+
import colors from '../../tokens/exports/_colors.module.scss'
|
|
4
|
+
import MOCK_DATA from "./advanced_table_mock_data.json"
|
|
5
|
+
import Flex from '../../pb_flex/_flex'
|
|
6
|
+
import Title from '../../pb_title/_title'
|
|
7
|
+
import Body from '../../pb_body/_body'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const AdvancedTableColumnStylingBackgroundCustom = (props) => {
|
|
11
|
+
const columnDefinitions = [
|
|
12
|
+
{
|
|
13
|
+
accessor: "year",
|
|
14
|
+
label: "Year",
|
|
15
|
+
cellAccessors: ["quarter", "month", "day"],
|
|
16
|
+
customRenderer: (row, value) => (
|
|
17
|
+
<Flex flexDirection="column">
|
|
18
|
+
<Title size={4}
|
|
19
|
+
text={value}
|
|
20
|
+
/>
|
|
21
|
+
<Body text="lorem ipsum" />
|
|
22
|
+
<Body text="lorem ipsum" />
|
|
23
|
+
</Flex>
|
|
24
|
+
),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
accessor: "newEnrollments",
|
|
28
|
+
label: "New Enrollments",
|
|
29
|
+
columnStyling:{
|
|
30
|
+
cellBackgroundColor: (row) => row.original.newEnrollments > 15 ? colors.success_subtle : colors.error_subtle,
|
|
31
|
+
fontColor: (row) => row.original.newEnrollments > 15 ? colors.success : colors.error,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
accessor: "scheduledMeetings",
|
|
36
|
+
label: "Scheduled Meetings",
|
|
37
|
+
columnStyling:{
|
|
38
|
+
cellBackgroundColor: (row) => row.original.scheduledMeetings >= 15 ? colors.info_subtle : colors.warning_subtle
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
accessor: "attendanceRate",
|
|
43
|
+
label: "Attendance Rate",
|
|
44
|
+
columnStyling:{cellBackgroundColor: colors.info, headerBackgroundColor: colors.info, fontColor: colors.white, headerFontColor: colors.white},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
accessor: "completedClasses",
|
|
48
|
+
label: "Completed Classes",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
accessor: "classCompletionRate",
|
|
52
|
+
label: "Class Completion Rate",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
accessor: "graduatedStudents",
|
|
56
|
+
label: "Graduated Students",
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
<AdvancedTable
|
|
63
|
+
columnDefinitions={columnDefinitions}
|
|
64
|
+
tableData={MOCK_DATA}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default AdvancedTableColumnStylingBackgroundCustom
|
|
@@ -2,4 +2,4 @@ the `enableSorting` prop is a boolean prop set to false by default. If true, the
|
|
|
2
2
|
|
|
3
3
|
### sortIcon
|
|
4
4
|
|
|
5
|
-
An optional prop, `sortIcon` allows you to customize your icon sets by passing it an array of any comma-separated pair of icon values. The first icon value will replace the kit's default icon when sort direction is desc, and the second value will replace the default icon when sort direction is asc. `sortIcon` also allows you to pass it a single icon as a string, in which case the icon will not toggle with the sort state. Default for this prop is `["arrow-up-short
|
|
5
|
+
An optional prop, `sortIcon` allows you to customize your icon sets by passing it an array of any comma-separated pair of icon values. The first icon value will replace the kit's default icon when sort direction is desc, and the second value will replace the default icon when sort direction is asc. `sortIcon` also allows you to pass it a single icon as a string, in which case the icon will not toggle with the sort state. Default for this prop is `["arrow-up-wide-short", "arrow-down-short-wide"]`. All strings must be valid FA icons.
|
|
@@ -78,6 +78,7 @@ examples:
|
|
|
78
78
|
- advanced_table_column_styling: Column Styling
|
|
79
79
|
- advanced_table_column_styling_column_headers: Column Styling with Multiple Headers
|
|
80
80
|
- advanced_table_column_styling_background: Column Styling Background Color
|
|
81
|
+
- advanced_table_column_styling_background_custom: Column Styling Background Color (Custom)
|
|
81
82
|
- advanced_table_column_styling_background_multi: Column Styling Background Color with Multiple Headers
|
|
82
83
|
- advanced_table_padding_control: Padding Control using Column Styling
|
|
83
84
|
- advanced_table_column_border_color: Column Group Border Color
|
|
@@ -47,4 +47,5 @@ export { default as AdvancedTableSortPerColumnForMultiColumn } from './_advanced
|
|
|
47
47
|
export { default as AdvancedTablePaddingControl } from './_advanced_table_padding_control.jsx'
|
|
48
48
|
export { default as AdvancedTablePaddingControlPerRow } from './_advanced_table_padding_control_per_row.jsx'
|
|
49
49
|
export { default as AdvancedTableColumnStylingBackground } from './_advanced_table_column_styling_background.jsx'
|
|
50
|
-
export { default as AdvancedTableColumnStylingBackgroundMulti } from './_advanced_table_column_styling_background_multi.jsx'
|
|
50
|
+
export { default as AdvancedTableColumnStylingBackgroundMulti } from './_advanced_table_column_styling_background_multi.jsx'
|
|
51
|
+
export { default as AdvancedTableColumnStylingBackgroundCustom } from './_advanced_table_column_styling_background_custom.jsx'
|
|
@@ -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
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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: " ")
|
|
@@ -131,3 +131,108 @@ test('should render child target prop', () => {
|
|
|
131
131
|
expect(kit).toHaveAttribute('target', 'child')
|
|
132
132
|
expect(kit).not.toHaveAttribute('rel')
|
|
133
133
|
})
|
|
134
|
+
|
|
135
|
+
describe('icon-only button', () => {
|
|
136
|
+
test('adds pb_button_icon_only class when icon is provided without text', () => {
|
|
137
|
+
render(
|
|
138
|
+
<Button
|
|
139
|
+
data={{ testid: 'icon-only-test' }}
|
|
140
|
+
icon="plus"
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
const kit = screen.getByTestId('icon-only-test')
|
|
145
|
+
expect(kit).toHaveClass('pb_button_icon_only')
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('does not add pb_button_icon_only class when text is provided', () => {
|
|
149
|
+
render(
|
|
150
|
+
<Button
|
|
151
|
+
data={{ testid: 'icon-with-text-test' }}
|
|
152
|
+
icon="plus"
|
|
153
|
+
text="Click me"
|
|
154
|
+
/>
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
const kit = screen.getByTestId('icon-with-text-test')
|
|
158
|
+
expect(kit).not.toHaveClass('pb_button_icon_only')
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
test('does not add pb_button_icon_only class when children are provided', () => {
|
|
162
|
+
render(
|
|
163
|
+
<Button
|
|
164
|
+
data={{ testid: 'icon-with-children-test' }}
|
|
165
|
+
icon="plus"
|
|
166
|
+
>
|
|
167
|
+
Click me
|
|
168
|
+
</Button>
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
const kit = screen.getByTestId('icon-with-children-test')
|
|
172
|
+
expect(kit).not.toHaveClass('pb_button_icon_only')
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test('does not add pb_button_icon_only class when variant is reaction', () => {
|
|
176
|
+
render(
|
|
177
|
+
<Button
|
|
178
|
+
data={{ testid: 'reaction-icon-test' }}
|
|
179
|
+
icon="plus"
|
|
180
|
+
variant="reaction"
|
|
181
|
+
/>
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
const kit = screen.getByTestId('reaction-icon-test')
|
|
185
|
+
expect(kit).not.toHaveClass('pb_button_icon_only')
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
test('adds pb_button_icon_only class with different variants', () => {
|
|
189
|
+
const variants = ['primary', 'secondary', 'link', 'danger']
|
|
190
|
+
|
|
191
|
+
variants.forEach(variant => {
|
|
192
|
+
const { unmount } = render(
|
|
193
|
+
<Button
|
|
194
|
+
data={{ testid: `icon-only-${variant}-test` }}
|
|
195
|
+
icon="plus"
|
|
196
|
+
variant={variant}
|
|
197
|
+
/>
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
const kit = screen.getByTestId(`icon-only-${variant}-test`)
|
|
201
|
+
expect(kit).toHaveClass('pb_button_icon_only')
|
|
202
|
+
unmount()
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
test('adds pb_button_icon_only class with loading state', () => {
|
|
207
|
+
render(
|
|
208
|
+
<Button
|
|
209
|
+
data={{ testid: 'icon-only-loading-test' }}
|
|
210
|
+
icon="plus"
|
|
211
|
+
loading
|
|
212
|
+
/>
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
const kit = screen.getByTestId('icon-only-loading-test')
|
|
216
|
+
expect(kit).toHaveClass('pb_button_icon_only')
|
|
217
|
+
expect(kit).toHaveClass('pb_button_loading')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
test('adds pb_button_icon_only class with size variants', () => {
|
|
221
|
+
const sizes = ['sm', 'md', 'lg']
|
|
222
|
+
|
|
223
|
+
sizes.forEach(size => {
|
|
224
|
+
const { unmount } = render(
|
|
225
|
+
<Button
|
|
226
|
+
data={{ testid: `icon-only-${size}-test` }}
|
|
227
|
+
icon="plus"
|
|
228
|
+
size={size}
|
|
229
|
+
/>
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
const kit = screen.getByTestId(`icon-only-${size}-test`)
|
|
233
|
+
expect(kit).toHaveClass('pb_button_icon_only')
|
|
234
|
+
expect(kit).toHaveClass(`pb_button_size_${size}`)
|
|
235
|
+
unmount()
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
})
|
|
@@ -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'
|